diff --git a/src/serena/agent.py b/src/serena/agent.py index 2cbb5dfa..69200043 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -86,7 +86,7 @@ class SerenaAgent: # project-specific instances, which will be initialized upon project activation self._active_project: Project | None = None - self.language_server_manager: LanguageServerManager | None = None + self._language_server_manager: LanguageServerManager | None = None # adjust log level serena_log_level = self.serena_config.log_level @@ -192,6 +192,18 @@ class SerenaAgent: process.start() process.join(timeout=1) + def get_language_server_manager(self) -> LanguageServerManager | None: + return self._language_server_manager + + def get_language_server_manager_or_raise(self) -> LanguageServerManager: + if self._language_server_manager is None: + raise Exception( + "The language server manager is not initialized, indicating a problem during project activation. " + "Inform the user, telling them to inspect Serena's logs in order to determine the issue. " + "IMPORTANT: Wait for further instructions before you continue!" + ) + return self._language_server_manager + def get_context(self) -> SerenaAgentContext: return self._context @@ -518,13 +530,13 @@ class SerenaAgent: ls_timeout = tool_timeout - 5 # the LS timeout is for a single call, it should be smaller than the tool timeout # stop the language server if it is running - if self.language_server_manager is not None: - self.language_server_manager.stop_all() - self.language_server_manager = None + if self._language_server_manager is not None: + self._language_server_manager.stop_all() + self._language_server_manager = None - # instantiate and start the necessarys language servers - assert self._active_project is not None - self.language_server_manager = self._active_project.create_language_server_manager( + # instantiate and start the necessary language servers + assert self._active_project is not None, "Active project required" + self._language_server_manager = self._active_project.create_language_server_manager( log_level=self.serena_config.log_level, ls_timeout=ls_timeout, trace_lsp_communication=self.serena_config.trace_lsp_communication, @@ -544,9 +556,9 @@ class SerenaAgent: if not hasattr(self, "_is_initialized"): return log.info("SerenaAgent is shutting down ...") - if self.language_server_manager is not None: - self.language_server_manager.stop_all(save_cache=True) - self.language_server_manager = None + if self._language_server_manager is not None: + self._language_server_manager.stop_all(save_cache=True) + self._language_server_manager = None if self._gui_log_viewer: log.info("Stopping the GUI log window ...") self._gui_log_viewer.stop() diff --git a/src/serena/tools/tools_base.py b/src/serena/tools/tools_base.py index 5fe58675..c4b0f300 100644 --- a/src/serena/tools/tools_base.py +++ b/src/serena/tools/tools_base.py @@ -47,8 +47,7 @@ class Component(ABC): def create_language_server_symbol_retriever(self) -> LanguageServerSymbolRetriever: if not self.agent.is_using_language_server(): raise Exception("Cannot create LanguageServerSymbolRetriever; agent is not in language server mode.") - language_server_manager = self.agent.language_server_manager - assert language_server_manager is not None + language_server_manager = self.agent.get_language_server_manager_or_raise() return LanguageServerSymbolRetriever(language_server_manager, agent=self.agent) @property @@ -239,7 +238,7 @@ class Tool(Component): try: # check whether the tool requires an active project and language server if not isinstance(self, ToolMarkerDoesNotRequireActiveProject): - if self.agent._active_project is None: + if self.agent.get_active_project() is None: return ( "Error: No active project. Ask the user to provide the project path or to select a project from this list of known projects: " + f"{self.agent.serena_config.project_names}" @@ -251,11 +250,11 @@ class Tool(Component): except SolidLSPException as e: if e.is_language_server_terminated(): affected_language = e.get_affected_language() - if affected_language is not None and self.agent.language_server_manager is not None: + if affected_language is not None: log.error( f"Language server terminated while executing tool ({e}). Restarting the language server and retrying ..." ) - self.agent.language_server_manager.restart_language_server(affected_language) + self.agent.get_language_server_manager_or_raise().restart_language_server(affected_language) result = apply_fn(**kwargs) else: log.error( @@ -271,7 +270,7 @@ class Tool(Component): except Exception as e: if not catch_exceptions: raise - msg = f"Error executing tool: {e}" + msg = f"Error executing tool: {e.__class__.__name__} - {e}" log.error(f"Error executing tool: {e}", exc_info=e) result = msg @@ -279,8 +278,9 @@ class Tool(Component): log.info(f"Result: {result}") try: - if self.agent.language_server_manager is not None: - self.agent.language_server_manager.save_all_caches() + ls_manager = self.agent.get_language_server_manager() + if ls_manager is not None: + ls_manager.save_all_caches() except Exception as e: log.error(f"Error saving language server cache: {e}")