@@ -207,7 +207,6 @@ async def _run_agent(
207207 Runtime events if stream_events=True, then final result
208208 """
209209 agent_input = self ._prepare_agent_input (input )
210- is_resuming = bool (options and options .resume )
211210
212211 # Create session for state persistence (local to this run)
213212 # SQLiteSession automatically loads existing data from the database when created
@@ -232,20 +231,12 @@ async def _run_agent(
232231 )
233232 yield self ._create_success_result (result .final_output )
234233
235- except Exception :
236- # Clean up session on error
237- if session and self .storage_path and not is_resuming :
238- # Delete incomplete session
239- try :
240- import os
241-
242- if os .path .exists (self .storage_path ):
243- os .remove (self .storage_path )
244- except Exception :
245- pass # Best effort cleanup
246- raise
247234 finally :
248235 # Always close session after run completes with proper WAL checkpoint
236+ # Note: We don't delete the database file on error because:
237+ # 1. Multiple sessions (different session_ids) coexist in the same file
238+ # 2. Deleting the file would delete ALL sessions, not just the failed one
239+ # 3. File deletion is handled at the factory level when starting new executions
249240 if session :
250241 self ._close_session_with_checkpoint (session )
251242
@@ -497,6 +488,10 @@ def _close_session_with_checkpoint(self, session: SQLiteSession) -> None:
497488 Args:
498489 session: The SQLiteSession to close
499490 """
491+ import gc
492+ import platform
493+ import time
494+
500495 try :
501496 # Get the underlying connection
502497 conn = session ._get_connection ()
@@ -525,6 +520,16 @@ def _close_session_with_checkpoint(self, session: SQLiteSession) -> None:
525520 except Exception :
526521 pass # Best effort
527522
523+ # Force garbage collection to close any open file handles
524+ # This is especially important on Windows where file handles
525+ # may remain open even after explicit close()
526+ gc .collect ()
527+
528+ # On Windows, give the OS time to release file locks
529+ # Virus scanners and backup agents often interfere
530+ if platform .system () == "Windows" :
531+ time .sleep (0.1 )
532+
528533 async def dispose (self ) -> None :
529534 """Cleanup runtime resources."""
530535 # Sessions are closed immediately after each run in _run_agent()
0 commit comments