browser-use 0.2.0 → 0.3.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 (259) hide show
  1. package/README.md +295 -686
  2. package/dist/actor/element.d.ts +19 -0
  3. package/dist/actor/element.js +46 -0
  4. package/dist/actor/index.d.ts +4 -0
  5. package/dist/actor/index.js +4 -0
  6. package/dist/actor/mouse.d.ts +19 -0
  7. package/dist/actor/mouse.js +39 -0
  8. package/dist/actor/page.d.ts +29 -0
  9. package/dist/actor/page.js +88 -0
  10. package/dist/actor/utils.d.ts +4 -0
  11. package/dist/actor/utils.js +35 -0
  12. package/dist/agent/cloud-events.d.ts +18 -0
  13. package/dist/agent/cloud-events.js +65 -2
  14. package/dist/agent/gif.d.ts +1 -0
  15. package/dist/agent/gif.js +24 -2
  16. package/dist/agent/judge.d.ts +17 -0
  17. package/dist/agent/judge.js +197 -0
  18. package/dist/agent/message-manager/service.d.ts +12 -4
  19. package/dist/agent/message-manager/service.js +205 -39
  20. package/dist/agent/message-manager/utils.js +0 -1
  21. package/dist/agent/message-manager/views.d.ts +4 -0
  22. package/dist/agent/message-manager/views.js +11 -7
  23. package/dist/agent/prompts.d.ts +24 -3
  24. package/dist/agent/prompts.js +274 -59
  25. package/dist/agent/service.d.ts +99 -41
  26. package/dist/agent/service.js +2266 -472
  27. package/dist/agent/variable-detector.d.ts +12 -0
  28. package/dist/agent/variable-detector.js +211 -0
  29. package/dist/agent/views.d.ts +237 -18
  30. package/dist/agent/views.js +446 -33
  31. package/dist/browser/cloud/cloud.d.ts +20 -0
  32. package/dist/browser/cloud/cloud.js +129 -0
  33. package/dist/browser/cloud/index.d.ts +2 -0
  34. package/dist/browser/cloud/index.js +2 -0
  35. package/dist/browser/cloud/views.d.ts +41 -0
  36. package/dist/browser/cloud/views.js +35 -0
  37. package/dist/browser/events.d.ts +345 -0
  38. package/dist/browser/events.js +566 -0
  39. package/dist/browser/extensions.js +17 -17
  40. package/dist/browser/index.d.ts +4 -0
  41. package/dist/browser/index.js +4 -0
  42. package/dist/browser/profile.d.ts +8 -2
  43. package/dist/browser/profile.js +79 -12
  44. package/dist/browser/session-manager.d.ts +85 -0
  45. package/dist/browser/session-manager.js +208 -0
  46. package/dist/browser/session.d.ts +100 -8
  47. package/dist/browser/session.js +1097 -58
  48. package/dist/browser/types.d.ts +0 -2
  49. package/dist/browser/views.d.ts +39 -0
  50. package/dist/browser/views.js +32 -0
  51. package/dist/browser/watchdogs/aboutblank-watchdog.d.ts +12 -0
  52. package/dist/browser/watchdogs/aboutblank-watchdog.js +131 -0
  53. package/dist/browser/watchdogs/base.d.ts +21 -0
  54. package/dist/browser/watchdogs/base.js +81 -0
  55. package/dist/browser/watchdogs/cdp-session-watchdog.d.ts +14 -0
  56. package/dist/browser/watchdogs/cdp-session-watchdog.js +177 -0
  57. package/dist/browser/watchdogs/crash-watchdog.d.ts +38 -0
  58. package/dist/browser/watchdogs/crash-watchdog.js +296 -0
  59. package/dist/browser/watchdogs/default-action-watchdog.d.ts +49 -0
  60. package/dist/browser/watchdogs/default-action-watchdog.js +212 -0
  61. package/dist/browser/watchdogs/dom-watchdog.d.ts +8 -0
  62. package/dist/browser/watchdogs/dom-watchdog.js +31 -0
  63. package/dist/browser/watchdogs/downloads-watchdog.d.ts +77 -0
  64. package/dist/browser/watchdogs/downloads-watchdog.js +409 -0
  65. package/dist/browser/watchdogs/har-recording-watchdog.d.ts +19 -0
  66. package/dist/browser/watchdogs/har-recording-watchdog.js +317 -0
  67. package/dist/browser/watchdogs/index.d.ts +15 -0
  68. package/dist/browser/watchdogs/index.js +15 -0
  69. package/dist/browser/watchdogs/local-browser-watchdog.d.ts +10 -0
  70. package/dist/browser/watchdogs/local-browser-watchdog.js +32 -0
  71. package/dist/browser/watchdogs/permissions-watchdog.d.ts +8 -0
  72. package/dist/browser/watchdogs/permissions-watchdog.js +73 -0
  73. package/dist/browser/watchdogs/popups-watchdog.d.ts +13 -0
  74. package/dist/browser/watchdogs/popups-watchdog.js +77 -0
  75. package/dist/browser/watchdogs/recording-watchdog.d.ts +27 -0
  76. package/dist/browser/watchdogs/recording-watchdog.js +249 -0
  77. package/dist/browser/watchdogs/screenshot-watchdog.d.ts +6 -0
  78. package/dist/browser/watchdogs/screenshot-watchdog.js +13 -0
  79. package/dist/browser/watchdogs/security-watchdog.d.ts +10 -0
  80. package/dist/browser/watchdogs/security-watchdog.js +84 -0
  81. package/dist/browser/watchdogs/storage-state-watchdog.d.ts +24 -0
  82. package/dist/browser/watchdogs/storage-state-watchdog.js +288 -0
  83. package/dist/cli.d.ts +7 -2
  84. package/dist/cli.js +182 -25
  85. package/dist/code-use/formatting.d.ts +3 -0
  86. package/dist/code-use/formatting.js +18 -0
  87. package/dist/code-use/index.d.ts +6 -0
  88. package/dist/code-use/index.js +6 -0
  89. package/dist/code-use/namespace.d.ts +5 -0
  90. package/dist/code-use/namespace.js +81 -0
  91. package/dist/code-use/notebook-export.d.ts +3 -0
  92. package/dist/code-use/notebook-export.js +56 -0
  93. package/dist/code-use/service.d.ts +24 -0
  94. package/dist/code-use/service.js +104 -0
  95. package/dist/code-use/utils.d.ts +4 -0
  96. package/dist/code-use/utils.js +98 -0
  97. package/dist/code-use/views.d.ts +108 -0
  98. package/dist/code-use/views.js +165 -0
  99. package/dist/config.d.ts +13 -0
  100. package/dist/config.js +69 -3
  101. package/dist/controller/registry/service.d.ts +10 -1
  102. package/dist/controller/registry/service.js +266 -10
  103. package/dist/controller/registry/views.d.ts +4 -1
  104. package/dist/controller/registry/views.js +25 -2
  105. package/dist/controller/service.d.ts +10 -1
  106. package/dist/controller/service.js +1807 -268
  107. package/dist/controller/views.d.ts +78 -155
  108. package/dist/controller/views.js +61 -12
  109. package/dist/dom/history-tree-processor/service.d.ts +5 -0
  110. package/dist/dom/history-tree-processor/service.js +169 -14
  111. package/dist/dom/history-tree-processor/view.d.ts +7 -1
  112. package/dist/dom/history-tree-processor/view.js +10 -1
  113. package/dist/dom/markdown-extractor.d.ts +37 -0
  114. package/dist/dom/markdown-extractor.js +345 -0
  115. package/dist/dom/service.d.ts +3 -1
  116. package/dist/dom/service.js +76 -0
  117. package/dist/dom/views.d.ts +1 -0
  118. package/dist/dom/views.js +45 -0
  119. package/dist/event-bus.d.ts +107 -7
  120. package/dist/event-bus.js +313 -10
  121. package/dist/exceptions.d.ts +0 -3
  122. package/dist/exceptions.js +0 -7
  123. package/dist/filesystem/file-system.d.ts +18 -0
  124. package/dist/filesystem/file-system.js +503 -42
  125. package/dist/index.d.ts +7 -0
  126. package/dist/index.js +6 -0
  127. package/dist/integrations/gmail/actions.d.ts +3 -3
  128. package/dist/integrations/gmail/actions.js +4 -4
  129. package/dist/llm/anthropic/chat.d.ts +18 -1
  130. package/dist/llm/anthropic/chat.js +123 -55
  131. package/dist/llm/anthropic/serializer.d.ts +2 -0
  132. package/dist/llm/anthropic/serializer.js +81 -9
  133. package/dist/llm/aws/chat-anthropic.d.ts +17 -0
  134. package/dist/llm/aws/chat-anthropic.js +126 -26
  135. package/dist/llm/aws/chat-bedrock.d.ts +28 -1
  136. package/dist/llm/aws/chat-bedrock.js +161 -34
  137. package/dist/llm/aws/serializer.d.ts +13 -1
  138. package/dist/llm/aws/serializer.js +56 -17
  139. package/dist/llm/azure/chat.d.ts +53 -2
  140. package/dist/llm/azure/chat.js +366 -54
  141. package/dist/llm/base.d.ts +2 -0
  142. package/dist/llm/browser-use/chat.d.ts +40 -0
  143. package/dist/llm/browser-use/chat.js +305 -0
  144. package/dist/llm/browser-use/index.d.ts +1 -0
  145. package/dist/llm/browser-use/index.js +1 -0
  146. package/dist/llm/cerebras/chat.d.ts +39 -0
  147. package/dist/llm/cerebras/chat.js +178 -0
  148. package/dist/llm/cerebras/index.d.ts +2 -0
  149. package/dist/llm/cerebras/index.js +2 -0
  150. package/dist/llm/cerebras/serializer.d.ts +7 -0
  151. package/dist/llm/cerebras/serializer.js +82 -0
  152. package/dist/llm/deepseek/chat.d.ts +19 -2
  153. package/dist/llm/deepseek/chat.js +138 -25
  154. package/dist/llm/google/chat.d.ts +46 -2
  155. package/dist/llm/google/chat.js +267 -64
  156. package/dist/llm/google/serializer.d.ts +9 -1
  157. package/dist/llm/google/serializer.js +141 -34
  158. package/dist/llm/groq/chat.d.ts +21 -2
  159. package/dist/llm/groq/chat.js +125 -26
  160. package/dist/llm/groq/parser.js +3 -1
  161. package/dist/llm/mistral/chat.d.ts +43 -0
  162. package/dist/llm/mistral/chat.js +154 -0
  163. package/dist/llm/mistral/index.d.ts +2 -0
  164. package/dist/llm/mistral/index.js +2 -0
  165. package/dist/llm/mistral/schema.d.ts +8 -0
  166. package/dist/llm/mistral/schema.js +27 -0
  167. package/dist/llm/models.d.ts +2 -0
  168. package/dist/llm/models.js +317 -0
  169. package/dist/llm/ollama/chat.d.ts +13 -1
  170. package/dist/llm/ollama/chat.js +110 -19
  171. package/dist/llm/ollama/serializer.d.ts +1 -0
  172. package/dist/llm/ollama/serializer.js +34 -12
  173. package/dist/llm/openai/chat.d.ts +16 -0
  174. package/dist/llm/openai/chat.js +94 -44
  175. package/dist/llm/openai/like.d.ts +5 -3
  176. package/dist/llm/openai/like.js +7 -3
  177. package/dist/llm/openai/responses-serializer.d.ts +18 -0
  178. package/dist/llm/openai/responses-serializer.js +72 -0
  179. package/dist/llm/openrouter/chat.d.ts +28 -2
  180. package/dist/llm/openrouter/chat.js +115 -29
  181. package/dist/llm/schema.d.ts +11 -1
  182. package/dist/llm/schema.js +81 -1
  183. package/dist/llm/vercel/chat.d.ts +50 -0
  184. package/dist/llm/vercel/chat.js +276 -0
  185. package/dist/llm/vercel/index.d.ts +1 -0
  186. package/dist/llm/vercel/index.js +1 -0
  187. package/dist/llm/vercel/serializer.d.ts +5 -0
  188. package/dist/llm/vercel/serializer.js +7 -0
  189. package/dist/llm/views.d.ts +2 -1
  190. package/dist/llm/views.js +3 -1
  191. package/dist/logging-config.d.ts +2 -0
  192. package/dist/logging-config.js +82 -29
  193. package/dist/mcp/client.d.ts +10 -5
  194. package/dist/mcp/client.js +14 -9
  195. package/dist/mcp/controller.d.ts +42 -3
  196. package/dist/mcp/controller.js +56 -31
  197. package/dist/mcp/server.d.ts +14 -0
  198. package/dist/mcp/server.js +255 -52
  199. package/dist/observability.js +10 -4
  200. package/dist/sandbox/index.d.ts +2 -0
  201. package/dist/sandbox/index.js +2 -0
  202. package/dist/sandbox/sandbox.d.ts +19 -0
  203. package/dist/sandbox/sandbox.js +140 -0
  204. package/dist/sandbox/views.d.ts +67 -0
  205. package/dist/sandbox/views.js +121 -0
  206. package/dist/skill-cli/index.d.ts +3 -0
  207. package/dist/skill-cli/index.js +3 -0
  208. package/dist/skill-cli/protocol.d.ts +30 -0
  209. package/dist/skill-cli/protocol.js +48 -0
  210. package/dist/skill-cli/server.d.ts +11 -0
  211. package/dist/skill-cli/server.js +85 -0
  212. package/dist/skill-cli/sessions.d.ts +24 -0
  213. package/dist/skill-cli/sessions.js +47 -0
  214. package/dist/skills/index.d.ts +3 -0
  215. package/dist/skills/index.js +3 -0
  216. package/dist/skills/service.d.ts +27 -0
  217. package/dist/skills/service.js +266 -0
  218. package/dist/skills/utils.d.ts +6 -0
  219. package/dist/skills/utils.js +53 -0
  220. package/dist/skills/views.d.ts +40 -0
  221. package/dist/skills/views.js +10 -0
  222. package/dist/sync/auth.js +8 -3
  223. package/dist/sync/service.d.ts +6 -6
  224. package/dist/sync/service.js +54 -89
  225. package/dist/telemetry/views.d.ts +20 -6
  226. package/dist/telemetry/views.js +23 -5
  227. package/dist/tokens/custom-pricing.d.ts +2 -0
  228. package/dist/tokens/custom-pricing.js +22 -0
  229. package/dist/tokens/index.d.ts +2 -0
  230. package/dist/tokens/index.js +2 -0
  231. package/dist/tokens/mappings.d.ts +1 -0
  232. package/dist/tokens/mappings.js +3 -0
  233. package/dist/tokens/service.js +27 -8
  234. package/dist/tools/extraction/index.d.ts +2 -0
  235. package/dist/tools/extraction/index.js +2 -0
  236. package/dist/tools/extraction/schema-utils.d.ts +6 -0
  237. package/dist/tools/extraction/schema-utils.js +237 -0
  238. package/dist/tools/extraction/views.d.ts +7 -0
  239. package/dist/tools/index.d.ts +5 -0
  240. package/dist/tools/index.js +5 -0
  241. package/dist/tools/registry/index.d.ts +2 -0
  242. package/dist/tools/registry/index.js +2 -0
  243. package/dist/tools/registry/service.d.ts +1 -0
  244. package/dist/tools/registry/service.js +1 -0
  245. package/dist/tools/registry/views.d.ts +1 -0
  246. package/dist/tools/registry/views.js +1 -0
  247. package/dist/tools/service.d.ts +2 -0
  248. package/dist/tools/service.js +1 -0
  249. package/dist/tools/utils.d.ts +2 -0
  250. package/dist/tools/utils.js +57 -0
  251. package/dist/tools/views.d.ts +1 -0
  252. package/dist/tools/views.js +1 -0
  253. package/dist/utils.d.ts +10 -1
  254. package/dist/utils.js +70 -3
  255. package/package.json +87 -26
  256. package/dist/dom/playground/process-dom.js +0 -5
  257. package/dist/dom/playground/test-accessibility.d.ts +0 -44
  258. package/dist/dom/playground/test-accessibility.js +0 -111
  259. /package/dist/{dom/playground/process-dom.d.ts → tools/extraction/views.js} +0 -0
