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
@@ -351,8 +351,8 @@ var ScriptPlayer = class {
|
|
351
351
|
var import_js_yaml = __toESM(require("js-yaml"));
|
352
352
|
|
353
353
|
// src/yaml/utils.ts
|
354
|
-
var import_utils2 = require("misoai-shared/utils");
|
355
354
|
var import_js_yaml2 = __toESM(require("js-yaml"));
|
355
|
+
var import_utils2 = require("misoai-shared/utils");
|
356
356
|
function interpolateEnvVars(content) {
|
357
357
|
return content.replace(/\$\{([^}]+)\}/g, (_, envVar) => {
|
358
358
|
const value = process.env[envVar.trim()];
|
@@ -498,13 +498,13 @@ function paramStr(task) {
|
|
498
498
|
}
|
499
499
|
|
500
500
|
// src/common/utils.ts
|
501
|
+
var import_dayjs = __toESM(require("dayjs"));
|
501
502
|
var import_ai_model = require("misoai-core/ai-model");
|
502
503
|
var import_utils3 = require("misoai-core/utils");
|
503
504
|
var import_env = require("misoai-shared/env");
|
504
505
|
var import_extractor = require("misoai-shared/extractor");
|
505
506
|
var import_img = require("misoai-shared/img");
|
506
507
|
var import_utils4 = require("misoai-shared/utils");
|
507
|
-
var import_dayjs = __toESM(require("dayjs"));
|
508
508
|
|
509
509
|
// src/web-element.ts
|
510
510
|
var WebElementInfo = class {
|
@@ -673,8 +673,12 @@ var WorkflowMemory = class {
|
|
673
673
|
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
674
674
|
workflow.memory = [...memory];
|
675
675
|
workflow.metadata.totalSteps = workflow.steps.length;
|
676
|
-
workflow.metadata.completedSteps = workflow.steps.filter(
|
677
|
-
|
676
|
+
workflow.metadata.completedSteps = workflow.steps.filter(
|
677
|
+
(s) => s.status === "completed"
|
678
|
+
).length;
|
679
|
+
workflow.metadata.failedSteps = workflow.steps.filter(
|
680
|
+
(s) => s.status === "failed"
|
681
|
+
).length;
|
678
682
|
this.workflows.set(workflowId, workflow);
|
679
683
|
this.enforceRetentionPolicy();
|
680
684
|
}
|
@@ -685,7 +689,9 @@ var WorkflowMemory = class {
|
|
685
689
|
const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
|
686
690
|
workflow.context = { ...workflow.context, ...context };
|
687
691
|
if (context.currentStep) {
|
688
|
-
const existingStep = workflow.steps.find(
|
692
|
+
const existingStep = workflow.steps.find(
|
693
|
+
(s) => s.stepName === context.currentStep
|
694
|
+
);
|
689
695
|
if (!existingStep) {
|
690
696
|
workflow.steps.push({
|
691
697
|
stepId: `step_${workflow.steps.length + 1}`,
|
@@ -730,7 +736,9 @@ var WorkflowMemory = class {
|
|
730
736
|
enforceRetentionPolicy() {
|
731
737
|
const maxWorkflows = 10;
|
732
738
|
if (this.workflows.size > maxWorkflows) {
|
733
|
-
const sortedWorkflows = Array.from(this.workflows.entries()).sort(
|
739
|
+
const sortedWorkflows = Array.from(this.workflows.entries()).sort(
|
740
|
+
([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime)
|
741
|
+
);
|
734
742
|
const toDelete = sortedWorkflows.slice(maxWorkflows);
|
735
743
|
toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
|
736
744
|
}
|
@@ -1297,6 +1305,7 @@ var PageTaskExecutor = class {
|
|
1297
1305
|
actions: [],
|
1298
1306
|
more_actions_needed_by_instruction: false,
|
1299
1307
|
log: "",
|
1308
|
+
summary: "Loaded YAML workflow configuration",
|
1300
1309
|
yamlString
|
1301
1310
|
},
|
1302
1311
|
cache: {
|
@@ -1398,6 +1407,7 @@ var PageTaskExecutor = class {
|
|
1398
1407
|
actions: finalActions,
|
1399
1408
|
more_actions_needed_by_instruction,
|
1400
1409
|
log: log2,
|
1410
|
+
summary: planResult.summary || "Generated action plan from user instruction",
|
1401
1411
|
yamlFlow: planResult.yamlFlow
|
1402
1412
|
},
|
1403
1413
|
cache: {
|
@@ -1453,6 +1463,7 @@ var PageTaskExecutor = class {
|
|
1453
1463
|
actionType: actions[0].type,
|
1454
1464
|
more_actions_needed_by_instruction: true,
|
1455
1465
|
log: "",
|
1466
|
+
summary: action_summary || "Generated VLM action plan",
|
1456
1467
|
yamlFlow: planResult.yamlFlow
|
1457
1468
|
},
|
1458
1469
|
cache: {
|
@@ -1469,7 +1480,9 @@ var PageTaskExecutor = class {
|
|
1469
1480
|
*/
|
1470
1481
|
getPersistentExecutor() {
|
1471
1482
|
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1472
|
-
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1483
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1484
|
+
this.sessionContext.workflowId
|
1485
|
+
);
|
1473
1486
|
this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
|
1474
1487
|
onTaskStart: this.onTaskStartCallback,
|
1475
1488
|
initialMemory: previousMemory
|
@@ -1498,7 +1511,9 @@ var PageTaskExecutor = class {
|
|
1498
1511
|
if (this.persistentExecutor) {
|
1499
1512
|
this.persistentExecutor.clearMemory();
|
1500
1513
|
}
|
1501
|
-
this.workflowMemory.clearWorkflow(
|
1514
|
+
this.workflowMemory.clearWorkflow(
|
1515
|
+
this.sessionContext.workflowId || "default"
|
1516
|
+
);
|
1502
1517
|
}
|
1503
1518
|
/**
|
1504
1519
|
* Mevcut hafızayı döndürür
|
@@ -1510,7 +1525,9 @@ var PageTaskExecutor = class {
|
|
1510
1525
|
* İş akışı hafızasını döndürür
|
1511
1526
|
*/
|
1512
1527
|
getWorkflowMemory() {
|
1513
|
-
return this.workflowMemory.getWorkflowData(
|
1528
|
+
return this.workflowMemory.getWorkflowData(
|
1529
|
+
this.sessionContext.workflowId || "default"
|
1530
|
+
);
|
1514
1531
|
}
|
1515
1532
|
/**
|
1516
1533
|
* Hafıza istatistiklerini döndürür
|
@@ -1518,7 +1535,13 @@ var PageTaskExecutor = class {
|
|
1518
1535
|
getMemoryStats() {
|
1519
1536
|
return this.persistentExecutor?.getMemoryStats() || {
|
1520
1537
|
totalItems: 0,
|
1521
|
-
analytics: {
|
1538
|
+
analytics: {
|
1539
|
+
totalTasks: 0,
|
1540
|
+
memoryHits: 0,
|
1541
|
+
memoryMisses: 0,
|
1542
|
+
averageMemorySize: 0,
|
1543
|
+
memoryEffectiveness: 0
|
1544
|
+
},
|
1522
1545
|
config: this.memoryConfig
|
1523
1546
|
};
|
1524
1547
|
}
|
@@ -1554,11 +1577,14 @@ var PageTaskExecutor = class {
|
|
1554
1577
|
let taskExecutor;
|
1555
1578
|
if (useMemory) {
|
1556
1579
|
taskExecutor = this.getPersistentExecutor();
|
1557
|
-
this.workflowMemory.updateWorkflowContext(
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1580
|
+
this.workflowMemory.updateWorkflowContext(
|
1581
|
+
{
|
1582
|
+
currentStep: title,
|
1583
|
+
pageInfo: this.sessionContext.pageInfo,
|
1584
|
+
timestamp: Date.now()
|
1585
|
+
},
|
1586
|
+
this.sessionContext.workflowId || "default"
|
1587
|
+
);
|
1562
1588
|
} else {
|
1563
1589
|
taskExecutor = new import_misoai_core.Executor(title, {
|
1564
1590
|
onTaskStart: this.onTaskStartCallback
|
@@ -1924,14 +1950,19 @@ var PageTaskExecutor = class {
|
|
1924
1950
|
*/
|
1925
1951
|
addToMemory(memoryItem) {
|
1926
1952
|
if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
|
1927
|
-
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1953
|
+
const previousMemory = this.workflowMemory.getWorkflowMemory(
|
1954
|
+
this.sessionContext.workflowId
|
1955
|
+
);
|
1928
1956
|
this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
|
1929
1957
|
onTaskStart: this.onTaskStartCallback,
|
1930
1958
|
initialMemory: previousMemory
|
1931
1959
|
});
|
1932
1960
|
}
|
1933
1961
|
this.persistentExecutor.memoryStore?.add(memoryItem);
|
1934
|
-
this.persistentExecutor.memoryAnalytics?.recordMemoryOperation(
|
1962
|
+
this.persistentExecutor.memoryAnalytics?.recordMemoryOperation(
|
1963
|
+
"add",
|
1964
|
+
memoryItem
|
1965
|
+
);
|
1935
1966
|
}
|
1936
1967
|
};
|
1937
1968
|
|
@@ -2020,14 +2051,14 @@ function buildPlans(type, locateParam, param) {
|
|
2020
2051
|
var import_node_assert = __toESM(require("assert"));
|
2021
2052
|
var import_node_fs2 = require("fs");
|
2022
2053
|
var import_node_path2 = require("path");
|
2054
|
+
var import_js_yaml3 = __toESM(require("js-yaml"));
|
2023
2055
|
var import_common2 = require("misoai-shared/common");
|
2024
2056
|
var import_logger3 = require("misoai-shared/logger");
|
2025
2057
|
var import_utils9 = require("misoai-shared/utils");
|
2026
|
-
var import_js_yaml3 = __toESM(require("js-yaml"));
|
2027
2058
|
var import_semver = __toESM(require("semver"));
|
2028
2059
|
|
2029
2060
|
// package.json
|
2030
|
-
var version = "1.6.
|
2061
|
+
var version = "1.6.2";
|
2031
2062
|
|
2032
2063
|
// src/common/task-cache.ts
|
2033
2064
|
var debug3 = (0, import_logger3.getDebug)("cache");
|
@@ -2322,22 +2353,28 @@ var PageAgent = class {
|
|
2322
2353
|
const allThoughts = executor.tasks.filter((task) => task.thought).map((task) => task.thought);
|
2323
2354
|
const allLocates = executor.tasks.filter((task) => task.locate).map((task) => task.locate);
|
2324
2355
|
const allPlans = executor.tasks.filter((task) => task.param?.plans).map((task) => task.param?.plans);
|
2325
|
-
const planningTasks = executor.tasks.filter(
|
2326
|
-
|
2356
|
+
const planningTasks = executor.tasks.filter(
|
2357
|
+
(task) => task.type === "Planning"
|
2358
|
+
);
|
2359
|
+
const insightTasks = executor.tasks.filter(
|
2360
|
+
(task) => task.type === "Insight"
|
2361
|
+
);
|
2327
2362
|
const actionTasks = executor.tasks.filter((task) => task.type === "Action");
|
2328
2363
|
const planning = planningTasks.length > 0 ? {
|
2329
2364
|
type: "Planning",
|
2330
|
-
description:
|
2365
|
+
description: "Planning for task execution",
|
2331
2366
|
steps: planningTasks.map((task) => task.thought || "Planning step")
|
2332
2367
|
} : void 0;
|
2333
2368
|
const insight = insightTasks.length > 0 ? {
|
2334
2369
|
type: "Insight",
|
2335
|
-
description:
|
2336
|
-
elements: insightTasks.map(
|
2370
|
+
description: "Insight for task execution",
|
2371
|
+
elements: insightTasks.map(
|
2372
|
+
(task) => task.thought || "Insight element"
|
2373
|
+
)
|
2337
2374
|
} : void 0;
|
2338
2375
|
const action = actionTasks.length > 0 ? {
|
2339
2376
|
type: "Action",
|
2340
|
-
description:
|
2377
|
+
description: "Action for task execution",
|
2341
2378
|
result: lastTask?.output
|
2342
2379
|
} : void 0;
|
2343
2380
|
const actionDetails = executor.tasks.map((task) => ({
|
@@ -2671,7 +2708,10 @@ ${memoryContext}` : void 0;
|
|
2671
2708
|
}
|
2672
2709
|
const memoryContext = this.getMemoryAsContext();
|
2673
2710
|
const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
|
2674
|
-
const { output, executor } = await this.taskExecutor.assert(
|
2711
|
+
const { output, executor } = await this.taskExecutor.assert(
|
2712
|
+
assertionWithContext,
|
2713
|
+
memoryContext
|
2714
|
+
);
|
2675
2715
|
const metadata = this.afterTaskRunning(executor, true);
|
2676
2716
|
if (output && opt?.keepRawResponse) {
|
2677
2717
|
return {
|
@@ -2710,7 +2750,10 @@ A complex CAPTCHA typically has one or more of these characteristics:
|
|
2710
2750
|
Return only "complex" or "simple" based on your analysis.
|
2711
2751
|
`;
|
2712
2752
|
const complexityMsgs = [
|
2713
|
-
{
|
2753
|
+
{
|
2754
|
+
role: "system",
|
2755
|
+
content: "You are an AI assistant that analyzes screenshots to determine CAPTCHA complexity."
|
2756
|
+
},
|
2714
2757
|
{
|
2715
2758
|
role: "user",
|
2716
2759
|
content: [
|
@@ -2734,7 +2777,12 @@ Return only "complex" or "simple" based on your analysis.
|
|
2734
2777
|
);
|
2735
2778
|
const responseText = typeof complexityResult.content === "string" ? complexityResult.content.toLowerCase() : JSON.stringify(complexityResult.content).toLowerCase();
|
2736
2779
|
shouldUseDeepThink = responseText.includes("complex");
|
2737
|
-
debug4(
|
2780
|
+
debug4(
|
2781
|
+
"CAPTCHA complexity analysis:",
|
2782
|
+
responseText,
|
2783
|
+
"Using deep think:",
|
2784
|
+
shouldUseDeepThink
|
2785
|
+
);
|
2738
2786
|
} catch (error) {
|
2739
2787
|
debug4("Failed to analyze CAPTCHA complexity:", error);
|
2740
2788
|
}
|
@@ -2751,7 +2799,9 @@ Return only "complex" or "simple" based on your analysis.
|
|
2751
2799
|
await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
|
2752
2800
|
} else if (action.type === "input" && action.value) {
|
2753
2801
|
if (action.target) {
|
2754
|
-
await this.aiInput(action.value, action.target, {
|
2802
|
+
await this.aiInput(action.value, action.target, {
|
2803
|
+
deepThink: shouldUseDeepThink
|
2804
|
+
});
|
2755
2805
|
}
|
2756
2806
|
} else if (action.type === "verify" && action.target) {
|
2757
2807
|
await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
|
@@ -2763,7 +2813,9 @@ Return only "complex" or "simple" based on your analysis.
|
|
2763
2813
|
if (action.coordinates) {
|
2764
2814
|
const x = action.coordinates[0];
|
2765
2815
|
const y = action.coordinates[1];
|
2766
|
-
await this.aiTap(`element at coordinates (${x}, ${y})`, {
|
2816
|
+
await this.aiTap(`element at coordinates (${x}, ${y})`, {
|
2817
|
+
deepThink: shouldUseDeepThink
|
2818
|
+
});
|
2767
2819
|
} else if (action.target) {
|
2768
2820
|
await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
|
2769
2821
|
}
|
@@ -2915,25 +2967,27 @@ ${errors}`);
|
|
2915
2967
|
const executionDump = {
|
2916
2968
|
name: screenshotTitle,
|
2917
2969
|
description: content,
|
2918
|
-
tasks: [
|
2919
|
-
|
2920
|
-
|
2921
|
-
|
2922
|
-
|
2923
|
-
|
2924
|
-
|
2925
|
-
|
2926
|
-
|
2927
|
-
|
2928
|
-
|
2929
|
-
|
2930
|
-
|
2931
|
-
|
2932
|
-
|
2933
|
-
|
2934
|
-
|
2970
|
+
tasks: [
|
2971
|
+
{
|
2972
|
+
type: "Screenshot",
|
2973
|
+
subType: "log",
|
2974
|
+
status: "finished",
|
2975
|
+
executor: null,
|
2976
|
+
param: {
|
2977
|
+
title: screenshotTitle,
|
2978
|
+
content
|
2979
|
+
},
|
2980
|
+
output: {
|
2981
|
+
screenshot
|
2982
|
+
},
|
2983
|
+
thought: `Logged screenshot: ${screenshotTitle}`,
|
2984
|
+
timing: {
|
2985
|
+
start: Date.now(),
|
2986
|
+
end: Date.now(),
|
2987
|
+
cost: 0
|
2988
|
+
}
|
2935
2989
|
}
|
2936
|
-
|
2990
|
+
],
|
2937
2991
|
sdkVersion: "1.0.0",
|
2938
2992
|
logTime: Date.now(),
|
2939
2993
|
model_name: "screenshot"
|
@@ -2985,7 +3039,9 @@ ${errors}`);
|
|
2985
3039
|
totalTasks: stats.analytics.totalTasks,
|
2986
3040
|
memoryHits: stats.analytics.memoryHits,
|
2987
3041
|
memoryMisses: stats.analytics.memoryMisses,
|
2988
|
-
memoryEffectiveness: Math.round(
|
3042
|
+
memoryEffectiveness: Math.round(
|
3043
|
+
stats.analytics.memoryEffectiveness * 100
|
3044
|
+
),
|
2989
3045
|
averageMemorySize: Math.round(stats.analytics.averageMemorySize * 100) / 100
|
2990
3046
|
},
|
2991
3047
|
config: stats.config,
|
@@ -3049,7 +3105,9 @@ ${errors}`);
|
|
3049
3105
|
calculateSuccessRate(memory) {
|
3050
3106
|
if (memory.length === 0)
|
3051
3107
|
return 0;
|
3052
|
-
const successCount = memory.filter(
|
3108
|
+
const successCount = memory.filter(
|
3109
|
+
(item) => item.metadata?.success !== false
|
3110
|
+
).length;
|
3053
3111
|
return Math.round(successCount / memory.length * 100);
|
3054
3112
|
}
|
3055
3113
|
calculateAverageExecutionTime(memory) {
|
@@ -3091,13 +3149,236 @@ var import_extractor2 = require("misoai-shared/extractor");
|
|
3091
3149
|
var import_fs = require("misoai-shared/fs");
|
3092
3150
|
var import_logger5 = require("misoai-shared/logger");
|
3093
3151
|
var import_utils16 = require("misoai-shared/utils");
|
3152
|
+
|
3153
|
+
// src/common/mouse-utils.ts
|
3154
|
+
function generateHumanMousePath(from, to, options = {}) {
|
3155
|
+
const {
|
3156
|
+
steps = 20,
|
3157
|
+
easing = "easeInOut"
|
3158
|
+
} = options;
|
3159
|
+
if (steps <= 1) {
|
3160
|
+
return [to];
|
3161
|
+
}
|
3162
|
+
const path = [];
|
3163
|
+
const controlPoint1 = {
|
3164
|
+
x: from.x + (to.x - from.x) * 0.25 + (Math.random() - 0.5) * 50,
|
3165
|
+
y: from.y + (to.y - from.y) * 0.25 + (Math.random() - 0.5) * 50
|
3166
|
+
};
|
3167
|
+
const controlPoint2 = {
|
3168
|
+
x: from.x + (to.x - from.x) * 0.75 + (Math.random() - 0.5) * 50,
|
3169
|
+
y: from.y + (to.y - from.y) * 0.75 + (Math.random() - 0.5) * 50
|
3170
|
+
};
|
3171
|
+
for (let i = 0; i <= steps; i++) {
|
3172
|
+
const t = i / steps;
|
3173
|
+
const easedT = applyEasing(t, easing);
|
3174
|
+
const point = calculateBezierPoint(from, controlPoint1, controlPoint2, to, easedT);
|
3175
|
+
path.push(point);
|
3176
|
+
}
|
3177
|
+
return path;
|
3178
|
+
}
|
3179
|
+
function calculateBezierPoint(p0, p1, p2, p3, t) {
|
3180
|
+
const oneMinusT = 1 - t;
|
3181
|
+
const oneMinusTSquared = oneMinusT * oneMinusT;
|
3182
|
+
const oneMinusTCubed = oneMinusTSquared * oneMinusT;
|
3183
|
+
const tSquared = t * t;
|
3184
|
+
const tCubed = tSquared * t;
|
3185
|
+
return {
|
3186
|
+
x: oneMinusTCubed * p0.x + 3 * oneMinusTSquared * t * p1.x + 3 * oneMinusT * tSquared * p2.x + tCubed * p3.x,
|
3187
|
+
y: oneMinusTCubed * p0.y + 3 * oneMinusTSquared * t * p1.y + 3 * oneMinusT * tSquared * p2.y + tCubed * p3.y
|
3188
|
+
};
|
3189
|
+
}
|
3190
|
+
function applyEasing(t, easing) {
|
3191
|
+
switch (easing) {
|
3192
|
+
case "linear":
|
3193
|
+
return t;
|
3194
|
+
case "easeIn":
|
3195
|
+
return t * t;
|
3196
|
+
case "easeOut":
|
3197
|
+
return 1 - (1 - t) * (1 - t);
|
3198
|
+
case "easeInOut":
|
3199
|
+
return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
|
3200
|
+
default:
|
3201
|
+
return t;
|
3202
|
+
}
|
3203
|
+
}
|
3204
|
+
function calculateStepDelay(totalDuration, currentStep, totalSteps) {
|
3205
|
+
const baseDelay = totalDuration / totalSteps;
|
3206
|
+
const variation = 0.3;
|
3207
|
+
const randomFactor = 1 + (Math.random() - 0.5) * variation;
|
3208
|
+
return Math.max(1, baseDelay * randomFactor);
|
3209
|
+
}
|
3210
|
+
|
3211
|
+
// src/common/visual-feedback.ts
|
3212
|
+
function getMousePointerScript(x, y, options = {}) {
|
3213
|
+
const {
|
3214
|
+
pointerSize = 20,
|
3215
|
+
pointerColor = "#ff4444",
|
3216
|
+
trailLength = 5,
|
3217
|
+
showTrail = true,
|
3218
|
+
animationDuration = 200
|
3219
|
+
} = options;
|
3220
|
+
return `
|
3221
|
+
(() => {
|
3222
|
+
// Create or update mouse pointer
|
3223
|
+
if (!window.misoaiMousePointer) {
|
3224
|
+
const pointer = document.createElement('div');
|
3225
|
+
pointer.id = 'misoai-mouse-pointer';
|
3226
|
+
pointer.style.cssText = \`
|
3227
|
+
position: fixed;
|
3228
|
+
width: ${pointerSize}px;
|
3229
|
+
height: ${pointerSize}px;
|
3230
|
+
background: ${pointerColor};
|
3231
|
+
border: 2px solid white;
|
3232
|
+
border-radius: 50%;
|
3233
|
+
pointer-events: none;
|
3234
|
+
z-index: 999999;
|
3235
|
+
box-shadow: 0 0 10px rgba(0,0,0,0.3);
|
3236
|
+
transition: all ${animationDuration}ms ease-out;
|
3237
|
+
transform: translate(-50%, -50%);
|
3238
|
+
\`;
|
3239
|
+
document.body.appendChild(pointer);
|
3240
|
+
window.misoaiMousePointer = pointer;
|
3241
|
+
|
3242
|
+
// Initialize trail array
|
3243
|
+
window.misoaiMouseTrail = [];
|
3244
|
+
}
|
3245
|
+
|
3246
|
+
const pointer = window.misoaiMousePointer;
|
3247
|
+
pointer.style.left = ${x}px;
|
3248
|
+
pointer.style.top = ${y}px;
|
3249
|
+
|
3250
|
+
${showTrail ? getTrailScript(x, y, trailLength, pointerColor) : ""}
|
3251
|
+
|
3252
|
+
// Auto-hide after 3 seconds of inactivity
|
3253
|
+
clearTimeout(window.misoaiMouseTimeout);
|
3254
|
+
pointer.style.opacity = '1';
|
3255
|
+
window.misoaiMouseTimeout = setTimeout(() => {
|
3256
|
+
if (pointer) pointer.style.opacity = '0.3';
|
3257
|
+
}, 3000);
|
3258
|
+
})();
|
3259
|
+
`;
|
3260
|
+
}
|
3261
|
+
function getTrailScript(x, y, trailLength, color) {
|
3262
|
+
return `
|
3263
|
+
// Add current position to trail
|
3264
|
+
window.misoaiMouseTrail.push({ x: ${x}, y: ${y}, timestamp: Date.now() });
|
3265
|
+
|
3266
|
+
// Keep only recent trail points
|
3267
|
+
if (window.misoaiMouseTrail.length > ${trailLength}) {
|
3268
|
+
window.misoaiMouseTrail.shift();
|
3269
|
+
}
|
3270
|
+
|
3271
|
+
// Remove old trail elements
|
3272
|
+
document.querySelectorAll('.misoai-mouse-trail').forEach(el => el.remove());
|
3273
|
+
|
3274
|
+
// Create new trail elements
|
3275
|
+
window.misoaiMouseTrail.forEach((point, index) => {
|
3276
|
+
if (index === window.misoaiMouseTrail.length - 1) return; // Skip current position
|
3277
|
+
|
3278
|
+
const trailElement = document.createElement('div');
|
3279
|
+
trailElement.className = 'misoai-mouse-trail';
|
3280
|
+
const opacity = (index + 1) / window.misoaiMouseTrail.length * 0.6;
|
3281
|
+
const size = 8 + (index + 1) / window.misoaiMouseTrail.length * 8;
|
3282
|
+
|
3283
|
+
trailElement.style.cssText = \`
|
3284
|
+
position: fixed;
|
3285
|
+
width: \${size}px;
|
3286
|
+
height: \${size}px;
|
3287
|
+
background: ${color};
|
3288
|
+
border-radius: 50%;
|
3289
|
+
pointer-events: none;
|
3290
|
+
z-index: 999998;
|
3291
|
+
opacity: \${opacity};
|
3292
|
+
transform: translate(-50%, -50%);
|
3293
|
+
left: \${point.x}px;
|
3294
|
+
top: \${point.y}px;
|
3295
|
+
\`;
|
3296
|
+
|
3297
|
+
document.body.appendChild(trailElement);
|
3298
|
+
|
3299
|
+
// Auto-remove trail element after animation
|
3300
|
+
setTimeout(() => {
|
3301
|
+
if (trailElement.parentNode) {
|
3302
|
+
trailElement.parentNode.removeChild(trailElement);
|
3303
|
+
}
|
3304
|
+
}, 1000);
|
3305
|
+
});
|
3306
|
+
`;
|
3307
|
+
}
|
3308
|
+
function getClickAnimationScript(x, y) {
|
3309
|
+
return `
|
3310
|
+
(() => {
|
3311
|
+
const clickRipple = document.createElement('div');
|
3312
|
+
clickRipple.style.cssText = \`
|
3313
|
+
position: fixed;
|
3314
|
+
left: ${x}px;
|
3315
|
+
top: ${y}px;
|
3316
|
+
width: 0;
|
3317
|
+
height: 0;
|
3318
|
+
border: 2px solid #ff4444;
|
3319
|
+
border-radius: 50%;
|
3320
|
+
pointer-events: none;
|
3321
|
+
z-index: 999999;
|
3322
|
+
transform: translate(-50%, -50%);
|
3323
|
+
animation: misoai-click-ripple 0.6s ease-out forwards;
|
3324
|
+
\`;
|
3325
|
+
|
3326
|
+
// Add CSS animation if not exists
|
3327
|
+
if (!document.getElementById('misoai-click-styles')) {
|
3328
|
+
const style = document.createElement('style');
|
3329
|
+
style.id = 'misoai-click-styles';
|
3330
|
+
style.textContent = \`
|
3331
|
+
@keyframes misoai-click-ripple {
|
3332
|
+
0% {
|
3333
|
+
width: 0;
|
3334
|
+
height: 0;
|
3335
|
+
opacity: 1;
|
3336
|
+
}
|
3337
|
+
100% {
|
3338
|
+
width: 40px;
|
3339
|
+
height: 40px;
|
3340
|
+
opacity: 0;
|
3341
|
+
}
|
3342
|
+
}
|
3343
|
+
\`;
|
3344
|
+
document.head.appendChild(style);
|
3345
|
+
}
|
3346
|
+
|
3347
|
+
document.body.appendChild(clickRipple);
|
3348
|
+
|
3349
|
+
// Remove after animation
|
3350
|
+
setTimeout(() => {
|
3351
|
+
if (clickRipple.parentNode) {
|
3352
|
+
clickRipple.parentNode.removeChild(clickRipple);
|
3353
|
+
}
|
3354
|
+
}, 600);
|
3355
|
+
})();
|
3356
|
+
`;
|
3357
|
+
}
|
3358
|
+
|
3359
|
+
// src/puppeteer/base-page.ts
|
3094
3360
|
var debugPage = (0, import_logger5.getDebug)("web:page");
|
3095
3361
|
var Page = class {
|
3096
3362
|
constructor(underlyingPage, pageType, opts) {
|
3363
|
+
this.currentMousePosition = { x: 0, y: 0 };
|
3364
|
+
this.mouseMovementOptions = {
|
3365
|
+
steps: 15,
|
3366
|
+
duration: 300,
|
3367
|
+
easing: "easeInOut",
|
3368
|
+
showVisualFeedback: true
|
3369
|
+
};
|
3370
|
+
this.visualFeedbackOptions = {
|
3371
|
+
pointerSize: 16,
|
3372
|
+
pointerColor: "#ff4444",
|
3373
|
+
trailLength: 4,
|
3374
|
+
showTrail: true,
|
3375
|
+
animationDuration: 150
|
3376
|
+
};
|
3097
3377
|
this.everMoved = false;
|
3098
3378
|
this.underlyingPage = underlyingPage;
|
3099
3379
|
this.pageType = pageType;
|
3100
3380
|
this.waitForNavigationTimeout = opts?.waitForNavigationTimeout ?? import_constants3.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
|
3381
|
+
this.initializeMousePosition();
|
3101
3382
|
}
|
3102
3383
|
async evaluate(pageFunction, arg) {
|
3103
3384
|
let result;
|
@@ -3116,9 +3397,76 @@ var Page = class {
|
|
3116
3397
|
debugPage("evaluate function end");
|
3117
3398
|
return result;
|
3118
3399
|
}
|
3400
|
+
/**
|
3401
|
+
* Initialize mouse position to center of viewport
|
3402
|
+
*/
|
3403
|
+
async initializeMousePosition() {
|
3404
|
+
try {
|
3405
|
+
const size = await this.size();
|
3406
|
+
this.currentMousePosition = {
|
3407
|
+
x: Math.floor(size.width / 2),
|
3408
|
+
y: Math.floor(size.height / 2)
|
3409
|
+
};
|
3410
|
+
} catch (error) {
|
3411
|
+
this.currentMousePosition = { x: 400, y: 300 };
|
3412
|
+
}
|
3413
|
+
}
|
3119
3414
|
async evaluateJavaScript(script) {
|
3120
3415
|
return this.evaluate(script);
|
3121
3416
|
}
|
3417
|
+
/**
|
3418
|
+
* Show visual feedback for mouse pointer
|
3419
|
+
*/
|
3420
|
+
async showMousePointer(x, y) {
|
3421
|
+
if (!this.mouseMovementOptions.showVisualFeedback)
|
3422
|
+
return;
|
3423
|
+
const script = getMousePointerScript(x, y, this.visualFeedbackOptions);
|
3424
|
+
try {
|
3425
|
+
await this.evaluate(script);
|
3426
|
+
} catch (error) {
|
3427
|
+
debugPage("Visual feedback error:", error);
|
3428
|
+
}
|
3429
|
+
}
|
3430
|
+
/**
|
3431
|
+
* Show click animation
|
3432
|
+
*/
|
3433
|
+
async showClickAnimation(x, y) {
|
3434
|
+
if (!this.mouseMovementOptions.showVisualFeedback)
|
3435
|
+
return;
|
3436
|
+
const script = getClickAnimationScript(x, y);
|
3437
|
+
try {
|
3438
|
+
await this.evaluate(script);
|
3439
|
+
} catch (error) {
|
3440
|
+
debugPage("Click animation error:", error);
|
3441
|
+
}
|
3442
|
+
}
|
3443
|
+
/**
|
3444
|
+
* Move mouse with human-like movement and visual feedback
|
3445
|
+
*/
|
3446
|
+
async moveMouseHumanLike(toX, toY, options) {
|
3447
|
+
const moveOptions = { ...this.mouseMovementOptions, ...options };
|
3448
|
+
const path = generateHumanMousePath(
|
3449
|
+
this.currentMousePosition,
|
3450
|
+
{ x: toX, y: toY },
|
3451
|
+
moveOptions
|
3452
|
+
);
|
3453
|
+
for (let i = 0; i < path.length; i++) {
|
3454
|
+
const point = path[i];
|
3455
|
+
if (moveOptions.showVisualFeedback) {
|
3456
|
+
await this.showMousePointer(point.x, point.y);
|
3457
|
+
}
|
3458
|
+
await this.underlyingPage.mouse.move(point.x, point.y);
|
3459
|
+
this.currentMousePosition = point;
|
3460
|
+
if (i < path.length - 1) {
|
3461
|
+
const delay = calculateStepDelay(
|
3462
|
+
moveOptions.duration || 300,
|
3463
|
+
i,
|
3464
|
+
path.length
|
3465
|
+
);
|
3466
|
+
await (0, import_utils15.sleep)(delay);
|
3467
|
+
}
|
3468
|
+
}
|
3469
|
+
}
|
3122
3470
|
async waitForNavigation() {
|
3123
3471
|
if (this.pageType === "puppeteer" || this.pageType === "playwright") {
|
3124
3472
|
debugPage("waitForNavigation begin");
|
@@ -3208,7 +3556,8 @@ var Page = class {
|
|
3208
3556
|
return {
|
3209
3557
|
click: async (x, y, options) => {
|
3210
3558
|
await this.mouse.move(x, y);
|
3211
|
-
this.
|
3559
|
+
await this.showClickAnimation(x, y);
|
3560
|
+
await this.underlyingPage.mouse.click(x, y, {
|
3212
3561
|
button: options?.button || "left",
|
3213
3562
|
count: options?.count || 1
|
3214
3563
|
});
|
@@ -3228,27 +3577,23 @@ var Page = class {
|
|
3228
3577
|
},
|
3229
3578
|
move: async (x, y) => {
|
3230
3579
|
this.everMoved = true;
|
3231
|
-
|
3580
|
+
await this.moveMouseHumanLike(x, y);
|
3581
|
+
return Promise.resolve();
|
3232
3582
|
},
|
3233
3583
|
drag: async (from, to) => {
|
3234
3584
|
if (this.pageType === "puppeteer") {
|
3235
|
-
await this.
|
3236
|
-
|
3237
|
-
|
3238
|
-
|
3239
|
-
|
3240
|
-
|
3241
|
-
|
3242
|
-
|
3243
|
-
}
|
3244
|
-
);
|
3585
|
+
await this.mouse.move(from.x, from.y);
|
3586
|
+
await this.underlyingPage.mouse.down();
|
3587
|
+
await this.moveMouseHumanLike(to.x, to.y, {
|
3588
|
+
duration: 500,
|
3589
|
+
// Slower for drag operations
|
3590
|
+
steps: 25
|
3591
|
+
});
|
3592
|
+
await this.underlyingPage.mouse.up();
|
3245
3593
|
} else if (this.pageType === "playwright") {
|
3246
|
-
await this.
|
3247
|
-
from.x,
|
3248
|
-
from.y
|
3249
|
-
);
|
3594
|
+
await this.mouse.move(from.x, from.y);
|
3250
3595
|
await this.underlyingPage.mouse.down();
|
3251
|
-
await this.
|
3596
|
+
await this.mouse.move(to.x, to.y);
|
3252
3597
|
await this.underlyingPage.mouse.up();
|
3253
3598
|
}
|
3254
3599
|
}
|
@@ -3311,6 +3656,18 @@ var Page = class {
|
|
3311
3656
|
await this.mouse.move(targetX, targetY);
|
3312
3657
|
}
|
3313
3658
|
}
|
3659
|
+
/**
|
3660
|
+
* Configure mouse movement behavior
|
3661
|
+
*/
|
3662
|
+
configureMouseMovement(options) {
|
3663
|
+
this.mouseMovementOptions = { ...this.mouseMovementOptions, ...options };
|
3664
|
+
}
|
3665
|
+
/**
|
3666
|
+
* Configure visual feedback
|
3667
|
+
*/
|
3668
|
+
configureVisualFeedback(options) {
|
3669
|
+
this.visualFeedbackOptions = { ...this.visualFeedbackOptions, ...options };
|
3670
|
+
}
|
3314
3671
|
async scrollUntilTop(startingPoint) {
|
3315
3672
|
await this.moveToPointBeforeScroll(startingPoint);
|
3316
3673
|
return this.mouse.wheel(0, -9999999);
|