@stablyai/playwright-base 0.2.1 → 1.0.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.ts CHANGED
@@ -1,25 +1,89 @@
1
- import * as _stablyai_internal_playwright_test from '@stablyai/internal-playwright-test';
2
- import { Browser, BrowserContext, BrowserType, Locator, Page, MatcherReturnType } from '@stablyai/internal-playwright-test';
1
+ import * as _playwright_test from '@playwright/test';
2
+ import { BrowserContext, Page, Locator, MatcherReturnType, Browser, BrowserType } from '@playwright/test';
3
3
  import * as z4 from 'zod/v4/core';
4
4
 
5
+ type AnthropicModel = "anthropic/claude-sonnet-4-5-20250929";
6
+ type GeminiModel = "google/gemini-2.5-computer-use-preview-10-2025";
7
+ type Model = AnthropicModel | GeminiModel | (string & {});
8
+
9
+ /**
10
+ * Options for configuring agent behavior during execution.
11
+ */
12
+ type AgentActOptions = {
13
+ /**
14
+ * The page the agent will operate on.
15
+ */
16
+ page: Page;
17
+ /**
18
+ * Maximum number of thinking cycles the agent can perform.
19
+ * Each cycle includes observing the page, planning, and executing one or more actions.
20
+ * @default 30
21
+ */
22
+ maxCycles?: number;
23
+ /**
24
+ * AI model to use for agent reasoning.
25
+ * Different models may have different capabilities and performance characteristics.
26
+ */
27
+ model?: Model;
28
+ };
29
+ /**
30
+ * AI agent for automating browser interactions using natural language.
31
+ *
32
+ * The Agent can perform complex browser actions by interpreting natural language instructions.
33
+ * It observes the page state, makes decisions, and executes actions autonomously.
34
+ *
35
+ * Agents are created via {@link BrowserContext.newAgent} or {@link Browser.newAgent}.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const agent = context.newAgent();
40
+ * await agent.act('Fill out the login form and submit', { page });
41
+ * ```
42
+ */
43
+ declare class Agent {
44
+ readonly browserContext: BrowserContext;
45
+ constructor(browserContext: BrowserContext);
46
+ /**
47
+ * Instructs the agent to perform actions on the page using natural language.
48
+ *
49
+ * The agent will analyze the page, plan actions, and execute them autonomously.
50
+ * It can perform multiple actions such as clicking, typing, navigating, and verifying
51
+ * page state based on the provided instruction.
52
+ *
53
+ * @param prompt - Natural language instruction describing what the agent should do
54
+ * @param options - Configuration for the agent's behavior including the page to operate on
55
+ * @returns Promise that resolves with the result of the agent's actions
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * // Simple action
60
+ * await agent.act('Click the login button', { page });
61
+ *
62
+ * // Complex multi-step action
63
+ * await agent.act('Navigate to settings, enable notifications, and save changes', { page });
64
+ *
65
+ * // With custom options
66
+ * const result = await agent.act('Complete the checkout process', {
67
+ * page,
68
+ * maxCycles: 20,
69
+ * model: 'gpt-4'
70
+ * });
71
+ *
72
+ * if (result.success) {
73
+ * console.log('Agent completed the task successfully');
74
+ * }
75
+ * ```
76
+ */
77
+ act(prompt: string, options: AgentActOptions): Promise<{
78
+ success: boolean;
79
+ }>;
80
+ }
81
+
5
82
  type ExtractSchema = {
6
83
  safeParseAsync(data: unknown, params?: z4.ParseContext<z4.$ZodIssue>): Promise<z4.util.SafeParseResult<z4.output<any>>>;
7
84
  } & z4.$ZodType;
8
85
  type SchemaOutput<T extends ExtractSchema> = z4.output<T>;
9
86
 
