Deleted obsolete tools. Essentially backwards compatible

Enhanced tool registry check to log a warning instead of crashing when
a deleted tool name is passed
This commit is contained in:
Michael Panchenko committed 2026-04-08 14:35:07 +02:00
1 parent fe2e2ce0cc
commit c1aedec189
13 files changed
+76 -195

No files matched your search

+24 -24
View File
@@ -48,41 +48,41 @@ read_only: false
# Below is the complete list of tools for convenience.
# To make sure you have the latest list of tools, and to view their descriptions,
# execute `uv run scripts/print_tool_overview.py`.
#
# * `activate_project`: Activates a project by name.
# * `activate_project`: Activates a project based on the project name or path.
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
# * `create_text_file`: Creates/overwrites a file in the project directory.
# * `delete_lines`: Deletes a range of lines within a file.
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
# * `delete_memory`: Delete a memory file. Should only happen if a user asks for it explicitly,
# for example by saying that the information retrieved from a memory file is no longer correct
# or no longer relevant for the project.
# * `edit_memory`: Replaces content matching a regular expression in a memory.
# * `execute_shell_command`: Executes a shell command.
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
# * `find_file`: Finds files in the given relative paths
# * `find_referencing_symbols`: Finds symbols that reference the given symbol using the language server backend
# * `find_symbol`: Performs a global (or local) search using the language server backend.
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
# * `initial_instructions`: Gets the initial instructions for the current project.
# Should only be used in settings where the system prompt cannot be set,
# e.g. in clients you have no control over, like Claude Desktop.
# * `initial_instructions`: Provides instructions Serena usage (i.e. the 'Serena Instructions Manual')
# for clients that do not read the initial instructions when the MCP server is connected.
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
# * `insert_at_line`: Inserts content at a given line in a file.
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
# * `list_memories`: Lists memories in Serena's project-specific memory store.
# * `list_memories`: List available memories. Any memory can be read using the `read_memory` tool.
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
# * `read_file`: Reads a file within the project directory.
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
# * `remove_project`: Removes a project from the Serena configuration.
# * `replace_lines`: Replaces a range of lines within a file with new content.
# * `replace_symbol_body`: Replaces the full definition of a symbol.
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
# * `read_memory`: Read the content of a memory file. This tool should only be used if the information
# is relevant to the current task. You can infer whether the information
# is relevant from the memory file name.
# You should not read the same memory file multiple times in the same conversation.
# * `rename_memory`: Renames or moves a memory. Moving between project and global scope is supported
# (e.g., renaming "global/foo" to "bar" moves it from global to project scope).
# * `rename_symbol`: Renames a symbol throughout the codebase using language server refactoring capabilities.
# For JB, we use a separate tool.
# * `replace_content`: Replaces content in a file (optionally using regular expressions).
# * `replace_symbol_body`: Replaces the full definition of a symbol using the language server backend.
# * `safe_delete_symbol`:
# * `search_for_pattern`: Performs a search for a pattern in the project.
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
# * `switch_modes`: Activates modes by providing a list of their names
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
# * `write_memory`: Write some information (utf-8-encoded) about this project that can be useful for future tasks to a memory in md format.
# The memory name should be meaningful.
excluded_tools: []
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default).
-4
View File
@@ -145,10 +145,6 @@ If you want to keep certain modes as always active, regardless of command-line p
define them as *base modes* in the global or project configuration.
:::
Modes can also be _switched dynamically_ during a session.
You can instruct the LLM to use the `switch_modes` tool to activate a different set of modes (e.g., "Switch to planning and one-shot modes").
Like command-line parameters, this only affects default modes, not base modes (which remain active).
:::{note}
**Mode Compatibility**: While you can combine modes, some may be semantically incompatible (e.g., `interactive` and `one-shot`).
Serena currently does not prevent incompatible combinations; it is up to the user to choose sensible mode configurations.
+4 -8
View File
@@ -146,24 +146,20 @@ class ToolSet:
tool_names = set()
for fixed_tool in definition.fixed_tools:
fixed_tool = get_updated_tool_name(fixed_tool)
if not registry.is_valid_tool_name(fixed_tool):
raise ValueError(f"Invalid tool name '{fixed_tool}' provided for fixed tool set")
tool_names.add(fixed_tool)
if registry.check_valid_tool_name(fixed_tool, " (in fixed tools set)"):
tool_names.add(fixed_tool)
log.info(f"{definition} defined a fixed tool set with {len(tool_names)} tools: {', '.join(tool_names)}")
else:
included_tools = []
excluded_tools = []
for included_tool in definition.included_optional_tools:
included_tool = get_updated_tool_name(included_tool)
if not registry.is_valid_tool_name(included_tool):
raise ValueError(f"Invalid tool name '{included_tool}' provided for inclusion")
if included_tool not in tool_names:
if registry.check_valid_tool_name(included_tool, " (in included optional tools)") and included_tool not in tool_names:
tool_names.add(included_tool)
included_tools.append(included_tool)
for excluded_tool in definition.excluded_tools:
excluded_tool = get_updated_tool_name(excluded_tool)
if not registry.is_valid_tool_name(excluded_tool):
raise ValueError(f"Invalid tool name '{excluded_tool}' provided for exclusion")
registry.check_valid_tool_name(excluded_tool, " (in excluded tools)")
if excluded_tool in tool_names:
tool_names.remove(excluded_tool)
excluded_tools.append(excluded_tool)
@@ -11,8 +11,7 @@ prompt: |
a diagram in addition to your text-based communication. Note that in the chat interface you have various rendering
options for text, html, and mermaid diagrams, as has been explained to you in your initial instructions.
excluded_tools: []
included_optional_tools:
- switch_modes
included_optional_tools: []
tool_description_overrides:
find_symbol: |
@@ -12,7 +12,6 @@ excluded_tools:
- create_text_file
- read_file
- execute_shell_command
- prepare_for_new_conversation
- replace_content
tool_description_overrides: {}
@@ -13,7 +13,6 @@ excluded_tools:
- create_text_file
- read_file
- execute_shell_command
- prepare_for_new_conversation
- replace_content
@@ -9,7 +9,6 @@ prompt: |
To illustrate complex relationships, consider creating diagrams in addition to your text-based communication
(depending on the options for text, html, mermaid diagrams, etc. that you are provided with in your initial instructions).
excluded_tools: []
included_optional_tools:
- switch_modes
included_optional_tools: []
tool_description_overrides: {}
@@ -12,7 +12,6 @@ excluded_tools:
- create_text_file
- read_file
- execute_shell_command
- prepare_for_new_conversation
tool_description_overrides: {}
@@ -34,42 +34,3 @@ prompts:
Moreover, you should create memory files for the style and conventions and a dedicated memory file for
what should be done when a task is completed.
**Important**: after done with the onboarding task, remember to call the `write_memory` to save the collected information!
think_about_collected_information: |
Have you collected all the information you need for solving the current task? If not, can the missing information be acquired by using the available tools,
in particular the tools related to symbol discovery? Or do you need to ask the user for more information?
Think about it step by step and give a summary of the missing information and how it could be acquired.
think_about_task_adherence: |
Are you deviating from the task at hand? Do you need any additional information to proceed?
Have you loaded all relevant memory files to see whether your implementation is fully aligned with the
code style, conventions, and guidelines of the project? If not, adjust your implementation accordingly
before modifying any code into the codebase.
Note that it is better to stop and ask the user for clarification
than to perform large changes which might not be aligned with the user's intentions.
If you feel like the conversation is deviating too much from the original task, apologize and suggest to the user
how to proceed. If the conversation became too long, create a summary of the current progress and suggest to the user
to start a new conversation based on that summary.
think_about_whether_you_are_done: |
Have you already performed all the steps required by the task? Is it appropriate to run tests and linting, and if so,
have you done that already? Is it appropriate to adjust non-code files like documentation and config and have you done that already?
Should new tests be written to cover the changes?
Note that a task that is just about exploring the codebase does not require running tests or linting.
Read the corresponding memory files to see what should be done when a task is completed.
summarize_changes: |
Summarize all the changes you have made to the codebase over the course of the conversation.
Explore the diff if needed (e.g. by using `git diff`) to ensure that you have not missed anything.
Explain whether and how the changes are covered by tests. Explain how to best use the new code, how to understand it,
which existing code it affects and interacts with. Are there any dangers (like potential breaking changes or potential new problems)
that the user should be aware of? Should any new documentation be written or existing documentation updated?
You can use tools to explore the codebase prior to writing the summary, but don't write any new code in this step until
the summary is complete.
prepare_for_new_conversation: |
You have not yet completed the current task but we are running out of context.
{mode_prepare_for_new_conversation}
Imagine that you are handing over the task to another person who has access to the
same tools and memory files as you do, but has not been part of the conversation so far.
Write a summary that can be used in the next conversation to a memory file using the `write_memory` tool.
+24 -23
View File
@@ -69,40 +69,41 @@ read_only: false
# To make sure you have the latest list of tools, and to view their descriptions,
# execute `uv run scripts/print_tool_overview.py`.
#
# * `activate_project`: Activates a project by name.
# * `activate_project`: Activates a project based on the project name or path.
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
# * `create_text_file`: Creates/overwrites a file in the project directory.
# * `delete_lines`: Deletes a range of lines within a file.
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
# * `delete_memory`: Delete a memory file. Should only happen if a user asks for it explicitly,
# for example by saying that the information retrieved from a memory file is no longer correct
# or no longer relevant for the project.
# * `edit_memory`: Replaces content matching a regular expression in a memory.
# * `execute_shell_command`: Executes a shell command.
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
# * `find_file`: Finds files in the given relative paths
# * `find_referencing_symbols`: Finds symbols that reference the given symbol using the language server backend
# * `find_symbol`: Performs a global (or local) search using the language server backend.
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
# * `initial_instructions`: Gets the initial instructions for the current project.
# Should only be used in settings where the system prompt cannot be set,
# e.g. in clients you have no control over, like Claude Desktop.
# * `initial_instructions`: Provides instructions Serena usage (i.e. the 'Serena Instructions Manual')
# for clients that do not read the initial instructions when the MCP server is connected.
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
# * `insert_at_line`: Inserts content at a given line in a file.
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
# * `list_memories`: Lists memories in Serena's project-specific memory store.
# * `list_memories`: List available memories. Any memory can be read using the `read_memory` tool.
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
# * `read_file`: Reads a file within the project directory.
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
# * `remove_project`: Removes a project from the Serena configuration.
# * `replace_lines`: Replaces a range of lines within a file with new content.
# * `replace_symbol_body`: Replaces the full definition of a symbol.
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
# * `read_memory`: Read the content of a memory file. This tool should only be used if the information
# is relevant to the current task. You can infer whether the information
# is relevant from the memory file name.
# You should not read the same memory file multiple times in the same conversation.
# * `rename_memory`: Renames or moves a memory. Moving between project and global scope is supported
# (e.g., renaming "global/foo" to "bar" moves it from global to project scope).
# * `rename_symbol`: Renames a symbol throughout the codebase using language server refactoring capabilities.
# For JB, we use a separate tool.
# * `replace_content`: Replaces content in a file (optionally using regular expressions).
# * `replace_symbol_body`: Replaces the full definition of a symbol using the language server backend.
# * `safe_delete_symbol`:
# * `search_for_pattern`: Performs a search for a pattern in the project.
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
# * `switch_modes`: Activates modes by providing a list of their names
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
# * `write_memory`: Write some information (utf-8-encoded) about this project that can be useful for future tasks to a memory in md format.
# The memory name should be meaningful.
excluded_tools: []
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default).
-21
View File
@@ -51,27 +51,6 @@ class RemoveProjectTool(Tool, ToolMarkerDoesNotRequireActiveProject, ToolMarkerO
return f"Successfully removed project '{project_name}' from configuration."
class SwitchModesTool(Tool, ToolMarkerOptional):
"""
Activates modes by providing a list of their names
"""
def apply(self, modes: list[str]) -> str:
"""
Activates the desired modes, like ["editing", "interactive"] or ["planning", "one-shot"]
:param modes: the names of the modes to activate
"""
self.agent.set_modes(modes)
# Inform the Agent about the activated modes and the currently active tools
mode_instances = self.agent.get_active_modes()
result_str = f"Active modes: {', '.join([mode.name for mode in mode_instances])}" + "\n"
result_str += "\n".join([mode_instance.prompt for mode_instance in mode_instances]) + "\n"
result_str += f"Currently active tools: {', '.join(self.agent.get_active_tool_names())}"
return result_str
class GetCurrentConfigTool(Tool):
"""
Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
+21
View File
@@ -429,6 +429,15 @@ tool_packages = ["serena.tools"]
@singleton
class ToolRegistry:
_deleted_tools: list[str] = [
"think_about_collected_information",
"think_about_collected_information",
"prepare_for_new_conversation",
"summarize_changes",
"think_about_whether_you_are_done",
"switch_modes",
]
def __init__(self) -> None:
self._tool_dict: dict[str, RegisteredTool] = {}
inclusion_predicate = lambda c: "apply" in c.__dict__ # include only concrete tool classes that implement apply
@@ -518,3 +527,15 @@ class ToolRegistry:
def is_valid_tool_name(self, tool_name: str) -> bool:
return tool_name in self._tool_dict
def check_valid_tool_name(self, tool_name: str, caller_context_for_logging: str = "") -> bool:
"""Returns True if the tool name is valid, False if it is deleted, and raises ValueError if it is invalid."""
if self.is_deleted_tool_name(tool_name):
log.warning(f"Tool name is deleted: {tool_name}{caller_context_for_logging}")
return False
if not self.is_valid_tool_name(tool_name):
raise ValueError(f"Invalid tool name: {tool_name}{caller_context_for_logging}")
return True
def is_deleted_tool_name(self, tool_name: str) -> bool:
return tool_name in self._deleted_tools
+1 -69
View File
@@ -4,7 +4,7 @@ Tools supporting the general workflow of the agent
import platform
from serena.tools import Tool, ToolMarkerDoesNotRequireActiveProject, ToolMarkerOptional
from serena.tools import Tool, ToolMarkerDoesNotRequireActiveProject
class CheckOnboardingPerformedTool(Tool):
@@ -50,74 +50,6 @@ class OnboardingTool(Tool):
return self.prompt_factory.create_onboarding_prompt(system=system)
class ThinkAboutCollectedInformationTool(Tool, ToolMarkerOptional):
"""
Thinking tool for pondering the completeness of collected information.
"""
def apply(self) -> str:
"""
Think about the collected information and whether it is sufficient and relevant.
This tool should ALWAYS be called after you have completed a non-trivial sequence of searching steps like
find_symbol, find_referencing_symbols, search_files_for_pattern, read_file, etc.
"""
return self.prompt_factory.create_think_about_collected_information()
class ThinkAboutTaskAdherenceTool(Tool, ToolMarkerOptional):
"""
Thinking tool for determining whether the agent is still on track with the current task.
"""
def apply(self) -> str:
"""
Think about the task at hand and whether you are still on track.
Especially important if the conversation has been going on for a while and there
has been a lot of back and forth.
This tool should ALWAYS be called before you insert, replace, or delete code.
"""
return self.prompt_factory.create_think_about_task_adherence()
class ThinkAboutWhetherYouAreDoneTool(Tool, ToolMarkerOptional):
"""
Thinking tool for determining whether the task is truly completed.
"""
def apply(self) -> str:
"""
Whenever you feel that you are done with what the user has asked for, it is important to call this tool.
"""
return self.prompt_factory.create_think_about_whether_you_are_done()
class SummarizeChangesTool(Tool, ToolMarkerOptional):
"""
Provides instructions for summarizing the changes made to the codebase.
"""
def apply(self) -> str:
"""
Summarize the changes you have made to the codebase.
This tool should always be called after you have fully completed any non-trivial coding task,
but only after the think_about_whether_you_are_done call.
"""
return self.prompt_factory.create_summarize_changes()
class PrepareForNewConversationTool(Tool):
"""
Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
"""
def apply(self) -> str:
"""
Instructions for preparing for a new conversation. This tool should only be called on explicit user request.
"""
return self.prompt_factory.create_prepare_for_new_conversation()
class InitialInstructionsTool(Tool, ToolMarkerDoesNotRequireActiveProject):
"""
Provides instructions Serena usage (i.e. the 'Serena Instructions Manual')