feat: enhance stale daemon cleanup and improve error logging in browser tool
- Updated the stale daemon cleanup function to support multiple patterns for identifying orphaned agent-browser processes, improving reliability across different versions. - Added logging for stderr output during browser command execution to aid in diagnostics, particularly for capturing warnings from the agent-browser. - Implemented a warning for empty snapshots returned from the agent-browser, indicating potential issues with stale daemons or CDP connections.
This commit is contained in:
parent
b33ed9176f
commit
5b3f708fcb
1 changed files with 42 additions and 17 deletions
|
|
@ -645,28 +645,41 @@ def _get_browserbase_config() -> Dict[str, str]:
|
||||||
_stale_daemons_cleaned = False
|
_stale_daemons_cleaned = False
|
||||||
|
|
||||||
def _kill_stale_agent_browser_daemons():
|
def _kill_stale_agent_browser_daemons():
|
||||||
"""Kill any orphaned agent-browser daemon processes from previous runs."""
|
"""Kill any orphaned agent-browser daemon processes from previous runs.
|
||||||
|
|
||||||
|
Uses multiple patterns to catch daemons from different agent-browser versions,
|
||||||
|
since the daemon process name/args can vary between releases.
|
||||||
|
"""
|
||||||
global _stale_daemons_cleaned
|
global _stale_daemons_cleaned
|
||||||
if _stale_daemons_cleaned:
|
if _stale_daemons_cleaned:
|
||||||
return
|
return
|
||||||
_stale_daemons_cleaned = True
|
_stale_daemons_cleaned = True
|
||||||
|
|
||||||
try:
|
patterns = [
|
||||||
result = subprocess.run(
|
"agent-browser.*daemon",
|
||||||
["pgrep", "-f", "agent-browser.*daemon"],
|
"agent-browser/.*dist/daemon",
|
||||||
capture_output=True, text=True, timeout=5
|
]
|
||||||
)
|
killed_pids = set()
|
||||||
pids = result.stdout.strip().split()
|
|
||||||
if pids and pids[0]:
|
for pattern in patterns:
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["pgrep", "-f", pattern],
|
||||||
|
capture_output=True, text=True, timeout=5
|
||||||
|
)
|
||||||
|
pids = result.stdout.strip().split()
|
||||||
for pid in pids:
|
for pid in pids:
|
||||||
try:
|
if pid and pid not in killed_pids:
|
||||||
os.kill(int(pid), signal.SIGTERM)
|
try:
|
||||||
except (ProcessLookupError, ValueError, PermissionError):
|
os.kill(int(pid), signal.SIGTERM)
|
||||||
pass
|
killed_pids.add(pid)
|
||||||
if not os.getenv("HERMES_QUIET"):
|
except (ProcessLookupError, ValueError, PermissionError):
|
||||||
print(f"[browser_tool] Cleaned up {len(pids)} stale daemon process(es)", file=sys.stderr)
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if killed_pids and not os.getenv("HERMES_QUIET"):
|
||||||
|
print(f"[browser_tool] Cleaned up {len(killed_pids)} stale daemon process(es)", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
def _find_agent_browser() -> str:
|
def _find_agent_browser() -> str:
|
||||||
|
|
@ -771,10 +784,22 @@ def _run_browser_command(
|
||||||
env=browser_env,
|
env=browser_env,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Log stderr for diagnostics (agent-browser may emit warnings there)
|
||||||
|
if result.stderr and result.stderr.strip() and not os.getenv("HERMES_QUIET"):
|
||||||
|
print(f"[browser_tool] stderr from '{command}': {result.stderr.strip()[:200]}", file=sys.stderr)
|
||||||
|
|
||||||
# Parse JSON output
|
# Parse JSON output
|
||||||
if result.stdout.strip():
|
if result.stdout.strip():
|
||||||
try:
|
try:
|
||||||
return json.loads(result.stdout.strip())
|
parsed = json.loads(result.stdout.strip())
|
||||||
|
# Warn if snapshot came back empty (common sign of daemon/CDP issues)
|
||||||
|
if command == "snapshot" and parsed.get("success"):
|
||||||
|
snap_data = parsed.get("data", {})
|
||||||
|
if not snap_data.get("snapshot") and not snap_data.get("refs"):
|
||||||
|
print(f"[browser_tool] WARNING: snapshot returned empty content. "
|
||||||
|
f"Possible stale daemon or CDP connection issue. "
|
||||||
|
f"returncode={result.returncode}", file=sys.stderr)
|
||||||
|
return parsed
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
# If not valid JSON, return as raw output
|
# If not valid JSON, return as raw output
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue