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
@@ -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(/[
|
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
|
-
|
1264
|
-
|
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
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
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
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
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
|
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
|
1455
|
-
|
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.
|
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
|
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
|