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
@@ -110,6 +110,10 @@ var ScriptPlayer = class {
|
|
110
110
|
} else if ("aiQuery" in flowItem) {
|
111
111
|
const queryTask = flowItem;
|
112
112
|
const prompt = queryTask.aiQuery;
|
113
|
+
const options = {
|
114
|
+
domIncluded: queryTask.domIncluded,
|
115
|
+
screenshotIncluded: queryTask.screenshotIncluded
|
116
|
+
};
|
113
117
|
assert(prompt, "missing prompt for aiQuery");
|
114
118
|
assert(
|
115
119
|
typeof prompt === "string",
|
@@ -120,6 +124,10 @@ var ScriptPlayer = class {
|
|
120
124
|
} else if ("aiNumber" in flowItem) {
|
121
125
|
const numberTask = flowItem;
|
122
126
|
const prompt = numberTask.aiNumber;
|
127
|
+
const options = {
|
128
|
+
domIncluded: numberTask.domIncluded,
|
129
|
+
screenshotIncluded: numberTask.screenshotIncluded
|
130
|
+
};
|
123
131
|
assert(prompt, "missing prompt for number");
|
124
132
|
assert(
|
125
133
|
typeof prompt === "string",
|
@@ -130,6 +138,10 @@ var ScriptPlayer = class {
|
|
130
138
|
} else if ("aiString" in flowItem) {
|
131
139
|
const stringTask = flowItem;
|
132
140
|
const prompt = stringTask.aiString;
|
141
|
+
const options = {
|
142
|
+
domIncluded: stringTask.domIncluded,
|
143
|
+
screenshotIncluded: stringTask.screenshotIncluded
|
144
|
+
};
|
133
145
|
assert(prompt, "missing prompt for string");
|
134
146
|
assert(
|
135
147
|
typeof prompt === "string",
|
@@ -140,6 +152,10 @@ var ScriptPlayer = class {
|
|
140
152
|
} else if ("aiBoolean" in flowItem) {
|
141
153
|
const booleanTask = flowItem;
|
142
154
|
const prompt = booleanTask.aiBoolean;
|
155
|
+
const options = {
|
156
|
+
domIncluded: booleanTask.domIncluded,
|
157
|
+
screenshotIncluded: booleanTask.screenshotIncluded
|
158
|
+
};
|
143
159
|
assert(prompt, "missing prompt for boolean");
|
144
160
|
assert(
|
145
161
|
typeof prompt === "string",
|
@@ -182,6 +198,9 @@ var ScriptPlayer = class {
|
|
182
198
|
} else if ("aiTap" in flowItem) {
|
183
199
|
const tapTask = flowItem;
|
184
200
|
await agent.aiTap(tapTask.aiTap, tapTask);
|
201
|
+
} else if ("aiRightClick" in flowItem) {
|
202
|
+
const rightClickTask = flowItem;
|
203
|
+
await agent.aiRightClick(rightClickTask.aiRightClick, rightClickTask);
|
185
204
|
} else if ("aiHover" in flowItem) {
|
186
205
|
const hoverTask = flowItem;
|
187
206
|
await agent.aiHover(hoverTask.aiHover, hoverTask);
|
@@ -204,6 +223,11 @@ var ScriptPlayer = class {
|
|
204
223
|
evaluateJavaScriptTask.javascript
|
205
224
|
);
|
206
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
|
+
});
|
207
231
|
} else {
|
208
232
|
throw new Error(`unknown flowItem: ${JSON.stringify(flowItem)}`);
|
209
233
|
}
|
@@ -472,7 +496,8 @@ var WebElementInfo = class {
|
|
472
496
|
id,
|
473
497
|
attributes,
|
474
498
|
indexId,
|
475
|
-
xpaths
|
499
|
+
xpaths,
|
500
|
+
isVisible
|
476
501
|
}) {
|
477
502
|
this.content = content;
|
478
503
|
this.rect = rect;
|
@@ -485,6 +510,7 @@ var WebElementInfo = class {
|
|
485
510
|
this.attributes = attributes;
|
486
511
|
this.indexId = indexId;
|
487
512
|
this.xpaths = xpaths;
|
513
|
+
this.isVisible = isVisible;
|
488
514
|
}
|
489
515
|
};
|
490
516
|
|
@@ -507,14 +533,15 @@ async function parseContextFromWebPage(page, _opt) {
|
|
507
533
|
})
|
508
534
|
]);
|
509
535
|
const webTree = traverseTree(tree, (elementInfo) => {
|
510
|
-
const { rect, id, content, attributes, locator, indexId } = elementInfo;
|
536
|
+
const { rect, id, content, attributes, locator, indexId, isVisible } = elementInfo;
|
511
537
|
return new WebElementInfo({
|
512
538
|
rect,
|
513
539
|
locator,
|
514
540
|
id,
|
515
541
|
content,
|
516
542
|
attributes,
|
517
|
-
indexId
|
543
|
+
indexId,
|
544
|
+
isVisible
|
518
545
|
});
|
519
546
|
});
|
520
547
|
assert3(screenshotBase64, "screenshotBase64 is required");
|
@@ -544,7 +571,7 @@ function printReportMsg(filepath) {
|
|
544
571
|
logMsg(`Midscene - report file updated: ${filepath}`);
|
545
572
|
}
|
546
573
|
function replaceIllegalPathCharsAndSpace(str) {
|
547
|
-
return str.replace(/[
|
574
|
+
return str.replace(/[:*?"<>| ]/g, "-");
|
548
575
|
}
|
549
576
|
function forceClosePopup(page, debug6) {
|
550
577
|
page.on("popup", async (popup) => {
|
@@ -601,6 +628,94 @@ var replanningCountLimit = 10;
|
|
601
628
|
var isAndroidPage = (page) => {
|
602
629
|
return page.pageType === "android";
|
603
630
|
};
|
631
|
+
var WorkflowMemory = class {
|
632
|
+
constructor(config) {
|
633
|
+
this.workflows = /* @__PURE__ */ new Map();
|
634
|
+
this.config = config;
|
635
|
+
}
|
636
|
+
/**
|
637
|
+
* İş akışı hafızasını getirir
|
638
|
+
*/
|
639
|
+
getWorkflowMemory(workflowId = "default") {
|
640
|
+
const workflow = this.workflows.get(workflowId);
|
641
|
+
return workflow?.memory || [];
|
642
|
+
}
|
643
|
+
/**
|
644
|
+
* İş akışı verilerini getirir
|
645
|
+
*/
|
646
|
+
getWorkflowData(workflowId = "default") {
|
647
|
+
return this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
648
|
+
}
|
649
|
+
/**
|
650
|
+
* İş akışı hafızasını kaydeder
|
651
|
+
*/
|
652
|
+
saveWorkflowMemory(memory, workflowId = "default") {
|
653
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
654
|
+
workflow.memory = [...memory];
|
655
|
+
workflow.metadata.totalSteps = workflow.steps.length;
|
656
|
+
workflow.metadata.completedSteps = workflow.steps.filter((s) => s.status === "completed").length;
|
657
|
+
workflow.metadata.failedSteps = workflow.steps.filter((s) => s.status === "failed").length;
|
658
|
+
this.workflows.set(workflowId, workflow);
|
659
|
+
this.enforceRetentionPolicy();
|
660
|
+
}
|
661
|
+
/**
|
662
|
+
* İş akışı bağlamını günceller
|
663
|
+
*/
|
664
|
+
updateWorkflowContext(context, workflowId = "default") {
|
665
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
666
|
+
workflow.context = { ...workflow.context, ...context };
|
667
|
+
if (context.currentStep) {
|
668
|
+
const existingStep = workflow.steps.find((s) => s.stepName === context.currentStep);
|
669
|
+
if (!existingStep) {
|
670
|
+
workflow.steps.push({
|
671
|
+
stepId: `step_${workflow.steps.length + 1}`,
|
672
|
+
stepName: context.currentStep,
|
673
|
+
timestamp: context.timestamp,
|
674
|
+
status: "running",
|
675
|
+
memoryItems: []
|
676
|
+
});
|
677
|
+
}
|
678
|
+
}
|
679
|
+
this.workflows.set(workflowId, workflow);
|
680
|
+
}
|
681
|
+
/**
|
682
|
+
* İş akışını temizler
|
683
|
+
*/
|
684
|
+
clearWorkflow(workflowId = "default") {
|
685
|
+
this.workflows.delete(workflowId);
|
686
|
+
}
|
687
|
+
/**
|
688
|
+
* Tüm iş akışlarını temizler
|
689
|
+
*/
|
690
|
+
clearAll() {
|
691
|
+
this.workflows.clear();
|
692
|
+
}
|
693
|
+
createEmptyWorkflowData(workflowId) {
|
694
|
+
return {
|
695
|
+
workflowId,
|
696
|
+
steps: [],
|
697
|
+
memory: [],
|
698
|
+
context: {
|
699
|
+
pageInfo: { url: "", title: "" },
|
700
|
+
timestamp: Date.now()
|
701
|
+
},
|
702
|
+
metadata: {
|
703
|
+
totalSteps: 0,
|
704
|
+
completedSteps: 0,
|
705
|
+
failedSteps: 0,
|
706
|
+
startTime: Date.now()
|
707
|
+
}
|
708
|
+
};
|
709
|
+
}
|
710
|
+
enforceRetentionPolicy() {
|
711
|
+
const maxWorkflows = 10;
|
712
|
+
if (this.workflows.size > maxWorkflows) {
|
713
|
+
const sortedWorkflows = Array.from(this.workflows.entries()).sort(([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime));
|
714
|
+
const toDelete = sortedWorkflows.slice(maxWorkflows);
|
715
|
+
toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
|
716
|
+
}
|
717
|
+
}
|
718
|
+
};
|
604
719
|
var PageTaskExecutor = class {
|
605
720
|
constructor(page, insight, opts) {
|
606
721
|
this.conversationHistory = [];
|
@@ -608,6 +723,25 @@ var PageTaskExecutor = class {
|
|
608
723
|
this.insight = insight;
|
609
724
|
this.taskCache = opts.taskCache;
|
610
725
|
this.onTaskStartCallback = opts?.onTaskStart;
|
726
|
+
this.memoryConfig = {
|
727
|
+
maxItems: 100,
|
728
|
+
maxAge: 2 * 60 * 60 * 1e3,
|
729
|
+
// 2 saat
|
730
|
+
enablePersistence: true,
|
731
|
+
enableAnalytics: true,
|
732
|
+
filterStrategy: "hybrid",
|
733
|
+
...opts?.memoryConfig
|
734
|
+
};
|
735
|
+
this.sessionContext = {
|
736
|
+
sessionId: opts?.sessionId || this.generateSessionId(),
|
737
|
+
workflowId: opts?.workflowId,
|
738
|
+
startTime: Date.now(),
|
739
|
+
pageInfo: {
|
740
|
+
url: "",
|
741
|
+
title: ""
|
742
|
+
}
|
743
|
+
};
|
744
|
+
this.workflowMemory = new WorkflowMemory(this.memoryConfig);
|
611
745
|
}
|
612
746
|
async recordScreenshot(timing) {
|
613
747
|
const base64 = await this.page.screenshotBase64();
|
@@ -820,8 +954,11 @@ var PageTaskExecutor = class {
|
|
820
954
|
insightDump = dump;
|
821
955
|
};
|
822
956
|
this.insight.onceDumpUpdatedFn = dumpCollector;
|
957
|
+
const memoryContext = this.getMemoryAsContext();
|
823
958
|
const assertion = await this.insight.assert(
|
824
|
-
assertPlan.param.assertion
|
959
|
+
assertPlan.param.assertion,
|
960
|
+
memoryContext
|
961
|
+
// Hafıza bağlamını geç
|
825
962
|
);
|
826
963
|
if (!assertion.pass) {
|
827
964
|
if (plan2.type === "Assert") {
|
@@ -858,10 +995,10 @@ var PageTaskExecutor = class {
|
|
858
995
|
if (!taskParam || !taskParam.value) {
|
859
996
|
return;
|
860
997
|
}
|
861
|
-
await this.page.keyboard.type(taskParam.value);
|
862
|
-
} else {
|
863
|
-
await this.page.keyboard.type(taskParam.value);
|
864
998
|
}
|
999
|
+
await this.page.keyboard.type(taskParam.value, {
|
1000
|
+
autoDismissKeyboard: taskParam.autoDismissKeyboard
|
1001
|
+
});
|
865
1002
|
}
|
866
1003
|
};
|
867
1004
|
tasks.push(taskActionInput);
|
@@ -890,6 +1027,22 @@ var PageTaskExecutor = class {
|
|
890
1027
|
}
|
891
1028
|
};
|
892
1029
|
tasks.push(taskActionTap);
|
1030
|
+
} else if (plan2.type === "RightClick") {
|
1031
|
+
const taskActionRightClick = {
|
1032
|
+
type: "Action",
|
1033
|
+
subType: "RightClick",
|
1034
|
+
thought: plan2.thought,
|
1035
|
+
locate: plan2.locate,
|
1036
|
+
executor: async (param, { element }) => {
|
1037
|
+
assert4(element, "Element not found, cannot right click");
|
1038
|
+
await this.page.mouse.click(
|
1039
|
+
element.center[0],
|
1040
|
+
element.center[1],
|
1041
|
+
{ button: "right" }
|
1042
|
+
);
|
1043
|
+
}
|
1044
|
+
};
|
1045
|
+
tasks.push(taskActionRightClick);
|
893
1046
|
} else if (plan2.type === "Drag") {
|
894
1047
|
const taskActionDrag = {
|
895
1048
|
type: "Action",
|
@@ -1291,25 +1444,146 @@ var PageTaskExecutor = class {
|
|
1291
1444
|
};
|
1292
1445
|
return task;
|
1293
1446
|
}
|
1447
|
+
/**
|
1448
|
+
* Persistent executor'ı getirir veya oluşturur
|
1449
|
+
*/
|
1450
|
+
getPersistentExecutor() {
|
1451
|
+
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1452
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
|
1453
|
+
this.persistentExecutor = new Executor("Persistent Task Executor", {
|
1454
|
+
onTaskStart: this.onTaskStartCallback,
|
1455
|
+
initialMemory: previousMemory
|
1456
|
+
});
|
1457
|
+
}
|
1458
|
+
return this.persistentExecutor;
|
1459
|
+
}
|
1460
|
+
/**
|
1461
|
+
* Sayfa bağlamını günceller
|
1462
|
+
*/
|
1463
|
+
async updatePageContext() {
|
1464
|
+
try {
|
1465
|
+
if (this.page.url) {
|
1466
|
+
this.sessionContext.pageInfo.url = await this.page.url();
|
1467
|
+
}
|
1468
|
+
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1469
|
+
this.sessionContext.pageInfo.title = await this.page.title();
|
1470
|
+
}
|
1471
|
+
} catch (e) {
|
1472
|
+
}
|
1473
|
+
}
|
1474
|
+
/**
|
1475
|
+
* Hafızayı temizler
|
1476
|
+
*/
|
1477
|
+
clearMemory() {
|
1478
|
+
if (this.persistentExecutor) {
|
1479
|
+
this.persistentExecutor.clearMemory();
|
1480
|
+
}
|
1481
|
+
this.workflowMemory.clearWorkflow(this.sessionContext.workflowId || "default");
|
1482
|
+
}
|
1483
|
+
/**
|
1484
|
+
* Mevcut hafızayı döndürür
|
1485
|
+
*/
|
1486
|
+
getMemory() {
|
1487
|
+
return this.persistentExecutor?.getMemory() || [];
|
1488
|
+
}
|
1489
|
+
/**
|
1490
|
+
* İş akışı hafızasını döndürür
|
1491
|
+
*/
|
1492
|
+
getWorkflowMemory() {
|
1493
|
+
return this.workflowMemory.getWorkflowData(this.sessionContext.workflowId || "default");
|
1494
|
+
}
|
1495
|
+
/**
|
1496
|
+
* Hafıza istatistiklerini döndürür
|
1497
|
+
*/
|
1498
|
+
getMemoryStats() {
|
1499
|
+
return this.persistentExecutor?.getMemoryStats() || {
|
1500
|
+
totalItems: 0,
|
1501
|
+
analytics: { totalTasks: 0, memoryHits: 0, memoryMisses: 0, averageMemorySize: 0, memoryEffectiveness: 0 },
|
1502
|
+
config: this.memoryConfig
|
1503
|
+
};
|
1504
|
+
}
|
1505
|
+
/**
|
1506
|
+
* Hafıza konfigürasyonunu günceller
|
1507
|
+
*/
|
1508
|
+
updateMemoryConfig(config) {
|
1509
|
+
this.memoryConfig = { ...this.memoryConfig, ...config };
|
1510
|
+
if (this.persistentExecutor) {
|
1511
|
+
this.persistentExecutor.updateMemoryConfig(this.memoryConfig);
|
1512
|
+
}
|
1513
|
+
}
|
1514
|
+
/**
|
1515
|
+
* Oturum ID'sini oluşturur
|
1516
|
+
*/
|
1517
|
+
generateSessionId() {
|
1518
|
+
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
1519
|
+
}
|
1520
|
+
/**
|
1521
|
+
* Hafızayı bağlam olarak formatlar
|
1522
|
+
*/
|
1523
|
+
getMemoryAsContext() {
|
1524
|
+
const memory = this.getMemory();
|
1525
|
+
if (memory.length === 0) {
|
1526
|
+
return "";
|
1527
|
+
}
|
1528
|
+
const recentMemory = memory.slice(-5);
|
1529
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
1530
|
+
}
|
1294
1531
|
async runPlans(title, plans, opts) {
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1532
|
+
await this.updatePageContext();
|
1533
|
+
const useMemory = opts?.useMemory !== false;
|
1534
|
+
let taskExecutor;
|
1535
|
+
if (useMemory) {
|
1536
|
+
taskExecutor = this.getPersistentExecutor();
|
1537
|
+
this.workflowMemory.updateWorkflowContext({
|
1538
|
+
currentStep: title,
|
1539
|
+
pageInfo: this.sessionContext.pageInfo,
|
1540
|
+
timestamp: Date.now()
|
1541
|
+
}, this.sessionContext.workflowId || "default");
|
1542
|
+
} else {
|
1543
|
+
taskExecutor = new Executor(title, {
|
1544
|
+
onTaskStart: this.onTaskStartCallback
|
1545
|
+
});
|
1546
|
+
}
|
1298
1547
|
const { tasks } = await this.convertPlanToExecutable(plans, opts);
|
1548
|
+
tasks.forEach((task) => {
|
1549
|
+
task.context = {
|
1550
|
+
...task.context,
|
1551
|
+
...this.sessionContext.pageInfo,
|
1552
|
+
workflowId: this.sessionContext.workflowId,
|
1553
|
+
sessionId: this.sessionContext.sessionId
|
1554
|
+
};
|
1555
|
+
});
|
1299
1556
|
await taskExecutor.append(tasks);
|
1300
1557
|
const result = await taskExecutor.flush();
|
1558
|
+
if (useMemory) {
|
1559
|
+
this.workflowMemory.saveWorkflowMemory(
|
1560
|
+
taskExecutor.getMemory(),
|
1561
|
+
this.sessionContext.workflowId || "default"
|
1562
|
+
);
|
1563
|
+
}
|
1301
1564
|
return {
|
1302
1565
|
output: result,
|
1303
1566
|
executor: taskExecutor
|
1304
1567
|
};
|
1305
1568
|
}
|
1306
1569
|
async action(userPrompt, actionContext, opts) {
|
1307
|
-
const
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1570
|
+
const useMemory = true;
|
1571
|
+
let taskExecutor;
|
1572
|
+
if (useMemory) {
|
1573
|
+
taskExecutor = this.getPersistentExecutor();
|
1574
|
+
} else {
|
1575
|
+
taskExecutor = new Executor(taskTitleStr("Action", userPrompt), {
|
1576
|
+
onTaskStart: this.onTaskStartCallback
|
1577
|
+
});
|
1578
|
+
}
|
1579
|
+
const memoryContext = this.getMemoryAsContext();
|
1580
|
+
const initialLog = memoryContext ? memoryContext : void 0;
|
1581
|
+
let planningTask = this.planningTaskFromPrompt(userPrompt, initialLog, actionContext);
|
1311
1582
|
let replanCount = 0;
|
1312
1583
|
const logList = [];
|
1584
|
+
if (memoryContext) {
|
1585
|
+
logList.push(memoryContext);
|
1586
|
+
}
|
1313
1587
|
const yamlFlow = [];
|
1314
1588
|
while (planningTask) {
|
1315
1589
|
if (replanCount > replanningCountLimit) {
|
@@ -1418,16 +1692,22 @@ var PageTaskExecutor = class {
|
|
1418
1692
|
executor: taskExecutor
|
1419
1693
|
};
|
1420
1694
|
}
|
1421
|
-
async createTypeQueryTask(type, demand) {
|
1422
|
-
const
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1695
|
+
async createTypeQueryTask(type, demand, opt) {
|
1696
|
+
const useMemory = true;
|
1697
|
+
let taskExecutor;
|
1698
|
+
if (useMemory) {
|
1699
|
+
taskExecutor = this.getPersistentExecutor();
|
1700
|
+
} else {
|
1701
|
+
taskExecutor = new Executor(
|
1702
|
+
taskTitleStr(
|
1703
|
+
type,
|
1704
|
+
typeof demand === "string" ? demand : JSON.stringify(demand)
|
1705
|
+
),
|
1706
|
+
{
|
1707
|
+
onTaskStart: this.onTaskStartCallback
|
1708
|
+
}
|
1709
|
+
);
|
1710
|
+
}
|
1431
1711
|
const queryTask = {
|
1432
1712
|
type: "Insight",
|
1433
1713
|
subType: type,
|
@@ -1449,7 +1729,13 @@ var PageTaskExecutor = class {
|
|
1449
1729
|
result: `${type}, ${demand}`
|
1450
1730
|
};
|
1451
1731
|
}
|
1452
|
-
const
|
1732
|
+
const memoryContext = this.getMemoryAsContext();
|
1733
|
+
const { data, usage } = await this.insight.extract(
|
1734
|
+
demandInput,
|
1735
|
+
opt,
|
1736
|
+
memoryContext
|
1737
|
+
// Hafıza bağlamını geç
|
1738
|
+
);
|
1453
1739
|
let outputResult = data;
|
1454
1740
|
if (ifTypeRestricted) {
|
1455
1741
|
assert4(data?.result !== void 0, "No result in query data");
|
@@ -1469,23 +1755,29 @@ var PageTaskExecutor = class {
|
|
1469
1755
|
executor: taskExecutor
|
1470
1756
|
};
|
1471
1757
|
}
|
1472
|
-
async query(demand) {
|
1473
|
-
return this.createTypeQueryTask("Query", demand);
|
1758
|
+
async query(demand, opt) {
|
1759
|
+
return this.createTypeQueryTask("Query", demand, opt);
|
1474
1760
|
}
|
1475
|
-
async boolean(prompt) {
|
1476
|
-
return this.createTypeQueryTask("Boolean", prompt);
|
1761
|
+
async boolean(prompt, opt) {
|
1762
|
+
return this.createTypeQueryTask("Boolean", prompt, opt);
|
1477
1763
|
}
|
1478
|
-
async number(prompt) {
|
1479
|
-
return this.createTypeQueryTask("Number", prompt);
|
1764
|
+
async number(prompt, opt) {
|
1765
|
+
return this.createTypeQueryTask("Number", prompt, opt);
|
1480
1766
|
}
|
1481
|
-
async string(prompt) {
|
1482
|
-
return this.createTypeQueryTask("String", prompt);
|
1767
|
+
async string(prompt, opt) {
|
1768
|
+
return this.createTypeQueryTask("String", prompt, opt);
|
1483
1769
|
}
|
1484
|
-
async assert(assertion) {
|
1770
|
+
async assert(assertion, memoryContext) {
|
1485
1771
|
const description = `assert: ${assertion}`;
|
1486
|
-
const
|
1487
|
-
|
1488
|
-
|
1772
|
+
const useMemory = true;
|
1773
|
+
let taskExecutor;
|
1774
|
+
if (useMemory) {
|
1775
|
+
taskExecutor = this.getPersistentExecutor();
|
1776
|
+
} else {
|
1777
|
+
taskExecutor = new Executor(taskTitleStr("Assert", description), {
|
1778
|
+
onTaskStart: this.onTaskStartCallback
|
1779
|
+
});
|
1780
|
+
}
|
1489
1781
|
const assertionPlan = {
|
1490
1782
|
type: "Assert",
|
1491
1783
|
param: {
|
@@ -1615,7 +1907,7 @@ function buildPlans(type, locateParam, param) {
|
|
1615
1907
|
param: locateParam,
|
1616
1908
|
thought: ""
|
1617
1909
|
} : null;
|
1618
|
-
if (type === "Tap" || type === "Hover") {
|
1910
|
+
if (type === "Tap" || type === "Hover" || type === "RightClick") {
|
1619
1911
|
assert5(locateParam, `missing locate info for action "${type}"`);
|
1620
1912
|
assert5(locatePlan, `missing locate info for action "${type}"`);
|
1621
1913
|
const tapPlan = {
|
@@ -1686,8 +1978,8 @@ function buildPlans(type, locateParam, param) {
|
|
1686
1978
|
|
1687
1979
|
// src/common/task-cache.ts
|
1688
1980
|
import assert6 from "assert";
|
1689
|
-
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
1690
|
-
import { join as join2 } from "path";
|
1981
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
1982
|
+
import { dirname as dirname2, join as join2 } from "path";
|
1691
1983
|
import { getMidsceneRunSubDir as getMidsceneRunSubDir2 } from "misoai-shared/common";
|
1692
1984
|
import { getDebug as getDebug3 } from "misoai-shared/logger";
|
1693
1985
|
import { ifInBrowser as ifInBrowser2 } from "misoai-shared/utils";
|
@@ -1695,7 +1987,7 @@ import yaml3 from "js-yaml";
|
|
1695
1987
|
import semver from "semver";
|
1696
1988
|
|
1697
1989
|
// package.json
|
1698
|
-
var version = "1.5.
|
1990
|
+
var version = "1.5.7";
|
1699
1991
|
|
1700
1992
|
// src/common/task-cache.ts
|
1701
1993
|
var debug3 = getDebug3("cache");
|
@@ -1826,8 +2118,14 @@ cache file: ${cacheFile}`
|
|
1826
2118
|
return;
|
1827
2119
|
}
|
1828
2120
|
try {
|
2121
|
+
const dir = dirname2(this.cacheFilePath);
|
2122
|
+
if (!existsSync2(dir)) {
|
2123
|
+
mkdirSync2(dir, { recursive: true });
|
2124
|
+
debug3("created cache directory: %s", dir);
|
2125
|
+
}
|
1829
2126
|
const yamlData = yaml3.dump(this.cache);
|
1830
2127
|
writeFileSync2(this.cacheFilePath, yamlData);
|
2128
|
+
debug3("cache flushed to file: %s", this.cacheFilePath);
|
1831
2129
|
} catch (err) {
|
1832
2130
|
debug3(
|
1833
2131
|
"write cache to file failed, path: %s, error: %s",
|
@@ -2085,6 +2383,23 @@ var PageAgent = class {
|
|
2085
2383
|
metadata
|
2086
2384
|
};
|
2087
2385
|
}
|
2386
|
+
async aiRightClick(locatePrompt, opt) {
|
2387
|
+
const detailedLocateParam = this.buildDetailedLocateParam(
|
2388
|
+
locatePrompt,
|
2389
|
+
opt
|
2390
|
+
);
|
2391
|
+
const plans = buildPlans("RightClick", detailedLocateParam);
|
2392
|
+
const { executor, output } = await this.taskExecutor.runPlans(
|
2393
|
+
taskTitleStr("RightClick", locateParamStr(detailedLocateParam)),
|
2394
|
+
plans,
|
2395
|
+
{ cacheable: opt?.cacheable }
|
2396
|
+
);
|
2397
|
+
const metadata = this.afterTaskRunning(executor);
|
2398
|
+
return {
|
2399
|
+
result: output,
|
2400
|
+
metadata
|
2401
|
+
};
|
2402
|
+
}
|
2088
2403
|
async aiInput(value, locatePrompt, opt) {
|
2089
2404
|
assert7(
|
2090
2405
|
typeof value === "string",
|
@@ -2159,7 +2474,13 @@ var PageAgent = class {
|
|
2159
2474
|
metadata: metadata2
|
2160
2475
|
};
|
2161
2476
|
}
|
2162
|
-
const
|
2477
|
+
const memoryContext = this.getMemoryAsContext();
|
2478
|
+
const enhancedActionContext = this.opts.aiActionContext ? `${this.opts.aiActionContext}
|
2479
|
+
|
2480
|
+
Previous workflow steps:
|
2481
|
+
${memoryContext}` : memoryContext ? `Previous workflow steps:
|
2482
|
+
${memoryContext}` : void 0;
|
2483
|
+
const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, enhancedActionContext, {
|
2163
2484
|
cacheable
|
2164
2485
|
}));
|
2165
2486
|
if (this.taskCache && output?.yamlFlow && cacheable !== false) {
|
@@ -2305,8 +2626,9 @@ var PageAgent = class {
|
|
2305
2626
|
} catch (e) {
|
2306
2627
|
}
|
2307
2628
|
}
|
2629
|
+
const memoryContext = this.getMemoryAsContext();
|
2308
2630
|
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2309
|
-
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2631
|
+
const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
|
2310
2632
|
const metadata = this.afterTaskRunning(executor, true);
|
2311
2633
|
if (output && opt?.keepRawResponse) {
|
2312
2634
|
return {
|
@@ -2516,9 +2838,72 @@ ${errors}`);
|
|
2516
2838
|
}
|
2517
2839
|
throw new Error("evaluateJavaScript is not supported in current agent");
|
2518
2840
|
}
|
2841
|
+
async logScreenshot(title, options) {
|
2842
|
+
const screenshotTitle = title || "untitled";
|
2843
|
+
const content = options?.content || "";
|
2844
|
+
const screenshot = await this.page.screenshotBase64?.();
|
2845
|
+
if (screenshot) {
|
2846
|
+
const executionDump = {
|
2847
|
+
name: screenshotTitle,
|
2848
|
+
description: content,
|
2849
|
+
tasks: [{
|
2850
|
+
type: "Screenshot",
|
2851
|
+
subType: "log",
|
2852
|
+
status: "finished",
|
2853
|
+
executor: null,
|
2854
|
+
param: {
|
2855
|
+
title: screenshotTitle,
|
2856
|
+
content
|
2857
|
+
},
|
2858
|
+
output: {
|
2859
|
+
screenshot
|
2860
|
+
},
|
2861
|
+
thought: `Logged screenshot: ${screenshotTitle}`,
|
2862
|
+
timing: {
|
2863
|
+
start: Date.now(),
|
2864
|
+
end: Date.now(),
|
2865
|
+
cost: 0
|
2866
|
+
}
|
2867
|
+
}],
|
2868
|
+
sdkVersion: "1.0.0",
|
2869
|
+
logTime: Date.now(),
|
2870
|
+
model_name: "screenshot"
|
2871
|
+
};
|
2872
|
+
this.appendExecutionDump(executionDump);
|
2873
|
+
}
|
2874
|
+
}
|
2519
2875
|
async destroy() {
|
2520
2876
|
await this.page.destroy();
|
2521
2877
|
}
|
2878
|
+
/**
|
2879
|
+
* Hafızayı bağlam olarak formatlar
|
2880
|
+
*/
|
2881
|
+
getMemoryAsContext() {
|
2882
|
+
const memory = this.taskExecutor.getMemory();
|
2883
|
+
if (memory.length === 0) {
|
2884
|
+
return "";
|
2885
|
+
}
|
2886
|
+
const recentMemory = memory.slice(-5);
|
2887
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
2888
|
+
}
|
2889
|
+
/**
|
2890
|
+
* Mevcut hafızayı döndürür
|
2891
|
+
*/
|
2892
|
+
getMemory() {
|
2893
|
+
return this.taskExecutor.getMemory();
|
2894
|
+
}
|
2895
|
+
/**
|
2896
|
+
* Hafıza istatistiklerini döndürür
|
2897
|
+
*/
|
2898
|
+
getMemoryStats() {
|
2899
|
+
return this.taskExecutor.getMemoryStats();
|
2900
|
+
}
|
2901
|
+
/**
|
2902
|
+
* Hafızayı temizler
|
2903
|
+
*/
|
2904
|
+
clearMemory() {
|
2905
|
+
this.taskExecutor.clearMemory();
|
2906
|
+
}
|
2522
2907
|
};
|
2523
2908
|
|
2524
2909
|
// src/puppeteer/index.ts
|