@@ -1,7 +1,9 @@
1
1
  import fs from 'node:fs';
2
2
  import { promises as fsp } from 'node:fs';
3
3
  import path from 'node:path';
4
+ import os from 'node:os';
4
5
  import https from 'node:https';
6
+ import { randomUUID } from 'node:crypto';
5
7
  import AdmZip from 'adm-zip';
6
8
  import { CONFIG } from '../config.js';
7
9
  import { observe_debug } from '../observability.js';
@@ -9,6 +11,7 @@ import { createLogger } from '../logging-config.js';
9
11
  import { log_pretty_path, uuid7str } from '../utils.js';
10
12
  const logger = createLogger('browser_use.browser.profile');
11
13
  export const CHROME_DEBUG_PORT = 9242;
14
+ export const DOMAIN_OPTIMIZATION_THRESHOLD = 100;
12
15
  export const CHROME_DISABLED_COMPONENTS = [
13
16
  'AcceptCHFrame',
14
17
  'AutoExpandDetailsElement',
@@ -39,6 +42,7 @@ export const CHROME_DISABLED_COMPONENTS = [
39
42
  'OverscrollHistoryNavigation',
40
43
  'InfiniteSessionRestore',
41
44
  'ExtensionDisableUnsupportedDeveloper',
45
+ 'ExtensionManifestV2Unsupported',
42
46
  ];
43
47
  export const CHROME_HEADLESS_ARGS = ['--headless=new'];
44
48
  export const CHROME_DOCKER_ARGS = [
@@ -86,8 +90,6 @@ export const CHROME_DEFAULT_ARGS = [
86
90
  '--disable-renderer-backgrounding',
87
91
  '--metrics-recording-only',
88
92
  '--no-first-run',
89
- '--password-store=basic',
90
- '--use-mock-keychain',
91
93
  '--no-service-autorun',
92
94
  '--export-tagged-pdf',
93
95
  '--disable-search-engine-choice-screen',
@@ -129,19 +131,39 @@ const DEFAULT_EXTENSIONS = [
129
131
  {
130
132
  name: 'uBlock Origin',
131
133
  id: 'cjpalhdlnbpafiamejdnhcphjbkeiagm',
132
- url: 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion=130&acceptformat=crx3&x=id%3Dcjpalhdlnbpafiamejdnhcphjbkeiagm%26uc',
134
+ url: 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion=133&acceptformat=crx3&x=id%3Dcjpalhdlnbpafiamejdnhcphjbkeiagm%26uc',
133
135
  },
134
136
  {
135
137
  name: "I still don't care about cookies",
136
138
  id: 'edibdbjcniadpccecjdfdjjppcpchdlm',
137
- url: 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion=130&acceptformat=crx3&x=id%3Dedibdbjcniadpccecjdfdjjppcpchdlm%26uc',
139
+ url: 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion=133&acceptformat=crx3&x=id%3Dedibdbjcniadpccecjdfdjjppcpchdlm%26uc',
138
140
  },
139
141
  {
140
142
  name: 'ClearURLs',
141
143
  id: 'lckanjgmijmafbedllaakclkaicjfmnk',
142
- url: 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion=130&acceptformat=crx3&x=id%3Dlckanjgmijmafbedllaakclkaicjfmnk%26uc',
144
+ url: 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion=133&acceptformat=crx3&x=id%3Dlckanjgmijmafbedllaakclkaicjfmnk%26uc',
145
+ },
146
+ {
147
+ name: 'Force Background Tab',
148
+ id: 'gidlfommnbibbmegmgajdbikelkdcmcl',
149
+ url: 'https://clients2.google.com/service/update2/crx?response=redirect&prodversion=133&acceptformat=crx3&x=id%3Dgidlfommnbibbmegmgajdbikelkdcmcl%26uc',
143
150
  },
144
151
  ];
152
+ const getEnableDefaultExtensionsDefault = () => {
153
+ const envValue = process.env.BROWSER_USE_DISABLE_EXTENSIONS;
154
+ if (typeof envValue === 'undefined') {
155
+ return true;
156
+ }
157
+ const normalized = envValue.trim().toLowerCase();
158
+ if (normalized === '' ||
159
+ normalized === '0' ||
160
+ normalized === 'false' ||
161
+ normalized === 'no' ||
162
+ normalized === 'off') {
163
+ return true;
164
+ }
165
+ return false;
166
+ };
145
167
  const parseDisplayEnv = () => {
146
168
  const width = process.env.BROWSER_USE_SCREEN_WIDTH;
147
169
  const height = process.env.BROWSER_USE_SCREEN_HEIGHT;
@@ -318,8 +340,10 @@ const DEFAULT_BROWSER_PROFILE_OPTIONS = {
318
340
  disable_security: false,
319
341
  deterministic_rendering: false,
320
342
  allowed_domains: null,
343
+ prohibited_domains: null,
344
+ block_ip_addresses: false,
321
345
  keep_alive: null,
322
- enable_default_extensions: true,
346
+ enable_default_extensions: getEnableDefaultExtensionsDefault(),
323
347
  window_size: null,
324
348
  window_height: null,
325
349
  window_width: null,
@@ -329,7 +353,7 @@ const DEFAULT_BROWSER_PROFILE_OPTIONS = {
329
353
  minimum_wait_page_load_time: 0.25,
330
354
  wait_for_network_idle_page_load_time: 0.5,
331
355
  maximum_wait_page_load_time: 5.0,
332
- wait_between_actions: 0.5,
356
+ wait_between_actions: 0.1,
333
357
  include_dynamic_attributes: true,
334
358
  highlight_elements: true,
335
359
  viewport_expansion: 500,
@@ -349,6 +373,17 @@ const argsAsList = (args) => Object.entries(args).map(([key, value]) => value
349
373
  ? `--${key.replace(/^-+/, '')}=${value}`
350
374
  : `--${key.replace(/^-+/, '')}`);
351
375
  const cloneDefaultOptions = () => JSON.parse(JSON.stringify(DEFAULT_BROWSER_PROFILE_OPTIONS));
376
+ const normalizeDomainEntry = (entry) => String(entry ?? '')
377
+ .trim()
378
+ .toLowerCase();
379
+ const optimizeDomainList = (value) => {
380
+ const cleaned = value.map(normalizeDomainEntry).filter(Boolean);
381
+ if (cleaned.length >= DOMAIN_OPTIMIZATION_THRESHOLD) {
382
+ logger.warning(`Optimizing domain list with ${cleaned.length} entries to a Set for O(1) matching`);
383
+ return new Set(cleaned);
384
+ }
385
+ return cleaned;
386
+ };
352
387
  export class BrowserProfile {
353
388
  options;
354
389
  constructor(init = {}) {
@@ -369,9 +404,24 @@ export class BrowserProfile {
369
404
  ignore_default_args: Array.isArray(init.ignore_default_args)
370
405
  ? init.ignore_default_args.map(validate_cli_arg)
371
406
  : (init.ignore_default_args ?? defaults.ignore_default_args),
407
+ allowed_domains: Array.isArray(init.allowed_domains)
408
+ ? optimizeDomainList(init.allowed_domains)
409
+ : init.allowed_domains instanceof Set
410
+ ? new Set(Array.from(init.allowed_domains)
411
+ .map(normalizeDomainEntry)
412
+ .filter(Boolean))
413
+ : defaults.allowed_domains,
414
+ prohibited_domains: Array.isArray(init.prohibited_domains)
415
+ ? optimizeDomainList(init.prohibited_domains)
416
+ : init.prohibited_domains instanceof Set
417
+ ? new Set(Array.from(init.prohibited_domains)
418
+ .map(normalizeDomainEntry)
419
+ .filter(Boolean))
420
+ : defaults.prohibited_domains,
372
421
  window_position: init.window_position ?? defaults.window_position,
373
422
  };
374
423
  this.options.id = init.id ?? uuid7str();
424
+ this.ensureDefaultDownloadsPath();
375
425
  this.applyLegacyWindowSize();
376
426
  this.warnStorageStateUserDataDirConflict();
377
427
  this.warnUserDataDirNonDefault();
@@ -393,6 +443,12 @@ export class BrowserProfile {
393
443
  get allowed_domains() {
394
444
  return this.options.allowed_domains;
395
445
  }
446
+ get prohibited_domains() {
447
+ return this.options.prohibited_domains;
448
+ }
449
+ get block_ip_addresses() {
450
+ return this.options.block_ip_addresses;
451
+ }
396
452
  get cookies_file() {
397
453
  return this.options.cookies_file;
398
454
  }
@@ -435,12 +491,12 @@ export class BrowserProfile {
435
491
  applyLegacyWindowSize() {
436
492
  const { window_width, window_height } = this.options;
437
493
  if (window_width || window_height) {
438
- logger.warning('⚠️ BrowserProfile(window_width=..., window_height=...) are deprecated, use BrowserProfile(window_size={"width": 1280, "height": 1100}) instead.');
494
+ logger.warning('⚠️ BrowserProfile(window_width=..., window_height=...) are deprecated, use BrowserProfile(window_size={"width": 1920, "height": 1080}) instead.');
439
495
  const newSize = {
440
496
  ...(this.options.window_size ?? { width: 0, height: 0 }),
441
497
  };
442
- newSize.width = newSize.width || window_width || 1280;
443
- newSize.height = newSize.height || window_height || 1100;
498
+ newSize.width = newSize.width || window_width || 1920;
499
+ newSize.height = newSize.height || window_height || 1080;
444
500
  this.options.window_size = newSize;
445
501
  }
446
502
  }
@@ -482,6 +538,17 @@ export class BrowserProfile {
482
538
  logger.warning('⚠️ BrowserSession(deterministic_rendering=True) is NOT RECOMMENDED. It breaks many sites and increases chances of getting blocked by anti-bot systems. It hardcodes the JS random seed and forces browsers across Linux/Mac/Windows to use the same font rendering engine so that identical screenshots can be generated.');
483
539
  }
484
540
  }
541
+ ensureDefaultDownloadsPath() {
542
+ if (this.options.downloads_path) {
543
+ return;
544
+ }
545
+ let downloadsPath = path.join(os.tmpdir(), `browser-use-downloads-${randomUUID().slice(0, 8)}`);
546
+ while (fs.existsSync(downloadsPath)) {
547
+ downloadsPath = path.join(os.tmpdir(), `browser-use-downloads-${randomUUID().slice(0, 8)}`);
548
+ }
549
+ fs.mkdirSync(downloadsPath, { recursive: true });
550
+ this.options.downloads_path = downloadsPath;
551
+ }
485
552
  getDefaultArgsList() {
486
553
  const ignore = this.options.ignore_default_args;
487
554
  if (Array.isArray(ignore)) {
@@ -671,7 +738,7 @@ export class BrowserProfile {
671
738
  const displaySize = get_display_size();
672
739
  const hasScreen = Boolean(displaySize);
673
740
  this.options.screen = this.options.screen ||
674
- displaySize || { width: 1280, height: 1100 };
741
+ displaySize || { width: 1920, height: 1080 };
675
742
  if (this.options.headless === null) {
676
743
  this.options.headless = !hasScreen;
677
744
  }
@@ -701,7 +768,7 @@ export class BrowserProfile {
701
768
  useViewport = !this.options.no_viewport;
702
769
  if (useViewport) {
703
770
  this.options.viewport = this.options.viewport ||
704
- this.options.screen || { width: 1280, height: 1100 };
771
+ this.options.screen || { width: 1920, height: 1080 };
705
772
  this.options.device_scale_factor =
706
773
  this.options.device_scale_factor || 1.0;
707
774
  }
@@ -0,0 +1,85 @@
1
+ import type { TabInfo } from './views.js';
2
+ export type SessionManagerTargetSource = 'tab' | 'cdp' | 'unknown';
3
+ export interface SessionManagerTarget {
4
+ target_id: string;
5
+ target_type: string;
6
+ url: string;
7
+ title: string;
8
+ attached: boolean;
9
+ source: SessionManagerTargetSource;
10
+ first_seen_at: string;
11
+ last_seen_at: string;
12
+ }
13
+ export interface SessionManagerChannel {
14
+ session_id: string;
15
+ target_id: string;
16
+ attached_at: string;
17
+ last_seen_at: string;
18
+ }
19
+ export interface TargetAttachedPayload {
20
+ target_id: string;
21
+ session_id?: string | null;
22
+ target_type?: string;
23
+ url?: string;
24
+ title?: string;
25
+ }
26
+ export interface TargetDetachedPayload {
27
+ target_id: string;
28
+ session_id?: string | null;
29
+ }
30
+ export interface TargetInfoChangedPayload {
31
+ target_id: string;
32
+ target_type?: string;
33
+ url?: string;
34
+ title?: string;
35
+ }
36
+ export declare class SessionManager {
37
+ private _targets;
38
+ private _sessions;
39
+ private _target_sessions;
40
+ private _session_to_target;
41
+ private _page_targets;
42
+ private _tab_target_ids;
43
+ private _focused_target_id;
44
+ sync_tabs(tabs: TabInfo[], current_tab_index: number, target_id_factory: (page_id: number) => string): void;
45
+ handle_target_attached(payload: TargetAttachedPayload): void;
46
+ handle_target_detached(payload: TargetDetachedPayload): void;
47
+ handle_target_info_changed(payload: TargetInfoChangedPayload): void;
48
+ upsert_target(init: {
49
+ target_id: string;
50
+ target_type?: string;
51
+ url?: string;
52
+ title?: string;
53
+ attached?: boolean;
54
+ source?: SessionManagerTargetSource;
55
+ }): SessionManagerTarget;
56
+ remove_target(target_id: string): void;
57
+ upsert_session(session_id: string, target_id: string): void;
58
+ remove_session(session_id: string): void;
59
+ bind_page_to_target(page_id: number, target_id: string): void;
60
+ unbind_page(page_id: number): void;
61
+ set_focused_target(target_id: string | null): void;
62
+ get_focused_target_id(): string | null;
63
+ get_target(target_id: string): SessionManagerTarget | null;
64
+ get_session(session_id: string): SessionManagerChannel | null;
65
+ get_target_id_for_session(session_id: string): string | null;
66
+ get_target_id_for_page(page_id: number): string | null;
67
+ get_sessions_for_target(target_id: string): SessionManagerChannel[];
68
+ get_all_targets(): {
69
+ target_id: string;
70
+ target_type: string;
71
+ url: string;
72
+ title: string;
73
+ attached: boolean;
74
+ source: SessionManagerTargetSource;
75
+ first_seen_at: string;
76
+ last_seen_at: string;
77
+ }[];
78
+ get_all_sessions(): {
79
+ session_id: string;
80
+ target_id: string;
81
+ attached_at: string;
82
+ last_seen_at: string;
83
+ }[];
84
+ clear(): void;
85
+ }
@@ -0,0 +1,208 @@
1
+ export class SessionManager {
2
+ _targets = new Map();
3
+ _sessions = new Map();
4
+ _target_sessions = new Map();
5
+ _session_to_target = new Map();
6
+ _page_targets = new Map();
7
+ _tab_target_ids = new Set();
8
+ _focused_target_id = null;
9
+ sync_tabs(tabs, current_tab_index, target_id_factory) {
10
+ const nextTabTargetIds = new Set();
11
+ const seenPageIds = new Set();
12
+ for (const tab of tabs) {
13
+ const target_id = tab.target_id ?? target_id_factory(tab.page_id);
14
+ tab.target_id = target_id;
15
+ nextTabTargetIds.add(target_id);
16
+ seenPageIds.add(tab.page_id);
17
+ this.upsert_target({
18
+ target_id,
19
+ target_type: 'page',
20
+ url: tab.url,
21
+ title: tab.title,
22
+ attached: true,
23
+ source: 'tab',
24
+ });
25
+ this.bind_page_to_target(tab.page_id, target_id);
26
+ }
27
+ for (const target_id of [...this._tab_target_ids]) {
28
+ if (!nextTabTargetIds.has(target_id)) {
29
+ this.remove_target(target_id);
30
+ }
31
+ }
32
+ this._tab_target_ids = nextTabTargetIds;
33
+ for (const page_id of [...this._page_targets.keys()]) {
34
+ if (!seenPageIds.has(page_id)) {
35
+ this._page_targets.delete(page_id);
36
+ }
37
+ }
38
+ const currentTab = tabs[current_tab_index] ?? null;
39
+ this._focused_target_id = currentTab?.target_id ?? null;
40
+ }
41
+ handle_target_attached(payload) {
42
+ this.upsert_target({
43
+ target_id: payload.target_id,
44
+ target_type: payload.target_type ?? 'page',
45
+ url: payload.url ?? '',
46
+ title: payload.title ?? '',
47
+ attached: true,
48
+ source: 'cdp',
49
+ });
50
+ if (payload.session_id) {
51
+ this.upsert_session(payload.session_id, payload.target_id);
52
+ }
53
+ }
54
+ handle_target_detached(payload) {
55
+ if (payload.session_id) {
56
+ this.remove_session(payload.session_id);
57
+ }
58
+ const targetSessions = this._target_sessions.get(payload.target_id);
59
+ if (targetSessions && targetSessions.size > 0) {
60
+ return;
61
+ }
62
+ const target = this._targets.get(payload.target_id);
63
+ if (!target) {
64
+ return;
65
+ }
66
+ if (target.source === 'tab' &&
67
+ this._tab_target_ids.has(payload.target_id)) {
68
+ target.attached = false;
69
+ target.last_seen_at = new Date().toISOString();
70
+ this._targets.set(payload.target_id, target);
71
+ return;
72
+ }
73
+ this.remove_target(payload.target_id);
74
+ }
75
+ handle_target_info_changed(payload) {
76
+ const current = this._targets.get(payload.target_id);
77
+ this.upsert_target({
78
+ target_id: payload.target_id,
79
+ target_type: payload.target_type ?? current?.target_type ?? 'page',
80
+ url: payload.url ?? current?.url ?? '',
81
+ title: payload.title ?? current?.title ?? '',
82
+ attached: current?.attached ?? true,
83
+ source: current?.source ?? 'cdp',
84
+ });
85
+ }
86
+ upsert_target(init) {
87
+ const now = new Date().toISOString();
88
+ const existing = this._targets.get(init.target_id);
89
+ const nextTarget = {
90
+ target_id: init.target_id,
91
+ target_type: init.target_type ?? existing?.target_type ?? 'page',
92
+ url: init.url ?? existing?.url ?? '',
93
+ title: init.title ?? existing?.title ?? '',
94
+ attached: init.attached ?? existing?.attached ?? true,
95
+ source: init.source ?? existing?.source ?? 'unknown',
96
+ first_seen_at: existing?.first_seen_at ?? now,
97
+ last_seen_at: now,
98
+ };
99
+ this._targets.set(init.target_id, nextTarget);
100
+ return nextTarget;
101
+ }
102
+ remove_target(target_id) {
103
+ this._targets.delete(target_id);
104
+ this._tab_target_ids.delete(target_id);
105
+ const sessions = this._target_sessions.get(target_id);
106
+ if (sessions) {
107
+ for (const session_id of sessions) {
108
+ this._sessions.delete(session_id);
109
+ this._session_to_target.delete(session_id);
110
+ }
111
+ }
112
+ this._target_sessions.delete(target_id);
113
+ for (const [page_id, mapped_target_id] of this._page_targets.entries()) {
114
+ if (mapped_target_id === target_id) {
115
+ this._page_targets.delete(page_id);
116
+ }
117
+ }
118
+ if (this._focused_target_id === target_id) {
119
+ this._focused_target_id = null;
120
+ }
121
+ }
122
+ upsert_session(session_id, target_id) {
123
+ const now = new Date().toISOString();
124
+ const existing = this._sessions.get(session_id);
125
+ this._sessions.set(session_id, {
126
+ session_id,
127
+ target_id,
128
+ attached_at: existing?.attached_at ?? now,
129
+ last_seen_at: now,
130
+ });
131
+ const previous_target_id = this._session_to_target.get(session_id);
132
+ if (previous_target_id && previous_target_id !== target_id) {
133
+ const previousSessions = this._target_sessions.get(previous_target_id);
134
+ previousSessions?.delete(session_id);
135
+ if (previousSessions && previousSessions.size === 0) {
136
+ this._target_sessions.delete(previous_target_id);
137
+ }
138
+ }
139
+ this._session_to_target.set(session_id, target_id);
140
+ const sessions = this._target_sessions.get(target_id) ?? new Set();
141
+ sessions.add(session_id);
142
+ this._target_sessions.set(target_id, sessions);
143
+ }
144
+ remove_session(session_id) {
145
+ const target_id = this._session_to_target.get(session_id);
146
+ this._session_to_target.delete(session_id);
147
+ this._sessions.delete(session_id);
148
+ if (!target_id) {
149
+ return;
150
+ }
151
+ const sessions = this._target_sessions.get(target_id);
152
+ if (!sessions) {
153
+ return;
154
+ }
155
+ sessions.delete(session_id);
156
+ if (sessions.size === 0) {
157
+ this._target_sessions.delete(target_id);
158
+ }
159
+ }
160
+ bind_page_to_target(page_id, target_id) {
161
+ this._page_targets.set(page_id, target_id);
162
+ }
163
+ unbind_page(page_id) {
164
+ this._page_targets.delete(page_id);
165
+ }
166
+ set_focused_target(target_id) {
167
+ this._focused_target_id = target_id;
168
+ }
169
+ get_focused_target_id() {
170
+ return this._focused_target_id;
171
+ }
172
+ get_target(target_id) {
173
+ return this._targets.get(target_id) ?? null;
174
+ }
175
+ get_session(session_id) {
176
+ return this._sessions.get(session_id) ?? null;
177
+ }
178
+ get_target_id_for_session(session_id) {
179
+ return this._session_to_target.get(session_id) ?? null;
180
+ }
181
+ get_target_id_for_page(page_id) {
182
+ return this._page_targets.get(page_id) ?? null;
183
+ }
184
+ get_sessions_for_target(target_id) {
185
+ const session_ids = this._target_sessions.get(target_id);
186
+ if (!session_ids) {
187
+ return [];
188
+ }
189
+ return [...session_ids]
190
+ .map((session_id) => this._sessions.get(session_id))
191
+ .filter((session) => session != null);
192
+ }
193
+ get_all_targets() {
194
+ return [...this._targets.values()].map((target) => ({ ...target }));
195
+ }
196
+ get_all_sessions() {
197
+ return [...this._sessions.values()].map((session) => ({ ...session }));
198
+ }
199
+ clear() {
200
+ this._targets.clear();
201
+ this._sessions.clear();
202
+ this._target_sessions.clear();
203
+ this._session_to_target.clear();
204
+ this._page_targets.clear();
205
+ this._tab_target_ids.clear();
206
+ this._focused_target_id = null;
207
+ }
208
+ }