@mastra/agent-browser 0.3.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @mastra/agent-browser
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed browser state reporting to identify when the agent or user closed the browser or changed the active URL. ([#17631](https://github.com/mastra-ai/mastra/pull/17631))
8
+
9
+ - Updated dependencies [[`d468acb`](https://github.com/mastra-ai/mastra/commit/d468acb07aec1bb19a2cb0ada8042b05b46746b2), [`575f815`](https://github.com/mastra-ai/mastra/commit/575f815c5c3567b71c0b83cbb7fa98c8253a9d9c), [`34839c1`](https://github.com/mastra-ai/mastra/commit/34839c1910b6964bf59ed0cee58844efebbb684e), [`053735a`](https://github.com/mastra-ai/mastra/commit/053735a75c2c18e23ce34d9468007efa4a45f4c4), [`306909a`](https://github.com/mastra-ai/mastra/commit/306909a693de77d709b38706e2673c9547d24a28), [`5191af8`](https://github.com/mastra-ai/mastra/commit/5191af80c799eea25357c545fc05d91b3883531d), [`43bd3d4`](https://github.com/mastra-ai/mastra/commit/43bd3d421987463fdf35386a45199c49499ed069), [`e6fa79e`](https://github.com/mastra-ai/mastra/commit/e6fa79ec72a2ddffdd25e85270398951e9d552a4), [`904bcdf`](https://github.com/mastra-ai/mastra/commit/904bcdf7b8004aa7be823f9f70ca63580e47e470), [`7f5ee1d`](https://github.com/mastra-ai/mastra/commit/7f5ee1dca46daee8d2817f2ebe49e6335da81956), [`1e9aab5`](https://github.com/mastra-ai/mastra/commit/1e9aab50ff11e6e88fde4d7cbf512c44a9fe8d61), [`2bccba4`](https://github.com/mastra-ai/mastra/commit/2bccba4c03cadc815c2d54cbf4dd43a922140a8d), [`bf8eb6d`](https://github.com/mastra-ai/mastra/commit/bf8eb6d0ec213a403eb9265a594ad283c44ab3dc), [`e9be4e7`](https://github.com/mastra-ai/mastra/commit/e9be4e747ec3d8b65548bff92f9377db06105376), [`493a328`](https://github.com/mastra-ai/mastra/commit/493a328f4346a1deeb9f1e2e44c8f2a3a4d7591b), [`d53cfc2`](https://github.com/mastra-ai/mastra/commit/d53cfc2c7f8d78343a4aa84ec4e129ba25f3325e), [`65799d4`](https://github.com/mastra-ai/mastra/commit/65799d4d549e5ebb9c848fbe3f51ac090f64becf), [`c268c89`](https://github.com/mastra-ai/mastra/commit/c268c89f4c63a93ee474d3cffdf3ea60bf00d4f2), [`34839c1`](https://github.com/mastra-ai/mastra/commit/34839c1910b6964bf59ed0cee58844efebbb684e), [`014e00f`](https://github.com/mastra-ai/mastra/commit/014e00f2b3a597a016b72f9901c6ab27d491f822), [`029a414`](https://github.com/mastra-ai/mastra/commit/029a4141719793bd3e898a39eb5a0466a55f5f3a), [`d468acb`](https://github.com/mastra-ai/mastra/commit/d468acb07aec1bb19a2cb0ada8042b05b46746b2), [`b147b29`](https://github.com/mastra-ai/mastra/commit/b147b2907f0cd1aa812efe6d6e3f58d22e66fc88), [`d371ac1`](https://github.com/mastra-ai/mastra/commit/d371ac1d9820afaaf7cfdbc380a475946a994d8f), [`2bccba4`](https://github.com/mastra-ai/mastra/commit/2bccba4c03cadc815c2d54cbf4dd43a922140a8d), [`0c72f03`](https://github.com/mastra-ai/mastra/commit/0c72f032abb13254df5a7856d64be2f207b8006d), [`cf182b7`](https://github.com/mastra-ai/mastra/commit/cf182b7fb495767946d9840ef29f19cfa906f31f), [`3b45ea9`](https://github.com/mastra-ai/mastra/commit/3b45ea95015557a6cb9d70dc5252af54ab1b78ac), [`a049c2a`](https://github.com/mastra-ai/mastra/commit/a049c2a9dfb41d0ee2e7a28874a88cd64fd5669f), [`f084be1`](https://github.com/mastra-ai/mastra/commit/f084be1fcbe33ad7480913e44d6130c421c0976f), [`b147b29`](https://github.com/mastra-ai/mastra/commit/b147b2907f0cd1aa812efe6d6e3f58d22e66fc88), [`2a96528`](https://github.com/mastra-ai/mastra/commit/2a9652848dfa3c5a2426f952e9d93554c26fd90f), [`f2ab060`](https://github.com/mastra-ai/mastra/commit/f2ab060162bea81505fda553e2cee29c1979fd04), [`5d302c8`](https://github.com/mastra-ai/mastra/commit/5d302c8eda1a6ac74eab5e442c4f64db6cc97a06), [`34839c1`](https://github.com/mastra-ai/mastra/commit/34839c1910b6964bf59ed0cee58844efebbb684e), [`a952852`](https://github.com/mastra-ai/mastra/commit/a952852c971a21fb646cd907c75fcf4443cdc963), [`2656d9c`](https://github.com/mastra-ai/mastra/commit/2656d9c2976d4f3354253bfbbbf9b88a1b2bbf34), [`63e3fe1`](https://github.com/mastra-ai/mastra/commit/63e3fe13cc1ea96f91d7c68aea92f400faf9e4da), [`1d4ce8d`](https://github.com/mastra-ai/mastra/commit/1d4ce8daaa54511f325c1b609d31b8e54009d677), [`8c68372`](https://github.com/mastra-ai/mastra/commit/8c68372e85fe0b066ec12c58bd29ffb93e54c552)]:
10
+ - @mastra/core@1.42.0
11
+
12
+ ## 0.3.1-alpha.0
13
+
14
+ ### Patch Changes
15
+
16
+ - Fixed browser state reporting to identify when the agent or user closed the browser or changed the active URL. ([#17631](https://github.com/mastra-ai/mastra/pull/17631))
17
+
18
+ - Updated dependencies [[`2bccba4`](https://github.com/mastra-ai/mastra/commit/2bccba4c03cadc815c2d54cbf4dd43a922140a8d), [`2bccba4`](https://github.com/mastra-ai/mastra/commit/2bccba4c03cadc815c2d54cbf4dd43a922140a8d), [`f2ab060`](https://github.com/mastra-ai/mastra/commit/f2ab060162bea81505fda553e2cee29c1979fd04), [`5d302c8`](https://github.com/mastra-ai/mastra/commit/5d302c8eda1a6ac74eab5e442c4f64db6cc97a06)]:
19
+ - @mastra/core@1.42.0-alpha.1
20
+
3
21
  ## 0.3.0
4
22
 
5
23
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -316,13 +316,16 @@ function createCloseTool(browser) {
316
316
  inputSchema: closeInputSchema,
317
317
  execute: async (_input, { agent }) => {
318
318
  const threadId = agent?.threadId;
319
+ browser.setCurrentThread(threadId);
319
320
  if (browser.getScope() !== "shared") {
320
321
  if (!threadId) {
321
322
  throw new Error("browser_close requires agent.threadId when browser scope is not shared");
322
323
  }
324
+ browser.markBrowserCloseReason("agent", threadId);
323
325
  await browser.closeThreadSession(threadId);
324
326
  return { success: true, hint: "Thread's browser session closed. A new session will be created on next use." };
325
327
  }
328
+ browser.markBrowserCloseReason("agent");
326
329
  await browser.close();
327
330
  return { success: true, hint: "Browser closed. It will be re-launched automatically on next use." };
328
331
  }
@@ -573,6 +576,8 @@ var AgentBrowser = class extends browser.MastraBrowser {
573
576
  defaultTimeout = 3e4;
574
577
  /** Pending PID lookups — awaited in disconnect handlers to avoid racing. */
575
578
  pidLookups = /* @__PURE__ */ new Set();
579
+ pendingCloseReasons = /* @__PURE__ */ new Map();
580
+ activeUrlChangeSources = /* @__PURE__ */ new Map();
576
581
  browserConfig;
577
582
  constructor(config = {}) {
578
583
  super(config);
@@ -641,6 +646,8 @@ var AgentBrowser = class extends browser.MastraBrowser {
641
646
  // Lifecycle
642
647
  // ---------------------------------------------------------------------------
643
648
  async doLaunch() {
649
+ this.pendingCloseReasons.clear();
650
+ this.activeUrlChangeSources.clear();
644
651
  const scope = this.threadManager.getScope();
645
652
  if (scope === "thread") {
646
653
  this.sharedManager = new agentBrowser.BrowserManager();
@@ -677,6 +684,7 @@ var AgentBrowser = class extends browser.MastraBrowser {
677
684
  const handleDisconnect = () => {
678
685
  if (disconnectHandled) return;
679
686
  disconnectHandled = true;
687
+ this.rememberClosedBrowserState(manager, "user");
680
688
  void pidLookup.catch(() => void 0).then(() => this.handleBrowserDisconnected());
681
689
  };
682
690
  const context = manager.getContext();
@@ -706,6 +714,14 @@ var AgentBrowser = class extends browser.MastraBrowser {
706
714
  }
707
715
  this.sharedManager = null;
708
716
  }
717
+ async closeThreadSession(threadId) {
718
+ const manager = this.threadManager.getExistingManagerForThread(threadId);
719
+ if (manager) {
720
+ const state = this.getBrowserStateForManager(manager, threadId);
721
+ if (state) this.threadManager.updateBrowserState(threadId, state);
722
+ }
723
+ await super.closeThreadSession(threadId);
724
+ }
709
725
  /**
710
726
  * Check if the browser is still alive by verifying the page is connected.
711
727
  * Called by base class ensureReady() to detect externally closed browsers.
@@ -756,6 +772,32 @@ var AgentBrowser = class extends browser.MastraBrowser {
756
772
  // ---------------------------------------------------------------------------
757
773
  // Helpers
758
774
  // ---------------------------------------------------------------------------
775
+ browserStateKey(threadId) {
776
+ return threadId ?? this.getCurrentThread() ?? browser.DEFAULT_THREAD_ID;
777
+ }
778
+ markBrowserCloseReason(reason, threadId) {
779
+ this.pendingCloseReasons.set(this.browserStateKey(threadId), reason);
780
+ }
781
+ markActiveUrlChangeSource(source, url, threadId) {
782
+ this.activeUrlChangeSources.set(this.browserStateKey(threadId), { url, source });
783
+ }
784
+ getCloseReason(threadId) {
785
+ return this.pendingCloseReasons.get(this.browserStateKey(threadId)) ?? this.pendingCloseReasons.get(browser.DEFAULT_THREAD_ID);
786
+ }
787
+ getActiveUrlChangeSource(activeUrl, threadId) {
788
+ const entry = this.activeUrlChangeSources.get(this.browserStateKey(threadId));
789
+ return entry && entry.url === activeUrl ? entry.source : void 0;
790
+ }
791
+ rememberClosedBrowserState(manager, reason, threadId) {
792
+ const state = this.getBrowserStateForManager(manager, threadId);
793
+ if (!state || state.tabs.length === 0) return;
794
+ const closedState = { ...state, closeReason: this.getCloseReason(threadId) ?? reason };
795
+ if (threadId) {
796
+ this.threadManager.updateBrowserState(threadId, closedState);
797
+ } else {
798
+ this.lastBrowserState = closedState;
799
+ }
800
+ }
759
801
  /**
760
802
  * Get the page for the current thread.
761
803
  * Uses thread scope if enabled, otherwise returns the shared page.
@@ -798,6 +840,7 @@ var AgentBrowser = class extends browser.MastraBrowser {
798
840
  const handleDisconnect = () => {
799
841
  if (disconnectHandled) return;
800
842
  disconnectHandled = true;
843
+ this.rememberClosedBrowserState(manager, "user", threadId);
801
844
  void pidLookup.catch(() => void 0).then(() => this.handleThreadBrowserDisconnected(threadId));
802
845
  };
803
846
  const context = manager.getContext();
@@ -929,12 +972,12 @@ var AgentBrowser = class extends browser.MastraBrowser {
929
972
  * Get the current browser state (all tabs and active tab index).
930
973
  */
931
974
  async getBrowserState(threadId) {
932
- if (!this.isBrowserRunning()) {
975
+ if (!this.isBrowserRunning(threadId)) {
933
976
  return null;
934
977
  }
935
978
  try {
936
979
  const manager = await this.getManagerForThread(threadId);
937
- return this.getBrowserStateForManager(manager);
980
+ return this.getBrowserStateForManager(manager, threadId);
938
981
  } catch {
939
982
  return null;
940
983
  }
@@ -947,22 +990,32 @@ var AgentBrowser = class extends browser.MastraBrowser {
947
990
  const effectiveThreadId = threadId ?? this.getCurrentThread() ?? browser.DEFAULT_THREAD_ID;
948
991
  const manager = this.threadManager.getExistingManagerForThread(effectiveThreadId);
949
992
  if (!manager) return null;
950
- return this.getBrowserStateForManager(manager);
993
+ return this.getBrowserStateForManager(manager, effectiveThreadId);
951
994
  }
952
995
  /**
953
996
  * Get browser state from a specific manager instance.
954
997
  */
955
- getBrowserStateForManager(manager) {
998
+ getBrowserStateForManager(manager, threadId) {
956
999
  try {
1000
+ const stateKey = this.browserStateKey(threadId);
957
1001
  const pages = manager.getPages();
958
1002
  const activeIndex = manager.getActiveIndex();
959
1003
  const tabs = pages.map((page) => ({
960
1004
  url: page.url()
961
1005
  }));
962
- return {
1006
+ const activeUrl = tabs[activeIndex]?.url;
1007
+ const previousState = this.threadManager.getSavedBrowserState(stateKey) ?? this.lastBrowserState;
1008
+ const previousUrl = previousState?.tabs[previousState.activeTabIndex]?.url;
1009
+ const activeUrlChangeSource = this.getActiveUrlChangeSource(activeUrl, stateKey) ?? (previousUrl && activeUrl !== previousUrl ? "user" : void 0);
1010
+ const state = {
963
1011
  tabs,
964
- activeTabIndex: activeIndex
1012
+ activeTabIndex: activeIndex,
1013
+ ...this.getCloseReason(stateKey) ? { closeReason: this.getCloseReason(stateKey) } : {},
1014
+ ...activeUrlChangeSource ? { activeUrlChangeSource } : {}
965
1015
  };
1016
+ this.threadManager.updateBrowserState(stateKey, state);
1017
+ this.lastBrowserState = state;
1018
+ return state;
966
1019
  } catch {
967
1020
  return null;
968
1021
  }
@@ -1017,9 +1070,11 @@ var AgentBrowser = class extends browser.MastraBrowser {
1017
1070
  timeout: input.timeout ?? this.defaultTimeout,
1018
1071
  waitUntil: input.waitUntil ?? "domcontentloaded"
1019
1072
  });
1073
+ const url = page.url();
1074
+ this.markActiveUrlChangeSource("agent", url, threadId);
1020
1075
  return {
1021
1076
  success: true,
1022
- url: page.url(),
1077
+ url,
1023
1078
  title: await page.title(),
1024
1079
  hint: "Take a snapshot to see interactive elements and get refs."
1025
1080
  };
@@ -1306,9 +1361,11 @@ var AgentBrowser = class extends browser.MastraBrowser {
1306
1361
  try {
1307
1362
  const page = await this.getPage(threadId);
1308
1363
  await page.goBack({ timeout: this.defaultTimeout });
1364
+ const url = page.url();
1365
+ this.markActiveUrlChangeSource("agent", url, threadId);
1309
1366
  return {
1310
1367
  success: true,
1311
- url: page.url(),
1368
+ url,
1312
1369
  title: await page.title(),
1313
1370
  hint: "Take a new snapshot to see the previous page."
1314
1371
  };
@@ -1439,6 +1496,7 @@ var AgentBrowser = class extends browser.MastraBrowser {
1439
1496
  if (input.url) {
1440
1497
  const page = await this.getPage(threadId);
1441
1498
  await page.goto(input.url);
1499
+ this.markActiveUrlChangeSource("agent", page.url(), threadId);
1442
1500
  }
1443
1501
  this.updateSessionBrowserState(threadId);
1444
1502
  return {
@@ -1459,6 +1517,7 @@ var AgentBrowser = class extends browser.MastraBrowser {
1459
1517
  await this.reconnectScreencastForThread(threadId, "tab switch");
1460
1518
  const page = browser.getPage();
1461
1519
  const pageUrl = page.url();
1520
+ this.markActiveUrlChangeSource("agent", pageUrl, threadId);
1462
1521
  const streamKey = this.getStreamKey(threadId);
1463
1522
  const stream = this.activeScreencastStreams.get(streamKey);
1464
1523
  if (pageUrl && stream?.isActive()) {