@mastra/agent-browser 0.2.2 → 0.3.0-alpha.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,38 @@
1
1
  # @mastra/agent-browser
2
2
 
3
+ ## 0.3.0-alpha.1
4
+
5
+ ### Minor Changes
6
+
7
+ - 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))
8
+
9
+ Usage example:
10
+
11
+ ```ts
12
+ await browser_click({ ref: '@e1', waitUntil: 'domcontentloaded', timeout: 5000 });
13
+ ```
14
+
15
+ Fixes #17397.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [[`19a8658`](https://github.com/mastra-ai/mastra/commit/19a86589c788ef48bb6c1b0612cc82a201857379), [`a659a77`](https://github.com/mastra-ai/mastra/commit/a659a779bdebe3a52a518c56d2260592d0240fe0), [`3332be9`](https://github.com/mastra-ai/mastra/commit/3332be9701ecd77aba840959d9a1d1ce7aef02d3)]:
20
+ - @mastra/core@1.38.0-alpha.6
21
+
22
+ ## 0.3.0-alpha.0
23
+
24
+ ### Minor Changes
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 [[`8ace89d`](https://github.com/mastra-ai/mastra/commit/8ace89df77f762e622d3b9f7f65ad7524350d050), [`fa63872`](https://github.com/mastra-ai/mastra/commit/fa6387280954e6b667bec5714b55ba082bc627ff), [`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), [`0f0d1ba`](https://github.com/mastra-ai/mastra/commit/0f0d1ba67bfcb2204e571401662f1eceefc03357), [`8c31bcd`](https://github.com/mastra-ai/mastra/commit/8c31bcdb00e597880d5939b1b7d7566fbe5dacae), [`95b14cd`](https://github.com/mastra-ai/mastra/commit/95b14cdd820e86d97ac05fe568424c513a252e31), [`aa36be2`](https://github.com/mastra-ai/mastra/commit/aa36be23aa513b7dc53cb8ca16b7fab8f20e43ad), [`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), [`47f71dc`](https://github.com/mastra-ai/mastra/commit/47f71dc6fbcbd12d71e21a979e676e20a02bd77d), [`50ceae2`](https://github.com/mastra-ai/mastra/commit/50ceae270878e2f8fb2b2c6c2faab09df0007c8a), [`8cdde58`](https://github.com/mastra-ai/mastra/commit/8cdde5875bbba6702d9df226f2b20232b8d75d6c), [`847ff1e`](https://github.com/mastra-ai/mastra/commit/847ff1e0d94368d94b2e173e4e0908e115568ef3), [`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), [`0f77241`](https://github.com/mastra-ai/mastra/commit/0f7724108806703799a8ba80ad0f09414afd5066), [`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), [`80c7737`](https://github.com/mastra-ai/mastra/commit/80c7737e32d7917b5f356957d67c169d01744fd3), [`3f1cf47`](https://github.com/mastra-ai/mastra/commit/3f1cf476f74c1e4cc2df908837e05853a5347e31)]:
34
+ - @mastra/core@1.38.0-alpha.3
35
+
3
36
  ## 0.2.2
4
37
 
5
38
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -141,7 +141,9 @@ var clickInputSchema = zod.z.object({
141
141
  ref: zod.z.string().describe("Element ref from snapshot (e.g., @e5)"),
142
142
  button: zod.z.enum(["left", "right", "middle"]).optional().describe("Mouse button (default: left)"),
143
143
  clickCount: zod.z.number().optional().describe("Number of clicks (default: 1, use 2 for double-click)"),
144
- modifiers: zod.z.array(zod.z.enum(["Alt", "Control", "Meta", "Shift"])).optional().describe("Modifier keys to hold")
144
+ modifiers: zod.z.array(zod.z.enum(["Alt", "Control", "Meta", "Shift"])).optional().describe("Modifier keys to hold"),
145
+ waitUntil: zod.z.enum(["load", "domcontentloaded", "networkidle"]).optional().describe("If the click triggers a navigation, wait for this page load state before returning"),
146
+ timeout: zod.z.number().nonnegative().optional().describe("Timeout in milliseconds for the click and optional waitUntil")
145
147
  });
146
148
  var typeInputSchema = zod.z.object({
147
149
  ref: zod.z.string().describe("Element ref from snapshot"),
@@ -151,13 +153,17 @@ var typeInputSchema = zod.z.object({
151
153
  });
152
154
  var pressInputSchema = zod.z.object({
153
155
  key: zod.z.string().describe("Key to press (e.g., Enter, Tab, Escape, Control+a)"),
154
- modifiers: zod.z.array(zod.z.enum(["Alt", "Control", "Meta", "Shift"])).optional().describe("Modifier keys to hold")
156
+ modifiers: zod.z.array(zod.z.enum(["Alt", "Control", "Meta", "Shift"])).optional().describe("Modifier keys to hold"),
157
+ waitUntil: zod.z.enum(["load", "domcontentloaded", "networkidle"]).optional().describe("If the key press triggers a navigation, wait for this page load state before returning"),
158
+ timeout: zod.z.number().nonnegative().optional().describe("Timeout in milliseconds for the optional waitUntil")
155
159
  });
156
160
  var selectInputSchema = zod.z.object({
157
161
  ref: zod.z.string().describe("Select element ref from snapshot"),
158
162
  value: zod.z.string().optional().describe("Option value to select"),
159
163
  label: zod.z.string().optional().describe("Option label to select"),
160
- index: zod.z.number().int().min(0).optional().describe("Option index to select (0-based)")
164
+ index: zod.z.number().int().min(0).optional().describe("Option index to select (0-based)"),
165
+ waitUntil: zod.z.enum(["load", "domcontentloaded", "networkidle"]).optional().describe("If the selection triggers a navigation, wait for this page load state before returning"),
166
+ timeout: zod.z.number().nonnegative().optional().describe("Timeout in milliseconds for the selection and optional waitUntil")
161
167
  }).superRefine((data, ctx) => {
162
168
  if (data.value === void 0 && data.label === void 0 && data.index === void 0) {
163
169
  ctx.addIssue({
@@ -293,7 +299,7 @@ function createBackTool(browser) {
293
299
  function createClickTool(browser) {
294
300
  return tools.createTool({
295
301
  id: BROWSER_TOOLS.CLICK,
296
- description: "Click an element using its ref from a snapshot. Use clickCount: 2 for double-click.",
302
+ description: "Click an element using its ref from a snapshot. Use clickCount: 2 for double-click. Pass waitUntil when the click triggers navigation so the page settles before the next snapshot.",
297
303
  inputSchema: clickInputSchema,
298
304
  execute: async (input, { agent }) => {
299
305
  const threadId = agent?.threadId;
@@ -390,7 +396,7 @@ function createHoverTool(browser) {
390
396
  function createPressTool(browser) {
391
397
  return tools.createTool({
392
398
  id: BROWSER_TOOLS.PRESS,
393
- description: "Press a keyboard key (e.g., Enter, Tab, Escape, Control+a).",
399
+ description: "Press a keyboard key (e.g., Enter, Tab, Escape, Control+a). Pass waitUntil when the keypress triggers navigation (e.g., Enter to submit a form) so the page settles before the next snapshot.",
394
400
  inputSchema: pressInputSchema,
395
401
  execute: async (input, { agent }) => {
396
402
  const threadId = agent?.threadId;
@@ -448,7 +454,7 @@ function createScrollTool(browser) {
448
454
  function createSelectTool(browser) {
449
455
  return tools.createTool({
450
456
  id: BROWSER_TOOLS.SELECT,
451
- description: "Select an option from a dropdown by value, label, or index.",
457
+ description: "Select an option from a dropdown by value, label, or index. Pass waitUntil when the selection triggers navigation so the page settles before the next snapshot.",
452
458
  inputSchema: selectInputSchema,
453
459
  execute: async (input, { agent }) => {
454
460
  const threadId = agent?.threadId;
@@ -576,7 +582,7 @@ var AgentBrowser = class extends browser.MastraBrowser {
576
582
  this.defaultTimeout = config.timeout;
577
583
  }
578
584
  const effectiveScope = config.cdpUrl ? config.scope ?? "shared" : config.scope ?? "thread";
579
- this.threadManager = new AgentBrowserThreadManager({
585
+ const threadManagerConfig = {
580
586
  scope: effectiveScope,
581
587
  browserConfig: { ...config, headless: this.headless },
582
588
  resolveCdpUrl: this.resolveCdpUrl.bind(this),
@@ -589,7 +595,9 @@ var AgentBrowser = class extends browser.MastraBrowser {
589
595
  onBrowserCreated: (manager, threadId) => {
590
596
  this.setupCloseListenerForThread(manager, threadId);
591
597
  }
592
- });
598
+ };
599
+ const createTm = config.createThreadManager ?? ((opts) => new AgentBrowserThreadManager(opts));
600
+ this.threadManager = createTm(threadManagerConfig);
593
601
  }
594
602
  // ---------------------------------------------------------------------------
595
603
  // Thread Scope (delegated to ThreadManager)
@@ -1089,12 +1097,15 @@ var AgentBrowser = class extends browser.MastraBrowser {
1089
1097
  "Take a new snapshot to see the current page state and get fresh refs."
1090
1098
  );
1091
1099
  }
1100
+ const timeout = input.timeout ?? this.defaultTimeout;
1101
+ const navigation = input.waitUntil ? page.waitForNavigation({ waitUntil: input.waitUntil, timeout }) : void 0;
1092
1102
  await locator.click({
1093
1103
  button: input.button ?? "left",
1094
1104
  clickCount: input.clickCount ?? 1,
1095
1105
  modifiers: input.modifiers,
1096
- timeout: this.defaultTimeout
1106
+ timeout
1097
1107
  });
1108
+ await navigation;
1098
1109
  return {
1099
1110
  success: true,
1100
1111
  url: page.url(),
@@ -1163,7 +1174,10 @@ var AgentBrowser = class extends browser.MastraBrowser {
1163
1174
  async press(input, threadId) {
1164
1175
  try {
1165
1176
  const page = await this.getPage(threadId);
1177
+ const timeout = input.timeout ?? this.defaultTimeout;
1178
+ const navigation = input.waitUntil ? page.waitForNavigation({ waitUntil: input.waitUntil, timeout }) : void 0;
1166
1179
  await page.keyboard.press(input.key);
1180
+ await navigation;
1167
1181
  return {
1168
1182
  success: true,
1169
1183
  url: page.url(),
@@ -1191,9 +1205,10 @@ var AgentBrowser = class extends browser.MastraBrowser {
1191
1205
  if (input.value) selectValue.value = input.value;
1192
1206
  if (input.label) selectValue.label = input.label;
1193
1207
  if (input.index !== void 0) selectValue.index = input.index;
1194
- const selected = await locator.selectOption(selectValue, {
1195
- timeout: this.defaultTimeout
1196
- });
1208
+ const timeout = input.timeout ?? this.defaultTimeout;
1209
+ const navigation = input.waitUntil ? page.waitForNavigation({ waitUntil: input.waitUntil, timeout }) : void 0;
1210
+ const selected = await locator.selectOption(selectValue, { timeout });
1211
+ await navigation;
1197
1212
  return {
1198
1213
  success: true,
1199
1214
  selected,
@@ -1687,6 +1702,7 @@ var AgentBrowser = class extends browser.MastraBrowser {
1687
1702
  };
1688
1703
 
1689
1704
  exports.AgentBrowser = AgentBrowser;
1705
+ exports.AgentBrowserThreadManager = AgentBrowserThreadManager;
1690
1706
  exports.BROWSER_TOOLS = BROWSER_TOOLS;
1691
1707
  exports.backInputSchema = backInputSchema;
1692
1708
  exports.browserSchemas = browserSchemas;