def _cleanup(self):
        """Enhanced resource cleanup with better process handling"""
        self.should_terminate.set()

        # Handle research thread with improved termination
        if self.research_thread and self.research_thread.is_alive():
            try:
                self.research_thread.join(timeout=1.0)
                if self.research_thread.is_alive():
                    import ctypes
                    ctypes.pythonapi.PyThreadState_SetAsyncExc(
                        ctypes.c_long(self.research_thread.ident),
                        ctypes.py_object(SystemExit))
                    time.sleep(0.1)  # Give thread time to exit
                    if self.research_thread.is_alive():  # Double-check
                        ctypes.pythonapi.PyThreadState_SetAsyncExc(
                            ctypes.c_long(self.research_thread.ident),
                            0)  # Reset exception
            except Exception as e:
                logger.error(f"Error terminating research thread: {str(e)}")

        # Clean up LLM with improved error handling
        if hasattr(self, 'llm') and hasattr(self.llm, '_cleanup'):
            try:
                self.llm.cleanup()
            except Exception as e:
                logger.error(f"Error cleaning up LLM: {str(e)}")

        # Ensure terminal is restored
        try:
            curses.endwin()
        except:
            pass

        # Final cleanup of UI
        self.cleanup()
Enhanced resource cleanup with better process handling
research_manager.py