browser-use 0.1.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 (258) hide show
  1. package/README.md +301 -636
  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 -40
  26. package/dist/agent/service.js +2282 -474
  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 -17
  30. package/dist/agent/views.js +446 -32
  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 +1102 -63
  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 +41 -0
  84. package/dist/cli.js +820 -10
  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 +1849 -288
  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/filesystem/file-system.d.ts +18 -0
  122. package/dist/filesystem/file-system.js +530 -42
  123. package/dist/index.d.ts +7 -0
  124. package/dist/index.js +6 -0
  125. package/dist/integrations/gmail/actions.d.ts +3 -3
  126. package/dist/integrations/gmail/actions.js +5 -5
  127. package/dist/llm/anthropic/chat.d.ts +18 -1
  128. package/dist/llm/anthropic/chat.js +123 -55
  129. package/dist/llm/anthropic/serializer.d.ts +2 -0
  130. package/dist/llm/anthropic/serializer.js +81 -9
  131. package/dist/llm/aws/chat-anthropic.d.ts +17 -0
  132. package/dist/llm/aws/chat-anthropic.js +129 -40
  133. package/dist/llm/aws/chat-bedrock.d.ts +28 -1
  134. package/dist/llm/aws/chat-bedrock.js +161 -34
  135. package/dist/llm/aws/serializer.d.ts +13 -1
  136. package/dist/llm/aws/serializer.js +56 -17
  137. package/dist/llm/azure/chat.d.ts +53 -2
  138. package/dist/llm/azure/chat.js +366 -53
  139. package/dist/llm/base.d.ts +2 -0
  140. package/dist/llm/browser-use/chat.d.ts +40 -0
  141. package/dist/llm/browser-use/chat.js +305 -0
  142. package/dist/llm/browser-use/index.d.ts +1 -0
  143. package/dist/llm/browser-use/index.js +1 -0
  144. package/dist/llm/cerebras/chat.d.ts +39 -0
  145. package/dist/llm/cerebras/chat.js +178 -0
  146. package/dist/llm/cerebras/index.d.ts +2 -0
  147. package/dist/llm/cerebras/index.js +2 -0
  148. package/dist/llm/cerebras/serializer.d.ts +7 -0
  149. package/dist/llm/cerebras/serializer.js +82 -0
  150. package/dist/llm/deepseek/chat.d.ts +19 -2
  151. package/dist/llm/deepseek/chat.js +138 -25
  152. package/dist/llm/google/chat.d.ts +46 -2
  153. package/dist/llm/google/chat.js +268 -63
  154. package/dist/llm/google/serializer.d.ts +9 -1
  155. package/dist/llm/google/serializer.js +141 -34
  156. package/dist/llm/groq/chat.d.ts +21 -2
  157. package/dist/llm/groq/chat.js +125 -26
  158. package/dist/llm/groq/parser.js +3 -1
  159. package/dist/llm/messages.d.ts +4 -4
  160. package/dist/llm/mistral/chat.d.ts +43 -0
  161. package/dist/llm/mistral/chat.js +154 -0
  162. package/dist/llm/mistral/index.d.ts +2 -0
  163. package/dist/llm/mistral/index.js +2 -0
  164. package/dist/llm/mistral/schema.d.ts +8 -0
  165. package/dist/llm/mistral/schema.js +27 -0
  166. package/dist/llm/models.d.ts +2 -0
  167. package/dist/llm/models.js +317 -0
  168. package/dist/llm/ollama/chat.d.ts +13 -1
  169. package/dist/llm/ollama/chat.js +110 -19
  170. package/dist/llm/ollama/serializer.d.ts +1 -0
  171. package/dist/llm/ollama/serializer.js +34 -12
  172. package/dist/llm/openai/chat.d.ts +16 -0
  173. package/dist/llm/openai/chat.js +94 -44
  174. package/dist/llm/openai/like.d.ts +5 -3
  175. package/dist/llm/openai/like.js +7 -3
  176. package/dist/llm/openai/responses-serializer.d.ts +18 -0
  177. package/dist/llm/openai/responses-serializer.js +72 -0
  178. package/dist/llm/openrouter/chat.d.ts +28 -2
  179. package/dist/llm/openrouter/chat.js +115 -29
  180. package/dist/llm/schema.d.ts +11 -1
  181. package/dist/llm/schema.js +81 -1
  182. package/dist/llm/vercel/chat.d.ts +50 -0
  183. package/dist/llm/vercel/chat.js +276 -0
  184. package/dist/llm/vercel/index.d.ts +1 -0
  185. package/dist/llm/vercel/index.js +1 -0
  186. package/dist/llm/vercel/serializer.d.ts +5 -0
  187. package/dist/llm/vercel/serializer.js +7 -0
  188. package/dist/llm/views.d.ts +2 -1
  189. package/dist/llm/views.js +3 -1
  190. package/dist/logging-config.d.ts +2 -0
  191. package/dist/logging-config.js +82 -29
  192. package/dist/mcp/client.d.ts +10 -5
  193. package/dist/mcp/client.js +21 -15
  194. package/dist/mcp/controller.d.ts +42 -3
  195. package/dist/mcp/controller.js +56 -31
  196. package/dist/mcp/server.d.ts +14 -0
  197. package/dist/mcp/server.js +257 -51
  198. package/dist/observability.js +10 -4
  199. package/dist/sandbox/index.d.ts +2 -0
  200. package/dist/sandbox/index.js +2 -0
  201. package/dist/sandbox/sandbox.d.ts +19 -0
  202. package/dist/sandbox/sandbox.js +140 -0
  203. package/dist/sandbox/views.d.ts +67 -0
  204. package/dist/sandbox/views.js +121 -0
  205. package/dist/skill-cli/index.d.ts +3 -0
  206. package/dist/skill-cli/index.js +3 -0
  207. package/dist/skill-cli/protocol.d.ts +30 -0
  208. package/dist/skill-cli/protocol.js +48 -0
  209. package/dist/skill-cli/server.d.ts +11 -0
  210. package/dist/skill-cli/server.js +85 -0
  211. package/dist/skill-cli/sessions.d.ts +24 -0
  212. package/dist/skill-cli/sessions.js +47 -0
  213. package/dist/skills/index.d.ts +3 -0
  214. package/dist/skills/index.js +3 -0
  215. package/dist/skills/service.d.ts +27 -0
  216. package/dist/skills/service.js +266 -0
  217. package/dist/skills/utils.d.ts +6 -0
  218. package/dist/skills/utils.js +53 -0
  219. package/dist/skills/views.d.ts +40 -0
  220. package/dist/skills/views.js +10 -0
  221. package/dist/sync/auth.js +8 -3
  222. package/dist/sync/service.d.ts +6 -6
  223. package/dist/sync/service.js +54 -89
  224. package/dist/telemetry/views.d.ts +20 -6
  225. package/dist/telemetry/views.js +23 -5
  226. package/dist/tokens/custom-pricing.d.ts +2 -0
  227. package/dist/tokens/custom-pricing.js +22 -0
  228. package/dist/tokens/index.d.ts +2 -0
  229. package/dist/tokens/index.js +2 -0
  230. package/dist/tokens/mappings.d.ts +1 -0
  231. package/dist/tokens/mappings.js +3 -0
  232. package/dist/tokens/service.js +30 -12
  233. package/dist/tools/extraction/index.d.ts +2 -0
  234. package/dist/tools/extraction/index.js +2 -0
  235. package/dist/tools/extraction/schema-utils.d.ts +6 -0
  236. package/dist/tools/extraction/schema-utils.js +237 -0
  237. package/dist/tools/extraction/views.d.ts +7 -0
  238. package/dist/tools/index.d.ts +5 -0
  239. package/dist/tools/index.js +5 -0
  240. package/dist/tools/registry/index.d.ts +2 -0
  241. package/dist/tools/registry/index.js +2 -0
  242. package/dist/tools/registry/service.d.ts +1 -0
  243. package/dist/tools/registry/service.js +1 -0
  244. package/dist/tools/registry/views.d.ts +1 -0
  245. package/dist/tools/registry/views.js +1 -0
  246. package/dist/tools/service.d.ts +2 -0
  247. package/dist/tools/service.js +1 -0
  248. package/dist/tools/utils.d.ts +2 -0
  249. package/dist/tools/utils.js +57 -0
  250. package/dist/tools/views.d.ts +1 -0
  251. package/dist/tools/views.js +1 -0
  252. package/dist/utils.d.ts +10 -1
  253. package/dist/utils.js +70 -3
  254. package/package.json +265 -28
  255. package/dist/dom/playground/process-dom.js +0 -5
  256. package/dist/dom/playground/test-accessibility.d.ts +0 -44
  257. package/dist/dom/playground/test-accessibility.js +0 -111
  258. /package/dist/{dom/playground/process-dom.d.ts → tools/extraction/views.js} +0 -0
