@mastra/agent-browser 0.1.0 → 0.2.0-alpha.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.
package/dist/index.d.cts CHANGED
@@ -283,11 +283,29 @@ declare const browserSchemas: {
283
283
  }, z.core.$strip>;
284
284
  };
285
285
 
286
+ /**
287
+ * AgentBrowser-specific configuration extensions.
288
+ */
289
+ interface AgentBrowserConfigExtensions {
290
+ /**
291
+ * Path to a Playwright storage state file (JSON) containing cookies and localStorage.
292
+ * This is a lighter-weight alternative to `profile` — it only persists
293
+ * authentication state, not the full browser profile.
294
+ *
295
+ * You can export storage state from a Playwright session and reuse it later.
296
+ *
297
+ * @example
298
+ * ```ts
299
+ * { storageState: './auth-state.json' }
300
+ * ```
301
+ */
302
+ storageState?: string;
303
+ }
286
304
  /**
287
305
  * Configuration options for AgentBrowser.
288
- * Type alias for BaseBrowserConfig.
306
+ * Extends the base BrowserConfig with agent-browser specific options.
289
307
  */
290
- type BrowserConfig = BrowserConfig$1;
308
+ type BrowserConfig = BrowserConfig$1 & AgentBrowserConfigExtensions;
291
309
 
292
310
  /**
293
311
  * AgentBrowserThreadManager - Thread scope management for AgentBrowser
@@ -365,6 +383,8 @@ declare class AgentBrowser extends MastraBrowser {
365
383
  /** Shared browser manager instance (for 'shared' scope) - narrowed type from base class */
366
384
  protected sharedManager: BrowserManager | null;
367
385
  private defaultTimeout;
386
+ /** Pending PID lookups — awaited in disconnect handlers to avoid racing. */
387
+ private pidLookups;
368
388
  /** Thread manager - narrowed type from base class */
369
389
  protected threadManager: AgentBrowserThreadManager;
370
390
  constructor(config?: BrowserConfig);
