@minded-ai/mindedjs 3.1.45 → 3.1.48

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.
Files changed (35) hide show
  1. package/dist/browserTask/resolveRpaBrowserSessionOptions.d.ts +13 -0
  2. package/dist/browserTask/resolveRpaBrowserSessionOptions.d.ts.map +1 -0
  3. package/dist/browserTask/resolveRpaBrowserSessionOptions.js +14 -0
  4. package/dist/browserTask/resolveRpaBrowserSessionOptions.js.map +1 -0
  5. package/dist/nodes/addBrowserTaskNode.js +7 -7
  6. package/dist/nodes/addBrowserTaskNode.js.map +1 -1
  7. package/dist/nodes/addPromptNode.d.ts.map +1 -1
  8. package/dist/nodes/addPromptNode.js +7 -20
  9. package/dist/nodes/addPromptNode.js.map +1 -1
  10. package/dist/nodes/addToolRunNode.d.ts.map +1 -1
  11. package/dist/nodes/addToolRunNode.js +8 -4
  12. package/dist/nodes/addToolRunNode.js.map +1 -1
  13. package/dist/platform/config.d.ts +2 -0
  14. package/dist/platform/config.d.ts.map +1 -1
  15. package/dist/platform/config.js +70 -4
  16. package/dist/platform/config.js.map +1 -1
  17. package/dist/platform/toolExecutor.d.ts.map +1 -1
  18. package/dist/platform/toolExecutor.js +7 -6
  19. package/dist/platform/toolExecutor.js.map +1 -1
  20. package/dist/toolsLibrary/browserSessionPersistence.d.ts.map +1 -1
  21. package/dist/toolsLibrary/browserSessionPersistence.js +27 -8
  22. package/dist/toolsLibrary/browserSessionPersistence.js.map +1 -1
  23. package/dist/toolsLibrary/extraction.d.ts +2 -2
  24. package/docs/api/knowledge.md +73 -14
  25. package/docs/low-code-editor/rpa-tools.md +18 -1
  26. package/docs/platform/knowledge-bases.md +14 -2
  27. package/docs/tooling/document-processing.md +16 -2
  28. package/package.json +15 -6
  29. package/src/browserTask/resolveRpaBrowserSessionOptions.ts +26 -0
  30. package/src/nodes/addBrowserTaskNode.ts +2 -2
  31. package/src/nodes/addPromptNode.ts +7 -22
  32. package/src/nodes/addToolRunNode.ts +8 -3
  33. package/src/platform/config.ts +75 -4
  34. package/src/platform/toolExecutor.ts +6 -5
  35. package/src/toolsLibrary/browserSessionPersistence.ts +60 -12
@@ -3,6 +3,7 @@ import { config } from 'dotenv';
3
3
  import { Environment } from '../types/Platform.types';
4
4
  import { BrowserTaskMode } from '../browserTask/types';
5
5
  import { logger } from '../utils/logger';
6
+ import { MindedProxyMode, ProxyConfig, ProxyProvider } from '../types/Tools.types';
6
7
  const path = resolve(__dirname, '../../.env');
7
8
  config({ path });
8
9
 
@@ -18,6 +19,7 @@ type MindedConfig = {
18
19
  elevenLabsKey: string | null;
19
20
  elevenLabsAgentId: string | null;
20
21
  browserTaskMode: BrowserTaskMode;
22
+ proxyConfig: ProxyConfig | null;
21
23
  isDeprioritizedSocket: boolean;
22
24
  };
23
25
 
@@ -37,8 +39,73 @@ const parseBrowserTaskMode = (value: string | undefined): BrowserTaskMode => {
37
39
  return BrowserTaskMode.CLOUD;
38
40
  };
39
41
 
42
+ const parseProxyConfig = (): ProxyConfig | null => {
43
+ const provider = process.env.BROWSER_PROXY_PROVIDER?.trim();
44
+ if (!provider) {
45
+ return null;
46
+ }
47
+
48
+ if (provider === ProxyProvider.MINDED) {
49
+ const mode = process.env.BROWSER_PROXY_MODE?.trim();
50
+ if (mode === MindedProxyMode.TRUSTED_IP) {
51
+ return {
52
+ provider: ProxyProvider.MINDED,
53
+ mode: MindedProxyMode.TRUSTED_IP,
54
+ };
55
+ }
56
+ if (mode === MindedProxyMode.REGION) {
57
+ const countryCode = process.env.BROWSER_PROXY_COUNTRY_CODE?.trim();
58
+ if (!countryCode) {
59
+ logger.warn({
60
+ message: 'BROWSER_PROXY_COUNTRY_CODE is required when BROWSER_PROXY_MODE is region; ignoring proxy config',
61
+ });
62
+ return null;
63
+ }
64
+ return {
65
+ provider: ProxyProvider.MINDED,
66
+ mode: MindedProxyMode.REGION,
67
+ countryCode,
68
+ };
69
+ }
70
+ logger.warn({
71
+ message: 'Invalid BROWSER_PROXY_MODE provided; ignoring proxy config',
72
+ provided: mode,
73
+ allowed: [MindedProxyMode.TRUSTED_IP, MindedProxyMode.REGION],
74
+ });
75
+ return null;
76
+ }
77
+
78
+ if (provider === ProxyProvider.CUSTOM) {
79
+ const server = process.env.BROWSER_PROXY_SERVER?.trim();
80
+ if (!server) {
81
+ logger.warn({
82
+ message: 'BROWSER_PROXY_SERVER is required when BROWSER_PROXY_PROVIDER is custom; ignoring proxy config',
83
+ });
84
+ return null;
85
+ }
86
+ const username = process.env.BROWSER_PROXY_USERNAME?.trim();
87
+ const password = process.env.BROWSER_PROXY_PASSWORD?.trim();
88
+ return {
89
+ provider: ProxyProvider.CUSTOM,
90
+ server,
91
+ ...(username ? { username } : {}),
92
+ ...(password ? { password } : {}),
93
+ };
94
+ }
95
+
96
+ logger.warn({
97
+ message: 'Invalid BROWSER_PROXY_PROVIDER provided; ignoring proxy config',
98
+ provided: provider,
99
+ allowed: [ProxyProvider.MINDED, ProxyProvider.CUSTOM],
100
+ });
101
+ return null;
102
+ };
103
+
40
104
  export const getConfig = (): MindedConfig => {
41
105
  const environment = (process.env.NODE_ENV as Environment) || Environment.DEVELOPMENT;
106
+ const browserTaskMode = parseBrowserTaskMode(process.env.BROWSER_TASK_MODE);
107
+ const proxyConfig = parseProxyConfig();
108
+
42
109
  switch (environment) {
43
110
  case Environment.TEST:
44
111
  return {
@@ -52,7 +119,8 @@ export const getConfig = (): MindedConfig => {
52
119
  dashboardConnected: false,
53
120
  elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
54
121
  elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || null,
55
- browserTaskMode: parseBrowserTaskMode(process.env.BROWSER_TASK_MODE),
122
+ browserTaskMode,
123
+ proxyConfig,
56
124
  isDeprioritizedSocket: process.env.IS_DEPRIORITIZED_SOCKET === 'true',
57
125
  };
58
126
  case Environment.DEVELOPMENT:
@@ -67,7 +135,8 @@ export const getConfig = (): MindedConfig => {
67
135
  elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
68
136
  dashboardConnected: true,
69
137
  elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || 'agent_01jye194psezr909nwec27m2t9',
70
- browserTaskMode: parseBrowserTaskMode(process.env.BROWSER_TASK_MODE),
138
+ browserTaskMode,
139
+ proxyConfig,
71
140
  isDeprioritizedSocket: process.env.IS_DEPRIORITIZED_SOCKET === 'true',
72
141
  };
73
142
  case Environment.STAGING:
@@ -82,7 +151,8 @@ export const getConfig = (): MindedConfig => {
82
151
  elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
83
152
  dashboardConnected: false,
84
153
  elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || 'agent_01jye1ajkaf17axpcxg220qwcm',
85
- browserTaskMode: parseBrowserTaskMode(process.env.BROWSER_TASK_MODE),
154
+ browserTaskMode,
155
+ proxyConfig,
86
156
  isDeprioritizedSocket: process.env.IS_DEPRIORITIZED_SOCKET === 'true',
87
157
  };
88
158
  case Environment.PRODUCTION:
@@ -97,7 +167,8 @@ export const getConfig = (): MindedConfig => {
97
167
  elevenLabsKey: process.env.ELEVEN_LABS_API_KEY || null,
98
168
  dashboardConnected: false,
99
169
  elevenLabsAgentId: process.env.ELEVEN_LABS_AGENT_ID || 'agent_01jye1ajkaf17axpcxg220qwcm',
100
- browserTaskMode: parseBrowserTaskMode(process.env.BROWSER_TASK_MODE),
170
+ browserTaskMode,
171
+ proxyConfig,
101
172
  isDeprioritizedSocket: process.env.IS_DEPRIORITIZED_SOCKET === 'true',
102
173
  };
103
174
  }
@@ -2,7 +2,7 @@ import { Tool } from '../types/Tools.types';
2
2
  import { Agent } from '../agent';
3
3
  import { logger } from '../utils/logger';
4
4
  import { withBrowserSession } from '../toolsLibrary/withBrowserSession';
5
- import { getConfig } from './config';
5
+ import { resolveRpaBrowserSessionOptions } from '../browserTask/resolveRpaBrowserSessionOptions';
6
6
 
7
7
  export interface ToolExecutionRequest {
8
8
  toolName: string;
@@ -86,9 +86,10 @@ export class ToolExecutor {
86
86
 
87
87
  // Check if this is an RPA tool
88
88
  if (tool.type === 'rpa') {
89
- const configBrowserTaskMode = getConfig().browserTaskMode;
90
- // Use tool's browserTaskMode if provided, otherwise fall back to config
91
- const browserTaskMode = tool.browserTaskMode ?? configBrowserTaskMode;
89
+ const { browserTaskMode, proxyConfig } = resolveRpaBrowserSessionOptions({
90
+ toolBrowserTaskMode: tool.browserTaskMode,
91
+ toolProxyConfig: tool.proxyConfig,
92
+ });
92
93
 
93
94
  // Wrap with browser session and screenshot capture
94
95
  const { result, breakpointHit, breakpointInfo } = await withBrowserSession(
@@ -96,7 +97,7 @@ export class ToolExecutor {
96
97
  sessionId,
97
98
  browserTaskMode,
98
99
  toolCallId: requestId, // Use requestId as toolCallId for tracking
99
- proxyConfig: tool.proxyConfig,
100
+ proxyConfig,
100
101
  toolName,
101
102
  persistSession: tool.persistSession,
102
103
  },
@@ -3,6 +3,7 @@ import { logger } from '../utils/logger';
3
3
  import { saveRecord, getRecords } from './storage';
4
4
 
5
5
  const BROWSER_SESSION_KEY = 'browser-session';
6
+ const STORAGE_OPERATION_TIMEOUT_MS = 3000;
6
7
 
7
8
  interface Cookie {
8
9
  name: string;
@@ -20,11 +21,34 @@ interface LocalStorageEntry {
20
21
  data: Record<string, string>;
21
22
  }
22
23
 
24
+ const withTimeout = async <T>(promise: Promise<T>, timeoutMs: number, operation: string): Promise<T> => {
25
+ let timeout: NodeJS.Timeout | null = null;
26
+
27
+ try {
28
+ return await Promise.race([
29
+ promise,
30
+ new Promise<never>((_, reject) => {
31
+ timeout = setTimeout(() => {
32
+ reject(new Error(`${operation} timed out after ${timeoutMs}ms`));
33
+ }, timeoutMs);
34
+ }),
35
+ ]);
36
+ } finally {
37
+ if (timeout) {
38
+ clearTimeout(timeout);
39
+ }
40
+ }
41
+ };
42
+
23
43
  /**
24
44
  * Extract localStorage from the current page
25
45
  */
26
46
  const extractLocalStorageFromPage = async (page: Page): Promise<Record<string, string>> => {
27
- return await page.evaluate(() => Object.fromEntries(Object.entries(localStorage)));
47
+ return await withTimeout(
48
+ page.evaluate(() => Object.fromEntries(Object.entries(localStorage))),
49
+ STORAGE_OPERATION_TIMEOUT_MS,
50
+ 'Extract localStorage from current page',
51
+ );
28
52
  };
29
53
 
30
54
  /**
@@ -64,7 +88,11 @@ export const saveSessionDataViaSocket = async (
64
88
  sessionId: string,
65
89
  ): Promise<void> => {
66
90
  try {
67
- const cookies = await context.cookies();
91
+ const cookies = await withTimeout(
92
+ context.cookies(),
93
+ STORAGE_OPERATION_TIMEOUT_MS,
94
+ 'Extract browser cookies',
95
+ );
68
96
  const data: Record<string, unknown> = {};
69
97
 
70
98
  if (cookies && cookies.length > 0) {
@@ -74,10 +102,18 @@ export const saveSessionDataViaSocket = async (
74
102
  // Extract localStorage for ALL origins using CDP
75
103
  let client;
76
104
  try {
77
- client = await context.newCDPSession(page);
105
+ client = await withTimeout(
106
+ context.newCDPSession(page),
107
+ STORAGE_OPERATION_TIMEOUT_MS,
108
+ 'Create CDP session for browser session persistence',
109
+ );
78
110
 
79
111
  // Enable Target domain to track all frames and their origins
80
- await client.send('Target.setDiscoverTargets', { discover: true });
112
+ await withTimeout(
113
+ client.send('Target.setDiscoverTargets', { discover: true }),
114
+ STORAGE_OPERATION_TIMEOUT_MS,
115
+ 'Enable CDP target discovery',
116
+ );
81
117
 
82
118
  // Get all targets (frames, workers, etc.)
83
119
  type TargetInfo = {
@@ -88,7 +124,11 @@ export const saveSessionDataViaSocket = async (
88
124
  attached: boolean;
89
125
  };
90
126
 
91
- const response = await client.send('Target.getTargets');
127
+ const response = await withTimeout(
128
+ client.send('Target.getTargets'),
129
+ STORAGE_OPERATION_TIMEOUT_MS,
130
+ 'Get CDP targets for localStorage persistence',
131
+ );
92
132
  const targetInfos = (response as { targetInfos: TargetInfo[] }).targetInfos;
93
133
 
94
134
  // Extract unique origins from all page-type targets
@@ -121,12 +161,16 @@ export const saveSessionDataViaSocket = async (
121
161
  entries: Array<[string, string]>;
122
162
  };
123
163
 
124
- const storageResponse = await client!.send('DOMStorage.getDOMStorageItems', {
125
- storageId: {
126
- securityOrigin: origin,
127
- isLocalStorage: true,
128
- },
129
- });
164
+ const storageResponse = await withTimeout(
165
+ client!.send('DOMStorage.getDOMStorageItems', {
166
+ storageId: {
167
+ securityOrigin: origin,
168
+ isLocalStorage: true,
169
+ },
170
+ }),
171
+ STORAGE_OPERATION_TIMEOUT_MS,
172
+ `Extract localStorage for origin ${origin}`,
173
+ );
130
174
  const { entries } = storageResponse as DOMStorageResponse;
131
175
 
132
176
  if (entries && entries.length > 0) {
@@ -178,7 +222,11 @@ export const saveSessionDataViaSocket = async (
178
222
  }
179
223
  } finally {
180
224
  if (client) {
181
- await client.detach().catch(() => { });
225
+ await withTimeout(
226
+ client.detach(),
227
+ STORAGE_OPERATION_TIMEOUT_MS,
228
+ 'Detach CDP session after browser session persistence',
229
+ ).catch(() => { });
182
230
  }
183
231
  }
184
232