browser-use 0.6.1 → 0.7.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 (82) hide show
  1. package/README.md +24 -18
  2. package/dist/actor/element.js +24 -3
  3. package/dist/actor/mouse.js +21 -3
  4. package/dist/actor/page.js +33 -11
  5. package/dist/agent/gif.js +28 -3
  6. package/dist/agent/message-manager/service.js +2 -22
  7. package/dist/agent/message-manager/utils.js +15 -2
  8. package/dist/agent/message-manager/views.d.ts +7 -7
  9. package/dist/agent/message-manager/views.js +1 -0
  10. package/dist/agent/prompts.d.ts +3 -0
  11. package/dist/agent/prompts.js +22 -12
  12. package/dist/agent/service.d.ts +9 -1
  13. package/dist/agent/service.js +204 -79
  14. package/dist/agent/system_prompt.md +12 -11
  15. package/dist/agent/system_prompt_anthropic_flash.md +6 -5
  16. package/dist/agent/system_prompt_no_thinking.md +12 -11
  17. package/dist/agent/views.d.ts +2 -0
  18. package/dist/agent/views.js +48 -36
  19. package/dist/browser/extensions.js +20 -10
  20. package/dist/browser/profile.d.ts +4 -0
  21. package/dist/browser/profile.js +107 -4
  22. package/dist/browser/session.d.ts +28 -1
  23. package/dist/browser/session.js +1436 -528
  24. package/dist/browser/watchdogs/default-action-watchdog.js +32 -3
  25. package/dist/browser/watchdogs/downloads-watchdog.d.ts +4 -0
  26. package/dist/browser/watchdogs/downloads-watchdog.js +105 -9
  27. package/dist/browser/watchdogs/har-recording-watchdog.d.ts +1 -0
  28. package/dist/browser/watchdogs/har-recording-watchdog.js +54 -2
  29. package/dist/browser/watchdogs/permissions-watchdog.d.ts +5 -0
  30. package/dist/browser/watchdogs/permissions-watchdog.js +106 -3
  31. package/dist/browser/watchdogs/recording-watchdog.d.ts +2 -0
  32. package/dist/browser/watchdogs/recording-watchdog.js +54 -2
  33. package/dist/browser/watchdogs/security-watchdog.d.ts +1 -0
  34. package/dist/browser/watchdogs/security-watchdog.js +47 -7
  35. package/dist/browser/watchdogs/storage-state-watchdog.d.ts +6 -0
  36. package/dist/browser/watchdogs/storage-state-watchdog.js +206 -14
  37. package/dist/cli.d.ts +13 -2
  38. package/dist/cli.js +187 -7
  39. package/dist/code-use/namespace.js +52 -7
  40. package/dist/code-use/notebook-export.js +18 -2
  41. package/dist/code-use/service.js +1 -0
  42. package/dist/config.js +26 -4
  43. package/dist/controller/action-timeout.d.ts +9 -0
  44. package/dist/controller/action-timeout.js +95 -0
  45. package/dist/controller/registry/service.d.ts +1 -0
  46. package/dist/controller/registry/service.js +28 -1
  47. package/dist/controller/service.d.ts +2 -1
  48. package/dist/controller/service.js +494 -329
  49. package/dist/filesystem/file-system.js +38 -8
  50. package/dist/integrations/gmail/service.js +30 -6
  51. package/dist/llm/browser-use/chat.js +2 -2
  52. package/dist/llm/codex/auth.d.ts +118 -0
  53. package/dist/llm/codex/auth.js +599 -0
  54. package/dist/llm/codex/chat.d.ts +70 -0
  55. package/dist/llm/codex/chat.js +392 -0
  56. package/dist/llm/codex/index.d.ts +2 -0
  57. package/dist/llm/codex/index.js +2 -0
  58. package/dist/llm/google/chat.js +18 -1
  59. package/dist/logging-config.js +22 -11
  60. package/dist/mcp/client.d.ts +1 -0
  61. package/dist/mcp/client.js +12 -10
  62. package/dist/mcp/redaction.d.ts +3 -0
  63. package/dist/mcp/redaction.js +132 -0
  64. package/dist/mcp/server.d.ts +2 -0
  65. package/dist/mcp/server.js +64 -22
  66. package/dist/screenshots/service.js +25 -2
  67. package/dist/skill-cli/direct.d.ts +4 -1
  68. package/dist/skill-cli/direct.js +260 -64
  69. package/dist/skill-cli/server.d.ts +1 -0
  70. package/dist/skill-cli/server.js +115 -25
  71. package/dist/skill-cli/tunnel.d.ts +1 -0
  72. package/dist/skill-cli/tunnel.js +16 -4
  73. package/dist/sync/auth.js +22 -9
  74. package/dist/telemetry/service.js +21 -2
  75. package/dist/telemetry/views.js +31 -8
  76. package/dist/tokens/custom-pricing.js +2 -2
  77. package/dist/tokens/openrouter-pricing.d.ts +11 -0
  78. package/dist/tokens/openrouter-pricing.js +102 -0
  79. package/dist/tokens/service.js +20 -16
  80. package/dist/utils.d.ts +3 -1
  81. package/dist/utils.js +3 -1
  82. package/package.json +68 -27
