fix(container): reclaim abandoned browser sessions

Each agent-browser session is a separate Chromium (~340 MB, ~12 processes)
and nothing owns a browser's lifecycle, so finished, stopped and crashed
agents strand theirs for the life of the sandbox. Enable the daemon's idle
timeout and stop telling agents each of them has its own browser.
This commit is contained in:
Ahmed Allam
2026-08-09 23:33:04 +00:00
committed by Devin AI
parent ae07af6159
commit 55e15f89fd
3 changed files with 39 additions and 3 deletions
+11
View File
@@ -117,6 +117,17 @@ ENV AGENT_BROWSER_EXECUTABLE_PATH=/usr/bin/chromium
ENV AGENT_BROWSER_USER_AGENT="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
ENV AGENT_BROWSER_ARGS="--disable-blink-features=AutomationControlled,--no-first-run,--no-default-browser-check,--lang=en-US"
ENV AGENT_BROWSER_SCREENSHOT_DIR=/workspace/.agent-browser-screenshots
# Reclaim abandoned browsers. Each `--session` name is a separate daemon owning its
# own Chromium process group — measured at ~340 MB and ~12 processes with one page
# open — and nothing in the engine owns a browser's lifecycle: agents drive
# `agent-browser` through exec_command, so an agent that finishes, is stopped, or
# crashes leaves its browser resident for the life of the sandbox. Upstream
# disables the idle timeout by default, which turns a wide fan-out into gigabytes
# of stranded Chromium. The daemon relaunches transparently on the next command, so
# the only cost of reclamation is losing browser state (see the skill's note on
# persisting it). Three minutes is longer than the gap between two browser commands
# in an active agent turn; override the env var to tune.
ENV AGENT_BROWSER_IDLE_TIMEOUT_MS=180000
RUN /home/pentester/.npm-global/bin/agent-browser doctor --offline --quick
RUN set -eux; \
+6 -1
View File
@@ -263,7 +263,12 @@ Remember: A single well-validated high-impact vulnerability is worth more than d
<multi_agent_system>
AGENT ISOLATION & SANDBOXING:
- All agents run in the same shared Docker container for efficiency
- Each agent has its own: browser sessions, terminal sessions
- Each agent has its own terminal sessions
- Browsers are NOT per-agent: `agent-browser` shares one browser across every agent
using the default session, so another agent may be driving it. Pass
`--session <name>` only when you genuinely need an isolated browser (separate
cookies/logins, e.g. testing two users at once) — each one costs a full Chromium
(~340 MB) on the shared box, and `close` it as soon as you're done with it
- All agents share the same /workspace directory and proxy history
- Agents can see each other's files and proxy traffic for better collaboration
+22 -2
View File
@@ -58,6 +58,14 @@ agent-browser screenshot
The browser stays running across commands so these feel like a single
session. Use `agent-browser close` (or `close --all`) when you're done.
The default session is **shared with every other agent in the sandbox**, and each
extra `--session <name>` is a whole extra Chromium (~340 MB) on a box you share —
so open one only when you need isolated cookies, and close it when you're done.
A browser left idle for 3 minutes is reclaimed automatically; the next command
relaunches it, but the page, tabs, refs and cookies are gone. If you're
authenticated and about to go do something else for a while, save the state
first (see [Persist session across runs](#persist-session-across-runs)).
## Reading a page
```bash
@@ -307,6 +315,15 @@ agent-browser --session b fill @e1 "bob@test.com"
`AGENT_BROWSER_SESSION=myapp` sets the default session for the current
shell.
Every session is a separate Chromium, so this is the most expensive thing you can
do to the shared sandbox — use it for genuine isolation (two users, two cookie
jars), not as a habit, and close each one when the flow is finished:
```bash
agent-browser --session a close
agent-browser --session b close
```
### Mock network requests
```bash
@@ -368,8 +385,11 @@ agent-browser dialog dismiss # cancel
## Readiness & recovery
The first `agent-browser open` in a session launches the headless-Chrome
daemon; later commands reuse it. Distinguish the two failure modes and react
differently — do **not** blindly re-run the same failing command in a loop:
daemon; later commands reuse it. A daemon left idle for 3 minutes shuts itself
down to free memory for the other agents, so an `open` after a long gap is a
fresh browser rather than a resumed one — expect to re-navigate, and re-`state
load` if you were logged in. Distinguish the failure modes and react differently
— do **not** blindly re-run the same failing command in a loop:
- **Daemon / connection failure** (`Failed to connect`, `connection refused`,
socket missing, `browser not running`): the daemon isn't up or has died. Run