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
@@ -648,6 +648,94 @@ var replanningCountLimit = 10;
|
|
648
648
|
var isAndroidPage = (page) => {
|
649
649
|
return page.pageType === "android";
|
650
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
|
+
};
|
651
739
|
var PageTaskExecutor = class {
|
652
740
|
constructor(page, insight, opts) {
|
653
741
|
this.conversationHistory = [];
|
@@ -655,6 +743,25 @@ var PageTaskExecutor = class {
|
|
655
743
|
this.insight = insight;
|
656
744
|
this.taskCache = opts.taskCache;
|
657
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);
|
658
765
|
}
|
659
766
|
async recordScreenshot(timing) {
|
660
767
|
const base64 = await this.page.screenshotBase64();
|
@@ -867,8 +974,11 @@ var PageTaskExecutor = class {
|
|
867
974
|
insightDump = dump;
|
868
975
|
};
|
869
976
|
this.insight.onceDumpUpdatedFn = dumpCollector;
|
977
|
+
const memoryContext = this.getMemoryAsContext();
|
870
978
|
const assertion = await this.insight.assert(
|
871
|
-
assertPlan.param.assertion
|
979
|
+
assertPlan.param.assertion,
|
980
|
+
memoryContext
|
981
|
+
// Hafıza bağlamını geç
|
872
982
|
);
|
873
983
|
if (!assertion.pass) {
|
874
984
|
if (plan2.type === "Assert") {
|
@@ -1354,25 +1464,146 @@ var PageTaskExecutor = class {
|
|
1354
1464
|
};
|
1355
1465
|
return task;
|
1356
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
|
+
}
|
1357
1551
|
async runPlans(title, plans, opts) {
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
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
|
+
}
|
1361
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
|
+
});
|
1362
1576
|
await taskExecutor.append(tasks);
|
1363
1577
|
const result = await taskExecutor.flush();
|
1578
|
+
if (useMemory) {
|
1579
|
+
this.workflowMemory.saveWorkflowMemory(
|
1580
|
+
taskExecutor.getMemory(),
|
1581
|
+
this.sessionContext.workflowId || "default"
|
1582
|
+
);
|
1583
|
+
}
|
1364
1584
|
return {
|
1365
1585
|
output: result,
|
1366
1586
|
executor: taskExecutor
|
1367
1587
|
};
|
1368
1588
|
}
|
1369
1589
|
async action(userPrompt, actionContext, opts) {
|
1370
|
-
const
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
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);
|
1374
1602
|
let replanCount = 0;
|
1375
1603
|
const logList = [];
|
1604
|
+
if (memoryContext) {
|
1605
|
+
logList.push(memoryContext);
|
1606
|
+
}
|
1376
1607
|
const yamlFlow = [];
|
1377
1608
|
while (planningTask) {
|
1378
1609
|
if (replanCount > replanningCountLimit) {
|
@@ -1482,15 +1713,21 @@ var PageTaskExecutor = class {
|
|
1482
1713
|
};
|
1483
1714
|
}
|
1484
1715
|
async createTypeQueryTask(type, demand, opt) {
|
1485
|
-
const
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
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
|
+
}
|
1494
1731
|
const queryTask = {
|
1495
1732
|
type: "Insight",
|
1496
1733
|
subType: type,
|
@@ -1512,9 +1749,12 @@ var PageTaskExecutor = class {
|
|
1512
1749
|
result: `${type}, ${demand}`
|
1513
1750
|
};
|
1514
1751
|
}
|
1752
|
+
const memoryContext = this.getMemoryAsContext();
|
1515
1753
|
const { data, usage } = await this.insight.extract(
|
1516
1754
|
demandInput,
|
1517
|
-
opt
|
1755
|
+
opt,
|
1756
|
+
memoryContext
|
1757
|
+
// Hafıza bağlamını geç
|
1518
1758
|
);
|
1519
1759
|
let outputResult = data;
|
1520
1760
|
if (ifTypeRestricted) {
|
@@ -1547,11 +1787,17 @@ var PageTaskExecutor = class {
|
|
1547
1787
|
async string(prompt, opt) {
|
1548
1788
|
return this.createTypeQueryTask("String", prompt, opt);
|
1549
1789
|
}
|
1550
|
-
async assert(assertion) {
|
1790
|
+
async assert(assertion, memoryContext) {
|
1551
1791
|
const description = `assert: ${assertion}`;
|
1552
|
-
const
|
1553
|
-
|
1554
|
-
|
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
|
+
}
|
1555
1801
|
const assertionPlan = {
|
1556
1802
|
type: "Assert",
|
1557
1803
|
param: {
|
@@ -1761,7 +2007,7 @@ var import_js_yaml3 = __toESM(require("js-yaml"));
|
|
1761
2007
|
var import_semver = __toESM(require("semver"));
|
1762
2008
|
|
1763
2009
|
// package.json
|
1764
|
-
var version = "1.
|
2010
|
+
var version = "1.5.8";
|
1765
2011
|
|
1766
2012
|
// src/common/task-cache.ts
|
1767
2013
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -2248,7 +2494,13 @@ var PageAgent = class {
|
|
2248
2494
|
metadata: metadata2
|
2249
2495
|
};
|
2250
2496
|
}
|
2251
|
-
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, {
|
2252
2504
|
cacheable
|
2253
2505
|
}));
|
2254
2506
|
if (this.taskCache && output?.yamlFlow && cacheable !== false) {
|
@@ -2394,8 +2646,9 @@ var PageAgent = class {
|
|
2394
2646
|
} catch (e) {
|
2395
2647
|
}
|
2396
2648
|
}
|
2649
|
+
const memoryContext = this.getMemoryAsContext();
|
2397
2650
|
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2398
|
-
const { output, executor } = await this.taskExecutor.assert(assertionWithContext);
|
2651
|
+
const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
|
2399
2652
|
const metadata = this.afterTaskRunning(executor, true);
|
2400
2653
|
if (output && opt?.keepRawResponse) {
|
2401
2654
|
return {
|
@@ -2642,6 +2895,138 @@ ${errors}`);
|
|
2642
2895
|
async destroy() {
|
2643
2896
|
await this.page.destroy();
|
2644
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
|
+
}
|
2927
|
+
/**
|
2928
|
+
* Test sonunda kullanım için detaylı hafıza raporu döndürür (JSON formatında)
|
2929
|
+
*/
|
2930
|
+
getMemoryReport() {
|
2931
|
+
const memory = this.getMemory();
|
2932
|
+
const stats = this.getMemoryStats();
|
2933
|
+
return {
|
2934
|
+
summary: {
|
2935
|
+
totalItems: memory.length,
|
2936
|
+
totalTasks: stats.analytics.totalTasks,
|
2937
|
+
memoryHits: stats.analytics.memoryHits,
|
2938
|
+
memoryMisses: stats.analytics.memoryMisses,
|
2939
|
+
memoryEffectiveness: Math.round(stats.analytics.memoryEffectiveness * 100),
|
2940
|
+
averageMemorySize: Math.round(stats.analytics.averageMemorySize * 100) / 100
|
2941
|
+
},
|
2942
|
+
config: stats.config,
|
2943
|
+
items: memory.map((item) => ({
|
2944
|
+
id: item.id,
|
2945
|
+
timestamp: item.timestamp,
|
2946
|
+
taskType: item.taskType,
|
2947
|
+
summary: item.summary,
|
2948
|
+
context: item.context,
|
2949
|
+
metadata: item.metadata,
|
2950
|
+
tags: item.tags,
|
2951
|
+
relativeTime: this.formatRelativeTime(item.timestamp)
|
2952
|
+
})),
|
2953
|
+
analytics: {
|
2954
|
+
taskTypeDistribution: this.getTaskTypeDistribution(memory),
|
2955
|
+
successRate: this.calculateSuccessRate(memory),
|
2956
|
+
averageExecutionTime: this.calculateAverageExecutionTime(memory),
|
2957
|
+
dataExtractionCount: this.countDataExtractions(memory),
|
2958
|
+
workflowSteps: this.extractWorkflowSteps(memory)
|
2959
|
+
}
|
2960
|
+
};
|
2961
|
+
}
|
2962
|
+
/**
|
2963
|
+
* Test sonunda kullanım için basit hafıza özeti döndürür (JSON formatında)
|
2964
|
+
*/
|
2965
|
+
getMemorySummary() {
|
2966
|
+
const memory = this.getMemory();
|
2967
|
+
const stats = this.getMemoryStats();
|
2968
|
+
return {
|
2969
|
+
totalItems: memory.length,
|
2970
|
+
memoryEffectiveness: `${Math.round(stats.analytics.memoryEffectiveness * 100)}%`,
|
2971
|
+
taskTypes: this.getTaskTypeDistribution(memory),
|
2972
|
+
recentSteps: memory.slice(-5).map((item) => ({
|
2973
|
+
step: item.summary,
|
2974
|
+
type: item.taskType,
|
2975
|
+
success: item.metadata?.success || false,
|
2976
|
+
time: this.formatRelativeTime(item.timestamp)
|
2977
|
+
})),
|
2978
|
+
dataExtracted: this.getExtractedDataSummary(memory)
|
2979
|
+
};
|
2980
|
+
}
|
2981
|
+
formatRelativeTime(timestamp) {
|
2982
|
+
const now = Date.now();
|
2983
|
+
const diff = now - timestamp;
|
2984
|
+
const seconds = Math.floor(diff / 1e3);
|
2985
|
+
const minutes = Math.floor(seconds / 60);
|
2986
|
+
const hours = Math.floor(minutes / 60);
|
2987
|
+
if (hours > 0)
|
2988
|
+
return `${hours}h ${minutes % 60}m ago`;
|
2989
|
+
if (minutes > 0)
|
2990
|
+
return `${minutes}m ${seconds % 60}s ago`;
|
2991
|
+
return `${seconds}s ago`;
|
2992
|
+
}
|
2993
|
+
getTaskTypeDistribution(memory) {
|
2994
|
+
const distribution = {};
|
2995
|
+
memory.forEach((item) => {
|
2996
|
+
distribution[item.taskType] = (distribution[item.taskType] || 0) + 1;
|
2997
|
+
});
|
2998
|
+
return distribution;
|
2999
|
+
}
|
3000
|
+
calculateSuccessRate(memory) {
|
3001
|
+
if (memory.length === 0)
|
3002
|
+
return 0;
|
3003
|
+
const successCount = memory.filter((item) => item.metadata?.success !== false).length;
|
3004
|
+
return Math.round(successCount / memory.length * 100);
|
3005
|
+
}
|
3006
|
+
calculateAverageExecutionTime(memory) {
|
3007
|
+
const executionTimes = memory.map((item) => item.metadata?.executionTime).filter((time) => typeof time === "number");
|
3008
|
+
if (executionTimes.length === 0)
|
3009
|
+
return 0;
|
3010
|
+
const average = executionTimes.reduce((sum, time) => sum + time, 0) / executionTimes.length;
|
3011
|
+
return Math.round(average);
|
3012
|
+
}
|
3013
|
+
countDataExtractions(memory) {
|
3014
|
+
return memory.filter(
|
3015
|
+
(item) => item.context?.dataExtracted || item.taskType === "Insight" && item.summary.includes("Extracted")
|
3016
|
+
).length;
|
3017
|
+
}
|
3018
|
+
extractWorkflowSteps(memory) {
|
3019
|
+
return memory.map((item) => item.summary);
|
3020
|
+
}
|
3021
|
+
getExtractedDataSummary(memory) {
|
3022
|
+
const extractedData = {};
|
3023
|
+
memory.forEach((item, index) => {
|
3024
|
+
if (item.context?.dataExtracted) {
|
3025
|
+
extractedData[`step_${index + 1}`] = item.context.dataExtracted;
|
3026
|
+
}
|
3027
|
+
});
|
3028
|
+
return extractedData;
|
3029
|
+
}
|
2645
3030
|
};
|
2646
3031
|
|
2647
3032
|
// src/puppeteer/index.ts
|