package/README.md CHANGED
@@ -125,23 +125,24 @@ npx browser-use --mcp
125
125
 
126
126
  ## 🔌 LLM Providers
127
127
 
128
- | Provider | Import | Vision | Notes |
129
- | ----------------- | ----------------------------- | ------ | --------------------------------------------- |
130
- | **OpenAI** | `browser-use/llm/openai` | ✅ | Default provider, reasoning models (o1/o3/o4) |
131
- | **Anthropic** | `browser-use/llm/anthropic` | ✅ | Prompt caching support |
132
- | **Google Gemini** | `browser-use/llm/google` | ✅ | Extended thinking support |
133
- | **Azure OpenAI** | `browser-use/llm/azure` | ✅ | Enterprise deployment |
134
- | **AWS Bedrock** | `browser-use/llm/aws` | ✅ | Claude via AWS |
135
- | **Groq** | `browser-use/llm/groq` | | Fastest inference |
136
- | **Ollama** | `browser-use/llm/ollama` | ❌ | Local/self-hosted models |
137
- | **DeepSeek** | `browser-use/llm/deepseek` | ❌ | Cost-effective |
138
- | **OpenRouter** | `browser-use/llm/openrouter` | Varies | Multi-model routing |
139
- | **Mistral** | `browser-use/llm/mistral` | Varies | Mistral models |
140
- | **Cerebras** | `browser-use/llm/cerebras` | | Fast inference |
141
- | **Browser Use** | `browser-use/llm/browser-use` | Varies | Hosted Browser Use LLM |
142
- | **LiteLLM** | `browser-use/llm/litellm` | Varies | OpenAI-compatible LiteLLM gateway |
143
- | **OCI Raw** | `browser-use/llm/oci-raw` | Varies | Oracle Cloud Generative AI |
144
- | **Vercel** | `browser-use/llm/vercel` | Varies | Vercel AI Gateway / routed models |
128
+ | Provider | Import | Vision | Notes |
129
+ | ----------------- | ----------------------------- | ------ | ----------------------------------------------- |
130
+ | **OpenAI** | `browser-use/llm/openai` | ✅ | Default provider, reasoning models (o1/o3/o4) |
131
+ | **Codex** | `browser-use/llm/codex` | ✅ | Experimental ChatGPT/Codex OAuth provider |
132
+ | **Anthropic** | `browser-use/llm/anthropic` | ✅ | Prompt caching support |
133
+ | **Google Gemini** | `browser-use/llm/google` | ✅ | Extended thinking support |
134
+ | **Azure OpenAI** | `browser-use/llm/azure` | ✅ | Enterprise deployment |
135
+ | **AWS Bedrock** | `browser-use/llm/aws` | | Claude via AWS |
136
+ | **Groq** | `browser-use/llm/groq` | ❌ | Fastest inference |
137
+ | **Ollama** | `browser-use/llm/ollama` | ❌ | Local/self-hosted models |
138
+ | **DeepSeek** | `browser-use/llm/deepseek` | | Cost-effective |
139
+ | **OpenRouter** | `browser-use/llm/openrouter` | Varies | Multi-model routing |
140
+ | **Mistral** | `browser-use/llm/mistral` | Varies | Mistral models |
141
+ | **Cerebras** | `browser-use/llm/cerebras` | | Fast inference |
142
+ | **Browser Use** | `browser-use/llm/browser-use` | Varies | Hosted Browser Use LLM |
143
+ | **LiteLLM** | `browser-use/llm/litellm` | Varies | OpenAI-compatible LiteLLM gateway |
144
+ | **OCI Raw** | `browser-use/llm/oci-raw` | Varies | Oracle Cloud Generative AI |
145
+ | **Vercel** | `browser-use/llm/vercel` | Varies | Vercel AI Gateway / routed models |
145
146
 
