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
@@ -150,6 +150,10 @@ var ScriptPlayer = class {
|
|
150
150
|
} else if ("aiQuery" in flowItem) {
|
151
151
|
const queryTask = flowItem;
|
152
152
|
const prompt = queryTask.aiQuery;
|
153
|
+
const options = {
|
154
|
+
domIncluded: queryTask.domIncluded,
|
155
|
+
screenshotIncluded: queryTask.screenshotIncluded
|
156
|
+
};
|
153
157
|
(0, import_utils.assert)(prompt, "missing prompt for aiQuery");
|
154
158
|
(0, import_utils.assert)(
|
155
159
|
typeof prompt === "string",
|
@@ -160,6 +164,10 @@ var ScriptPlayer = class {
|
|
160
164
|
} else if ("aiNumber" in flowItem) {
|
161
165
|
const numberTask = flowItem;
|
162
166
|
const prompt = numberTask.aiNumber;
|
167
|
+
const options = {
|
168
|
+
domIncluded: numberTask.domIncluded,
|
169
|
+
screenshotIncluded: numberTask.screenshotIncluded
|
170
|
+
};
|
163
171
|
(0, import_utils.assert)(prompt, "missing prompt for number");
|
164
172
|
(0, import_utils.assert)(
|
165
173
|
typeof prompt === "string",
|
@@ -170,6 +178,10 @@ var ScriptPlayer = class {
|
|
170
178
|
} else if ("aiString" in flowItem) {
|
171
179
|
const stringTask = flowItem;
|
172
180
|
const prompt = stringTask.aiString;
|
181
|
+
const options = {
|
182
|
+
domIncluded: stringTask.domIncluded,
|
183
|
+
screenshotIncluded: stringTask.screenshotIncluded
|
184
|
+
};
|
173
185
|
(0, import_utils.assert)(prompt, "missing prompt for string");
|
174
186
|
(0, import_utils.assert)(
|
175
187
|
typeof prompt === "string",
|
@@ -180,6 +192,10 @@ var ScriptPlayer = class {
|
|
180
192
|
} else if ("aiBoolean" in flowItem) {
|
181
193
|
const booleanTask = flowItem;
|
182
194
|
const prompt = booleanTask.aiBoolean;
|
195
|
+
const options = {
|
196
|
+
domIncluded: booleanTask.domIncluded,
|
197
|
+
screenshotIncluded: booleanTask.screenshotIncluded
|
198
|
+
};
|
183
199
|
(0, import_utils.assert)(prompt, "missing prompt for boolean");
|
184
200
|
(0, import_utils.assert)(
|
185
201
|
typeof prompt === "string",
|
@@ -222,6 +238,9 @@ var ScriptPlayer = class {
|
|
222
238
|
} else if ("aiTap" in flowItem) {
|
223
239
|
const tapTask = flowItem;
|
224
240
|
await agent.aiTap(tapTask.aiTap, tapTask);
|
241
|
+
} else if ("aiRightClick" in flowItem) {
|
242
|
+
const rightClickTask = flowItem;
|
243
|
+
await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
|
225
244
|
} else if ("aiHover" in flowItem) {
|
226
245
|
const hoverTask = flowItem;
|
227
246
|
await agent.aiHover(hoverTask.aiHover, hoverTask);
|
@@ -244,6 +263,11 @@ var ScriptPlayer = class {
|
|
244
263
|
evaluateJavaScriptTask.javascript
|
245
264
|
);
|
246
265
|
this.setResult(evaluateJavaScriptTask.name, result);
|
266
|
+
} else if ("logScreenshot" in flowItem) {
|
267
|
+
const logScreenshotTask = flowItem;
|
268
|
+
await agent.logScreenshot(logScreenshotTask.logScreenshot, {
|
269
|
+
content: logScreenshotTask.content || ""
|
270
|
+
});
|
247
271
|
} else {
|
248
272
|
throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
|
249
273
|
}
|
@@ -492,7 +516,8 @@ var WebElementInfo = class {
|
|
492
516
|
id,
|
493
517
|
attributes,
|
494
518
|
indexId,
|
495
|
-
xpaths
|
519
|
+
xpaths,
|
520
|
+
isVisible
|
496
521
|
}) {
|
497
522
|
this.content = content;
|
498
523
|
this.rect = rect;
|
@@ -505,6 +530,7 @@ var WebElementInfo = class {
|
|
505
530
|
this.attributes = attributes;
|
506
531
|
this.indexId = indexId;
|
507
532
|
this.xpaths = xpaths;
|
533
|
+
this.isVisible = isVisible;
|
508
534
|
}
|
509
535
|
};
|
510
536
|
|
@@ -527,14 +553,15 @@ async function parseContextFromWebPage(page, _opt) {
|
|
527
553
|
})
|
528
554
|
]);
|
529
555
|
const webTree = (0, import_extractor.traverseTree)(tree, (elementInfo) => {
|
530
|
-
const { rect, id, content, attributes, locator, indexId } = elementInfo;
|
556
|
+
const { rect, id, content, attributes, locator, indexId, isVisible } = elementInfo;
|
531
557
|
return new WebElementInfo({
|
532
558
|
rect,
|
533
559
|
locator,
|
534
560
|
id,
|
535
561
|
content,
|
536
562
|
attributes,
|
537
|
-
indexId
|
563
|
+
indexId,
|
564
|
+
isVisible
|
538
565
|
});
|
539
566
|
});
|
540
567
|
(0, import_utils4.assert)(screenshotBase64, "screenshotBase64 is required");
|
@@ -564,7 +591,7 @@ function printReportMsg(filepath) {
|
|
564
591
|
(0, import_utils4.logMsg)(`Midscene - report file updated: ${filepath}`);
|
565
592
|
}
|
566
593
|
function replaceIllegalPathCharsAndSpace(str) {
|
567
|
-
return str.replace(/[
|
594
|
+
return str.replace(/[:*?"<>| ]/g, "-");
|
568
595
|
}
|
569
596
|
function forceClosePopup(page, debug6) {
|
570
597
|
page.on("popup", async (popup) => {
|
@@ -621,6 +648,94 @@ var replanningCountLimit = 10;
|
|
621
648
|
var isAndroidPage = (page) => {
|
622
649
|
return page.pageType === "android";
|
623
650
|
};
|
651
|
+
var WorkflowMemory = class {
|
652
|
+
constructor(config) {
|
653
|
+
this.workflows = /* @__PURE__ */ new Map();
|
654
|
+
this.config = config;
|
655
|
+
}
|
656
|
+
/**
|
657
|
+
* İş akışı hafızasını getirir
|
658
|
+
*/
|
659
|
+
getWorkflowMemory(workflowId = "default") {
|
660
|
+
const workflow = this.workflows.get(workflowId);
|
661
|
+
return workflow?.memory || [];
|
662
|
+
}
|
663
|
+
/**
|
664
|
+
* İş akışı verilerini getirir
|
665
|
+
*/
|
666
|
+
getWorkflowData(workflowId = "default") {
|
667
|
+
return this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
668
|
+
}
|
669
|
+
/**
|
670
|
+
* İş akışı hafızasını kaydeder
|
671
|
+
*/
|
672
|
+
saveWorkflowMemory(memory, workflowId = "default") {
|
673
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
674
|
+
workflow.memory = [...memory];
|
675
|
+
workflow.metadata.totalSteps = workflow.steps.length;
|
676
|
+
workflow.metadata.completedSteps = workflow.steps.filter((s) => s.status === "completed").length;
|
677
|
+
workflow.metadata.failedSteps = workflow.steps.filter((s) => s.status === "failed").length;
|
678
|
+
this.workflows.set(workflowId, workflow);
|
679
|
+
this.enforceRetentionPolicy();
|
680
|
+
}
|
681
|
+
/**
|
682
|
+
* İş akışı bağlamını günceller
|
683
|
+
*/
|
684
|
+
updateWorkflowContext(context, workflowId = "default") {
|
685
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
686
|
+
workflow.context = { ...workflow.context, ...context };
|
687
|
+
if (context.currentStep) {
|
688
|
+
const existingStep = workflow.steps.find((s) => s.stepName === context.currentStep);
|
689
|
+
if (!existingStep) {
|
690
|
+
workflow.steps.push({
|
691
|
+
stepId: `step_${workflow.steps.length + 1}`,
|
692
|
+
stepName: context.currentStep,
|
693
|
+
timestamp: context.timestamp,
|
694
|
+
status: "running",
|
695
|
+
memoryItems: []
|
696
|
+
});
|
697
|
+
}
|
698
|
+
}
|
699
|
+
this.workflows.set(workflowId, workflow);
|
700
|
+
}
|
701
|
+
/**
|
702
|
+
* İş akışını temizler
|
703
|
+
*/
|
704
|
+
clearWorkflow(workflowId = "default") {
|
705
|
+
this.workflows.delete(workflowId);
|
706
|
+
}
|
707
|
+
/**
|
708
|
+
* Tüm iş akışlarını temizler
|
709
|
+
*/
|
710
|
+
clearAll() {
|
711
|
+
this.workflows.clear();
|
712
|
+
}
|
713
|
+
createEmptyWorkflowData(workflowId) {
|
714
|
+
return {
|
715
|
+
workflowId,
|
716
|
+
steps: [],
|
717
|
+
memory: [],
|
718
|
+
context: {
|
719
|
+
pageInfo: { url: "", title: "" },
|
720
|
+
timestamp: Date.now()
|
721
|
+
},
|
722
|
+
metadata: {
|
723
|
+
totalSteps: 0,
|
724
|
+
completedSteps: 0,
|
725
|
+
failedSteps: 0,
|
726
|
+
startTime: Date.now()
|
727
|
+
}
|
728
|
+
};
|
729
|
+
}
|
730
|
+
enforceRetentionPolicy() {
|
731
|
+
const maxWorkflows = 10;
|
732
|
+
if (this.workflows.size > maxWorkflows) {
|
733
|
+
const sortedWorkflows = Array.from(this.workflows.entries()).sort(([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime));
|
734
|
+
const toDelete = sortedWorkflows.slice(maxWorkflows);
|
735
|
+
toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
|
736
|
+
}
|
737
|
+
}
|
738
|
+
};
|
624
739
|
var PageTaskExecutor = class {
|
625
740
|
constructor(page, insight, opts) {
|
626
741
|
this.conversationHistory = [];
|
@@ -628,6 +743,25 @@ var PageTaskExecutor = class {
|
|
628
743
|
this.insight = insight;
|
629
744
|
this.taskCache = opts.taskCache;
|
630
745
|
this.onTaskStartCallback = opts?.onTaskStart;
|
746
|
+
this.memoryConfig = {
|
747
|
+
maxItems: 100,
|
748
|
+
maxAge: 2 * 60 * 60 * 1e3,
|
749
|
+
// 2 saat
|
750
|
+
enablePersistence: true,
|
751
|
+
enableAnalytics: true,
|
752
|
+
filterStrategy: "hybrid",
|
753
|
+
...opts?.memoryConfig
|
754
|
+
};
|
755
|
+
this.sessionContext = {
|
756
|
+
sessionId: opts?.sessionId || this.generateSessionId(),
|
757
|
+
workflowId: opts?.workflowId,
|
758
|
+
startTime: Date.now(),
|
759
|
+
pageInfo: {
|
760
|
+
url: "",
|
761
|
+
title: ""
|
762
|
+
}
|
763
|
+
};
|
764
|
+
this.workflowMemory = new WorkflowMemory(this.memoryConfig);
|
631
765
|
}
|
632
766
|
async recordScreenshot(timing) {
|
633
767
|
const base64 = await this.page.screenshotBase64();
|
@@ -840,8 +974,11 @@ var PageTaskExecutor = class {
|
|
840
974
|
insightDump = dump;
|
841
975
|
};
|
842
976
|
this.insight.onceDumpUpdatedFn = dumpCollector;
|
977
|
+
const memoryContext = this.getMemoryAsContext();
|
843
978
|
const assertion = await this.insight.assert(
|
844
|
-
assertPlan.param.assertion
|
979
|
+
assertPlan.param.assertion,
|
980
|
+
memoryContext
|
981
|
+
// Hafıza bağlamını geç
|
845
982
|
);
|
846
983
|
if (!assertion.pass) {
|
847
984
|
if (plan2.type === "Assert") {
|
@@ -878,10 +1015,10 @@ var PageTaskExecutor = class {
|
|
878
1015
|
if (!taskParam || !taskParam.value) {
|
879
1016
|
return;
|
880
1017
|
}
|
881
|
-
await this.page.keyboard.type(taskParam.value);
|
882
|
-
} else {
|
883
|
-
await this.page.keyboard.type(taskParam.value);
|
884
1018
|
}
|
1019
|
+
await this.page.keyboard.type(taskParam.value, {
|
1020
|
+
autoDismissKeyboard: taskParam.autoDismissKeyboard
|
1021
|
+
});
|
885
1022
|
}
|
886
1023
|
};
|
887
1024
|
tasks.push(taskActionInput);
|
@@ -910,6 +1047,22 @@ var PageTaskExecutor = class {
|
|
910
1047
|
}
|
911
1048
|
};
|
912
1049
|
tasks.push(taskActionTap);
|
1050
|
+
} else if (plan2.type === "RightClick") {
|
1051
|
+
const taskActionRightClick = {
|
1052
|
+
type: "Action",
|
1053
|
+
subType: "RightClick",
|
1054
|
+
thought: plan2.thought,
|
1055
|
+
locate: plan2.locate,
|
1056
|
+
executor: async (param, { element }) => {
|
1057
|
+
(0, import_utils6.assert)(element, "Element not found, cannot right click");
|
1058
|
+
await this.page.mouse.click(
|
1059
|
+
element.center[0],
|
1060
|
+
element.center[1],
|
1061
|
+
{ button: "right" }
|
1062
|
+
);
|
1063
|
+
}
|
1064
|
+
};
|
1065
|
+
tasks.push(taskActionRightClick);
|
913
1066
|
} else if (plan2.type === "Drag") {
|
914
1067
|
const taskActionDrag = {
|
915
1068
|
type: "Action",
|
@@ -1311,25 +1464,146 @@ var PageTaskExecutor = class {
|
|
1311
1464
|
};
|
1312
1465
|
return task;
|
1313
1466
|
}
|
1467
|
+
/**
|
1468
|
+
* Persistent executor'ı getirir veya oluşturur
|
1469
|
+
*/
|
1470
|
+
getPersistentExecutor() {
|
1471
|
+
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1472
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
|
1473
|
+
this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
|
1474
|
+
onTaskStart: this.onTaskStartCallback,
|
1475
|
+
initialMemory: previousMemory
|
1476
|
+
});
|
1477
|
+
}
|
1478
|
+
return this.persistentExecutor;
|
1479
|
+
}
|
1480
|
+
/**
|
1481
|
+
* Sayfa bağlamını günceller
|
1482
|
+
*/
|
1483
|
+
async updatePageContext() {
|
1484
|
+
try {
|
1485
|
+
if (this.page.url) {
|
1486
|
+
this.sessionContext.pageInfo.url = await this.page.url();
|
1487
|
+
}
|
1488
|
+
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1489
|
+
this.sessionContext.pageInfo.title = await this.page.title();
|
1490
|
+
}
|
1491
|
+
} catch (e) {
|
1492
|
+
}
|
1493
|
+
}
|
1494
|
+
/**
|
1495
|
+
* Hafızayı temizler
|
1496
|
+
*/
|
1497
|
+
clearMemory() {
|
1498
|
+
if (this.persistentExecutor) {
|
1499
|
+
this.persistentExecutor.clearMemory();
|
1500
|
+
}
|
1501
|
+
this.workflowMemory.clearWorkflow(this.sessionContext.workflowId || "default");
|
1502
|
+
}
|
1503
|
+
/**
|
1504
|
+
* Mevcut hafızayı döndürür
|
1505
|
+
*/
|
1506
|
+
getMemory() {
|
1507
|
+
return this.persistentExecutor?.getMemory() || [];
|
1508
|
+
}
|
1509
|
+
/**
|
1510
|
+
* İş akışı hafızasını döndürür
|
1511
|
+
*/
|
1512
|
+
getWorkflowMemory() {
|
1513
|
+
return this.workflowMemory.getWorkflowData(this.sessionContext.workflowId || "default");
|
1514
|
+
}
|
1515
|
+
/**
|
1516
|
+
* Hafıza istatistiklerini döndürür
|
1517
|
+
*/
|
1518
|
+
getMemoryStats() {
|
1519
|
+
return this.persistentExecutor?.getMemoryStats() || {
|
1520
|
+
totalItems: 0,
|
1521
|
+
analytics: { totalTasks: 0, memoryHits: 0, memoryMisses: 0, averageMemorySize: 0, memoryEffectiveness: 0 },
|
1522
|
+
config: this.memoryConfig
|
1523
|
+
};
|
1524
|
+
}
|
1525
|
+
/**
|
1526
|
+
* Hafıza konfigürasyonunu günceller
|
1527
|
+
*/
|
1528
|
+
updateMemoryConfig(config) {
|
1529
|
+
this.memoryConfig = { ...this.memoryConfig, ...config };
|
1530
|
+
if (this.persistentExecutor) {
|
1531
|
+
this.persistentExecutor.updateMemoryConfig(this.memoryConfig);
|
1532
|
+
}
|
1533
|
+
}
|
1534
|
+
/**
|
1535
|
+
* Oturum ID'sini oluşturur
|
1536
|
+
*/
|
1537
|
+
generateSessionId() {
|
1538
|
+
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
1539
|
+
}
|
1540
|
+
/**
|
1541
|
+
* Hafızayı bağlam olarak formatlar
|
1542
|
+
*/
|
1543
|
+
getMemoryAsContext() {
|
1544
|
+
const memory = this.getMemory();
|
1545
|
+
if (memory.length === 0) {
|
1546
|
+
return "";
|
1547
|
+
}
|
1548
|
+
const recentMemory = memory.slice(-5);
|
1549
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
1550
|
+
}
|
1314
1551
|
async runPlans(title, plans, opts) {
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1552
|
+
await this.updatePageContext();
|
1553
|
+
const useMemory = opts?.useMemory !== false;
|
1554
|
+
let taskExecutor;
|
1555
|
+
if (useMemory) {
|
1556
|
+
taskExecutor = this.getPersistentExecutor();
|
1557
|
+
this.workflowMemory.updateWorkflowContext({
|
1558
|
+
currentStep: title,
|
1559
|
+
pageInfo: this.sessionContext.pageInfo,
|
1560
|
+
timestamp: Date.now()
|
1561
|
+
}, this.sessionContext.workflowId || "default");
|
1562
|
+
} else {
|
1563
|
+
taskExecutor = new import_misoai_core.Executor(title, {
|
1564
|
+
onTaskStart: this.onTaskStartCallback
|
1565
|
+
});
|
1566
|
+
}
|
1318
1567
|
const { tasks } = await this.convertPlanToExecutable(plans, opts);
|
1568
|
+
tasks.forEach((task) => {
|
1569
|
+
task.context = {
|
1570
|
+
...task.context,
|
1571
|
+
...this.sessionContext.pageInfo,
|
1572
|
+
workflowId: this.sessionContext.workflowId,
|
1573
|
+
sessionId: this.sessionContext.sessionId
|
1574
|
+
};
|
1575
|
+
});
|
1319
1576
|
await taskExecutor.append(tasks);
|
1320
1577
|
const result = await taskExecutor.flush();
|
1578
|
+
if (useMemory) {
|
1579
|
+
this.workflowMemory.saveWorkflowMemory(
|
1580
|
+
taskExecutor.getMemory(),
|
1581
|
+
this.sessionContext.workflowId || "default"
|
1582
|
+
);
|
1583
|
+
}
|
1321
1584
|
return {
|
1322
1585
|
output: result,
|
1323
1586
|
executor: taskExecutor
|
1324
1587
|
};
|
1325
1588
|
}
|
1326
1589
|
async action(userPrompt, actionContext, opts) {
|
1327
|
-
const
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1590
|
+
const useMemory = true;
|
1591
|
+
let taskExecutor;
|
1592
|
+
if (useMemory) {
|
1593
|
+
taskExecutor = this.getPersistentExecutor();
|
1594
|
+
} else {
|
1595
|
+
taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
|
1596
|
+
onTaskStart: this.onTaskStartCallback
|
1597
|
+
});
|
1598
|
+
}
|
1599
|
+
const memoryContext = this.getMemoryAsContext();
|
1600
|
+
const initialLog = memoryContext ? memoryContext : void 0;
|
1601
|
+
let planningTask = this.planningTaskFromPrompt(userPrompt, initialLog, actionContext);
|
1331
1602
|
let replanCount = 0;
|
1332
1603
|
const logList = [];
|
1604
|
+
if (memoryContext) {
|
1605
|
+
logList.push(memoryContext);
|
1606
|
+
}
|
1333
1607
|
const yamlFlow = [];
|
1334
1608
|
while (planningTask) {
|
1335
1609
|
if (replanCount > replanningCountLimit) {
|
@@ -1438,16 +1712,22 @@ var PageTaskExecutor = class {
|
|
1438
1712
|
executor: taskExecutor
|
1439
1713
|
};
|
1440
1714
|
}
|
1441
|
-
async createTypeQueryTask(type, demand) {
|
1442
|
-
const
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1715
|
+
async createTypeQueryTask(type, demand, opt) {
|
1716
|
+
const useMemory = true;
|
1717
|
+
let taskExecutor;
|
1718
|
+
if (useMemory) {
|
1719
|
+
taskExecutor = this.getPersistentExecutor();
|
1720
|
+
} else {
|
1721
|
+
taskExecutor = new import_misoai_core.Executor(
|
1722
|
+
taskTitleStr(
|
1723
|
+
type,
|
1724
|
+
typeof demand === "string" ? demand : JSON.stringify(demand)
|
1725
|
+
),
|
1726
|
+
{
|
1727
|
+
onTaskStart: this.onTaskStartCallback
|
1728
|
+
}
|
1729
|
+
);
|
1730
|
+
}
|
1451
1731
|
const queryTask = {
|
1452
1732
|
type: "Insight",
|
1453
1733
|
subType: type,
|
@@ -1469,7 +1749,13 @@ var PageTaskExecutor = class {
|
|
1469
1749
|
result: `${type}, ${demand}`
|
1470
1750
|
};
|
1471
1751
|
}
|
1472
|
-
const
|
1752
|
+
const memoryContext = this.getMemoryAsContext();
|
1753
|
+
const { data, usage } = await this.insight.extract(
|
1754
|
+
demandInput,
|
1755
|
+
opt,
|
1756
|
+
memoryContext
|
1757
|
+
// Hafıza bağlamını geç
|
1758
|
+
);
|
1473
1759
|
let outputResult = data;
|
1474
1760
|
if (ifTypeRestricted) {
|
1475
1761
|
(0, import_utils6.assert)(data?.result !== void 0, "No result in query data");
|
@@ -1489,23 +1775,29 @@ var PageTaskExecutor = class {
|
|
1489
1775
|
executor: taskExecutor
|
1490
1776
|
};
|
1491
1777
|
}
|
1492
|
-
async query(demand) {
|
1493
|
-
return this.createTypeQueryTask("Query", demand);
|
1778
|
+
async query(demand, opt) {
|
1779
|
+
return this.createTypeQueryTask("Query", demand, opt);
|
1494
1780
|
}
|
1495
|
-
async boolean(prompt) {
|
1496
|
-
return this.createTypeQueryTask("Boolean", prompt);
|
1781
|
+
async boolean(prompt, opt) {
|
1782
|
+
return this.createTypeQueryTask("Boolean", prompt, opt);
|
1497
1783
|
}
|
1498
|
-
async number(prompt) {
|
1499
|
-
return this.createTypeQueryTask("Number", prompt);
|
1784
|
+
async number(prompt, opt) {
|
1785
|
+
return this.createTypeQueryTask("Number", prompt, opt);
|
1500
1786
|
}
|
1501
|
-
async string(prompt) {
|
1502
|
-
return this.createTypeQueryTask("String", prompt);
|
1787
|
+
async string(prompt, opt) {
|
1788
|
+
return this.createTypeQueryTask("String", prompt, opt);
|
1503
1789
|
}
|
1504
|
-
async assert(assertion) {
|
1790
|
+
async assert(assertion, memoryContext) {
|
1505
1791
|
const description = `assert: ${assertion}`;
|
1506
|
-
const
|
1507
|
-
|
1508
|
-
|
1792
|
+
const useMemory = true;
|
1793
|
+
let taskExecutor;
|
1794
|
+
if (useMemory) {
|
1795
|
+
taskExecutor = this.getPersistentExecutor();
|
1796
|
+
} else {
|
1797
|
+
taskExecutor = new import_misoai_core.Executor(taskTitleStr("Assert", description), {
|
1798
|
+
onTaskStart: this.onTaskStartCallback
|
1799
|
+
});
|
1800
|
+
}
|
1509
1801
|
const assertionPlan = {
|
1510
1802
|
type: "Assert",
|
1511
1803
|
param: {
|
@@ -1635,7 +1927,7 @@ function buildPlans(type, locateParam, param) {
|
|
1635
1927
|
param: locateParam,
|
1636
1928
|
thought: ""
|
1637
1929
|
} : null;
|
1638
|
-
if (type === "Tap" || type === "Hover") {
|
1930
|
+
if (type === "Tap" || type === "Hover" || type === "RightClick") {
|
1639
1931
|
(0, import_utils8.assert)(locateParam, `missing locate info for action "${type}"`);
|
1640
1932
|
(0, import_utils8.assert)(locatePlan, `missing locate info for action "${type}"`);
|
1641
1933
|
const tapPlan = {
|
@@ -1715,7 +2007,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
|
|
1715
2007
|
var import_semver = __toESM(require("semver"));
|
1716
2008
|
|
1717
2009
|
// package.json
|
1718
|
-
var version = "1.5.
|
2010
|
+
var version = "1.5.7";
|
1719
2011
|
|
1720
2012
|
// src/common/task-cache.ts
|
1721
2013
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -1846,8 +2138,14 @@ cache file: ${cacheFile}`
|
|
1846
2138
|
return;
|
1847
2139
|
}
|
1848
2140
|
try {
|
2141
|
+
const dir = (0, import_node_path2.dirname)(this.cacheFilePath);
|
2142
|
+
if (!(0, import_node_fs2.existsSync)(dir)) {
|
2143
|
+
(0, import_node_fs2.mkdirSync)(dir, { recursive: true });
|
2144
|
+
debug3("created cache directory: %s", dir);
|
2145
|
+
}
|
1849
2146
|
const yamlData = import_js_yaml3.default.dump(this.cache);
|
1850
2147
|
(0, import_node_fs2.writeFileSync)(this.cacheFilePath, yamlData);
|
2148
|
+
debug3("cache flushed to file: %s", this.cacheFilePath);
|
1851
2149
|
} catch (err) {
|
1852
2150
|
debug3(
|
1853
2151
|
"write cache to file failed, path: %s, error: %s",
|
@@ -2105,6 +2403,23 @@ var PageAgent = class {
|
|
2105
2403
|
metadata
|
2106
2404
|
};
|
2107
2405
|
}
|
2406
|
+
async aiRightClick(locatePrompt, opt) {
|
2407
|
+
const detailedLocateParam = this.buildDetailedLocateParam(
|
2408
|
+
locatePrompt,
|
2409
|
+
opt
|
2410
|
+
);
|
2411
|
+
const plans = buildPlans("RightClick", detailedLocateParam);
|
2412
|
+
const { executor, output } = await this.taskExecutor.runPlans(
|
2413
|
+
taskTitleStr("RightClick", locateParamStr(detailedLocateParam)),
|
2414
|
+
plans,
|
2415
|
+
{ cacheable: opt?.cacheable }
|
2416
|
+
);
|
2417
|
+
const metadata = this.afterTaskRunning(executor);
|
2418
|
+
return {
|
2419
|
+
result: output,
|
2420
|
+
metadata
|
2421
|
+
};
|
2422
|
+
}
|
2108
2423
|
async aiInput(value, locatePrompt, opt) {
|
2109
2424
|
(0, import_utils12.assert)(
|
2110
2425
|
typeof value === "string",
|
@@ -2179,7 +2494,13 @@ var PageAgent = class {
|
|
2179
2494
|
metadata: metadata2
|
2180
2495
|
};
|
2181
2496
|
}
|
2182
|
-
const
|
2497
|
+
const memoryContext = this.getMemoryAsContext();
|
2498
|
+
const enhancedActionContext = this.opts.aiActionContext ? `${this.opts.aiActionContext}
|
2499
|
+
|
2500
|
+
Previous workflow steps:
|
2501
|
+
${memoryContext}` : memoryContext ? `Previous workflow steps:
|
2502
|
+
${memoryContext}` : void 0;
|
2503
|
+
const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, enhancedActionContext, {
|
2183
2504
|
cacheable
|
2184
2505
|
}));
|
2185
2506
|
if (this.taskCache && output?.yamlFlow && cacheable !== false) {
|
@@ -2325,8 +2646,9 @@ var PageAgent = class {
|
|
2325
2646
|
} catch (e) {
|
2326
2647
|
}
|
2327
2648
|
}
|
2649
|
+
const memoryContext = this.getMemoryAsContext();
|
2328
2650
|
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2329
|
-
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2651
|
+
const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
|
2330
2652
|
const metadata = this.afterTaskRunning(executor, true);
|
2331
2653
|
if (output && opt?.keepRawResponse) {
|
2332
2654
|
return {
|
@@ -2536,9 +2858,72 @@ ${errors}`);
|
|
2536
2858
|
}
|
2537
2859
|
throw new Error("evaluateJavaScript is not supported in current agent");
|
2538
2860
|
}
|
2861
|
+
async logScreenshot(title, options) {
|
2862
|
+
const screenshotTitle = title || "untitled";
|
2863
|
+
const content = options?.content || "";
|
2864
|
+
const screenshot = await this.page.screenshotBase64?.();
|
2865
|
+
if (screenshot) {
|
2866
|
+
const executionDump = {
|
2867
|
+
name: screenshotTitle,
|
2868
|
+
description: content,
|
2869
|
+
tasks: [{
|
2870
|
+
type: "Screenshot",
|
2871
|
+
subType: "log",
|
2872
|
+
status: "finished",
|
2873
|
+
executor: null,
|
2874
|
+
param: {
|
2875
|
+
title: screenshotTitle,
|
2876
|
+
content
|
2877
|
+
},
|
2878
|
+
output: {
|
2879
|
+
screenshot
|
2880
|
+
},
|
2881
|
+
thought: `Logged screenshot: ${screenshotTitle}`,
|
2882
|
+
timing: {
|
2883
|
+
start: Date.now(),
|
2884
|
+
end: Date.now(),
|
2885
|
+
cost: 0
|
2886
|
+
}
|
2887
|
+
}],
|
2888
|
+
sdkVersion: "1.0.0",
|
2889
|
+
logTime: Date.now(),
|
2890
|
+
model_name: "screenshot"
|
2891
|
+
};
|
2892
|
+
this.appendExecutionDump(executionDump);
|
2893
|
+
}
|
2894
|
+
}
|
2539
2895
|
async destroy() {
|
2540
2896
|
await this.page.destroy();
|
2541
2897
|
}
|
2898
|
+
/**
|
2899
|
+
* Hafızayı bağlam olarak formatlar
|
2900
|
+
*/
|
2901
|
+
getMemoryAsContext() {
|
2902
|
+
const memory = this.taskExecutor.getMemory();
|
2903
|
+
if (memory.length === 0) {
|
2904
|
+
return "";
|
2905
|
+
}
|
2906
|
+
const recentMemory = memory.slice(-5);
|
2907
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
2908
|
+
}
|
2909
|
+
/**
|
2910
|
+
* Mevcut hafızayı döndürür
|
2911
|
+
*/
|
2912
|
+
getMemory() {
|
2913
|
+
return this.taskExecutor.getMemory();
|
2914
|
+
}
|
2915
|
+
/**
|
2916
|
+
* Hafıza istatistiklerini döndürür
|
2917
|
+
*/
|
2918
|
+
getMemoryStats() {
|
2919
|
+
return this.taskExecutor.getMemoryStats();
|
2920
|
+
}
|
2921
|
+
/**
|
2922
|
+
* Hafızayı temizler
|
2923
|
+
*/
|
2924
|
+
clearMemory() {
|
2925
|
+
this.taskExecutor.clearMemory();
|
2926
|
+
}
|
2542
2927
|
};
|
2543
2928
|
|
2544
2929
|
// src/puppeteer/index.ts
|