@@ -485,24 +485,34 @@ def stop_agent(self) -> dict:
485485 if not self .agent_running :
486486 return {"error" : "Not running" }
487487 self .stop_event .set ()
488- orphaned = False
489488 if self .agent_thread :
489+ # First wait: cooperative shutdown via stop_event (should be fast
490+ # now that TickClock and warmup sleeps are interruptible).
490491 self .agent_thread .join (timeout = 10 )
491492 if self .agent_thread .is_alive ():
492- log .warning (
493- "[LIFECYCLE] stop_agent: brain thread did not stop within 10s -- it will be orphaned"
493+ log .warning ("[LIFECYCLE] stop_agent: brain thread did not stop within 10s -- waiting longer" )
494+ # Second wait: allow cleanup callbacks (file I/O) to finish.
495+ self .agent_thread .join (timeout = 20 )
496+ if self .agent_thread .is_alive ():
497+ # Thread is truly stuck (hung syscall, deadlock). Keep the
498+ # reference so start_agent() still refuses to create a
499+ # duplicate runner -- the daemon flag ensures it dies at
500+ # process exit.
501+ log .error (
502+ "[LIFECYCLE] stop_agent: brain thread stuck after 30s -- "
503+ "thread kept alive (daemon); start_agent will block until it exits"
494504 )
495- orphaned = True
496- else :
497- self .agent_thread = None
505+ with self ._agent_lock :
506+ self .agent_running = False
507+ defeats = self .agent_defeats
508+ self .add_log (f"Agent stopped -- { defeats } defeats (thread stuck, will block next start)" )
509+ return {"running" : False , "defeats" : defeats , "stuck_thread" : True }
510+ self .agent_thread = None
498511 with self ._agent_lock :
499512 self .agent_running = False
500513 defeats = self .agent_defeats
501- self .add_log (f"Agent stopped -- { defeats } defeats" + (" (thread orphaned)" if orphaned else "" ))
502- result : dict = {"running" : False , "defeats" : defeats }
503- if orphaned :
504- result ["orphaned_thread" ] = True
505- return result
514+ self .add_log (f"Agent stopped -- { defeats } defeats" )
515+ return {"running" : False , "defeats" : defeats }
506516
507517 def pause_agent (self ) -> dict :
508518 with self ._agent_lock :
0 commit comments