misoai-web 1.5.7 → 1.5.9
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 +410 -25
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +3 -3
- package/dist/es/bridge-mode.js +412 -27
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +411 -26
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +410 -25
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +410 -25
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/playground.js +410 -25
- package/dist/es/playground.js.map +1 -1
- package/dist/es/playwright.js +410 -25
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +410 -25
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +410 -25
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/lib/agent.js +410 -25
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +3 -3
- package/dist/lib/bridge-mode.js +412 -27
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +411 -26
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +410 -25
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +410 -25
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/playground.js +410 -25
- package/dist/lib/playground.js.map +1 -1
- package/dist/lib/playwright.js +410 -25
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +410 -25
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +410 -25
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/types/agent.d.ts +107 -2
- package/package.json +2 -2
package/dist/lib/index.js
CHANGED
@@ -646,6 +646,94 @@ var replanningCountLimit = 10;
|
|
646
646
|
var isAndroidPage = (page) => {
|
647
647
|
return page.pageType === "android";
|
648
648
|
};
|
649
|
+
var WorkflowMemory = class {
|
650
|
+
constructor(config) {
|
651
|
+
this.workflows = /* @__PURE__ */ new Map();
|
652
|
+
this.config = config;
|
653
|
+
}
|
654
|
+
/**
|
655
|
+
* İş akışı hafızasını getirir
|
656
|
+
*/
|
657
|
+
getWorkflowMemory(workflowId = "default") {
|
658
|
+
const workflow = this.workflows.get(workflowId);
|
659
|
+
return workflow?.memory || [];
|
660
|
+
}
|
661
|
+
/**
|
662
|
+
* İş akışı verilerini getirir
|
663
|
+
*/
|
664
|
+
getWorkflowData(workflowId = "default") {
|
665
|
+
return this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
666
|
+
}
|
667
|
+
/**
|
668
|
+
* İş akışı hafızasını kaydeder
|
669
|
+
*/
|
670
|
+
saveWorkflowMemory(memory, workflowId = "default") {
|
671
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
672
|
+
workflow.memory = [...memory];
|
673
|
+
workflow.metadata.totalSteps = workflow.steps.length;
|
674
|
+
workflow.metadata.completedSteps = workflow.steps.filter((s) => s.status === "completed").length;
|
675
|
+
workflow.metadata.failedSteps = workflow.steps.filter((s) => s.status === "failed").length;
|
676
|
+
this.workflows.set(workflowId, workflow);
|
677
|
+
this.enforceRetentionPolicy();
|
678
|
+
}
|
679
|
+
/**
|
680
|
+
* İş akışı bağlamını günceller
|
681
|
+
*/
|
682
|
+
updateWorkflowContext(context, workflowId = "default") {
|
683
|
+
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
684
|
+
workflow.context = { ...workflow.context, ...context };
|
685
|
+
if (context.currentStep) {
|
686
|
+
const existingStep = workflow.steps.find((s) => s.stepName === context.currentStep);
|
687
|
+
if (!existingStep) {
|
688
|
+
workflow.steps.push({
|
689
|
+
stepId: `step_${workflow.steps.length + 1}`,
|
690
|
+
stepName: context.currentStep,
|
691
|
+
timestamp: context.timestamp,
|
692
|
+
status: "running",
|
693
|
+
memoryItems: []
|
694
|
+
});
|
695
|
+
}
|
696
|
+
}
|
697
|
+
this.workflows.set(workflowId, workflow);
|
698
|
+
}
|
699
|
+
/**
|
700
|
+
* İş akışını temizler
|
701
|
+
*/
|
702
|
+
clearWorkflow(workflowId = "default") {
|
703
|
+
this.workflows.delete(workflowId);
|
704
|
+
}
|
705
|
+
/**
|
706
|
+
* Tüm iş akışlarını temizler
|
707
|
+
*/
|
708
|
+
clearAll() {
|
709
|
+
this.workflows.clear();
|
710
|
+
}
|
711
|
+
createEmptyWorkflowData(workflowId) {
|
712
|
+
return {
|
713
|
+
workflowId,
|
714
|
+
steps: [],
|
715
|
+
memory: [],
|
716
|
+
context: {
|
717
|
+
pageInfo: { url: "", title: "" },
|
718
|
+
timestamp: Date.now()
|
719
|
+
},
|
720
|
+
metadata: {
|
721
|
+
totalSteps: 0,
|
722
|
+
completedSteps: 0,
|
723
|
+
failedSteps: 0,
|
724
|
+
startTime: Date.now()
|
725
|
+
}
|
726
|
+
};
|
727
|
+
}
|
728
|
+
enforceRetentionPolicy() {
|
729
|
+
const maxWorkflows = 10;
|
730
|
+
if (this.workflows.size > maxWorkflows) {
|
731
|
+
const sortedWorkflows = Array.from(this.workflows.entries()).sort(([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime));
|
732
|
+
const toDelete = sortedWorkflows.slice(maxWorkflows);
|
733
|
+
toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
|
734
|
+
}
|
735
|
+
}
|
736
|
+
};
|
649
737
|
var PageTaskExecutor = class {
|
650
738
|
constructor(page, insight, opts) {
|
651
739
|
this.conversationHistory = [];
|
@@ -653,6 +741,25 @@ var PageTaskExecutor = class {
|
|
653
741
|
this.insight = insight;
|
654
742
|
this.taskCache = opts.taskCache;
|
655
743
|
this.onTaskStartCallback = opts?.onTaskStart;
|
744
|
+
this.memoryConfig = {
|
745
|
+
maxItems: 100,
|
746
|
+
maxAge: 2 * 60 * 60 * 1e3,
|
747
|
+
// 2 saat
|
748
|
+
enablePersistence: true,
|
749
|
+
enableAnalytics: true,
|
750
|
+
filterStrategy: "hybrid",
|
751
|
+
...opts?.memoryConfig
|
752
|
+
};
|
753
|
+
this.sessionContext = {
|
754
|
+
sessionId: opts?.sessionId || this.generateSessionId(),
|
755
|
+
workflowId: opts?.workflowId,
|
756
|
+
startTime: Date.now(),
|
757
|
+
pageInfo: {
|
758
|
+
url: "",
|
759
|
+
title: ""
|
760
|
+
}
|
761
|
+
};
|
762
|
+
this.workflowMemory = new WorkflowMemory(this.memoryConfig);
|
656
763
|
}
|
657
764
|
async recordScreenshot(timing) {
|
658
765
|
const base64 = await this.page.screenshotBase64();
|
@@ -865,8 +972,11 @@ var PageTaskExecutor = class {
|
|
865
972
|
insightDump = dump;
|
866
973
|
};
|
867
974
|
this.insight.onceDumpUpdatedFn = dumpCollector;
|
975
|
+
const memoryContext = this.getMemoryAsContext();
|
868
976
|
const assertion = await this.insight.assert(
|
869
|
-
assertPlan.param.assertion
|
977
|
+
assertPlan.param.assertion,
|
978
|
+
memoryContext
|
979
|
+
// Hafıza bağlamını geç
|
870
980
|
);
|
871
981
|
if (!assertion.pass) {
|
872
982
|
if (plan2.type === "Assert") {
|
@@ -1352,25 +1462,146 @@ var PageTaskExecutor = class {
|
|
1352
1462
|
};
|
1353
1463
|
return task;
|
1354
1464
|
}
|
1465
|
+
/**
|
1466
|
+
* Persistent executor'ı getirir veya oluşturur
|
1467
|
+
*/
|
1468
|
+
getPersistentExecutor() {
|
1469
|
+
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1470
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
|
1471
|
+
this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
|
1472
|
+
onTaskStart: this.onTaskStartCallback,
|
1473
|
+
initialMemory: previousMemory
|
1474
|
+
});
|
1475
|
+
}
|
1476
|
+
return this.persistentExecutor;
|
1477
|
+
}
|
1478
|
+
/**
|
1479
|
+
* Sayfa bağlamını günceller
|
1480
|
+
*/
|
1481
|
+
async updatePageContext() {
|
1482
|
+
try {
|
1483
|
+
if (this.page.url) {
|
1484
|
+
this.sessionContext.pageInfo.url = await this.page.url();
|
1485
|
+
}
|
1486
|
+
if (this.page.pageType === "puppeteer" || this.page.pageType === "playwright") {
|
1487
|
+
this.sessionContext.pageInfo.title = await this.page.title();
|
1488
|
+
}
|
1489
|
+
} catch (e) {
|
1490
|
+
}
|
1491
|
+
}
|
1492
|
+
/**
|
1493
|
+
* Hafızayı temizler
|
1494
|
+
*/
|
1495
|
+
clearMemory() {
|
1496
|
+
if (this.persistentExecutor) {
|
1497
|
+
this.persistentExecutor.clearMemory();
|
1498
|
+
}
|
1499
|
+
this.workflowMemory.clearWorkflow(this.sessionContext.workflowId || "default");
|
1500
|
+
}
|
1501
|
+
/**
|
1502
|
+
* Mevcut hafızayı döndürür
|
1503
|
+
*/
|
1504
|
+
getMemory() {
|
1505
|
+
return this.persistentExecutor?.getMemory() || [];
|
1506
|
+
}
|
1507
|
+
/**
|
1508
|
+
* İş akışı hafızasını döndürür
|
1509
|
+
*/
|
1510
|
+
getWorkflowMemory() {
|
1511
|
+
return this.workflowMemory.getWorkflowData(this.sessionContext.workflowId || "default");
|
1512
|
+
}
|
1513
|
+
/**
|
1514
|
+
* Hafıza istatistiklerini döndürür
|
1515
|
+
*/
|
1516
|
+
getMemoryStats() {
|
1517
|
+
return this.persistentExecutor?.getMemoryStats() || {
|
1518
|
+
totalItems: 0,
|
1519
|
+
analytics: { totalTasks: 0, memoryHits: 0, memoryMisses: 0, averageMemorySize: 0, memoryEffectiveness: 0 },
|
1520
|
+
config: this.memoryConfig
|
1521
|
+
};
|
1522
|
+
}
|
1523
|
+
/**
|
1524
|
+
* Hafıza konfigürasyonunu günceller
|
1525
|
+
*/
|
1526
|
+
updateMemoryConfig(config) {
|
1527
|
+
this.memoryConfig = { ...this.memoryConfig, ...config };
|
1528
|
+
if (this.persistentExecutor) {
|
1529
|
+
this.persistentExecutor.updateMemoryConfig(this.memoryConfig);
|
1530
|
+
}
|
1531
|
+
}
|
1532
|
+
/**
|
1533
|
+
* Oturum ID'sini oluşturur
|
1534
|
+
*/
|
1535
|
+
generateSessionId() {
|
1536
|
+
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
1537
|
+
}
|
1538
|
+
/**
|
1539
|
+
* Hafızayı bağlam olarak formatlar
|
1540
|
+
*/
|
1541
|
+
getMemoryAsContext() {
|
1542
|
+
const memory = this.getMemory();
|
1543
|
+
if (memory.length === 0) {
|
1544
|
+
return "";
|
1545
|
+
}
|
1546
|
+
const recentMemory = memory.slice(-5);
|
1547
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
1548
|
+
}
|
1355
1549
|
async runPlans(title, plans, opts) {
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1550
|
+
await this.updatePageContext();
|
1551
|
+
const useMemory = opts?.useMemory !== false;
|
1552
|
+
let taskExecutor;
|
1553
|
+
if (useMemory) {
|
1554
|
+
taskExecutor = this.getPersistentExecutor();
|
1555
|
+
this.workflowMemory.updateWorkflowContext({
|
1556
|
+
currentStep: title,
|
1557
|
+
pageInfo: this.sessionContext.pageInfo,
|
1558
|
+
timestamp: Date.now()
|
1559
|
+
}, this.sessionContext.workflowId || "default");
|
1560
|
+
} else {
|
1561
|
+
taskExecutor = new import_misoai_core.Executor(title, {
|
1562
|
+
onTaskStart: this.onTaskStartCallback
|
1563
|
+
});
|
1564
|
+
}
|
1359
1565
|
const { tasks } = await this.convertPlanToExecutable(plans, opts);
|
1566
|
+
tasks.forEach((task) => {
|
1567
|
+
task.context = {
|
1568
|
+
...task.context,
|
1569
|
+
...this.sessionContext.pageInfo,
|
1570
|
+
workflowId: this.sessionContext.workflowId,
|
1571
|
+
sessionId: this.sessionContext.sessionId
|
1572
|
+
};
|
1573
|
+
});
|
1360
1574
|
await taskExecutor.append(tasks);
|
1361
1575
|
const result = await taskExecutor.flush();
|
1576
|
+
if (useMemory) {
|
1577
|
+
this.workflowMemory.saveWorkflowMemory(
|
1578
|
+
taskExecutor.getMemory(),
|
1579
|
+
this.sessionContext.workflowId || "default"
|
1580
|
+
);
|
1581
|
+
}
|
1362
1582
|
return {
|
1363
1583
|
output: result,
|
1364
1584
|
executor: taskExecutor
|
1365
1585
|
};
|
1366
1586
|
}
|
1367
1587
|
async action(userPrompt, actionContext, opts) {
|
1368
|
-
const
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1588
|
+
const useMemory = true;
|
1589
|
+
let taskExecutor;
|
1590
|
+
if (useMemory) {
|
1591
|
+
taskExecutor = this.getPersistentExecutor();
|
1592
|
+
} else {
|
1593
|
+
taskExecutor = new import_misoai_core.Executor(taskTitleStr("Action", userPrompt), {
|
1594
|
+
onTaskStart: this.onTaskStartCallback
|
1595
|
+
});
|
1596
|
+
}
|
1597
|
+
const memoryContext = this.getMemoryAsContext();
|
1598
|
+
const initialLog = memoryContext ? memoryContext : void 0;
|
1599
|
+
let planningTask = this.planningTaskFromPrompt(userPrompt, initialLog, actionContext);
|
1372
1600
|
let replanCount = 0;
|
1373
1601
|
const logList = [];
|
1602
|
+
if (memoryContext) {
|
1603
|
+
logList.push(memoryContext);
|
1604
|
+
}
|
1374
1605
|
const yamlFlow = [];
|
1375
1606
|
while (planningTask) {
|
1376
1607
|
if (replanCount > replanningCountLimit) {
|
@@ -1480,15 +1711,21 @@ var PageTaskExecutor = class {
|
|
1480
1711
|
};
|
1481
1712
|
}
|
1482
1713
|
async createTypeQueryTask(type, demand, opt) {
|
1483
|
-
const
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1714
|
+
const useMemory = true;
|
1715
|
+
let taskExecutor;
|
1716
|
+
if (useMemory) {
|
1717
|
+
taskExecutor = this.getPersistentExecutor();
|
1718
|
+
} else {
|
1719
|
+
taskExecutor = new import_misoai_core.Executor(
|
1720
|
+
taskTitleStr(
|
1721
|
+
type,
|
1722
|
+
typeof demand === "string" ? demand : JSON.stringify(demand)
|
1723
|
+
),
|
1724
|
+
{
|
1725
|
+
onTaskStart: this.onTaskStartCallback
|
1726
|
+
}
|
1727
|
+
);
|
1728
|
+
}
|
1492
1729
|
const queryTask = {
|
1493
1730
|
type: "Insight",
|
1494
1731
|
subType: type,
|
@@ -1510,9 +1747,12 @@ var PageTaskExecutor = class {
|
|
1510
1747
|
result: `${type}, ${demand}`
|
1511
1748
|
};
|
1512
1749
|
}
|
1750
|
+
const memoryContext = this.getMemoryAsContext();
|
1513
1751
|
const { data, usage } = await this.insight.extract(
|
1514
1752
|
demandInput,
|
1515
|
-
opt
|
1753
|
+
opt,
|
1754
|
+
memoryContext
|
1755
|
+
// Hafıza bağlamını geç
|
1516
1756
|
);
|
1517
1757
|
let outputResult = data;
|
1518
1758
|
if (ifTypeRestricted) {
|
@@ -1545,11 +1785,17 @@ var PageTaskExecutor = class {
|
|
1545
1785
|
async string(prompt, opt) {
|
1546
1786
|
return this.createTypeQueryTask("String", prompt, opt);
|
1547
1787
|
}
|
1548
|
-
async assert(assertion) {
|
1788
|
+
async assert(assertion, memoryContext) {
|
1549
1789
|
const description = `assert: ${assertion}`;
|
1550
|
-
const
|
1551
|
-
|
1552
|
-
|
1790
|
+
const useMemory = true;
|
1791
|
+
let taskExecutor;
|
1792
|
+
if (useMemory) {
|
1793
|
+
taskExecutor = this.getPersistentExecutor();
|
1794
|
+
} else {
|
1795
|
+
taskExecutor = new import_misoai_core.Executor(taskTitleStr("Assert", description), {
|
1796
|
+
onTaskStart: this.onTaskStartCallback
|
1797
|
+
});
|
1798
|
+
}
|
1553
1799
|
const assertionPlan = {
|
1554
1800
|
type: "Assert",
|
1555
1801
|
param: {
|
@@ -1759,7 +2005,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
|
|
1759
2005
|
var import_semver = __toESM(require("semver"));
|
1760
2006
|
|
1761
2007
|
// package.json
|
1762
|
-
var version = "1.
|
2008
|
+
var version = "1.5.8";
|
1763
2009
|
|
1764
2010
|
// src/common/task-cache.ts
|
1765
2011
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -2246,7 +2492,13 @@ var PageAgent = class {
|
|
2246
2492
|
metadata: metadata2
|
2247
2493
|
};
|
2248
2494
|
}
|
2249
|
-
const
|
2495
|
+
const memoryContext = this.getMemoryAsContext();
|
2496
|
+
const enhancedActionContext = this.opts.aiActionContext ? `${this.opts.aiActionContext}
|
2497
|
+
|
2498
|
+
Previous workflow steps:
|
2499
|
+
${memoryContext}` : memoryContext ? `Previous workflow steps:
|
2500
|
+
${memoryContext}` : void 0;
|
2501
|
+
const { output, executor } = await (isVlmUiTars ? this.taskExecutor.actionToGoal(taskPrompt, { cacheable }) : this.taskExecutor.action(taskPrompt, enhancedActionContext, {
|
2250
2502
|
cacheable
|
2251
2503
|
}));
|
2252
2504
|
if (this.taskCache && output?.yamlFlow && cacheable !== false) {
|
@@ -2392,8 +2644,9 @@ var PageAgent = class {
|
|
2392
2644
|
} catch (e) {
|
2393
2645
|
}
|
2394
2646
|
}
|
2647
|
+
const memoryContext = this.getMemoryAsContext();
|
2395
2648
|
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2396
|
-
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2649
|
+
const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
|
2397
2650
|
const metadata = this.afterTaskRunning(executor, true);
|
2398
2651
|
if (output && opt?.keepRawResponse) {
|
2399
2652
|
return {
|
@@ -2640,6 +2893,138 @@ ${errors}`);
|
|
2640
2893
|
async destroy() {
|
2641
2894
|
await this.page.destroy();
|
2642
2895
|
}
|
2896
|
+
/**
|
2897
|
+
* Hafızayı bağlam olarak formatlar
|
2898
|
+
*/
|
2899
|
+
getMemoryAsContext() {
|
2900
|
+
const memory = this.taskExecutor.getMemory();
|
2901
|
+
if (memory.length === 0) {
|
2902
|
+
return "";
|
2903
|
+
}
|
2904
|
+
const recentMemory = memory.slice(-5);
|
2905
|
+
return recentMemory.map((item) => `- ${item.summary}`).join("\n");
|
2906
|
+
}
|
2907
|
+
/**
|
2908
|
+
* Mevcut hafızayı döndürür
|
2909
|
+
*/
|
2910
|
+
getMemory() {
|
2911
|
+
return this.taskExecutor.getMemory();
|
2912
|
+
}
|
2913
|
+
/**
|
2914
|
+
* Hafıza istatistiklerini döndürür
|
2915
|
+
*/
|
2916
|
+
getMemoryStats() {
|
2917
|
+
return this.taskExecutor.getMemoryStats();
|
2918
|
+
}
|
2919
|
+
/**
|
2920
|
+
* Hafızayı temizler
|
2921
|
+
*/
|
2922
|
+
clearMemory() {
|
2923
|
+
this.taskExecutor.clearMemory();
|
2924
|
+
}
|
2925
|
+
/**
|
2926
|
+
* Test sonunda kullanım için detaylı hafıza raporu döndürür (JSON formatında)
|
2927
|
+
*/
|
2928
|
+
getMemoryReport() {
|
2929
|
+
const memory = this.getMemory();
|
2930
|
+
const stats = this.getMemoryStats();
|
2931
|
+
return {
|
2932
|
+
summary: {
|
2933
|
+
totalItems: memory.length,
|
2934
|
+
totalTasks: stats.analytics.totalTasks,
|
2935
|
+
memoryHits: stats.analytics.memoryHits,
|
2936
|
+
memoryMisses: stats.analytics.memoryMisses,
|
2937
|
+
memoryEffectiveness: Math.round(stats.analytics.memoryEffectiveness * 100),
|
2938
|
+
averageMemorySize: Math.round(stats.analytics.averageMemorySize * 100) / 100
|
2939
|
+
},
|
2940
|
+
config: stats.config,
|
2941
|
+
items: memory.map((item) => ({
|
2942
|
+
id: item.id,
|
2943
|
+
timestamp: item.timestamp,
|
2944
|
+
taskType: item.taskType,
|
2945
|
+
summary: item.summary,
|
2946
|
+
context: item.context,
|
2947
|
+
metadata: item.metadata,
|
2948
|
+
tags: item.tags,
|
2949
|
+
relativeTime: this.formatRelativeTime(item.timestamp)
|
2950
|
+
})),
|
2951
|
+
analytics: {
|
2952
|
+
taskTypeDistribution: this.getTaskTypeDistribution(memory),
|
2953
|
+
successRate: this.calculateSuccessRate(memory),
|
2954
|
+
averageExecutionTime: this.calculateAverageExecutionTime(memory),
|
2955
|
+
dataExtractionCount: this.countDataExtractions(memory),
|
2956
|
+
workflowSteps: this.extractWorkflowSteps(memory)
|
2957
|
+
}
|
2958
|
+
};
|
2959
|
+
}
|
2960
|
+
/**
|
2961
|
+
* Test sonunda kullanım için basit hafıza özeti döndürür (JSON formatında)
|
2962
|
+
*/
|
2963
|
+
getMemorySummary() {
|
2964
|
+
const memory = this.getMemory();
|
2965
|
+
const stats = this.getMemoryStats();
|
2966
|
+
return {
|
2967
|
+
totalItems: memory.length,
|
2968
|
+
memoryEffectiveness: `${Math.round(stats.analytics.memoryEffectiveness * 100)}%`,
|
2969
|
+
taskTypes: this.getTaskTypeDistribution(memory),
|
2970
|
+
recentSteps: memory.slice(-5).map((item) => ({
|
2971
|
+
step: item.summary,
|
2972
|
+
type: item.taskType,
|
2973
|
+
success: item.metadata?.success || false,
|
2974
|
+
time: this.formatRelativeTime(item.timestamp)
|
2975
|
+
})),
|
2976
|
+
dataExtracted: this.getExtractedDataSummary(memory)
|
2977
|
+
};
|
2978
|
+
}
|
2979
|
+
formatRelativeTime(timestamp) {
|
2980
|
+
const now = Date.now();
|
2981
|
+
const diff = now - timestamp;
|
2982
|
+
const seconds = Math.floor(diff / 1e3);
|
2983
|
+
const minutes = Math.floor(seconds / 60);
|
2984
|
+
const hours = Math.floor(minutes / 60);
|
2985
|
+
if (hours > 0)
|
2986
|
+
return `${hours}h ${minutes % 60}m ago`;
|
2987
|
+
if (minutes > 0)
|
2988
|
+
return `${minutes}m ${seconds % 60}s ago`;
|
2989
|
+
return `${seconds}s ago`;
|
2990
|
+
}
|
2991
|
+
getTaskTypeDistribution(memory) {
|
2992
|
+
const distribution = {};
|
2993
|
+
memory.forEach((item) => {
|
2994
|
+
distribution[item.taskType] = (distribution[item.taskType] || 0) + 1;
|
2995
|
+
});
|
2996
|
+
return distribution;
|
2997
|
+
}
|
2998
|
+
calculateSuccessRate(memory) {
|
2999
|
+
if (memory.length === 0)
|
3000
|
+
return 0;
|
3001
|
+
const successCount = memory.filter((item) => item.metadata?.success !== false).length;
|
3002
|
+
return Math.round(successCount / memory.length * 100);
|
3003
|
+
}
|
3004
|
+
calculateAverageExecutionTime(memory) {
|
3005
|
+
const executionTimes = memory.map((item) => item.metadata?.executionTime).filter((time) => typeof time === "number");
|
3006
|
+
if (executionTimes.length === 0)
|
3007
|
+
return 0;
|
3008
|
+
const average = executionTimes.reduce((sum, time) => sum + time, 0) / executionTimes.length;
|
3009
|
+
return Math.round(average);
|
3010
|
+
}
|
3011
|
+
countDataExtractions(memory) {
|
3012
|
+
return memory.filter(
|
3013
|
+
(item) => item.context?.dataExtracted || item.taskType === "Insight" && item.summary.includes("Extracted")
|
3014
|
+
).length;
|
3015
|
+
}
|
3016
|
+
extractWorkflowSteps(memory) {
|
3017
|
+
return memory.map((item) => item.summary);
|
3018
|
+
}
|
3019
|
+
getExtractedDataSummary(memory) {
|
3020
|
+
const extractedData = {};
|
3021
|
+
memory.forEach((item, index) => {
|
3022
|
+
if (item.context?.dataExtracted) {
|
3023
|
+
extractedData[`step_${index + 1}`] = item.context.dataExtracted;
|
3024
|
+
}
|
3025
|
+
});
|
3026
|
+
return extractedData;
|
3027
|
+
}
|
2643
3028
|
};
|
2644
3029
|
|
2645
3030
|
// src/puppeteer/base-page.ts
|