package/dist/cli.js CHANGED
@@ -1,10 +1,770 @@
1
1
  #!/usr/bin/env node
2
+ import { promises as fs } from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { stdin, stdout } from 'node:process';
6
+ import { createInterface } from 'node:readline/promises';
2
7
  import { Agent } from './agent/service.js';
8
+ import { BrowserProfile, } from './browser/profile.js';
9
+ import { BrowserSession } from './browser/session.js';
10
+ import { CONFIG } from './config.js';
3
11
  import { ChatOpenAI } from './llm/openai/chat.js';
12
+ import { ChatAnthropic } from './llm/anthropic/chat.js';
13
+ import { ChatGoogle } from './llm/google/chat.js';
14
+ import { ChatDeepSeek } from './llm/deepseek/chat.js';
15
+ import { ChatGroq } from './llm/groq/chat.js';
16
+ import { ChatOpenRouter } from './llm/openrouter/chat.js';
17
+ import { ChatAzure } from './llm/azure/chat.js';
18
+ import { ChatOllama } from './llm/ollama/chat.js';
19
+ import { ChatMistral } from './llm/mistral/chat.js';
20
+ import { ChatCerebras } from './llm/cerebras/chat.js';
21
+ import { ChatVercel } from './llm/vercel/chat.js';
22
+ import { ChatAnthropicBedrock } from './llm/aws/chat-anthropic.js';
23
+ import { ChatBedrockConverse } from './llm/aws/chat-bedrock.js';
24
+ import { ChatBrowserUse } from './llm/browser-use/chat.js';
4
25
  import { MCPServer } from './mcp/server.js';
5
26
  import { get_browser_use_version } from './utils.js';
27
+ import { setupLogging } from './logging-config.js';
6
28
  import dotenv from 'dotenv';
7
29
  dotenv.config();
