fix: add diagnostic logging to browser tool for errors.log
All failure paths in _run_browser_command now log at WARNING level, which means they automatically land in ~/.hermes/logs/errors.log (the persistent error log captures WARNING+). What's now logged: - agent-browser CLI not found (warning) - Session creation failure with task ID (warning) - Command entry with socket_dir path and length (debug) - Non-zero return code with stderr (warning) - Non-JSON output from agent-browser (warning — version mismatch/crash) - Command timeout with task ID and socket path (warning) - Unexpected exceptions with full traceback (warning + exc_info) - browser_vision: which model is used and screenshot size (debug) - browser_vision: LLM analysis failure with full traceback (warning) Also fixed: _get_vision_model() was called twice in browser_vision — now called once and reused.
This commit is contained in:
parent
2036c22f88
commit
4d7d9d9715
1 changed files with 18 additions and 3 deletions
|
|
@ -802,6 +802,7 @@ def _run_browser_command(
|
||||||
try:
|
try:
|
||||||
browser_cmd = _find_agent_browser()
|
browser_cmd = _find_agent_browser()
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
|
logger.warning("agent-browser CLI not found: %s", e)
|
||||||
return {"success": False, "error": str(e)}
|
return {"success": False, "error": str(e)}
|
||||||
|
|
||||||
from tools.interrupt import is_interrupted
|
from tools.interrupt import is_interrupted
|
||||||
|
|
@ -812,6 +813,7 @@ def _run_browser_command(
|
||||||
try:
|
try:
|
||||||
session_info = _get_session_info(task_id)
|
session_info = _get_session_info(task_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logger.warning("Failed to create browser session for task=%s: %s", task_id, e)
|
||||||
return {"success": False, "error": f"Failed to create browser session: {str(e)}"}
|
return {"success": False, "error": f"Failed to create browser session: {str(e)}"}
|
||||||
|
|
||||||
# Build the command with the appropriate backend flag.
|
# Build the command with the appropriate backend flag.
|
||||||
|
|
@ -841,6 +843,8 @@ def _run_browser_command(
|
||||||
f"agent-browser-{session_info['session_name']}"
|
f"agent-browser-{session_info['session_name']}"
|
||||||
)
|
)
|
||||||
os.makedirs(task_socket_dir, mode=0o700, exist_ok=True)
|
os.makedirs(task_socket_dir, mode=0o700, exist_ok=True)
|
||||||
|
logger.debug("browser cmd=%s task=%s socket_dir=%s (%d chars)",
|
||||||
|
command, task_id, task_socket_dir, len(task_socket_dir))
|
||||||
|
|
||||||
browser_env = {**os.environ}
|
browser_env = {**os.environ}
|
||||||
# Ensure PATH includes standard dirs (systemd services may have minimal PATH)
|
# Ensure PATH includes standard dirs (systemd services may have minimal PATH)
|
||||||
|
|
@ -882,22 +886,29 @@ def _run_browser_command(
|
||||||
"returncode=%s", result.returncode)
|
"returncode=%s", result.returncode)
|
||||||
return parsed
|
return parsed
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
# If not valid JSON, return as raw output
|
# Non-JSON output indicates agent-browser crash or version mismatch
|
||||||
|
raw = result.stdout.strip()[:500]
|
||||||
|
logger.warning("browser '%s' returned non-JSON output (rc=%s): %s",
|
||||||
|
command, result.returncode, raw[:200])
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"data": {"raw": result.stdout.strip()}
|
"data": {"raw": raw}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check for errors
|
# Check for errors
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
error_msg = result.stderr.strip() if result.stderr else f"Command failed with code {result.returncode}"
|
error_msg = result.stderr.strip() if result.stderr else f"Command failed with code {result.returncode}"
|
||||||
|
logger.warning("browser '%s' failed (rc=%s): %s", command, result.returncode, error_msg[:300])
|
||||||
return {"success": False, "error": error_msg}
|
return {"success": False, "error": error_msg}
|
||||||
|
|
||||||
return {"success": True, "data": {}}
|
return {"success": True, "data": {}}
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
|
logger.warning("browser '%s' timed out after %ds (task=%s, socket_dir=%s)",
|
||||||
|
command, timeout, task_id, task_socket_dir)
|
||||||
return {"success": False, "error": f"Command timed out after {timeout} seconds"}
|
return {"success": False, "error": f"Command timed out after {timeout} seconds"}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logger.warning("browser '%s' exception: %s", command, e, exc_info=True)
|
||||||
return {"success": False, "error": str(e)}
|
return {"success": False, "error": str(e)}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1426,8 +1437,11 @@ def browser_vision(question: str, task_id: Optional[str] = None) -> str:
|
||||||
|
|
||||||
# Use the sync auxiliary vision client directly
|
# Use the sync auxiliary vision client directly
|
||||||
from agent.auxiliary_client import auxiliary_max_tokens_param
|
from agent.auxiliary_client import auxiliary_max_tokens_param
|
||||||
|
vision_model = _get_vision_model()
|
||||||
|
logger.debug("browser_vision: analysing screenshot (%d bytes) with model=%s",
|
||||||
|
len(image_data), vision_model)
|
||||||
response = _aux_vision_client.chat.completions.create(
|
response = _aux_vision_client.chat.completions.create(
|
||||||
model=_get_vision_model(),
|
model=vision_model,
|
||||||
messages=[
|
messages=[
|
||||||
{
|
{
|
||||||
"role": "user",
|
"role": "user",
|
||||||
|
|
@ -1453,6 +1467,7 @@ def browser_vision(question: str, task_id: Optional[str] = None) -> str:
|
||||||
# in the LLM vision analysis, not the capture. Deleting a valid
|
# in the LLM vision analysis, not the capture. Deleting a valid
|
||||||
# screenshot loses evidence the user might need. The 24-hour cleanup
|
# screenshot loses evidence the user might need. The 24-hour cleanup
|
||||||
# in _cleanup_old_screenshots prevents unbounded disk growth.
|
# in _cleanup_old_screenshots prevents unbounded disk growth.
|
||||||
|
logger.warning("browser_vision failed: %s", e, exc_info=True)
|
||||||
error_info = {"success": False, "error": f"Error during vision analysis: {str(e)}"}
|
error_info = {"success": False, "error": f"Error during vision analysis: {str(e)}"}
|
||||||
if screenshot_path.exists():
|
if screenshot_path.exists():
|
||||||
error_info["screenshot_path"] = str(screenshot_path)
|
error_info["screenshot_path"] = str(screenshot_path)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue