mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 19:56:53 +00:00
reap() read the idle time before it took the agent's lock, and ensure() set _last_used only once the agent answered its health endpoint. Two requests lost their agent to that order. A turn longer than idle_minutes counted from the moment the agent became ready, so the sweep stopped it mid-request; a start slower than idle_minutes let the sweep queue on the lock and stop the agent the moment ensure() released it. A turn on a CPU-served model costs minutes per model call, so neither case is theoretical. The broker now counts in-flight chats per agent. server._chat brackets the forwarded request in begin()/end(), and end() also stamps _last_used, so idle time counts from the end of a request rather than its start. The sweep skips a busy agent, and after taking the lock it re-reads the agent and its idle time before stopping anything, which is what closes the start race. The relay deliberately does not stamp anything: an agent's own background traffic would otherwise hold it open forever. Unit tests cover the sweep: an idle agent is stopped, idle_stop false stops nothing, a busy agent survives its idle time, and a prompt landing during the sweep keeps its agent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>