@@ -454,6 +474,14 @@ declare class AgentBrowser extends MastraBrowser {
454
474
  * Get the active tab index.
455
475
  */
456
476
  getActiveTabIndex(threadId?: string): Promise<number>;
477
+ /**
478
+ * Export the current browser session's storage state (cookies, localStorage) to a JSON file.
479
+ * This can later be loaded via the `storageState` config option to restore the session.
480
+ *
481
+ * @param path - File path to save the storage state JSON
482
+ * @param threadId - Optional thread ID (defaults to current thread)
483
+ */
484
+ exportStorageState(path: string, threadId?: string): Promise<void>;
457
485
  goto(input: GotoInput, threadId?: string): Promise<{
458
486
  success: true;
459
487
  url: string;
@@ -550,6 +578,17 @@ declare class AgentBrowser extends MastraBrowser {
550
578
  injectKeyboardEvent(event: KeyboardEventParams, threadId?: string): Promise<void>;
551
579
  }
552
580
 
581
+ /**
582
+ * Get the browser process PID from a BrowserManager instance via CDP.
583
+ *
584
+ * Playwright doesn't expose the browser process PID directly, so we use CDP's
585
+ * SystemInfo.getProcessInfo to get it. This works for both regular browser
586
+ * launches and persistent contexts (profiles).
587
+ *
588
+ * Returns undefined if the PID can't be retrieved (e.g., browser not running).
589
+ */
590
+ declare function getBrowserPid(manager: BrowserManager): Promise<number | undefined>;
591
+
553
592
  /**
554
593
  * Browser Tool Constants
555
594
  */
@@ -585,4 +624,4 @@ type BrowserToolName = (typeof BROWSER_TOOLS)[keyof typeof BROWSER_TOOLS];
585
624
  */
586
625
  declare function createAgentBrowserTools(browser: AgentBrowser): Record<string, Tool<any, any>>;
587
626
 
588
- export { AgentBrowser, BROWSER_TOOLS, type BackInput, type BrowserConfig, type BrowserToolName, type ClickInput, type CloseInput, type DialogInput, type DragInput, type EvaluateInput, type GotoInput, type HoverInput, type PressInput, type ScrollInput, type SelectInput, type SnapshotInput, type TabsInput, type TypeInput, type WaitInput, backInputSchema, browserSchemas, clickInputSchema, closeInputSchema, createAgentBrowserTools, dialogInputSchema, dragInputSchema, evaluateInputSchema, gotoInputSchema, hoverInputSchema, pressInputSchema, scrollInputSchema, selectInputSchema, snapshotInputSchema, tabsInputSchema, typeInputSchema, waitInputSchema };
627
+ export { AgentBrowser, BROWSER_TOOLS, type BackInput, type BrowserConfig, type BrowserToolName, type ClickInput, type CloseInput, type DialogInput, type DragInput, type EvaluateInput, type GotoInput, type HoverInput, type PressInput, type ScrollInput, type SelectInput, type SnapshotInput, type TabsInput, type TypeInput, type WaitInput, backInputSchema, browserSchemas, clickInputSchema, closeInputSchema, createAgentBrowserTools, dialogInputSchema, dragInputSchema, evaluateInputSchema, getBrowserPid, gotoInputSchema, hoverInputSchema, pressInputSchema, scrollInputSchema, selectInputSchema, snapshotInputSchema, tabsInputSchema, typeInputSchema, waitInputSchema };
package/dist/index.d.ts CHANGED
@@ -283,11 +283,29 @@ declare const browserSchemas: {
283
283
  }, z.core.$strip>;
284
284
  };
285
285
 
286
+ /**
287
+ * AgentBrowser-specific configuration extensions.
288
+ */
289
+ interface AgentBrowserConfigExtensions {
290
+ /**
291
+ * Path to a Playwright storage state file (JSON) containing cookies and localStorage.
292
+ * This is a lighter-weight alternative to `profile` — it only persists
293
+ * authentication state, not the full browser profile.
294
+ *
295
+ * You can export storage state from a Playwright session and reuse it later.
296
+ *
297
+ * @example
298
+ * ```ts
299
+ * { storageState: './auth-state.json' }
300
+ * ```
301
+ */
302
+ storageState?: string;
303
+ }
286
304
  /**
287
305
  * Configuration options for AgentBrowser.
288
- * Type alias for BaseBrowserConfig.
306
+ * Extends the base BrowserConfig with agent-browser specific options.
289
307
  */
290
- type BrowserConfig = BrowserConfig$1;
308
+ type BrowserConfig = BrowserConfig$1 & AgentBrowserConfigExtensions;
291
309
 
292
310
  /**
293
311
  * AgentBrowserThreadManager - Thread scope management for AgentBrowser
@@ -365,6 +383,8 @@ declare class AgentBrowser extends MastraBrowser {
365
383
  /** Shared browser manager instance (for 'shared' scope) - narrowed type from base class */
366
384
  protected sharedManager: BrowserManager | null;
367
385
  private defaultTimeout;
386
+ /** Pending PID lookups — awaited in disconnect handlers to avoid racing. */
387
+ private pidLookups;
368
388
  /** Thread manager - narrowed type from base class */
369
389
  protected threadManager: AgentBrowserThreadManager;
370
390
  constructor(config?: BrowserConfig);
@@ -454,6 +474,14 @@ declare class AgentBrowser extends MastraBrowser {
454
474
  * Get the active tab index.
455
475
  */
456
476
  getActiveTabIndex(threadId?: string): Promise<number>;
477
+ /**
478
+ * Export the current browser session's storage state (cookies, localStorage) to a JSON file.
479
+ * This can later be loaded via the `storageState` config option to restore the session.
480
+ *
481
+ * @param path - File path to save the storage state JSON
482
+ * @param threadId - Optional thread ID (defaults to current thread)
483
+ */
484
+ exportStorageState(path: string, threadId?: string): Promise<void>;
457
485
  goto(input: GotoInput, threadId?: string): Promise<{
458
486
  success: true;
459
487
  url: string;
@@ -550,6 +578,17 @@ declare class AgentBrowser extends MastraBrowser {
550
578
  injectKeyboardEvent(event: KeyboardEventParams, threadId?: string): Promise<void>;
551
579
  }
552
580
 
581
+ /**
582
+ * Get the browser process PID from a BrowserManager instance via CDP.
583
+ *
584
+ * Playwright doesn't expose the browser process PID directly, so we use CDP's
585
+ * SystemInfo.getProcessInfo to get it. This works for both regular browser
586
+ * launches and persistent contexts (profiles).
587
+ *
588
+ * Returns undefined if the PID can't be retrieved (e.g., browser not running).
589
+ */
590
+ declare function getBrowserPid(manager: BrowserManager): Promise<number | undefined>;
591
+
553
592
  /**
554
593
  * Browser Tool Constants
555
594
  */
@@ -585,4 +624,4 @@ type BrowserToolName = (typeof BROWSER_TOOLS)[keyof typeof BROWSER_TOOLS];
585
624
  */
586
625
  declare function createAgentBrowserTools(browser: AgentBrowser): Record<string, Tool<any, any>>;
587
626
 
588
- export { AgentBrowser, BROWSER_TOOLS, type BackInput, type BrowserConfig, type BrowserToolName, type ClickInput, type CloseInput, type DialogInput, type DragInput, type EvaluateInput, type GotoInput, type HoverInput, type PressInput, type ScrollInput, type SelectInput, type SnapshotInput, type TabsInput, type TypeInput, type WaitInput, backInputSchema, browserSchemas, clickInputSchema, closeInputSchema, createAgentBrowserTools, dialogInputSchema, dragInputSchema, evaluateInputSchema, gotoInputSchema, hoverInputSchema, pressInputSchema, scrollInputSchema, selectInputSchema, snapshotInputSchema, tabsInputSchema, typeInputSchema, waitInputSchema };
627
+ export { AgentBrowser, BROWSER_TOOLS, type BackInput, type BrowserConfig, type BrowserToolName, type ClickInput, type CloseInput, type DialogInput, type DragInput, type EvaluateInput, type GotoInput, type HoverInput, type PressInput, type ScrollInput, type SelectInput, type SnapshotInput, type TabsInput, type TypeInput, type WaitInput, backInputSchema, browserSchemas, clickInputSchema, closeInputSchema, createAgentBrowserTools, dialogInputSchema, dragInputSchema, evaluateInputSchema, getBrowserPid, gotoInputSchema, hoverInputSchema, pressInputSchema, scrollInputSchema, selectInputSchema, snapshotInputSchema, tabsInputSchema, typeInputSchema, waitInputSchema };
package/dist/index.js CHANGED
@@ -35,7 +35,10 @@ var AgentBrowserThreadManager = class extends ThreadManager {
35
35
  const manager = new BrowserManager();
36
36
  const launchOptions = {
37
37
  headless: this.browserConfig.headless ?? true,
38
- viewport: this.browserConfig.viewport
38
+ viewport: this.browserConfig.viewport,
39
+ profile: this.browserConfig.profile,
40
+ executablePath: this.browserConfig.executablePath,
41
+ storageState: this.browserConfig.storageState
39
42
  };
40
43
  if (this.browserConfig.cdpUrl && this.resolveCdpUrl) {
41
44
  launchOptions.cdpUrl = await this.resolveCdpUrl(this.browserConfig.cdpUrl);
@@ -489,12 +492,36 @@ function createAgentBrowserTools(browser) {
489
492
  };
490
493
  }
491
494
 
495
+ // src/utils.ts
496
+ async function getBrowserPid(manager) {
497
+ try {
498
+ let browser = manager.getBrowser();
499
+ if (!browser) {
500
+ const ctx = manager.getContext();
501
+ browser = ctx?.browser?.() ?? null;
502
+ }
503
+ if (!browser) return void 0;
504
+ const cdp = await browser.newBrowserCDPSession();
505
+ try {
506
+ const info = await cdp.send("SystemInfo.getProcessInfo");
507
+ const browserProcess = info.processInfo?.find((p) => p.type === "browser");
508
+ return browserProcess?.id;
509
+ } finally {
510
+ await cdp.detach().catch(() => void 0);
511
+ }
512
+ } catch {
513
+ return void 0;
514
+ }
515
+ }
516
+
492
517
  // src/agent-browser.ts
493
518
  var AgentBrowser = class extends MastraBrowser {
494
519
  id;
495
520
  name = "AgentBrowser";
496
521
  provider = "vercel-labs/agent-browser";
497
522
  defaultTimeout = 3e4;
523
+ /** Pending PID lookups — awaited in disconnect handlers to avoid racing. */
524
+ pidLookups = /* @__PURE__ */ new Set();
498
525
  constructor(config = {}) {
499
526
  super(config);
500
527
  this.id = `agent-browser-${Date.now()}`;
@@ -532,11 +559,11 @@ var AgentBrowser = class extends MastraBrowser {
532
559
  const scope = this.threadManager.getScope();
533
560
  const threadId = this.getCurrentThread();
534
561
  const existingSession = this.threadManager.hasSession(threadId);
535
- if (scope === "thread" && threadId !== DEFAULT_THREAD_ID && !existingSession) {
562
+ if (scope === "thread" && !existingSession) {
536
563
  await this.getManagerForThread(threadId);
537
564
  }
538
565
  await super.ensureReady();
539
- if (scope === "thread" && threadId !== DEFAULT_THREAD_ID && existingSession) {
566
+ if (scope === "thread" && existingSession) {
540
567
  await this.getManagerForThread(threadId);
541
568
  }
542
569
  }
@@ -569,7 +596,10 @@ var AgentBrowser = class extends MastraBrowser {
569
596
  const localConfig = this.config;
570
597
  const launchOptions = {
571
598
  headless: localConfig.headless ?? true,
572
- viewport: localConfig.viewport
599
+ viewport: localConfig.viewport,
600
+ profile: localConfig.profile,
601
+ executablePath: localConfig.executablePath,
602
+ storageState: localConfig.storageState
573
603
  };
574
604
  if (localConfig.cdpUrl) {
575
605
  launchOptions.cdpUrl = await this.resolveCdpUrl(localConfig.cdpUrl);
@@ -584,11 +614,15 @@ var AgentBrowser = class extends MastraBrowser {
584
614
  */
585
615
  setupCloseListenerForSharedScope(manager) {
586
616
  try {
617
+ const pidLookup = getBrowserPid(manager).then((pid) => {
618
+ if (pid && this.sharedManager === manager) this.sharedBrowserPid = pid;
619
+ }).finally(() => this.pidLookups.delete(pidLookup));
620
+ this.pidLookups.add(pidLookup);
587
621
  let disconnectHandled = false;
588
622
  const handleDisconnect = () => {
589
623
  if (disconnectHandled) return;
590
624
  disconnectHandled = true;
591
- this.handleBrowserDisconnected();
625
+ void pidLookup.catch(() => void 0).then(() => this.handleBrowserDisconnected());
592
626
  };
593
627
  const context = manager.getContext();
594
628
  if (context) {
@@ -607,6 +641,8 @@ var AgentBrowser = class extends MastraBrowser {
607
641
  }
608
642
  }
609
643
  async doClose() {
644
+ await Promise.allSettled([...this.pidLookups]);
645
+ this.pidLookups.clear();
610
646
  await this.threadManager.destroyAllSessions();
611
647
  this.setCurrentThread(void 0);
612
648
  const scope = this.threadManager.getScope();
@@ -690,11 +726,17 @@ var AgentBrowser = class extends MastraBrowser {
690
726
  */
691
727
  setupCloseListenerForThread(manager, threadId) {
692
728
  try {
729
+ const pidLookup = getBrowserPid(manager).then((pid) => {
730
+ if (pid && this.threadManager?.getExistingManagerForThread(threadId) === manager) {
731
+ this.threadBrowserPids.set(threadId, pid);
732
+ }
733
+ }).finally(() => this.pidLookups.delete(pidLookup));
734
+ this.pidLookups.add(pidLookup);
693
735
  let disconnectHandled = false;
694
736
  const handleDisconnect = () => {
695
737
  if (disconnectHandled) return;
696
738
  disconnectHandled = true;
697
- this.handleThreadBrowserDisconnected(threadId);
739
+ void pidLookup.catch(() => void 0).then(() => this.handleThreadBrowserDisconnected(threadId));
698
740
  };
699
741
  const context = manager.getContext();
700
742
  if (context) {
@@ -884,6 +926,25 @@ var AgentBrowser = class extends MastraBrowser {
884
926
  return 0;
885
927
  }
886
928
  }
929
+ /**
930
+ * Export the current browser session's storage state (cookies, localStorage) to a JSON file.
931
+ * This can later be loaded via the `storageState` config option to restore the session.
932
+ *
933
+ * @param path - File path to save the storage state JSON
934
+ * @param threadId - Optional thread ID (defaults to current thread)
935
+ */
936
+ async exportStorageState(path, threadId) {
937
+ const effectiveThreadId = threadId ?? this.getCurrentThread();
938
+ const manager = this.threadManager.getExistingManagerForThread(effectiveThreadId);
939
+ if (!manager) {
940
+ throw new Error("No browser is running. Launch a browser first before exporting storage state.");
941
+ }
942
+ const context = manager.getContext();
943
+ if (!context) {
944
+ throw new Error("Browser context not available");
945
+ }
946
+ await context.storageState({ path });
947
+ }
887
948
  // ---------------------------------------------------------------------------
888
949
  // 1. browser_goto - Navigate to URL
889
950
  // ---------------------------------------------------------------------------
@@ -1552,6 +1613,6 @@ var AgentBrowser = class extends MastraBrowser {
1552
1613
  }
1553
1614
  };
1554
1615
 
1555
- export { AgentBrowser, BROWSER_TOOLS, backInputSchema, browserSchemas, clickInputSchema, closeInputSchema, createAgentBrowserTools, dialogInputSchema, dragInputSchema, evaluateInputSchema, gotoInputSchema, hoverInputSchema, pressInputSchema, scrollInputSchema, selectInputSchema, snapshotInputSchema, tabsInputSchema, typeInputSchema, waitInputSchema };
1616
+ export { AgentBrowser, BROWSER_TOOLS, backInputSchema, browserSchemas, clickInputSchema, closeInputSchema, createAgentBrowserTools, dialogInputSchema, dragInputSchema, evaluateInputSchema, getBrowserPid, gotoInputSchema, hoverInputSchema, pressInputSchema, scrollInputSchema, selectInputSchema, snapshotInputSchema, tabsInputSchema, typeInputSchema, waitInputSchema };
1556
1617
  //# sourceMappingURL=index.js.map
1557
1618
  //# sourceMappingURL=index.js.map