n8n-nodes-smart-browser-automation 1.5.1 → 1.6.0
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
1
|
+
import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, ISupplyDataFunctions } from 'n8n-workflow';
|
|
2
2
|
export declare class SmartBrowserAutomation implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
methods: {
|
|
@@ -6,5 +6,6 @@ export declare class SmartBrowserAutomation implements INodeType {
|
|
|
6
6
|
getAvailableTools(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
7
|
};
|
|
8
8
|
};
|
|
9
|
+
supplyData(this: ISupplyDataFunctions, _itemIndex: number): Promise<any>;
|
|
9
10
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
10
11
|
}
|
|
@@ -36,12 +36,14 @@ class SmartBrowserAutomation {
|
|
|
36
36
|
description: 'Override CDP endpoint from credentials. Use this to connect to a specific browser instance.',
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
|
-
displayName: 'Tool Name',
|
|
39
|
+
displayName: 'Tool Name or ID',
|
|
40
40
|
name: 'toolName',
|
|
41
|
-
type: '
|
|
42
|
-
|
|
41
|
+
type: 'options',
|
|
42
|
+
typeOptions: {
|
|
43
|
+
loadOptionsMethod: 'getAvailableTools',
|
|
44
|
+
},
|
|
43
45
|
default: 'browser_navigate',
|
|
44
|
-
description: '
|
|
46
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
45
47
|
},
|
|
46
48
|
{
|
|
47
49
|
displayName: 'Tool Parameters',
|
|
@@ -75,13 +77,59 @@ class SmartBrowserAutomation {
|
|
|
75
77
|
},
|
|
76
78
|
},
|
|
77
79
|
};
|
|
80
|
+
async supplyData(_itemIndex) {
|
|
81
|
+
const credentials = await this.getCredentials('smartBrowserAutomationApi');
|
|
82
|
+
const sessionManager = BrowserSessionManager_1.default.getInstance();
|
|
83
|
+
// Initialize session
|
|
84
|
+
const cdpEndpoint = credentials.cdpEndpoint || '';
|
|
85
|
+
await sessionManager.initialize(credentials.mcpEndpoint, !!cdpEndpoint, cdpEndpoint);
|
|
86
|
+
// Get all available tools from MCP server
|
|
87
|
+
const mcpTools = await sessionManager.listTools();
|
|
88
|
+
// Convert MCP tools to n8n tool format
|
|
89
|
+
const n8nTools = mcpTools.map((tool) => ({
|
|
90
|
+
name: tool.name,
|
|
91
|
+
description: tool.description || `Execute the ${tool.name} tool`,
|
|
92
|
+
schema: tool.inputSchema || { type: 'object', properties: {}, additionalProperties: false },
|
|
93
|
+
func: async (params) => {
|
|
94
|
+
try {
|
|
95
|
+
const result = await sessionManager.callTool(tool.name, params);
|
|
96
|
+
return JSON.stringify(result);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Tool execution failed: ${error.message}`);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
}));
|
|
103
|
+
return {
|
|
104
|
+
response: n8nTools,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
78
107
|
async execute() {
|
|
108
|
+
const items = this.getInputData();
|
|
79
109
|
const returnData = [];
|
|
80
110
|
const credentials = await this.getCredentials('smartBrowserAutomationApi');
|
|
81
111
|
const sessionManager = BrowserSessionManager_1.default.getInstance();
|
|
82
112
|
// Get CDP override or use from credentials
|
|
83
113
|
const cdpOverride = this.getNodeParameter('cdpOverride', 0, '');
|
|
84
|
-
|
|
114
|
+
// Check if AI Agent sent Tool_Parameters in input
|
|
115
|
+
const inputData = items[0]?.json;
|
|
116
|
+
const aiToolParams = inputData?.Tool_Parameters;
|
|
117
|
+
const aiAction = inputData?.action;
|
|
118
|
+
// Determine tool name: prefer AI input, fallback to manual parameter
|
|
119
|
+
let toolName;
|
|
120
|
+
// Check if Tool_Parameters has browser_action field
|
|
121
|
+
if (aiToolParams && typeof aiToolParams === 'object' && 'browser_action' in aiToolParams) {
|
|
122
|
+
const browserAction = aiToolParams.browser_action;
|
|
123
|
+
toolName = `browser_${browserAction}`;
|
|
124
|
+
}
|
|
125
|
+
else if (aiAction && typeof aiAction === 'string' && aiAction !== 'sendMessage') {
|
|
126
|
+
// AI Agent sent action like "click", "open", etc - map to browser tool
|
|
127
|
+
toolName = aiAction === 'open' ? 'browser_navigate' : `browser_${aiAction}`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Manual mode or no AI action
|
|
131
|
+
toolName = this.getNodeParameter('toolName', 0);
|
|
132
|
+
}
|
|
85
133
|
try {
|
|
86
134
|
// Initialize session if not ready
|
|
87
135
|
if (!sessionManager.isReady()) {
|
|
@@ -91,28 +139,34 @@ class SmartBrowserAutomation {
|
|
|
91
139
|
// Handle tool execution
|
|
92
140
|
let toolParams;
|
|
93
141
|
try {
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
toolParams =
|
|
142
|
+
// First check if AI Agent sent Tool_Parameters in input
|
|
143
|
+
if (aiToolParams && typeof aiToolParams === 'object') {
|
|
144
|
+
toolParams = aiToolParams;
|
|
97
145
|
}
|
|
98
|
-
else
|
|
99
|
-
|
|
146
|
+
else {
|
|
147
|
+
// Fallback to manual toolParameters field
|
|
148
|
+
const rawParams = this.getNodeParameter('toolParameters', 0);
|
|
149
|
+
if (rawParams === undefined || rawParams === null) {
|
|
100
150
|
toolParams = {};
|
|
101
151
|
}
|
|
102
|
-
else {
|
|
103
|
-
|
|
152
|
+
else if (typeof rawParams === 'string') {
|
|
153
|
+
if (!rawParams || rawParams.trim() === '') {
|
|
154
|
+
toolParams = {};
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
toolParams = JSON.parse(rawParams);
|
|
158
|
+
}
|
|
104
159
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
// Handle object input (when used as a tool in AI Agent)
|
|
108
|
-
toolParams = rawParams;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
try {
|
|
112
|
-
toolParams = JSON.parse(JSON.stringify(rawParams));
|
|
160
|
+
else if (typeof rawParams === 'object') {
|
|
161
|
+
toolParams = rawParams;
|
|
113
162
|
}
|
|
114
|
-
|
|
115
|
-
|
|
163
|
+
else {
|
|
164
|
+
try {
|
|
165
|
+
toolParams = JSON.parse(JSON.stringify(rawParams));
|
|
166
|
+
}
|
|
167
|
+
catch (parseError) {
|
|
168
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid parameter type: ${typeof rawParams}`);
|
|
169
|
+
}
|
|
116
170
|
}
|
|
117
171
|
}
|
|
118
172
|
// Ensure toolParams is an object
|