10
- type LocatorDescribeOptions = {
11
- autoHeal?: boolean;
12
- };
13
- declare function augmentLocator<T extends Locator>(locator: T): T;
14
- declare function augmentPage<T extends Page>(page: T): T;
15
- declare function augmentBrowserContext<T extends BrowserContext>(context: T): T;
16
- declare function augmentBrowser<T extends Browser>(browser: T): T;
17
- declare function augmentBrowserType<TBrowser extends Browser>(browserType: BrowserType<TBrowser>): BrowserType<TBrowser>;
18
-
19
- type AnthropicModel = "anthropic/claude-sonnet-4-5-20250929";
20
- type GeminiModel = "google/gemini-2.5-computer-use-preview-10-2025";
21
- type Model = AnthropicModel | GeminiModel | string;
22
-
23
87
  type MatcherContext = {
24
88
  isNot: boolean;
25
89
  message?: () => string;
@@ -28,15 +92,21 @@ declare const stablyPlaywrightMatchers: {
28
92
  readonly toMatchScreenshotPrompt: (this: MatcherContext, received: Page | Locator, condition: string, options?: ScreenshotPromptOptions) => Promise<MatcherReturnType>;
29
93
  };
30
94
 
95
+ declare function augmentLocator<T extends Locator>(locator: T): T;
96
+ declare function augmentPage<T extends Page>(page: T): T;
97
+ declare function augmentBrowserContext<T extends BrowserContext>(context: T): T;
98
+ declare function augmentBrowser<T extends Browser>(browser: T): T;
99
+ declare function augmentBrowserType<TBrowser extends Browser>(browserType: BrowserType<TBrowser>): BrowserType<TBrowser>;
100
+
31
101
  declare function setApiKey(apiKey: string): void;
32
102
  declare function requireApiKey(): string;
33
103
 
34
- type ScreenshotPromptOptions = _stablyai_internal_playwright_test.PageAssertionsToHaveScreenshotOptions;
104
+ type ScreenshotPromptOptions = _playwright_test.PageAssertionsToHaveScreenshotOptions;
35
105
 
36
106
  type Expect<T = Page> = {
37
107
  toMatchScreenshotPrompt(condition: string, options?: ScreenshotPromptOptions): Promise<void>;
38
108
  };
39
- declare module "@stablyai/internal-playwright-test" {
109
+ declare module "@playwright/test" {
40
110
  interface Locator {
41
111
  /**
42
112
  * Extracts information from this locator using Stably AI.
@@ -63,7 +133,6 @@ declare module "@stablyai/internal-playwright-test" {
63
133
  extract<T extends ExtractSchema>(prompt: string, options: {
64
134
  schema: T;
65
135
  }): Promise<SchemaOutput<T>>;
66
- describe(description: string, options?: LocatorDescribeOptions): Locator;
67
136
  }
68
137
  interface Page {
69
138
  /**
@@ -93,23 +162,61 @@ declare module "@stablyai/internal-playwright-test" {
93
162
  }): Promise<SchemaOutput<T>>;
94
163
  }
95
164
  interface BrowserContext {
96
- agent(prompt: string, options: {
97
- page: Page;
98
- maxCycles?: number;
99
- model?: Model;
100
- }): Promise<{
101
- success: boolean;
102
- }>;
165
+ /**
166
+ * Creates a new AI agent instance for automating browser interactions.
167
+ *
168
+ * An agent can perform complex browser actions by interpreting natural language instructions.
169
+ * It observes the page, makes autonomous decisions, and executes actions like clicking,
170
+ * typing, navigating, and verifying page state.
171
+ *
172
+ * The agent operates within this browser context and can interact with all pages in the context.
173
+ * Use the returned agent's [agent.act(prompt, options)](#agent-act) method to give instructions.
174
+ * The page to operate on is specified when calling `act()`.
175
+ *
176
+ * **Usage**
177
+ *
178
+ * ```js
179
+ * const context = await browser.newContext();
180
+ * const page = await context.newPage();
181
+ * await page.goto('https://example.com');
182
+ *
183
+ * // Create an agent for this context
184
+ * const agent = context.newAgent();
185
+ *
186
+ * // Give the agent natural language instructions with the page to operate on
187
+ * await agent.act('Click the login button and enter credentials', { page });
188
+ * ```
189
+ */
190
+ newAgent(): Agent;
103
191
  }
104
192
  interface Browser {
105
- agent(prompt: string, options: {
106
- page: Page;
107
- maxCycles?: number;
108
- model?: Model;
109
- }): Promise<{
110
- success: boolean;
111
- }>;
193
+ /**
194
+ * Creates a new AI agent instance for automating browser interactions.
195
+ *
196
+ * An agent can perform complex browser actions by interpreting natural language instructions.
197
+ * It observes the page, makes autonomous decisions, and executes actions like clicking,
198
+ * typing, navigating, and verifying page state.
199
+ *
200
+ * The agent operates within a browser context and can interact with all pages in that context.
201
+ * Use the returned agent's [agent.act(prompt, options)](#agent-act) method to give instructions.
202
+ * The page to operate on is specified when calling `act()`.
203
+ *
204
+ * **Usage**
205
+ *
206
+ * ```js
207
+ * const browser = await chromium.launch();
208
+ * const page = await browser.newPage();
209
+ * await page.goto('https://example.com');
210
+ *
211
+ * // Create an agent
212
+ * const agent = browser.newAgent();
213
+ *
214
+ * // Give the agent natural language instructions with the page to operate on
215
+ * await agent.act('Fill out the registration form and submit', { page });
216
+ * ```
217
+ */
218
+ newAgent(): Agent;
112
219
  }
113
220
  }
114
221
 
115
- export { type Expect, type ExtractSchema, type LocatorDescribeOptions, type SchemaOutput, type ScreenshotPromptOptions, augmentBrowser, augmentBrowserContext, augmentBrowserType, augmentLocator, augmentPage, requireApiKey, setApiKey, stablyPlaywrightMatchers };
222
+ export { Agent, type Expect, type ExtractSchema, type SchemaOutput, type ScreenshotPromptOptions, augmentBrowser, augmentBrowserContext, augmentBrowserType, augmentLocator, augmentPage, requireApiKey, setApiKey, stablyPlaywrightMatchers };
package/dist/index.mjs CHANGED
@@ -6,7 +6,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
6
6
  });
