@minded-ai/mindedjs 3.1.21 → 3.1.23
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.map +1 -1
- package/dist/agent.js +0 -4
- package/dist/agent.js.map +1 -1
- package/dist/browserTask/executeBrowserTask.d.ts.map +1 -1
- package/dist/browserTask/executeBrowserTask.js +1 -69
- package/dist/browserTask/executeBrowserTask.js.map +1 -1
- package/dist/cli/validateAgent.d.ts.map +1 -1
- package/dist/cli/validateAgent.js +15 -0
- package/dist/cli/validateAgent.js.map +1 -1
- package/dist/nodes/addPromptNode.d.ts.map +1 -1
- package/dist/nodes/addPromptNode.js +1 -0
- package/dist/nodes/addPromptNode.js.map +1 -1
- package/dist/nodes/addToolRunNode.d.ts.map +1 -1
- package/dist/nodes/addToolRunNode.js +1 -0
- package/dist/nodes/addToolRunNode.js.map +1 -1
- package/dist/platform/toolExecutor.d.ts.map +1 -1
- package/dist/platform/toolExecutor.js +1 -0
- package/dist/platform/toolExecutor.js.map +1 -1
- package/dist/toolsLibrary/browserSessionPersistence.d.ts +28 -0
- package/dist/toolsLibrary/browserSessionPersistence.d.ts.map +1 -0
- package/dist/toolsLibrary/browserSessionPersistence.js +159 -0
- package/dist/toolsLibrary/browserSessionPersistence.js.map +1 -0
- package/dist/toolsLibrary/withBrowserSession.d.ts +2 -1
- package/dist/toolsLibrary/withBrowserSession.d.ts.map +1 -1
- package/dist/toolsLibrary/withBrowserSession.js +65 -50
- package/dist/toolsLibrary/withBrowserSession.js.map +1 -1
- package/dist/types/Flows.types.d.ts +0 -5
- package/dist/types/Flows.types.d.ts.map +1 -1
- package/dist/types/Flows.types.js.map +1 -1
- package/dist/types/Tools.types.d.ts +1 -0
- package/dist/types/Tools.types.d.ts.map +1 -1
- package/dist/types/Tools.types.js.map +1 -1
- package/docs/low-code-editor/rpa-tools.md +4 -1
- package/docs/low-code-editor/tools.md +86 -1
- package/package.json +1 -1
- package/src/agent.ts +0 -5
- package/src/browserTask/executeBrowserTask.ts +1 -73
- package/src/cli/validateAgent.ts +17 -0
- package/src/nodes/addPromptNode.ts +1 -0
- package/src/nodes/addToolRunNode.ts +1 -0
- package/src/platform/toolExecutor.ts +1 -0
- package/src/toolsLibrary/browserSessionPersistence.ts +203 -0
- package/src/toolsLibrary/withBrowserSession.ts +74 -56
- package/src/types/Flows.types.ts +0 -5
- package/src/types/Tools.types.ts +1 -0
|
@@ -4,13 +4,10 @@ import { createBrowserSession, destroyBrowserSession } from '../browserTask/exec
|
|
|
4
4
|
import { logger } from '../utils/logger';
|
|
5
5
|
import * as fs from 'fs';
|
|
6
6
|
import * as path from 'path';
|
|
7
|
-
import { CookieStore } from '../browserTask/CookieStore';
|
|
8
7
|
import { awaitEmit, emit } from '../platform/mindedConnection';
|
|
9
8
|
import { mindedConnectionSocketMessageType } from '../platform/mindedConnectionTypes';
|
|
10
9
|
import { ProxyType } from '../types/Tools.types';
|
|
11
|
-
|
|
12
|
-
// Initialize cookie store
|
|
13
|
-
const cookieStore = new CookieStore(path.join(process.cwd(), 'local_storage', 'cookies'));
|
|
10
|
+
import { fetchSessionDataViaSocket, saveSessionDataViaSocket } from './browserSessionPersistence';
|
|
14
11
|
|
|
15
12
|
/**
|
|
16
13
|
* Strips unnecessary content from HTML to reduce file size
|
|
@@ -85,7 +82,6 @@ class ScreenshotCapture {
|
|
|
85
82
|
error,
|
|
86
83
|
});
|
|
87
84
|
});
|
|
88
|
-
|
|
89
85
|
} catch (error) {
|
|
90
86
|
logger.warn({
|
|
91
87
|
message: 'Failed to capture screenshot',
|
|
@@ -141,7 +137,7 @@ class LogsCapture {
|
|
|
141
137
|
try {
|
|
142
138
|
const timestamp = new Date().toISOString();
|
|
143
139
|
|
|
144
|
-
// Send
|
|
140
|
+
// Send full log history to backend - backend overwrites the file on each upload
|
|
145
141
|
await awaitEmit(mindedConnectionSocketMessageType.RPA_LOGS_UPLOAD, {
|
|
146
142
|
type: mindedConnectionSocketMessageType.RPA_LOGS_UPLOAD,
|
|
147
143
|
sessionId: this.sessionId,
|
|
@@ -216,13 +212,20 @@ const createProxyLocator = (
|
|
|
216
212
|
/**
|
|
217
213
|
* Create a proxy page that intercepts actions and captures screenshots and logs
|
|
218
214
|
*/
|
|
219
|
-
const createProxyPage = (
|
|
220
|
-
page: Page,
|
|
221
|
-
screenshotCapture: ScreenshotCapture,
|
|
222
|
-
logsCapture: LogsCapture,
|
|
223
|
-
): Page => {
|
|
215
|
+
const createProxyPage = (page: Page, screenshotCapture: ScreenshotCapture, logsCapture: LogsCapture): Page => {
|
|
224
216
|
// List of methods to intercept for screenshot capture and logging
|
|
225
|
-
const methodsToIntercept = [
|
|
217
|
+
const methodsToIntercept = [
|
|
218
|
+
'click',
|
|
219
|
+
'fill',
|
|
220
|
+
'type',
|
|
221
|
+
'goto',
|
|
222
|
+
'selectOption',
|
|
223
|
+
'check',
|
|
224
|
+
'uncheck',
|
|
225
|
+
'setInputFiles',
|
|
226
|
+
'waitForTimeout',
|
|
227
|
+
'evaluate',
|
|
228
|
+
];
|
|
226
229
|
// Methods that return locators and need special handling
|
|
227
230
|
const locatorMethods = ['locator'];
|
|
228
231
|
|
|
@@ -323,37 +326,6 @@ const formatLocatorActionLog = (action: string, selector: string | undefined, ar
|
|
|
323
326
|
}
|
|
324
327
|
};
|
|
325
328
|
|
|
326
|
-
// Helper function to load cookies for a session
|
|
327
|
-
const loadCookiesForSession = async (context: BrowserContext, sessionId: string): Promise<void> => {
|
|
328
|
-
const stored = await cookieStore.load();
|
|
329
|
-
if (!stored || stored.length === 0) {
|
|
330
|
-
logger.info({ message: 'No stored cookies to load', sessionId });
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
try {
|
|
335
|
-
await context.addCookies(stored);
|
|
336
|
-
logger.info({ message: 'Loaded cookies into browser session', sessionId, count: stored.length });
|
|
337
|
-
} catch (error) {
|
|
338
|
-
logger.warn({ message: 'Failed to add cookies to context', sessionId, error });
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
// Helper function to save cookies for a session
|
|
343
|
-
const saveCookiesForSession = async (context: BrowserContext, sessionId: string): Promise<void> => {
|
|
344
|
-
try {
|
|
345
|
-
const cookies = await context.cookies();
|
|
346
|
-
if (cookies && cookies.length > 0) {
|
|
347
|
-
await cookieStore.save(cookies);
|
|
348
|
-
logger.info({ message: 'Saved cookies from browser session', sessionId, count: cookies.length });
|
|
349
|
-
} else {
|
|
350
|
-
logger.info({ message: 'No cookies found in browser session', sessionId });
|
|
351
|
-
}
|
|
352
|
-
} catch (error) {
|
|
353
|
-
logger.warn({ message: 'Failed to get/save cookies from session', sessionId, error: JSON.stringify(error) });
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
|
|
357
329
|
export const withBrowserSession = async <T>(
|
|
358
330
|
{
|
|
359
331
|
sessionId,
|
|
@@ -365,6 +337,7 @@ export const withBrowserSession = async <T>(
|
|
|
365
337
|
proxyUser,
|
|
366
338
|
proxyPass,
|
|
367
339
|
toolName,
|
|
340
|
+
persistSession = true,
|
|
368
341
|
}: {
|
|
369
342
|
sessionId: string;
|
|
370
343
|
browserTaskMode: BrowserTaskMode;
|
|
@@ -375,10 +348,19 @@ export const withBrowserSession = async <T>(
|
|
|
375
348
|
proxyUser?: string;
|
|
376
349
|
proxyPass?: string;
|
|
377
350
|
toolName: string;
|
|
351
|
+
persistSession?: boolean;
|
|
378
352
|
},
|
|
379
353
|
callback: (page: Page) => Promise<T>,
|
|
380
354
|
): Promise<{ result: T }> => {
|
|
381
|
-
const { cdpUrl } = await createBrowserSession({
|
|
355
|
+
const { cdpUrl } = await createBrowserSession({
|
|
356
|
+
sessionId,
|
|
357
|
+
browserTaskMode,
|
|
358
|
+
proxyCountryCode,
|
|
359
|
+
proxyType,
|
|
360
|
+
proxyServer,
|
|
361
|
+
proxyUser,
|
|
362
|
+
proxyPass,
|
|
363
|
+
});
|
|
382
364
|
if (!cdpUrl) {
|
|
383
365
|
throw new Error('CDP URL was not provided by the browser session.');
|
|
384
366
|
}
|
|
@@ -409,16 +391,52 @@ export const withBrowserSession = async <T>(
|
|
|
409
391
|
const logsCapture = new LogsCapture(sessionId, toolCallId);
|
|
410
392
|
page = createProxyPage(page, screenshotCapture, logsCapture);
|
|
411
393
|
|
|
412
|
-
// Load cookies
|
|
413
|
-
|
|
414
|
-
if (browserTaskMode === BrowserTaskMode.LOCAL && !noCookies) {
|
|
394
|
+
// Load session data (cookies + localStorage) once at startup (if persistence is enabled)
|
|
395
|
+
if (persistSession) {
|
|
415
396
|
try {
|
|
416
|
-
await
|
|
397
|
+
const { cookies, localStorage: localStorageEntries } = await fetchSessionDataViaSocket();
|
|
398
|
+
|
|
399
|
+
// Load cookies into browser context
|
|
400
|
+
if (cookies && cookies.length > 0) {
|
|
401
|
+
await context.addCookies(cookies);
|
|
402
|
+
logger.info({ message: 'Loaded cookies into browser session', sessionId, count: cookies.length });
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Inject localStorage for ALL origins using addInitScript
|
|
406
|
+
// This runs on EVERY page load, but only sets items that don't already exist
|
|
407
|
+
// This prevents overwriting user changes during the session while restoring stored data
|
|
408
|
+
if (localStorageEntries && localStorageEntries.length > 0) {
|
|
409
|
+
const localStorageByOrigin = localStorageEntries.reduce(
|
|
410
|
+
(acc, entry) => {
|
|
411
|
+
try {
|
|
412
|
+
const origin = new URL(entry.url).origin;
|
|
413
|
+
acc[origin] = entry.data;
|
|
414
|
+
} catch (error) {
|
|
415
|
+
logger.warn({ message: 'Failed to parse origin for localStorage', url: entry.url, error });
|
|
416
|
+
}
|
|
417
|
+
return acc;
|
|
418
|
+
},
|
|
419
|
+
{} as Record<string, Record<string, string>>,
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
await context.addInitScript((storageData: Record<string, Record<string, string>>) => {
|
|
423
|
+
const currentOrigin = window.location.origin;
|
|
424
|
+
const dataForOrigin = storageData[currentOrigin];
|
|
425
|
+
|
|
426
|
+
if (dataForOrigin) {
|
|
427
|
+
// Only set items that don't already exist (non-destructive merge)
|
|
428
|
+
// This preserves any changes made by the user during the current session
|
|
429
|
+
for (const [key, value] of Object.entries(dataForOrigin)) {
|
|
430
|
+
if (localStorage.getItem(key) === null) {
|
|
431
|
+
localStorage.setItem(key, value);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}, localStorageByOrigin);
|
|
436
|
+
}
|
|
417
437
|
} catch (error) {
|
|
418
|
-
logger.warn({ message: 'Failed to load
|
|
438
|
+
logger.warn({ message: 'Failed to load session data', sessionId, error });
|
|
419
439
|
}
|
|
420
|
-
} else if (noCookies) {
|
|
421
|
-
logger.info({ message: 'Cookies disabled via cookies=false flag', sessionId });
|
|
422
440
|
}
|
|
423
441
|
|
|
424
442
|
// Configure download behavior via CDP
|
|
@@ -532,12 +550,12 @@ export const withBrowserSession = async <T>(
|
|
|
532
550
|
}
|
|
533
551
|
}
|
|
534
552
|
|
|
535
|
-
// Save cookies before destroying session (
|
|
536
|
-
if (
|
|
553
|
+
// Save cookies and localStorage before destroying session (if persistence is enabled)
|
|
554
|
+
if (persistSession) {
|
|
537
555
|
try {
|
|
538
|
-
await
|
|
556
|
+
await saveSessionDataViaSocket(context, page, sessionId);
|
|
539
557
|
} catch (error) {
|
|
540
|
-
logger.warn({ message: 'Failed to save
|
|
558
|
+
logger.warn({ message: 'Failed to save session data', sessionId, error });
|
|
541
559
|
}
|
|
542
560
|
}
|
|
543
561
|
|
|
@@ -545,7 +563,7 @@ export const withBrowserSession = async <T>(
|
|
|
545
563
|
sessionId,
|
|
546
564
|
localRun: browserTaskMode === BrowserTaskMode.LOCAL,
|
|
547
565
|
onPrem: browserTaskMode === BrowserTaskMode.ON_PREM,
|
|
548
|
-
}).catch(() => {
|
|
566
|
+
}).catch(() => {});
|
|
549
567
|
}
|
|
550
568
|
};
|
|
551
569
|
|
package/src/types/Flows.types.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { LLMConfig } from './LLM.types';
|
|
2
2
|
import { ToolType } from './Tools.types';
|
|
3
|
-
export interface Position {
|
|
4
|
-
x: number;
|
|
5
|
-
y: number;
|
|
6
|
-
}
|
|
7
3
|
|
|
8
4
|
export enum NodeType {
|
|
9
5
|
TRIGGER = 'trigger',
|
|
@@ -24,7 +20,6 @@ export enum EdgeType {
|
|
|
24
20
|
export interface BaseNode {
|
|
25
21
|
name: string;
|
|
26
22
|
type: NodeType;
|
|
27
|
-
position?: Position;
|
|
28
23
|
humanInTheLoop?: boolean;
|
|
29
24
|
canStayOnNode?: boolean;
|
|
30
25
|
displayName: string;
|
package/src/types/Tools.types.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface RPATool<Input extends z.ZodSchema, Memory = any, Output extends
|
|
|
33
33
|
proxyUser?: string; // Custom proxy username - used when proxyType is CUSTOM
|
|
34
34
|
proxyPass?: string; // Custom proxy password - used when proxyType is CUSTOM
|
|
35
35
|
browserTaskMode?: BrowserTaskMode; // Optional browser provider (local/cloud/onPrem)
|
|
36
|
+
persistSession?: boolean; // Session persistence: true (global persistence with cloud storage, default), false (no persistence)
|
|
36
37
|
execute: (input: RPAToolExecuteInput<Input, Memory>) => Promise<ToolReturnType>;
|
|
37
38
|
}
|
|
38
39
|
|