browser-use 0.6.1 → 0.7.1
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 +24 -18
- package/dist/actor/element.js +24 -3
- package/dist/actor/mouse.js +21 -3
- package/dist/actor/page.js +33 -11
- package/dist/agent/gif.js +28 -3
- package/dist/agent/message-manager/service.js +2 -22
- package/dist/agent/message-manager/utils.js +15 -2
- package/dist/agent/message-manager/views.d.ts +7 -7
- package/dist/agent/message-manager/views.js +1 -0
- package/dist/agent/prompts.d.ts +3 -0
- package/dist/agent/prompts.js +22 -12
- package/dist/agent/service.d.ts +9 -1
- package/dist/agent/service.js +204 -79
- package/dist/agent/system_prompt.md +12 -11
- package/dist/agent/system_prompt_anthropic_flash.md +6 -5
- package/dist/agent/system_prompt_no_thinking.md +12 -11
- package/dist/agent/views.d.ts +2 -0
- package/dist/agent/views.js +48 -36
- package/dist/browser/extensions.js +20 -10
- package/dist/browser/profile.d.ts +4 -0
- package/dist/browser/profile.js +107 -4
- package/dist/browser/session.d.ts +28 -1
- package/dist/browser/session.js +1436 -528
- package/dist/browser/watchdogs/default-action-watchdog.js +32 -3
- package/dist/browser/watchdogs/downloads-watchdog.d.ts +4 -0
- package/dist/browser/watchdogs/downloads-watchdog.js +105 -9
- package/dist/browser/watchdogs/har-recording-watchdog.d.ts +1 -0
- package/dist/browser/watchdogs/har-recording-watchdog.js +54 -2
- package/dist/browser/watchdogs/permissions-watchdog.d.ts +5 -0
- package/dist/browser/watchdogs/permissions-watchdog.js +106 -3
- package/dist/browser/watchdogs/recording-watchdog.d.ts +2 -0
- package/dist/browser/watchdogs/recording-watchdog.js +54 -2
- package/dist/browser/watchdogs/security-watchdog.d.ts +1 -0
- package/dist/browser/watchdogs/security-watchdog.js +47 -7
- package/dist/browser/watchdogs/storage-state-watchdog.d.ts +6 -0
- package/dist/browser/watchdogs/storage-state-watchdog.js +206 -14
- package/dist/cli.d.ts +13 -2
- package/dist/cli.js +190 -9
- package/dist/code-use/namespace.js +52 -7
- package/dist/code-use/notebook-export.js +18 -2
- package/dist/code-use/service.js +1 -0
- package/dist/config.js +26 -4
- package/dist/controller/action-timeout.d.ts +9 -0
- package/dist/controller/action-timeout.js +95 -0
- package/dist/controller/registry/service.d.ts +1 -0
- package/dist/controller/registry/service.js +28 -1
- package/dist/controller/service.d.ts +2 -1
- package/dist/controller/service.js +494 -329
- package/dist/entrypoint.d.ts +1 -0
- package/dist/entrypoint.js +27 -0
- package/dist/filesystem/file-system.js +38 -8
- package/dist/integrations/gmail/service.js +30 -6
- package/dist/llm/browser-use/chat.js +2 -2
- package/dist/llm/codex/auth.d.ts +118 -0
- package/dist/llm/codex/auth.js +599 -0
- package/dist/llm/codex/chat.d.ts +70 -0
- package/dist/llm/codex/chat.js +392 -0
- package/dist/llm/codex/index.d.ts +2 -0
- package/dist/llm/codex/index.js +2 -0
- package/dist/llm/google/chat.js +18 -1
- package/dist/logging-config.js +22 -11
- package/dist/mcp/client.d.ts +1 -0
- package/dist/mcp/client.js +12 -10
- package/dist/mcp/redaction.d.ts +3 -0
- package/dist/mcp/redaction.js +132 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +64 -22
- package/dist/screenshots/service.js +25 -2
- package/dist/skill-cli/direct.d.ts +4 -1
- package/dist/skill-cli/direct.js +263 -66
- package/dist/skill-cli/server.d.ts +1 -0
- package/dist/skill-cli/server.js +115 -25
- package/dist/skill-cli/tunnel.d.ts +1 -0
- package/dist/skill-cli/tunnel.js +16 -4
- package/dist/sync/auth.js +22 -9
- package/dist/telemetry/service.js +21 -2
- package/dist/telemetry/views.js +31 -8
- package/dist/tokens/custom-pricing.js +2 -2
- package/dist/tokens/openrouter-pricing.d.ts +11 -0
- package/dist/tokens/openrouter-pricing.js +102 -0
- package/dist/tokens/service.js +20 -16
- package/dist/utils.d.ts +3 -1
- package/dist/utils.js +3 -1
- package/package.json +68 -27
package/dist/agent/service.js
CHANGED
|
@@ -10,10 +10,11 @@ import { CONFIG } from '../config.js';
|
|
|
10
10
|
import { EventBus } from '../event-bus.js';
|
|
11
11
|
import { uuid7str, SignalHandler, get_browser_use_version, check_latest_browser_use_version, sanitize_surrogates, } from '../utils.js';
|
|
12
12
|
import { Controller as DefaultController } from '../controller/service.js';
|
|
13
|
+
import { isActionTimeoutError, runActionWithTimeout, } from '../controller/action-timeout.js';
|
|
13
14
|
import { FileSystem as AgentFileSystem, DEFAULT_FILE_SYSTEM_PATH, } from '../filesystem/file-system.js';
|
|
14
15
|
import { SystemPrompt, get_ai_step_system_prompt, get_ai_step_user_prompt, get_rerun_summary_message, get_rerun_summary_prompt, } from './prompts.js';
|
|
15
16
|
import { MessageManager } from './message-manager/service.js';
|
|
16
|
-
import { BrowserStateHistory } from '../browser/views.js';
|
|
17
|
+
import { BrowserError, BrowserStateHistory, } from '../browser/views.js';
|
|
17
18
|
import { BrowserSession } from '../browser/session.js';
|
|
18
19
|
import { BrowserProfile, DEFAULT_BROWSER_PROFILE } from '../browser/profile.js';
|
|
19
20
|
import { HistoryTreeProcessor } from '../dom/history-tree-processor/service.js';
|
|
@@ -24,7 +25,7 @@ import { ChatBrowserUse } from '../llm/browser-use/chat.js';
|
|
|
24
25
|
import { ModelProviderError, ModelRateLimitError } from '../llm/exceptions.js';
|
|
25
26
|
import { AssistantMessage, ContentPartTextParam, SystemMessage, UserMessage, } from '../llm/messages.js';
|
|
26
27
|
import { getLlmByName } from '../llm/models.js';
|
|
27
|
-
import { ActionResult, AgentHistory, AgentHistoryList, AgentOutput, AgentState, AgentStepInfo, AgentError, StepMetadata, ActionModel, PlanItem, defaultMessageCompactionSettings, normalizeMessageCompactionSettings, } from './views.js';
|
|
28
|
+
import { ActionResult, AgentHistory, AgentHistoryList, AgentOutput, AgentState, AgentStepInfo, AgentError, StepMetadata, ActionModel, PlanItem, defaultMessageCompactionSettings, normalizeMessageCompactionSettings, redactSensitiveDataFromString, } from './views.js';
|
|
28
29
|
import { detect_variables_in_history, substitute_in_dict, } from './variable-detector.js';
|
|
29
30
|
import { CreateAgentOutputFileEvent, CreateAgentSessionEvent, CreateAgentTaskEvent, CreateAgentStepEvent, UpdateAgentTaskEvent, } from './cloud-events.js';
|
|
30
31
|
import { create_history_gif } from './gif.js';
|
|
@@ -37,28 +38,30 @@ import { CloudSkillService, MissingCookieException, build_skill_parameters_schem
|
|
|
37
38
|
loadEnv({ quiet: true });
|
|
38
39
|
const logger = createLogger('browser_use.agent');
|
|
39
40
|
const URL_PATTERN = /https?:\/\/[^\s<>"']+|www\.[^\s<>"']+|[^\s<>"']+\.[a-z]{2,}(?:\/[^\s<>"']*)?/gi;
|
|
40
|
-
export const log_response = (response, registry, logInstance = logger) => {
|
|
41
|
+
export const log_response = (response, registry, logInstance = logger, sensitive_data = null) => {
|
|
42
|
+
const redact = (value) => redactSensitiveDataFromString(value, sensitive_data);
|
|
41
43
|
if (response.current_state.thinking) {
|
|
42
|
-
logInstance.debug(`💡 Thinking:\n${response.current_state.thinking}`);
|
|
44
|
+
logInstance.debug(`💡 Thinking:\n${redact(response.current_state.thinking)}`);
|
|
43
45
|
}
|
|
44
46
|
const evalGoal = response.current_state.evaluation_previous_goal;
|
|
45
47
|
if (evalGoal) {
|
|
48
|
+
const redactedEvalGoal = redact(evalGoal);
|
|
46
49
|
if (evalGoal.toLowerCase().includes('success')) {
|
|
47
|
-
logInstance.info(` \x1b[32m👍 Eval: ${
|
|
50
|
+
logInstance.info(` \x1b[32m👍 Eval: ${redactedEvalGoal}\x1b[0m`);
|
|
48
51
|
}
|
|
49
52
|
else if (evalGoal.toLowerCase().includes('failure')) {
|
|
50
|
-
logInstance.info(` \x1b[31m⚠️ Eval: ${
|
|
53
|
+
logInstance.info(` \x1b[31m⚠️ Eval: ${redactedEvalGoal}\x1b[0m`);
|
|
51
54
|
}
|
|
52
55
|
else {
|
|
53
|
-
logInstance.info(` ❔ Eval: ${
|
|
56
|
+
logInstance.info(` ❔ Eval: ${redactedEvalGoal}`);
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
if (response.current_state.memory) {
|
|
57
|
-
logInstance.info(` 🧠 Memory: ${response.current_state.memory}`);
|
|
60
|
+
logInstance.info(` 🧠 Memory: ${redact(response.current_state.memory)}`);
|
|
58
61
|
}
|
|
59
62
|
const nextGoal = response.current_state.next_goal;
|
|
60
63
|
if (nextGoal) {
|
|
61
|
-
logInstance.info(` \x1b[34m🎯 Next goal: ${nextGoal}\x1b[0m`);
|
|
64
|
+
logInstance.info(` \x1b[34m🎯 Next goal: ${redact(nextGoal)}\x1b[0m`);
|
|
62
65
|
}
|
|
63
66
|
};
|
|
64
67
|
class AsyncMutex {
|
|
@@ -103,8 +106,10 @@ class ExecutionTimeoutError extends Error {
|
|
|
103
106
|
}
|
|
104
107
|
}
|
|
105
108
|
const ensureDir = (target) => {
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
const existed = fs.existsSync(target);
|
|
110
|
+
fs.mkdirSync(target, { recursive: true, mode: 0o700 });
|
|
111
|
+
if (!existed && process.platform !== 'win32') {
|
|
112
|
+
fs.chmodSync(target, 0o700);
|
|
108
113
|
}
|
|
109
114
|
};
|
|
110
115
|
const resolve_agent_llm = (llm) => {
|
|
@@ -183,6 +188,11 @@ const defaultAgentOptions = () => ({
|
|
|
183
188
|
loop_detection_enabled: true,
|
|
184
189
|
_url_shortening_limit: 25,
|
|
185
190
|
});
|
|
191
|
+
const chmodPrivateFile = async (filePath) => {
|
|
192
|
+
if (process.platform !== 'win32') {
|
|
193
|
+
await fs.promises.chmod(filePath, 0o600);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
186
196
|
const AgentLLMOutputSchema = z.object({
|
|
187
197
|
thinking: z.string().optional().nullable(),
|
|
188
198
|
evaluation_previous_goal: z.string().optional().nullable(),
|
|
@@ -290,6 +300,9 @@ export class Agent {
|
|
|
290
300
|
_url_shortening_limit = 25;
|
|
291
301
|
skill_service = null;
|
|
292
302
|
_skills_registered = false;
|
|
303
|
+
_redactSensitiveText(value) {
|
|
304
|
+
return redactSensitiveDataFromString(value, this.sensitive_data ?? null);
|
|
305
|
+
}
|
|
293
306
|
constructor(params) {
|
|
294
307
|
const { task, llm, page = null, browser = null, browser_context = null, browser_profile = null, browser_session = null, tools = null, controller = null, sensitive_data = null, initial_actions = null, directly_open_url = true, register_new_step_callback = null, register_done_callback = null, register_should_stop_callback = null, register_external_agent_status_raise_error_callback = null, output_model_schema = null, extraction_schema = null, use_vision = true, include_recent_events = false, sample_images = null, llm_screenshot_size = null, save_conversation_path = null, save_conversation_path_encoding = 'utf-8', max_failures = 3, override_system_message = null, extend_system_message = null, generate_gif = false, available_file_paths = [], include_attributes, max_actions_per_step = 5, use_thinking = true, flash_mode = false, use_judge = true, ground_truth = null, max_history_items = null, page_extraction_llm = null, fallback_llm = null, judge_llm = null, skill_ids = null, skills = null, skill_service = null, enable_planning = true, planning_replan_on_stall = 3, planning_exploration_limit = 5, context = null, source = null, file_system_path = null, task_id = null, cloud_sync = null, calculate_cost = false, display_files_in_done_text = true, include_tool_call_examples = false, vision_detail_level = 'auto', session_attachment_mode = 'copy', llm_timeout = null, step_timeout = 180, final_response_after_failure = true, message_compaction = true, loop_detection_window = 20, loop_detection_enabled = true, _url_shortening_limit = 25, } = { ...defaultAgentOptions(), ...params };
|
|
295
308
|
const resolvedLlm = resolve_agent_llm(llm);
|
|
@@ -408,7 +421,7 @@ export class Agent {
|
|
|
408
421
|
const extractedUrl = this._extract_start_url(task);
|
|
409
422
|
if (extractedUrl) {
|
|
410
423
|
this.initial_url = extractedUrl;
|
|
411
|
-
this.logger.info(`🔗 Found URL in task: ${extractedUrl}, adding as initial action...`);
|
|
424
|
+
this.logger.info(`🔗 Found URL in task: ${this._redactSensitiveText(extractedUrl)}, adding as initial action...`);
|
|
412
425
|
resolvedInitialActions = [
|
|
413
426
|
{ go_to_url: { url: extractedUrl, new_tab: false } },
|
|
414
427
|
];
|
|
@@ -1189,7 +1202,7 @@ export class Agent {
|
|
|
1189
1202
|
}
|
|
1190
1203
|
}
|
|
1191
1204
|
if (shouldExclude) {
|
|
1192
|
-
this.logger.debug(`Excluding URL with file extension from auto-navigation: ${url}`);
|
|
1205
|
+
this.logger.debug(`Excluding URL with file extension from auto-navigation: ${this._redactSensitiveText(url)}`);
|
|
1193
1206
|
continue;
|
|
1194
1207
|
}
|
|
1195
1208
|
const contextStart = Math.max(0, startIndex - 20);
|
|
@@ -1197,7 +1210,7 @@ export class Agent {
|
|
|
1197
1210
|
.slice(contextStart, startIndex)
|
|
1198
1211
|
.toLowerCase();
|
|
1199
1212
|
if (excludedWords.some((word) => contextText.includes(word))) {
|
|
1200
|
-
this.logger.debug(`Excluding URL with word in excluded words from auto-navigation: ${url} (context: "${contextText.trim()}")`);
|
|
1213
|
+
this.logger.debug(`Excluding URL with word in excluded words from auto-navigation: ${this._redactSensitiveText(url)} (context: "${this._redactSensitiveText(contextText.trim())}")`);
|
|
1201
1214
|
continue;
|
|
1202
1215
|
}
|
|
1203
1216
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
|
@@ -1288,9 +1301,9 @@ export class Agent {
|
|
|
1288
1301
|
}
|
|
1289
1302
|
}
|
|
1290
1303
|
const paramStr = paramSummary.length > 0 ? `(${paramSummary.join(', ')})` : '';
|
|
1291
|
-
actionDetails.push(`${actionName}${paramStr}`);
|
|
1304
|
+
actionDetails.push(this._redactSensitiveText(`${actionName}${paramStr}`));
|
|
1292
1305
|
lastActionName = actionName;
|
|
1293
|
-
lastParamStr = paramStr;
|
|
1306
|
+
lastParamStr = this._redactSensitiveText(paramStr);
|
|
1294
1307
|
}
|
|
1295
1308
|
// Create summary based on single vs multi-action
|
|
1296
1309
|
if (actionCount === 1) {
|
|
@@ -1355,6 +1368,21 @@ export class Agent {
|
|
|
1355
1368
|
this.DoneAgentOutput = AgentOutput.type_with_custom_actions_no_thinking(this.DoneActionModel);
|
|
1356
1369
|
}
|
|
1357
1370
|
}
|
|
1371
|
+
_filter_cookies_for_domain_policy(browser_session, cookies) {
|
|
1372
|
+
const checker = browser_session._get_cookie_access_denial_reason;
|
|
1373
|
+
if (typeof checker !== 'function') {
|
|
1374
|
+
return cookies;
|
|
1375
|
+
}
|
|
1376
|
+
return cookies.filter((cookie) => {
|
|
1377
|
+
try {
|
|
1378
|
+
return checker.call(browser_session, cookie) == null;
|
|
1379
|
+
}
|
|
1380
|
+
catch (error) {
|
|
1381
|
+
this.logger.debug(`Skipping skill cookie because domain policy check failed: ${error.message}`);
|
|
1382
|
+
return false;
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1358
1386
|
async _register_skills_as_actions() {
|
|
1359
1387
|
if (!this.skill_service || this._skills_registered) {
|
|
1360
1388
|
return;
|
|
@@ -1386,8 +1414,9 @@ export class Agent {
|
|
|
1386
1414
|
}
|
|
1387
1415
|
try {
|
|
1388
1416
|
const cookiesRaw = await browser_session.get_cookies();
|
|
1389
|
-
const
|
|
1390
|
-
|
|
1417
|
+
const allowedCookies = this._filter_cookies_for_domain_policy(browser_session, Array.isArray(cookiesRaw) ? cookiesRaw : []);
|
|
1418
|
+
const cookies = allowedCookies.length > 0
|
|
1419
|
+
? allowedCookies
|
|
1391
1420
|
.map((cookie) => {
|
|
1392
1421
|
const record = cookie && typeof cookie === 'object'
|
|
1393
1422
|
? cookie
|
|
@@ -1455,18 +1484,17 @@ export class Agent {
|
|
|
1455
1484
|
return '';
|
|
1456
1485
|
}
|
|
1457
1486
|
const currentCookies = await this.browser_session.get_cookies();
|
|
1487
|
+
const allowedCookies = this._filter_cookies_for_domain_policy(this.browser_session, Array.isArray(currentCookies) ? currentCookies : []);
|
|
1458
1488
|
const cookieNames = new Set();
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
cookieNames.add(name);
|
|
1469
|
-
}
|
|
1489
|
+
for (const cookie of allowedCookies) {
|
|
1490
|
+
if (!cookie || typeof cookie !== 'object') {
|
|
1491
|
+
continue;
|
|
1492
|
+
}
|
|
1493
|
+
const name = typeof cookie.name === 'string'
|
|
1494
|
+
? String(cookie.name)
|
|
1495
|
+
: '';
|
|
1496
|
+
if (name) {
|
|
1497
|
+
cookieNames.add(name);
|
|
1470
1498
|
}
|
|
1471
1499
|
}
|
|
1472
1500
|
const unavailableSkills = [];
|
|
@@ -1516,9 +1544,10 @@ export class Agent {
|
|
|
1516
1544
|
return lines.join('\n');
|
|
1517
1545
|
}
|
|
1518
1546
|
catch (error) {
|
|
1519
|
-
|
|
1547
|
+
const message = error instanceof Error
|
|
1520
1548
|
? `${error.name}: ${error.message}`
|
|
1521
|
-
: String(error)
|
|
1549
|
+
: String(error);
|
|
1550
|
+
this.logger.error(`Error getting unavailable skills info: ${this._redactSensitiveText(message)}`);
|
|
1522
1551
|
return '';
|
|
1523
1552
|
}
|
|
1524
1553
|
}
|
|
@@ -1669,7 +1698,7 @@ export class Agent {
|
|
|
1669
1698
|
const isTimeout = error instanceof ExecutionTimeoutError;
|
|
1670
1699
|
if (isTimeout) {
|
|
1671
1700
|
const timeoutMessage = `Step ${currentStep + 1} timed out after ${this.settings.step_timeout} seconds`;
|
|
1672
|
-
this.logger.error(`⏰ ${timeoutMessage}`);
|
|
1701
|
+
this.logger.error(`⏰ ${this._redactSensitiveText(timeoutMessage)}`);
|
|
1673
1702
|
this.state.consecutive_failures += 1;
|
|
1674
1703
|
this.state.last_result = [
|
|
1675
1704
|
new ActionResult({ error: timeoutMessage }),
|
|
@@ -1680,7 +1709,7 @@ export class Agent {
|
|
|
1680
1709
|
agent_run_error = timeoutMessage;
|
|
1681
1710
|
break;
|
|
1682
1711
|
}
|
|
1683
|
-
this.logger.error(`❌ Unhandled step error at step ${currentStep + 1}: ${message}`);
|
|
1712
|
+
this.logger.error(`❌ Unhandled step error at step ${currentStep + 1}: ${this._redactSensitiveText(message)}`);
|
|
1684
1713
|
this.state.consecutive_failures += 1;
|
|
1685
1714
|
this.state.last_result = [
|
|
1686
1715
|
new ActionResult({
|
|
@@ -1718,7 +1747,7 @@ export class Agent {
|
|
|
1718
1747
|
include_in_memory: true,
|
|
1719
1748
|
}),
|
|
1720
1749
|
], new BrowserStateHistory('', '', [], [], null), null));
|
|
1721
|
-
this.logger.info(`❌ ${agent_run_error}`);
|
|
1750
|
+
this.logger.info(`❌ ${this._redactSensitiveText(agent_run_error)}`);
|
|
1722
1751
|
}
|
|
1723
1752
|
this.logger.debug('📊 Collecting usage summary...');
|
|
1724
1753
|
this.history.usage =
|
|
@@ -1731,7 +1760,7 @@ export class Agent {
|
|
|
1731
1760
|
}
|
|
1732
1761
|
catch (error) {
|
|
1733
1762
|
agent_run_error = error instanceof Error ? error.message : String(error);
|
|
1734
|
-
this.logger.error(`Agent run failed with exception: ${agent_run_error}`);
|
|
1763
|
+
this.logger.error(`Agent run failed with exception: ${this._redactSensitiveText(agent_run_error)}`);
|
|
1735
1764
|
throw error;
|
|
1736
1765
|
}
|
|
1737
1766
|
finally {
|
|
@@ -1813,7 +1842,7 @@ export class Agent {
|
|
|
1813
1842
|
catch (error) {
|
|
1814
1843
|
if (signal?.aborted) {
|
|
1815
1844
|
const message = error instanceof Error ? error.message : String(error);
|
|
1816
|
-
this.logger.debug(`Step aborted before completion: ${message}`);
|
|
1845
|
+
this.logger.debug(`Step aborted before completion: ${this._redactSensitiveText(message)}`);
|
|
1817
1846
|
}
|
|
1818
1847
|
else {
|
|
1819
1848
|
await this._handle_step_error(error);
|
|
@@ -1890,7 +1919,7 @@ export class Agent {
|
|
|
1890
1919
|
}
|
|
1891
1920
|
catch (error) {
|
|
1892
1921
|
const message = error instanceof Error ? error.message : String(error);
|
|
1893
|
-
this.logger.error(`📸 Failed to store screenshot for step ${this.state.n_steps}: ${message}`);
|
|
1922
|
+
this.logger.error(`📸 Failed to store screenshot for step ${this.state.n_steps}: ${this._redactSensitiveText(message)}`);
|
|
1894
1923
|
this._current_screenshot_path = null;
|
|
1895
1924
|
}
|
|
1896
1925
|
}
|
|
@@ -1961,10 +1990,10 @@ export class Agent {
|
|
|
1961
1990
|
? finalResult.extracted_content
|
|
1962
1991
|
: String(finalResult.extracted_content ?? '');
|
|
1963
1992
|
if (success) {
|
|
1964
|
-
this.logger.info(`\n📄 \x1b[32m Final Result:\x1b[0m \n${renderedContent}\n\n`);
|
|
1993
|
+
this.logger.info(`\n📄 \x1b[32m Final Result:\x1b[0m \n${this._redactSensitiveText(renderedContent)}\n\n`);
|
|
1965
1994
|
}
|
|
1966
1995
|
else {
|
|
1967
|
-
this.logger.info(`\n📄 \x1b[31m Final Result:\x1b[0m \n${renderedContent}\n\n`);
|
|
1996
|
+
this.logger.info(`\n📄 \x1b[31m Final Result:\x1b[0m \n${this._redactSensitiveText(renderedContent)}\n\n`);
|
|
1968
1997
|
}
|
|
1969
1998
|
const attachments = Array.isArray(finalResult.attachments)
|
|
1970
1999
|
? finalResult.attachments
|
|
@@ -1977,7 +2006,7 @@ export class Agent {
|
|
|
1977
2006
|
}
|
|
1978
2007
|
}
|
|
1979
2008
|
async multi_act(actions, options = {}) {
|
|
1980
|
-
const { signal = null } = options;
|
|
2009
|
+
const { signal = null, action_timeout = null } = options;
|
|
1981
2010
|
const results = [];
|
|
1982
2011
|
if (!this.browser_session) {
|
|
1983
2012
|
throw new Error('BrowserSession is not set up');
|
|
@@ -2014,7 +2043,7 @@ export class Agent {
|
|
|
2014
2043
|
const preActionFocusTargetId = this.browser_session.agent_focus_target_id ??
|
|
2015
2044
|
this.browser_session.active_tab?.page_id ??
|
|
2016
2045
|
null;
|
|
2017
|
-
const actResult = await this.controller.registry.execute_action(actionName, actionParams, {
|
|
2046
|
+
const actResult = await runActionWithTimeout(actionName, action_timeout, signal, (actionSignal) => this.controller.registry.execute_action(actionName, actionParams, {
|
|
2018
2047
|
browser_session: this.browser_session,
|
|
2019
2048
|
page_extraction_llm: this.settings.page_extraction_llm,
|
|
2020
2049
|
extraction_schema: this.extraction_schema,
|
|
@@ -2022,11 +2051,11 @@ export class Agent {
|
|
|
2022
2051
|
available_file_paths: this.available_file_paths,
|
|
2023
2052
|
file_system: this.file_system,
|
|
2024
2053
|
context: this.context ?? undefined,
|
|
2025
|
-
signal,
|
|
2026
|
-
});
|
|
2054
|
+
signal: actionSignal,
|
|
2055
|
+
}));
|
|
2027
2056
|
results.push(actResult);
|
|
2028
2057
|
// Log action execution
|
|
2029
|
-
this.logger.info(`☑️ Executed action ${i + 1}/${actions.length}: ${actionName}(${JSON.stringify(actionParams)})`);
|
|
2058
|
+
this.logger.info(`☑️ Executed action ${i + 1}/${actions.length}: ${actionName}(${this._redactSensitiveText(JSON.stringify(actionParams))})`);
|
|
2030
2059
|
// Break early if done, error, or last action
|
|
2031
2060
|
if (results[results.length - 1]?.is_done ||
|
|
2032
2061
|
results[results.length - 1]?.error ||
|
|
@@ -2055,14 +2084,87 @@ export class Agent {
|
|
|
2055
2084
|
this._capture_shared_pinned_tab();
|
|
2056
2085
|
}
|
|
2057
2086
|
catch (error) {
|
|
2058
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2059
|
-
this.logger.error(`❌ Action ${i + 1} failed: ${message}`);
|
|
2060
2087
|
this._capture_shared_pinned_tab();
|
|
2061
|
-
|
|
2088
|
+
if (this._shouldPropagateActionError(error)) {
|
|
2089
|
+
throw error;
|
|
2090
|
+
}
|
|
2091
|
+
if (isActionTimeoutError(error)) {
|
|
2092
|
+
this.logger.error(`❌ Action ${i + 1} failed: ${this._redactSensitiveText(error.message)}`);
|
|
2093
|
+
results.push(new ActionResult({ error: error.message }));
|
|
2094
|
+
return results;
|
|
2095
|
+
}
|
|
2096
|
+
if (error instanceof BrowserError) {
|
|
2097
|
+
const browserErrorResult = this._actionResultFromBrowserError(error);
|
|
2098
|
+
if (browserErrorResult) {
|
|
2099
|
+
this.logger.error(`❌ Action ${i + 1} failed with BrowserError: ${this._redactSensitiveText(error.toString())}`);
|
|
2100
|
+
results.push(browserErrorResult);
|
|
2101
|
+
return results;
|
|
2102
|
+
}
|
|
2103
|
+
throw error;
|
|
2104
|
+
}
|
|
2105
|
+
const registryTimeoutResult = this._actionResultFromRegistryTimeout(actionName, error);
|
|
2106
|
+
if (registryTimeoutResult) {
|
|
2107
|
+
this.logger.error(`❌ Action ${i + 1} failed: ${this._redactSensitiveText(registryTimeoutResult.error ?? '')}`);
|
|
2108
|
+
results.push(registryTimeoutResult);
|
|
2109
|
+
return results;
|
|
2110
|
+
}
|
|
2111
|
+
const message = this._formatActionExecutionError(error);
|
|
2112
|
+
this.logger.error(`❌ Action ${i + 1} failed: ${this._redactSensitiveText(message)}`);
|
|
2113
|
+
results.push(new ActionResult({ error: message }));
|
|
2114
|
+
return results;
|
|
2062
2115
|
}
|
|
2063
2116
|
}
|
|
2064
2117
|
return results;
|
|
2065
2118
|
}
|
|
2119
|
+
_shouldPropagateActionError(error) {
|
|
2120
|
+
if (error instanceof Error) {
|
|
2121
|
+
if (error.name === 'InterruptedError' || error.name === 'AbortError') {
|
|
2122
|
+
return true;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
return this._isConnectionLikeError(error);
|
|
2126
|
+
}
|
|
2127
|
+
_isConnectionLikeError(error) {
|
|
2128
|
+
const name = error instanceof Error ? error.name : '';
|
|
2129
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2130
|
+
const text = `${name} ${message}`.toLowerCase();
|
|
2131
|
+
return (name === 'ConnectionError' ||
|
|
2132
|
+
text.includes('websocket connection closed') ||
|
|
2133
|
+
text.includes('connection closed') ||
|
|
2134
|
+
text.includes('browser has been closed') ||
|
|
2135
|
+
text.includes('browser closed') ||
|
|
2136
|
+
text.includes('no browser'));
|
|
2137
|
+
}
|
|
2138
|
+
_formatActionExecutionError(error) {
|
|
2139
|
+
const typeName = error instanceof Error
|
|
2140
|
+
? error.name || error.constructor.name || 'Error'
|
|
2141
|
+
: 'Error';
|
|
2142
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2143
|
+
return `${typeName}: ${message}`;
|
|
2144
|
+
}
|
|
2145
|
+
_actionResultFromBrowserError(error) {
|
|
2146
|
+
if (error.long_term_memory == null) {
|
|
2147
|
+
this.logger.warning('⚠️ A BrowserError was raised without long_term_memory - always set long_term_memory when raising BrowserError to propagate right messages to LLM.');
|
|
2148
|
+
return null;
|
|
2149
|
+
}
|
|
2150
|
+
if (error.short_term_memory != null) {
|
|
2151
|
+
return new ActionResult({
|
|
2152
|
+
extracted_content: error.short_term_memory,
|
|
2153
|
+
error: error.long_term_memory,
|
|
2154
|
+
include_extracted_content_only_once: true,
|
|
2155
|
+
});
|
|
2156
|
+
}
|
|
2157
|
+
return new ActionResult({ error: error.long_term_memory });
|
|
2158
|
+
}
|
|
2159
|
+
_actionResultFromRegistryTimeout(actionName, error) {
|
|
2160
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2161
|
+
if (message !== `Error executing action ${actionName} due to timeout.`) {
|
|
2162
|
+
return null;
|
|
2163
|
+
}
|
|
2164
|
+
return new ActionResult({
|
|
2165
|
+
error: `${actionName} was not executed due to timeout.`,
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2066
2168
|
async _generate_rerun_summary(originalTask, results, summaryLlm = null, signal = null) {
|
|
2067
2169
|
if (!this.browser_session) {
|
|
2068
2170
|
return new ActionResult({
|
|
@@ -2077,7 +2179,8 @@ export class Agent {
|
|
|
2077
2179
|
screenshotB64 = await this.browser_session.take_screenshot(false);
|
|
2078
2180
|
}
|
|
2079
2181
|
catch (error) {
|
|
2080
|
-
|
|
2182
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2183
|
+
this.logger.warning(`Failed to capture screenshot for rerun summary: ${this._redactSensitiveText(message)}`);
|
|
2081
2184
|
}
|
|
2082
2185
|
const errorCount = results.filter((result) => Boolean(result.error)).length;
|
|
2083
2186
|
const successCount = results.length - errorCount;
|
|
@@ -2105,7 +2208,7 @@ export class Agent {
|
|
|
2105
2208
|
!['complete', 'partial', 'failed'].includes(String(summary.completion_status))) {
|
|
2106
2209
|
throw new Error('Structured rerun summary response did not match expected schema');
|
|
2107
2210
|
}
|
|
2108
|
-
this.logger.info(`Rerun Summary: ${summary.summary}`);
|
|
2211
|
+
this.logger.info(`Rerun Summary: ${this._redactSensitiveText(summary.summary)}`);
|
|
2109
2212
|
this.logger.info(`Rerun Status: ${summary.completion_status} (success=${summary.success})`);
|
|
2110
2213
|
return new ActionResult({
|
|
2111
2214
|
is_done: true,
|
|
@@ -2115,9 +2218,10 @@ export class Agent {
|
|
|
2115
2218
|
});
|
|
2116
2219
|
}
|
|
2117
2220
|
catch (structuredError) {
|
|
2118
|
-
|
|
2221
|
+
const message = structuredError instanceof Error
|
|
2119
2222
|
? structuredError.message
|
|
2120
|
-
: String(structuredError)
|
|
2223
|
+
: String(structuredError);
|
|
2224
|
+
this.logger.debug(`Structured rerun summary failed: ${this._redactSensitiveText(message)}, falling back to text response`);
|
|
2121
2225
|
}
|
|
2122
2226
|
try {
|
|
2123
2227
|
const response = await llm.ainvoke([message], undefined, {
|
|
@@ -2135,7 +2239,8 @@ export class Agent {
|
|
|
2135
2239
|
});
|
|
2136
2240
|
}
|
|
2137
2241
|
catch (error) {
|
|
2138
|
-
|
|
2242
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2243
|
+
this.logger.warning(`Failed to generate rerun summary: ${this._redactSensitiveText(message)}`);
|
|
2139
2244
|
return new ActionResult({
|
|
2140
2245
|
is_done: true,
|
|
2141
2246
|
success: errorCount === 0,
|
|
@@ -2159,10 +2264,17 @@ export class Agent {
|
|
|
2159
2264
|
if (!page || typeof page.content !== 'function') {
|
|
2160
2265
|
throw new Error('No page available for markdown extraction');
|
|
2161
2266
|
}
|
|
2267
|
+
await this.browser_session.validate_page_after_action(page, signal);
|
|
2162
2268
|
if (typeof page.url === 'function') {
|
|
2163
2269
|
currentUrl = page.url();
|
|
2164
2270
|
}
|
|
2165
|
-
|
|
2271
|
+
let html = '';
|
|
2272
|
+
try {
|
|
2273
|
+
html = (await page.content()) || '';
|
|
2274
|
+
}
|
|
2275
|
+
finally {
|
|
2276
|
+
await this.browser_session.validate_page_after_action(page, signal);
|
|
2277
|
+
}
|
|
2166
2278
|
const extracted = extractCleanMarkdownFromHtml(html, {
|
|
2167
2279
|
extract_links: extractLinks,
|
|
2168
2280
|
});
|
|
@@ -2191,7 +2303,8 @@ export class Agent {
|
|
|
2191
2303
|
(await this.browser_session.take_screenshot?.(false)) ?? null;
|
|
2192
2304
|
}
|
|
2193
2305
|
catch (error) {
|
|
2194
|
-
|
|
2306
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2307
|
+
this.logger.warning(`Failed to capture screenshot for ai_step: ${this._redactSensitiveText(message)}`);
|
|
2195
2308
|
}
|
|
2196
2309
|
}
|
|
2197
2310
|
const userMessage = screenshotB64
|
|
@@ -2226,9 +2339,10 @@ export class Agent {
|
|
|
2226
2339
|
});
|
|
2227
2340
|
}
|
|
2228
2341
|
catch (error) {
|
|
2229
|
-
|
|
2342
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2343
|
+
this.logger.warning(`Failed to execute AI step: ${this._redactSensitiveText(message)}`);
|
|
2230
2344
|
return new ActionResult({
|
|
2231
|
-
error: `AI step failed: ${
|
|
2345
|
+
error: `AI step failed: ${message}`,
|
|
2232
2346
|
});
|
|
2233
2347
|
}
|
|
2234
2348
|
}
|
|
@@ -2261,7 +2375,7 @@ export class Agent {
|
|
|
2261
2375
|
delaySource = `using saved step_interval=${this._formatDelaySeconds(stepDelay)}`;
|
|
2262
2376
|
}
|
|
2263
2377
|
}
|
|
2264
|
-
this.logger.info(`Replaying ${stepName} (${index + 1}/${history.history.length}) [${delaySource}]: ${goal}`);
|
|
2378
|
+
this.logger.info(`Replaying ${stepName} (${index + 1}/${history.history.length}) [${delaySource}]: ${this._redactSensitiveText(goal)}`);
|
|
2265
2379
|
const actions = historyItem.model_output?.action ?? [];
|
|
2266
2380
|
const hasValidAction = actions.length && !actions.every((action) => action == null);
|
|
2267
2381
|
if (!historyItem.model_output || !hasValidAction) {
|
|
@@ -2279,7 +2393,7 @@ export class Agent {
|
|
|
2279
2393
|
const preview = firstError.length > 100
|
|
2280
2394
|
? `${firstError.slice(0, 100)}...`
|
|
2281
2395
|
: firstError;
|
|
2282
|
-
this.logger.warning(`${stepName}: Original step had error(s), skipping (skip_failures=true): ${preview}`);
|
|
2396
|
+
this.logger.warning(`${stepName}: Original step had error(s), skipping (skip_failures=true): ${this._redactSensitiveText(preview)}`);
|
|
2283
2397
|
results.push(new ActionResult({
|
|
2284
2398
|
error: `Skipped - original step had error: ${preview}`,
|
|
2285
2399
|
}));
|
|
@@ -2332,7 +2446,7 @@ export class Agent {
|
|
|
2332
2446
|
}
|
|
2333
2447
|
if (attempt === max_retries) {
|
|
2334
2448
|
const message = `${stepName} failed after ${max_retries} attempts: ${errorMessage}`;
|
|
2335
|
-
this.logger.error(message);
|
|
2449
|
+
this.logger.error(this._redactSensitiveText(message));
|
|
2336
2450
|
const failure = new ActionResult({ error: message });
|
|
2337
2451
|
results.push(failure);
|
|
2338
2452
|
if (!skip_failures) {
|
|
@@ -2409,7 +2523,7 @@ export class Agent {
|
|
|
2409
2523
|
const params = actionPayload[actionName] ?? {};
|
|
2410
2524
|
const query = typeof params.query === 'string' ? params.query : '';
|
|
2411
2525
|
const extractLinks = Boolean(params.extract_links);
|
|
2412
|
-
this.logger.info(`Using AI step for extract action: ${query.slice(0, 50)}...`);
|
|
2526
|
+
this.logger.info(`Using AI step for extract action: ${this._redactSensitiveText(query.slice(0, 50))}...`);
|
|
2413
2527
|
const aiResult = await this._execute_ai_step(query, false, extractLinks, ai_step_llm, signal);
|
|
2414
2528
|
results.push(aiResult);
|
|
2415
2529
|
continue;
|
|
@@ -2674,7 +2788,8 @@ export class Agent {
|
|
|
2674
2788
|
return true;
|
|
2675
2789
|
}
|
|
2676
2790
|
catch (error) {
|
|
2677
|
-
|
|
2791
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2792
|
+
this.logger.warning(`Failed to re-open dropdown: ${this._redactSensitiveText(message)}`);
|
|
2678
2793
|
return false;
|
|
2679
2794
|
}
|
|
2680
2795
|
}
|
|
@@ -2739,7 +2854,7 @@ export class Agent {
|
|
|
2739
2854
|
if (node?.xpath === historicalElement.xpath) {
|
|
2740
2855
|
currentNode = node;
|
|
2741
2856
|
matchLevel = 'XPATH';
|
|
2742
|
-
this.logger.info(`Element matched at XPATH fallback: ${historicalElement.xpath}`);
|
|
2857
|
+
this.logger.info(`Element matched at XPATH fallback: ${this._redactSensitiveText(historicalElement.xpath)}`);
|
|
2743
2858
|
break;
|
|
2744
2859
|
}
|
|
2745
2860
|
}
|
|
@@ -2754,7 +2869,7 @@ export class Agent {
|
|
|
2754
2869
|
nodeAxName === targetAxName) {
|
|
2755
2870
|
currentNode = node;
|
|
2756
2871
|
matchLevel = 'AX_NAME';
|
|
2757
|
-
this.logger.info(`Element matched at AX_NAME fallback: ${targetAxName}`);
|
|
2872
|
+
this.logger.info(`Element matched at AX_NAME fallback: ${this._redactSensitiveText(targetAxName)}`);
|
|
2758
2873
|
break;
|
|
2759
2874
|
}
|
|
2760
2875
|
}
|
|
@@ -2771,7 +2886,7 @@ export class Agent {
|
|
|
2771
2886
|
node?.attributes?.[attrKey] === attrValue) {
|
|
2772
2887
|
currentNode = node;
|
|
2773
2888
|
matchLevel = 'ATTRIBUTE';
|
|
2774
|
-
this.logger.info(`Element matched via ${attrKey} attribute fallback: ${attrValue}`);
|
|
2889
|
+
this.logger.info(`Element matched via ${attrKey} attribute fallback: ${this._redactSensitiveText(attrValue)}`);
|
|
2775
2890
|
break;
|
|
2776
2891
|
}
|
|
2777
2892
|
}
|
|
@@ -2994,7 +3109,8 @@ export class Agent {
|
|
|
2994
3109
|
}
|
|
2995
3110
|
}
|
|
2996
3111
|
catch (error) {
|
|
2997
|
-
|
|
3112
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3113
|
+
this.logger.error(`Error during agent cleanup: ${this._redactSensitiveText(message)}`);
|
|
2998
3114
|
}
|
|
2999
3115
|
if (this.skill_service &&
|
|
3000
3116
|
typeof this.skill_service.close === 'function') {
|
|
@@ -3002,7 +3118,8 @@ export class Agent {
|
|
|
3002
3118
|
await this.skill_service.close();
|
|
3003
3119
|
}
|
|
3004
3120
|
catch (error) {
|
|
3005
|
-
|
|
3121
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3122
|
+
this.logger.error(`Error during skill service cleanup: ${this._redactSensitiveText(message)}`);
|
|
3006
3123
|
}
|
|
3007
3124
|
}
|
|
3008
3125
|
})();
|
|
@@ -3089,7 +3206,7 @@ export class Agent {
|
|
|
3089
3206
|
return { trace, trace_details };
|
|
3090
3207
|
}
|
|
3091
3208
|
async _log_agent_run() {
|
|
3092
|
-
this.logger.info(`\x1b[34m🎯 Task: ${this.task}\x1b[0m`);
|
|
3209
|
+
this.logger.info(`\x1b[34m🎯 Task: ${this._redactSensitiveText(this.task)}\x1b[0m`);
|
|
3093
3210
|
this.logger.debug(`🤖 Browser-Use Library Version ${this.version} (${this.source})`);
|
|
3094
3211
|
if (CONFIG.BROWSER_USE_VERSION_CHECK &&
|
|
3095
3212
|
process.env.NODE_ENV !== 'test' &&
|
|
@@ -3131,15 +3248,20 @@ export class Agent {
|
|
|
3131
3248
|
if (this.register_new_step_callback && this.state.last_model_output) {
|
|
3132
3249
|
await this.register_new_step_callback(browser_state_summary, this.state.last_model_output, this.state.n_steps);
|
|
3133
3250
|
}
|
|
3134
|
-
log_response(this.state.last_model_output, this.controller, this.logger);
|
|
3251
|
+
log_response(this.state.last_model_output, this.controller, this.logger, this.sensitive_data);
|
|
3135
3252
|
if (this.settings.save_conversation_path) {
|
|
3136
3253
|
const dir = this.settings.save_conversation_path;
|
|
3137
3254
|
const filepath = path.join(dir, `step_${this.state.n_steps}.json`);
|
|
3138
|
-
|
|
3255
|
+
ensureDir(path.dirname(filepath));
|
|
3139
3256
|
await fs.promises.writeFile(filepath, JSON.stringify({
|
|
3140
3257
|
messages: input_messages,
|
|
3141
3258
|
response: this.state.last_model_output?.model_dump(),
|
|
3142
|
-
}, null, 2),
|
|
3259
|
+
}, null, 2), {
|
|
3260
|
+
encoding: this.settings
|
|
3261
|
+
.save_conversation_path_encoding,
|
|
3262
|
+
mode: 0o600,
|
|
3263
|
+
});
|
|
3264
|
+
await chmodPrivateFile(filepath);
|
|
3143
3265
|
}
|
|
3144
3266
|
}
|
|
3145
3267
|
/** Handle all types of errors that can occur during a step (python c011 parity). */
|
|
@@ -3148,7 +3270,7 @@ export class Agent {
|
|
|
3148
3270
|
const message = error.message
|
|
3149
3271
|
? `The agent was interrupted mid-step - ${error.message}`
|
|
3150
3272
|
: 'The agent was interrupted mid-step';
|
|
3151
|
-
this.logger.warning(message);
|
|
3273
|
+
this.logger.warning(this._redactSensitiveText(message));
|
|
3152
3274
|
return;
|
|
3153
3275
|
}
|
|
3154
3276
|
const include_trace = this.logger.level === 'debug';
|
|
@@ -3168,11 +3290,12 @@ export class Agent {
|
|
|
3168
3290
|
this.logger.warning(parseLog);
|
|
3169
3291
|
}
|
|
3170
3292
|
}
|
|
3293
|
+
const redactedErrorMsg = this._redactSensitiveText(error_msg);
|
|
3171
3294
|
if (isFinalFailure) {
|
|
3172
|
-
this.logger.error(`${prefix}${
|
|
3295
|
+
this.logger.error(`${prefix}${redactedErrorMsg}`);
|
|
3173
3296
|
}
|
|
3174
3297
|
else {
|
|
3175
|
-
this.logger.warning(`${prefix}${
|
|
3298
|
+
this.logger.warning(`${prefix}${redactedErrorMsg}`);
|
|
3176
3299
|
}
|
|
3177
3300
|
this.state.last_result = [new ActionResult({ error: error_msg })];
|
|
3178
3301
|
}
|
|
@@ -3415,7 +3538,7 @@ export class Agent {
|
|
|
3415
3538
|
? parsed.reason.trim()
|
|
3416
3539
|
: 'Task requirements not fully met';
|
|
3417
3540
|
if (!isCorrect) {
|
|
3418
|
-
this.logger.info(`⚠️ Simple judge overriding success to failure: ${reason}`);
|
|
3541
|
+
this.logger.info(`⚠️ Simple judge overriding success to failure: ${this._redactSensitiveText(reason)}`);
|
|
3419
3542
|
lastResult.success = false;
|
|
3420
3543
|
const note = `[Simple judge: ${reason}]`;
|
|
3421
3544
|
if (lastResult.extracted_content) {
|
|
@@ -3427,7 +3550,8 @@ export class Agent {
|
|
|
3427
3550
|
}
|
|
3428
3551
|
}
|
|
3429
3552
|
catch (error) {
|
|
3430
|
-
|
|
3553
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3554
|
+
this.logger.warning(`Simple judge failed with error: ${this._redactSensitiveText(message)}`);
|
|
3431
3555
|
}
|
|
3432
3556
|
}
|
|
3433
3557
|
async _judge_trace() {
|
|
@@ -3456,7 +3580,8 @@ export class Agent {
|
|
|
3456
3580
|
return validation.data;
|
|
3457
3581
|
}
|
|
3458
3582
|
catch (error) {
|
|
3459
|
-
|
|
3583
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3584
|
+
this.logger.warning(`Judge trace failed: ${this._redactSensitiveText(message)}`);
|
|
3460
3585
|
return null;
|
|
3461
3586
|
}
|
|
3462
3587
|
}
|
|
@@ -3493,7 +3618,7 @@ export class Agent {
|
|
|
3493
3618
|
if (judgement.reasoning) {
|
|
3494
3619
|
judgeLog += ` ${judgement.reasoning}\n`;
|
|
3495
3620
|
}
|
|
3496
|
-
this.logger.info(judgeLog);
|
|
3621
|
+
this.logger.info(this._redactSensitiveText(judgeLog));
|
|
3497
3622
|
}
|
|
3498
3623
|
_replace_urls_in_text(text) {
|
|
3499
3624
|
const replacedUrls = {};
|
|
@@ -3788,7 +3913,7 @@ export class Agent {
|
|
|
3788
3913
|
}
|
|
3789
3914
|
_try_switch_to_fallback_llm(error) {
|
|
3790
3915
|
if (this._using_fallback_llm) {
|
|
3791
|
-
this.logger.warning(`⚠️ Fallback LLM also failed (${error.name}: ${error.message}), no more fallbacks available`);
|
|
3916
|
+
this.logger.warning(`⚠️ Fallback LLM also failed (${error.name}: ${this._redactSensitiveText(error.message)}), no more fallbacks available`);
|
|
3792
3917
|
return false;
|
|
3793
3918
|
}
|
|
3794
3919
|
const retryableStatusCodes = new Set([401, 402, 429, 500, 502, 503, 504]);
|
|
@@ -3799,7 +3924,7 @@ export class Agent {
|
|
|
3799
3924
|
return false;
|
|
3800
3925
|
}
|
|
3801
3926
|
if (!this._fallback_llm) {
|
|
3802
|
-
this.logger.warning(`⚠️ LLM error (${error.name}: ${error.message}) but no fallback_llm configured`);
|
|
3927
|
+
this.logger.warning(`⚠️ LLM error (${error.name}: ${this._redactSensitiveText(error.message)}) but no fallback_llm configured`);
|
|
3803
3928
|
return false;
|
|
3804
3929
|
}
|
|
3805
3930
|
this._log_fallback_switch(error, this._fallback_llm);
|