misoai-web 1.6.0 → 1.6.2
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 +108 -50
- package/dist/es/agent.js.map +1 -1
- package/dist/es/bridge-mode-browser.js +3 -3
- package/dist/es/bridge-mode-browser.js.map +1 -1
- package/dist/es/bridge-mode.js +110 -52
- package/dist/es/bridge-mode.js.map +1 -1
- package/dist/es/chrome-extension.js +109 -51
- package/dist/es/chrome-extension.js.map +1 -1
- package/dist/es/index.js +425 -68
- package/dist/es/index.js.map +1 -1
- package/dist/es/midscene-playground.js +111 -53
- package/dist/es/midscene-playground.js.map +1 -1
- package/dist/es/midscene-server.js +4 -4
- package/dist/es/midscene-server.js.map +1 -1
- package/dist/es/playground.js +108 -50
- 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 +425 -68
- package/dist/es/playwright.js.map +1 -1
- package/dist/es/puppeteer-agent-launcher.js +424 -67
- package/dist/es/puppeteer-agent-launcher.js.map +1 -1
- package/dist/es/puppeteer.js +424 -67
- package/dist/es/puppeteer.js.map +1 -1
- package/dist/es/utils.js +1 -1
- package/dist/es/utils.js.map +1 -1
- package/dist/es/yaml.js +1 -1
- package/dist/es/yaml.js.map +1 -1
- package/dist/lib/agent.js +108 -50
- package/dist/lib/agent.js.map +1 -1
- package/dist/lib/bridge-mode-browser.js +3 -3
- package/dist/lib/bridge-mode-browser.js.map +1 -1
- package/dist/lib/bridge-mode.js +110 -52
- package/dist/lib/bridge-mode.js.map +1 -1
- package/dist/lib/chrome-extension.js +109 -51
- package/dist/lib/chrome-extension.js.map +1 -1
- package/dist/lib/index.js +425 -68
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/midscene-playground.js +111 -53
- package/dist/lib/midscene-playground.js.map +1 -1
- package/dist/lib/midscene-server.js +4 -4
- package/dist/lib/midscene-server.js.map +1 -1
- package/dist/lib/playground.js +108 -50
- 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 +425 -68
- package/dist/lib/playwright.js.map +1 -1
- package/dist/lib/puppeteer-agent-launcher.js +424 -67
- package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
- package/dist/lib/puppeteer.js +424 -67
- package/dist/lib/puppeteer.js.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/lib/yaml.js +1 -1
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent.d.ts +1 -1
- package/dist/types/bridge-mode-browser.d.ts +2 -2
- package/dist/types/bridge-mode.d.ts +2 -2
- package/dist/types/{browser-9b472ffb.d.ts → browser-f205f69d.d.ts} +1 -1
- package/dist/types/chrome-extension.d.ts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/midscene-server.d.ts +1 -1
- package/dist/types/{page-ed0ecb44.d.ts → page-c5452809.d.ts} +45 -0
- package/dist/types/playground.d.ts +2 -2
- package/dist/types/playwright.d.ts +2 -2
- package/dist/types/puppeteer-agent-launcher.d.ts +1 -1
- package/dist/types/puppeteer.d.ts +2 -2
- package/dist/types/utils.d.ts +1 -1
- package/dist/types/yaml.d.ts +1 -1
- package/package.json +18 -54
package/dist/lib/puppeteer.js
CHANGED
@@ -344,8 +344,8 @@ var ScriptPlayer = class {
|
|
344
344
|
var import_js_yaml = __toESM(require("js-yaml"));
|
345
345
|
|
346
346
|
// src/yaml/utils.ts
|
347
|
-
var import_utils2 = require("misoai-shared/utils");
|
348
347
|
var import_js_yaml2 = __toESM(require("js-yaml"));
|
348
|
+
var import_utils2 = require("misoai-shared/utils");
|
349
349
|
function interpolateEnvVars(content) {
|
350
350
|
return content.replace(/\$\{([^}]+)\}/g, (_, envVar) => {
|
351
351
|
const value = process.env[envVar.trim()];
|
@@ -491,13 +491,13 @@ function paramStr(task) {
|
|
491
491
|
}
|
492
492
|
|
493
493
|
// src/common/utils.ts
|
494
|
+
var import_dayjs = __toESM(require("dayjs"));
|
494
495
|
var import_ai_model = require("misoai-core/ai-model");
|
495
496
|
var import_utils3 = require("misoai-core/utils");
|
496
497
|
var import_env = require("misoai-shared/env");
|
497
498
|
var import_extractor = require("misoai-shared/extractor");
|
498
499
|
var import_img = require("misoai-shared/img");
|
499
500
|
var import_utils4 = require("misoai-shared/utils");
|
500
|
-
var import_dayjs = __toESM(require("dayjs"));
|
501
501
|
|
502
502
|
// src/web-element.ts
|
503
503
|
var WebElementInfo = class {
|
@@ -666,8 +666,12 @@ var WorkflowMemory = class {
|
|
666
666
|
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
667
667
|
workflow.memory = [...memory];
|
668
668
|
workflow.metadata.totalSteps = workflow.steps.length;
|
669
|
-
workflow.metadata.completedSteps = workflow.steps.filter(
|
670
|
-
|
669
|
+
workflow.metadata.completedSteps = workflow.steps.filter(
|
670
|
+
(s) => s.status === "completed"
|
671
|
+
).length;
|
672
|
+
workflow.metadata.failedSteps = workflow.steps.filter(
|
673
|
+
(s) => s.status === "failed"
|
674
|
+
).length;
|
671
675
|
this.workflows.set(workflowId, workflow);
|
672
676
|
this.enforceRetentionPolicy();
|
673
677
|
}
|
@@ -678,7 +682,9 @@ var WorkflowMemory = class {
|
|
678
682
|
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
679
683
|
workflow.context = { ...workflow.context, ...context };
|
680
684
|
if (context.currentStep) {
|
681
|
-
const existingStep = workflow.steps.find(
|
685
|
+
const existingStep = workflow.steps.find(
|
686
|
+
(s) => s.stepName === context.currentStep
|
687
|
+
);
|
682
688
|
if (!existingStep) {
|
683
689
|
workflow.steps.push({
|
684
690
|
stepId: `step_${workflow.steps.length + 1}`,
|
@@ -723,7 +729,9 @@ var WorkflowMemory = class {
|
|
723
729
|
enforceRetentionPolicy() {
|
724
730
|
const maxWorkflows = 10;
|
725
731
|
if (this.workflows.size > maxWorkflows) {
|
726
|
-
const sortedWorkflows = Array.from(this.workflows.entries()).sort(
|
732
|
+
const sortedWorkflows = Array.from(this.workflows.entries()).sort(
|
733
|
+
([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime)
|
734
|
+
);
|
727
735
|
const toDelete = sortedWorkflows.slice(maxWorkflows);
|
728
736
|
toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
|
729
737
|
}
|
@@ -1290,6 +1298,7 @@ var PageTaskExecutor = class {
|
|
1290
1298
|
actions: [],
|
1291
1299
|
more_actions_needed_by_instruction: false,
|
1292
1300
|
log: "",
|
1301
|
+
summary: "Loaded YAML workflow configuration",
|
1293
1302
|
yamlString
|
1294
1303
|
},
|
1295
1304
|
cache: {
|
@@ -1391,6 +1400,7 @@ var PageTaskExecutor = class {
|
|
1391
1400
|
actions: finalActions,
|
1392
1401
|
more_actions_needed_by_instruction,
|
1393
1402
|
log: log2,
|
1403
|
+
summary: planResult.summary || "Generated action plan from user instruction",
|
1394
1404
|
yamlFlow: planResult.yamlFlow
|
1395
1405
|
},
|
1396
1406
|
cache: {
|
@@ -1446,6 +1456,7 @@ var PageTaskExecutor = class {
|
|
1446
1456
|
actionType: actions[0].type,
|
1447
1457
|
more_actions_needed_by_instruction: true,
|
1448
1458
|
log: "",
|
1459
|
+
summary: action_summary || "Generated VLM action plan",
|
1449
1460
|
yamlFlow: planResult.yamlFlow
|
1450
1461
|
},
|
1451
1462
|
cache: {
|
@@ -1462,7 +1473,9 @@ var PageTaskExecutor = class {
|
|
1462
1473
|
*/
|
1463
1474
|
getPersistentExecutor() {
|
1464
1475
|
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1465
|
-
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1476
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1477
|
+
this.sessionContext.workflowId
|
1478
|
+
);
|
1466
1479
|
this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
|
1467
1480
|
onTaskStart: this.onTaskStartCallback,
|
1468
1481
|
initialMemory: previousMemory
|
@@ -1491,7 +1504,9 @@ var PageTaskExecutor = class {
|
|
1491
1504
|
if (this.persistentExecutor) {
|
1492
1505
|
this.persistentExecutor.clearMemory();
|
1493
1506
|
}
|
1494
|
-
this.workflowMemory.clearWorkflow(
|
1507
|
+
this.workflowMemory.clearWorkflow(
|
1508
|
+
this.sessionContext.workflowId || "default"
|
1509
|
+
);
|
1495
1510
|
}
|
1496
1511
|
/**
|
1497
1512
|
* Mevcut hafızayı döndürür
|
@@ -1503,7 +1518,9 @@ var PageTaskExecutor = class {
|
|
1503
1518
|
* İş akışı hafızasını döndürür
|
1504
1519
|
*/
|
1505
1520
|
getWorkflowMemory() {
|
1506
|
-
return this.workflowMemory.getWorkflowData(
|
1521
|
+
return this.workflowMemory.getWorkflowData(
|
1522
|
+
this.sessionContext.workflowId || "default"
|
1523
|
+
);
|
1507
1524
|
}
|
1508
1525
|
/**
|
1509
1526
|
* Hafıza istatistiklerini döndürür
|
@@ -1511,7 +1528,13 @@ var PageTaskExecutor = class {
|
|
1511
1528
|
getMemoryStats() {
|
1512
1529
|
return this.persistentExecutor?.getMemoryStats() || {
|
1513
1530
|
totalItems: 0,
|
1514
|
-
analytics: {
|
1531
|
+
analytics: {
|
1532
|
+
totalTasks: 0,
|
1533
|
+
memoryHits: 0,
|
1534
|
+
memoryMisses: 0,
|
1535
|
+
averageMemorySize: 0,
|
1536
|
+
memoryEffectiveness: 0
|
1537
|
+
},
|
1515
1538
|
config: this.memoryConfig
|
1516
1539
|
};
|
1517
1540
|
}
|
@@ -1547,11 +1570,14 @@ var PageTaskExecutor = class {
|
|
1547
1570
|
let taskExecutor;
|
1548
1571
|
if (useMemory) {
|
1549
1572
|
taskExecutor = this.getPersistentExecutor();
|
1550
|
-
this.workflowMemory.updateWorkflowContext(
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1573
|
+
this.workflowMemory.updateWorkflowContext(
|
1574
|
+
{
|
1575
|
+
currentStep: title,
|
1576
|
+
pageInfo: this.sessionContext.pageInfo,
|
1577
|
+
timestamp: Date.now()
|
1578
|
+
},
|
1579
|
+
this.sessionContext.workflowId || "default"
|
1580
|
+
);
|
1555
1581
|
} else {
|
1556
1582
|
taskExecutor = new import_misoai_core.Executor(title, {
|
1557
1583
|
onTaskStart: this.onTaskStartCallback
|
@@ -1917,14 +1943,19 @@ var PageTaskExecutor = class {
|
|
1917
1943
|
*/
|
1918
1944
|
addToMemory(memoryItem) {
|
1919
1945
|
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1920
|
-
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1946
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1947
|
+
this.sessionContext.workflowId
|
1948
|
+
);
|
1921
1949
|
this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
|
1922
1950
|
onTaskStart: this.onTaskStartCallback,
|
1923
1951
|
initialMemory: previousMemory
|
1924
1952
|
});
|
1925
1953
|
}
|
1926
1954
|
this.persistentExecutor.memoryStore?.add(memoryItem);
|
1927
|
-
this.persistentExecutor.memoryAnalytics?.recordMemoryOperation(
|
1955
|
+
this.persistentExecutor.memoryAnalytics?.recordMemoryOperation(
|
1956
|
+
"add",
|
1957
|
+
memoryItem
|
1958
|
+
);
|
1928
1959
|
}
|
1929
1960
|
};
|
1930
1961
|
|
@@ -2013,14 +2044,14 @@ function buildPlans(type, locateParam, param) {
|
|
2013
2044
|
var import_node_assert = __toESM(require("assert"));
|
2014
2045
|
var import_node_fs2 = require("fs");
|
2015
2046
|
var import_node_path2 = require("path");
|
2047
|
+
var import_js_yaml3 = __toESM(require("js-yaml"));
|
2016
2048
|
var import_common2 = require("misoai-shared/common");
|
2017
2049
|
var import_logger3 = require("misoai-shared/logger");
|
2018
2050
|
var import_utils9 = require("misoai-shared/utils");
|
2019
|
-
var import_js_yaml3 = __toESM(require("js-yaml"));
|
2020
2051
|
var import_semver = __toESM(require("semver"));
|
2021
2052
|
|
2022
2053
|
// package.json
|
2023
|
-
var version = "1.6.
|
2054
|
+
var version = "1.6.2";
|
2024
2055
|
|
2025
2056
|
// src/common/task-cache.ts
|
2026
2057
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -2315,22 +2346,28 @@ var PageAgent = class {
|
|
2315
2346
|
const allThoughts = executor.tasks.filter((task) => task.thought).map((task) => task.thought);
|
2316
2347
|
const allLocates = executor.tasks.filter((task) => task.locate).map((task) => task.locate);
|
2317
2348
|
const allPlans = executor.tasks.filter((task) => task.param?.plans).map((task) => task.param?.plans);
|
2318
|
-
const planningTasks = executor.tasks.filter(
|
2319
|
-
|
2349
|
+
const planningTasks = executor.tasks.filter(
|
2350
|
+
(task) => task.type === "Planning"
|
2351
|
+
);
|
2352
|
+
const insightTasks = executor.tasks.filter(
|
2353
|
+
(task) => task.type === "Insight"
|
2354
|
+
);
|
2320
2355
|
const actionTasks = executor.tasks.filter((task) => task.type === "Action");
|
2321
2356
|
const planning = planningTasks.length > 0 ? {
|
2322
2357
|
type: "Planning",
|
2323
|
-
description:
|
2358
|
+
description: "Planning for task execution",
|
2324
2359
|
steps: planningTasks.map((task) => task.thought || "Planning step")
|
2325
2360
|
} : void 0;
|
2326
2361
|
const insight = insightTasks.length > 0 ? {
|
2327
2362
|
type: "Insight",
|
2328
|
-
description:
|
2329
|
-
elements: insightTasks.map(
|
2363
|
+
description: "Insight for task execution",
|
2364
|
+
elements: insightTasks.map(
|
2365
|
+
(task) => task.thought || "Insight element"
|
2366
|
+
)
|
2330
2367
|
} : void 0;
|
2331
2368
|
const action = actionTasks.length > 0 ? {
|
2332
2369
|
type: "Action",
|
2333
|
-
description:
|
2370
|
+
description: "Action for task execution",
|
2334
2371
|
result: lastTask?.output
|
2335
2372
|
} : void 0;
|
2336
2373
|
const actionDetails = executor.tasks.map((task) => ({
|
@@ -2664,7 +2701,10 @@ ${memoryContext}` : void 0;
|
|
2664
2701
|
}
|
2665
2702
|
const memoryContext = this.getMemoryAsContext();
|
2666
2703
|
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2667
|
-
const { output, executor } = await this.taskExecutor.assert(
|
2704
|
+
const { output, executor } = await this.taskExecutor.assert(
|
2705
|
+
assertionWithContext,
|
2706
|
+
memoryContext
|
2707
|
+
);
|
2668
2708
|
const metadata = this.afterTaskRunning(executor, true);
|
2669
2709
|
if (output && opt?.keepRawResponse) {
|
2670
2710
|
return {
|
@@ -2703,7 +2743,10 @@ A complex CAPTCHA typically has one or more of these characteristics:
|
|
2703
2743
|
Return only "complex" or "simple" based on your analysis.
|
2704
2744
|
`;
|
2705
2745
|
const complexityMsgs = [
|
2706
|
-
{
|
2746
|
+
{
|
2747
|
+
role: "system",
|
2748
|
+
content: "You are an AI assistant that analyzes screenshots to determine CAPTCHA complexity."
|
2749
|
+
},
|
2707
2750
|
{
|
2708
2751
|
role: "user",
|
2709
2752
|
content: [
|
@@ -2727,7 +2770,12 @@ Return only "complex" or "simple" based on your analysis.
|
|
2727
2770
|
);
|
2728
2771
|
const responseText = typeof complexityResult.content === "string" ? complexityResult.content.toLowerCase() : JSON.stringify(complexityResult.content).toLowerCase();
|
2729
2772
|
shouldUseDeepThink = responseText.includes("complex");
|
2730
|
-
debug4(
|
2773
|
+
debug4(
|
2774
|
+
"CAPTCHA complexity analysis:",
|
2775
|
+
responseText,
|
2776
|
+
"Using deep think:",
|
2777
|
+
shouldUseDeepThink
|
2778
|
+
);
|
2731
2779
|
} catch (error) {
|
2732
2780
|
debug4("Failed to analyze CAPTCHA complexity:", error);
|
2733
2781
|
}
|
@@ -2744,7 +2792,9 @@ Return only "complex" or "simple" based on your analysis.
|
|
2744
2792
|
await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
|
2745
2793
|
} else if (action.type === "input" && action.value) {
|
2746
2794
|
if (action.target) {
|
2747
|
-
await this.aiInput(action.value, action.target, {
|
2795
|
+
await this.aiInput(action.value, action.target, {
|
2796
|
+
deepThink: shouldUseDeepThink
|
2797
|
+
});
|
2748
2798
|
}
|
2749
2799
|
} else if (action.type === "verify" && action.target) {
|
2750
2800
|
await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
|
@@ -2756,7 +2806,9 @@ Return only "complex" or "simple" based on your analysis.
|
|
2756
2806
|
if (action.coordinates) {
|
2757
2807
|
const x = action.coordinates[0];
|
2758
2808
|
const y = action.coordinates[1];
|
2759
|
-
await this.aiTap(`element at coordinates (${x}, ${y})`, {
|
2809
|
+
await this.aiTap(`element at coordinates (${x}, ${y})`, {
|
2810
|
+
deepThink: shouldUseDeepThink
|
2811
|
+
});
|
2760
2812
|
} else if (action.target) {
|
2761
2813
|
await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
|
2762
2814
|
}
|
@@ -2908,25 +2960,27 @@ ${errors}`);
|
|
2908
2960
|
const executionDump = {
|
2909
2961
|
name: screenshotTitle,
|
2910
2962
|
description: content,
|
2911
|
-
tasks: [
|
2912
|
-
|
2913
|
-
|
2914
|
-
|
2915
|
-
|
2916
|
-
|
2917
|
-
|
2918
|
-
|
2919
|
-
|
2920
|
-
|
2921
|
-
|
2922
|
-
|
2923
|
-
|
2924
|
-
|
2925
|
-
|
2926
|
-
|
2927
|
-
|
2963
|
+
tasks: [
|
2964
|
+
{
|
2965
|
+
type: "Screenshot",
|
2966
|
+
subType: "log",
|
2967
|
+
status: "finished",
|
2968
|
+
executor: null,
|
2969
|
+
param: {
|
2970
|
+
title: screenshotTitle,
|
2971
|
+
content
|
2972
|
+
},
|
2973
|
+
output: {
|
2974
|
+
screenshot
|
2975
|
+
},
|
2976
|
+
thought: `Logged screenshot: ${screenshotTitle}`,
|
2977
|
+
timing: {
|
2978
|
+
start: Date.now(),
|
2979
|
+
end: Date.now(),
|
2980
|
+
cost: 0
|
2981
|
+
}
|
2928
2982
|
}
|
2929
|
-
|
2983
|
+
],
|
2930
2984
|
sdkVersion: "1.0.0",
|
2931
2985
|
logTime: Date.now(),
|
2932
2986
|
model_name: "screenshot"
|
@@ -2978,7 +3032,9 @@ ${errors}`);
|
|
2978
3032
|
totalTasks: stats.analytics.totalTasks,
|
2979
3033
|
memoryHits: stats.analytics.memoryHits,
|
2980
3034
|
memoryMisses: stats.analytics.memoryMisses,
|
2981
|
-
memoryEffectiveness: Math.round(
|
3035
|
+
memoryEffectiveness: Math.round(
|
3036
|
+
stats.analytics.memoryEffectiveness * 100
|
3037
|
+
),
|
2982
3038
|
averageMemorySize: Math.round(stats.analytics.averageMemorySize * 100) / 100
|
2983
3039
|
},
|
2984
3040
|
config: stats.config,
|
@@ -3042,7 +3098,9 @@ ${errors}`);
|
|
3042
3098
|
calculateSuccessRate(memory) {
|
3043
3099
|
if (memory.length === 0)
|
3044
3100
|
return 0;
|
3045
|
-
const successCount = memory.filter(
|
3101
|
+
const successCount = memory.filter(
|
3102
|
+
(item) => item.metadata?.success !== false
|
3103
|
+
).length;
|
3046
3104
|
return Math.round(successCount / memory.length * 100);
|
3047
3105
|
}
|
3048
3106
|
calculateAverageExecutionTime(memory) {
|
@@ -3084,13 +3142,236 @@ var import_extractor2 = require("misoai-shared/extractor");
|
|
3084
3142
|
var import_fs = require("misoai-shared/fs");
|
3085
3143
|
var import_logger5 = require("misoai-shared/logger");
|
3086
3144
|
var import_utils16 = require("misoai-shared/utils");
|
3145
|
+
|
3146
|
+
// src/common/mouse-utils.ts
|
3147
|
+
function generateHumanMousePath(from, to, options = {}) {
|
3148
|
+
const {
|
3149
|
+
steps = 20,
|
3150
|
+
easing = "easeInOut"
|
3151
|
+
} = options;
|
3152
|
+
if (steps <= 1) {
|
3153
|
+
return [to];
|
3154
|
+
}
|
3155
|
+
const path = [];
|
3156
|
+
const controlPoint1 = {
|
3157
|
+
x: from.x + (to.x - from.x) * 0.25 + (Math.random() - 0.5) * 50,
|
3158
|
+
y: from.y + (to.y - from.y) * 0.25 + (Math.random() - 0.5) * 50
|
3159
|
+
};
|
3160
|
+
const controlPoint2 = {
|
3161
|
+
x: from.x + (to.x - from.x) * 0.75 + (Math.random() - 0.5) * 50,
|
3162
|
+
y: from.y + (to.y - from.y) * 0.75 + (Math.random() - 0.5) * 50
|
3163
|
+
};
|
3164
|
+
for (let i = 0; i <= steps; i++) {
|
3165
|
+
const t = i / steps;
|
3166
|
+
const easedT = applyEasing(t, easing);
|
3167
|
+
const point = calculateBezierPoint(from, controlPoint1, controlPoint2, to, easedT);
|
3168
|
+
path.push(point);
|
3169
|
+
}
|
3170
|
+
return path;
|
3171
|
+
}
|
3172
|
+
function calculateBezierPoint(p0, p1, p2, p3, t) {
|
3173
|
+
const oneMinusT = 1 - t;
|
3174
|
+
const oneMinusTSquared = oneMinusT * oneMinusT;
|
3175
|
+
const oneMinusTCubed = oneMinusTSquared * oneMinusT;
|
3176
|
+
const tSquared = t * t;
|
3177
|
+
const tCubed = tSquared * t;
|
3178
|
+
return {
|
3179
|
+
x: oneMinusTCubed * p0.x + 3 * oneMinusTSquared * t * p1.x + 3 * oneMinusT * tSquared * p2.x + tCubed * p3.x,
|
3180
|
+
y: oneMinusTCubed * p0.y + 3 * oneMinusTSquared * t * p1.y + 3 * oneMinusT * tSquared * p2.y + tCubed * p3.y
|
3181
|
+
};
|
3182
|
+
}
|
3183
|
+
function applyEasing(t, easing) {
|
3184
|
+
switch (easing) {
|
3185
|
+
case "linear":
|
3186
|
+
return t;
|
3187
|
+
case "easeIn":
|
3188
|
+
return t * t;
|
3189
|
+
case "easeOut":
|
3190
|
+
return 1 - (1 - t) * (1 - t);
|
3191
|
+
case "easeInOut":
|
3192
|
+
return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
|
3193
|
+
default:
|
3194
|
+
return t;
|
3195
|
+
}
|
3196
|
+
}
|
3197
|
+
function calculateStepDelay(totalDuration, currentStep, totalSteps) {
|
3198
|
+
const baseDelay = totalDuration / totalSteps;
|
3199
|
+
const variation = 0.3;
|
3200
|
+
const randomFactor = 1 + (Math.random() - 0.5) * variation;
|
3201
|
+
return Math.max(1, baseDelay * randomFactor);
|
3202
|
+
}
|
3203
|
+
|
3204
|
+
// src/common/visual-feedback.ts
|
3205
|
+
function getMousePointerScript(x, y, options = {}) {
|
3206
|
+
const {
|
3207
|
+
pointerSize = 20,
|
3208
|
+
pointerColor = "#ff4444",
|
3209
|
+
trailLength = 5,
|
3210
|
+
showTrail = true,
|
3211
|
+
animationDuration = 200
|
3212
|
+
} = options;
|
3213
|
+
return `
|
3214
|
+
(() => {
|
3215
|
+
// Create or update mouse pointer
|
3216
|
+
if (!window.misoaiMousePointer) {
|
3217
|
+
const pointer = document.createElement('div');
|
3218
|
+
pointer.id = 'misoai-mouse-pointer';
|
3219
|
+
pointer.style.cssText = \`
|
3220
|
+
position: fixed;
|
3221
|
+
width: ${pointerSize}px;
|
3222
|
+
height: ${pointerSize}px;
|
3223
|
+
background: ${pointerColor};
|
3224
|
+
border: 2px solid white;
|
3225
|
+
border-radius: 50%;
|
3226
|
+
pointer-events: none;
|
3227
|
+
z-index: 999999;
|
3228
|
+
box-shadow: 0 0 10px rgba(0,0,0,0.3);
|
3229
|
+
transition: all ${animationDuration}ms ease-out;
|
3230
|
+
transform: translate(-50%, -50%);
|
3231
|
+
\`;
|
3232
|
+
document.body.appendChild(pointer);
|
3233
|
+
window.misoaiMousePointer = pointer;
|
3234
|
+
|
3235
|
+
// Initialize trail array
|
3236
|
+
window.misoaiMouseTrail = [];
|
3237
|
+
}
|
3238
|
+
|
3239
|
+
const pointer = window.misoaiMousePointer;
|
3240
|
+
pointer.style.left = ${x}px;
|
3241
|
+
pointer.style.top = ${y}px;
|
3242
|
+
|
3243
|
+
${showTrail ? getTrailScript(x, y, trailLength, pointerColor) : ""}
|
3244
|
+
|
3245
|
+
// Auto-hide after 3 seconds of inactivity
|
3246
|
+
clearTimeout(window.misoaiMouseTimeout);
|
3247
|
+
pointer.style.opacity = '1';
|
3248
|
+
window.misoaiMouseTimeout = setTimeout(() => {
|
3249
|
+
if (pointer) pointer.style.opacity = '0.3';
|
3250
|
+
}, 3000);
|
3251
|
+
})();
|
3252
|
+
`;
|
3253
|
+
}
|
3254
|
+
function getTrailScript(x, y, trailLength, color) {
|
3255
|
+
return `
|
3256
|
+
// Add current position to trail
|
3257
|
+
window.misoaiMouseTrail.push({ x: ${x}, y: ${y}, timestamp: Date.now() });
|
3258
|
+
|
3259
|
+
// Keep only recent trail points
|
3260
|
+
if (window.misoaiMouseTrail.length > ${trailLength}) {
|
3261
|
+
window.misoaiMouseTrail.shift();
|
3262
|
+
}
|
3263
|
+
|
3264
|
+
// Remove old trail elements
|
3265
|
+
document.querySelectorAll('.misoai-mouse-trail').forEach(el => el.remove());
|
3266
|
+
|
3267
|
+
// Create new trail elements
|
3268
|
+
window.misoaiMouseTrail.forEach((point, index) => {
|
3269
|
+
if (index === window.misoaiMouseTrail.length - 1) return; // Skip current position
|
3270
|
+
|
3271
|
+
const trailElement = document.createElement('div');
|
3272
|
+
trailElement.className = 'misoai-mouse-trail';
|
3273
|
+
const opacity = (index + 1) / window.misoaiMouseTrail.length * 0.6;
|
3274
|
+
const size = 8 + (index + 1) / window.misoaiMouseTrail.length * 8;
|
3275
|
+
|
3276
|
+
trailElement.style.cssText = \`
|
3277
|
+
position: fixed;
|
3278
|
+
width: \${size}px;
|
3279
|
+
height: \${size}px;
|
3280
|
+
background: ${color};
|
3281
|
+
border-radius: 50%;
|
3282
|
+
pointer-events: none;
|
3283
|
+
z-index: 999998;
|
3284
|
+
opacity: \${opacity};
|
3285
|
+
transform: translate(-50%, -50%);
|
3286
|
+
left: \${point.x}px;
|
3287
|
+
top: \${point.y}px;
|
3288
|
+
\`;
|
3289
|
+
|
3290
|
+
document.body.appendChild(trailElement);
|
3291
|
+
|
3292
|
+
// Auto-remove trail element after animation
|
3293
|
+
setTimeout(() => {
|
3294
|
+
if (trailElement.parentNode) {
|
3295
|
+
trailElement.parentNode.removeChild(trailElement);
|
3296
|
+
}
|
3297
|
+
}, 1000);
|
3298
|
+
});
|
3299
|
+
`;
|
3300
|
+
}
|
3301
|
+
function getClickAnimationScript(x, y) {
|
3302
|
+
return `
|
3303
|
+
(() => {
|
3304
|
+
const clickRipple = document.createElement('div');
|
3305
|
+
clickRipple.style.cssText = \`
|
3306
|
+
position: fixed;
|
3307
|
+
left: ${x}px;
|
3308
|
+
top: ${y}px;
|
3309
|
+
width: 0;
|
3310
|
+
height: 0;
|
3311
|
+
border: 2px solid #ff4444;
|
3312
|
+
border-radius: 50%;
|
3313
|
+
pointer-events: none;
|
3314
|
+
z-index: 999999;
|
3315
|
+
transform: translate(-50%, -50%);
|
3316
|
+
animation: misoai-click-ripple 0.6s ease-out forwards;
|
3317
|
+
\`;
|
3318
|
+
|
3319
|
+
// Add CSS animation if not exists
|
3320
|
+
if (!document.getElementById('misoai-click-styles')) {
|
3321
|
+
const style = document.createElement('style');
|
3322
|
+
style.id = 'misoai-click-styles';
|
3323
|
+
style.textContent = \`
|
3324
|
+
@keyframes misoai-click-ripple {
|
3325
|
+
0% {
|
3326
|
+
width: 0;
|
3327
|
+
height: 0;
|
3328
|
+
opacity: 1;
|
3329
|
+
}
|
3330
|
+
100% {
|
3331
|
+
width: 40px;
|
3332
|
+
height: 40px;
|
3333
|
+
opacity: 0;
|
3334
|
+
}
|
3335
|
+
}
|
3336
|
+
\`;
|
3337
|
+
document.head.appendChild(style);
|
3338
|
+
}
|
3339
|
+
|
3340
|
+
document.body.appendChild(clickRipple);
|
3341
|
+
|
3342
|
+
// Remove after animation
|
3343
|
+
setTimeout(() => {
|
3344
|
+
if (clickRipple.parentNode) {
|
3345
|
+
clickRipple.parentNode.removeChild(clickRipple);
|
3346
|
+
}
|
3347
|
+
}, 600);
|
3348
|
+
})();
|
3349
|
+
`;
|
3350
|
+
}
|
3351
|
+
|
3352
|
+
// src/puppeteer/base-page.ts
|
3087
3353
|
var debugPage = (0, import_logger5.getDebug)("web:page");
|
3088
3354
|
var Page = class {
|
3089
3355
|
constructor(underlyingPage, pageType, opts) {
|
3356
|
+
this.currentMousePosition = { x: 0, y: 0 };
|
3357
|
+
this.mouseMovementOptions = {
|
3358
|
+
steps: 15,
|
3359
|
+
duration: 300,
|
3360
|
+
easing: "easeInOut",
|
3361
|
+
showVisualFeedback: true
|
3362
|
+
};
|
3363
|
+
this.visualFeedbackOptions = {
|
3364
|
+
pointerSize: 16,
|
3365
|
+
pointerColor: "#ff4444",
|
3366
|
+
trailLength: 4,
|
3367
|
+
showTrail: true,
|
3368
|
+
animationDuration: 150
|
3369
|
+
};
|
3090
3370
|
this.everMoved = false;
|
3091
3371
|
this.underlyingPage = underlyingPage;
|
3092
3372
|
this.pageType = pageType;
|
3093
3373
|
this.waitForNavigationTimeout = opts?.waitForNavigationTimeout ?? import_constants3.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
3374
|
+
this.initializeMousePosition();
|
3094
3375
|
}
|
3095
3376
|
async evaluate(pageFunction, arg) {
|
3096
3377
|
let result;
|
@@ -3109,9 +3390,76 @@ var Page = class {
|
|
3109
3390
|
debugPage("evaluate function end");
|
3110
3391
|
return result;
|
3111
3392
|
}
|
3393
|
+
/**
|
3394
|
+
* Initialize mouse position to center of viewport
|
3395
|
+
*/
|
3396
|
+
async initializeMousePosition() {
|
3397
|
+
try {
|
3398
|
+
const size = await this.size();
|
3399
|
+
this.currentMousePosition = {
|
3400
|
+
x: Math.floor(size.width / 2),
|
3401
|
+
y: Math.floor(size.height / 2)
|
3402
|
+
};
|
3403
|
+
} catch (error) {
|
3404
|
+
this.currentMousePosition = { x: 400, y: 300 };
|
3405
|
+
}
|
3406
|
+
}
|
3112
3407
|
async evaluateJavaScript(script) {
|
3113
3408
|
return this.evaluate(script);
|
3114
3409
|
}
|
3410
|
+
/**
|
3411
|
+
* Show visual feedback for mouse pointer
|
3412
|
+
*/
|
3413
|
+
async showMousePointer(x, y) {
|
3414
|
+
if (!this.mouseMovementOptions.showVisualFeedback)
|
3415
|
+
return;
|
3416
|
+
const script = getMousePointerScript(x, y, this.visualFeedbackOptions);
|
3417
|
+
try {
|
3418
|
+
await this.evaluate(script);
|
3419
|
+
} catch (error) {
|
3420
|
+
debugPage("Visual feedback error:", error);
|
3421
|
+
}
|
3422
|
+
}
|
3423
|
+
/**
|
3424
|
+
* Show click animation
|
3425
|
+
*/
|
3426
|
+
async showClickAnimation(x, y) {
|
3427
|
+
if (!this.mouseMovementOptions.showVisualFeedback)
|
3428
|
+
return;
|
3429
|
+
const script = getClickAnimationScript(x, y);
|
3430
|
+
try {
|
3431
|
+
await this.evaluate(script);
|
3432
|
+
} catch (error) {
|
3433
|
+
debugPage("Click animation error:", error);
|
3434
|
+
}
|
3435
|
+
}
|
3436
|
+
/**
|
3437
|
+
* Move mouse with human-like movement and visual feedback
|
3438
|
+
*/
|
3439
|
+
async moveMouseHumanLike(toX, toY, options) {
|
3440
|
+
const moveOptions = { ...this.mouseMovementOptions, ...options };
|
3441
|
+
const path = generateHumanMousePath(
|
3442
|
+
this.currentMousePosition,
|
3443
|
+
{ x: toX, y: toY },
|
3444
|
+
moveOptions
|
3445
|
+
);
|
3446
|
+
for (let i = 0; i < path.length; i++) {
|
3447
|
+
const point = path[i];
|
3448
|
+
if (moveOptions.showVisualFeedback) {
|
3449
|
+
await this.showMousePointer(point.x, point.y);
|
3450
|
+
}
|
3451
|
+
await this.underlyingPage.mouse.move(point.x, point.y);
|
3452
|
+
this.currentMousePosition = point;
|
3453
|
+
if (i < path.length - 1) {
|
3454
|
+
const delay = calculateStepDelay(
|
3455
|
+
moveOptions.duration || 300,
|
3456
|
+
i,
|
3457
|
+
path.length
|
3458
|
+
);
|
3459
|
+
await (0, import_utils15.sleep)(delay);
|
3460
|
+
}
|
3461
|
+
}
|
3462
|
+
}
|
3115
3463
|
async waitForNavigation() {
|
3116
3464
|
if (this.pageType === "puppeteer" || this.pageType === "playwright") {
|
3117
3465
|
debugPage("waitForNavigation begin");
|
@@ -3201,7 +3549,8 @@ var Page = class {
|
|
3201
3549
|
return {
|
3202
3550
|
click: async (x, y, options) => {
|
3203
3551
|
await this.mouse.move(x, y);
|
3204
|
-
this.
|
3552
|
+
await this.showClickAnimation(x, y);
|
3553
|
+
await this.underlyingPage.mouse.click(x, y, {
|
3205
3554
|
button: options?.button || "left",
|
3206
3555
|
count: options?.count || 1
|
3207
3556
|
});
|
@@ -3221,27 +3570,23 @@ var Page = class {
|
|
3221
3570
|
},
|
3222
3571
|
move: async (x, y) => {
|
3223
3572
|
this.everMoved = true;
|
3224
|
-
|
3573
|
+
await this.moveMouseHumanLike(x, y);
|
3574
|
+
return Promise.resolve();
|
3225
3575
|
},
|
3226
3576
|
drag: async (from, to) => {
|
3227
3577
|
if (this.pageType === "puppeteer") {
|
3228
|
-
await this.
|
3229
|
-
|
3230
|
-
|
3231
|
-
|
3232
|
-
|
3233
|
-
|
3234
|
-
|
3235
|
-
|
3236
|
-
}
|
3237
|
-
);
|
3578
|
+
await this.mouse.move(from.x, from.y);
|
3579
|
+
await this.underlyingPage.mouse.down();
|
3580
|
+
await this.moveMouseHumanLike(to.x, to.y, {
|
3581
|
+
duration: 500,
|
3582
|
+
// Slower for drag operations
|
3583
|
+
steps: 25
|
3584
|
+
});
|
3585
|
+
await this.underlyingPage.mouse.up();
|
3238
3586
|
} else if (this.pageType === "playwright") {
|
3239
|
-
await this.
|
3240
|
-
from.x,
|
3241
|
-
from.y
|
3242
|
-
);
|
3587
|
+
await this.mouse.move(from.x, from.y);
|
3243
3588
|
await this.underlyingPage.mouse.down();
|
3244
|
-
await this.
|
3589
|
+
await this.mouse.move(to.x, to.y);
|
3245
3590
|
await this.underlyingPage.mouse.up();
|
3246
3591
|
}
|
3247
3592
|
}
|
@@ -3304,6 +3649,18 @@ var Page = class {
|
|
3304
3649
|
await this.mouse.move(targetX, targetY);
|
3305
3650
|
}
|
3306
3651
|
}
|
3652
|
+
/**
|
3653
|
+
* Configure mouse movement behavior
|
3654
|
+
*/
|
3655
|
+
configureMouseMovement(options) {
|
3656
|
+
this.mouseMovementOptions = { ...this.mouseMovementOptions, ...options };
|
3657
|
+
}
|
3658
|
+
/**
|
3659
|
+
* Configure visual feedback
|
3660
|
+
*/
|
3661
|
+
configureVisualFeedback(options) {
|
3662
|
+
this.visualFeedbackOptions = { ...this.visualFeedbackOptions, ...options };
|
3663
|
+
}
|
3307
3664
|
async scrollUntilTop(startingPoint) {
|
3308
3665
|
await this.moveToPointBeforeScroll(startingPoint);
|
3309
3666
|
return this.mouse.wheel(0, -9999999);
|