30
+ const CLI_PROVIDER_ALIASES = {
31
+ openai: 'openai',
32
+ anthropic: 'anthropic',
33
+ google: 'google',
34
+ gemini: 'google',
35
+ deepseek: 'deepseek',
36
+ groq: 'groq',
37
+ openrouter: 'openrouter',
38
+ azure: 'azure',
39
+ mistral: 'mistral',
40
+ cerebras: 'cerebras',
41
+ vercel: 'vercel',
42
+ oci: 'oci',
43
+ ollama: 'ollama',
44
+ 'browser-use': 'browser-use',
45
+ browseruse: 'browser-use',
46
+ bu: 'browser-use',
47
+ bedrock: 'aws',
48
+ aws: 'aws',
49
+ 'aws-anthropic': 'aws-anthropic',
50
+ 'bedrock-anthropic': 'aws-anthropic',
51
+ };
52
+ export const CLI_HISTORY_LIMIT = 100;
53
+ const INTERACTIVE_EXIT_COMMANDS = new Set(['exit', 'quit', ':q', '/q', '.q']);
54
+ const INTERACTIVE_HELP_COMMANDS = new Set(['help', '?', ':help']);
55
+ const parseAllowedDomains = (value) => {
56
+ const domains = value
57
+ .split(',')
58
+ .map((entry) => entry.trim())
59
+ .filter((entry) => entry.length > 0);
60
+ if (domains.length === 0) {
61
+ throw new Error('--allowed-domains must include at least one domain pattern');
62
+ }
63
+ return domains;
64
+ };
65
+ const parsePositiveInt = (name, value) => {
66
+ const parsed = Number.parseInt(value, 10);
67
+ if (!Number.isFinite(parsed) || Number.isNaN(parsed) || parsed <= 0) {
68
+ throw new Error(`${name} must be a positive integer, got "${value}"`);
69
+ }
70
+ return parsed;
71
+ };
72
+ const parseProvider = (value) => {
73
+ const normalized = value.trim().toLowerCase();
74
+ const provider = CLI_PROVIDER_ALIASES[normalized];
75
+ if (!provider) {
76
+ throw new Error(`Unsupported provider "${value}". Supported values: openai, anthropic, google, deepseek, groq, openrouter, azure, mistral, cerebras, vercel, oci, ollama, browser-use, aws, aws-anthropic.`);
77
+ }
78
+ return provider;
79
+ };
80
+ const takeOptionValue = (arg, currentIndex, argv) => {
81
+ const eqIndex = arg.indexOf('=');
82
+ if (eqIndex >= 0) {
83
+ const inlineValue = arg.slice(eqIndex + 1).trim();
84
+ if (!inlineValue) {
85
+ throw new Error(`Missing value for option: ${arg.slice(0, eqIndex)}`);
86
+ }
87
+ return { value: inlineValue, nextIndex: currentIndex };
88
+ }
89
+ const next = argv[currentIndex + 1];
90
+ if (!next || next.startsWith('-')) {
91
+ throw new Error(`Missing value for option: ${arg}`);
92
+ }
93
+ return { value: next, nextIndex: currentIndex + 1 };
94
+ };
95
+ const expandHome = (value) => {
96
+ if (!value.startsWith('~')) {
97
+ return value;
98
+ }
99
+ const home = process.env.HOME || process.env.USERPROFILE || '';
100
+ if (!home) {
101
+ return value;
102
+ }
103
+ if (value === '~') {
104
+ return home;
105
+ }
106
+ if (value.startsWith('~/') || value.startsWith('~\\')) {
107
+ return path.join(home, value.slice(2));
108
+ }
109
+ return value;
110
+ };
111
+ export const parseCliArgs = (argv) => {
112
+ const parsed = {
113
+ help: false,
114
+ version: false,
115
+ debug: false,
116
+ headless: null,
117
+ window_width: null,
118
+ window_height: null,
119
+ user_data_dir: null,
120
+ profile_directory: null,
121
+ allowed_domains: null,
122
+ proxy_url: null,
123
+ no_proxy: null,
124
+ proxy_username: null,
125
+ proxy_password: null,
126
+ cdp_url: null,
127
+ model: null,
128
+ provider: null,
129
+ prompt: null,
130
+ mcp: false,
131
+ positional: [],
132
+ };
133
+ for (let i = 0; i < argv.length; i += 1) {
134
+ const arg = argv[i];
135
+ if (arg === '--') {
136
+ parsed.positional.push(...argv.slice(i + 1));
137
+ break;
138
+ }
139
+ if (arg === '-h' || arg === '--help') {
140
+ parsed.help = true;
141
+ continue;
142
+ }
143
+ if (arg === '--version') {
144
+ parsed.version = true;
145
+ continue;
146
+ }
147
+ if (arg === '--debug') {
148
+ parsed.debug = true;
149
+ continue;
150
+ }
151
+ if (arg === '--headless') {
152
+ parsed.headless = true;
153
+ continue;
154
+ }
155
+ if (arg === '--mcp') {
156
+ parsed.mcp = true;
157
+ continue;
158
+ }
159
+ if (arg === '-p' || arg === '--prompt' || arg.startsWith('--prompt=')) {
160
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
161
+ parsed.prompt = value;
162
+ i = nextIndex;
163
+ continue;
164
+ }
165
+ if (arg === '--model' || arg.startsWith('--model=')) {
166
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
167
+ parsed.model = value;
168
+ i = nextIndex;
169
+ continue;
170
+ }
171
+ if (arg === '--provider' || arg.startsWith('--provider=')) {
172
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
173
+ parsed.provider = parseProvider(value);
174
+ i = nextIndex;
175
+ continue;
176
+ }
177
+ if (arg === '--window-width' || arg.startsWith('--window-width=')) {
178
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
179
+ parsed.window_width = parsePositiveInt('--window-width', value);
180
+ i = nextIndex;
181
+ continue;
182
+ }
183
+ if (arg === '--window-height' || arg.startsWith('--window-height=')) {
184
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
185
+ parsed.window_height = parsePositiveInt('--window-height', value);
186
+ i = nextIndex;
187
+ continue;
188
+ }
189
+ if (arg === '--user-data-dir' || arg.startsWith('--user-data-dir=')) {
190
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
191
+ parsed.user_data_dir = path.resolve(expandHome(value));
192
+ i = nextIndex;
193
+ continue;
194
+ }
195
+ if (arg === '--profile-directory' ||
196
+ arg.startsWith('--profile-directory=')) {
197
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
198
+ parsed.profile_directory = value;
199
+ i = nextIndex;
200
+ continue;
201
+ }
202
+ if (arg === '--allowed-domains' || arg.startsWith('--allowed-domains=')) {
203
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
204
+ const domains = parseAllowedDomains(value);
205
+ parsed.allowed_domains = [...(parsed.allowed_domains ?? []), ...domains];
206
+ i = nextIndex;
207
+ continue;
208
+ }
209
+ if (arg === '--proxy-url' || arg.startsWith('--proxy-url=')) {
210
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
211
+ parsed.proxy_url = value.trim();
212
+ i = nextIndex;
213
+ continue;
214
+ }
215
+ if (arg === '--no-proxy' || arg.startsWith('--no-proxy=')) {
216
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
217
+ parsed.no_proxy = value;
218
+ i = nextIndex;
219
+ continue;
220
+ }
221
+ if (arg === '--proxy-username' || arg.startsWith('--proxy-username=')) {
222
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
223
+ parsed.proxy_username = value;
224
+ i = nextIndex;
225
+ continue;
226
+ }
227
+ if (arg === '--proxy-password' || arg.startsWith('--proxy-password=')) {
228
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
229
+ parsed.proxy_password = value;
230
+ i = nextIndex;
231
+ continue;
232
+ }
233
+ if (arg === '--cdp-url' || arg.startsWith('--cdp-url=')) {
234
+ const { value, nextIndex } = takeOptionValue(arg, i, argv);
235
+ parsed.cdp_url = value;
236
+ i = nextIndex;
237
+ continue;
238
+ }
239
+ if (arg.startsWith('-')) {
240
+ throw new Error(`Unknown option: ${arg}`);
241
+ }
242
+ parsed.positional.push(arg);
243
+ }
244
+ if (parsed.prompt && parsed.positional.length > 0) {
245
+ throw new Error('Use either positional task text or --prompt, not both.');
246
+ }
247
+ return parsed;
248
+ };
249
+ const resolveTask = (args) => {
250
+ if (args.prompt) {
251
+ return args.prompt.trim();
252
+ }
253
+ if (args.positional.length > 0) {
254
+ return args.positional.join(' ').trim();
255
+ }
256
+ return null;
257
+ };
258
+ export const isInteractiveExitCommand = (value) => INTERACTIVE_EXIT_COMMANDS.has(value.trim().toLowerCase());
259
+ export const isInteractiveHelpCommand = (value) => INTERACTIVE_HELP_COMMANDS.has(value.trim().toLowerCase());
260
+ export const normalizeCliHistory = (history, maxLength = CLI_HISTORY_LIMIT) => {
261
+ const normalized = history
262
+ .map((entry) => (typeof entry === 'string' ? entry.trim() : ''))
263
+ .filter((entry) => entry.length > 0);
264
+ return normalized.slice(-maxLength);
265
+ };
266
+ export const getCliHistoryPath = (configDir) => {
267
+ const baseDir = configDir ??
268
+ CONFIG.BROWSER_USE_CONFIG_DIR ??
269
+ path.join(os.homedir(), '.config', 'browseruse');
270
+ return path.join(baseDir, 'command_history.json');
271
+ };
272
+ export const loadCliHistory = async (historyPath = getCliHistoryPath()) => {
273
+ try {
274
+ const raw = await fs.readFile(historyPath, 'utf-8');
275
+ const parsed = JSON.parse(raw);
276
+ if (!Array.isArray(parsed)) {
277
+ return [];
278
+ }
279
+ return normalizeCliHistory(parsed);
280
+ }
281
+ catch (error) {
282
+ const nodeError = error;
283
+ if (nodeError.code === 'ENOENT') {
284
+ return [];
285
+ }
286
+ return [];
287
+ }
288
+ };
289
+ export const saveCliHistory = async (history, historyPath = getCliHistoryPath()) => {
290
+ const normalized = normalizeCliHistory(history);
291
+ await fs.mkdir(path.dirname(historyPath), { recursive: true });
292
+ await fs.writeFile(historyPath, JSON.stringify(normalized, null, 2), 'utf-8');
293
+ };
294
+ export const shouldStartInteractiveMode = (task, options = {}) => {
295
+ const forceInteractive = options.forceInteractive ??
296
+ process.env.BROWSER_USE_CLI_FORCE_INTERACTIVE === '1';
297
+ const inputIsTTY = options.inputIsTTY ?? Boolean(stdin.isTTY);
298
+ const outputIsTTY = options.outputIsTTY ?? Boolean(stdout.isTTY);
299
+ return !task && (forceInteractive || (inputIsTTY && outputIsTTY));
300
+ };
301
+ const requireEnv = (name) => {
302
+ const value = process.env[name];
303
+ if (!value) {
304
+ throw new Error(`Missing environment variable: ${name}`);
305
+ }
306
+ return value;
307
+ };
308
+ const inferProviderFromModel = (model) => {
309
+ const lower = model.toLowerCase();
310
+ if (lower.startsWith('gpt') ||
311
+ lower.startsWith('o1') ||
312
+ lower.startsWith('o3') ||
313
+ lower.startsWith('o4') ||
314
+ lower.startsWith('gpt-5')) {
315
+ return 'openai';
316
+ }
317
+ if (lower.startsWith('claude')) {
318
+ return 'anthropic';
319
+ }
320
+ if (lower.startsWith('gemini')) {
321
+ return 'google';
322
+ }
323
+ if (lower.startsWith('deepseek')) {
324
+ return 'deepseek';
325
+ }
326
+ if (lower.startsWith('groq:')) {
327
+ return 'groq';
328
+ }
329
+ if (lower.startsWith('openrouter:')) {
330
+ return 'openrouter';
331
+ }
332
+ if (lower.startsWith('azure:')) {
333
+ return 'azure';
334
+ }
335
+ if (lower.startsWith('mistral:')) {
336
+ return 'mistral';
337
+ }
338
+ if (lower.startsWith('cerebras:')) {
339
+ return 'cerebras';
340
+ }
341
+ if (lower.startsWith('vercel:')) {
342
+ return 'vercel';
343
+ }
344
+ if (lower.startsWith('oci:')) {
345
+ return 'oci';
346
+ }
347
+ if (lower.startsWith('mistral-') ||
348
+ lower.startsWith('codestral') ||
349
+ lower.startsWith('pixtral')) {
350
+ return 'mistral';
351
+ }
352
+ if (lower.startsWith('llama3.') ||
353
+ lower.startsWith('llama-4-') ||
354
+ lower.startsWith('gpt-oss-') ||
355
+ lower.startsWith('qwen-3-')) {
356
+ return 'cerebras';
357
+ }
358
+ if (lower.startsWith('ollama:')) {
359
+ return 'ollama';
360
+ }
361
+ if (lower.startsWith('browser-use:') ||
362
+ lower.startsWith('bu-') ||
363
+ lower.startsWith('browser-use/')) {
364
+ return 'browser-use';
365
+ }
366
+ if (lower.startsWith('bedrock:anthropic.')) {
367
+ return 'aws-anthropic';
368
+ }
369
+ if (lower.startsWith('bedrock:')) {
370
+ return 'aws';
371
+ }
372
+ if (lower.startsWith('anthropic.')) {
373
+ return 'aws-anthropic';
374
+ }
375
+ if (lower.includes('/') &&
376
+ !lower.startsWith('http://') &&
377
+ !lower.startsWith('https://')) {
378
+ return 'openrouter';
379
+ }
380
+ return null;
381
+ };
382
+ const normalizeModelValue = (model, provider) => {
383
+ const lower = model.toLowerCase();
384
+ if (provider === 'groq' && lower.startsWith('groq:')) {
385
+ return model.slice('groq:'.length);
386
+ }
387
+ if (provider === 'openrouter' && lower.startsWith('openrouter:')) {
388
+ return model.slice('openrouter:'.length);
389
+ }
390
+ if (provider === 'azure' && lower.startsWith('azure:')) {
391
+ return model.slice('azure:'.length);
392
+ }
393
+ if (provider === 'mistral' && lower.startsWith('mistral:')) {
394
+ return model.slice('mistral:'.length);
395
+ }
396
+ if (provider === 'cerebras' && lower.startsWith('cerebras:')) {
397
+ return model.slice('cerebras:'.length);
398
+ }
399
+ if (provider === 'vercel' && lower.startsWith('vercel:')) {
400
+ return model.slice('vercel:'.length);
401
+ }
402
+ if (provider === 'oci' && lower.startsWith('oci:')) {
403
+ return model.slice('oci:'.length);
404
+ }
405
+ if (provider === 'ollama' && lower.startsWith('ollama:')) {
406
+ return model.slice('ollama:'.length);
407
+ }
408
+ if (provider === 'browser-use' && lower.startsWith('browser-use:')) {
409
+ return model.slice('browser-use:'.length);
410
+ }
411
+ if (provider === 'browser-use' && lower.startsWith('bu_')) {
412
+ return model.replace(/_/g, '-');
413
+ }
414
+ if (provider === 'aws-anthropic' && lower.startsWith('bedrock:')) {
415
+ return model.slice('bedrock:'.length);
416
+ }
417
+ if (provider === 'aws' && lower.startsWith('bedrock:')) {
418
+ return model.slice('bedrock:'.length);
419
+ }
420
+ return model;
421
+ };
422
+ const providersAreCompatible = (explicitProvider, inferredProvider) => {
423
+ if (explicitProvider === inferredProvider) {
424
+ return true;
425
+ }
426
+ if ((explicitProvider === 'aws' && inferredProvider === 'aws-anthropic') ||
427
+ (explicitProvider === 'aws-anthropic' && inferredProvider === 'aws')) {
428
+ return true;
429
+ }
430
+ return false;
431
+ };
432
+ const getDefaultModelForProvider = (provider) => {
433
+ switch (provider) {
434
+ case 'openai':
435
+ return 'gpt-5-mini';
436
+ case 'anthropic':
437
+ return 'claude-4-sonnet';
438
+ case 'google':
439
+ return 'gemini-2.5-pro';
440
+ case 'deepseek':
441
+ return 'deepseek-chat';
442
+ case 'groq':
443
+ return 'llama-3.1-70b-versatile';
444
+ case 'openrouter':
445
+ return 'openai/gpt-5-mini';
446
+ case 'azure':
447
+ return 'gpt-4o';
448
+ case 'mistral':
449
+ return 'mistral-large-latest';
450
+ case 'cerebras':
451
+ return 'llama3.1-8b';
452
+ case 'vercel':
453
+ return 'openai/gpt-5-mini';
454
+ case 'oci':
455
+ return null;
456
+ case 'aws-anthropic':
457
+ return 'anthropic.claude-3-5-sonnet-20241022-v2:0';
458
+ case 'ollama':
459
+ return process.env.OLLAMA_MODEL || 'qwen2.5:latest';
460
+ case 'browser-use':
461
+ return 'bu-latest';
462
+ case 'aws':
463
+ return null;
464
+ default:
465
+ return null;
466
+ }
467
+ };
468
+ const createLlmForProvider = (provider, model) => {
469
+ switch (provider) {
470
+ case 'openai':
471
+ return new ChatOpenAI({
472
+ model,
473
+ apiKey: requireEnv('OPENAI_API_KEY'),
474
+ });
475
+ case 'anthropic':
476
+ return new ChatAnthropic({
477
+ model,
478
+ apiKey: requireEnv('ANTHROPIC_API_KEY'),
479
+ });
480
+ case 'google':
481
+ requireEnv('GOOGLE_API_KEY');
482
+ return new ChatGoogle(model);
483
+ case 'deepseek':
484
+ requireEnv('DEEPSEEK_API_KEY');
485
+ return new ChatDeepSeek(model);
486
+ case 'groq':
487
+ requireEnv('GROQ_API_KEY');
488
+ return new ChatGroq(model);
489
+ case 'openrouter':
490
+ requireEnv('OPENROUTER_API_KEY');
491
+ return new ChatOpenRouter(model);
492
+ case 'azure':
493
+ requireEnv('AZURE_OPENAI_API_KEY');
494
+ requireEnv('AZURE_OPENAI_ENDPOINT');
495
+ return new ChatAzure(model);
496
+ case 'mistral':
497
+ return new ChatMistral({
498
+ model,
499
+ apiKey: requireEnv('MISTRAL_API_KEY'),
500
+ baseURL: process.env.MISTRAL_BASE_URL,
501
+ });
502
+ case 'cerebras':
503
+ return new ChatCerebras({
504
+ model,
505
+ apiKey: requireEnv('CEREBRAS_API_KEY'),
506
+ baseURL: process.env.CEREBRAS_BASE_URL,
507
+ });
508
+ case 'vercel':
509
+ return new ChatVercel({
510
+ model,
511
+ apiKey: requireEnv('VERCEL_API_KEY'),
512
+ baseURL: process.env.VERCEL_BASE_URL,
513
+ });
514
+ case 'oci':
515
+ throw new Error('OCI models require manual configuration in TypeScript runtime. Use a custom BaseChatModel integration for OCI credentials and endpoint setup.');
516
+ case 'ollama': {
517
+ const host = process.env.OLLAMA_HOST || 'http://localhost:11434';
518
+ return new ChatOllama(model, host);
519
+ }
520
+ case 'browser-use':
521
+ return new ChatBrowserUse({
522
+ model,
523
+ apiKey: requireEnv('BROWSER_USE_API_KEY'),
524
+ });
525
+ case 'aws-anthropic':
526
+ return new ChatAnthropicBedrock({
527
+ model,
528
+ region: process.env.AWS_REGION || 'us-east-1',
529
+ });
530
+ case 'aws':
531
+ return new ChatBedrockConverse(model, process.env.AWS_REGION || 'us-east-1');
532
+ default:
533
+ throw new Error(`Unsupported provider "${provider}"`);
534
+ }
535
+ };
536
+ export const getLlmFromCliArgs = (args) => {
537
+ if (args.model) {
538
+ const inferredProvider = inferProviderFromModel(args.model);
539
+ if (args.provider &&
540
+ inferredProvider &&
541
+ !providersAreCompatible(args.provider, inferredProvider)) {
542
+ throw new Error(`Provider mismatch: --provider ${args.provider} conflicts with model "${args.model}" (inferred: ${inferredProvider}).`);
543
+ }
544
+ const provider = args.provider ?? inferredProvider;
545
+ if (!provider) {
546
+ throw new Error(`Cannot infer provider from model "${args.model}". Provide --provider or use a supported model prefix: gpt*/o*, claude*, gemini*, deepseek*, groq:, openrouter:, azure:, mistral:, cerebras:, vercel:, oci:, ollama:, browser-use:, bu-*, bedrock:.`);
547
+ }
548
+ const normalizedModel = normalizeModelValue(args.model, provider);
549
+ return createLlmForProvider(provider, normalizedModel);
550
+ }
551
+ if (args.provider) {
552
+ const defaultModel = getDefaultModelForProvider(args.provider);
553
+ if (!defaultModel) {
554
+ throw new Error(`Provider "${args.provider}" requires --model. Example: --provider aws --model bedrock:us.amazon.nova-lite-v1:0`);
555
+ }
556
+ return createLlmForProvider(args.provider, defaultModel);
557
+ }
558
+ if (process.env.OPENAI_API_KEY) {
559
+ return new ChatOpenAI({
560
+ model: 'gpt-5-mini',
561
+ apiKey: process.env.OPENAI_API_KEY,
562
+ });
563
+ }
564
+ if (process.env.ANTHROPIC_API_KEY) {
565
+ return new ChatAnthropic({
566
+ model: 'claude-4-sonnet',
567
+ apiKey: process.env.ANTHROPIC_API_KEY,
568
+ });
569
+ }
570
+ if (process.env.GOOGLE_API_KEY) {
571
+ return new ChatGoogle('gemini-2.5-pro');
572
+ }
573
+ if (process.env.DEEPSEEK_API_KEY) {
574
+ return new ChatDeepSeek('deepseek-chat');
575
+ }
576
+ if (process.env.GROQ_API_KEY) {
577
+ return new ChatGroq('llama-3.1-70b-versatile');
578
+ }
579
+ if (process.env.OPENROUTER_API_KEY) {
580
+ return new ChatOpenRouter('openai/gpt-5-mini');
581
+ }
582
+ if (process.env.AZURE_OPENAI_API_KEY && process.env.AZURE_OPENAI_ENDPOINT) {
583
+ return new ChatAzure('gpt-4o');
584
+ }
585
+ if (process.env.MISTRAL_API_KEY) {
586
+ return new ChatMistral({
587
+ model: 'mistral-large-latest',
588
+ apiKey: process.env.MISTRAL_API_KEY,
589
+ baseURL: process.env.MISTRAL_BASE_URL,
590
+ });
591
+ }
592
+ if (process.env.CEREBRAS_API_KEY) {
593
+ return new ChatCerebras({
594
+ model: 'llama3.1-8b',
595
+ apiKey: process.env.CEREBRAS_API_KEY,
596
+ baseURL: process.env.CEREBRAS_BASE_URL,
597
+ });
598
+ }
599
+ if (process.env.VERCEL_API_KEY) {
600
+ return new ChatVercel({
601
+ model: 'openai/gpt-5-mini',
602
+ apiKey: process.env.VERCEL_API_KEY,
603
+ baseURL: process.env.VERCEL_BASE_URL,
604
+ });
605
+ }
606
+ if (process.env.AWS_ACCESS_KEY_ID || process.env.AWS_PROFILE) {
607
+ return new ChatAnthropicBedrock({
608
+ model: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
609
+ region: process.env.AWS_REGION || 'us-east-1',
610
+ });
611
+ }
612
+ return new ChatOllama(process.env.OLLAMA_MODEL || 'qwen2.5:latest', process.env.OLLAMA_HOST || 'http://localhost:11434');
613
+ };
614
+ const parseCommaSeparatedList = (value) => value
615
+ .split(',')
616
+ .map((entry) => entry.trim())
617
+ .filter((entry) => entry.length > 0);
618
+ export const buildBrowserProfileFromCliArgs = (args) => {
619
+ const profile = {};
620
+ if (args.headless !== null) {
621
+ profile.headless = args.headless;
622
+ }
623
+ if (args.window_width !== null) {
624
+ profile.window_width = args.window_width;
625
+ }
626
+ if (args.window_height !== null) {
627
+ profile.window_height = args.window_height;
628
+ }
629
+ if (args.user_data_dir) {
630
+ profile.user_data_dir = args.user_data_dir;
631
+ }
632
+ if (args.profile_directory) {
633
+ profile.profile_directory = args.profile_directory;
634
+ }
635
+ if (args.allowed_domains && args.allowed_domains.length > 0) {
636
+ profile.allowed_domains = args.allowed_domains;
637
+ }
638
+ if (args.proxy_url ||
639
+ args.no_proxy ||
640
+ args.proxy_username ||
641
+ args.proxy_password) {
642
+ const proxy = {};
643
+ if (args.proxy_url) {
644
+ proxy.server = args.proxy_url;
645
+ }
646
+ if (args.no_proxy) {
647
+ proxy.bypass = parseCommaSeparatedList(args.no_proxy).join(',');
648
+ }
649
+ if (args.proxy_username) {
650
+ proxy.username = args.proxy_username;
651
+ }
652
+ if (args.proxy_password) {
653
+ proxy.password = args.proxy_password;
654
+ }
655
+ profile.proxy = proxy;
656
+ }
657
+ if (Object.keys(profile).length === 0) {
658
+ return null;
659
+ }
660
+ return new BrowserProfile(profile);
661
+ };
662
+ const runAgentTask = async ({ task, llm, browserProfile, browserSession, sessionAttachmentMode, }) => {
663
+ const agent = new Agent({
664
+ task,
665
+ llm,
666
+ ...(browserProfile ? { browser_profile: browserProfile } : {}),
667
+ ...(browserSession ? { browser_session: browserSession } : {}),
668
+ ...(sessionAttachmentMode
669
+ ? { session_attachment_mode: sessionAttachmentMode }
670
+ : {}),
671
+ source: 'cli',
672
+ });
673
+ await agent.run();
674
+ };
675
+ const runInteractiveMode = async (args, llm) => {
676
+ const historyPath = getCliHistoryPath();
677
+ const history = await loadCliHistory(historyPath);
678
+ const browserProfile = buildBrowserProfileFromCliArgs(args) ?? new BrowserProfile();
679
+ browserProfile.keep_alive = true;
680
+ const browserSession = new BrowserSession({
681
+ browser_profile: browserProfile,
682
+ ...(args.cdp_url ? { cdp_url: args.cdp_url } : {}),
683
+ });
684
+ const rl = createInterface({
685
+ input: stdin,
686
+ output: stdout,
687
+ terminal: true,
688
+ historySize: CLI_HISTORY_LIMIT,
689
+ });
690
+ if (Array.isArray(rl.history) && history.length > 0) {
691
+ rl.history = [...history].reverse();
692
+ }
693
+ console.log('Interactive mode started. Type a task and press Enter.');
694
+ console.log('Commands: help, exit');
695
+ try {
696
+ while (true) {
697
+ const line = await rl.question('browser-use> ');
698
+ const task = line.trim();
699
+ if (!task) {
700
+ continue;
701
+ }
702
+ if (isInteractiveExitCommand(task)) {
703
+ break;
704
+ }
705
+ if (isInteractiveHelpCommand(task)) {
706
+ console.log('Type any task to run it. Use "exit" to quit.');
707
+ continue;
708
+ }
709
+ history.push(task);
710
+ await saveCliHistory(history, historyPath);
711
+ console.log(`Starting task: ${task}`);
712
+ try {
713
+ await runAgentTask({
714
+ task,
715
+ llm,
716
+ browserProfile,
717
+ browserSession,
718
+ sessionAttachmentMode: 'strict',
719
+ });
720
+ }
721
+ catch (error) {
722
+ console.error('Error running agent:', error);
723
+ }
724
+ }
725
+ }
726
+ finally {
727
+ rl.close();
728
+ await saveCliHistory(history, historyPath);
729
+ try {
730
+ if (browserSession._owns_browser_resources) {
731
+ await browserSession.kill();
732
+ }
733
+ else {
734
+ await browserSession.stop();
735
+ }
736
+ }
737
+ catch (error) {
738
+ console.error(`Warning: failed to close interactive browser session: ${error.message}`);
739
+ }
740
+ }
741
+ };
742
+ export const getCliUsage = () => `Usage:
743
+ browser-use # interactive mode (TTY)
744
+ browser-use <task>
745
+ browser-use -p "<task>"
746
+ browser-use [options] <task>
747
+ browser-use --mcp
748
+
749
+ Options:
750
+ -h, --help Show this help message
751
+ --version Print version and exit
752
+ --mcp Run as MCP server
753
+ --provider <name> Force provider (openai|anthropic|google|deepseek|groq|openrouter|azure|mistral|cerebras|vercel|oci|ollama|browser-use|aws|aws-anthropic)
754
+ --model <model> Set model (e.g., gpt-5-mini, claude-4-sonnet, gemini-2.5-pro)
755
+ -p, --prompt <task> Run a single task
756
+ --headless Run browser in headless mode
757
+ --allowed-domains <items> Comma-separated allowlist (e.g., example.com,*.example.org)
758
+ --window-width <px> Browser window width
759
+ --window-height <px> Browser window height
760
+ --user-data-dir <path> Chrome user data directory
761
+ --profile-directory <name> Chrome profile directory (Default, Profile 1, ...)
762
+ --proxy-url <url> Proxy server URL (e.g., http://proxy.example.com:8080)
763
+ --no-proxy <items> Comma-separated proxy bypass list
764
+ --proxy-username <value> Proxy username
765
+ --proxy-password <value> Proxy password
766
+ --cdp-url <url> Connect to an existing Chromium instance via CDP
767
+ --debug Enable debug logging`;
8
768
  async function runMcpServer() {
9
769
  const server = new MCPServer('browser-use', get_browser_use_version());
10
770
  await server.start();
@@ -16,23 +776,73 @@ async function runMcpServer() {
16
776
  process.once('SIGTERM', () => void shutdown());
17
777
  await new Promise(() => { });
18
778
  }
19
- async function main() {
20
- const args = process.argv.slice(2);
21
- if (args.includes('--mcp')) {
779
+ export async function main(argv = process.argv.slice(2)) {
780
+ let args;
781
+ try {
782
+ args = parseCliArgs(argv);
783
+ }
784
+ catch (error) {
785
+ console.error(error.message);
786
+ console.error(getCliUsage());
787
+ process.exit(1);
788
+ return;
789
+ }
790
+ if (args.help) {
791
+ console.log(getCliUsage());
792
+ return;
793
+ }
794
+ if (args.version) {
795
+ console.log(get_browser_use_version());
796
+ return;
797
+ }
798
+ if (args.debug) {
799
+ process.env.BROWSER_USE_LOGGING_LEVEL = 'debug';
800
+ setupLogging({ logLevel: 'debug', forceSetup: true });
801
+ }
802
+ if (args.mcp) {
22
803
  await runMcpServer();
23
804
  return;
24
805
  }
25
- if (args.length === 0 || args.includes('--help')) {
26
- console.log('Usage: browser-use <task>');
27
- console.log(' browser-use --mcp');
806
+ const task = resolveTask(args);
807
+ const shouldStartInteractive = shouldStartInteractiveMode(task);
808
+ if (!task && !shouldStartInteractive) {
809
+ console.error(getCliUsage());
28
810
  process.exit(1);
811
+ return;
812
+ }
813
+ let llm;
814
+ try {
815
+ llm = getLlmFromCliArgs(args);
816
+ }
817
+ catch (error) {
818
+ console.error(`Error selecting LLM: ${error.message}`);
819
+ process.exit(1);
820
+ return;
821
+ }
822
+ if (shouldStartInteractive) {
823
+ await runInteractiveMode(args, llm);
824
+ return;
825
+ }
826
+ if (!task) {
827
+ console.error(getCliUsage());
828
+ process.exit(1);
829
+ return;
29
830
  }
30
- const task = args.join(' ');
31
831
  console.log(`Starting task: ${task}`);
32
- const llm = new ChatOpenAI();
33
- const agent = new Agent({ task, llm });
832
+ const browserProfile = buildBrowserProfileFromCliArgs(args);
833
+ const browserSession = args.cdp_url
834
+ ? new BrowserSession({
835
+ browser_profile: browserProfile ?? undefined,
836
+ cdp_url: args.cdp_url,
837
+ })
838
+ : null;
34
839
  try {
35
- await agent.run();
840
+ await runAgentTask({
841
+ task,
842
+ llm,
843
+ browserProfile,
844
+ browserSession,
845
+ });
36
846
  }
37
847
  catch (error) {
38
848
  console.error('Error running agent:', error);