diff --git a/backend/apps/agents/browser/browser_agent.py b/backend/apps/agents/browser/browser_agent.py
index f46dac43..957e4831 100644
--- a/backend/apps/agents/browser/browser_agent.py
+++ b/backend/apps/agents/browser/browser_agent.py
@@ -2015,7 +2015,7 @@ async def run_browser_agent(
DEAD_CARDS.add(browser_id)
logger.info(f"[browser-agent] {browser_id} marked dead; same-host reuse will skip it")
# Tear the wedged webview DOWN now, before recovery spawns a fresh card. Two heavy pages (the dead one + the recovery one) starve the renderer's event loop = the recovery-card wedge; unmounting the dead one frees its renderer so the recovery card is the only heavy neighbor.
- await p_evict_dead_card(dashboard_id, browser_id)
+ await evict_dead_card(dashboard_id, browser_id)
break
if cancel_event.is_set():
@@ -2263,7 +2263,7 @@ def find_reusable_card(dashboard_id: str, url: str, parent_session_id: str | Non
P_EVICT_SETTLE_S = 1.5
-async def p_evict_dead_card(dashboard_id: str | None, browser_id: str) -> None:
+async def evict_dead_card(dashboard_id: str | None, browser_id: str) -> None:
"""Free a wedged card's webview so the recovery card isn't its heavy neighbor: tell the
renderer to unmount it (frees the renderer process), drop it from the persisted layout, and
WAIT for teardown before the caller spawns the recovery card. Fail-open, never raises into the
diff --git a/backend/tests/test_deadcard_evict.py b/backend/tests/test_deadcard_evict.py
index c48af909..898d11e7 100644
--- a/backend/tests/test_deadcard_evict.py
+++ b/backend/tests/test_deadcard_evict.py
@@ -1,6 +1,6 @@
"""The recovery-card wedge fix: when a card is declared dead, its webview must be
torn down (renderer unmount + layout removal) BEFORE recovery spawns a fresh card,
-so two heavy pages never co-exist and starve the renderer. Pins p_evict_dead_card."""
+so two heavy pages never co-exist and starve the renderer. Pins evict_dead_card."""
import asyncio
import backend.apps.agents.browser.browser_agent as ba
@@ -36,7 +36,7 @@ def p_patch(monkeypatch, cards):
def test_evict_broadcasts_unmount_and_removes_from_layout(monkeypatch):
broadcasts, saved, dash = p_patch(monkeypatch, {"browser-dead": FakeCard("sess-1"), "browser-keep": FakeCard("sess-1")})
ba.ACTIVE_AGENT_CARDS.add("browser-dead")
- asyncio.run(ba.p_evict_dead_card("dash-1", "browser-dead"))
+ asyncio.run(ba.evict_dead_card("dash-1", "browser-dead"))
# the renderer is told to unmount exactly the dead card
assert ("dashboard:browser_card_evict", {"dashboard_id": "dash-1", "browser_id": "browser-dead"}) in broadcasts
# it's gone from the persisted layout, its neighbor is untouched
@@ -50,7 +50,7 @@ def test_evict_without_a_dashboard_deletes_nothing(monkeypatch):
# No dashboard = ownership unverifiable = fail SAFE: never unmount or delete
# what might be the user's card; the reuse-skip alone handles it.
broadcasts, saved, _ = p_patch(monkeypatch, {})
- asyncio.run(ba.p_evict_dead_card("", "browser-x"))
+ asyncio.run(ba.evict_dead_card("", "browser-x"))
assert not broadcasts and not saved
@@ -63,6 +63,6 @@ def test_user_card_is_never_evicted(monkeypatch):
"""A wedged USER card (no spawned_by) must never be deleted out from under the
user; reuse-skip is the whole remedy. Only agent-spawned cards evict."""
broadcasts, saved, dash = p_patch(monkeypatch, {"browser-user": FakeCard(None)})
- asyncio.run(ba.p_evict_dead_card("dash-1", "browser-user"))
+ asyncio.run(ba.evict_dead_card("dash-1", "browser-user"))
assert not broadcasts and not saved
assert "browser-user" in dash.layout.browser_cards
diff --git a/backend/tests/test_spawn_agent.py b/backend/tests/test_spawn_agent.py
index 9ab47e35..54550eed 100644
--- a/backend/tests/test_spawn_agent.py
+++ b/backend/tests/test_spawn_agent.py
@@ -101,8 +101,9 @@ def test_spawn_server_schema_is_prompt_plus_background_only() -> None:
def test_spawn_server_speaks_mcp_stdio() -> None:
+ from backend.apps.agents import spawn_agent_mcp_server as srv
proc = subprocess.Popen(
- [sys.executable, "backend/apps/agents/spawn_agent_mcp_server.py"],
+ [sys.executable, srv.__file__],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True,
)
try:
diff --git a/frontend/src/app/pages/Tools/Tools.tsx b/frontend/src/app/pages/Tools/Tools.tsx
index 89499e43..ef2518b1 100644
--- a/frontend/src/app/pages/Tools/Tools.tsx
+++ b/frontend/src/app/pages/Tools/Tools.tsx
@@ -179,7 +179,6 @@ const Tools: React.FC = () => {
-