misoai-web 1.5.6 → 1.5.8

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 (75) hide show
  1. package/dist/es/agent.js +429 -44
  2. package/dist/es/agent.js.map +1 -1
  3. package/dist/es/bridge-mode-browser.js +10 -9
  4. package/dist/es/bridge-mode-browser.js.map +1 -1
  5. package/dist/es/bridge-mode.js +431 -46
  6. package/dist/es/bridge-mode.js.map +1 -1
  7. package/dist/es/chrome-extension.js +437 -51
  8. package/dist/es/chrome-extension.js.map +1 -1
  9. package/dist/es/index.js +445 -44
  10. package/dist/es/index.js.map +1 -1
  11. package/dist/es/midscene-playground.js +429 -44
  12. package/dist/es/midscene-playground.js.map +1 -1
  13. package/dist/es/midscene-server.js.map +1 -1
  14. package/dist/es/playground.js +429 -44
  15. package/dist/es/playground.js.map +1 -1
  16. package/dist/es/playwright-report.js +1 -1
  17. package/dist/es/playwright-report.js.map +1 -1
  18. package/dist/es/playwright.js +445 -44
  19. package/dist/es/playwright.js.map +1 -1
  20. package/dist/es/puppeteer-agent-launcher.js +429 -44
  21. package/dist/es/puppeteer-agent-launcher.js.map +1 -1
  22. package/dist/es/puppeteer.js +429 -44
  23. package/dist/es/puppeteer.js.map +1 -1
  24. package/dist/es/ui-utils.js.map +1 -1
  25. package/dist/es/utils.js +7 -4
  26. package/dist/es/utils.js.map +1 -1
  27. package/dist/es/yaml.js +24 -0
  28. package/dist/es/yaml.js.map +1 -1
  29. package/dist/lib/agent.js +427 -42
  30. package/dist/lib/agent.js.map +1 -1
  31. package/dist/lib/bridge-mode-browser.js +10 -9
  32. package/dist/lib/bridge-mode-browser.js.map +1 -1
  33. package/dist/lib/bridge-mode.js +429 -44
  34. package/dist/lib/bridge-mode.js.map +1 -1
  35. package/dist/lib/chrome-extension.js +435 -49
  36. package/dist/lib/chrome-extension.js.map +1 -1
  37. package/dist/lib/index.js +443 -42
  38. package/dist/lib/index.js.map +1 -1
  39. package/dist/lib/midscene-playground.js +427 -42
  40. package/dist/lib/midscene-playground.js.map +1 -1
  41. package/dist/lib/midscene-server.js.map +1 -1
  42. package/dist/lib/playground.js +427 -42
  43. package/dist/lib/playground.js.map +1 -1
  44. package/dist/lib/playwright-report.js +1 -1
  45. package/dist/lib/playwright-report.js.map +1 -1
  46. package/dist/lib/playwright.js +443 -42
  47. package/dist/lib/playwright.js.map +1 -1
  48. package/dist/lib/puppeteer-agent-launcher.js +427 -42
  49. package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
  50. package/dist/lib/puppeteer.js +427 -42
  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 +7 -4
  54. package/dist/lib/utils.js.map +1 -1
  55. package/dist/lib/yaml.js +24 -0
  56. package/dist/lib/yaml.js.map +1 -1
  57. package/dist/types/agent.d.ts +101 -8
  58. package/dist/types/bridge-mode-browser.d.ts +2 -3
  59. package/dist/types/bridge-mode.d.ts +2 -3
  60. package/dist/types/{browser-aec1055d.d.ts → browser-9b472ffb.d.ts} +1 -1
  61. package/dist/types/chrome-extension.d.ts +2 -3
  62. package/dist/types/index.d.ts +1 -2
  63. package/dist/types/midscene-server.d.ts +1 -2
  64. package/dist/types/{page-86ab0fe1.d.ts → page-ed0ecb44.d.ts} +19 -9
  65. package/dist/types/playground.d.ts +2 -3
  66. package/dist/types/playwright.d.ts +9 -2
  67. package/dist/types/puppeteer-agent-launcher.d.ts +1 -2
  68. package/dist/types/puppeteer.d.ts +6 -5
  69. package/dist/types/ui-utils.d.ts +1 -1
  70. package/dist/types/utils.d.ts +1 -2
  71. package/dist/types/yaml.d.ts +1 -2
  72. package/iife-script/htmlElement.js +51 -73
  73. package/iife-script/htmlElementDebug.js +33 -54
  74. package/package.json +23 -23
  75. package/LICENSE +0 -21
@@ -22,7 +22,8 @@ var WebElementInfo = class {
22
22
  id,
23
23
  attributes,
24
24
  indexId,
25
- xpaths
25
+ xpaths,
26
+ isVisible
26
27
  }) {
27
28
  this.content = content;
28
29
  this.rect = rect;
@@ -35,6 +36,7 @@ var WebElementInfo = class {
35
36
  this.attributes = attributes;
36
37
  this.indexId = indexId;
37
38
  this.xpaths = xpaths;
39
+ this.isVisible = isVisible;
38
40
  }
39
41
  };
40
42
 
@@ -57,14 +59,15 @@ async function parseContextFromWebPage(page, _opt) {
57
59
  })
58
60
  ]);
59
61
  const webTree = traverseTree(tree, (elementInfo) => {
60
- const { rect, id, content, attributes, locator, indexId } = elementInfo;
62
+ const { rect, id, content, attributes, locator, indexId, isVisible } = elementInfo;
61
63
  return new WebElementInfo({
62
64
  rect,
63
65
  locator,
64
66
  id,
65
67
  content,
66
68
  attributes,
67
- indexId
69
+ indexId,
70
+ isVisible
68
71
  });
69
72
  });
70
73
  assert(screenshotBase64, "screenshotBase64 is required");
@@ -95,7 +98,7 @@ function printReportMsg(filepath) {
95
98
  }
96
99
  var ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED = "NOT_IMPLEMENTED_AS_DESIGNED";
97
100
  function replaceIllegalPathCharsAndSpace(str) {
98
- return str.replace(/[/\\:*?"<>| ]/g, "-");
101
+ return str.replace(/[:*?"<>| ]/g, "-");
99
102
  }
100
103
  function matchElementFromPlan(planLocateParam, tree) {
101
104
  if (!planLocateParam) {
@@ -225,6 +228,10 @@ var ScriptPlayer = class {
225
228
  } else if ("aiQuery" in flowItem) {
226
229
  const queryTask = flowItem;
227
230
  const prompt = queryTask.aiQuery;
231
+ const options = {
232
+ domIncluded: queryTask.domIncluded,
233
+ screenshotIncluded: queryTask.screenshotIncluded
234
+ };
228
235
  assert2(prompt, "missing prompt for aiQuery");
229
236
  assert2(
230
237
  typeof prompt === "string",
@@ -235,6 +242,10 @@ var ScriptPlayer = class {
235
242
  } else if ("aiNumber" in flowItem) {
236
243
  const numberTask = flowItem;
237
244
  const prompt = numberTask.aiNumber;
245
+ const options = {
246
+ domIncluded: numberTask.domIncluded,
247
+ screenshotIncluded: numberTask.screenshotIncluded
248
+ };
238
249
  assert2(prompt, "missing prompt for number");
239
250
  assert2(
240
251
  typeof prompt === "string",
@@ -245,6 +256,10 @@ var ScriptPlayer = class {
245
256
  } else if ("aiString" in flowItem) {
246
257
  const stringTask = flowItem;
247
258
  const prompt = stringTask.aiString;
259
+ const options = {
260
+ domIncluded: stringTask.domIncluded,
261
+ screenshotIncluded: stringTask.screenshotIncluded
262
+ };
248
263
  assert2(prompt, "missing prompt for string");
249
264
  assert2(
250
265
  typeof prompt === "string",
@@ -255,6 +270,10 @@ var ScriptPlayer = class {
255
270
  } else if ("aiBoolean" in flowItem) {
256
271
  const booleanTask = flowItem;
257
272
  const prompt = booleanTask.aiBoolean;
273
+ const options = {
274
+ domIncluded: booleanTask.domIncluded,
275
+ screenshotIncluded: booleanTask.screenshotIncluded
276
+ };
258
277
  assert2(prompt, "missing prompt for boolean");
259
278
  assert2(
260
279
  typeof prompt === "string",
@@ -297,6 +316,9 @@ var ScriptPlayer = class {
297
316
  } else if ("aiTap" in flowItem) {
298
317
  const tapTask = flowItem;
299
318
  await agent.aiTap(tapTask.aiTap, tapTask);
319
+ } else if ("aiRightClick" in flowItem) {
320
+ const rightClickTask = flowItem;
321
+ await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
300
322
  } else if ("aiHover" in flowItem) {
301
323
  const hoverTask = flowItem;
302
324
  await agent.aiHover(hoverTask.aiHover, hoverTask);
@@ -319,6 +341,11 @@ var ScriptPlayer = class {
319
341
  evaluateJavaScriptTask.javascript
320
342
  );
321
343
  this.setResult(evaluateJavaScriptTask.name, result);
344
+ } else if ("logScreenshot" in flowItem) {
345
+ const logScreenshotTask = flowItem;
346
+ await agent.logScreenshot(logScreenshotTask.logScreenshot, {
347
+ content: logScreenshotTask.content || ""
348
+ });
322
349
  } else {
323
350
  throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
324
351
  }
@@ -569,6 +596,94 @@ var replanningCountLimit = 10;
569
596
  var isAndroidPage = (page) => {
570
597
  return page.pageType === "android";
571
598
  };
599
+ var WorkflowMemory = class {
600
+ constructor(config) {
601
+ this.workflows = /* @__PURE__ */ new Map();
602
+ this.config = config;
603
+ }
604
+ /**
605
+ * İş akışı hafızasını getirir
606
+ */
607
+ getWorkflowMemory(workflowId = "default") {
608
+ const workflow = this.workflows.get(workflowId);
609
+ return workflow?.memory || [];
610
+ }
611
+ /**
612
+ * İş akışı verilerini getirir
613
+ */
614
+ getWorkflowData(workflowId = "default") {
615
+ return this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
616
+ }
617
+ /**
618
+ * İş akışı hafızasını kaydeder
619
+ */
620
+ saveWorkflowMemory(memory, workflowId = "default") {
621
+ const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
622
+ workflow.memory = [...memory];
623
+ workflow.metadata.totalSteps = workflow.steps.length;
624
+ workflow.metadata.completedSteps = workflow.steps.filter((s) => s.status === "completed").length;
625
+ workflow.metadata.failedSteps = workflow.steps.filter((s) => s.status === "failed").length;
626
+ this.workflows.set(workflowId, workflow);
627
+ this.enforceRetentionPolicy();
628
+ }
629
+ /**
630
+ * İş akışı bağlamını günceller
631
+ */
632
+ updateWorkflowContext(context, workflowId = "default") {
633
+ const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
634
+ workflow.context = { ...workflow.context, ...context };
635
+ if (context.currentStep) {
636
+ const existingStep = workflow.steps.find((s) => s.stepName === context.currentStep);
637
+ if (!existingStep) {
638
+ workflow.steps.push({
639
+ stepId: `step_${workflow.steps.length + 1}`,
640
+ stepName: context.currentStep,
641
+ timestamp: context.timestamp,
642
+ status: "running",
643
+ memoryItems: []
644
+ });
645
+ }
646
+ }
647
+ this.workflows.set(workflowId, workflow);
648
+ }
649
+ /**
650
+ * İş akışını temizler
651
+ */
652
+ clearWorkflow(workflowId = "default") {
653
+ this.workflows.delete(workflowId);
654
+ }
655
+ /**
656
+ * Tüm iş akışlarını temizler
657
+ */
658
+ clearAll() {
659
+ this.workflows.clear();
660
+ }
661
+ createEmptyWorkflowData(workflowId) {
662
+ return {
663
+ workflowId,
664
+ steps: [],
665
+ memory: [],
666
+ context: {
667
+ pageInfo: { url: "", title: "" },
668
+ timestamp: Date.now()
669
+ },
670
+ metadata: {
671
+ totalSteps: 0,
672
+ completedSteps: 0,
673
+ failedSteps: 0,
674
+ startTime: Date.now()
675
+ }
676
+ };
677
+ }
678
+ enforceRetentionPolicy() {
679
+ const maxWorkflows = 10;
680
+ if (this.workflows.size > maxWorkflows) {
681
+ const sortedWorkflows = Array.from(this.workflows.entries()).sort(([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime));
682
+ const toDelete = sortedWorkflows.slice(maxWorkflows);
683
+ toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
684
+ }
685
+ }
686
+ };
572
687
  var PageTaskExecutor = class {
573
688
  constructor(page, insight, opts) {
574
689
  this.conversationHistory = [];
@@ -576,6 +691,25 @@ var PageTaskExecutor = class {
576
691
  this.insight = insight;
577
692
  this.taskCache = opts.taskCache;
578
693
  this.onTaskStartCallback = opts?.onTaskStart;
694
+ this.memoryConfig = {
695
+ maxItems: 100,
696
+ maxAge: 2 * 60 * 60 * 1e3,
697
+ // 2 saat
698
+ enablePersistence: true,
699
+ enableAnalytics: true,
700
+ filterStrategy: "hybrid",
701
+ ...opts?.memoryConfig
702
+ };
703
+ this.sessionContext = {
704
+ sessionId: opts?.sessionId || this.generateSessionId(),
705
+ workflowId: opts?.workflowId,
706
+ startTime: Date.now(),
707
+ pageInfo: {
708
+ url: "",
709
+ title: ""
710
+ }
711
+ };
712
+ this.workflowMemory = new WorkflowMemory(this.memoryConfig);
579
713
  }
580
714
  async recordScreenshot(timing) {
581
715
  const base64 = await this.page.screenshotBase64();
@@ -788,8 +922,11 @@ var PageTaskExecutor = class {
788
922
  insightDump = dump;
789
923
  };
790
924
  this.insight.onceDumpUpdatedFn = dumpCollector;
925
+ const memoryContext = this.getMemoryAsContext();
791
926
  const assertion = await this.insight.assert(
792
- assertPlan.param.assertion
927
+ assertPlan.param.assertion,
928
+ memoryContext
929
+ // Hafıza bağlamını geç
793
930
  );
794
931
  if (!assertion.pass) {
795
932
  if (plan2.type === "Assert") {
@@ -826,10 +963,10 @@ var PageTaskExecutor = class {
826
963
  if (!taskParam || !taskParam.value) {
827
964
  return;
828
965
  }
829
- await this.page.keyboard.type(taskParam.value);
830
- } else {
831
- await this.page.keyboard.type(taskParam.value);
832
966
  }
967
+ await this.page.keyboard.type(taskParam.value, {
968
+ autoDismissKeyboard: taskParam.autoDismissKeyboard
969
+ });
833
970
  }
834
971
  };
835
972
  tasks.push(taskActionInput);
@@ -858,6 +995,22 @@ var PageTaskExecutor = class {
858
995
  }
859
996
  };
860
997
  tasks.push(taskActionTap);
998
+ } else if (plan2.type === "RightClick") {
999
+ const taskActionRightClick = {
1000
+ type: "Action",
1001
+ subType: "RightClick",
1002
+ thought: plan2.thought,
1003
+ locate: plan2.locate,
1004
+ executor: async (param, { element }) => {
1005
+ assert4(element, "Element not found, cannot right click");
1006
+ await this.page.mouse.click(
1007
+ element.center[0],
1008
+ element.center[1],
1009
+ { button: "right" }
1010
+ );
1011
+ }
1012
+ };
1013
+ tasks.push(taskActionRightClick);
861
1014
  } else if (plan2.type === "Drag") {
862
1015
  const taskActionDrag = {
863
1016
  type: "Action",
@@ -1259,25 +1412,146 @@ var PageTaskExecutor = class {
1259
1412
  };
1260
1413
  return task;
1261
1414
  }
1415
+ /**
1416
+ * Persistent executor'ı getirir veya oluşturur
1417
+ */
1418
+ getPersistentExecutor() {
1419
+ if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
1420
+ const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
1421
+ this.persistentExecutor = new Executor("Persistent Task Executor", {
1422
+ onTaskStart: this.onTaskStartCallback,
1423
+ initialMemory: previousMemory
1424
+ });
1425
+ }
1426
+ return this.persistentExecutor;
1427
+ }
1428
+ /**
1429
+ * Sayfa bağlamını günceller
1430
+ */
1431
+ async updatePageContext() {
1432
+ try {
1433
+ if (this.page.url) {
1434
+ this.sessionContext.pageInfo.url = await this.page.url();
1435
+ }
1436
+ if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
1437
+ this.sessionContext.pageInfo.title = await this.page.title();
1438
+ }
1439
+ } catch (e) {
1440
+ }
1441
+ }
1442
+ /**
1443
+ * Hafızayı temizler
1444
+ */
1445
+ clearMemory() {
1446
+ if (this.persistentExecutor) {
1447
+ this.persistentExecutor.clearMemory();
1448
+ }
1449
+ this.workflowMemory.clearWorkflow(this.sessionContext.workflowId || "default");
1450
+ }
1451
+ /**
1452
+ * Mevcut hafızayı döndürür
1453
+ */
1454
+ getMemory() {
1455
+ return this.persistentExecutor?.getMemory() || [];
1456
+ }
1457
+ /**
1458
+ * İş akışı hafızasını döndürür
1459
+ */
1460
+ getWorkflowMemory() {
1461
+ return this.workflowMemory.getWorkflowData(this.sessionContext.workflowId || "default");
1462
+ }
1463
+ /**
1464
+ * Hafıza istatistiklerini döndürür
1465
+ */
1466
+ getMemoryStats() {
1467
+ return this.persistentExecutor?.getMemoryStats() || {
1468
+ totalItems: 0,
1469
+ analytics: { totalTasks: 0, memoryHits: 0, memoryMisses: 0, averageMemorySize: 0, memoryEffectiveness: 0 },
1470
+ config: this.memoryConfig
1471
+ };
1472
+ }
1473
+ /**
1474
+ * Hafıza konfigürasyonunu günceller
1475
+ */
1476
+ updateMemoryConfig(config) {
1477
+ this.memoryConfig = { ...this.memoryConfig, ...config };
1478
+ if (this.persistentExecutor) {
1479
+ this.persistentExecutor.updateMemoryConfig(this.memoryConfig);
1480
+ }
1481
+ }
1482
+ /**
1483
+ * Oturum ID'sini oluşturur
1484
+ */
1485
+ generateSessionId() {
1486
+ return `session_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
1487
+ }
1488
+ /**
1489
+ * Hafızayı bağlam olarak formatlar
1490
+ */
1491
+ getMemoryAsContext() {
1492
+ const memory = this.getMemory();
1493
+ if (memory.length === 0) {
1494
+ return "";
1495
+ }
1496
+ const recentMemory = memory.slice(-5);
1497
+ return recentMemory.map((item) => `- ${item.summary}`).join("\n");
1498
+ }
1262
1499
  async runPlans(title, plans, opts) {
1263
- const taskExecutor = new Executor(title, {
1264
- onTaskStart: this.onTaskStartCallback
1265
- });
1500
+ await this.updatePageContext();
1501
+ const useMemory = opts?.useMemory !== false;
1502
+ let taskExecutor;
1503
+ if (useMemory) {
1504
+ taskExecutor = this.getPersistentExecutor();
1505
+ this.workflowMemory.updateWorkflowContext({
1506
+ currentStep: title,
1507
+ pageInfo: this.sessionContext.pageInfo,
1508
+ timestamp: Date.now()
1509
+ }, this.sessionContext.workflowId || "default");
1510
+ } else {
1511
+ taskExecutor = new Executor(title, {
1512
+ onTaskStart: this.onTaskStartCallback
1513
+ });
1514
+ }
1266
1515
  const { tasks } = await this.convertPlanToExecutable(plans, opts);
1516
+ tasks.forEach((task) => {
1517
+ task.context = {
1518
+ ...task.context,
1519
+ ...this.sessionContext.pageInfo,
1520
+ workflowId: this.sessionContext.workflowId,
1521
+ sessionId: this.sessionContext.sessionId
1522
+ };
1523
+ });
1267
1524
  await taskExecutor.append(tasks);
1268
1525
  const result = await taskExecutor.flush();
1526
+ if (useMemory) {
1527
+ this.workflowMemory.saveWorkflowMemory(
1528
+ taskExecutor.getMemory(),
1529
+ this.sessionContext.workflowId || "default"
1530
+ );
1531
+ }
1269
1532
  return {
1270
1533
  output: result,
1271
1534
  executor: taskExecutor
1272
1535
  };
1273
1536
  }
1274
1537
  async action(userPrompt, actionContext, opts) {
1275
- const taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
1276
- onTaskStart: this.onTaskStartCallback
1277
- });
1278
- let planningTask = this.planningTaskFromPrompt(userPrompt, void 0, actionContext);
1538
+ const useMemory = true;
1539
+ let taskExecutor;
1540
+ if (useMemory) {
1541
+ taskExecutor = this.getPersistentExecutor();
1542
+ } else {
1543
+ taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
1544
+ onTaskStart: this.onTaskStartCallback
1545
+ });
1546
+ }
1547
+ const memoryContext = this.getMemoryAsContext();
1548
+ const initialLog = memoryContext ? memoryContext : void 0;
1549
+ let planningTask = this.planningTaskFromPrompt(userPrompt, initialLog, actionContext);
1279
1550
  let replanCount = 0;
1280
1551
  const logList = [];
1552
+ if (memoryContext) {
1553
+ logList.push(memoryContext);
1554
+ }
1281
1555
  const yamlFlow = [];
1282
1556
  while (planningTask) {
1283
1557
  if (replanCount > replanningCountLimit) {
@@ -1386,16 +1660,22 @@ var PageTaskExecutor = class {
1386
1660
  executor: taskExecutor
1387
1661
  };
1388
1662
  }
1389
- async createTypeQueryTask(type, demand) {
1390
- const taskExecutor = new Executor(
1391
- taskTitleStr(
1392
- type,
1393
- typeof demand === "string" ? demand : JSON.stringify(demand)
1394
- ),
1395
- {
1396
- onTaskStart: this.onTaskStartCallback
1397
- }
1398
- );
1663
+ async createTypeQueryTask(type, demand, opt) {
1664
+ const useMemory = true;
1665
+ let taskExecutor;
1666
+ if (useMemory) {
1667
+ taskExecutor = this.getPersistentExecutor();
1668
+ } else {
1669
+ taskExecutor = new Executor(
1670
+ taskTitleStr(
1671
+ type,
1672
+ typeof demand === "string" ? demand : JSON.stringify(demand)
1673
+ ),
1674
+ {
1675
+ onTaskStart: this.onTaskStartCallback
1676
+ }
1677
+ );
1678
+ }
1399
1679
  const queryTask = {
1400
1680
  type: "Insight",
1401
1681
  subType: type,
@@ -1417,7 +1697,13 @@ var PageTaskExecutor = class {
1417
1697
  result: `${type}, ${demand}`
1418
1698
  };
1419
1699
  }
1420
- const { data, usage } = await this.insight.extract(demandInput);
1700
+ const memoryContext = this.getMemoryAsContext();
1701
+ const { data, usage } = await this.insight.extract(
1702
+ demandInput,
1703
+ opt,
1704
+ memoryContext
1705
+ // Hafıza bağlamını geç
1706
+ );
1421
1707
  let outputResult = data;
1422
1708
  if (ifTypeRestricted) {
1423
1709
  assert4(data?.result !== void 0, "No result in query data");
@@ -1437,23 +1723,29 @@ var PageTaskExecutor = class {
1437
1723
  executor: taskExecutor
1438
1724
  };
1439
1725
  }
1440
- async query(demand) {
1441
- return this.createTypeQueryTask("Query", demand);
1726
+ async query(demand, opt) {
1727
+ return this.createTypeQueryTask("Query", demand, opt);
1442
1728
  }
1443
- async boolean(prompt) {
1444
- return this.createTypeQueryTask("Boolean", prompt);
1729
+ async boolean(prompt, opt) {
1730
+ return this.createTypeQueryTask("Boolean", prompt, opt);
1445
1731
  }
1446
- async number(prompt) {
1447
- return this.createTypeQueryTask("Number", prompt);
1732
+ async number(prompt, opt) {
1733
+ return this.createTypeQueryTask("Number", prompt, opt);
1448
1734
  }
1449
- async string(prompt) {
1450
- return this.createTypeQueryTask("String", prompt);
1735
+ async string(prompt, opt) {
1736
+ return this.createTypeQueryTask("String", prompt, opt);
1451
1737
  }
1452
- async assert(assertion) {
1738
+ async assert(assertion, memoryContext) {
1453
1739
  const description = `assert: ${assertion}`;
1454
- const taskExecutor = new Executor(taskTitleStr("Assert", description), {
1455
- onTaskStart: this.onTaskStartCallback
1456
- });
1740
+ const useMemory = true;
1741
+ let taskExecutor;
1742
+ if (useMemory) {
1743
+ taskExecutor = this.getPersistentExecutor();
1744
+ } else {
1745
+ taskExecutor = new Executor(taskTitleStr("Assert", description), {
1746
+ onTaskStart: this.onTaskStartCallback
1747
+ });
1748
+ }
1457
1749
  const assertionPlan = {
1458
1750
  type: "Assert",
1459
1751
  param: {
@@ -1583,7 +1875,7 @@ function buildPlans(type, locateParam, param) {
1583
1875
  param: locateParam,
1584
1876
  thought: ""
1585
1877
  } : null;
1586
- if (type === "Tap" || type === "Hover") {
1878
+ if (type === "Tap" || type === "Hover" || type === "RightClick") {
1587
1879
  assert5(locateParam, `missing locate info for action "${type}"`);
1588
1880
  assert5(locatePlan, `missing locate info for action "${type}"`);
1589
1881
  const tapPlan = {
@@ -1654,8 +1946,8 @@ function buildPlans(type, locateParam, param) {
1654
1946
 
1655
1947
  // src/common/task-cache.ts
1656
1948
  import assert6 from "assert";
1657
- import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
1658
- import { join as join2 } from "path";
1949
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
1950
+ import { dirname as dirname2, join as join2 } from "path";
1659
1951
  import { getMidsceneRunSubDir as getMidsceneRunSubDir2 } from "misoai-shared/common";
1660
1952
  import { getDebug as getDebug3 } from "misoai-shared/logger";
1661
1953
  import { ifInBrowser as ifInBrowser2 } from "misoai-shared/utils";
@@ -1663,7 +1955,7 @@ import yaml3 from "js-yaml";
1663
1955
  import semver from "semver";
1664
1956
 
1665
1957
  // package.json
1666
- var version = "1.5.6";
1958
+ var version = "1.5.7";
1667
1959
 
1668
1960
  // src/common/task-cache.ts
1669
1961
  var debug3 = getDebug3("cache");
@@ -1794,8 +2086,14 @@ cache file: ${cacheFile}`
1794
2086
  return;
1795
2087
  }
1796
2088
  try {
2089
+ const dir = dirname2(this.cacheFilePath);
2090
+ if (!existsSync2(dir)) {
2091
+ mkdirSync2(dir, { recursive: true });
2092
+ debug3("created cache directory: %s", dir);
2093
+ }
1797
2094
  const yamlData = yaml3.dump(this.cache);
1798
2095
  writeFileSync2(this.cacheFilePath, yamlData);
2096
+ debug3("cache flushed to file: %s", this.cacheFilePath);
1799
2097
  } catch (err) {
1800
2098
  debug3(
1801
2099
  "write cache to file failed, path: %s, error: %s",
@@ -2053,6 +2351,23 @@ var PageAgent = class {
2053
2351
  metadata
2054
2352
  };
2055
2353
  }
2354
+ async aiRightClick(locatePrompt, opt) {
2355
+ const detailedLocateParam = this.buildDetailedLocateParam(
2356
+ locatePrompt,
2357
+ opt
2358
+ );
2359
+ const plans = buildPlans("RightClick", detailedLocateParam);
2360
+ const { executor, output } = await this.taskExecutor.runPlans(
2361
+ taskTitleStr("RightClick", locateParamStr(detailedLocateParam)),
2362
+ plans,
2363
+ { cacheable: opt?.cacheable }
2364
+ );
2365
+ const metadata = this.afterTaskRunning(executor);
2366
+ return {
2367
+ result: output,
2368
+ metadata
2369
+ };
2370
+ }
2056
2371
  async aiInput(value, locatePrompt, opt) {
2057
2372
  assert7(
2058
2373
  typeof value === "string",
@@ -2127,7 +2442,13 @@ var PageAgent = class {
2127
2442
  metadata: metadata2
2128
2443
  };
2129
2444
  }
2130
- const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, this.opts.aiActionContext, {
2445
+ const memoryContext = this.getMemoryAsContext();
2446
+ const enhancedActionContext = this.opts.aiActionContext ? `${this.opts.aiActionContext}
2447
+
2448
+ Previous workflow steps:
2449
+ ${memoryContext}` : memoryContext ? `Previous workflow steps:
2450
+ ${memoryContext}` : void 0;
2451
+ const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, enhancedActionContext, {
2131
2452
  cacheable
2132
2453
  }));
2133
2454
  if (this.taskCache && output?.yamlFlow && cacheable !== false) {
@@ -2273,8 +2594,9 @@ var PageAgent = class {
2273
2594
  } catch (e) {
2274
2595
  }
2275
2596
  }
2597
+ const memoryContext = this.getMemoryAsContext();
2276
2598
  const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2277
- const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
2599
+ const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
2278
2600
  const metadata = this.afterTaskRunning(executor, true);
2279
2601
  if (output && opt?.keepRawResponse) {
2280
2602
  return {
@@ -2484,9 +2806,72 @@ ${errors}`);
2484
2806
  }
2485
2807
  throw new Error("evaluateJavaScript is not supported in current agent");
2486
2808
  }
2809
+ async logScreenshot(title, options) {
2810
+ const screenshotTitle = title || "untitled";
2811
+ const content = options?.content || "";
2812
+ const screenshot = await this.page.screenshotBase64?.();
2813
+ if (screenshot) {
2814
+ const executionDump = {
2815
+ name: screenshotTitle,
2816
+ description: content,
2817
+ tasks: [{
2818
+ type: "Screenshot",
2819
+ subType: "log",
2820
+ status: "finished",
2821
+ executor: null,
2822
+ param: {
2823
+ title: screenshotTitle,
2824
+ content
2825
+ },
2826
+ output: {
2827
+ screenshot
2828
+ },
2829
+ thought: `Logged screenshot: ${screenshotTitle}`,
2830
+ timing: {
2831
+ start: Date.now(),
2832
+ end: Date.now(),
2833
+ cost: 0
2834
+ }
2835
+ }],
2836
+ sdkVersion: "1.0.0",
2837
+ logTime: Date.now(),
2838
+ model_name: "screenshot"
2839
+ };
2840
+ this.appendExecutionDump(executionDump);
2841
+ }
2842
+ }
2487
2843
  async destroy() {
2488
2844
  await this.page.destroy();
2489
2845
  }
2846
+ /**
2847
+ * Hafızayı bağlam olarak formatlar
2848
+ */
2849
+ getMemoryAsContext() {
2850
+ const memory = this.taskExecutor.getMemory();
2851
+ if (memory.length === 0) {
2852
+ return "";
2853
+ }
2854
+ const recentMemory = memory.slice(-5);
2855
+ return recentMemory.map((item) => `- ${item.summary}`).join("\n");
2856
+ }
2857
+ /**
2858
+ * Mevcut hafızayı döndürür
2859
+ */
2860
+ getMemory() {
2861
+ return this.taskExecutor.getMemory();
2862
+ }
2863
+ /**
2864
+ * Hafıza istatistiklerini döndürür
2865
+ */
2866
+ getMemoryStats() {
2867
+ return this.taskExecutor.getMemoryStats();
2868
+ }
2869
+ /**
2870
+ * Hafızayı temizler
2871
+ */
2872
+ clearMemory() {
2873
+ this.taskExecutor.clearMemory();
2874
+ }
2490
2875
  };
2491
2876
 
2492
2877
  // src/playground/agent.ts