146
147
  <details>
147
148
  <summary>Provider examples</summary>
@@ -171,6 +172,11 @@ const llm = new ChatOllama('llama3', 'http://localhost:11434');
171
172
 
172
173
  // OpenAI Reasoning Models
173
174
  const llm = new ChatOpenAI({ model: 'o3-mini', reasoningEffort: 'medium' });
175
+
176
+ // Codex OAuth provider (experimental)
177
+ // First run: npx browser-use auth codex login
178
+ import { ChatCodex } from 'browser-use/llm/codex';
179
+ const codexLlm = new ChatCodex({ model: 'gpt-5.5' });
174
180
  ```
175
181
 
176
182
  </details>
@@ -359,7 +365,7 @@ Core MCP tools include `retry_with_browser_use_agent`, `browser_navigate`, `brow
359
365
  - **Sensitive Data Masking** — Credentials are automatically masked in logs and LLM context
360
366
  - **Domain Restrictions** — Lock browser navigation to trusted domains
361
367
  - **Domain-scoped Secrets** — Credentials are only injected on matching domains
362
- - **Hard Safety Gate** — `sensitive_data` requires `allowed_domains` by default
368
+ - **Sensitive Data Warning** — Browser-Use warns when `sensitive_data` is used without `allowed_domains`
363
369
  - **Chromium Sandbox** — Enabled by default for production security
364
370
 
