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
@@ -0,0 +1,104 @@
1
+ import { CodeAgentHistory, CodeAgentHistoryList, CodeAgentState, CodeAgentStepMetadata, NotebookSession, } from './views.js';
2
+ import { create_namespace } from './namespace.js';
3
+ const AsyncFunction = Object.getPrototypeOf(async function () {
4
+ return undefined;
5
+ }).constructor;
6
+ const default_executor = async (source, namespace) => {
7
+ const injectableNames = Object.keys(namespace).filter((name) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name));
8
+ const prelude = injectableNames
9
+ .map((name) => `const ${name} = namespace[${JSON.stringify(name)}];`)
10
+ .join('\n');
11
+ const runner = new AsyncFunction('namespace', `${prelude}\n${source}\nreturn undefined;`);
12
+ return runner(namespace);
13
+ };
14
+ export class CodeAgent {
15
+ task;
16
+ browser_session;
17
+ session;
18
+ namespace;
19
+ complete_history = [];
20
+ executor;
21
+ constructor(options) {
22
+ this.task = options.task;
23
+ this.browser_session = options.browser_session;
24
+ this.namespace = create_namespace(options.browser_session, options.namespace ? { namespace: options.namespace } : {});
25
+ this.session = new NotebookSession({ namespace: this.namespace });
26
+ this.executor = options.executor ?? default_executor;
27
+ }
28
+ add_cell(source) {
29
+ return this.session.add_cell(source);
30
+ }
31
+ async execute_cell(source) {
32
+ const cell = this.add_cell(source);
33
+ const startedAt = Date.now() / 1000;
34
+ cell.status = 'running';
35
+ cell.execution_count = this.session.increment_execution_count();
36
+ let resultItem;
37
+ try {
38
+ const output = await this.executor(cell.source, this.namespace);
39
+ cell.status = 'success';
40
+ cell.output =
41
+ output == null
42
+ ? null
43
+ : typeof output === 'string'
44
+ ? output
45
+ : JSON.stringify(output);
46
+ cell.error = null;
47
+ resultItem = {
48
+ extracted_content: cell.output,
49
+ error: null,
50
+ is_done: Boolean(this.namespace._task_done),
51
+ success: typeof this.namespace._task_success === 'boolean'
52
+ ? this.namespace._task_success
53
+ : null,
54
+ };
55
+ }
56
+ catch (error) {
57
+ cell.status = 'error';
58
+ cell.output = null;
59
+ cell.error = String(error?.message ?? error);
60
+ resultItem = {
61
+ extracted_content: null,
62
+ error: cell.error,
63
+ is_done: false,
64
+ success: false,
65
+ };
66
+ }
67
+ const page = await this.browser_session.get_current_page();
68
+ const state = new CodeAgentState({
69
+ url: typeof page?.url === 'function' ? page.url() : null,
70
+ title: typeof page?.title === 'function' ? await page.title() : null,
71
+ });
72
+ const metadata = new CodeAgentStepMetadata({
73
+ step_start_time: startedAt,
74
+ step_end_time: Date.now() / 1000,
75
+ });
76
+ const modelOutput = {
77
+ model_output: cell.source,
78
+ full_response: cell.source,
79
+ };
80
+ const historyItem = new CodeAgentHistory({
81
+ model_output: modelOutput,
82
+ result: [resultItem],
83
+ state,
84
+ metadata,
85
+ });
86
+ this.complete_history.push(historyItem);
87
+ this.session._complete_history = [...this.complete_history];
88
+ return cell;
89
+ }
90
+ async run(max_steps = 100) {
91
+ const pending = this.session.cells.filter((cell) => cell.status === 'pending');
92
+ const toRun = pending.slice(0, Math.max(max_steps, 0));
93
+ for (const cell of toRun) {
94
+ await this.execute_cell(cell.source);
95
+ }
96
+ return this.history;
97
+ }
98
+ get history() {
99
+ return new CodeAgentHistoryList(this.complete_history, null);
100
+ }
101
+ async close() {
102
+ // Keep lifecycle explicit; caller controls browser shutdown.
103
+ }
104
+ }
@@ -0,0 +1,4 @@
1
+ export declare const truncate_message_content: (content: string, max_length?: number) => string;
2
+ export declare const detect_token_limit_issue: (completion: string, completion_tokens: number | null, max_tokens: number | null, stop_reason: string | null) => [boolean, string | null];
3
+ export declare const extract_url_from_task: (task: string) => string | null;
4
+ export declare const extract_code_blocks: (text: string) => Record<string, string>;
@@ -0,0 +1,98 @@
1
+ export const truncate_message_content = (content, max_length = 10000) => {
2
+ if (content.length <= max_length) {
3
+ return content;
4
+ }
5
+ return `${content.slice(0, max_length)}\n\n[... truncated ${content.length - max_length} characters for history]`;
6
+ };
7
+ export const detect_token_limit_issue = (completion, completion_tokens, max_tokens, stop_reason) => {
8
+ if (stop_reason === 'max_tokens') {
9
+ return [true, `Response terminated due to max_tokens (${stop_reason})`];
10
+ }
11
+ if (completion_tokens != null &&
12
+ max_tokens != null &&
13
+ max_tokens > 0 &&
14
+ completion_tokens / max_tokens >= 0.9) {
15
+ return [
16
+ true,
17
+ `Response used ${(completion_tokens / max_tokens) * 100}% of max_tokens (${completion_tokens}/${max_tokens})`,
18
+ ];
19
+ }
20
+ if (completion.length >= 6) {
21
+ const last6 = completion.slice(-6);
22
+ const repeated = completion.split(last6).length - 1;
23
+ if (repeated >= 40) {
24
+ return [
25
+ true,
26
+ `Repetitive output detected: last 6 chars "${last6}" appears ${repeated} times`,
27
+ ];
28
+ }
29
+ }
30
+ return [false, null];
31
+ };
32
+ export const extract_url_from_task = (task) => {
33
+ const withoutEmails = task.replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g, '');
34
+ const matches = [];
35
+ const patterns = [
36
+ /https?:\/\/[^\s<>"']+/g,
37
+ /(?:www\.)?[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.[a-zA-Z]{2,}(?:\/[^\s<>"']*)?/g,
38
+ ];
39
+ for (const pattern of patterns) {
40
+ const found = withoutEmails.match(pattern) ?? [];
41
+ for (const entry of found) {
42
+ const trimmed = entry.replace(/[.,;:!?()[\]]+$/g, '');
43
+ matches.push(trimmed.startsWith('http://') || trimmed.startsWith('https://')
44
+ ? trimmed
45
+ : `https://${trimmed}`);
46
+ }
47
+ }
48
+ const unique = [...new Set(matches)];
49
+ if (unique.length !== 1) {
50
+ return null;
51
+ }
52
+ return unique[0];
53
+ };
54
+ export const extract_code_blocks = (text) => {
55
+ const blocks = {};
56
+ const regex = /(`{3,})(\w+)(?:\s+(\w+))?\n([\s\S]*?)\1(?:\n|$)/g;
57
+ let match;
58
+ let pythonIndex = 0;
59
+ while ((match = regex.exec(text)) != null) {
60
+ const langRaw = match[2].toLowerCase();
61
+ const name = match[3] ?? null;
62
+ const content = match[4].replace(/\s+$/, '');
63
+ if (!content) {
64
+ continue;
65
+ }
66
+ const lang = langRaw === 'javascript' || langRaw === 'js'
67
+ ? 'js'
68
+ : langRaw === 'markdown' || langRaw === 'md'
69
+ ? 'markdown'
70
+ : langRaw === 'sh' || langRaw === 'shell'
71
+ ? 'bash'
72
+ : langRaw;
73
+ if (!['python', 'js', 'bash', 'markdown'].includes(lang)) {
74
+ continue;
75
+ }
76
+ if (name) {
77
+ blocks[name] = content;
78
+ continue;
79
+ }
80
+ if (lang === 'python') {
81
+ blocks[`python_${pythonIndex}`] = content;
82
+ pythonIndex += 1;
83
+ continue;
84
+ }
85
+ blocks[lang] = content;
86
+ }
87
+ if (pythonIndex > 0) {
88
+ blocks.python = blocks.python_0;
89
+ }
90
+ else {
91
+ const genericMatches = [...text.matchAll(/```\n([\s\S]*?)```/g)].map((entry) => entry[1].trim());
92
+ const generic = genericMatches.filter(Boolean).join('\n\n');
93
+ if (generic) {
94
+ blocks.python = generic;
95
+ }
96
+ }
97
+ return blocks;
98
+ };
@@ -0,0 +1,108 @@
1
+ import type { UsageSummary } from '../tokens/views.js';
2
+ export type CellType = 'code' | 'markdown';
3
+ export type ExecutionStatus = 'pending' | 'running' | 'success' | 'error';
4
+ export interface CodeCellInit {
5
+ id?: string;
6
+ cell_type?: CellType;
7
+ source: string;
8
+ output?: string | null;
9
+ execution_count?: number | null;
10
+ status?: ExecutionStatus;
11
+ error?: string | null;
12
+ browser_state?: string | null;
13
+ }
14
+ export declare class CodeCell {
15
+ id: string;
16
+ cell_type: CellType;
17
+ source: string;
18
+ output: string | null;
19
+ execution_count: number | null;
20
+ status: ExecutionStatus;
21
+ error: string | null;
22
+ browser_state: string | null;
23
+ constructor(init: CodeCellInit);
24
+ }
25
+ export interface CodeAgentModelOutput {
26
+ model_output: string;
27
+ full_response: string;
28
+ }
29
+ export interface CodeAgentResult {
30
+ extracted_content?: string | null;
31
+ error?: string | null;
32
+ is_done: boolean;
33
+ success?: boolean | null;
34
+ }
35
+ export declare class CodeAgentState {
36
+ url: string | null;
37
+ title: string | null;
38
+ screenshot_path: string | null;
39
+ constructor(init: {
40
+ url?: string | null;
41
+ title?: string | null;
42
+ screenshot_path?: string | null;
43
+ });
44
+ get_screenshot(): string | null;
45
+ }
46
+ export declare class CodeAgentStepMetadata {
47
+ input_tokens: number | null;
48
+ output_tokens: number | null;
49
+ step_start_time: number;
50
+ step_end_time: number;
51
+ constructor(init: {
52
+ input_tokens?: number | null;
53
+ output_tokens?: number | null;
54
+ step_start_time: number;
55
+ step_end_time: number;
56
+ });
57
+ get duration_seconds(): number;
58
+ }
59
+ export declare class CodeAgentHistory {
60
+ model_output: CodeAgentModelOutput | null;
61
+ result: CodeAgentResult[];
62
+ state: CodeAgentState;
63
+ metadata: CodeAgentStepMetadata | null;
64
+ screenshot_path: string | null;
65
+ constructor(init: {
66
+ model_output?: CodeAgentModelOutput | null;
67
+ result?: CodeAgentResult[];
68
+ state: CodeAgentState;
69
+ metadata?: CodeAgentStepMetadata | null;
70
+ screenshot_path?: string | null;
71
+ });
72
+ }
73
+ export declare class CodeAgentHistoryList {
74
+ private readonly complete_history;
75
+ private readonly usage_summary;
76
+ constructor(complete_history: CodeAgentHistory[], usage_summary?: UsageSummary | null);
77
+ get history(): CodeAgentHistory[];
78
+ get usage(): UsageSummary | null;
79
+ final_result(): string | null;
80
+ is_done(): boolean;
81
+ is_successful(): boolean | null;
82
+ errors(): (string | null)[];
83
+ has_errors(): boolean;
84
+ urls(): (string | null)[];
85
+ action_results(): CodeAgentResult[];
86
+ extracted_content(): string[];
87
+ number_of_steps(): number;
88
+ total_duration_seconds(): number;
89
+ }
90
+ export declare class NotebookSession {
91
+ id: string;
92
+ cells: CodeCell[];
93
+ current_execution_count: number;
94
+ namespace: Record<string, unknown>;
95
+ _complete_history: CodeAgentHistory[];
96
+ _usage_summary: UsageSummary | null;
97
+ constructor(init?: {
98
+ id?: string;
99
+ cells?: CodeCell[];
100
+ current_execution_count?: number;
101
+ namespace?: Record<string, unknown>;
102
+ });
103
+ add_cell(source: string): CodeCell;
104
+ get_cell(cell_id: string): CodeCell | null;
105
+ get_latest_cell(): CodeCell;
106
+ increment_execution_count(): number;
107
+ get history(): CodeAgentHistoryList;
108
+ }
@@ -0,0 +1,165 @@
1
+ import fs from 'node:fs';
2
+ import { uuid7str } from '../utils.js';
3
+ export class CodeCell {
4
+ id;
5
+ cell_type;
6
+ source;
7
+ output;
8
+ execution_count;
9
+ status;
10
+ error;
11
+ browser_state;
12
+ constructor(init) {
13
+ this.id = init.id ?? uuid7str();
14
+ this.cell_type = init.cell_type ?? 'code';
15
+ this.source = init.source;
16
+ this.output = init.output ?? null;
17
+ this.execution_count = init.execution_count ?? null;
18
+ this.status = init.status ?? 'pending';
19
+ this.error = init.error ?? null;
20
+ this.browser_state = init.browser_state ?? null;
21
+ }
22
+ }
23
+ export class CodeAgentState {
24
+ url;
25
+ title;
26
+ screenshot_path;
27
+ constructor(init) {
28
+ this.url = init.url ?? null;
29
+ this.title = init.title ?? null;
30
+ this.screenshot_path = init.screenshot_path ?? null;
31
+ }
32
+ get_screenshot() {
33
+ if (!this.screenshot_path || !fs.existsSync(this.screenshot_path)) {
34
+ return null;
35
+ }
36
+ return Buffer.from(fs.readFileSync(this.screenshot_path)).toString('base64');
37
+ }
38
+ }
39
+ export class CodeAgentStepMetadata {
40
+ input_tokens;
41
+ output_tokens;
42
+ step_start_time;
43
+ step_end_time;
44
+ constructor(init) {
45
+ this.input_tokens = init.input_tokens ?? null;
46
+ this.output_tokens = init.output_tokens ?? null;
47
+ this.step_start_time = init.step_start_time;
48
+ this.step_end_time = init.step_end_time;
49
+ }
50
+ get duration_seconds() {
51
+ return this.step_end_time - this.step_start_time;
52
+ }
53
+ }
54
+ export class CodeAgentHistory {
55
+ model_output;
56
+ result;
57
+ state;
58
+ metadata;
59
+ screenshot_path;
60
+ constructor(init) {
61
+ this.model_output = init.model_output ?? null;
62
+ this.result = init.result ?? [];
63
+ this.state = init.state;
64
+ this.metadata = init.metadata ?? null;
65
+ this.screenshot_path = init.screenshot_path ?? null;
66
+ }
67
+ }
68
+ export class CodeAgentHistoryList {
69
+ complete_history;
70
+ usage_summary;
71
+ constructor(complete_history, usage_summary = null) {
72
+ this.complete_history = complete_history;
73
+ this.usage_summary = usage_summary;
74
+ }
75
+ get history() {
76
+ return this.complete_history;
77
+ }
78
+ get usage() {
79
+ return this.usage_summary;
80
+ }
81
+ final_result() {
82
+ const last = this.complete_history[this.complete_history.length - 1];
83
+ if (!last?.result?.length) {
84
+ return null;
85
+ }
86
+ return last.result[last.result.length - 1].extracted_content ?? null;
87
+ }
88
+ is_done() {
89
+ const last = this.complete_history[this.complete_history.length - 1];
90
+ if (!last?.result?.length) {
91
+ return false;
92
+ }
93
+ return Boolean(last.result[last.result.length - 1].is_done);
94
+ }
95
+ is_successful() {
96
+ const last = this.complete_history[this.complete_history.length - 1];
97
+ if (!last?.result?.length) {
98
+ return null;
99
+ }
100
+ const final = last.result[last.result.length - 1];
101
+ return final.is_done ? (final.success ?? null) : null;
102
+ }
103
+ errors() {
104
+ return this.complete_history.map((entry) => {
105
+ const withError = entry.result.find((result) => Boolean(result.error));
106
+ return withError?.error ?? null;
107
+ });
108
+ }
109
+ has_errors() {
110
+ return this.errors().some((error) => Boolean(error));
111
+ }
112
+ urls() {
113
+ return this.complete_history.map((entry) => entry.state.url);
114
+ }
115
+ action_results() {
116
+ return this.complete_history.flatMap((entry) => entry.result);
117
+ }
118
+ extracted_content() {
119
+ return this.action_results()
120
+ .map((entry) => entry.extracted_content ?? null)
121
+ .filter((entry) => typeof entry === 'string');
122
+ }
123
+ number_of_steps() {
124
+ return this.complete_history.length;
125
+ }
126
+ total_duration_seconds() {
127
+ return this.complete_history.reduce((sum, entry) => {
128
+ return sum + (entry.metadata?.duration_seconds ?? 0);
129
+ }, 0);
130
+ }
131
+ }
132
+ export class NotebookSession {
133
+ id;
134
+ cells;
135
+ current_execution_count;
136
+ namespace;
137
+ _complete_history;
138
+ _usage_summary;
139
+ constructor(init = {}) {
140
+ this.id = init.id ?? uuid7str();
141
+ this.cells = init.cells ?? [];
142
+ this.current_execution_count = init.current_execution_count ?? 0;
143
+ this.namespace = init.namespace ?? {};
144
+ this._complete_history = [];
145
+ this._usage_summary = null;
146
+ }
147
+ add_cell(source) {
148
+ const cell = new CodeCell({ source });
149
+ this.cells.push(cell);
150
+ return cell;
151
+ }
152
+ get_cell(cell_id) {
153
+ return this.cells.find((cell) => cell.id === cell_id) ?? null;
154
+ }
155
+ get_latest_cell() {
156
+ return this.cells[this.cells.length - 1] ?? null;
157
+ }
158
+ increment_execution_count() {
159
+ this.current_execution_count += 1;
160
+ return this.current_execution_count;
161
+ }
162
+ get history() {
163
+ return new CodeAgentHistoryList(this._complete_history, this._usage_summary);
164
+ }
165
+ }
package/dist/config.d.ts CHANGED
@@ -6,6 +6,8 @@ declare class OldConfig {
6
6
  get BROWSER_USE_CLOUD_SYNC(): boolean;
7
7
  get BROWSER_USE_CLOUD_API_URL(): string;
8
8
  get BROWSER_USE_CLOUD_UI_URL(): string;
9
+ get BROWSER_USE_DEBUG_LOG_FILE(): string | null;
10
+ get BROWSER_USE_INFO_LOG_FILE(): string | null;
9
11
  get XDG_CACHE_HOME(): string;
10
12
  get XDG_CONFIG_HOME(): string;
11
13
  get BROWSER_USE_CONFIG_DIR(): string;
@@ -22,8 +24,10 @@ declare class OldConfig {
22
24
  get AZURE_OPENAI_ENDPOINT(): string;
23
25
  get AZURE_OPENAI_KEY(): string;
24
26
  get SKIP_LLM_API_KEY_VERIFICATION(): boolean;
27
+ get DEFAULT_LLM(): string;
25
28
  get IN_DOCKER(): boolean;
26
29
  get IS_IN_EVALS(): boolean;
30
+ get BROWSER_USE_VERSION_CHECK(): boolean;
27
31
  get WIN_FONT_DIR(): string;
28
32
  _ensure_dirs(base_dir?: string): void;
29
33
  }
@@ -33,6 +37,8 @@ declare class FlatEnvConfig {
33
37
  get BROWSER_USE_CLOUD_SYNC(): boolean | null;
34
38
  get BROWSER_USE_CLOUD_API_URL(): string;
35
39
  get BROWSER_USE_CLOUD_UI_URL(): string;
40
+ get BROWSER_USE_DEBUG_LOG_FILE(): string | null;
41
+ get BROWSER_USE_INFO_LOG_FILE(): string | null;
36
42
  get XDG_CACHE_HOME(): string;
37
43
  get XDG_CONFIG_HOME(): string;
38
44
  get BROWSER_USE_CONFIG_DIR(): string | null;
@@ -45,13 +51,20 @@ declare class FlatEnvConfig {
45
51
  get AZURE_OPENAI_ENDPOINT(): string;
46
52
  get AZURE_OPENAI_KEY(): string;
47
53
  get SKIP_LLM_API_KEY_VERIFICATION(): boolean;
54
+ get DEFAULT_LLM(): string;
48
55
  get IN_DOCKER(): boolean | null;
49
56
  get IS_IN_EVALS(): boolean;
57
+ get BROWSER_USE_VERSION_CHECK(): boolean;
50
58
  get WIN_FONT_DIR(): string;
51
59
  get BROWSER_USE_CONFIG_PATH(): string | null;
52
60
  get BROWSER_USE_HEADLESS(): boolean | null;
53
61
  get BROWSER_USE_ALLOWED_DOMAINS(): string | null;
54
62
  get BROWSER_USE_LLM_MODEL(): string | null;
63
+ get BROWSER_USE_PROXY_URL(): string | null;
64
+ get BROWSER_USE_NO_PROXY(): string | null;
65
+ get BROWSER_USE_PROXY_USERNAME(): string | null;
66
+ get BROWSER_USE_PROXY_PASSWORD(): string | null;
67
+ get BROWSER_USE_DISABLE_EXTENSIONS(): boolean | null;
55
68
  }
56
69
  interface DBStyleEntry {
57
70
  id: string;
package/dist/config.js CHANGED
@@ -92,6 +92,12 @@ class OldConfig {
92
92
  }
93
93
  return url;
94
94
  }
95
+ get BROWSER_USE_DEBUG_LOG_FILE() {
96
+ return process.env.BROWSER_USE_DEBUG_LOG_FILE ?? null;
97
+ }
98
+ get BROWSER_USE_INFO_LOG_FILE() {
99
+ return process.env.BROWSER_USE_INFO_LOG_FILE ?? null;
100
+ }
95
101
  get XDG_CACHE_HOME() {
96
102
  return resolve_path(process.env.XDG_CACHE_HOME ?? '~/.cache');
97
103
  }
@@ -149,12 +155,18 @@ class OldConfig {
149
155
  get SKIP_LLM_API_KEY_VERIFICATION() {
150
156
  return string_to_bool(process.env.SKIP_LLM_API_KEY_VERIFICATION, false);
151
157
  }
158
+ get DEFAULT_LLM() {
159
+ return process.env.DEFAULT_LLM ?? '';
160
+ }
152
161
  get IN_DOCKER() {
153
162
  return (string_to_bool(process.env.IN_DOCKER, false) || is_running_in_docker());
154
163
  }
155
164
  get IS_IN_EVALS() {
156
165
  return string_to_bool(process.env.IS_IN_EVALS, false);
157
166
  }
167
+ get BROWSER_USE_VERSION_CHECK() {
168
+ return string_to_bool(process.env.BROWSER_USE_VERSION_CHECK, true);
169
+ }
158
170
  get WIN_FONT_DIR() {
159
171
  return process.env.WIN_FONT_DIR ?? 'C:\\Windows\\Fonts';
160
172
  }
@@ -188,6 +200,12 @@ class FlatEnvConfig {
188
200
  get BROWSER_USE_CLOUD_UI_URL() {
189
201
  return process.env.BROWSER_USE_CLOUD_UI_URL ?? '';
190
202
  }
203
+ get BROWSER_USE_DEBUG_LOG_FILE() {
204
+ return process.env.BROWSER_USE_DEBUG_LOG_FILE ?? null;
205
+ }
206
+ get BROWSER_USE_INFO_LOG_FILE() {
207
+ return process.env.BROWSER_USE_INFO_LOG_FILE ?? null;
208
+ }
191
209
  get XDG_CACHE_HOME() {
192
210
  return resolve_path(process.env.XDG_CACHE_HOME ?? '~/.cache');
193
211
  }
@@ -226,6 +244,9 @@ class FlatEnvConfig {
226
244
  get SKIP_LLM_API_KEY_VERIFICATION() {
227
245
  return string_to_bool(process.env.SKIP_LLM_API_KEY_VERIFICATION, false);
228
246
  }
247
+ get DEFAULT_LLM() {
248
+ return process.env.DEFAULT_LLM ?? '';
249
+ }
229
250
  get IN_DOCKER() {
230
251
  const value = process.env.IN_DOCKER;
231
252
  return value === undefined ? null : string_to_bool(value);
@@ -233,6 +254,9 @@ class FlatEnvConfig {
233
254
  get IS_IN_EVALS() {
234
255
  return string_to_bool(process.env.IS_IN_EVALS, false);
235
256
  }
257
+ get BROWSER_USE_VERSION_CHECK() {
258
+ return string_to_bool(process.env.BROWSER_USE_VERSION_CHECK, true);
259
+ }
236
260
  get WIN_FONT_DIR() {
237
261
  return process.env.WIN_FONT_DIR ?? 'C:\\Windows\\Fonts';
238
262
  }
@@ -251,9 +275,25 @@ class FlatEnvConfig {
251
275
  get BROWSER_USE_LLM_MODEL() {
252
276
  return process.env.BROWSER_USE_LLM_MODEL ?? null;
253
277
  }
278
+ get BROWSER_USE_PROXY_URL() {
279
+ return process.env.BROWSER_USE_PROXY_URL ?? null;
280
+ }
281
+ get BROWSER_USE_NO_PROXY() {
282
+ return process.env.BROWSER_USE_NO_PROXY ?? null;
283
+ }
284
+ get BROWSER_USE_PROXY_USERNAME() {
285
+ return process.env.BROWSER_USE_PROXY_USERNAME ?? null;
286
+ }
287
+ get BROWSER_USE_PROXY_PASSWORD() {
288
+ return process.env.BROWSER_USE_PROXY_PASSWORD ?? null;
289
+ }
290
+ get BROWSER_USE_DISABLE_EXTENSIONS() {
291
+ const value = process.env.BROWSER_USE_DISABLE_EXTENSIONS;
292
+ return value === undefined ? null : string_to_bool(value);
293
+ }
254
294
  }
255
295
  const create_default_config = () => {
256
- logger.info('Creating fresh default config.json');
296
+ logger.debug('Creating fresh default config.json');
257
297
  const profile_id = randomUUID();
258
298
  const llm_id = randomUUID();
259
299
  const agent_id = randomUUID();
@@ -274,7 +314,7 @@ const create_default_config = () => {
274
314
  id: llm_id,
275
315
  default: true,
276
316
  created_at: new Date().toISOString(),
277
- model: 'gpt-4o',
317
+ model: 'gpt-4.1-mini',
278
318
  api_key: 'your-openai-api-key-here',
279
319
  temperature: null,
280
320
  max_tokens: null,
@@ -309,7 +349,7 @@ const load_and_migrate_config = (config_path) => {
309
349
  if (looks_like_new_format(raw)) {
310
350
  return raw;
311
351
  }
312
- logger.info(`Old config format detected at ${config_path}, creating fresh config`);
352
+ logger.debug(`Old config format detected at ${config_path}, creating fresh config`);
313
353
  const fresh = create_default_config();
314
354
  fs.writeFileSync(config_path, JSON.stringify(fresh, null, 2), 'utf-8');
315
355
  return fresh;
@@ -374,12 +414,38 @@ class ConfigCore {
374
414
  .map((domain) => domain.trim())
375
415
  .filter(Boolean);
376
416
  }
417
+ const proxy = {};
418
+ if (env.BROWSER_USE_PROXY_URL) {
419
+ proxy.server = env.BROWSER_USE_PROXY_URL;
420
+ }
421
+ if (env.BROWSER_USE_NO_PROXY) {
422
+ proxy.bypass = env.BROWSER_USE_NO_PROXY.split(',')
423
+ .map((domain) => domain.trim())
424
+ .filter(Boolean)
425
+ .join(',');
426
+ }
427
+ if (env.BROWSER_USE_PROXY_USERNAME) {
428
+ proxy.username = env.BROWSER_USE_PROXY_USERNAME;
429
+ }
430
+ if (env.BROWSER_USE_PROXY_PASSWORD) {
431
+ proxy.password = env.BROWSER_USE_PROXY_PASSWORD;
432
+ }
433
+ if (Object.keys(proxy).length > 0) {
434
+ config.browser_profile.proxy = proxy;
435
+ }
377
436
  if (env.OPENAI_API_KEY) {
378
437
  config.llm.api_key = env.OPENAI_API_KEY;
379
438
  }
439
+ if (env.DEFAULT_LLM) {
440
+ config.llm.model = env.DEFAULT_LLM;
441
+ }
380
442
  if (env.BROWSER_USE_LLM_MODEL) {
381
443
  config.llm.model = env.BROWSER_USE_LLM_MODEL;
382
444
  }
445
+ if (env.BROWSER_USE_DISABLE_EXTENSIONS !== null) {
446
+ config.browser_profile.enable_default_extensions =
447
+ !env.BROWSER_USE_DISABLE_EXTENSIONS;
448
+ }
383
449
  return config;
384
450
  }
385
451
  _ensure_dirs() {