811df74a10
The #45966 cross-process coherence guard popped the stale cached agent and then called the blocking _cleanup_agent_resources (memory-provider shutdown, tool-resource teardown, async-client teardown) while still holding _agent_cache_lock, on the gateway event-loop thread. While that ran, _sweep_idle_cached_agents (driven by _session_expiry_watcher) blocked acquiring the same lock and the asyncio loop stalled for minutes, tripping repeated Discord 'heartbeat blocked' warnings. Fix mirrors the cap-enforcer / idle-sweep paths: pop the stale entry under the lock, release it, then schedule the SOFT release on a daemon thread. The soft path (_release_evicted_agent_soft) is also more correct here than the hard teardown the regression used — the same session rebuilds a fresh agent immediately after invalidation, so its terminal sandbox / browser / bg processes (keyed on task_id) must be preserved for the rebuilt agent to inherit, not torn down. Verified the cross-process site was the only cleanup-under-lock instance; the other _cleanup_agent_resources call sites run outside the lock.