From 60067f327433c9a4a5f3897acf705299bfca13ca Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Fri, 3 Apr 2026 15:05:36 +0200 Subject: [PATCH] Mark some new tools as beta tools and denote in tool list --- docs/autogen_docs.py | 11 ++++++++--- src/serena/tools/jetbrains_tools.py | 8 ++++---- src/serena/tools/tools_base.py | 10 +++++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/autogen_docs.py b/docs/autogen_docs.py index 8c828809..6dfd37f0 100644 --- a/docs/autogen_docs.py +++ b/docs/autogen_docs.py @@ -153,9 +153,10 @@ def autogen_tool_list(target_filename = "01-about/035_tools.md"): with open(target_file, "w") as f: f.write("\n\n") f.write("# Tools\n\n") - f.write("Find the full list of Serena's tools below. \n") + f.write("Find the full list of Serena's tools below.\n\n") f.write("Note that in most configurations, only a subset of these tools will be enabled simultaneously.\n") - f.write("Tools marked as optional are disabled by default.\n\n") + f.write("Tools marked as *optional* are disabled by default.\n\n") + f.write("Tools marked as [BETA] were recently introduced and may not be fully robust yet.\n\n") tools_by_module = ToolRegistry().get_registered_tools_by_module() priority_modules = {"serena.tools.symbol_tools": 1, "serena.tools.jetbrains_tools": 2} @@ -166,7 +167,11 @@ def autogen_tool_list(target_filename = "01-about/035_tools.md"): module = module.replace("serena.tools.", "") text.with_line(f"* **{module}**") for tool in tools: - info = " *(optional)*" if tool.is_optional else "" + info = "" + if tool.is_optional: + info += " *(optional)*" + if tool.is_beta: + info += " [BETA]" text.with_line(f"* `{tool.tool_name}`{info}: {tool.class_docstring}", indent=2) f.write(text.build()) diff --git a/src/serena/tools/jetbrains_tools.py b/src/serena/tools/jetbrains_tools.py index fdffa191..1c4ef63f 100644 --- a/src/serena/tools/jetbrains_tools.py +++ b/src/serena/tools/jetbrains_tools.py @@ -7,7 +7,7 @@ from serena.code_editor import JetBrainsCodeEditor from serena.jetbrains.jetbrains_plugin_client import JetBrainsPluginClient from serena.jetbrains.jetbrains_types import SymbolDTO from serena.symbol import JetBrainsSymbolDictGrouper -from serena.tools import Tool, ToolMarkerOptional, ToolMarkerSymbolicEdit, ToolMarkerSymbolicRead +from serena.tools import Tool, ToolMarkerBeta, ToolMarkerOptional, ToolMarkerSymbolicEdit, ToolMarkerSymbolicRead from serena.util.text_utils import find_text_coordinates log = logging.getLogger(__name__) @@ -113,7 +113,7 @@ class JetBrainsFindSymbolTool(Tool, ToolMarkerSymbolicRead, ToolMarkerOptional): return self._limit_length(result, max_answer_chars, shortened_result_factories=[create_shortened_result]) -class JetBrainsMoveTool(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional): +class JetBrainsMoveTool(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional, ToolMarkerBeta): """ Moves a symbol, file or directory to a new location using the JetBrains backend, updating all references """ @@ -155,7 +155,7 @@ class JetBrainsMoveTool(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional): return self._to_json(response_dict) -class JetBrainsSafeDeleteTool(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional): +class JetBrainsSafeDeleteTool(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional, ToolMarkerBeta): """ Safely deletes a symbol using the JetBrains backend, checking for remaining usages first """ @@ -189,7 +189,7 @@ class JetBrainsSafeDeleteTool(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional): return self._to_json(response_dict) -class JetBrainsInlineSymbol(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional): +class JetBrainsInlineSymbol(Tool, ToolMarkerSymbolicEdit, ToolMarkerOptional, ToolMarkerBeta): """ Inlines a symbol using the JetBrains backend, replacing all call sites with the symbol's body """ diff --git a/src/serena/tools/tools_base.py b/src/serena/tools/tools_base.py index 200c2ae3..cb2b299d 100644 --- a/src/serena/tools/tools_base.py +++ b/src/serena/tools/tools_base.py @@ -110,6 +110,12 @@ class ToolMarkerSymbolicEdit(ToolMarkerCanEdit): """ +class ToolMarkerBeta(ToolMarker): + """ + Marker for tools that are considered beta features (may not be fully robust) + """ + + class ApplyMethodProtocol(Protocol): """Callable protocol for the apply method of a tool.""" @@ -407,6 +413,7 @@ class EditedFileContext: class RegisteredTool: tool_class: type[Tool] is_optional: bool + is_beta: bool tool_name: str @property @@ -429,10 +436,11 @@ class ToolRegistry: if not any(cls.__module__.startswith(pkg) for pkg in tool_packages): continue is_optional = issubclass(cls, ToolMarkerOptional) + is_beta = issubclass(cls, ToolMarkerBeta) name = cls.get_name_from_cls() if name in self._tool_dict: raise ValueError(f"Duplicate tool name found: {name}. Tool classes must have unique names.") - self._tool_dict[name] = RegisteredTool(tool_class=cls, is_optional=is_optional, tool_name=name) + self._tool_dict[name] = RegisteredTool(tool_class=cls, is_optional=is_optional, tool_name=name, is_beta=is_beta) def get_registered_tools_by_module(self) -> dict[str, list[RegisteredTool]]: """