@mastra/stagehand 0.3.2 → 0.3.3

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.js CHANGED
@@ -230,14 +230,17 @@ function createCloseTool(browser) {
230
230
  inputSchema: closeInputSchema,
231
231
  execute: async (_input, { agent }) => {
232
232
  const threadId = agent?.threadId;
233
+ browser.setCurrentThread(threadId);
233
234
  if (browser.getScope() !== "shared") {
234
235
  if (!threadId) throw new Error("stagehand_close requires agent.threadId when browser scope is not shared");
236
+ browser.markBrowserCloseReason("agent", threadId);
235
237
  await browser.closeThreadSession(threadId);
236
238
  return {
237
239
  success: true,
238
240
  hint: "Thread's browser session closed. A new session will be created on next use."
239
241
  };
240
242
  }
243
+ browser.markBrowserCloseReason("agent");
241
244
  await browser.close();
242
245
  return {
243
246
  success: true,
@@ -441,6 +444,7 @@ var StagehandBrowser = class extends MastraBrowser {
441
444
  stagehandConfig;
442
445
  /** Debounce timers per thread for tab change reconnection */
443
446
  tabChangeDebounceTimers = /* @__PURE__ */ new Map();
447
+ pendingCloseReasons = /* @__PURE__ */ new Map();
444
448
  constructor(config = {}) {
445
449
  super(config);
446
450
  this.id = `stagehand-${Date.now()}`;
@@ -520,6 +524,7 @@ var StagehandBrowser = class extends MastraBrowser {
520
524
  return stagehand;
521
525
  }
522
526
  async doLaunch() {
527
+ this.pendingCloseReasons.clear();
523
528
  const scope = this.getScope();
524
529
  this.threadManager.setCreateStagehand(() => this.createStagehandInstance());
525
530
  if (scope === "thread") return;
@@ -547,6 +552,7 @@ var StagehandBrowser = class extends MastraBrowser {
547
552
  const handleDisconnect = () => {
548
553
  if (disconnectHandled) return;
549
554
  disconnectHandled = true;
555
+ this.rememberClosedBrowserState(stagehand, "user", threadId);
550
556
  onDisconnect();
551
557
  };
552
558
  try {
@@ -587,9 +593,30 @@ var StagehandBrowser = class extends MastraBrowser {
587
593
  this.patchExitType();
588
594
  }
589
595
  async closeThreadSession(threadId) {
596
+ const stagehand = this.threadManager.getExistingManagerForThread(threadId);
597
+ if (stagehand) this.rememberClosedBrowserState(stagehand, "agent", threadId);
590
598
  await super.closeThreadSession(threadId);
591
599
  this.patchExitType();
592
600
  }
601
+ browserStateKey(threadId) {
602
+ return threadId ?? this.getCurrentThread() ?? DEFAULT_THREAD_ID;
603
+ }
604
+ markBrowserCloseReason(reason, threadId) {
605
+ this.pendingCloseReasons.set(this.browserStateKey(threadId), reason);
606
+ }
607
+ getCloseReason(threadId) {
608
+ return this.pendingCloseReasons.get(this.browserStateKey(threadId)) ?? this.pendingCloseReasons.get(DEFAULT_THREAD_ID);
609
+ }
610
+ rememberClosedBrowserState(stagehand, reason, threadId) {
611
+ const state = this.getBrowserStateFromStagehand(stagehand, threadId);
612
+ if (!state || state.tabs.length === 0) return;
613
+ const closedState = {
614
+ ...state,
615
+ closeReason: this.getCloseReason(threadId) ?? reason
616
+ };
617
+ if (threadId) this.threadManager.updateBrowserState(threadId, closedState);
618
+ else this.lastBrowserState = closedState;
619
+ }
593
620
  patchExitType() {
594
621
  if (!this.config.profile) return;
595
622
  patchProfileExitType(this.config.profile, this.logger);
@@ -946,9 +973,9 @@ var StagehandBrowser = class extends MastraBrowser {
946
973
  if (scope === "thread" && effectiveThreadId) {
947
974
  const stagehand = this.threadManager.getExistingManagerForThread(effectiveThreadId);
948
975
  if (!stagehand) return null;
949
- return this.getBrowserStateFromStagehand(stagehand);
976
+ return this.getBrowserStateFromStagehand(stagehand, effectiveThreadId);
950
977
  }
951
- return this.getBrowserStateFromStagehand(this.sharedManager);
978
+ return this.getBrowserStateFromStagehand(this.sharedManager, effectiveThreadId);
952
979
  } catch {
953
980
  return null;
954
981
  }
@@ -960,23 +987,26 @@ var StagehandBrowser = class extends MastraBrowser {
960
987
  getBrowserStateForThread(threadId) {
961
988
  const effectiveThreadId = threadId ?? this.getCurrentThread() ?? DEFAULT_THREAD_ID;
962
989
  const stagehand = this.threadManager.getExistingManagerForThread(effectiveThreadId);
963
- return this.getBrowserStateFromStagehand(stagehand);
990
+ return this.getBrowserStateFromStagehand(stagehand, effectiveThreadId);
964
991
  }
965
992
  /**
966
993
  * Get browser state from a specific Stagehand instance.
967
994
  */
968
- getBrowserStateFromStagehand(stagehand) {
995
+ getBrowserStateFromStagehand(stagehand, threadId) {
969
996
  if (!stagehand?.context) return null;
970
997
  try {
971
998
  const pages = stagehand.context.pages();
972
999
  const activePage = stagehand.context.activePage();
973
1000
  let activeIndex = 0;
1001
+ const tabs = pages.map((page, index) => {
1002
+ if (page === activePage) activeIndex = index;
1003
+ return { url: page.url() };
1004
+ });
1005
+ const closeReason = this.getCloseReason(threadId);
974
1006
  return {
975
- tabs: pages.map((page, index) => {
976
- if (page === activePage) activeIndex = index;
977
- return { url: page.url() };
978
- }),
979
- activeTabIndex: activeIndex
1007
+ tabs,
1008
+ activeTabIndex: activeIndex,
1009
+ ...closeReason ? { closeReason } : {}
980
1010
  };
981
1011
  } catch {
982
1012
  return null;