365
371
  ```typescript
@@ -18,7 +18,14 @@ export class Element {
18
18
  if (!locator?.hover) {
19
19
  return;
20
20
  }
21
- await locator.hover({ timeout: 5000 });
21
+ const page = await this.browser_session.get_current_page();
22
+ await this.browser_session.validate_page_after_action(page);
23
+ try {
24
+ await locator.hover({ timeout: 5000 });
25
+ }
26
+ finally {
27
+ await this.browser_session.validate_page_after_action(page);
28
+ }
22
29
  }
23
30
  async get_attribute(name) {
24
31
  return this.node.attributes?.[name] ?? null;
@@ -28,7 +35,14 @@ export class Element {
28
35
  if (!locator?.boundingBox) {
29
36
  return null;
30
37
  }
31
- return locator.boundingBox();
38
+ const page = await this.browser_session.get_current_page();
39
+ await this.browser_session.validate_page_after_action(page);
40
+ try {
41
+ return await locator.boundingBox();
42
+ }
43
+ finally {
44
+ await this.browser_session.validate_page_after_action(page);
45
+ }
32
46
  }
33
47
  async select_option(values) {
34
48
  const list = Array.isArray(values) ? values : [values];
@@ -41,6 +55,13 @@ export class Element {
41
55
  if (!locator?.evaluate) {
42
56
  throw new Error('Element evaluate is unavailable for this node');
43
57
  }
44
- return locator.evaluate(page_function, ...args);
58
+ const page = await this.browser_session.get_current_page();
59
+ await this.browser_session.validate_page_after_action(page);
60
+ try {
61
+ return await locator.evaluate(page_function, ...args);
62
+ }
63
+ finally {
64
+ await this.browser_session.validate_page_after_action(page);
65
+ }
45
66
  }
46
67
  }
@@ -20,20 +20,38 @@ export class Mouse {
20
20
  if (!page?.mouse?.move) {
21
21
  return;
22
22
  }
23
- await page.mouse.move(x, y);
23
+ await this.browser_session.validate_page_after_action(page);
24
+ try {
25
+ await page.mouse.move(x, y);
26
+ }
27
+ finally {
28
+ await this.browser_session.validate_page_after_action(page);
29
+ }
24
30
  }
25
31
  async down(options = {}) {
26
32
  const page = await this._page();
27
33
  if (!page?.mouse?.down) {
28
34
  return;
29
35
  }
30
- await page.mouse.down({ button: options.button ?? 'left' });
36
+ await this.browser_session.validate_page_after_action(page);
37
+ try {
38
+ await page.mouse.down({ button: options.button ?? 'left' });
39
+ }
40
+ finally {
41
+ await this.browser_session.validate_page_after_action(page);
42
+ }
31
43
  }
32
44
  async up(options = {}) {
33
45
  const page = await this._page();
34
46
  if (!page?.mouse?.up) {
35
47
  return;
36
48
  }
37
- await page.mouse.up({ button: options.button ?? 'left' });
49
+ await this.browser_session.validate_page_after_action(page);
50
+ try {
51
+ await page.mouse.up({ button: options.button ?? 'left' });
52
+ }
53
+ finally {
54
+ await this.browser_session.validate_page_after_action(page);
55
+ }
38
56
  }
39
57
  }
@@ -1,5 +1,6 @@
1
1
  import { Element } from './element.js';
2
2
  import { Mouse } from './mouse.js';
3
+ const buildExpression = (source, args) => `(${source})(${args.map((arg) => JSON.stringify(arg)).join(',')})`;
3
4
  export class Page {
4
5
  browser_session;
5
6
  _mouse = null;
@@ -21,11 +22,23 @@ export class Page {
21
22
  }
22
23
  async get_url() {
23
24
  const page = await this._currentPage();
24
- return typeof page.url === 'function' ? page.url() : '';
25
+ await this.browser_session.validate_page_after_action(page);
26
+ try {
27
+ return typeof page.url === 'function' ? page.url() : '';
28
+ }
29
+ finally {
30
+ await this.browser_session.validate_page_after_action(page);
31
+ }
25
32
  }
26
33
  async get_title() {
27
34
  const page = await this._currentPage();
28
- return typeof page.title === 'function' ? page.title() : '';
35
+ await this.browser_session.validate_page_after_action(page);
36
+ try {
37
+ return typeof page.title === 'function' ? page.title() : '';
38
+ }
39
+ finally {
40
+ await this.browser_session.validate_page_after_action(page);
41
+ }
29
42
  }
30
43
  async goto(url, options = {}) {
31
44
  await this.browser_session.navigate_to(url, {
@@ -47,16 +60,19 @@ export class Page {
47
60
  }
48
61
  async evaluate(page_function, ...args) {
49
62
  const page = await this._currentPage();
50
- if (typeof page_function === 'function') {
51
- return page.evaluate(page_function, ...args);
63
+ await this.browser_session.validate_page_after_action(page);
64
+ try {
65
+ if (typeof page_function === 'function') {
66
+ return await page.evaluate(page_function, ...args);
67
+ }
68
+ if (args.length === 0) {
69
+ return await page.evaluate(page_function);
70
+ }
71
+ return await page.evaluate(buildExpression(page_function, args));
52
72
  }
53
- if (args.length === 0) {
54
- return page.evaluate(page_function);
73
+ finally {
74
+ await this.browser_session.validate_page_after_action(page);
55
75
  }
56
- const expression = `(${page_function})(${args
57
- .map((arg) => JSON.stringify(arg))
58
- .join(',')})`;
59
- return page.evaluate(expression);
60
76
  }
61
77
  async screenshot(options = {}) {
62
78
  return this.browser_session.take_screenshot(options.full_page ?? false);
@@ -69,7 +85,13 @@ export class Page {
69
85
  if (!page.setViewportSize) {
70
86
  return;
71
87
  }
72
- await page.setViewportSize({ width, height });
88
+ await this.browser_session.validate_page_after_action(page);
89
+ try {
90
+ await page.setViewportSize({ width, height });
91
+ }
92
+ finally {
93
+ await this.browser_session.validate_page_after_action(page);
94
+ }
73
95
  }
74
96
  async get_element_by_index(index) {
75
97
  const node = await this.browser_session.get_dom_element_by_index(index);
package/dist/agent/gif.js CHANGED
@@ -6,6 +6,29 @@ import { createLogger } from '../logging-config.js';
6
6
  import { PLACEHOLDER_4PX_SCREENSHOT } from '../browser/views.js';
7
7
  import { is_new_tab_page } from '../utils.js';
8
8
  const logger = createLogger('browser_use.agent.gif');
9
+ const chmodPrivateFile = (filePath) => {
10
+ if (process.platform === 'win32') {
11
+ return;
12
+ }
13
+ try {
14
+ fs.chmodSync(filePath, 0o600);
15
+ }
16
+ catch {
17
+ /* best effort */
18
+ }
19
+ };
20
+ const ensurePrivateDirectoryIfCreated = async (dirPath) => {
21
+ const existed = fs.existsSync(dirPath);
22
+ await fs.promises.mkdir(dirPath, { recursive: true, mode: 0o700 });
23
+ if (!existed && process.platform !== 'win32') {
24
+ try {
25
+ await fs.promises.chmod(dirPath, 0o700);
26
+ }
27
+ catch {
28
+ /* best effort */
29
+ }
30
+ }
31
+ };
9
32
  export const decode_unicode_escapes_to_utf8 = (text) => {
10
33
  if (!text.includes('\\u')) {
11
34
  return text;
@@ -186,10 +209,11 @@ export const create_history_gif = async (task, history, { output_path = 'agent_h
186
209
  const canvas = createCanvas(width, height);
187
210
  const ctx = canvas.getContext('2d');
188
211
  const encoder = new GIFEncoder(width, height);
189
- await fs.promises.mkdir(path.dirname(path.resolve(output_path)), {
190
- recursive: true,
212
+ const resolvedOutputPath = path.resolve(output_path);
213
+ await ensurePrivateDirectoryIfCreated(path.dirname(resolvedOutputPath));
214
+ const writeStream = fs.createWriteStream(resolvedOutputPath, {
215
+ mode: 0o600,
191
216
  });
192
- const writeStream = fs.createWriteStream(path.resolve(output_path));
193
217
  encoder.createReadStream().pipe(writeStream);
194
218
  encoder.start();
195
219
  encoder.setRepeat(0);
@@ -233,5 +257,6 @@ export const create_history_gif = async (task, history, { output_path = 'agent_h
233
257
  writeStream.on('finish', resolve);
234
258
  writeStream.on('error', reject);
235
259
  });
260
+ chmodPrivateFile(resolvedOutputPath);
236
261
  logger.info(`Created GIF at ${output_path}`);
237
262
  };
@@ -1,4 +1,5 @@
1
1
  import { ContentPartTextParam, SystemMessage, UserMessage, } from '../../llm/messages.js';
2
+ import { redactSensitiveDataFromString, } from '../views.js';
2
3
  import { AgentMessagePrompt } from '../prompts.js';
3
4
  import { MessageManagerState, HistoryItem } from './views.js';
4
5
  import { match_url_with_domain_pattern } from '../../utils.js';
@@ -336,28 +337,7 @@ export class MessageManager {
336
337
  if (!this.sensitiveData) {
337
338
  return message;
338
339
  }
339
- const replaceSensitive = (value) => {
340
- const placeholders = {};
341
- for (const [keyOrDomain, content] of Object.entries(this.sensitiveData)) {
342
- if (content && typeof content === 'object' && !Array.isArray(content)) {
343
- for (const [k, v] of Object.entries(content)) {
344
- if (v)
345
- placeholders[k] = v;
346
- }
347
- }
348
- else if (typeof content === 'string') {
349
- placeholders[keyOrDomain] = content;
350
- }
351
- }
352
- if (!Object.keys(placeholders).length) {
353
- return value;
354
- }
355
- let updated = value;
356
- for (const [key, val] of Object.entries(placeholders)) {
357
- updated = updated.replaceAll(val, `<secret>${key}</secret>`);
358
- }
359
- return updated;
360
- };
340
+ const replaceSensitive = (value) => redactSensitiveDataFromString(value, this.sensitiveData ?? null);
361
341
  if (typeof message.content === 'string') {
362
342
  message.content = replaceSensitive(message.content);
363
343
  }
@@ -1,5 +1,17 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ const chmodPrivateFile = (filePath) => {
4
+ if (process.platform !== 'win32') {
5
+ fs.chmodSync(filePath, 0o600);
6
+ }
7
+ };
8
+ const ensurePrivateDirectoryIfCreated = async (dirPath) => {
9
+ const existed = fs.existsSync(dirPath);
10
+ await fs.promises.mkdir(dirPath, { recursive: true, mode: 0o700 });
11
+ if (!existed && process.platform !== 'win32') {
12
+ await fs.promises.chmod(dirPath, 0o700);
13
+ }
14
+ };
3
15
  const serializeResponse = (response) => {
4
16
  if (!response) {
5
17
  return '';
@@ -34,7 +46,8 @@ const formatConversation = (messages, response) => {
34
46
  };
35
47
  export const saveConversation = async (inputMessages, response, target, encoding = 'utf-8') => {
36
48
  const targetPath = path.resolve(target);
37
- await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });
49
+ await ensurePrivateDirectoryIfCreated(path.dirname(targetPath));
38
50
  const payload = formatConversation(inputMessages, response);
39
- await fs.promises.writeFile(targetPath, payload, { encoding });
51
+ await fs.promises.writeFile(targetPath, payload, { encoding, mode: 0o600 });
52
+ chmodPrivateFile(targetPath);
40
53
  };
@@ -1,12 +1,12 @@
1
1
  import type { Message } from '../../llm/messages.js';
2
2
  export declare class HistoryItem {
3
- step_number: number | null;
4
- evaluation_previous_goal: string | null;
5
- memory: string | null;
6
- next_goal: string | null;
7
- action_results: string | null;
8
- error: string | null;
9
- system_message: string | null;
3
+ readonly step_number: number | null;
4
+ readonly evaluation_previous_goal: string | null;
5
+ readonly memory: string | null;
6
+ readonly next_goal: string | null;
7
+ readonly action_results: string | null;
8
+ readonly error: string | null;
9
+ readonly system_message: string | null;
10
10
  constructor(step_number?: number | null, evaluation_previous_goal?: string | null, memory?: string | null, next_goal?: string | null, action_results?: string | null, error?: string | null, system_message?: string | null);
11
11
  to_string(): string;
12
12
  }
@@ -17,6 +17,7 @@ export class HistoryItem {
17
17
  if (this.error && this.system_message) {
18
18
  throw new Error('Cannot have both error and system_message at the same time');
19
19
  }
20
+ Object.freeze(this);
20
21
  }
21
22
  to_string() {
22
23
  const stepStr = this.step_number != null ? 'step' : 'step_unknown';
@@ -62,6 +62,9 @@ export declare class AgentMessagePrompt {
62
62
  constructor(init: AgentMessagePromptInit);
63
63
  private extractPageStatistics;
64
64
  private browserStateDescription;
65
+ private currentDateString;
66
+ private userRequestDescription;
67
+ private stepMetaDescription;
65
68
  private agentStateDescription;
66
69
  private resizeScreenshotForLlm;
67
70
  get_user_message(use_vision?: boolean): UserMessage;
@@ -268,20 +268,30 @@ ${recentEventsText}${closedPopupsText}${pdfMessage}Interactive elements${truncat
268
268
  ${elementsText}
269
269
  `;
