@minded-ai/mindedjs 1.0.108 → 1.0.109-beta-1
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/agent.d.ts +12 -12
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +37 -13
- package/dist/agent.js.map +1 -1
- package/dist/browserTask/README.md +419 -0
- package/dist/browserTask/browserAgent.py +632 -0
- package/dist/browserTask/captcha_isolated.png +0 -0
- package/dist/browserTask/executeBrowserTask.d.ts +1 -11
- package/dist/browserTask/executeBrowserTask.d.ts.map +1 -1
- package/dist/browserTask/executeBrowserTask.js +67 -170
- package/dist/browserTask/executeBrowserTask.js.map +1 -1
- package/dist/browserTask/executeBrowserTask.ts +79 -0
- package/dist/browserTask/requirements.txt +8 -0
- package/dist/browserTask/setup.sh +144 -0
- package/dist/cli/index.js +103 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/edges/createLogicalRouter.d.ts +3 -1
- package/dist/edges/createLogicalRouter.d.ts.map +1 -1
- package/dist/edges/createLogicalRouter.js +41 -2
- package/dist/edges/createLogicalRouter.js.map +1 -1
- package/dist/edges/edgeFactory.d.ts.map +1 -1
- package/dist/edges/edgeFactory.js +7 -7
- package/dist/edges/edgeFactory.js.map +1 -1
- package/dist/events/AgentEvents.d.ts +19 -1
- package/dist/events/AgentEvents.d.ts.map +1 -1
- package/dist/events/AgentEvents.js +2 -0
- package/dist/events/AgentEvents.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/internalTools/timer.d.ts +3 -3
- package/dist/internalTools/timer.d.ts.map +1 -1
- package/dist/internalTools/timer.js +3 -3
- package/dist/internalTools/timer.js.map +1 -1
- package/dist/nodes/addBrowserTaskNode.d.ts +1 -3
- package/dist/nodes/addBrowserTaskNode.d.ts.map +1 -1
- package/dist/nodes/addBrowserTaskNode.js +54 -186
- package/dist/nodes/addBrowserTaskNode.js.map +1 -1
- package/dist/nodes/nodeFactory.js +1 -1
- package/dist/nodes/nodeFactory.js.map +1 -1
- package/docs/SUMMARY.md +8 -4
- package/docs/low-code-editor/edges.md +4 -0
- package/docs/sdk/debugging.md +342 -0
- package/docs/{platform → sdk}/events.md +168 -1
- package/package.json +12 -5
- package/dist/nodes/addBrowserTaskRunNode.d.ts +0 -13
- package/dist/nodes/addBrowserTaskRunNode.d.ts.map +0 -1
- package/dist/nodes/addBrowserTaskRunNode.js +0 -130
- package/dist/nodes/addBrowserTaskRunNode.js.map +0 -1
- package/src/agent.ts +0 -928
- package/src/browserTask/executeBrowserTask.ts +0 -213
- package/src/checkpointer/checkpointSaverFactory.ts +0 -18
- package/src/cli/index.ts +0 -170
- package/src/cli/lambdaHandlerTemplate.ts +0 -45
- package/src/edges/createDirectEdge.ts +0 -16
- package/src/edges/createLogicalRouter.ts +0 -114
- package/src/edges/createPromptRouter.ts +0 -218
- package/src/edges/edgeFactory.ts +0 -141
- package/src/events/AgentEvents.ts +0 -47
- package/src/events/index.ts +0 -3
- package/src/index.ts +0 -70
- package/src/interfaces/zendesk.ts +0 -157
- package/src/internalTools/appActionRunnerTool.ts +0 -68
- package/src/internalTools/documentExtraction/documentExtraction.ts +0 -809
- package/src/internalTools/documentExtraction/types.ts +0 -59
- package/src/internalTools/libraryActionRunnerTool.ts +0 -63
- package/src/internalTools/retell.ts +0 -28
- package/src/internalTools/sendPlaceholderMessage.ts +0 -27
- package/src/internalTools/timer.ts +0 -137
- package/src/llm/createLlmInstance.ts +0 -33
- package/src/nodes/addAppToolNode.ts +0 -106
- package/src/nodes/addBrowserTaskNode.ts +0 -231
- package/src/nodes/addBrowserTaskRunNode.ts +0 -144
- package/src/nodes/addHumanInTheLoopNode.ts +0 -25
- package/src/nodes/addJumpToNode.ts +0 -25
- package/src/nodes/addJunctionNode.ts +0 -20
- package/src/nodes/addPromptNode.ts +0 -119
- package/src/nodes/addToolNode.ts +0 -72
- package/src/nodes/addToolRunNode.ts +0 -76
- package/src/nodes/addTriggerNode.ts +0 -27
- package/src/nodes/nodeFactory.ts +0 -57
- package/src/platform/config.ts +0 -77
- package/src/platform/mindedCheckpointSaver.ts +0 -146
- package/src/platform/mindedConnection.ts +0 -199
- package/src/platform/mindedConnectionTypes.ts +0 -220
- package/src/platform/models/mindedChatOpenAI.ts +0 -49
- package/src/platform/models/parallelWrapper.ts +0 -141
- package/src/platform/piiGateway/gateway.ts +0 -103
- package/src/platform/piiGateway/index.ts +0 -5
- package/src/platform/piiGateway/types.ts +0 -29
- package/src/platform/utils/parseAttachments.ts +0 -56
- package/src/playbooks/playbooks.ts +0 -209
- package/src/toolsLibrary/index.ts +0 -6
- package/src/toolsLibrary/parseDocument.ts +0 -136
- package/src/triggers/triggerTypeToDefaultMessage.ts +0 -9
- package/src/types/Agent.types.ts +0 -67
- package/src/types/Flows.types.ts +0 -200
- package/src/types/LLM.types.ts +0 -15
- package/src/types/LangGraph.types.ts +0 -53
- package/src/types/Platform.types.ts +0 -1
- package/src/types/Tools.types.ts +0 -31
- package/src/types/Voice.types.ts +0 -4
- package/src/utils/extractStateMemoryResponse.ts +0 -16
- package/src/utils/history.ts +0 -9
- package/src/utils/logger.ts +0 -22
- package/src/utils/wait.ts +0 -1
- package/src/voice/elevenLabsUtils.ts +0 -81
- package/src/voice/voiceSession.ts +0 -294
- /package/docs/{platform → sdk}/logging.md +0 -0
- /package/docs/{platform → sdk}/memory.md +0 -0
- /package/docs/{platform → sdk}/parallel-llm.md +0 -0
|
@@ -1,181 +1,78 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.executeBrowserTask = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const path_1 = require("path");
|
|
4
6
|
const logger_1 = require("../utils/logger");
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
use_proxy: false,
|
|
23
|
-
llm_model: model || 'gpt-4o',
|
|
24
|
-
}),
|
|
25
|
-
});
|
|
26
|
-
if (!response.ok) {
|
|
27
|
-
logger_1.logger.error({ msg: 'Failed to create cloud browser task', status: response.status, statusText: response.statusText });
|
|
28
|
-
throw new Error(`Failed to create browser task: ${response.statusText}`);
|
|
29
|
-
}
|
|
30
|
-
const data = await response.json();
|
|
31
|
-
logger_1.logger.debug({ msg: 'Cloud browser task created', taskId: data.id });
|
|
32
|
-
return data.id;
|
|
33
|
-
};
|
|
34
|
-
exports.createCloudTask = createCloudTask;
|
|
35
|
-
const getTaskDetails = async (taskId) => {
|
|
36
|
-
const apiKey = process.env.BROWSER_USE_API_KEY;
|
|
37
|
-
if (!apiKey) {
|
|
38
|
-
throw new Error('BROWSER_USE_API_KEY environment variable is required');
|
|
39
|
-
}
|
|
40
|
-
const response = await fetch(`${BROWSER_USE_API_BASE_URL}/task/${taskId}`, {
|
|
41
|
-
headers: {
|
|
42
|
-
Authorization: `Bearer ${apiKey}`,
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
if (!response.ok) {
|
|
46
|
-
logger_1.logger.error({ msg: 'Failed to get task details', taskId, status: response.status, statusText: response.statusText });
|
|
47
|
-
throw new Error(`Failed to get task details: ${response.statusText}`);
|
|
48
|
-
}
|
|
49
|
-
return response.json();
|
|
50
|
-
};
|
|
51
|
-
exports.getTaskDetails = getTaskDetails;
|
|
52
|
-
const waitForLiveUrl = async (taskId, maxWaitTime = 30000) => {
|
|
53
|
-
const startTime = Date.now();
|
|
54
|
-
const pollInterval = 2000; // 2 seconds
|
|
55
|
-
let pollCount = 0;
|
|
56
|
-
logger_1.logger.debug({ msg: 'Starting to poll for live_url', taskId, maxWaitTime, pollInterval });
|
|
57
|
-
while (Date.now() - startTime < maxWaitTime) {
|
|
58
|
-
pollCount++;
|
|
59
|
-
const elapsedTime = Date.now() - startTime;
|
|
60
|
-
logger_1.logger.trace({
|
|
61
|
-
msg: 'Polling for live_url',
|
|
62
|
-
taskId,
|
|
63
|
-
pollCount,
|
|
64
|
-
elapsedTime,
|
|
65
|
-
remainingTime: maxWaitTime - elapsedTime,
|
|
7
|
+
const executeBrowserTask = async (prompt) => {
|
|
8
|
+
const pythonScriptPath = (0, path_1.join)(__dirname, 'browserAgent.py');
|
|
9
|
+
const venvPythonPath = (0, path_1.join)(__dirname, '.venv', 'bin', 'python');
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
// Determine which Python to use - prefer venv if it exists
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const pythonCommand = fs.existsSync(venvPythonPath) ? venvPythonPath : 'python3';
|
|
14
|
+
// Use Python to run our browser agent script with CAPTCHA bypass
|
|
15
|
+
const child = (0, child_process_1.spawn)(pythonCommand, [pythonScriptPath, '-p', prompt, '--output-format', 'json'], {
|
|
16
|
+
env: {
|
|
17
|
+
...process.env,
|
|
18
|
+
// Ensure Python can find the script and dependencies
|
|
19
|
+
PYTHONPATH: __dirname,
|
|
20
|
+
// Set virtual environment if it exists
|
|
21
|
+
VIRTUAL_ENV: fs.existsSync((0, path_1.join)(__dirname, '.venv')) ? (0, path_1.join)(__dirname, '.venv') : undefined,
|
|
22
|
+
},
|
|
23
|
+
cwd: __dirname,
|
|
66
24
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
25
|
+
let output = '';
|
|
26
|
+
let errorOutput = '';
|
|
27
|
+
// Stream stdout to console and collect it
|
|
28
|
+
child.stdout.on('data', (data) => {
|
|
29
|
+
const chunk = data.toString();
|
|
30
|
+
logger_1.logger.trace({ message: 'Browser task output', output: chunk });
|
|
31
|
+
output += chunk;
|
|
74
32
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
pollCount,
|
|
81
|
-
totalTime: elapsedTime,
|
|
82
|
-
});
|
|
83
|
-
return taskDetails;
|
|
84
|
-
}
|
|
85
|
-
if (taskDetails.status === 'failed' || taskDetails.status === 'stopped') {
|
|
86
|
-
logger_1.logger.error({
|
|
87
|
-
msg: 'Task failed while waiting for live_url',
|
|
88
|
-
taskId,
|
|
89
|
-
status: taskDetails.status,
|
|
90
|
-
pollCount,
|
|
91
|
-
elapsedTime,
|
|
92
|
-
});
|
|
93
|
-
throw new Error(`Task failed with status: ${taskDetails.status}`);
|
|
94
|
-
}
|
|
95
|
-
logger_1.logger.trace({
|
|
96
|
-
msg: 'Live URL not yet available, continuing to poll',
|
|
97
|
-
taskId,
|
|
98
|
-
status: taskDetails.status,
|
|
99
|
-
pollCount,
|
|
100
|
-
nextPollIn: pollInterval,
|
|
101
|
-
});
|
|
102
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
103
|
-
}
|
|
104
|
-
logger_1.logger.error({
|
|
105
|
-
msg: 'Timeout waiting for live_url',
|
|
106
|
-
taskId,
|
|
107
|
-
pollCount,
|
|
108
|
-
totalTime: Date.now() - startTime,
|
|
109
|
-
maxWaitTime,
|
|
110
|
-
});
|
|
111
|
-
throw new Error('Timeout waiting for live_url to become available');
|
|
112
|
-
};
|
|
113
|
-
exports.waitForLiveUrl = waitForLiveUrl;
|
|
114
|
-
const waitForCompletion = async (taskId, maxWaitTime = 300000) => {
|
|
115
|
-
var _a, _b, _c, _d;
|
|
116
|
-
const startTime = Date.now();
|
|
117
|
-
const pollInterval = 3000; // 3 seconds for completion polling
|
|
118
|
-
let pollCount = 0;
|
|
119
|
-
logger_1.logger.debug({ msg: 'Starting to poll for task completion', taskId, maxWaitTime, pollInterval });
|
|
120
|
-
while (Date.now() - startTime < maxWaitTime) {
|
|
121
|
-
pollCount++;
|
|
122
|
-
const elapsedTime = Date.now() - startTime;
|
|
123
|
-
logger_1.logger.trace({
|
|
124
|
-
msg: 'Polling for task completion',
|
|
125
|
-
taskId,
|
|
126
|
-
pollCount,
|
|
127
|
-
elapsedTime,
|
|
128
|
-
remainingTime: maxWaitTime - elapsedTime,
|
|
33
|
+
// Stream stderr to console and collect errors
|
|
34
|
+
child.stderr.on('data', (data) => {
|
|
35
|
+
const chunk = data.toString();
|
|
36
|
+
logger_1.logger.error({ message: 'Browser task error', error: chunk });
|
|
37
|
+
errorOutput += chunk;
|
|
129
38
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
taskId,
|
|
134
|
-
status: taskDetails.status,
|
|
135
|
-
pollCount,
|
|
136
|
-
hasOutput: !!taskDetails.output,
|
|
137
|
-
stepCount: ((_a = taskDetails.steps) === null || _a === void 0 ? void 0 : _a.length) || 0,
|
|
39
|
+
child.on('error', (error) => {
|
|
40
|
+
logger_1.logger.error({ message: 'Failed to start browser task process', error: error.message });
|
|
41
|
+
reject(new Error(`Failed to start browser task: ${error.message}`));
|
|
138
42
|
});
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
43
|
+
child.on('close', (code) => {
|
|
44
|
+
if (code !== 0) {
|
|
45
|
+
logger_1.logger.error({
|
|
46
|
+
message: 'Browser task process exited with error',
|
|
47
|
+
code,
|
|
48
|
+
stderr: errorOutput,
|
|
49
|
+
});
|
|
50
|
+
reject(new Error(`Browser task failed with code ${code}: ${errorOutput}`));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
try {
|
|
54
|
+
// Parse JSON output from Python script
|
|
55
|
+
const result = JSON.parse(output.trim());
|
|
56
|
+
if (result.success) {
|
|
57
|
+
logger_1.logger.info({ message: 'Browser task completed successfully' });
|
|
58
|
+
resolve(result.result || 'Task completed successfully');
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
logger_1.logger.error({ message: 'Browser task failed', error: result.error });
|
|
62
|
+
reject(new Error(result.error || 'Unknown error occurred'));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (parseError) {
|
|
66
|
+
// Fallback to plain text output if JSON parsing fails
|
|
67
|
+
logger_1.logger.warn({
|
|
68
|
+
message: 'Could not parse JSON output, using plain text',
|
|
69
|
+
output: output.trim(),
|
|
70
|
+
});
|
|
71
|
+
resolve(output.trim() || 'Task completed');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
168
74
|
});
|
|
169
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
170
|
-
}
|
|
171
|
-
logger_1.logger.error({
|
|
172
|
-
msg: 'Timeout waiting for task completion',
|
|
173
|
-
taskId,
|
|
174
|
-
pollCount,
|
|
175
|
-
totalTime: Date.now() - startTime,
|
|
176
|
-
maxWaitTime,
|
|
177
75
|
});
|
|
178
|
-
throw new Error('Timeout waiting for task completion');
|
|
179
76
|
};
|
|
180
|
-
exports.
|
|
77
|
+
exports.executeBrowserTask = executeBrowserTask;
|
|
181
78
|
//# sourceMappingURL=executeBrowserTask.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeBrowserTask.js","sourceRoot":"","sources":["../../src/browserTask/executeBrowserTask.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"executeBrowserTask.js","sourceRoot":"","sources":["../../src/browserTask/executeBrowserTask.ts"],"names":[],"mappings":";;;AAAA,iDAAsC;AACtC,+BAA4B;AAC5B,4CAAyC;AAElC,MAAM,kBAAkB,GAAG,KAAK,EAAE,MAAc,EAAmB,EAAE;IAC1E,MAAM,gBAAgB,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAEjE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,2DAA2D;QAC3D,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,aAAa,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QAEjF,iEAAiE;QACjE,MAAM,KAAK,GAAG,IAAA,qBAAK,EAAC,aAAa,EAAE,CAAC,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE;YAC9F,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,qDAAqD;gBACrD,UAAU,EAAE,SAAS;gBACrB,uCAAuC;gBACvC,WAAW,EAAE,EAAE,CAAC,UAAU,CAAC,IAAA,WAAI,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAA,WAAI,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;aAC5F;YACD,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,WAAW,GAAG,EAAE,CAAC;QAErB,0CAA0C;QAC1C,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,eAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,eAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9D,WAAW,IAAI,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,eAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,sCAAsC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACxF,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,eAAM,CAAC,KAAK,CAAC;oBACX,OAAO,EAAE,wCAAwC;oBACjD,IAAI;oBACJ,MAAM,EAAE,WAAW;iBACpB,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,IAAI,KAAK,WAAW,EAAE,CAAC,CAAC,CAAC;YAC7E,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,uCAAuC;oBACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;oBACzC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACnB,eAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,qCAAqC,EAAE,CAAC,CAAC;wBAChE,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,6BAA6B,CAAC,CAAC;oBAC1D,CAAC;yBAAM,CAAC;wBACN,eAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;wBACtE,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAC,CAAC;oBAC9D,CAAC;gBACH,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,sDAAsD;oBACtD,eAAM,CAAC,IAAI,CAAC;wBACV,OAAO,EAAE,+CAA+C;wBACxD,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;qBACtB,CAAC,CAAC;oBACH,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,gBAAgB,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAzEW,QAAA,kBAAkB,sBAyE7B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { logger } from '../utils/logger';
|
|
4
|
+
|
|
5
|
+
export const executeBrowserTask = async (prompt: string): Promise<string> => {
|
|
6
|
+
const pythonScriptPath = join(__dirname, 'browserAgent.py');
|
|
7
|
+
const venvPythonPath = join(__dirname, '.venv', 'bin', 'python');
|
|
8
|
+
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
// Determine which Python to use - prefer venv if it exists
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const pythonCommand = fs.existsSync(venvPythonPath) ? venvPythonPath : 'python3';
|
|
13
|
+
|
|
14
|
+
// Use Python to run our browser agent script with CAPTCHA bypass
|
|
15
|
+
const child = spawn(pythonCommand, [pythonScriptPath, '-p', prompt, '--output-format', 'json'], {
|
|
16
|
+
env: {
|
|
17
|
+
...process.env,
|
|
18
|
+
// Ensure Python can find the script and dependencies
|
|
19
|
+
PYTHONPATH: __dirname,
|
|
20
|
+
// Set virtual environment if it exists
|
|
21
|
+
VIRTUAL_ENV: fs.existsSync(join(__dirname, '.venv')) ? join(__dirname, '.venv') : undefined,
|
|
22
|
+
},
|
|
23
|
+
cwd: __dirname,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
let output = '';
|
|
27
|
+
let errorOutput = '';
|
|
28
|
+
|
|
29
|
+
// Stream stdout to console and collect it
|
|
30
|
+
child.stdout.on('data', (data) => {
|
|
31
|
+
const chunk = data.toString();
|
|
32
|
+
logger.trace({ message: 'Browser task output', output: chunk });
|
|
33
|
+
output += chunk;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Stream stderr to console and collect errors
|
|
37
|
+
child.stderr.on('data', (data) => {
|
|
38
|
+
const chunk = data.toString();
|
|
39
|
+
logger.error({ message: 'Browser task error', error: chunk });
|
|
40
|
+
errorOutput += chunk;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
child.on('error', (error) => {
|
|
44
|
+
logger.error({ message: 'Failed to start browser task process', error: error.message });
|
|
45
|
+
reject(new Error(`Failed to start browser task: ${error.message}`));
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
child.on('close', (code) => {
|
|
49
|
+
if (code !== 0) {
|
|
50
|
+
logger.error({
|
|
51
|
+
message: 'Browser task process exited with error',
|
|
52
|
+
code,
|
|
53
|
+
stderr: errorOutput,
|
|
54
|
+
});
|
|
55
|
+
reject(new Error(`Browser task failed with code ${code}: ${errorOutput}`));
|
|
56
|
+
} else {
|
|
57
|
+
try {
|
|
58
|
+
// Parse JSON output from Python script
|
|
59
|
+
const result = JSON.parse(output.trim());
|
|
60
|
+
if (result.success) {
|
|
61
|
+
logger.info({ message: 'Browser task completed successfully' });
|
|
62
|
+
resolve(result.result || 'Task completed successfully');
|
|
63
|
+
} else {
|
|
64
|
+
logger.error({ message: 'Browser task failed', error: result.error });
|
|
65
|
+
reject(new Error(result.error || 'Unknown error occurred'));
|
|
66
|
+
}
|
|
67
|
+
} catch (parseError) {
|
|
68
|
+
// Fallback to plain text output if JSON parsing fails
|
|
69
|
+
logger.warn({
|
|
70
|
+
message: 'Could not parse JSON output, using plain text',
|
|
71
|
+
output: output.trim(),
|
|
72
|
+
});
|
|
73
|
+
resolve(output.trim() || 'Task completed');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Browser Agent Setup Script
|
|
4
|
+
# This script sets up the Python environment for the browser agent with CAPTCHA bypass
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "🚀 Setting up Browser Agent with CAPTCHA Bypass..."
|
|
9
|
+
|
|
10
|
+
# Get the directory where this script is located
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
cd "$SCRIPT_DIR"
|
|
13
|
+
|
|
14
|
+
# Check if Python 3 is installed
|
|
15
|
+
if ! command -v python3 &> /dev/null; then
|
|
16
|
+
echo "❌ Python 3 is not installed. Please install Python 3.11 or higher."
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Check Python version - browser-use requires Python 3.11+
|
|
21
|
+
PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
|
|
22
|
+
PYTHON_MAJOR=$(echo $PYTHON_VERSION | cut -d. -f1)
|
|
23
|
+
PYTHON_MINOR=$(echo $PYTHON_VERSION | cut -d. -f2)
|
|
24
|
+
|
|
25
|
+
if [ "$PYTHON_MAJOR" -lt 3 ] || { [ "$PYTHON_MAJOR" -eq 3 ] && [ "$PYTHON_MINOR" -lt 11 ]; }; then
|
|
26
|
+
echo "❌ Python 3.11 or higher is required for browser-use. Found Python $PYTHON_VERSION"
|
|
27
|
+
echo "💡 Please install Python 3.11+ or use a version manager like pyenv:"
|
|
28
|
+
echo " # Install pyenv (if not installed)"
|
|
29
|
+
echo " curl https://pyenv.run | bash"
|
|
30
|
+
echo " # Install and use Python 3.12"
|
|
31
|
+
echo " pyenv install 3.12.0"
|
|
32
|
+
echo " pyenv local 3.12.0"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
echo "✅ Python $PYTHON_VERSION detected"
|
|
37
|
+
|
|
38
|
+
# Check if uv is installed
|
|
39
|
+
if ! command -v uv &> /dev/null; then
|
|
40
|
+
echo "⚠️ uv is not installed. Installing uv..."
|
|
41
|
+
# Install uv
|
|
42
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
43
|
+
|
|
44
|
+
# Source the shell to get uv in PATH
|
|
45
|
+
export PATH="$HOME/.cargo/bin:$PATH"
|
|
46
|
+
|
|
47
|
+
# Verify installation
|
|
48
|
+
if ! command -v uv &> /dev/null; then
|
|
49
|
+
echo "❌ Failed to install uv. Please install manually:"
|
|
50
|
+
echo " curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
echo "✅ uv detected"
|
|
56
|
+
|
|
57
|
+
echo "🐍 Setting up Python environment with uv..."
|
|
58
|
+
|
|
59
|
+
# Create virtual environment with uv (if not exists)
|
|
60
|
+
if [ ! -d ".venv" ]; then
|
|
61
|
+
echo "🐍 Creating virtual environment..."
|
|
62
|
+
|
|
63
|
+
# Try Python 3.12 first, then fall back to 3.11
|
|
64
|
+
if uv venv --python 3.12 2>/dev/null; then
|
|
65
|
+
echo "✅ Created virtual environment with Python 3.12"
|
|
66
|
+
elif uv venv --python 3.11 2>/dev/null; then
|
|
67
|
+
echo "✅ Created virtual environment with Python 3.11"
|
|
68
|
+
else
|
|
69
|
+
echo "❌ Failed to create virtual environment with Python 3.11+. Please check your Python installation."
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
else
|
|
73
|
+
echo "✅ Virtual environment already exists"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
echo "📦 Installing Python dependencies with uv..."
|
|
77
|
+
|
|
78
|
+
# Install Python dependencies using uv
|
|
79
|
+
uv pip install -r requirements.txt
|
|
80
|
+
|
|
81
|
+
# Install playwright browsers
|
|
82
|
+
echo "🌐 Installing Playwright browsers..."
|
|
83
|
+
uv run playwright install
|
|
84
|
+
|
|
85
|
+
# Check if tesseract is installed (required for OCR)
|
|
86
|
+
if ! command -v tesseract &> /dev/null; then
|
|
87
|
+
echo "⚠️ Tesseract OCR is not installed. Installing..."
|
|
88
|
+
|
|
89
|
+
# Detect OS and install tesseract
|
|
90
|
+
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
91
|
+
# Linux
|
|
92
|
+
if command -v apt-get &> /dev/null; then
|
|
93
|
+
sudo apt-get update
|
|
94
|
+
sudo apt-get install -y tesseract-ocr tesseract-ocr-eng
|
|
95
|
+
elif command -v yum &> /dev/null; then
|
|
96
|
+
sudo yum install -y tesseract tesseract-langpack-eng
|
|
97
|
+
elif command -v dnf &> /dev/null; then
|
|
98
|
+
sudo dnf install -y tesseract tesseract-langpack-eng
|
|
99
|
+
else
|
|
100
|
+
echo "❌ Could not install tesseract automatically. Please install it manually."
|
|
101
|
+
echo " For Ubuntu/Debian: sudo apt-get install tesseract-ocr"
|
|
102
|
+
echo " For CentOS/RHEL: sudo yum install tesseract"
|
|
103
|
+
fi
|
|
104
|
+
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
|
105
|
+
# macOS
|
|
106
|
+
if command -v brew &> /dev/null; then
|
|
107
|
+
brew install tesseract
|
|
108
|
+
else
|
|
109
|
+
echo "❌ Homebrew not found. Please install tesseract manually:"
|
|
110
|
+
echo " brew install tesseract"
|
|
111
|
+
exit 1
|
|
112
|
+
fi
|
|
113
|
+
else
|
|
114
|
+
echo "❌ Unsupported OS. Please install tesseract manually."
|
|
115
|
+
exit 1
|
|
116
|
+
fi
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Verify tesseract installation
|
|
120
|
+
if command -v tesseract &> /dev/null; then
|
|
121
|
+
TESSERACT_VERSION=$(tesseract --version | head -n1)
|
|
122
|
+
echo "✅ $TESSERACT_VERSION detected"
|
|
123
|
+
else
|
|
124
|
+
echo "❌ Tesseract installation failed or not found in PATH"
|
|
125
|
+
exit 1
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Make the Python script executable
|
|
129
|
+
chmod +x browserAgent.py
|
|
130
|
+
|
|
131
|
+
echo "🎉 Setup completed successfully!"
|
|
132
|
+
echo ""
|
|
133
|
+
echo "📋 Next steps:"
|
|
134
|
+
echo "1. Activate the virtual environment:"
|
|
135
|
+
echo " source .venv/bin/activate"
|
|
136
|
+
echo ""
|
|
137
|
+
echo "2. Set your OpenAI API key in environment variables:"
|
|
138
|
+
echo " export OPENAI_API_KEY='your-api-key-here'"
|
|
139
|
+
echo ""
|
|
140
|
+
echo "3. Test the browser agent:"
|
|
141
|
+
echo " uv run python browserAgent.py -p 'Navigate to google.com and search for browser automation'"
|
|
142
|
+
echo " # Or with activated venv: python browserAgent.py -p 'Navigate to google.com'"
|
|
143
|
+
echo ""
|
|
144
|
+
echo "✨ The browser agent is now ready with CAPTCHA bypass capabilities!"
|
package/dist/cli/index.js
CHANGED
|
@@ -165,6 +165,105 @@ function generateLambdaHandler() {
|
|
|
165
165
|
process.exit(1);
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
+
function setupBrowser() {
|
|
169
|
+
try {
|
|
170
|
+
logger_1.logger.info('🚀 Setting up browser automation environment...');
|
|
171
|
+
// First, check if Python 3.11+ is available before running the setup script
|
|
172
|
+
try {
|
|
173
|
+
const pythonVersion = (0, child_process_1.execSync)('python3 -c "import sys; print(\\".\\".join(map(str, sys.version_info[:2])))"', {
|
|
174
|
+
encoding: 'utf8',
|
|
175
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
176
|
+
}).trim();
|
|
177
|
+
const [major, minor] = pythonVersion.split('.').map(Number);
|
|
178
|
+
if (major < 3 || (major === 3 && minor < 11)) {
|
|
179
|
+
logger_1.logger.error(`❌ Python ${pythonVersion} detected, but Python 3.11+ is required for browser automation.`);
|
|
180
|
+
logger_1.logger.info('');
|
|
181
|
+
logger_1.logger.info('🔧 To install Python 3.11+ using pyenv:');
|
|
182
|
+
logger_1.logger.info('');
|
|
183
|
+
logger_1.logger.info('1. Install pyenv (if not already installed):');
|
|
184
|
+
logger_1.logger.info(' curl https://pyenv.run | bash');
|
|
185
|
+
logger_1.logger.info('');
|
|
186
|
+
logger_1.logger.info('2. Restart your shell or run:');
|
|
187
|
+
logger_1.logger.info(' export PATH="$HOME/.pyenv/bin:$PATH"');
|
|
188
|
+
logger_1.logger.info(' eval "$(pyenv init -)"');
|
|
189
|
+
logger_1.logger.info('');
|
|
190
|
+
logger_1.logger.info('3. Install Python 3.12:');
|
|
191
|
+
logger_1.logger.info(' pyenv install 3.12.0');
|
|
192
|
+
logger_1.logger.info('');
|
|
193
|
+
logger_1.logger.info('4. Set Python 3.12 as default for this project:');
|
|
194
|
+
logger_1.logger.info(' pyenv local 3.12.0');
|
|
195
|
+
logger_1.logger.info('');
|
|
196
|
+
logger_1.logger.info('5. Try the setup again:');
|
|
197
|
+
logger_1.logger.info(' npx minded setup-browser');
|
|
198
|
+
logger_1.logger.info('');
|
|
199
|
+
logger_1.logger.info('🍺 Alternative - Install with Homebrew (macOS):');
|
|
200
|
+
logger_1.logger.info(' brew install python@3.12');
|
|
201
|
+
logger_1.logger.info(' ln -sf /opt/homebrew/bin/python3.12 /usr/local/bin/python3');
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
logger_1.logger.info(`✅ Python ${pythonVersion} detected (compatible)`);
|
|
205
|
+
}
|
|
206
|
+
catch (pythonCheckError) {
|
|
207
|
+
logger_1.logger.error('❌ Python 3 not found. Please install Python 3.11+ first.');
|
|
208
|
+
logger_1.logger.info('');
|
|
209
|
+
logger_1.logger.info('📥 Installation options:');
|
|
210
|
+
logger_1.logger.info('');
|
|
211
|
+
logger_1.logger.info('🍎 macOS:');
|
|
212
|
+
logger_1.logger.info(' brew install python@3.12');
|
|
213
|
+
logger_1.logger.info('');
|
|
214
|
+
logger_1.logger.info('🐧 Ubuntu/Debian:');
|
|
215
|
+
logger_1.logger.info(' sudo apt update && sudo apt install python3.12 python3.12-venv');
|
|
216
|
+
logger_1.logger.info('');
|
|
217
|
+
logger_1.logger.info('🎩 Using pyenv (recommended):');
|
|
218
|
+
logger_1.logger.info(' curl https://pyenv.run | bash');
|
|
219
|
+
logger_1.logger.info(' pyenv install 3.12.0');
|
|
220
|
+
logger_1.logger.info(' pyenv local 3.12.0');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Get the path to the browserTask directory within the installed package
|
|
224
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
225
|
+
const browserTaskDir = path.join(packageRoot, 'browserTask');
|
|
226
|
+
if (!fs.existsSync(browserTaskDir)) {
|
|
227
|
+
logger_1.logger.error(`Browser task directory not found at ${browserTaskDir}`);
|
|
228
|
+
logger_1.logger.error('This might be a package installation issue.');
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const setupScriptPath = path.join(browserTaskDir, 'setup.sh');
|
|
232
|
+
if (!fs.existsSync(setupScriptPath)) {
|
|
233
|
+
logger_1.logger.error(`Setup script not found at ${setupScriptPath}`);
|
|
234
|
+
logger_1.logger.error('This might be a package installation issue.');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
logger_1.logger.info('🐍 Running browser automation setup script...');
|
|
238
|
+
// Execute the setup script in the browserTask directory
|
|
239
|
+
(0, child_process_1.execSync)('bash setup.sh', {
|
|
240
|
+
cwd: browserTaskDir,
|
|
241
|
+
stdio: 'inherit', // Show output to user
|
|
242
|
+
});
|
|
243
|
+
logger_1.logger.info('');
|
|
244
|
+
logger_1.logger.info('✅ Browser automation environment setup completed!');
|
|
245
|
+
logger_1.logger.info('');
|
|
246
|
+
logger_1.logger.info('📋 Next steps:');
|
|
247
|
+
logger_1.logger.info('1. Set your OpenAI API key for CAPTCHA solving:');
|
|
248
|
+
logger_1.logger.info(' export OPENAI_API_KEY="your-api-key-here"');
|
|
249
|
+
logger_1.logger.info('');
|
|
250
|
+
logger_1.logger.info('2. Add to your .env file for persistence:');
|
|
251
|
+
logger_1.logger.info(' echo "OPENAI_API_KEY=your-api-key-here" >> .env');
|
|
252
|
+
logger_1.logger.info('');
|
|
253
|
+
logger_1.logger.info('3. Use browserTask nodes in your flows!');
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
logger_1.logger.error({ message: 'Failed to setup browser automation environment', error: error });
|
|
257
|
+
logger_1.logger.error('');
|
|
258
|
+
logger_1.logger.error('🛠️ Manual setup instructions:');
|
|
259
|
+
logger_1.logger.error('1. Ensure Python 3.11+ is installed and available as python3');
|
|
260
|
+
logger_1.logger.error('2. Run the setup script manually:');
|
|
261
|
+
logger_1.logger.error(' cd node_modules/@minded-ai/mindedjs/dist/browserTask');
|
|
262
|
+
logger_1.logger.error(' ./setup.sh');
|
|
263
|
+
logger_1.logger.error('');
|
|
264
|
+
logger_1.logger.error('💬 Need help? Check the documentation or create an issue.');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
168
267
|
function main() {
|
|
169
268
|
const args = process.argv.slice(2);
|
|
170
269
|
const command = args[0];
|
|
@@ -179,8 +278,11 @@ function main() {
|
|
|
179
278
|
else if (command === 'generate-lambda-ts-handler') {
|
|
180
279
|
generateLambdaHandler();
|
|
181
280
|
}
|
|
281
|
+
else if (command === 'setup-browser') {
|
|
282
|
+
setupBrowser();
|
|
283
|
+
}
|
|
182
284
|
else {
|
|
183
|
-
logger_1.logger.error('Unknown command. Available commands: token, generate-lambda-ts-handler');
|
|
285
|
+
logger_1.logger.error('Unknown command. Available commands: token, generate-lambda-ts-handler, setup-browser');
|
|
184
286
|
process.exit(1);
|
|
185
287
|
}
|
|
186
288
|
}
|