browser-use 0.4.0 → 0.6.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.
Files changed (58) hide show
  1. package/dist/agent/service.js +2 -0
  2. package/dist/agent/system_prompt.md +269 -0
  3. package/dist/agent/system_prompt_anthropic_flash.md +240 -0
  4. package/dist/agent/system_prompt_browser_use.md +18 -0
  5. package/dist/agent/system_prompt_browser_use_flash.md +15 -0
  6. package/dist/agent/system_prompt_browser_use_no_thinking.md +17 -0
  7. package/dist/agent/system_prompt_flash.md +16 -0
  8. package/dist/agent/system_prompt_flash_anthropic.md +30 -0
  9. package/dist/agent/system_prompt_no_thinking.md +245 -0
  10. package/dist/browser/cloud/index.d.ts +1 -0
  11. package/dist/browser/cloud/index.js +1 -0
  12. package/dist/browser/cloud/management.d.ts +130 -0
  13. package/dist/browser/cloud/management.js +140 -0
  14. package/dist/browser/events.d.ts +61 -3
  15. package/dist/browser/events.js +66 -0
  16. package/dist/browser/profile.d.ts +1 -0
  17. package/dist/browser/profile.js +25 -8
  18. package/dist/browser/session.d.ts +59 -2
  19. package/dist/browser/session.js +943 -131
  20. package/dist/browser/watchdogs/base.js +34 -1
  21. package/dist/browser/watchdogs/captcha-watchdog.d.ts +26 -0
  22. package/dist/browser/watchdogs/captcha-watchdog.js +151 -0
  23. package/dist/browser/watchdogs/index.d.ts +1 -0
  24. package/dist/browser/watchdogs/index.js +1 -0
  25. package/dist/browser/watchdogs/screenshot-watchdog.js +4 -3
  26. package/dist/cli.d.ts +120 -0
  27. package/dist/cli.js +1816 -4
  28. package/dist/controller/service.js +106 -362
  29. package/dist/controller/views.d.ts +9 -6
  30. package/dist/controller/views.js +8 -5
  31. package/dist/dom/dom_tree/index.js +24 -11
  32. package/dist/filesystem/file-system.js +1 -1
  33. package/dist/llm/litellm/chat.d.ts +11 -0
  34. package/dist/llm/litellm/chat.js +16 -0
  35. package/dist/llm/litellm/index.d.ts +1 -0
  36. package/dist/llm/litellm/index.js +1 -0
  37. package/dist/llm/models.js +29 -3
  38. package/dist/llm/oci-raw/chat.d.ts +64 -0
  39. package/dist/llm/oci-raw/chat.js +350 -0
  40. package/dist/llm/oci-raw/index.d.ts +2 -0
  41. package/dist/llm/oci-raw/index.js +2 -0
  42. package/dist/llm/oci-raw/serializer.d.ts +12 -0
  43. package/dist/llm/oci-raw/serializer.js +128 -0
  44. package/dist/mcp/server.d.ts +1 -0
  45. package/dist/mcp/server.js +62 -13
  46. package/dist/skill-cli/direct.d.ts +100 -0
  47. package/dist/skill-cli/direct.js +984 -0
  48. package/dist/skill-cli/index.d.ts +2 -0
  49. package/dist/skill-cli/index.js +2 -0
  50. package/dist/skill-cli/server.d.ts +2 -0
  51. package/dist/skill-cli/server.js +472 -11
  52. package/dist/skill-cli/tunnel.d.ts +61 -0
  53. package/dist/skill-cli/tunnel.js +257 -0
  54. package/dist/sync/auth.d.ts +8 -0
  55. package/dist/sync/auth.js +12 -0
  56. package/dist/utils.d.ts +1 -1
  57. package/dist/utils.js +2 -1
  58. package/package.json +22 -4
@@ -276,6 +276,34 @@ export class BrowserConnectedEvent extends BrowserEvent {
276
276
  this.cdp_url = init.cdp_url;
277
277
  }
278
278
  }
279
+ export class BrowserReconnectingEvent extends BrowserEvent {
280
+ cdp_url;
281
+ attempt;
282
+ max_attempts;
283
+ constructor(init) {
284
+ super('BrowserReconnectingEvent', {
285
+ ...init,
286
+ event_timeout: resolveEventTimeout('BrowserReconnectingEvent', 30, init.event_timeout),
287
+ });
288
+ this.cdp_url = init.cdp_url;
289
+ this.attempt = init.attempt;
290
+ this.max_attempts = init.max_attempts;
291
+ }
292
+ }
293
+ export class BrowserReconnectedEvent extends BrowserEvent {
294
+ cdp_url;
295
+ attempt;
296
+ downtime_seconds;
297
+ constructor(init) {
298
+ super('BrowserReconnectedEvent', {
299
+ ...init,
300
+ event_timeout: resolveEventTimeout('BrowserReconnectedEvent', 30, init.event_timeout),
301
+ });
302
+ this.cdp_url = init.cdp_url;
303
+ this.attempt = init.attempt;
304
+ this.downtime_seconds = init.downtime_seconds;
305
+ }
306
+ }
279
307
  export class BrowserStoppedEvent extends BrowserEvent {
280
308
  reason;
281
309
  constructor(init = {}) {
@@ -286,6 +314,42 @@ export class BrowserStoppedEvent extends BrowserEvent {
286
314
  this.reason = init.reason ?? null;
287
315
  }
288
316
  }
317
+ export class CaptchaSolverStartedEvent extends BrowserEvent {
318
+ target_id;
319
+ vendor;
320
+ url;
321
+ started_at;
322
+ constructor(init) {
323
+ super('CaptchaSolverStartedEvent', {
324
+ ...init,
325
+ event_timeout: resolveEventTimeout('CaptchaSolverStartedEvent', 5, init.event_timeout),
326
+ });
327
+ this.target_id = init.target_id;
328
+ this.vendor = init.vendor;
329
+ this.url = init.url;
330
+ this.started_at = init.started_at;
331
+ }
332
+ }
333
+ export class CaptchaSolverFinishedEvent extends BrowserEvent {
334
+ target_id;
335
+ vendor;
336
+ url;
337
+ duration_ms;
338
+ finished_at;
339
+ success;
340
+ constructor(init) {
341
+ super('CaptchaSolverFinishedEvent', {
342
+ ...init,
343
+ event_timeout: resolveEventTimeout('CaptchaSolverFinishedEvent', 5, init.event_timeout),
344
+ });
345
+ this.target_id = init.target_id;
346
+ this.vendor = init.vendor;
347
+ this.url = init.url;
348
+ this.duration_ms = init.duration_ms;
349
+ this.finished_at = init.finished_at;
350
+ this.success = init.success;
351
+ }
352
+ }
289
353
  export class TabCreatedEvent extends BrowserEvent {
290
354
  target_id;
291
355
  url;
@@ -529,6 +593,8 @@ export const BROWSER_EVENT_CLASSES = [
529
593
  BrowserLaunchEvent,
530
594
  BrowserKillEvent,
531
595
  BrowserConnectedEvent,
596
+ BrowserReconnectingEvent,
597
+ BrowserReconnectedEvent,
532
598
  BrowserStoppedEvent,
533
599
  TabCreatedEvent,
534
600
  TabClosedEvent,
@@ -137,6 +137,7 @@ export interface BrowserProfileSpecificOptions {
137
137
  block_ip_addresses: boolean;
138
138
  keep_alive: Nullable<boolean>;
139
139
  enable_default_extensions: boolean;
140
+ captcha_solver: boolean;
140
141
  window_size: Nullable<ViewportSize>;
141
142
  window_height: Nullable<number>;
142
143
  window_width: Nullable<number>;
@@ -344,6 +344,7 @@ const DEFAULT_BROWSER_PROFILE_OPTIONS = {
344
344
  block_ip_addresses: false,
345
345
  keep_alive: null,
346
346
  enable_default_extensions: getEnableDefaultExtensionsDefault(),
347
+ captcha_solver: true,
347
348
  window_size: null,
348
349
  window_height: null,
349
350
  window_width: null,
@@ -360,10 +361,17 @@ const DEFAULT_BROWSER_PROFILE_OPTIONS = {
360
361
  profile_directory: 'Default',
361
362
  cookies_file: null,
362
363
  };
364
+ const splitArgOnce = (arg) => {
365
+ const separatorIndex = arg.indexOf('=');
366
+ if (separatorIndex === -1) {
367
+ return [arg, ''];
368
+ }
369
+ return [arg.slice(0, separatorIndex), arg.slice(separatorIndex + 1)];
370
+ };
363
371
  const argsAsDict = (args) => {
364
372
  const result = {};
365
373
  for (const arg of args) {
366
- const [keyPart, valuePart = ''] = arg.split('=', 1);
374
+ const [keyPart, valuePart = ''] = splitArgOnce(arg);
367
375
  const key = keyPart.trim().replace(/^-+/, '');
368
376
  result[key] = valuePart.trim();
369
377
  }
@@ -376,9 +384,22 @@ const cloneDefaultOptions = () => JSON.parse(JSON.stringify(DEFAULT_BROWSER_PROF
376
384
  const normalizeDomainEntry = (entry) => String(entry ?? '')
377
385
  .trim()
378
386
  .toLowerCase();
387
+ const isExactHostDomainEntry = (entry) => {
388
+ if (!entry) {
389
+ return false;
390
+ }
391
+ if (entry.includes('*') || entry.includes('://') || entry.includes('/')) {
392
+ return false;
393
+ }
394
+ // Keep set optimization for plain hostnames only. Entries with ports/pattern-like
395
+ // delimiters must stay as arrays to preserve wildcard/scheme matching semantics.
396
+ return !entry.includes(':');
397
+ };
379
398
  const optimizeDomainList = (value) => {
380
399
  const cleaned = value.map(normalizeDomainEntry).filter(Boolean);
381
- if (cleaned.length >= DOMAIN_OPTIMIZATION_THRESHOLD) {
400
+ const canOptimizeToSet = cleaned.length >= DOMAIN_OPTIMIZATION_THRESHOLD &&
401
+ cleaned.every(isExactHostDomainEntry);
402
+ if (canOptimizeToSet) {
382
403
  logger.warning(`Optimizing domain list with ${cleaned.length} entries to a Set for O(1) matching`);
383
404
  return new Set(cleaned);
384
405
  }
@@ -407,16 +428,12 @@ export class BrowserProfile {
407
428
  allowed_domains: Array.isArray(init.allowed_domains)
408
429
  ? optimizeDomainList(init.allowed_domains)
409
430
  : init.allowed_domains instanceof Set
410
- ? new Set(Array.from(init.allowed_domains)
411
- .map(normalizeDomainEntry)
412
- .filter(Boolean))
431
+ ? optimizeDomainList(Array.from(init.allowed_domains))
413
432
  : defaults.allowed_domains,
414
433
  prohibited_domains: Array.isArray(init.prohibited_domains)
415
434
  ? optimizeDomainList(init.prohibited_domains)
416
435
  : init.prohibited_domains instanceof Set
417
- ? new Set(Array.from(init.prohibited_domains)
418
- .map(normalizeDomainEntry)
419
- .filter(Boolean))
436
+ ? optimizeDomainList(Array.from(init.prohibited_domains))
420
437
  : defaults.prohibited_domains,
421
438
  window_position: init.window_position ?? defaults.window_position,
422
439
  };
@@ -5,6 +5,7 @@ import { BrowserStateSummary, type TabInfo } from './views.js';
5
5
  import { type WaitUntilState } from './events.js';
6
6
  import { DOMElementNode, type SelectorMap } from '../dom/views.js';
7
7
  import { SessionManager } from './session-manager.js';
8
+ import { type CaptchaWaitResult } from './watchdogs/captcha-watchdog.js';
8
9
  import type { BaseWatchdog } from './watchdogs/base.js';
9
10
  export interface BrowserSessionInit {
10
11
  id?: string;
@@ -22,6 +23,21 @@ export interface BrowserSessionInit {
22
23
  downloaded_files?: string[];
23
24
  closed_popup_messages?: string[];
24
25
  }
26
+ export interface ChromeProfileInfo {
27
+ directory: string;
28
+ name: string;
29
+ email?: string;
30
+ }
31
+ export declare const systemChrome: {
32
+ findExecutable(): string | null;
33
+ getUserDataDir(executablePath?: string | null): string | null;
34
+ listProfiles(userDataDir?: string | null): ChromeProfileInfo[];
35
+ };
36
+ export interface BrowserSessionFromSystemChromeInit extends Omit<BrowserSessionInit, 'browser_profile' | 'profile'> {
37
+ browser_profile?: BrowserProfile;
38
+ profile?: Partial<BrowserProfileOptions>;
39
+ profile_directory?: string | null;
40
+ }
25
41
  export interface BrowserStateOptions {
26
42
  cache_clickable_elements_hashes?: boolean;
27
43
  include_screenshot?: boolean;
@@ -78,7 +94,18 @@ export declare class BrowserSession {
78
94
  private readonly _maxRecentEvents;
79
95
  private _watchdogs;
80
96
  private _defaultWatchdogsAttached;
97
+ private _captchaWatchdog;
98
+ readonly RECONNECT_WAIT_TIMEOUT = 54;
99
+ private _reconnecting;
100
+ private _reconnectTask;
101
+ private _reconnectWaitPromise;
102
+ private _resolveReconnectWait;
103
+ private _intentionalStop;
104
+ private _disconnectAwareBrowser;
105
+ private _browserDisconnectHandler;
81
106
  constructor(init?: BrowserSessionInit);
107
+ static from_system_chrome(init?: BrowserSessionFromSystemChromeInit): BrowserSession;
108
+ static list_chrome_profiles(): ChromeProfileInfo[];
82
109
  attach_watchdog(watchdog: BaseWatchdog): void;
83
110
  attach_watchdogs(watchdogs: BaseWatchdog[]): void;
84
111
  detach_watchdog(watchdog: BaseWatchdog): void;
@@ -89,6 +116,7 @@ export declare class BrowserSession {
89
116
  cdp_url: string;
90
117
  }>;
91
118
  attach_default_watchdogs(): void;
119
+ wait_if_captcha_solving(timeoutSeconds?: number): Promise<CaptchaWaitResult | null>;
92
120
  private _formatTabId;
93
121
  private _createTabInfo;
94
122
  private _buildSyntheticTargetId;
@@ -96,6 +124,8 @@ export declare class BrowserSession {
96
124
  get_or_create_cdp_session(page?: Page | null): Promise<any>;
97
125
  private _waitForStableNetwork;
98
126
  private _setActivePage;
127
+ private _syncCurrentTabFromPage;
128
+ private _syncTabsWithBrowserPages;
99
129
  private _captureClosedPopupMessage;
100
130
  private _getClosedPopupMessagesSnapshot;
101
131
  private _recordRecentEvent;
@@ -108,6 +138,10 @@ export declare class BrowserSession {
108
138
  describe(): string;
109
139
  get _owns_browser_resources(): boolean;
110
140
  get is_stopping(): boolean;
141
+ get is_reconnecting(): boolean;
142
+ get should_gate_watchdog_events(): boolean;
143
+ get is_cdp_connected(): boolean;
144
+ wait_for_reconnect(timeoutSeconds?: number): Promise<void>;
111
145
  claim_agent(agentId: string, mode?: 'exclusive' | 'shared'): boolean;
112
146
  claimAgent(agentId: string, mode?: 'exclusive' | 'shared'): boolean;
113
147
  release_agent(agentId?: string): boolean;
@@ -123,6 +157,22 @@ export declare class BrowserSession {
123
157
  private _waitWithAbort;
124
158
  private _withAbort;
125
159
  private _toPlaywrightOptions;
160
+ set_extra_headers(headers: Record<string, string>): Promise<void>;
161
+ private _applyConfiguredExtraHttpHeaders;
162
+ private _usesRemoteBrowserConnection;
163
+ private _connectToConfiguredBrowser;
164
+ private _ensureBrowserContextFromBrowser;
165
+ private _beginReconnectWait;
166
+ private _endReconnectWait;
167
+ private _detachRemoteDisconnectHandler;
168
+ private _attachRemoteDisconnectHandler;
169
+ private _handleUnexpectedRemoteDisconnect;
170
+ private _restorePagesAfterReconnect;
171
+ reconnect(options?: {
172
+ preferred_url?: string | null;
173
+ preferred_tab_index?: number;
174
+ }): Promise<void>;
175
+ private _auto_reconnect;
126
176
  private _isSandboxLaunchError;
127
177
  private _createNoSandboxLaunchOptions;
128
178
  private _launchChromiumWithSandboxFallback;
@@ -253,11 +303,17 @@ export declare class BrowserSession {
253
303
  */
254
304
  wait_for_element(selector: string, timeout?: number): Promise<void>;
255
305
  /**
256
- * Take a screenshot of the current page
306
+ * Take a screenshot of the current page.
257
307
  * @param full_page Whether to capture the full scrollable page
308
+ * @param clip Optional clip region for partial screenshots
258
309
  * @returns Base64 encoded PNG screenshot
259
310
  */
260
- take_screenshot(full_page?: boolean): Promise<string | null>;
311
+ take_screenshot(full_page?: boolean, clip?: {
312
+ x: number;
313
+ y: number;
314
+ width: number;
315
+ height: number;
316
+ } | null): Promise<string | null>;
261
317
  /**
262
318
  * Add a request event listener to the current page
263
319
  */
@@ -327,6 +383,7 @@ export declare class BrowserSession {
327
383
  private _is_new_tab_page;
328
384
  private _is_ip_address_host;
329
385
  private _get_domain_variants;
386
+ private _setEntryMatchesUrl;
330
387
  /**
331
388
  * Check if page is displaying a PDF
332
389
  */