feat(browser): auto-snapshot on navigate, screenshot prompt guidance

Browser tool enhancements:
- Navigate action now auto-includes snapshot result, saving one LLM round-trip
- Wait for networkidle + 800ms after navigation for SPA/JS-rendered pages
- Prompt guides agent to screenshot key results and ask user for login/CAPTCHA help
- Fixed playwright version pinned to 1.52.0; mirror fallback to official CDN on failure

Web console file/image support:
- SSE real-time push for images and files via on_event (file_to_send)
- Added /api/file endpoint to serve local files for web preview
- Frontend renders images in media-content container (survives delta/done overwrites)
- File attachment cards with download links; RFC 5987 encoding for non-ASCII filenames

Tool workspace fix:
- Inject workspace_dir as cwd into send and browser tools (previously only file tools)
- Screenshots now save to ~/cow/tmp/ instead of project directory
This commit is contained in:
zhayujie
2026-03-29 19:09:11 +08:00
parent 511ee0bbaf
commit d09ae49287
8 changed files with 105 additions and 10 deletions

View File

@@ -283,7 +283,7 @@ class BrowserService:
# ------------------------------------------------------------------
def navigate(self, url: str, timeout: int = 30000) -> Dict[str, Any]:
"""Navigate to a URL and return page info."""
"""Navigate to a URL and wait for the page to be fully rendered."""
page = self.page
try:
resp = page.goto(url, wait_until="domcontentloaded", timeout=timeout)
@@ -291,6 +291,14 @@ class BrowserService:
except Exception as e:
return {"error": f"Navigation failed: {e}"}
# Wait for network idle and visual stability
try:
page.wait_for_load_state("networkidle", timeout=10000)
except Exception:
pass
# Extra settle time for JS-rendered content (SPA frameworks, animations)
page.wait_for_timeout(800)
return {
"url": page.url,
"title": page.title(),