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.
- package/dist/es/agent.js +429 -44
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +10 -9
- package/dist/es/bridge-mode-browser.js.map +1 -1
- package/dist/es/bridge-mode.js +431 -46
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +437 -51
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +445 -44
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +429 -44
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/midscene-server.js.map +1 -1
- package/dist/es/playground.js +429 -44
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright-report.js +1 -1
- package/dist/es/playwright-report.js.map +1 -1
- package/dist/es/playwright.js +445 -44
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +429 -44
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +429 -44
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/es/ui-utils.js.map +1 -1
- package/dist/es/utils.js +7 -4
- package/dist/es/utils.js.map +1 -1
- package/dist/es/yaml.js +24 -0
- package/dist/es/yaml.js.map +1 -1
- package/dist/lib/agent.js +427 -42
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +10 -9
- package/dist/lib/bridge-mode-browser.js.map +1 -1
- package/dist/lib/bridge-mode.js +429 -44
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +435 -49
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +443 -42
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +427 -42
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/midscene-server.js.map +1 -1
- package/dist/lib/playground.js +427 -42
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright-report.js +1 -1
- package/dist/lib/playwright-report.js.map +1 -1
- package/dist/lib/playwright.js +443 -42
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +427 -42
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +427 -42
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/lib/ui-utils.js.map +1 -1
- package/dist/lib/utils.js +7 -4
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/yaml.js +24 -0
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent.d.ts +101 -8
- package/dist/types/bridge-mode-browser.d.ts +2 -3
- package/dist/types/bridge-mode.d.ts +2 -3
- package/dist/types/{browser-aec1055d.d.ts → browser-9b472ffb.d.ts} +1 -1
- package/dist/types/chrome-extension.d.ts +2 -3
- package/dist/types/index.d.ts +1 -2
- package/dist/types/midscene-server.d.ts +1 -2
- package/dist/types/{page-86ab0fe1.d.ts → page-ed0ecb44.d.ts} +19 -9
- package/dist/types/playground.d.ts +2 -3
- package/dist/types/playwright.d.ts +9 -2
- package/dist/types/puppeteer-agent-launcher.d.ts +1 -2
- package/dist/types/puppeteer.d.ts +6 -5
- package/dist/types/ui-utils.d.ts +1 -1
- package/dist/types/utils.d.ts +1 -2
- package/dist/types/yaml.d.ts +1 -2
- package/iife-script/htmlElement.js +51 -73
- package/iife-script/htmlElementDebug.js +33 -54
- package/package.json +23 -23
- package/LICENSE +0 -21
package/dist/es/puppeteer.js
CHANGED
@@ -105,6 +105,10 @@ var ScriptPlayer = class {
|
|
105
105
|
} else if ("aiQuery" in flowItem) {
|
106
106
|
const queryTask = flowItem;
|
107
107
|
const prompt = queryTask.aiQuery;
|
108
|
+
const options = {
|
109
|
+
domIncluded: queryTask.domIncluded,
|
110
|
+
screenshotIncluded: queryTask.screenshotIncluded
|
111
|
+
};
|
108
112
|
assert(prompt, "missing prompt for aiQuery");
|
109
113
|
assert(
|
110
114
|
typeof prompt === "string",
|
@@ -115,6 +119,10 @@ var ScriptPlayer = class {
|
|
115
119
|
} else if ("aiNumber" in flowItem) {
|
116
120
|
const numberTask = flowItem;
|
117
121
|
const prompt = numberTask.aiNumber;
|
122
|
+
const options = {
|
123
|
+
domIncluded: numberTask.domIncluded,
|
124
|
+
screenshotIncluded: numberTask.screenshotIncluded
|
125
|
+
};
|
118
126
|
assert(prompt, "missing prompt for number");
|
119
127
|
assert(
|
120
128
|
typeof prompt === "string",
|
@@ -125,6 +133,10 @@ var ScriptPlayer = class {
|
|
125
133
|
} else if ("aiString" in flowItem) {
|
126
134
|
const stringTask = flowItem;
|
127
135
|
const prompt = stringTask.aiString;
|
136
|
+
const options = {
|
137
|
+
domIncluded: stringTask.domIncluded,
|
138
|
+
screenshotIncluded: stringTask.screenshotIncluded
|
139
|
+
};
|
128
140
|
assert(prompt, "missing prompt for string");
|
129
141
|
assert(
|
130
142
|
typeof prompt === "string",
|
@@ -135,6 +147,10 @@ var ScriptPlayer = class {
|
|
135
147
|
} else if ("aiBoolean" in flowItem) {
|
136
148
|
const booleanTask = flowItem;
|
137
149
|
const prompt = booleanTask.aiBoolean;
|
150
|
+
const options = {
|
151
|
+
domIncluded: booleanTask.domIncluded,
|
152
|
+
screenshotIncluded: booleanTask.screenshotIncluded
|
153
|
+
};
|
138
154
|
assert(prompt, "missing prompt for boolean");
|
139
155
|
assert(
|
140
156
|
typeof prompt === "string",
|
@@ -177,6 +193,9 @@ var ScriptPlayer = class {
|
|
177
193
|
} else if ("aiTap" in flowItem) {
|
178
194
|
const tapTask = flowItem;
|
179
195
|
await agent.aiTap(tapTask.aiTap, tapTask);
|
196
|
+
} else if ("aiRightClick" in flowItem) {
|
197
|
+
const rightClickTask = flowItem;
|
198
|
+
await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
|
180
199
|
} else if ("aiHover" in flowItem) {
|
181
200
|
const hoverTask = flowItem;
|
182
201
|
await agent.aiHover(hoverTask.aiHover, hoverTask);
|
@@ -199,6 +218,11 @@ var ScriptPlayer = class {
|
|
199
218
|
evaluateJavaScriptTask.javascript
|
200
219
|
);
|
201
220
|
this.setResult(evaluateJavaScriptTask.name, result);
|
221
|
+
} else if ("logScreenshot" in flowItem) {
|
222
|
+
const logScreenshotTask = flowItem;
|
223
|
+
await agent.logScreenshot(logScreenshotTask.logScreenshot, {
|
224
|
+
content: logScreenshotTask.content || ""
|
225
|
+
});
|
202
226
|
} else {
|
203
227
|
throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
|
204
228
|
}
|
@@ -467,7 +491,8 @@ var WebElementInfo = class {
|
|
467
491
|
id,
|
468
492
|
attributes,
|
469
493
|
indexId,
|
470
|
-
xpaths
|
494
|
+
xpaths,
|
495
|
+
isVisible
|
471
496
|
}) {
|
472
497
|
this.content = content;
|
473
498
|
this.rect = rect;
|
@@ -480,6 +505,7 @@ var WebElementInfo = class {
|
|
480
505
|
this.attributes = attributes;
|
481
506
|
this.indexId = indexId;
|
482
507
|
this.xpaths = xpaths;
|
508
|
+
this.isVisible = isVisible;
|
483
509
|
}
|
484
510
|
};
|
485
511
|
|
@@ -502,14 +528,15 @@ async function parseContextFromWebPage(page, _opt) {
|
|
502
528
|
})
|
503
529
|
]);
|
504
530
|
const webTree = traverseTree(tree, (elementInfo) => {
|
505
|
-
const { rect, id, content, attributes, locator, indexId } = elementInfo;
|
531
|
+
const { rect, id, content, attributes, locator, indexId, isVisible } = elementInfo;
|
506
532
|
return new WebElementInfo({
|
507
533
|
rect,
|
508
534
|
locator,
|
509
535
|
id,
|
510
536
|
content,
|
511
537
|
attributes,
|
512
|
-
indexId
|
538
|
+
indexId,
|
539
|
+
isVisible
|
513
540
|
});
|
514
541
|
});
|
515
542
|
assert3(screenshotBase64, "screenshotBase64 is required");
|
@@ -539,7 +566,7 @@ function printReportMsg(filepath) {
|
|
539
566
|
logMsg(`Midscene - report file updated: ${filepath}`);
|
540
567
|
}
|
541
568
|
function replaceIllegalPathCharsAndSpace(str) {
|
542
|
-
return str.replace(/[
|
569
|
+
return str.replace(/[:*?"<>| ]/g, "-");
|
543
570
|
}
|
544
571
|
function forceClosePopup(page, debug6) {
|
545
572
|
page.on("popup", async (popup) => {
|
@@ -596,6 +623,94 @@ var replanningCountLimit = 10;
|
|
596
623
|
var isAndroidPage = (page) => {
|
597
624
|
return page.pageType === "android";
|
598
625
|
};
|
626
|
+
var WorkflowMemory = class {
|
627
|
+
constructor(config) {
|
628
|
+
this.workflows = /* @__PURE__ */ new Map();
|
629
|
+
this.config = config;
|
630
|
+
}
|
631
|
+
/**
|
632
|
+
* İş akışı hafızasını getirir
|
633
|
+
*/
|
634
|
+
getWorkflowMemory(workflowId = "default") {
|
635
|
+
const workflow = this.workflows.get(workflowId);
|
636
|
+
return workflow?.memory || [];
|
637
|
+
}
|
638
|
+
/**
|
639
|
+
* İş akışı verilerini getirir
|
640
|
+
*/
|
641
|
+
getWorkflowData(workflowId = "default") {
|
642
|
+
return this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
643
|
+
}
|
644
|
+
/**
|
645
|
+
* İş akışı hafızasını kaydeder
|
646
|
+
*/
|
647
|
+
saveWorkflowMemory(memory, workflowId = "default") {
|
648
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
649
|
+
workflow.memory = [...memory];
|
650
|
+
workflow.metadata.totalSteps = workflow.steps.length;
|
651
|
+
workflow.metadata.completedSteps = workflow.steps.filter((s) => s.status === "completed").length;
|
652
|
+
workflow.metadata.failedSteps = workflow.steps.filter((s) => s.status === "failed").length;
|
653
|
+
this.workflows.set(workflowId, workflow);
|
654
|
+
this.enforceRetentionPolicy();
|
655
|
+
}
|
656
|
+
/**
|
657
|
+
* İş akışı bağlamını günceller
|
658
|
+
*/
|
659
|
+
updateWorkflowContext(context, workflowId = "default") {
|
660
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
661
|
+
workflow.context = { ...workflow.context, ...context };
|
662
|
+
if (context.currentStep) {
|
663
|
+
const existingStep = workflow.steps.find((s) => s.stepName === context.currentStep);
|
664
|
+
if (!existingStep) {
|
665
|
+
workflow.steps.push({
|
666
|
+
stepId: `step_${workflow.steps.length + 1}`,
|
667
|
+
stepName: context.currentStep,
|
668
|
+
timestamp: context.timestamp,
|
669
|
+
status: "running",
|
670
|
+
memoryItems: []
|
671
|
+
});
|
672
|
+
}
|
673
|
+
}
|
674
|
+
this.workflows.set(workflowId, workflow);
|
675
|
+
}
|
676
|
+
/**
|
677
|
+
* İş akışını temizler
|
678
|
+
*/
|
679
|
+
clearWorkflow(workflowId = "default") {
|
680
|
+
this.workflows.delete(workflowId);
|
681
|
+
}
|
682
|
+
/**
|
683
|
+
* Tüm iş akışlarını temizler
|
684
|
+
*/
|
685
|
+
clearAll() {
|
686
|
+
this.workflows.clear();
|
687
|
+
}
|
688
|
+
createEmptyWorkflowData(workflowId) {
|
689
|
+
return {
|
690
|
+
workflowId,
|
691
|
+
steps: [],
|
692
|
+
memory: [],
|
693
|
+
context: {
|
694
|
+
pageInfo: { url: "", title: "" },
|
695
|
+
timestamp: Date.now()
|
696
|
+
},
|
697
|
+
metadata: {
|
698
|
+
totalSteps: 0,
|
699
|
+
completedSteps: 0,
|
700
|
+
failedSteps: 0,
|
701
|
+
startTime: Date.now()
|
702
|
+
}
|
703
|
+
};
|
704
|
+
}
|
705
|
+
enforceRetentionPolicy() {
|
706
|
+
const maxWorkflows = 10;
|
707
|
+
if (this.workflows.size > maxWorkflows) {
|
708
|
+
const sortedWorkflows = Array.from(this.workflows.entries()).sort(([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime));
|
709
|
+
const toDelete = sortedWorkflows.slice(maxWorkflows);
|
710
|
+
toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
|
711
|
+
}
|
712
|
+
}
|
713
|
+
};
|
599
714
|
var PageTaskExecutor = class {
|
600
715
|
constructor(page, insight, opts) {
|
601
716
|
this.conversationHistory = [];
|
@@ -603,6 +718,25 @@ var PageTaskExecutor = class {
|
|
603
718
|
this.insight = insight;
|
604
719
|
this.taskCache = opts.taskCache;
|
605
720
|
this.onTaskStartCallback = opts?.onTaskStart;
|
721
|
+
this.memoryConfig = {
|
722
|
+
maxItems: 100,
|
723
|
+
maxAge: 2 * 60 * 60 * 1e3,
|
724
|
+
// 2 saat
|
725
|
+
enablePersistence: true,
|
726
|
+
enableAnalytics: true,
|
727
|
+
filterStrategy: "hybrid",
|
728
|
+
...opts?.memoryConfig
|
729
|
+
};
|
730
|
+
this.sessionContext = {
|
731
|
+
sessionId: opts?.sessionId || this.generateSessionId(),
|
732
|
+
workflowId: opts?.workflowId,
|
733
|
+
startTime: Date.now(),
|
734
|
+
pageInfo: {
|
735
|
+
url: "",
|
736
|
+
title: ""
|
737
|
+
}
|
738
|
+
};
|
739
|
+
this.workflowMemory = new WorkflowMemory(this.memoryConfig);
|
606
740
|
}
|
607
741
|
async recordScreenshot(timing) {
|
608
742
|
const base64 = await this.page.screenshotBase64();
|
@@ -815,8 +949,11 @@ var PageTaskExecutor = class {
|
|
815
949
|
insightDump = dump;
|
816
950
|
};
|
817
951
|
this.insight.onceDumpUpdatedFn = dumpCollector;
|
952
|
+
const memoryContext = this.getMemoryAsContext();
|
818
953
|
const assertion = await this.insight.assert(
|
819
|
-
assertPlan.param.assertion
|
954
|
+
assertPlan.param.assertion,
|
955
|
+
memoryContext
|
956
|
+
// Hafıza bağlamını geç
|
820
957
|
);
|
821
958
|
if (!assertion.pass) {
|
822
959
|
if (plan2.type === "Assert") {
|
@@ -853,10 +990,10 @@ var PageTaskExecutor = class {
|
|
853
990
|
if (!taskParam || !taskParam.value) {
|
854
991
|
return;
|
855
992
|
}
|
856
|
-
await this.page.keyboard.type(taskParam.value);
|
857
|
-
} else {
|
858
|
-
await this.page.keyboard.type(taskParam.value);
|
859
993
|
}
|
994
|
+
await this.page.keyboard.type(taskParam.value, {
|
995
|
+
autoDismissKeyboard: taskParam.autoDismissKeyboard
|
996
|
+
});
|
860
997
|
}
|
861
998
|
};
|
862
999
|
tasks.push(taskActionInput);
|
@@ -885,6 +1022,22 @@ var PageTaskExecutor = class {
|
|
885
1022
|
}
|
886
1023
|
};
|
887
1024
|
tasks.push(taskActionTap);
|
1025
|
+
} else if (plan2.type === "RightClick") {
|
1026
|
+
const taskActionRightClick = {
|
1027
|
+
type: "Action",
|
1028
|
+
subType: "RightClick",
|
1029
|
+
thought: plan2.thought,
|
1030
|
+
locate: plan2.locate,
|
1031
|
+
executor: async (param, { element }) => {
|
1032
|
+
assert4(element, "Element not found, cannot right click");
|
1033
|
+
await this.page.mouse.click(
|
1034
|
+
element.center[0],
|
1035
|
+
element.center[1],
|
1036
|
+
{ button: "right" }
|
1037
|
+
);
|
1038
|
+
}
|
1039
|
+
};
|
1040
|
+
tasks.push(taskActionRightClick);
|
888
1041
|
} else if (plan2.type === "Drag") {
|
889
1042
|
const taskActionDrag = {
|
890
1043
|
type: "Action",
|
@@ -1286,25 +1439,146 @@ var PageTaskExecutor = class {
|
|
1286
1439
|
};
|
1287
1440
|
return task;
|
1288
1441
|
}
|
1442
|
+
/**
|
1443
|
+
* Persistent executor'ı getirir veya oluşturur
|
1444
|
+
*/
|
1445
|
+
getPersistentExecutor() {
|
1446
|
+
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1447
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
|
1448
|
+
this.persistentExecutor = new Executor("Persistent Task Executor", {
|
1449
|
+
onTaskStart: this.onTaskStartCallback,
|
1450
|
+
initialMemory: previousMemory
|
1451
|
+
});
|
1452
|
+
}
|
1453
|
+
return this.persistentExecutor;
|
1454
|
+
}
|
1455
|
+
/**
|
1456
|
+
* Sayfa bağlamını günceller
|
1457
|
+
*/
|
1458
|
+
async updatePageContext() {
|
1459
|
+
try {
|
1460
|
+
if (this.page.url) {
|
1461
|
+
this.sessionContext.pageInfo.url = await this.page.url();
|
1462
|
+
}
|
1463
|
+
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1464
|
+
this.sessionContext.pageInfo.title = await this.page.title();
|
1465
|
+
}
|
1466
|
+
} catch (e) {
|
1467
|
+
}
|
1468
|
+
}
|
1469
|
+
/**
|
1470
|
+
* Hafızayı temizler
|
1471
|
+
*/
|
1472
|
+
clearMemory() {
|
1473
|
+
if (this.persistentExecutor) {
|
1474
|
+
this.persistentExecutor.clearMemory();
|
1475
|
+
}
|
1476
|
+
this.workflowMemory.clearWorkflow(this.sessionContext.workflowId || "default");
|
1477
|
+
}
|
1478
|
+
/**
|
1479
|
+
* Mevcut hafızayı döndürür
|
1480
|
+
*/
|
1481
|
+
getMemory() {
|
1482
|
+
return this.persistentExecutor?.getMemory() || [];
|
1483
|
+
}
|
1484
|
+
/**
|
1485
|
+
* İş akışı hafızasını döndürür
|
1486
|
+
*/
|
1487
|
+
getWorkflowMemory() {
|
1488
|
+
return this.workflowMemory.getWorkflowData(this.sessionContext.workflowId || "default");
|
1489
|
+
}
|
1490
|
+
/**
|
1491
|
+
* Hafıza istatistiklerini döndürür
|
1492
|
+
*/
|
1493
|
+
getMemoryStats() {
|
1494
|
+
return this.persistentExecutor?.getMemoryStats() || {
|
1495
|
+
totalItems: 0,
|
1496
|
+
analytics: { totalTasks: 0, memoryHits: 0, memoryMisses: 0, averageMemorySize: 0, memoryEffectiveness: 0 },
|
1497
|
+
config: this.memoryConfig
|
1498
|
+
};
|
1499
|
+
}
|
1500
|
+
/**
|
1501
|
+
* Hafıza konfigürasyonunu günceller
|
1502
|
+
*/
|
1503
|
+
updateMemoryConfig(config) {
|
1504
|
+
this.memoryConfig = { ...this.memoryConfig, ...config };
|
1505
|
+
if (this.persistentExecutor) {
|
1506
|
+
this.persistentExecutor.updateMemoryConfig(this.memoryConfig);
|
1507
|
+
}
|
1508
|
+
}
|
1509
|
+
/**
|
1510
|
+
* Oturum ID'sini oluşturur
|
1511
|
+
*/
|
1512
|
+
generateSessionId() {
|
1513
|
+
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
1514
|
+
}
|
1515
|
+
/**
|
1516
|
+
* Hafızayı bağlam olarak formatlar
|
1517
|
+
*/
|
1518
|
+
getMemoryAsContext() {
|
1519
|
+
const memory = this.getMemory();
|
1520
|
+
if (memory.length === 0) {
|
1521
|
+
return "";
|
1522
|
+
}
|
1523
|
+
const recentMemory = memory.slice(-5);
|
1524
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
1525
|
+
}
|
1289
1526
|
async runPlans(title, plans, opts) {
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1527
|
+
await this.updatePageContext();
|
1528
|
+
const useMemory = opts?.useMemory !== false;
|
1529
|
+
let taskExecutor;
|
1530
|
+
if (useMemory) {
|
1531
|
+
taskExecutor = this.getPersistentExecutor();
|
1532
|
+
this.workflowMemory.updateWorkflowContext({
|
1533
|
+
currentStep: title,
|
1534
|
+
pageInfo: this.sessionContext.pageInfo,
|
1535
|
+
timestamp: Date.now()
|
1536
|
+
}, this.sessionContext.workflowId || "default");
|
1537
|
+
} else {
|
1538
|
+
taskExecutor = new Executor(title, {
|
1539
|
+
onTaskStart: this.onTaskStartCallback
|
1540
|
+
});
|
1541
|
+
}
|
1293
1542
|
const { tasks } = await this.convertPlanToExecutable(plans, opts);
|
1543
|
+
tasks.forEach((task) => {
|
1544
|
+
task.context = {
|
1545
|
+
...task.context,
|
1546
|
+
...this.sessionContext.pageInfo,
|
1547
|
+
workflowId: this.sessionContext.workflowId,
|
1548
|
+
sessionId: this.sessionContext.sessionId
|
1549
|
+
};
|
1550
|
+
});
|
1294
1551
|
await taskExecutor.append(tasks);
|
1295
1552
|
const result = await taskExecutor.flush();
|
1553
|
+
if (useMemory) {
|
1554
|
+
this.workflowMemory.saveWorkflowMemory(
|
1555
|
+
taskExecutor.getMemory(),
|
1556
|
+
this.sessionContext.workflowId || "default"
|
1557
|
+
);
|
1558
|
+
}
|
1296
1559
|
return {
|
1297
1560
|
output: result,
|
1298
1561
|
executor: taskExecutor
|
1299
1562
|
};
|
1300
1563
|
}
|
1301
1564
|
async action(userPrompt, actionContext, opts) {
|
1302
|
-
const
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1565
|
+
const useMemory = true;
|
1566
|
+
let taskExecutor;
|
1567
|
+
if (useMemory) {
|
1568
|
+
taskExecutor = this.getPersistentExecutor();
|
1569
|
+
} else {
|
1570
|
+
taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
|
1571
|
+
onTaskStart: this.onTaskStartCallback
|
1572
|
+
});
|
1573
|
+
}
|
1574
|
+
const memoryContext = this.getMemoryAsContext();
|
1575
|
+
const initialLog = memoryContext ? memoryContext : void 0;
|
1576
|
+
let planningTask = this.planningTaskFromPrompt(userPrompt, initialLog, actionContext);
|
1306
1577
|
let replanCount = 0;
|
1307
1578
|
const logList = [];
|
1579
|
+
if (memoryContext) {
|
1580
|
+
logList.push(memoryContext);
|
1581
|
+
}
|
1308
1582
|
const yamlFlow = [];
|
1309
1583
|
while (planningTask) {
|
1310
1584
|
if (replanCount > replanningCountLimit) {
|
@@ -1413,16 +1687,22 @@ var PageTaskExecutor = class {
|
|
1413
1687
|
executor: taskExecutor
|
1414
1688
|
};
|
1415
1689
|
}
|
1416
|
-
async createTypeQueryTask(type, demand) {
|
1417
|
-
const
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1690
|
+
async createTypeQueryTask(type, demand, opt) {
|
1691
|
+
const useMemory = true;
|
1692
|
+
let taskExecutor;
|
1693
|
+
if (useMemory) {
|
1694
|
+
taskExecutor = this.getPersistentExecutor();
|
1695
|
+
} else {
|
1696
|
+
taskExecutor = new Executor(
|
1697
|
+
taskTitleStr(
|
1698
|
+
type,
|
1699
|
+
typeof demand === "string" ? demand : JSON.stringify(demand)
|
1700
|
+
),
|
1701
|
+
{
|
1702
|
+
onTaskStart: this.onTaskStartCallback
|
1703
|
+
}
|
1704
|
+
);
|
1705
|
+
}
|
1426
1706
|
const queryTask = {
|
1427
1707
|
type: "Insight",
|
1428
1708
|
subType: type,
|
@@ -1444,7 +1724,13 @@ var PageTaskExecutor = class {
|
|
1444
1724
|
result: `${type}, ${demand}`
|
1445
1725
|
};
|
1446
1726
|
}
|
1447
|
-
const
|
1727
|
+
const memoryContext = this.getMemoryAsContext();
|
1728
|
+
const { data, usage } = await this.insight.extract(
|
1729
|
+
demandInput,
|
1730
|
+
opt,
|
1731
|
+
memoryContext
|
1732
|
+
// Hafıza bağlamını geç
|
1733
|
+
);
|
1448
1734
|
let outputResult = data;
|
1449
1735
|
if (ifTypeRestricted) {
|
1450
1736
|
assert4(data?.result !== void 0, "No result in query data");
|
@@ -1464,23 +1750,29 @@ var PageTaskExecutor = class {
|
|
1464
1750
|
executor: taskExecutor
|
1465
1751
|
};
|
1466
1752
|
}
|
1467
|
-
async query(demand) {
|
1468
|
-
return this.createTypeQueryTask("Query", demand);
|
1753
|
+
async query(demand, opt) {
|
1754
|
+
return this.createTypeQueryTask("Query", demand, opt);
|
1469
1755
|
}
|
1470
|
-
async boolean(prompt) {
|
1471
|
-
return this.createTypeQueryTask("Boolean", prompt);
|
1756
|
+
async boolean(prompt, opt) {
|
1757
|
+
return this.createTypeQueryTask("Boolean", prompt, opt);
|
1472
1758
|
}
|
1473
|
-
async number(prompt) {
|
1474
|
-
return this.createTypeQueryTask("Number", prompt);
|
1759
|
+
async number(prompt, opt) {
|
1760
|
+
return this.createTypeQueryTask("Number", prompt, opt);
|
1475
1761
|
}
|
1476
|
-
async string(prompt) {
|
1477
|
-
return this.createTypeQueryTask("String", prompt);
|
1762
|
+
async string(prompt, opt) {
|
1763
|
+
return this.createTypeQueryTask("String", prompt, opt);
|
1478
1764
|
}
|
1479
|
-
async assert(assertion) {
|
1765
|
+
async assert(assertion, memoryContext) {
|
1480
1766
|
const description = `assert: ${assertion}`;
|
1481
|
-
const
|
1482
|
-
|
1483
|
-
|
1767
|
+
const useMemory = true;
|
1768
|
+
let taskExecutor;
|
1769
|
+
if (useMemory) {
|
1770
|
+
taskExecutor = this.getPersistentExecutor();
|
1771
|
+
} else {
|
1772
|
+
taskExecutor = new Executor(taskTitleStr("Assert", description), {
|
1773
|
+
onTaskStart: this.onTaskStartCallback
|
1774
|
+
});
|
1775
|
+
}
|
1484
1776
|
const assertionPlan = {
|
1485
1777
|
type: "Assert",
|
1486
1778
|
param: {
|
@@ -1610,7 +1902,7 @@ function buildPlans(type, locateParam, param) {
|
|
1610
1902
|
param: locateParam,
|
1611
1903
|
thought: ""
|
1612
1904
|
} : null;
|
1613
|
-
if (type === "Tap" || type === "Hover") {
|
1905
|
+
if (type === "Tap" || type === "Hover" || type === "RightClick") {
|
1614
1906
|
assert5(locateParam, `missing locate info for action "${type}"`);
|
1615
1907
|
assert5(locatePlan, `missing locate info for action "${type}"`);
|
1616
1908
|
const tapPlan = {
|
@@ -1681,8 +1973,8 @@ function buildPlans(type, locateParam, param) {
|
|
1681
1973
|
|
1682
1974
|
// src/common/task-cache.ts
|
1683
1975
|
import assert6 from "assert";
|
1684
|
-
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
1685
|
-
import { join as join2 } from "path";
|
1976
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
1977
|
+
import { dirname as dirname2, join as join2 } from "path";
|
1686
1978
|
import { getMidsceneRunSubDir as getMidsceneRunSubDir2 } from "misoai-shared/common";
|
1687
1979
|
import { getDebug as getDebug3 } from "misoai-shared/logger";
|
1688
1980
|
import { ifInBrowser as ifInBrowser2 } from "misoai-shared/utils";
|
@@ -1690,7 +1982,7 @@ import yaml3 from "js-yaml";
|
|
1690
1982
|
import semver from "semver";
|
1691
1983
|
|
1692
1984
|
// package.json
|
1693
|
-
var version = "1.5.
|
1985
|
+
var version = "1.5.7";
|
1694
1986
|
|
1695
1987
|
// src/common/task-cache.ts
|
1696
1988
|
var debug3 = getDebug3("cache");
|
@@ -1821,8 +2113,14 @@ cache file: ${cacheFile}`
|
|
1821
2113
|
return;
|
1822
2114
|
}
|
1823
2115
|
try {
|
2116
|
+
const dir = dirname2(this.cacheFilePath);
|
2117
|
+
if (!existsSync2(dir)) {
|
2118
|
+
mkdirSync2(dir, { recursive: true });
|
2119
|
+
debug3("created cache directory: %s", dir);
|
2120
|
+
}
|
1824
2121
|
const yamlData = yaml3.dump(this.cache);
|
1825
2122
|
writeFileSync2(this.cacheFilePath, yamlData);
|
2123
|
+
debug3("cache flushed to file: %s", this.cacheFilePath);
|
1826
2124
|
} catch (err) {
|
1827
2125
|
debug3(
|
1828
2126
|
"write cache to file failed, path: %s, error: %s",
|
@@ -2080,6 +2378,23 @@ var PageAgent = class {
|
|
2080
2378
|
metadata
|
2081
2379
|
};
|
2082
2380
|
}
|
2381
|
+
async aiRightClick(locatePrompt, opt) {
|
2382
|
+
const detailedLocateParam = this.buildDetailedLocateParam(
|
2383
|
+
locatePrompt,
|
2384
|
+
opt
|
2385
|
+
);
|
2386
|
+
const plans = buildPlans("RightClick", detailedLocateParam);
|
2387
|
+
const { executor, output } = await this.taskExecutor.runPlans(
|
2388
|
+
taskTitleStr("RightClick", locateParamStr(detailedLocateParam)),
|
2389
|
+
plans,
|
2390
|
+
{ cacheable: opt?.cacheable }
|
2391
|
+
);
|
2392
|
+
const metadata = this.afterTaskRunning(executor);
|
2393
|
+
return {
|
2394
|
+
result: output,
|
2395
|
+
metadata
|
2396
|
+
};
|
2397
|
+
}
|
2083
2398
|
async aiInput(value, locatePrompt, opt) {
|
2084
2399
|
assert7(
|
2085
2400
|
typeof value === "string",
|
@@ -2154,7 +2469,13 @@ var PageAgent = class {
|
|
2154
2469
|
metadata: metadata2
|
2155
2470
|
};
|
2156
2471
|
}
|
2157
|
-
const
|
2472
|
+
const memoryContext = this.getMemoryAsContext();
|
2473
|
+
const enhancedActionContext = this.opts.aiActionContext ? `${this.opts.aiActionContext}
|
2474
|
+
|
2475
|
+
Previous workflow steps:
|
2476
|
+
${memoryContext}` : memoryContext ? `Previous workflow steps:
|
2477
|
+
${memoryContext}` : void 0;
|
2478
|
+
const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, enhancedActionContext, {
|
2158
2479
|
cacheable
|
2159
2480
|
}));
|
2160
2481
|
if (this.taskCache && output?.yamlFlow && cacheable !== false) {
|
@@ -2300,8 +2621,9 @@ var PageAgent = class {
|
|
2300
2621
|
} catch (e) {
|
2301
2622
|
}
|
2302
2623
|
}
|
2624
|
+
const memoryContext = this.getMemoryAsContext();
|
2303
2625
|
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2304
|
-
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2626
|
+
const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
|
2305
2627
|
const metadata = this.afterTaskRunning(executor, true);
|
2306
2628
|
if (output && opt?.keepRawResponse) {
|
2307
2629
|
return {
|
@@ -2511,9 +2833,72 @@ ${errors}`);
|
|
2511
2833
|
}
|
2512
2834
|
throw new Error("evaluateJavaScript is not supported in current agent");
|
2513
2835
|
}
|
2836
|
+
async logScreenshot(title, options) {
|
2837
|
+
const screenshotTitle = title || "untitled";
|
2838
|
+
const content = options?.content || "";
|
2839
|
+
const screenshot = await this.page.screenshotBase64?.();
|
2840
|
+
if (screenshot) {
|
2841
|
+
const executionDump = {
|
2842
|
+
name: screenshotTitle,
|
2843
|
+
description: content,
|
2844
|
+
tasks: [{
|
2845
|
+
type: "Screenshot",
|
2846
|
+
subType: "log",
|
2847
|
+
status: "finished",
|
2848
|
+
executor: null,
|
2849
|
+
param: {
|
2850
|
+
title: screenshotTitle,
|
2851
|
+
content
|
2852
|
+
},
|
2853
|
+
output: {
|
2854
|
+
screenshot
|
2855
|
+
},
|
2856
|
+
thought: `Logged screenshot: ${screenshotTitle}`,
|
2857
|
+
timing: {
|
2858
|
+
start: Date.now(),
|
2859
|
+
end: Date.now(),
|
2860
|
+
cost: 0
|
2861
|
+
}
|
2862
|
+
}],
|
2863
|
+
sdkVersion: "1.0.0",
|
2864
|
+
logTime: Date.now(),
|
2865
|
+
model_name: "screenshot"
|
2866
|
+
};
|
2867
|
+
this.appendExecutionDump(executionDump);
|
2868
|
+
}
|
2869
|
+
}
|
2514
2870
|
async destroy() {
|
2515
2871
|
await this.page.destroy();
|
2516
2872
|
}
|
2873
|
+
/**
|
2874
|
+
* Hafızayı bağlam olarak formatlar
|
2875
|
+
*/
|
2876
|
+
getMemoryAsContext() {
|
2877
|
+
const memory = this.taskExecutor.getMemory();
|
2878
|
+
if (memory.length === 0) {
|
2879
|
+
return "";
|
2880
|
+
}
|
2881
|
+
const recentMemory = memory.slice(-5);
|
2882
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
2883
|
+
}
|
2884
|
+
/**
|
2885
|
+
* Mevcut hafızayı döndürür
|
2886
|
+
*/
|
2887
|
+
getMemory() {
|
2888
|
+
return this.taskExecutor.getMemory();
|
2889
|
+
}
|
2890
|
+
/**
|
2891
|
+
* Hafıza istatistiklerini döndürür
|
2892
|
+
*/
|
2893
|
+
getMemoryStats() {
|
2894
|
+
return this.taskExecutor.getMemoryStats();
|
2895
|
+
}
|
2896
|
+
/**
|
2897
|
+
* Hafızayı temizler
|
2898
|
+
*/
|
2899
|
+
clearMemory() {
|
2900
|
+
this.taskExecutor.clearMemory();
|
2901
|
+
}
|
2517
2902
|
};
|
2518
2903
|
|
2519
2904
|
// src/puppeteer/index.ts
|