7
7
 
8
8
  // src/expect.ts
9
- import { test } from "@stablyai/internal-playwright-test";
9
+ import { test } from "@playwright/test";
10
10
 
11
11
  // src/runtime.ts
12
12
  var configuredApiKey = process.env.STABLY_API_KEY;
@@ -34,11 +34,16 @@ var isObject = (value) => {
34
34
  // src/ai/metadata.ts
35
35
  var SDK_METADATA_HEADERS = {
36
36
  "X-Client-Name": "stably-playwright-sdk-js",
37
- "X-Client-Version": "0.2.1"
37
+ "X-Client-Version": "1.0.0-next.1"
38
38
  };
39
39
 
40
40
  // src/ai/verify-prompt.ts
41
- var PROMPT_ASSERTION_ENDPOINT = "https://api.stably.ai/internal/v1/assert";
41
+ var PROMPT_ASSERTION_PATH = "internal/v1/assert";
42
+ var STABLY_API_URL = process.env.STABLY_API_URL || "https://api.stably.ai";
43
+ var PROMPT_ASSERTION_ENDPOINT = new URL(
44
+ PROMPT_ASSERTION_PATH,
45
+ STABLY_API_URL
46
+ ).toString();
42
47
  var parseSuccessResponse = (value) => {
43
48
  if (!isObject(value)) {
44
49
  throw new Error("Verify prompt returned unexpected response shape");
@@ -413,7 +418,7 @@ var stablyPlaywrightMatchers = {
413
418
  };
414
419
 
415
420
  // src/playwright-augment/methods/agent.ts
416
- import { test as test2 } from "@stablyai/internal-playwright-test";
421
+ import { test as test2 } from "@playwright/test";
417
422
 
418
423
  // src/utils/truncate.ts
419
424
  var truncate = (inp, length) => inp.length <= length || inp.length <= 3 ? inp : `${inp.slice(0, length - 3)}...`;
@@ -621,16 +626,48 @@ ${ariaSnapshot}` }
621
626
 
622
627
  // src/playwright-augment/methods/agent.ts
623
628
  var AGENT_PATH = "internal/v3/agent";
624
- var STABLY_API_URL = process.env.STABLY_API_URL || "https://api.stably.ai";
625
- var AGENT_ENDPOINT = new URL(AGENT_PATH, STABLY_API_URL).toString();
626
- function createAgentStub() {
627
- let thoughtsIndex = 0;
628
- return async (prompt, options) => {
629
+ var STABLY_API_URL2 = process.env.STABLY_API_URL || "https://api.stably.ai";
630
+ var AGENT_ENDPOINT = new URL(AGENT_PATH, STABLY_API_URL2).toString();
631
+ var Agent = class {
632
+ constructor(browserContext) {
633
+ this.browserContext = browserContext;
634
+ }
635
+ /**
636
+ * Instructs the agent to perform actions on the page using natural language.
637
+ *
638
+ * The agent will analyze the page, plan actions, and execute them autonomously.
639
+ * It can perform multiple actions such as clicking, typing, navigating, and verifying
640
+ * page state based on the provided instruction.
641
+ *
642
+ * @param prompt - Natural language instruction describing what the agent should do
643
+ * @param options - Configuration for the agent's behavior including the page to operate on
644
+ * @returns Promise that resolves with the result of the agent's actions
645
+ *
646
+ * @example
647
+ * ```typescript
648
+ * // Simple action
649
+ * await agent.act('Click the login button', { page });
650
+ *
651
+ * // Complex multi-step action
652
+ * await agent.act('Navigate to settings, enable notifications, and save changes', { page });
653
+ *
654
+ * // With custom options
655
+ * const result = await agent.act('Complete the checkout process', {
656
+ * page,
657
+ * maxCycles: 20,
658
+ * model: 'gpt-4'
659
+ * });
660
+ *
661
+ * if (result.success) {
662
+ * console.log('Agent completed the task successfully');
663
+ * }
664
+ * ```
665
+ */
666
+ async act(prompt, options) {
629
667
  const apiKey = requireApiKey();
630
668
  const maxCycles = options.maxCycles ?? 30;
631
- const browserContext = options.page.context();
632
669
  const tabManager = /* @__PURE__ */ new Map();
633
- browserContext.pages().forEach((page, index) => {
670
+ this.browserContext.pages().forEach((page, index) => {
634
671
  tabManager.set(page, `page${index + 1}`);
635
672
  });
636
673
  let activePage = options.page;
@@ -653,14 +690,14 @@ function createAgentStub() {
653
690
  const alias = tabManager.get(page);
654
691
  newPageOpenedMsg = `opened new tab ${alias} (${page.url()})`;
655
692
  };
656
- browserContext.on("page", onNewPage);
693
+ this.browserContext.on("page", onNewPage);
657
694
  return await test2.step(`[Agent] ${prompt}`, async () => {
658
695
  try {
659
696
  for (let i = 0; i < maxCycles; i++) {
660
697
  if (agentMessage.shouldTerminate) {
661
698
  break;
662
699
  }
663
- const agentResponses = await test2.step(`[Thinking ${thoughtsIndex + 1}]`, async (stepInfo) => {
700
+ const agentResponses = await test2.step(`[Thinking ${i + 1}]`, async (stepInfo) => {
664
701
  const screenshot = await takeStableScreenshot(activePage);
665
702
  const response = await fetch(AGENT_ENDPOINT, {
666
703
  body: constructAgentPayload({
@@ -690,13 +727,12 @@ function createAgentStub() {
690
727
  const reasoningText = reasoningTexts.join("\n\n");
691
728
  const truncatedReasoningText = truncate(reasoningText, 120);
692
729
  await stepInfo.attach(
693
- `[Thinking ${thoughtsIndex + 1}] ${truncatedReasoningText}`,
730
+ `[Thinking ${i + 1}] ${truncatedReasoningText}`,
694
731
  {
695
732
  body: reasoningText,
696
733
  contentType: "text/plain"
697
734
  }
698
735
  );
699
- thoughtsIndex++;
700
736
  return responseJson;
701
737
  });
702
738
  let combinedMessages = [];
@@ -710,7 +746,7 @@ function createAgentStub() {
710
746
  } = await execResponse({
711
747
  activePage,
712
748
  agentResponse,
713
- browserContext,
749
+ browserContext: this.browserContext,
714
750
  tabManager
715
751
  });
716
752
  activePage = newActivePage;
@@ -731,17 +767,19 @@ function createAgentStub() {
731
767
  };
732
768
  }
733
769
  } finally {
734
- browserContext.off("page", onNewPage);
770
+ this.browserContext.off("page", onNewPage);
735
771
  }
736
772
  return { success: finalSuccess ?? false };
737
773
  });
738
- };
739
- }
774
+ }
775
+ };
776
+ var createNewAgent = (browserContext) => new Agent(browserContext);
740
777
 
741
778
  // src/ai/extract.ts
779
+ import { test as test3 } from "@playwright/test";
742
780
  var EXTRACT_PATH = "internal/v2/extract";
743
- var STABLY_API_URL2 = process.env.STABLY_API_URL || "https://api.stably.ai";
744
- var EXTRACT_ENDPOINT = new URL(EXTRACT_PATH, STABLY_API_URL2).toString();
781
+ var STABLY_API_URL3 = process.env.STABLY_API_URL || "https://api.stably.ai";
782
+ var EXTRACT_ENDPOINT = new URL(EXTRACT_PATH, STABLY_API_URL3).toString();
745
783
  var zodV4 = (() => {
746
784
  try {
747
785
  return __require("zod/v4/core");
@@ -771,7 +809,10 @@ var ExtractValidationError = class extends Error {
771
809
  async function validateWithSchema(schema, value) {
772
810
  const result = await schema.safeParseAsync(value);
773
811
  if (!result.success) {
774
- throw new ExtractValidationError("Validation failed", result.error.issues);
812
+ throw new ExtractValidationError(
813
+ "AI is unable to return the data in the desired format",
814
+ result.error.issues
815
+ );
775
816
  }
776
817
  return result.data;
777
818
  }
@@ -789,36 +830,47 @@ async function extract({
789
830
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
790
831
  schema
791
832
  ) : void 0;
792
- const apiKey = requireApiKey();
793
- const form = new FormData();
794
- form.append("prompt", prompt);
795
- if (jsonSchema) {
796
- form.append("jsonSchema", JSON.stringify(jsonSchema));
797
- }
798
- const pngBuffer = await pageOrLocator.screenshot({ type: "png" });
799
- const u8 = Uint8Array.from(pngBuffer);
800
- const blob = new Blob([u8], { type: "image/png" });
801
- form.append("image", blob, "screenshot.png");
802
- const response = await fetch(EXTRACT_ENDPOINT, {
803
- body: form,
804
- headers: {
805
- ...SDK_METADATA_HEADERS,
806
- Authorization: `Bearer ${apiKey}`
807
- },
808
- method: "POST"
809
- });
810
- const raw = await response.json().catch(() => void 0);
811
- if (response.ok) {
812
- if (!isExtractionResponse(raw)) {
813
- throw new Error("Extract returned unexpected response shape");
833
+ return await test3.step(`[Extract] ${prompt}`, async (stepInfo) => {
834
+ const apiKey = requireApiKey();
835
+ const form = new FormData();
836
+ form.append("prompt", prompt);
837
+ if (jsonSchema) {
838
+ form.append("jsonSchema", JSON.stringify(jsonSchema));
814
839
  }
815
- if (!raw.success) {
816
- throw new Error(`Extract failed: ${raw.error}`);
840
+ const pngBuffer = await pageOrLocator.screenshot({ type: "png" });
841
+ const u8 = Uint8Array.from(pngBuffer);
842
+ const blob = new Blob([u8], { type: "image/png" });
843
+ form.append("image", blob, "screenshot.png");
844
+ const response = await fetch(EXTRACT_ENDPOINT, {
845
+ body: form,
846
+ headers: {
847
+ ...SDK_METADATA_HEADERS,
848
+ Authorization: `Bearer ${apiKey}`
849
+ },
850
+ method: "POST"
851
+ });
852
+ const raw = await response.json().catch(() => void 0);
853
+ if (response.ok) {
854
+ if (!isExtractionResponse(raw)) {
855
+ throw new Error("Extract returned unexpected response shape");
856
+ }
857
+ if (!raw.success) {
858
+ await stepInfo.attach("[Extract] error", {
859
+ body: raw.error,
860
+ contentType: "text/plain"
861
+ });
862
+ throw new Error(`Extract failed: ${raw.error}`);
863
+ }
864
+ const { value } = raw;
865
+ const body = typeof value === "string" ? value : JSON.stringify(value, null, 2);
866
+ await stepInfo.attach("[Extract] result", {
867
+ body,
868
+ contentType: "text/plain"
869
+ });
870
+ return schema ? await validateWithSchema(schema, value) : typeof value === "string" ? value : JSON.stringify(value);
817
871
  }
818
- const { value } = raw;
819
- return schema ? await validateWithSchema(schema, value) : typeof value === "string" ? value : JSON.stringify(value);
820
- }
821
- throw new Error(isErrorResponse(raw) ? raw.error : "Extract failed");
872
+ throw new Error(isErrorResponse(raw) ? raw.error : "Extract failed");
873
+ });
822
874
  }
823
875
 
824
876
  // src/playwright-augment/methods/extract.ts
@@ -840,9 +892,6 @@ var createPageExtract = (page) => createExtract(page);
840
892
 
841
893
  // src/playwright-augment/augment.ts
842
894
  var LOCATOR_PATCHED = Symbol.for("stably.playwright.locatorPatched");
843
- var LOCATOR_DESCRIBE_WRAPPED = Symbol.for(
844
- "stably.playwright.locatorDescribeWrapped"
845
- );
846
895
  var PAGE_PATCHED = Symbol.for("stably.playwright.pagePatched");
847
896
  var CONTEXT_PATCHED = Symbol.for("stably.playwright.contextPatched");
848
897
  var BROWSER_PATCHED = Symbol.for("stably.playwright.browserPatched");
@@ -860,15 +909,6 @@ function augmentLocator(locator) {
860
909
  return locator;
861
910
  }
862
911
  defineHiddenProperty(locator, "extract", createLocatorExtract(locator));
863
- const markerTarget = locator;
864
- if (typeof locator.describe === "function" && !markerTarget[LOCATOR_DESCRIBE_WRAPPED]) {
865
- const originalDescribe = locator.describe.bind(locator);
866
- locator.describe = (description, options) => {
867
- const result = originalDescribe(description, options);
868
- return result ? augmentLocator(result) : result;
869
- };
870
- defineHiddenProperty(locator, LOCATOR_DESCRIBE_WRAPPED, true);
871
- }
872
912
  defineHiddenProperty(locator, LOCATOR_PATCHED, true);
873
913
  return locator;
874
914
  }
@@ -896,13 +936,12 @@ function augmentBrowserContext(context) {
896
936
  };
897
937
  const originalPages = context.pages?.bind(context);
898
938
  if (originalPages) {
899
- context.pages = () => originalPages().map(
900
- (page) => augmentPage(page)
901
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
902
- );
939
+ context.pages = () => originalPages().map((page) => augmentPage(page));
903
940
  }
904
- if (!context.agent) {
905
- defineHiddenProperty(context, "agent", createAgentStub());
941
+ if (!context.newAgent) {
942
+ defineHiddenProperty(context, "newAgent", () => {
943
+ return createNewAgent(context);
944
+ });
906
945
  }
907
946
  defineHiddenProperty(context, CONTEXT_PATCHED, true);
908
947
  return context;
@@ -924,10 +963,13 @@ function augmentBrowser(browser) {
924
963
  const originalContexts = browser.contexts.bind(browser);
925
964
  browser.contexts = () => originalContexts().map(
926
965
  (context) => augmentBrowserContext(context)
927
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
928
966
  );
929
- if (!browser.agent) {
930
- defineHiddenProperty(browser, "agent", createAgentStub());
967
+ if (!browser.newAgent) {
968
+ defineHiddenProperty(browser, "newAgent", () => {
969
+ const contexts = browser.contexts();
970
+ const context = contexts.length > 0 ? contexts[0] : browser.contexts()[0];
971
+ return createNewAgent(context);
972
+ });
931
973
  }
932
974
  defineHiddenProperty(browser, BROWSER_PATCHED, true);
933
975
  return browser;
@@ -957,10 +999,7 @@ function augmentBrowserType(browserType) {
957
999
  return augmentBrowser(browser);
958
1000
  };
959
1001
  }
960
- const originalLaunchPersistentContext = (
961
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
962
- browserType.launchPersistentContext?.bind(browserType)
963
- );
1002
+ const originalLaunchPersistentContext = browserType.launchPersistentContext?.bind(browserType);
964
1003
  if (originalLaunchPersistentContext) {
965
1004
  browserType.launchPersistentContext = async (...args) => {
966
1005
  const context = await originalLaunchPersistentContext(...args);
@@ -971,6 +1010,7 @@ function augmentBrowserType(browserType) {
971
1010
  return browserType;
972
1011
  }
973
1012
  export {
1013
+ Agent,
974
1014
  augmentBrowser,
975
1015
  augmentBrowserContext,
976
1016
  augmentBrowserType,