@mastra/agent-browser 0.3.0-alpha.1 → 0.3.1-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/CHANGELOG.md +33 -0
- package/dist/index.cjs +67 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +67 -8
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @mastra/agent-browser
|
|
2
2
|
|
|
3
|
+
## 0.3.1-alpha.0
|
|
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 [[`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)]:
|
|
10
|
+
- @mastra/core@1.42.0-alpha.1
|
|
11
|
+
|
|
12
|
+
## 0.3.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- Add `waitUntil` support to `browser_click`, `browser_press`, and `browser_select`. When provided, the tool waits for the page to reach the given load state (`load`, `domcontentloaded`, or `networkidle`) after the action completes, preventing the next `browser_snapshot` from capturing stale DOM when the interaction triggers navigation. The parameter is optional and behaviour is unchanged when omitted. ([#17426](https://github.com/mastra-ai/mastra/pull/17426))
|
|
17
|
+
|
|
18
|
+
Usage example:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
await browser_click({ ref: '@e1', waitUntil: 'domcontentloaded', timeout: 5000 });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Fixes #17397.
|
|
25
|
+
|
|
26
|
+
- Added extensibility hooks for custom browser providers (e.g. Firecrawl Browser Sandbox). ([#15724](https://github.com/mastra-ai/mastra/pull/15724))
|
|
27
|
+
- New `createThreadManager` config option to inject a custom thread manager factory
|
|
28
|
+
- Exported `AgentBrowserThreadManager` class and related types (`AgentBrowserSession`, `AgentBrowserThreadManagerConfig`, `CreateAgentBrowserThreadManager`)
|
|
29
|
+
- Changed several internal members from `private` to `protected` to support subclassing
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- Updated dependencies [[`fa63872`](https://github.com/mastra-ai/mastra/commit/fa6387280954e6b667bec5714b55ba082bc627ff), [`d779de3`](https://github.com/mastra-ai/mastra/commit/d779de3cd9d2e7ed8110547190e2f15e786a0e41), [`1750c97`](https://github.com/mastra-ai/mastra/commit/1750c975d6179fbf6db2813b15229d4f8f23fc55), [`9283971`](https://github.com/mastra-ai/mastra/commit/928397157009b4aef4d5fdf3a0a273cb371beb55), [`f07b646`](https://github.com/mastra-ai/mastra/commit/f07b64604ab7d25391179790b7fd4823df9e2dff), [`d8838ae`](https://github.com/mastra-ai/mastra/commit/d8838ae80b69780361693d27098f7f6684af12fe), [`40f9297`](https://github.com/mastra-ai/mastra/commit/40f9297003b921c62373d3e8d3a4bda76c9f6de3), [`19a8658`](https://github.com/mastra-ai/mastra/commit/19a86589c788ef48bb6c1b0612cc82a201857379), [`850af77`](https://github.com/mastra-ai/mastra/commit/850af7779cb87c350804488734544a5b1843de25), [`0f0d1ba`](https://github.com/mastra-ai/mastra/commit/0f0d1ba67bfcb2204e571401662f1eceefc03357), [`a18775a`](https://github.com/mastra-ai/mastra/commit/a18775a693172546ee2378d39b67d4e32895b251), [`1baf2d1`](https://github.com/mastra-ai/mastra/commit/1baf2d152c6881338ff8f114633d5316fe13dd15), [`8c31bcd`](https://github.com/mastra-ai/mastra/commit/8c31bcdb00e597880d5939b1b7d7566fbe5dacae), [`0e32507`](https://github.com/mastra-ai/mastra/commit/0e32507962cdfa5569b7bda5bc6fb3dd34e40b03), [`95b14cd`](https://github.com/mastra-ai/mastra/commit/95b14cdd820e86d97ac05fe568424c513a252e31), [`07c3de7`](https://github.com/mastra-ai/mastra/commit/07c3de7f7bc418beccaea3b5e6b7f7cdda79d492), [`0bf2d93`](https://github.com/mastra-ai/mastra/commit/0bf2d932d20e2936f2d9abb8c0a86e24fbc97ec6), [`7b0d34c`](https://github.com/mastra-ai/mastra/commit/7b0d34cfe4a2fce22ac86ae17404685ff67a2ddb), [`a659a77`](https://github.com/mastra-ai/mastra/commit/a659a779bdebe3a52a518c56d2260592d0240fe0), [`aa36be2`](https://github.com/mastra-ai/mastra/commit/aa36be23aa513b7dc53cb8ca16b7fab8f20e43ad), [`3332be9`](https://github.com/mastra-ai/mastra/commit/3332be9701ecd77aba840959d9a1d1ce7aef02d3), [`212c635`](https://github.com/mastra-ai/mastra/commit/212c635203e61d036ab41db8ff86c3893dc795b3), [`d8838ae`](https://github.com/mastra-ai/mastra/commit/d8838ae80b69780361693d27098f7f6684af12fe), [`9aa5a73`](https://github.com/mastra-ai/mastra/commit/9aa5a73e7e110f6e9365eec69364a33d5f03bb56), [`f73c789`](https://github.com/mastra-ai/mastra/commit/f73c789e8ef21561580395d2c410119cab5848c8), [`8bd16da`](https://github.com/mastra-ai/mastra/commit/8bd16da73a4cb874d739373643dbd6a6e7f88684), [`c8630f8`](https://github.com/mastra-ai/mastra/commit/c8630f80d4f40cb5d22e60ab162b618b1907167a), [`94dfef6`](https://github.com/mastra-ai/mastra/commit/94dfef6e2bf19a88467ea3940afcbce88a433f0f), [`47f71dc`](https://github.com/mastra-ai/mastra/commit/47f71dc6fbcbd12d71e21a979e676e20a02bd77d), [`50ceae2`](https://github.com/mastra-ai/mastra/commit/50ceae270878e2f8fb2b2c6c2faab09df0007c8a), [`a122f79`](https://github.com/mastra-ai/mastra/commit/a122f79427ae225ec79c7b2ed46278da48d04b17), [`8cdde58`](https://github.com/mastra-ai/mastra/commit/8cdde5875bbba6702d9df226f2b20232b8d75d6c), [`3a081c1`](https://github.com/mastra-ai/mastra/commit/3a081c1255c5ae8c99f6dad91cc612934ef6f2bd), [`49f8abc`](https://github.com/mastra-ai/mastra/commit/49f8abce8258e4f2f87bd326acfbdb641264a47c), [`847ff1e`](https://github.com/mastra-ai/mastra/commit/847ff1e0d94368d94b2e173e4e0908e115568ef3), [`0c1ed1d`](https://github.com/mastra-ai/mastra/commit/0c1ed1d00c7d87b5ac99ca95896211a2fa9189fa), [`259d409`](https://github.com/mastra-ai/mastra/commit/259d409a514174299dbde1ff5e1121209b3ba850), [`9e16c68`](https://github.com/mastra-ai/mastra/commit/9e16c6818b6485ccb43df28aba6f3a2219d28662), [`cefca33`](https://github.com/mastra-ai/mastra/commit/cefca33ae666e69810c935fedf95a929c173d1d7), [`d00e8c5`](https://github.com/mastra-ai/mastra/commit/d00e8c50daebe5bce5bf2f48bde39c86fc3d2fe4), [`36fa7e2`](https://github.com/mastra-ai/mastra/commit/36fa7e24d14e58a1eb46147097b32f583e5b8775), [`87e9774`](https://github.com/mastra-ai/mastra/commit/87e97741c1e493cd6d62f478eb810b49bda4d57c), [`65a72e7`](https://github.com/mastra-ai/mastra/commit/65a72e70c25eedea8ff985a6624b96be2850236b), [`fe9eacd`](https://github.com/mastra-ai/mastra/commit/fe9eacd9545a0a9d64aad31c9fa90294a425289e), [`4c02027`](https://github.com/mastra-ai/mastra/commit/4c020277235eaa6b1dc957c90ad0639eef213992), [`0f77241`](https://github.com/mastra-ai/mastra/commit/0f7724108806703799a8ba80ad0f09414afd5066), [`849efb9`](https://github.com/mastra-ai/mastra/commit/849efb9fca6dc976589c1f90a303fea618769109), [`92ff509`](https://github.com/mastra-ai/mastra/commit/92ff5098ef8a990438ca038077021a5f7541ec1d), [`3fce5e7`](https://github.com/mastra-ai/mastra/commit/3fce5e70d011d289043e75003ef3336ed4aa43c3), [`a763592`](https://github.com/mastra-ai/mastra/commit/a763592c3db46963ef1011cfe16fe372816e775e), [`db79c86`](https://github.com/mastra-ai/mastra/commit/db79c86c60723d57e02f9636ca2611bd4515f194), [`6855012`](https://github.com/mastra-ai/mastra/commit/685501247cc4717506f3e89beed03509d63a5370), [`80c7737`](https://github.com/mastra-ai/mastra/commit/80c7737e32d7917b5f356957d67c169d01744fd3), [`7fef31c`](https://github.com/mastra-ai/mastra/commit/7fef31c0d2a6d362a43a647a8a4f6ab893758a23), [`7fef31c`](https://github.com/mastra-ai/mastra/commit/7fef31c0d2a6d362a43a647a8a4f6ab893758a23), [`3f1cf47`](https://github.com/mastra-ai/mastra/commit/3f1cf476f74c1e4cc2df908837e05853a5347e31)]:
|
|
34
|
+
- @mastra/core@1.38.0
|
|
35
|
+
|
|
3
36
|
## 0.3.0-alpha.1
|
|
4
37
|
|
|
5
38
|
### 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
|
-
|
|
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
|
|
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
|
|
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()) {
|