browser-use 0.2.0 → 0.4.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.
- package/README.md +295 -686
- package/dist/actor/element.d.ts +19 -0
- package/dist/actor/element.js +46 -0
- package/dist/actor/index.d.ts +4 -0
- package/dist/actor/index.js +4 -0
- package/dist/actor/mouse.d.ts +19 -0
- package/dist/actor/mouse.js +39 -0
- package/dist/actor/page.d.ts +29 -0
- package/dist/actor/page.js +88 -0
- package/dist/actor/utils.d.ts +4 -0
- package/dist/actor/utils.js +35 -0
- package/dist/agent/cloud-events.d.ts +18 -0
- package/dist/agent/cloud-events.js +65 -2
- package/dist/agent/gif.d.ts +1 -0
- package/dist/agent/gif.js +24 -2
- package/dist/agent/judge.d.ts +17 -0
- package/dist/agent/judge.js +197 -0
- package/dist/agent/message-manager/service.d.ts +12 -4
- package/dist/agent/message-manager/service.js +205 -39
- package/dist/agent/message-manager/utils.js +0 -1
- package/dist/agent/message-manager/views.d.ts +4 -0
- package/dist/agent/message-manager/views.js +11 -7
- package/dist/agent/prompts.d.ts +24 -3
- package/dist/agent/prompts.js +274 -59
- package/dist/agent/service.d.ts +103 -41
- package/dist/agent/service.js +2336 -472
- package/dist/agent/variable-detector.d.ts +12 -0
- package/dist/agent/variable-detector.js +211 -0
- package/dist/agent/views.d.ts +237 -18
- package/dist/agent/views.js +446 -33
- package/dist/browser/cloud/cloud.d.ts +20 -0
- package/dist/browser/cloud/cloud.js +129 -0
- package/dist/browser/cloud/index.d.ts +2 -0
- package/dist/browser/cloud/index.js +2 -0
- package/dist/browser/cloud/views.d.ts +41 -0
- package/dist/browser/cloud/views.js +35 -0
- package/dist/browser/events.d.ts +345 -0
- package/dist/browser/events.js +566 -0
- package/dist/browser/extensions.js +17 -17
- package/dist/browser/index.d.ts +4 -0
- package/dist/browser/index.js +4 -0
- package/dist/browser/profile.d.ts +10 -4
- package/dist/browser/profile.js +79 -12
- package/dist/browser/session-manager.d.ts +85 -0
- package/dist/browser/session-manager.js +208 -0
- package/dist/browser/session.d.ts +105 -9
- package/dist/browser/session.js +1166 -95
- package/dist/browser/types.d.ts +153 -156
- package/dist/browser/views.d.ts +39 -0
- package/dist/browser/views.js +32 -0
- package/dist/browser/watchdogs/aboutblank-watchdog.d.ts +12 -0
- package/dist/browser/watchdogs/aboutblank-watchdog.js +131 -0
- package/dist/browser/watchdogs/base.d.ts +21 -0
- package/dist/browser/watchdogs/base.js +81 -0
- package/dist/browser/watchdogs/cdp-session-watchdog.d.ts +14 -0
- package/dist/browser/watchdogs/cdp-session-watchdog.js +177 -0
- package/dist/browser/watchdogs/crash-watchdog.d.ts +38 -0
- package/dist/browser/watchdogs/crash-watchdog.js +296 -0
- package/dist/browser/watchdogs/default-action-watchdog.d.ts +49 -0
- package/dist/browser/watchdogs/default-action-watchdog.js +212 -0
- package/dist/browser/watchdogs/dom-watchdog.d.ts +8 -0
- package/dist/browser/watchdogs/dom-watchdog.js +31 -0
- package/dist/browser/watchdogs/downloads-watchdog.d.ts +77 -0
- package/dist/browser/watchdogs/downloads-watchdog.js +409 -0
- package/dist/browser/watchdogs/har-recording-watchdog.d.ts +19 -0
- package/dist/browser/watchdogs/har-recording-watchdog.js +317 -0
- package/dist/browser/watchdogs/index.d.ts +15 -0
- package/dist/browser/watchdogs/index.js +15 -0
- package/dist/browser/watchdogs/local-browser-watchdog.d.ts +10 -0
- package/dist/browser/watchdogs/local-browser-watchdog.js +32 -0
- package/dist/browser/watchdogs/permissions-watchdog.d.ts +8 -0
- package/dist/browser/watchdogs/permissions-watchdog.js +73 -0
- package/dist/browser/watchdogs/popups-watchdog.d.ts +13 -0
- package/dist/browser/watchdogs/popups-watchdog.js +77 -0
- package/dist/browser/watchdogs/recording-watchdog.d.ts +27 -0
- package/dist/browser/watchdogs/recording-watchdog.js +249 -0
- package/dist/browser/watchdogs/screenshot-watchdog.d.ts +6 -0
- package/dist/browser/watchdogs/screenshot-watchdog.js +13 -0
- package/dist/browser/watchdogs/security-watchdog.d.ts +10 -0
- package/dist/browser/watchdogs/security-watchdog.js +84 -0
- package/dist/browser/watchdogs/storage-state-watchdog.d.ts +24 -0
- package/dist/browser/watchdogs/storage-state-watchdog.js +288 -0
- package/dist/cli.d.ts +7 -2
- package/dist/cli.js +182 -25
- package/dist/code-use/formatting.d.ts +3 -0
- package/dist/code-use/formatting.js +18 -0
- package/dist/code-use/index.d.ts +6 -0
- package/dist/code-use/index.js +6 -0
- package/dist/code-use/namespace.d.ts +5 -0
- package/dist/code-use/namespace.js +81 -0
- package/dist/code-use/notebook-export.d.ts +3 -0
- package/dist/code-use/notebook-export.js +56 -0
- package/dist/code-use/service.d.ts +24 -0
- package/dist/code-use/service.js +104 -0
- package/dist/code-use/utils.d.ts +4 -0
- package/dist/code-use/utils.js +98 -0
- package/dist/code-use/views.d.ts +108 -0
- package/dist/code-use/views.js +165 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.js +109 -7
- package/dist/controller/registry/service.d.ts +10 -1
- package/dist/controller/registry/service.js +266 -10
- package/dist/controller/registry/views.d.ts +4 -1
- package/dist/controller/registry/views.js +25 -2
- package/dist/controller/service.d.ts +10 -1
- package/dist/controller/service.js +1814 -268
- package/dist/controller/views.d.ts +78 -155
- package/dist/controller/views.js +61 -12
- package/dist/dom/history-tree-processor/service.d.ts +5 -0
- package/dist/dom/history-tree-processor/service.js +169 -14
- package/dist/dom/history-tree-processor/view.d.ts +7 -1
- package/dist/dom/history-tree-processor/view.js +10 -1
- package/dist/dom/markdown-extractor.d.ts +37 -0
- package/dist/dom/markdown-extractor.js +345 -0
- package/dist/dom/service.d.ts +3 -1
- package/dist/dom/service.js +76 -0
- package/dist/dom/views.d.ts +1 -0
- package/dist/dom/views.js +45 -0
- package/dist/event-bus.d.ts +107 -7
- package/dist/event-bus.js +313 -10
- package/dist/exceptions.d.ts +0 -3
- package/dist/exceptions.js +0 -7
- package/dist/filesystem/file-system.d.ts +18 -0
- package/dist/filesystem/file-system.js +503 -42
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/integrations/gmail/actions.d.ts +3 -3
- package/dist/integrations/gmail/actions.js +4 -4
- package/dist/llm/anthropic/chat.d.ts +18 -1
- package/dist/llm/anthropic/chat.js +123 -55
- package/dist/llm/anthropic/serializer.d.ts +2 -0
- package/dist/llm/anthropic/serializer.js +81 -9
- package/dist/llm/aws/chat-anthropic.d.ts +17 -0
- package/dist/llm/aws/chat-anthropic.js +126 -26
- package/dist/llm/aws/chat-bedrock.d.ts +28 -1
- package/dist/llm/aws/chat-bedrock.js +161 -34
- package/dist/llm/aws/serializer.d.ts +13 -1
- package/dist/llm/aws/serializer.js +56 -17
- package/dist/llm/azure/chat.d.ts +53 -2
- package/dist/llm/azure/chat.js +366 -54
- package/dist/llm/base.d.ts +2 -0
- package/dist/llm/browser-use/chat.d.ts +40 -0
- package/dist/llm/browser-use/chat.js +305 -0
- package/dist/llm/browser-use/index.d.ts +1 -0
- package/dist/llm/browser-use/index.js +1 -0
- package/dist/llm/cerebras/chat.d.ts +39 -0
- package/dist/llm/cerebras/chat.js +178 -0
- package/dist/llm/cerebras/index.d.ts +2 -0
- package/dist/llm/cerebras/index.js +2 -0
- package/dist/llm/cerebras/serializer.d.ts +7 -0
- package/dist/llm/cerebras/serializer.js +82 -0
- package/dist/llm/deepseek/chat.d.ts +19 -2
- package/dist/llm/deepseek/chat.js +138 -25
- package/dist/llm/google/chat.d.ts +46 -2
- package/dist/llm/google/chat.js +267 -64
- package/dist/llm/google/serializer.d.ts +9 -1
- package/dist/llm/google/serializer.js +141 -34
- package/dist/llm/groq/chat.d.ts +21 -2
- package/dist/llm/groq/chat.js +125 -26
- package/dist/llm/groq/parser.js +3 -1
- package/dist/llm/mistral/chat.d.ts +43 -0
- package/dist/llm/mistral/chat.js +154 -0
- package/dist/llm/mistral/index.d.ts +2 -0
- package/dist/llm/mistral/index.js +2 -0
- package/dist/llm/mistral/schema.d.ts +8 -0
- package/dist/llm/mistral/schema.js +27 -0
- package/dist/llm/models.d.ts +2 -0
- package/dist/llm/models.js +317 -0
- package/dist/llm/ollama/chat.d.ts +13 -1
- package/dist/llm/ollama/chat.js +110 -19
- package/dist/llm/ollama/serializer.d.ts +1 -0
- package/dist/llm/ollama/serializer.js +34 -12
- package/dist/llm/openai/chat.d.ts +16 -0
- package/dist/llm/openai/chat.js +94 -44
- package/dist/llm/openai/like.d.ts +5 -3
- package/dist/llm/openai/like.js +7 -3
- package/dist/llm/openai/responses-serializer.d.ts +18 -0
- package/dist/llm/openai/responses-serializer.js +72 -0
- package/dist/llm/openrouter/chat.d.ts +28 -2
- package/dist/llm/openrouter/chat.js +115 -29
- package/dist/llm/schema.d.ts +11 -1
- package/dist/llm/schema.js +109 -4
- package/dist/llm/vercel/chat.d.ts +50 -0
- package/dist/llm/vercel/chat.js +276 -0
- package/dist/llm/vercel/index.d.ts +1 -0
- package/dist/llm/vercel/index.js +1 -0
- package/dist/llm/vercel/serializer.d.ts +5 -0
- package/dist/llm/vercel/serializer.js +7 -0
- package/dist/llm/views.d.ts +2 -1
- package/dist/llm/views.js +3 -1
- package/dist/logging-config.d.ts +2 -0
- package/dist/logging-config.js +82 -29
- package/dist/mcp/client.d.ts +10 -5
- package/dist/mcp/client.js +14 -9
- package/dist/mcp/controller.d.ts +42 -3
- package/dist/mcp/controller.js +56 -31
- package/dist/mcp/server.d.ts +15 -0
- package/dist/mcp/server.js +261 -52
- package/dist/observability.js +10 -4
- package/dist/sandbox/index.d.ts +2 -0
- package/dist/sandbox/index.js +2 -0
- package/dist/sandbox/sandbox.d.ts +19 -0
- package/dist/sandbox/sandbox.js +140 -0
- package/dist/sandbox/views.d.ts +67 -0
- package/dist/sandbox/views.js +121 -0
- package/dist/skill-cli/index.d.ts +3 -0
- package/dist/skill-cli/index.js +3 -0
- package/dist/skill-cli/protocol.d.ts +30 -0
- package/dist/skill-cli/protocol.js +48 -0
- package/dist/skill-cli/server.d.ts +11 -0
- package/dist/skill-cli/server.js +85 -0
- package/dist/skill-cli/sessions.d.ts +24 -0
- package/dist/skill-cli/sessions.js +47 -0
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/service.d.ts +27 -0
- package/dist/skills/service.js +266 -0
- package/dist/skills/utils.d.ts +6 -0
- package/dist/skills/utils.js +53 -0
- package/dist/skills/views.d.ts +40 -0
- package/dist/skills/views.js +10 -0
- package/dist/sync/auth.js +8 -3
- package/dist/sync/service.d.ts +6 -6
- package/dist/sync/service.js +54 -89
- package/dist/telemetry/views.d.ts +20 -6
- package/dist/telemetry/views.js +23 -5
- package/dist/tokens/custom-pricing.d.ts +2 -0
- package/dist/tokens/custom-pricing.js +22 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.js +2 -0
- package/dist/tokens/mappings.d.ts +1 -0
- package/dist/tokens/mappings.js +3 -0
- package/dist/tokens/service.js +27 -8
- package/dist/tools/extraction/index.d.ts +2 -0
- package/dist/tools/extraction/index.js +2 -0
- package/dist/tools/extraction/schema-utils.d.ts +6 -0
- package/dist/tools/extraction/schema-utils.js +237 -0
- package/dist/tools/extraction/views.d.ts +7 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/registry/index.d.ts +2 -0
- package/dist/tools/registry/index.js +2 -0
- package/dist/tools/registry/service.d.ts +1 -0
- package/dist/tools/registry/service.js +1 -0
- package/dist/tools/registry/views.d.ts +1 -0
- package/dist/tools/registry/views.js +1 -0
- package/dist/tools/service.d.ts +2 -0
- package/dist/tools/service.js +1 -0
- package/dist/tools/utils.d.ts +2 -0
- package/dist/tools/utils.js +57 -0
- package/dist/tools/views.d.ts +1 -0
- package/dist/tools/views.js +1 -0
- package/dist/utils.d.ts +10 -1
- package/dist/utils.js +70 -3
- package/package.json +116 -49
- package/dist/dom/playground/process-dom.js +0 -5
- package/dist/dom/playground/test-accessibility.d.ts +0 -44
- package/dist/dom/playground/test-accessibility.js +0 -111
- /package/dist/{dom/playground/process-dom.d.ts → tools/extraction/views.js} +0 -0
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
|
}
|
|
@@ -134,8 +140,11 @@ class OldConfig {
|
|
|
134
140
|
get DEEPSEEK_API_KEY() {
|
|
135
141
|
return process.env.DEEPSEEK_API_KEY ?? '';
|
|
136
142
|
}
|
|
143
|
+
get GROQ_API_KEY() {
|
|
144
|
+
return process.env.GROQ_API_KEY ?? process.env.GROK_API_KEY ?? '';
|
|
145
|
+
}
|
|
137
146
|
get GROK_API_KEY() {
|
|
138
|
-
return
|
|
147
|
+
return this.GROQ_API_KEY;
|
|
139
148
|
}
|
|
140
149
|
get NOVITA_API_KEY() {
|
|
141
150
|
return process.env.NOVITA_API_KEY ?? '';
|
|
@@ -149,12 +158,18 @@ class OldConfig {
|
|
|
149
158
|
get SKIP_LLM_API_KEY_VERIFICATION() {
|
|
150
159
|
return string_to_bool(process.env.SKIP_LLM_API_KEY_VERIFICATION, false);
|
|
151
160
|
}
|
|
161
|
+
get DEFAULT_LLM() {
|
|
162
|
+
return process.env.DEFAULT_LLM ?? '';
|
|
163
|
+
}
|
|
152
164
|
get IN_DOCKER() {
|
|
153
165
|
return (string_to_bool(process.env.IN_DOCKER, false) || is_running_in_docker());
|
|
154
166
|
}
|
|
155
167
|
get IS_IN_EVALS() {
|
|
156
168
|
return string_to_bool(process.env.IS_IN_EVALS, false);
|
|
157
169
|
}
|
|
170
|
+
get BROWSER_USE_VERSION_CHECK() {
|
|
171
|
+
return string_to_bool(process.env.BROWSER_USE_VERSION_CHECK, true);
|
|
172
|
+
}
|
|
158
173
|
get WIN_FONT_DIR() {
|
|
159
174
|
return process.env.WIN_FONT_DIR ?? 'C:\\Windows\\Fonts';
|
|
160
175
|
}
|
|
@@ -188,6 +203,12 @@ class FlatEnvConfig {
|
|
|
188
203
|
get BROWSER_USE_CLOUD_UI_URL() {
|
|
189
204
|
return process.env.BROWSER_USE_CLOUD_UI_URL ?? '';
|
|
190
205
|
}
|
|
206
|
+
get BROWSER_USE_DEBUG_LOG_FILE() {
|
|
207
|
+
return process.env.BROWSER_USE_DEBUG_LOG_FILE ?? null;
|
|
208
|
+
}
|
|
209
|
+
get BROWSER_USE_INFO_LOG_FILE() {
|
|
210
|
+
return process.env.BROWSER_USE_INFO_LOG_FILE ?? null;
|
|
211
|
+
}
|
|
191
212
|
get XDG_CACHE_HOME() {
|
|
192
213
|
return resolve_path(process.env.XDG_CACHE_HOME ?? '~/.cache');
|
|
193
214
|
}
|
|
@@ -211,8 +232,11 @@ class FlatEnvConfig {
|
|
|
211
232
|
get DEEPSEEK_API_KEY() {
|
|
212
233
|
return process.env.DEEPSEEK_API_KEY ?? '';
|
|
213
234
|
}
|
|
235
|
+
get GROQ_API_KEY() {
|
|
236
|
+
return process.env.GROQ_API_KEY ?? process.env.GROK_API_KEY ?? '';
|
|
237
|
+
}
|
|
214
238
|
get GROK_API_KEY() {
|
|
215
|
-
return
|
|
239
|
+
return this.GROQ_API_KEY;
|
|
216
240
|
}
|
|
217
241
|
get NOVITA_API_KEY() {
|
|
218
242
|
return process.env.NOVITA_API_KEY ?? '';
|
|
@@ -226,6 +250,9 @@ class FlatEnvConfig {
|
|
|
226
250
|
get SKIP_LLM_API_KEY_VERIFICATION() {
|
|
227
251
|
return string_to_bool(process.env.SKIP_LLM_API_KEY_VERIFICATION, false);
|
|
228
252
|
}
|
|
253
|
+
get DEFAULT_LLM() {
|
|
254
|
+
return process.env.DEFAULT_LLM ?? '';
|
|
255
|
+
}
|
|
229
256
|
get IN_DOCKER() {
|
|
230
257
|
const value = process.env.IN_DOCKER;
|
|
231
258
|
return value === undefined ? null : string_to_bool(value);
|
|
@@ -233,6 +260,9 @@ class FlatEnvConfig {
|
|
|
233
260
|
get IS_IN_EVALS() {
|
|
234
261
|
return string_to_bool(process.env.IS_IN_EVALS, false);
|
|
235
262
|
}
|
|
263
|
+
get BROWSER_USE_VERSION_CHECK() {
|
|
264
|
+
return string_to_bool(process.env.BROWSER_USE_VERSION_CHECK, true);
|
|
265
|
+
}
|
|
236
266
|
get WIN_FONT_DIR() {
|
|
237
267
|
return process.env.WIN_FONT_DIR ?? 'C:\\Windows\\Fonts';
|
|
238
268
|
}
|
|
@@ -251,9 +281,25 @@ class FlatEnvConfig {
|
|
|
251
281
|
get BROWSER_USE_LLM_MODEL() {
|
|
252
282
|
return process.env.BROWSER_USE_LLM_MODEL ?? null;
|
|
253
283
|
}
|
|
284
|
+
get BROWSER_USE_PROXY_URL() {
|
|
285
|
+
return process.env.BROWSER_USE_PROXY_URL ?? null;
|
|
286
|
+
}
|
|
287
|
+
get BROWSER_USE_NO_PROXY() {
|
|
288
|
+
return process.env.BROWSER_USE_NO_PROXY ?? null;
|
|
289
|
+
}
|
|
290
|
+
get BROWSER_USE_PROXY_USERNAME() {
|
|
291
|
+
return process.env.BROWSER_USE_PROXY_USERNAME ?? null;
|
|
292
|
+
}
|
|
293
|
+
get BROWSER_USE_PROXY_PASSWORD() {
|
|
294
|
+
return process.env.BROWSER_USE_PROXY_PASSWORD ?? null;
|
|
295
|
+
}
|
|
296
|
+
get BROWSER_USE_DISABLE_EXTENSIONS() {
|
|
297
|
+
const value = process.env.BROWSER_USE_DISABLE_EXTENSIONS;
|
|
298
|
+
return value === undefined ? null : string_to_bool(value);
|
|
299
|
+
}
|
|
254
300
|
}
|
|
255
301
|
const create_default_config = () => {
|
|
256
|
-
logger.
|
|
302
|
+
logger.debug('Creating fresh default config.json');
|
|
257
303
|
const profile_id = randomUUID();
|
|
258
304
|
const llm_id = randomUUID();
|
|
259
305
|
const agent_id = randomUUID();
|
|
@@ -274,8 +320,8 @@ const create_default_config = () => {
|
|
|
274
320
|
id: llm_id,
|
|
275
321
|
default: true,
|
|
276
322
|
created_at: new Date().toISOString(),
|
|
277
|
-
model: 'gpt-
|
|
278
|
-
api_key:
|
|
323
|
+
model: 'gpt-4.1-mini',
|
|
324
|
+
api_key: null,
|
|
279
325
|
temperature: null,
|
|
280
326
|
max_tokens: null,
|
|
281
327
|
},
|
|
@@ -292,6 +338,36 @@ const create_default_config = () => {
|
|
|
292
338
|
},
|
|
293
339
|
};
|
|
294
340
|
};
|
|
341
|
+
const OPENAI_API_KEY_PLACEHOLDERS = new Set([
|
|
342
|
+
'your-openai-api-key-here',
|
|
343
|
+
'your-openai-api-key',
|
|
344
|
+
]);
|
|
345
|
+
const sanitize_llm_api_key = (apiKey) => {
|
|
346
|
+
if (typeof apiKey !== 'string') {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
const trimmed = apiKey.trim();
|
|
350
|
+
if (!trimmed) {
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
if (OPENAI_API_KEY_PLACEHOLDERS.has(trimmed.toLowerCase())) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
return trimmed;
|
|
357
|
+
};
|
|
358
|
+
const sanitize_db_config = (config) => {
|
|
359
|
+
const sanitizedLlmEntries = Object.fromEntries(Object.entries(config.llm ?? {}).map(([id, entry]) => [
|
|
360
|
+
id,
|
|
361
|
+
{
|
|
362
|
+
...entry,
|
|
363
|
+
api_key: sanitize_llm_api_key(entry.api_key),
|
|
364
|
+
},
|
|
365
|
+
]));
|
|
366
|
+
return {
|
|
367
|
+
...config,
|
|
368
|
+
llm: sanitizedLlmEntries,
|
|
369
|
+
};
|
|
370
|
+
};
|
|
295
371
|
const looks_like_new_format = (data) => data &&
|
|
296
372
|
typeof data === 'object' &&
|
|
297
373
|
['browser_profile', 'llm', 'agent'].every((key) => typeof data[key] === 'object') &&
|
|
@@ -307,9 +383,9 @@ const load_and_migrate_config = (config_path) => {
|
|
|
307
383
|
try {
|
|
308
384
|
const raw = JSON.parse(fs.readFileSync(config_path, 'utf-8'));
|
|
309
385
|
if (looks_like_new_format(raw)) {
|
|
310
|
-
return raw;
|
|
386
|
+
return sanitize_db_config(raw);
|
|
311
387
|
}
|
|
312
|
-
logger.
|
|
388
|
+
logger.debug(`Old config format detected at ${config_path}, creating fresh config`);
|
|
313
389
|
const fresh = create_default_config();
|
|
314
390
|
fs.writeFileSync(config_path, JSON.stringify(fresh, null, 2), 'utf-8');
|
|
315
391
|
return fresh;
|
|
@@ -374,12 +450,38 @@ class ConfigCore {
|
|
|
374
450
|
.map((domain) => domain.trim())
|
|
375
451
|
.filter(Boolean);
|
|
376
452
|
}
|
|
453
|
+
const proxy = {};
|
|
454
|
+
if (env.BROWSER_USE_PROXY_URL) {
|
|
455
|
+
proxy.server = env.BROWSER_USE_PROXY_URL;
|
|
456
|
+
}
|
|
457
|
+
if (env.BROWSER_USE_NO_PROXY) {
|
|
458
|
+
proxy.bypass = env.BROWSER_USE_NO_PROXY.split(',')
|
|
459
|
+
.map((domain) => domain.trim())
|
|
460
|
+
.filter(Boolean)
|
|
461
|
+
.join(',');
|
|
462
|
+
}
|
|
463
|
+
if (env.BROWSER_USE_PROXY_USERNAME) {
|
|
464
|
+
proxy.username = env.BROWSER_USE_PROXY_USERNAME;
|
|
465
|
+
}
|
|
466
|
+
if (env.BROWSER_USE_PROXY_PASSWORD) {
|
|
467
|
+
proxy.password = env.BROWSER_USE_PROXY_PASSWORD;
|
|
468
|
+
}
|
|
469
|
+
if (Object.keys(proxy).length > 0) {
|
|
470
|
+
config.browser_profile.proxy = proxy;
|
|
471
|
+
}
|
|
377
472
|
if (env.OPENAI_API_KEY) {
|
|
378
473
|
config.llm.api_key = env.OPENAI_API_KEY;
|
|
379
474
|
}
|
|
475
|
+
if (env.DEFAULT_LLM) {
|
|
476
|
+
config.llm.model = env.DEFAULT_LLM;
|
|
477
|
+
}
|
|
380
478
|
if (env.BROWSER_USE_LLM_MODEL) {
|
|
381
479
|
config.llm.model = env.BROWSER_USE_LLM_MODEL;
|
|
382
480
|
}
|
|
481
|
+
if (env.BROWSER_USE_DISABLE_EXTENSIONS !== null) {
|
|
482
|
+
config.browser_profile.enable_default_extensions =
|
|
483
|
+
!env.BROWSER_USE_DISABLE_EXTENSIONS;
|
|
484
|
+
}
|
|
383
485
|
return config;
|
|
384
486
|
}
|
|
385
487
|
_ensure_dirs() {
|
|
@@ -10,7 +10,12 @@ export interface SensitiveDataMap {
|
|
|
10
10
|
export interface ExecuteActionContext<Context> {
|
|
11
11
|
context?: Context;
|
|
12
12
|
browser_session?: BrowserSession | null;
|
|
13
|
+
browser?: BrowserSession | null;
|
|
14
|
+
browser_context?: BrowserSession | null;
|
|
15
|
+
page_url?: string | null;
|
|
16
|
+
cdp_client?: unknown;
|
|
13
17
|
page_extraction_llm?: BaseChatModel | null;
|
|
18
|
+
extraction_schema?: Record<string, unknown> | null;
|
|
14
19
|
file_system?: FileSystem | null;
|
|
15
20
|
available_file_paths?: string[] | null;
|
|
16
21
|
sensitive_data?: SensitiveDataMap | null;
|
|
@@ -22,16 +27,20 @@ export type RegistryActionHandler<Params = any, Context = unknown> = (params: Pa
|
|
|
22
27
|
}) => Promise<unknown> | unknown;
|
|
23
28
|
export interface ActionOptions {
|
|
24
29
|
param_model?: ZodTypeAny;
|
|
30
|
+
action_name?: string;
|
|
25
31
|
domains?: string[] | null;
|
|
26
32
|
allowed_domains?: string[] | null;
|
|
27
33
|
page_filter?: ((page: Page) => boolean) | null;
|
|
34
|
+
terminates_sequence?: boolean;
|
|
28
35
|
}
|
|
29
36
|
export declare class Registry<Context = unknown> {
|
|
30
37
|
private registry;
|
|
31
38
|
private excludeActions;
|
|
32
39
|
constructor(exclude_actions?: string[] | null);
|
|
33
|
-
action(description: string, options?: ActionOptions): <Params = any>(handler: RegistryActionHandler<Params, Context>) =>
|
|
40
|
+
action(description: string, options?: ActionOptions): <Params = any>(handler: RegistryActionHandler<Params, Context>) => any;
|
|
34
41
|
get_action(action_name: string): RegisteredAction | null;
|
|
42
|
+
exclude_action(action_name: string): void;
|
|
43
|
+
remove_action(action_name: string): void;
|
|
35
44
|
get_all_actions(): Map<string, RegisteredAction>;
|
|
36
45
|
execute_action: (...args: any[]) => any;
|
|
37
46
|
private replace_sensitive_data;
|
|
@@ -1,10 +1,145 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { createHmac } from 'node:crypto';
|
|
2
3
|
import { createLogger } from '../../logging-config.js';
|
|
3
4
|
import { observe_debug } from '../../observability.js';
|
|
4
5
|
import { time_execution_async } from '../../utils.js';
|
|
5
6
|
import { is_new_tab_page, match_url_with_domain_pattern } from '../../utils.js';
|
|
7
|
+
import { BrowserError } from '../../browser/views.js';
|
|
6
8
|
import { ActionModel, ActionRegistry, RegisteredAction } from './views.js';
|
|
7
9
|
const logger = createLogger('browser_use.controller.registry');
|
|
10
|
+
const SPECIAL_PARAM_NAMES = new Set([
|
|
11
|
+
'context',
|
|
12
|
+
'browser_session',
|
|
13
|
+
'browser',
|
|
14
|
+
'browser_context',
|
|
15
|
+
'page',
|
|
16
|
+
'page_url',
|
|
17
|
+
'cdp_client',
|
|
18
|
+
'page_extraction_llm',
|
|
19
|
+
'available_file_paths',
|
|
20
|
+
'has_sensitive_data',
|
|
21
|
+
'file_system',
|
|
22
|
+
'extraction_schema',
|
|
23
|
+
'sensitive_data',
|
|
24
|
+
'signal',
|
|
25
|
+
]);
|
|
26
|
+
const splitTopLevelParameters = (paramsSource) => {
|
|
27
|
+
const segments = [];
|
|
28
|
+
let current = '';
|
|
29
|
+
let depthParen = 0;
|
|
30
|
+
let depthBrace = 0;
|
|
31
|
+
let depthBracket = 0;
|
|
32
|
+
let quote = null;
|
|
33
|
+
let escaped = false;
|
|
34
|
+
const flush = () => {
|
|
35
|
+
const trimmed = current.trim();
|
|
36
|
+
if (trimmed) {
|
|
37
|
+
segments.push(trimmed);
|
|
38
|
+
}
|
|
39
|
+
current = '';
|
|
40
|
+
};
|
|
41
|
+
for (const char of paramsSource) {
|
|
42
|
+
if (escaped) {
|
|
43
|
+
current += char;
|
|
44
|
+
escaped = false;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (char === '\\') {
|
|
48
|
+
current += char;
|
|
49
|
+
escaped = true;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (quote) {
|
|
53
|
+
current += char;
|
|
54
|
+
if (char === quote) {
|
|
55
|
+
quote = null;
|
|
56
|
+
}
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
60
|
+
current += char;
|
|
61
|
+
quote = char;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (char === '(')
|
|
65
|
+
depthParen += 1;
|
|
66
|
+
else if (char === ')')
|
|
67
|
+
depthParen -= 1;
|
|
68
|
+
else if (char === '{')
|
|
69
|
+
depthBrace += 1;
|
|
70
|
+
else if (char === '}')
|
|
71
|
+
depthBrace -= 1;
|
|
72
|
+
else if (char === '[')
|
|
73
|
+
depthBracket += 1;
|
|
74
|
+
else if (char === ']')
|
|
75
|
+
depthBracket -= 1;
|
|
76
|
+
if (char === ',' &&
|
|
77
|
+
depthParen === 0 &&
|
|
78
|
+
depthBrace === 0 &&
|
|
79
|
+
depthBracket === 0) {
|
|
80
|
+
flush();
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
current += char;
|
|
84
|
+
}
|
|
85
|
+
flush();
|
|
86
|
+
return segments;
|
|
87
|
+
};
|
|
88
|
+
const extractFunctionParameters = (fn) => {
|
|
89
|
+
const source = fn.toString().trim();
|
|
90
|
+
if (!source) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
let paramsSource;
|
|
94
|
+
const arrowIndex = source.indexOf('=>');
|
|
95
|
+
if (arrowIndex !== -1) {
|
|
96
|
+
let lhs = source.slice(0, arrowIndex).trim();
|
|
97
|
+
if (lhs.startsWith('async ')) {
|
|
98
|
+
lhs = lhs.slice('async '.length).trim();
|
|
99
|
+
}
|
|
100
|
+
if (lhs.startsWith('(') && lhs.endsWith(')')) {
|
|
101
|
+
paramsSource = lhs.slice(1, -1);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
paramsSource = lhs;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
const openIndex = source.indexOf('(');
|
|
109
|
+
const closeIndex = source.indexOf(')', openIndex + 1);
|
|
110
|
+
if (openIndex === -1 || closeIndex === -1) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
paramsSource = source.slice(openIndex + 1, closeIndex);
|
|
114
|
+
}
|
|
115
|
+
const tokens = splitTopLevelParameters(paramsSource);
|
|
116
|
+
if (!tokens.length) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
const parsed = [];
|
|
120
|
+
for (const token of tokens) {
|
|
121
|
+
if (token.startsWith('...')) {
|
|
122
|
+
const fnName = fn.name || '<anonymous>';
|
|
123
|
+
throw new Error(`Action '${fnName}' has ${token} which is not allowed. Actions must have explicit positional parameters only.`);
|
|
124
|
+
}
|
|
125
|
+
if (token.includes('{') ||
|
|
126
|
+
token.includes('}') ||
|
|
127
|
+
token.includes('[') ||
|
|
128
|
+
token.includes(']')) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const eqIndex = token.indexOf('=');
|
|
132
|
+
const name = (eqIndex === -1 ? token : token.slice(0, eqIndex)).trim();
|
|
133
|
+
if (!name) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
parsed.push({
|
|
137
|
+
name,
|
|
138
|
+
hasDefault: eqIndex !== -1,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return parsed;
|
|
142
|
+
};
|
|
8
143
|
const isAbortError = (error) => error instanceof Error && error.name === 'AbortError';
|
|
9
144
|
const createAbortError = (reason) => {
|
|
10
145
|
if (isAbortError(reason)) {
|
|
@@ -19,6 +154,9 @@ const createAbortError = (reason) => {
|
|
|
19
154
|
return error;
|
|
20
155
|
};
|
|
21
156
|
const wrapActionExecutionError = (actionName, error) => {
|
|
157
|
+
if (error instanceof BrowserError) {
|
|
158
|
+
return error;
|
|
159
|
+
}
|
|
22
160
|
const message = error instanceof Error ? error.message : String(error);
|
|
23
161
|
const wrapped = new Error(`Error executing action ${actionName}: ${message}`);
|
|
24
162
|
if (error !== undefined) {
|
|
@@ -26,6 +164,61 @@ const wrapActionExecutionError = (actionName, error) => {
|
|
|
26
164
|
}
|
|
27
165
|
return wrapped;
|
|
28
166
|
};
|
|
167
|
+
const isSpecialContextMissingError = (error) => {
|
|
168
|
+
if (!(error instanceof Error)) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
return (error.message.includes('requires browser_session but none provided') ||
|
|
172
|
+
error.message.includes('requires page_extraction_llm but none provided'));
|
|
173
|
+
};
|
|
174
|
+
const safeJsonStringify = (value) => {
|
|
175
|
+
try {
|
|
176
|
+
return JSON.stringify(value);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return String(value);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
const isTimeoutError = (error) => error instanceof Error && error.name === 'TimeoutError';
|
|
183
|
+
const BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
184
|
+
const decodeBase32Secret = (secret) => {
|
|
185
|
+
const sanitized = secret.toUpperCase().replace(/[^A-Z2-7]/g, '');
|
|
186
|
+
if (!sanitized.length) {
|
|
187
|
+
throw new Error('Invalid TOTP secret: empty base32 payload');
|
|
188
|
+
}
|
|
189
|
+
let bits = 0;
|
|
190
|
+
let bitBuffer = 0;
|
|
191
|
+
const bytes = [];
|
|
192
|
+
for (const char of sanitized) {
|
|
193
|
+
const value = BASE32_ALPHABET.indexOf(char);
|
|
194
|
+
if (value < 0) {
|
|
195
|
+
throw new Error(`Invalid base32 character in TOTP secret: ${char}`);
|
|
196
|
+
}
|
|
197
|
+
bitBuffer = (bitBuffer << 5) | value;
|
|
198
|
+
bits += 5;
|
|
199
|
+
while (bits >= 8) {
|
|
200
|
+
bytes.push((bitBuffer >>> (bits - 8)) & 0xff);
|
|
201
|
+
bits -= 8;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (!bytes.length) {
|
|
205
|
+
throw new Error('Invalid TOTP secret: failed to decode base32 payload');
|
|
206
|
+
}
|
|
207
|
+
return Buffer.from(bytes);
|
|
208
|
+
};
|
|
209
|
+
const generateTotpCode = (secret) => {
|
|
210
|
+
const key = decodeBase32Secret(secret);
|
|
211
|
+
const counter = Math.floor(Date.now() / 1000 / 30);
|
|
212
|
+
const counterBuffer = Buffer.alloc(8);
|
|
213
|
+
counterBuffer.writeBigUInt64BE(BigInt(counter));
|
|
214
|
+
const hmac = createHmac('sha1', key).update(counterBuffer).digest();
|
|
215
|
+
const offset = hmac[hmac.length - 1] & 0x0f;
|
|
216
|
+
const binaryCode = ((hmac[offset] & 0x7f) << 24) |
|
|
217
|
+
((hmac[offset + 1] & 0xff) << 16) |
|
|
218
|
+
((hmac[offset + 2] & 0xff) << 8) |
|
|
219
|
+
(hmac[offset + 3] & 0xff);
|
|
220
|
+
return String(binaryCode % 1_000_000).padStart(6, '0');
|
|
221
|
+
};
|
|
29
222
|
export class Registry {
|
|
30
223
|
registry = new ActionRegistry();
|
|
31
224
|
excludeActions;
|
|
@@ -33,21 +226,68 @@ export class Registry {
|
|
|
33
226
|
this.excludeActions = new Set(exclude_actions ?? []);
|
|
34
227
|
}
|
|
35
228
|
action(description, options = {}) {
|
|
36
|
-
|
|
229
|
+
if (options.allowed_domains && options.domains) {
|
|
230
|
+
throw new Error("Cannot specify both 'domains' and 'allowed_domains' - they are aliases for the same parameter");
|
|
231
|
+
}
|
|
232
|
+
let schema = options.param_model ?? z.object({}).strict();
|
|
233
|
+
const actionNameOverride = options.action_name ?? null;
|
|
37
234
|
const domains = options.allowed_domains ?? options.domains ?? null;
|
|
38
235
|
const pageFilter = options.page_filter ?? null;
|
|
236
|
+
const terminatesSequence = options.terminates_sequence ?? false;
|
|
39
237
|
return (handler) => {
|
|
40
|
-
|
|
238
|
+
const actionName = actionNameOverride ?? handler.name;
|
|
239
|
+
if (this.excludeActions.has(actionName)) {
|
|
41
240
|
return handler;
|
|
42
241
|
}
|
|
43
|
-
const
|
|
242
|
+
const parsedHandlerParams = extractFunctionParameters(handler);
|
|
243
|
+
let normalizedHandler = handler;
|
|
244
|
+
if (!options.param_model) {
|
|
245
|
+
const supportsCompatSignature = Boolean(parsedHandlerParams &&
|
|
246
|
+
parsedHandlerParams.length > 0 &&
|
|
247
|
+
!(parsedHandlerParams.length <= 2 &&
|
|
248
|
+
parsedHandlerParams[0]?.name === 'params'));
|
|
249
|
+
if (supportsCompatSignature && parsedHandlerParams) {
|
|
250
|
+
const actionParams = parsedHandlerParams.filter((entry) => !SPECIAL_PARAM_NAMES.has(entry.name));
|
|
251
|
+
const shape = Object.fromEntries(actionParams.map((entry) => [
|
|
252
|
+
entry.name,
|
|
253
|
+
entry.hasDefault ? z.any().optional() : z.any(),
|
|
254
|
+
]));
|
|
255
|
+
schema = z.object(shape).strict();
|
|
256
|
+
normalizedHandler = ((params, ctx) => {
|
|
257
|
+
const args = parsedHandlerParams.map((entry) => {
|
|
258
|
+
if (SPECIAL_PARAM_NAMES.has(entry.name)) {
|
|
259
|
+
const value = ctx[entry.name];
|
|
260
|
+
if ((value === null || value === undefined) &&
|
|
261
|
+
!entry.hasDefault) {
|
|
262
|
+
throw new Error(`Action ${actionName} requires ${entry.name} but none provided.`);
|
|
263
|
+
}
|
|
264
|
+
return value;
|
|
265
|
+
}
|
|
266
|
+
const value = params[entry.name];
|
|
267
|
+
if (value === undefined && !entry.hasDefault) {
|
|
268
|
+
throw new Error(`${actionName}() missing required parameter '${entry.name}'`);
|
|
269
|
+
}
|
|
270
|
+
return value;
|
|
271
|
+
});
|
|
272
|
+
return handler(...args);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const action = new RegisteredAction(actionName, description, normalizedHandler, schema, domains, pageFilter, terminatesSequence);
|
|
44
277
|
this.registry.register(action);
|
|
45
|
-
return
|
|
278
|
+
return normalizedHandler;
|
|
46
279
|
};
|
|
47
280
|
}
|
|
48
281
|
get_action(action_name) {
|
|
49
282
|
return this.registry.get(action_name);
|
|
50
283
|
}
|
|
284
|
+
exclude_action(action_name) {
|
|
285
|
+
this.excludeActions.add(action_name);
|
|
286
|
+
this.registry.remove(action_name);
|
|
287
|
+
}
|
|
288
|
+
remove_action(action_name) {
|
|
289
|
+
this.registry.remove(action_name);
|
|
290
|
+
}
|
|
51
291
|
get_all_actions() {
|
|
52
292
|
return this.registry.actionsMap;
|
|
53
293
|
}
|
|
@@ -55,14 +295,14 @@ export class Registry {
|
|
|
55
295
|
name: 'execute_action',
|
|
56
296
|
ignore_input: true,
|
|
57
297
|
ignore_output: true,
|
|
58
|
-
})(time_execution_async('--execute_action')(async (action_name, params, { browser_session = null, page_extraction_llm = null, file_system = null, sensitive_data = null, available_file_paths = null, signal = null, context = null, } = {}) => {
|
|
298
|
+
})(time_execution_async('--execute_action')(async (action_name, params, { browser_session = null, page_extraction_llm = null, extraction_schema = null, file_system = null, sensitive_data = null, available_file_paths = null, signal = null, context = null, } = {}) => {
|
|
59
299
|
const action = this.registry.get(action_name);
|
|
60
300
|
if (!action) {
|
|
61
301
|
throw new Error(`Action ${action_name} not found`);
|
|
62
302
|
}
|
|
63
303
|
const parsed = action.paramSchema.safeParse(params);
|
|
64
304
|
if (!parsed.success) {
|
|
65
|
-
throw new Error(`Invalid parameters for action ${action_name}: ${parsed.error.message}`);
|
|
305
|
+
throw new Error(`Invalid parameters ${safeJsonStringify(params)} for action ${action_name}: ${parsed.error.message}`);
|
|
66
306
|
}
|
|
67
307
|
let validatedParams = parsed.data;
|
|
68
308
|
let currentUrl = null;
|
|
@@ -86,11 +326,16 @@ export class Registry {
|
|
|
86
326
|
browser: browser_session,
|
|
87
327
|
browser_context: browser_session,
|
|
88
328
|
page,
|
|
329
|
+
page_url: currentUrl,
|
|
330
|
+
cdp_client: browser_session?.cdp_client ?? null,
|
|
89
331
|
page_extraction_llm,
|
|
332
|
+
extraction_schema,
|
|
90
333
|
file_system,
|
|
91
334
|
available_file_paths,
|
|
335
|
+
sensitive_data,
|
|
92
336
|
signal,
|
|
93
|
-
has_sensitive_data: action_name === 'input_text'
|
|
337
|
+
has_sensitive_data: (action_name === 'input_text' || action_name === 'input') &&
|
|
338
|
+
Boolean(sensitive_data),
|
|
94
339
|
};
|
|
95
340
|
if (signal?.aborted) {
|
|
96
341
|
throw createAbortError(signal.reason);
|
|
@@ -102,6 +347,12 @@ export class Registry {
|
|
|
102
347
|
if (signal?.aborted || isAbortError(error)) {
|
|
103
348
|
throw createAbortError(signal?.reason ?? error);
|
|
104
349
|
}
|
|
350
|
+
if (isTimeoutError(error)) {
|
|
351
|
+
throw new Error(`Error executing action ${action_name} due to timeout.`, { cause: error });
|
|
352
|
+
}
|
|
353
|
+
if (isSpecialContextMissingError(error)) {
|
|
354
|
+
throw error;
|
|
355
|
+
}
|
|
105
356
|
throw wrapActionExecutionError(action_name, error);
|
|
106
357
|
}
|
|
107
358
|
}));
|
|
@@ -134,10 +385,15 @@ export class Registry {
|
|
|
134
385
|
const missing = new Set();
|
|
135
386
|
const traverse = (value) => {
|
|
136
387
|
if (typeof value === 'string') {
|
|
137
|
-
return value.replace(secretPattern, (_,
|
|
388
|
+
return value.replace(secretPattern, (_, placeholderValue) => {
|
|
389
|
+
const placeholder = String(placeholderValue);
|
|
138
390
|
if (placeholder in applicableSecrets) {
|
|
139
391
|
replaced.add(placeholder);
|
|
140
|
-
|
|
392
|
+
const replacement = applicableSecrets[placeholder];
|
|
393
|
+
if (placeholder.endsWith('bu_2fa_code')) {
|
|
394
|
+
return generateTotpCode(replacement);
|
|
395
|
+
}
|
|
396
|
+
return replacement;
|
|
141
397
|
}
|
|
142
398
|
missing.add(placeholder);
|
|
143
399
|
return `<secret>${placeholder}</secret>`;
|
|
@@ -165,7 +421,7 @@ export class Registry {
|
|
|
165
421
|
return;
|
|
166
422
|
}
|
|
167
423
|
const urlInfo = currentUrl && !is_new_tab_page(currentUrl) ? ` on ${currentUrl}` : '';
|
|
168
|
-
logger.info(`🔒 Using sensitive data placeholders: ${Array.from(placeholders).join(', ')}${urlInfo}`);
|
|
424
|
+
logger.info(`🔒 Using sensitive data placeholders: ${Array.from(placeholders).sort().join(', ')}${urlInfo}`);
|
|
169
425
|
}
|
|
170
426
|
create_action_model(options = {}) {
|
|
171
427
|
const { include_actions = null, page = null } = options;
|
|
@@ -11,7 +11,8 @@ export declare class RegisteredAction {
|
|
|
11
11
|
readonly paramSchema: ZodTypeAny;
|
|
12
12
|
readonly domains: string[] | null;
|
|
13
13
|
readonly pageFilter: ((page: Page) => boolean) | null;
|
|
14
|
-
|
|
14
|
+
readonly terminates_sequence: boolean;
|
|
15
|
+
constructor(name: string, description: string, handler: ActionHandler, paramSchema: ZodTypeAny, domains?: string[] | null, pageFilter?: ((page: Page) => boolean) | null, terminates_sequence?: boolean);
|
|
15
16
|
promptDescription(): string;
|
|
16
17
|
}
|
|
17
18
|
export declare class ActionModel {
|
|
@@ -30,6 +31,7 @@ export declare class ActionModel {
|
|
|
30
31
|
export declare class ActionRegistry {
|
|
31
32
|
private actions;
|
|
32
33
|
register(action: RegisteredAction): void;
|
|
34
|
+
remove(name: string): void;
|
|
33
35
|
get(name: string): RegisteredAction | null;
|
|
34
36
|
getAll(): RegisteredAction[];
|
|
35
37
|
get actionsMap(): Map<string, RegisteredAction>;
|
|
@@ -46,6 +48,7 @@ export declare class SpecialActionParameters {
|
|
|
46
48
|
browser_context: BrowserSession | null;
|
|
47
49
|
page: Page | null;
|
|
48
50
|
page_extraction_llm: BaseChatModel | null;
|
|
51
|
+
extraction_schema: Record<string, unknown> | null;
|
|
49
52
|
file_system: FileSystem | null;
|
|
50
53
|
available_file_paths: string[] | null;
|
|
51
54
|
signal: AbortSignal | null;
|