@minded-ai/mindedjs 2.0.7 → 2.0.8-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/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 +12 -3
- package/dist/browserTask/executeBrowserTask.d.ts.map +1 -1
- package/dist/browserTask/executeBrowserTask.js +35 -3
- package/dist/browserTask/executeBrowserTask.js.map +1 -1
- package/dist/browserTask/executeBrowserTask.py +42 -0
- package/dist/browserTask/executeBrowserTask.ts +79 -0
- package/dist/browserTask/localBrowserTask.d.ts +21 -0
- package/dist/browserTask/localBrowserTask.d.ts.map +1 -0
- package/dist/browserTask/localBrowserTask.js +229 -0
- package/dist/browserTask/localBrowserTask.js.map +1 -0
- package/dist/browserTask/requirements.txt +8 -0
- package/dist/browserTask/setup.sh +144 -0
- package/dist/cli/index.js +0 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/internalTools/retell.d.ts +12 -0
- package/dist/internalTools/retell.d.ts.map +1 -0
- package/dist/internalTools/retell.js +54 -0
- package/dist/internalTools/retell.js.map +1 -0
- package/dist/internalTools/sendPlaceholderMessage.d.ts +14 -0
- package/dist/internalTools/sendPlaceholderMessage.d.ts.map +1 -0
- package/dist/internalTools/sendPlaceholderMessage.js +61 -0
- package/dist/internalTools/sendPlaceholderMessage.js.map +1 -0
- package/dist/nodes/addBrowserTaskNode.d.ts.map +1 -1
- package/dist/nodes/addBrowserTaskNode.js +6 -1
- package/dist/nodes/addBrowserTaskNode.js.map +1 -1
- package/dist/nodes/addBrowserTaskRunNode.d.ts.map +1 -1
- package/dist/nodes/addBrowserTaskRunNode.js +1 -1
- package/dist/nodes/addBrowserTaskRunNode.js.map +1 -1
- package/dist/nodes/addRpaNode.d.ts +16 -0
- package/dist/nodes/addRpaNode.d.ts.map +1 -0
- package/dist/nodes/addRpaNode.js +177 -0
- package/dist/nodes/addRpaNode.js.map +1 -0
- package/dist/nodes/nodeFactory.d.ts.map +1 -1
- package/dist/nodes/nodeFactory.js +4 -0
- package/dist/nodes/nodeFactory.js.map +1 -1
- package/dist/types/Flows.types.d.ts +36 -2
- package/dist/types/Flows.types.d.ts.map +1 -1
- package/dist/types/Flows.types.js +13 -1
- package/dist/types/Flows.types.js.map +1 -1
- package/dist/utils/extractStateMemoryResponse.d.ts +5 -0
- package/dist/utils/extractStateMemoryResponse.d.ts.map +1 -0
- package/dist/utils/extractStateMemoryResponse.js +91 -0
- package/dist/utils/extractStateMemoryResponse.js.map +1 -0
- package/package.json +5 -2
- package/src/browserTask/executeBrowserTask.py +42 -0
- package/src/browserTask/executeBrowserTask.ts +36 -2
- package/src/browserTask/localBrowserTask.ts +250 -0
- package/src/index.ts +3 -0
- package/src/nodes/addBrowserTaskNode.ts +7 -2
- package/src/nodes/addBrowserTaskRunNode.ts +1 -0
- package/src/nodes/addRpaNode.ts +205 -0
- package/src/nodes/nodeFactory.ts +4 -0
- package/src/types/Flows.types.ts +38 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { RunnableLike } from '@langchain/core/runnables';
|
|
2
|
+
import { NodeType, RpaNode, RpaActionType } from '../types/Flows.types';
|
|
3
|
+
import { PreCompiledGraph, stateAnnotation } from '../types/LangGraph.types';
|
|
4
|
+
import { Tool } from '../types/Tools.types';
|
|
5
|
+
import { AgentEventRequestPayloads } from '../events/AgentEvents';
|
|
6
|
+
import { EmitSignature, HistoryStep } from '../types/Agent.types';
|
|
7
|
+
import { Agent } from '../agent';
|
|
8
|
+
import { logger } from '../utils/logger';
|
|
9
|
+
import { createHistoryStep } from '../utils/history';
|
|
10
|
+
import { chromium, Browser, Page } from 'playwright';
|
|
11
|
+
|
|
12
|
+
type AddRpaNodeParams = {
|
|
13
|
+
graph: PreCompiledGraph;
|
|
14
|
+
node: RpaNode;
|
|
15
|
+
tools: Tool<any, any>[];
|
|
16
|
+
emit: EmitSignature<any, keyof AgentEventRequestPayloads<any>>;
|
|
17
|
+
agent: Agent;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const addRpaNode = async ({ graph, node, tools, emit, agent }: AddRpaNodeParams) => {
|
|
21
|
+
const callback: RunnableLike = async (state: typeof stateAnnotation.State) => {
|
|
22
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId);
|
|
23
|
+
logger.info({ msg: `[Node] Executing RPA node`, node: node.displayName, sessionId: state.sessionId });
|
|
24
|
+
|
|
25
|
+
let browser: Browser | null = null;
|
|
26
|
+
let page: Page | null = null;
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
// Get CDP URL from state
|
|
30
|
+
const cdpUrl = state.cdpUrl;
|
|
31
|
+
if (!cdpUrl) {
|
|
32
|
+
throw new Error('CDP URL not found in state. Make sure a browser session is available.');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
logger.debug({
|
|
36
|
+
msg: '[RPA] Connecting to browser via CDP',
|
|
37
|
+
cdpUrl,
|
|
38
|
+
sessionId: state.sessionId,
|
|
39
|
+
node: node.displayName,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Connect to existing browser via CDP
|
|
43
|
+
browser = await chromium.connectOverCDP(cdpUrl);
|
|
44
|
+
const contexts = browser.contexts();
|
|
45
|
+
if (contexts.length === 0) {
|
|
46
|
+
throw new Error('No browser contexts found');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Get the first page or create a new one
|
|
50
|
+
const pages = contexts[0].pages();
|
|
51
|
+
page = pages.length > 0 ? pages[0] : await contexts[0].newPage();
|
|
52
|
+
|
|
53
|
+
// Set viewport if specified
|
|
54
|
+
if (node.viewport) {
|
|
55
|
+
await page.setViewportSize(node.viewport);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Execute each step
|
|
59
|
+
const results = [];
|
|
60
|
+
for (const [index, step] of node.steps.entries()) {
|
|
61
|
+
logger.debug({
|
|
62
|
+
msg: '[RPA] Executing step',
|
|
63
|
+
stepIndex: index + 1,
|
|
64
|
+
stepType: step.type,
|
|
65
|
+
sessionId: state.sessionId,
|
|
66
|
+
node: node.displayName,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const result = await executeRpaStep(page, step);
|
|
71
|
+
results.push({
|
|
72
|
+
stepIndex: index + 1,
|
|
73
|
+
type: step.type,
|
|
74
|
+
success: true,
|
|
75
|
+
result,
|
|
76
|
+
});
|
|
77
|
+
} catch (stepError) {
|
|
78
|
+
logger.error({
|
|
79
|
+
msg: '[RPA] Step execution failed',
|
|
80
|
+
stepIndex: index + 1,
|
|
81
|
+
stepType: step.type,
|
|
82
|
+
error: stepError instanceof Error ? stepError.message : 'Unknown error',
|
|
83
|
+
sessionId: state.sessionId,
|
|
84
|
+
node: node.displayName,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
results.push({
|
|
88
|
+
stepIndex: index + 1,
|
|
89
|
+
type: step.type,
|
|
90
|
+
success: false,
|
|
91
|
+
error: stepError instanceof Error ? stepError.message : 'Unknown error',
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Stop execution on error unless configured otherwise
|
|
95
|
+
throw stepError;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Update history with RPA execution results
|
|
100
|
+
state.history.push(
|
|
101
|
+
createHistoryStep<HistoryStep>(state.history, {
|
|
102
|
+
type: NodeType.RPA,
|
|
103
|
+
nodeId: node.name,
|
|
104
|
+
nodeDisplayName: node.displayName,
|
|
105
|
+
raw: {
|
|
106
|
+
steps: node.steps,
|
|
107
|
+
results,
|
|
108
|
+
viewport: node.viewport,
|
|
109
|
+
},
|
|
110
|
+
messageIds: [],
|
|
111
|
+
}),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// Clear goto to allow natural flow progression
|
|
115
|
+
state.goto = null;
|
|
116
|
+
|
|
117
|
+
// Check for interrupts after RPA execution
|
|
118
|
+
await agent.interruptSessionManager.checkQueueAndInterrupt(state.sessionId, state);
|
|
119
|
+
|
|
120
|
+
return state;
|
|
121
|
+
} catch (error) {
|
|
122
|
+
logger.error({
|
|
123
|
+
msg: '[RPA] Error executing RPA node',
|
|
124
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
125
|
+
sessionId: state.sessionId,
|
|
126
|
+
node: node.displayName,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
throw error;
|
|
130
|
+
} finally {
|
|
131
|
+
// Note: We don't close the browser as it's connected via CDP
|
|
132
|
+
// The browser session should remain active for other operations
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
graph.addNode(node.name, callback);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Helper function to execute individual RPA steps
|
|
140
|
+
async function executeRpaStep(page: Page, step: any): Promise<any> {
|
|
141
|
+
switch (step.type) {
|
|
142
|
+
case RpaActionType.CLICK:
|
|
143
|
+
if (step.xpath) {
|
|
144
|
+
await page.locator(`xpath=${step.xpath}`).click({ timeout: 30000 });
|
|
145
|
+
} else if (step.selector) {
|
|
146
|
+
await page.click(step.selector, { timeout: 30000 });
|
|
147
|
+
}
|
|
148
|
+
return { action: 'clicked' };
|
|
149
|
+
|
|
150
|
+
case RpaActionType.TYPE:
|
|
151
|
+
if (step.shouldReplaceExistingText) {
|
|
152
|
+
if (step.xpath) {
|
|
153
|
+
await page.locator(`xpath=${step.xpath}`).fill(step.text || '');
|
|
154
|
+
} else if (step.selector) {
|
|
155
|
+
await page.fill(step.selector, step.text || '');
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
if (step.xpath) {
|
|
159
|
+
await page.locator(`xpath=${step.xpath}`).type(step.text || '');
|
|
160
|
+
} else if (step.selector) {
|
|
161
|
+
await page.type(step.selector, step.text || '');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { action: 'typed', text: step.text };
|
|
165
|
+
|
|
166
|
+
case RpaActionType.WAIT:
|
|
167
|
+
await page.waitForTimeout(step.waitTime || 1000);
|
|
168
|
+
return { action: 'waited', duration: step.waitTime };
|
|
169
|
+
|
|
170
|
+
case RpaActionType.GOTO:
|
|
171
|
+
await page.goto(step.url || '', { waitUntil: 'networkidle' });
|
|
172
|
+
return { action: 'navigated', url: step.url };
|
|
173
|
+
|
|
174
|
+
case RpaActionType.PRESS:
|
|
175
|
+
await page.keyboard.press(step.key || 'Enter');
|
|
176
|
+
return { action: 'pressed', key: step.key };
|
|
177
|
+
|
|
178
|
+
case RpaActionType.SELECT:
|
|
179
|
+
if (step.xpath) {
|
|
180
|
+
await page.locator(`xpath=${step.xpath}`).selectOption(step.value || '');
|
|
181
|
+
} else if (step.selector) {
|
|
182
|
+
await page.selectOption(step.selector, step.value || '');
|
|
183
|
+
}
|
|
184
|
+
return { action: 'selected', value: step.value };
|
|
185
|
+
|
|
186
|
+
case RpaActionType.HOVER:
|
|
187
|
+
if (step.xpath) {
|
|
188
|
+
await page.locator(`xpath=${step.xpath}`).hover();
|
|
189
|
+
} else if (step.selector) {
|
|
190
|
+
await page.hover(step.selector);
|
|
191
|
+
}
|
|
192
|
+
return { action: 'hovered' };
|
|
193
|
+
|
|
194
|
+
case RpaActionType.SCREENSHOT:
|
|
195
|
+
const screenshot = await page.screenshot({ type: 'png' });
|
|
196
|
+
return {
|
|
197
|
+
action: 'screenshot',
|
|
198
|
+
description: step.description,
|
|
199
|
+
data: screenshot.toString('base64'),
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
default:
|
|
203
|
+
throw new Error(`Unknown RPA action type: ${step.type}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
package/src/nodes/nodeFactory.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { Agent } from '../agent';
|
|
|
12
12
|
import { addJumpToNode } from './addJumpToNode';
|
|
13
13
|
import { addJunctionNode } from './addJunctionNode';
|
|
14
14
|
import { addBrowserTaskNode } from './addBrowserTaskNode';
|
|
15
|
+
import { addRpaNode } from './addRpaNode';
|
|
15
16
|
|
|
16
17
|
export const nodeFactory = ({
|
|
17
18
|
graph,
|
|
@@ -51,6 +52,9 @@ export const nodeFactory = ({
|
|
|
51
52
|
case NodeType.BROWSER_TASK:
|
|
52
53
|
addBrowserTaskNode({ graph, node, agent, llm });
|
|
53
54
|
break;
|
|
55
|
+
case NodeType.RPA:
|
|
56
|
+
addRpaNode({ graph, node, tools, emit, agent });
|
|
57
|
+
break;
|
|
54
58
|
default:
|
|
55
59
|
throw new Error(`Unsupported node type: ${nodeType}`);
|
|
56
60
|
}
|
package/src/types/Flows.types.ts
CHANGED
|
@@ -12,6 +12,7 @@ export enum NodeType {
|
|
|
12
12
|
PROMPT_NODE = 'promptNode',
|
|
13
13
|
JUMP_TO_NODE = 'jumpToNode',
|
|
14
14
|
BROWSER_TASK = 'browserTask',
|
|
15
|
+
RPA = 'rpa',
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export enum EdgeType {
|
|
@@ -121,6 +122,42 @@ export interface BrowserTaskNode extends BaseNode {
|
|
|
121
122
|
proxy?: string; // 2-digit country code like 'IL'
|
|
122
123
|
hooks?: { name: string }[]; // Array of hooks to be passed to the browser-use lambda
|
|
123
124
|
onPrem?: boolean;
|
|
125
|
+
localRun?: boolean;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export enum RpaActionType {
|
|
129
|
+
CLICK = 'click',
|
|
130
|
+
TYPE = 'type',
|
|
131
|
+
WAIT = 'wait',
|
|
132
|
+
SCREENSHOT = 'screenshot',
|
|
133
|
+
SELECT = 'select',
|
|
134
|
+
HOVER = 'hover',
|
|
135
|
+
PRESS = 'press',
|
|
136
|
+
GOTO = 'goto',
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface RpaStep {
|
|
140
|
+
id: string;
|
|
141
|
+
type: RpaActionType;
|
|
142
|
+
xpath?: string;
|
|
143
|
+
selector?: string;
|
|
144
|
+
text?: string;
|
|
145
|
+
value?: string;
|
|
146
|
+
key?: string;
|
|
147
|
+
url?: string;
|
|
148
|
+
shouldReplaceExistingText?: boolean;
|
|
149
|
+
waitTime?: number;
|
|
150
|
+
description?: string;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface RpaNode extends BaseNode {
|
|
154
|
+
type: NodeType.RPA;
|
|
155
|
+
steps: RpaStep[];
|
|
156
|
+
timeout?: number;
|
|
157
|
+
viewport?: {
|
|
158
|
+
width: number;
|
|
159
|
+
height: number;
|
|
160
|
+
};
|
|
124
161
|
}
|
|
125
162
|
|
|
126
163
|
export type TriggerNode = AppTriggerNode | WebhookTriggerNode | ManualTriggerNode | VoiceTriggerNode | InterfaceTriggerNode;
|
|
@@ -145,7 +182,7 @@ export interface AppToolNode extends BaseNode, BaseAppNode {
|
|
|
145
182
|
actionKey: string;
|
|
146
183
|
}
|
|
147
184
|
|
|
148
|
-
export type Node = TriggerNode | JunctionNode | ToolNode | AppToolNode | PromptNode | JumpToNode | BrowserTaskNode;
|
|
185
|
+
export type Node = TriggerNode | JunctionNode | ToolNode | AppToolNode | PromptNode | JumpToNode | BrowserTaskNode | RpaNode;
|
|
149
186
|
|
|
150
187
|
export interface BaseEdge {
|
|
151
188
|
source: string;
|