270
270
  }
271
- agentStateDescription() {
272
- const todoContents = this.fileSystem.get_todo_contents();
273
- const todoText = todoContents || '[empty todo.md, fill it when applicable]';
271
+ currentDateString() {
274
272
  const now = new Date();
275
273
  const pad = (value) => String(value).padStart(2, '0');
276
- const dateString = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
274
+ return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
275
+ }
276
+ userRequestDescription() {
277
+ return `<user_request>
278
+ ${this.task ?? ''}
279
+ </user_request>
280
+
281
+ `;
282
+ }
283
+ stepMetaDescription() {
277
284
  let stepInfoDescription = this.stepInfo != null
278
285
  ? `Step${this.stepInfo.step_number + 1} maximum:${this.stepInfo.max_steps}\n`
279
286
  : '';
280
- stepInfoDescription += `Today:${dateString}`;
281
- let agentState = `<user_request>
282
- ${this.task ?? ''}
283
- </user_request>
284
- <file_system>
287
+ stepInfoDescription += `Today:${this.currentDateString()}`;
288
+ return `<step_info>${stepInfoDescription}</step_info>
289
+ `;
290
+ }
291
+ agentStateDescription() {
292
+ const todoContents = this.fileSystem.get_todo_contents();
293
+ const todoText = todoContents || '[empty todo.md, fill it when applicable]';
294
+ let agentState = `<file_system>
285
295
  ${this.fileSystem.describe()}
286
296
  </file_system>
287
297
  <todo_contents>
@@ -298,8 +308,6 @@ ${this.planDescription}
298
308
  agentState += `<sensitive_data>${this.sensitiveData}</sensitive_data>
299
309
  `;
300
310
  }
301
- agentState += `<step_info>${stepInfoDescription}</step_info>
302
- `;
303
311
  if (this.availableFilePaths?.length) {
304
312
  agentState += `<available_file_paths>${this.availableFilePaths.join('\n')}
305
313
  Use with absolute paths</available_file_paths>
@@ -337,7 +345,8 @@ Use with absolute paths</available_file_paths>
337
345
  this.browserState.tabs.length === 1) {
338
346
  use_vision = false;
339
347
  }
340
- let stateDescription = `<agent_history>
348
+ let stateDescription = this.userRequestDescription();
349
+ stateDescription += `<agent_history>
341
350
  ${(this.agentHistoryDescription ?? '').trim()}
342
351
  </agent_history>
343
352
 
@@ -366,6 +375,7 @@ ${this.pageFilteredActions}
366
375
  if (this.unavailableSkillsInfo) {
367
376
  stateDescription += `\n${this.unavailableSkillsInfo}\n`;
368
377
  }
378
+ stateDescription += this.stepMetaDescription();
369
379
  stateDescription = sanitize_surrogates(stateDescription);
370
380
  const hasReadStateImages = this.readStateImages.length > 0;
371
381
  if ((use_vision === true && this.screenshots.length > 0) ||
@@ -15,7 +15,7 @@ import type { StructuredOutputParser } from './views.js';
15
15
  import { ScreenshotService } from '../screenshots/service.js';
16
16
  import { ProductTelemetry } from '../telemetry/service.js';
17
17
  import { type SkillService } from '../skills/index.js';
18
- export declare const log_response: (response: AgentOutput, registry?: Controller<any>, logInstance?: import("../logging-config.js").Logger) => void;
18
+ export declare const log_response: (response: AgentOutput, registry?: Controller<any>, logInstance?: import("../logging-config.js").Logger, sensitive_data?: Record<string, string | Record<string, string>> | null) => void;
19
19
  type ControllerContext = unknown;
20
20
  type AgentHookFunc<Context, AgentStructuredOutput> = (agent: Agent<Context, AgentStructuredOutput>) => Promise<void> | void;
21
21
  interface RerunHistoryOptions {
@@ -162,6 +162,7 @@ export declare class Agent<Context = ControllerContext, AgentStructuredOutput =
162
162
  private _url_shortening_limit;
163
163
  private skill_service;
164
164
  private _skills_registered;
165
+ private _redactSensitiveText;
165
166
  constructor(params: AgentConstructorParams<Context, AgentStructuredOutput>);
166
167
  private _normalizeMessageCompactionSetting;
167
168
  private _createSessionIdWithAgentSuffix;
@@ -243,6 +244,7 @@ export declare class Agent<Context = ControllerContext, AgentStructuredOutput =
243
244
  * Initially only include actions with no filters
244
245
  */
245
246
  private _setup_action_models;
247
+ private _filter_cookies_for_domain_policy;
246
248
  private _register_skills_as_actions;
247
249
  private _get_unavailable_skills_info;
248
250
  /**
@@ -263,7 +265,13 @@ export declare class Agent<Context = ControllerContext, AgentStructuredOutput =
263
265
  multi_act(actions: Array<Record<string, Record<string, unknown>>>, options?: {
264
266
  check_for_new_elements?: boolean;
265
267
  signal?: AbortSignal | null;
268
+ action_timeout?: number | null;
266
269
  }): Promise<ActionResult[]>;
270
+ private _shouldPropagateActionError;
271
+ private _isConnectionLikeError;
272
+ private _formatActionExecutionError;
273
+ private _actionResultFromBrowserError;
274
+ private _actionResultFromRegistryTimeout;
267
275
  private _generate_rerun_summary;
268
276
  private _execute_ai_step;
269
277
  rerun_history(history: AgentHistoryList, options?: RerunHistoryOptions): Promise<ActionResult[]>;