insert_after_symbol
Insert specified code content after a defined symbol in a file. Use this tool to add classes, functions, methods, or variable assignments efficiently within large codebases.
Instructions
Inserts the given body/content after the end of the definition of the given symbol (via the symbol's location). A typical use case is to insert a new class, function, method, field or variable assignment.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | The body/content to be inserted. The inserted code shall begin with the next line after the symbol. | |
| name_path | Yes | Name path of the symbol after which to insert content (definitions in the `find_symbol` tool apply). | |
| relative_path | Yes | The relative path to the file containing the symbol. |
Implementation Reference
- src/serena/tools/symbol_tools.py:237-259 (handler)The MCP tool handler: InsertAfterSymbolTool class with apply method that executes the tool logic by delegating to CodeEditor.insert_after_symbol.class InsertAfterSymbolTool(Tool, ToolMarkerSymbolicEdit): """ Inserts content after the end of the definition of a given symbol. """ def apply( self, name_path: str, relative_path: str, body: str, ) -> str: """ Inserts the given body/content after the end of the definition of the given symbol (via the symbol's location). A typical use case is to insert a new class, function, method, field or variable assignment. :param name_path: name path of the symbol after which to insert content (definitions in the `find_symbol` tool apply) :param relative_path: the relative path to the file containing the symbol :param body: the body/content to be inserted. The inserted code shall begin with the next line after the symbol. """ code_editor = self.create_code_editor() code_editor.insert_after_symbol(name_path, relative_file_path=relative_path, body=body) return SUCCESS_RESULT
- src/serena/code_editor.py:121-154 (helper)Core helper method in CodeEditor that performs the actual file insertion after locating the symbol using language server symbols.def insert_after_symbol(self, name_path: str, relative_file_path: str, body: str) -> None: """ Inserts content after the symbol with the given name in the given file. """ symbol = self._find_unique_symbol(name_path, relative_file_path) # make sure body always ends with at least one newline if not body.endswith("\n"): body += "\n" pos = symbol.get_body_end_position_or_raise() # start at the beginning of the next line col = 0 line = pos.line + 1 # make sure a suitable number of leading empty lines is used (at least 0/1 depending on the symbol type, # otherwise as many as the caller wanted to insert) original_leading_newlines = self._count_leading_newlines(body) body = body.lstrip("\r\n") min_empty_lines = 0 if symbol.is_neighbouring_definition_separated_by_empty_line(): min_empty_lines = 1 num_leading_empty_lines = max(min_empty_lines, original_leading_newlines) if num_leading_empty_lines: body = ("\n" * num_leading_empty_lines) + body # make sure the one line break succeeding the original symbol, which we repurposed as prefix via # `line += 1`, is replaced body = body.rstrip("\r\n") + "\n" with self._edited_file_context(relative_file_path) as edited_file: edited_file.insert_text_at_position(PositionInFile(line, col), body)
- src/serena/tools/tools_base.py:358-370 (registration)ToolRegistry singleton that automatically discovers and registers all Tool subclasses in serena.tools modules, including InsertAfterSymbolTool as 'insert_after_symbol'.@singleton class ToolRegistry: def __init__(self) -> None: self._tool_dict: dict[str, RegisteredTool] = {} for cls in iter_subclasses(Tool): if not cls.__module__.startswith("serena.tools"): continue is_optional = issubclass(cls, ToolMarkerOptional) 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)
- The apply method signature and docstring define the tool schema (parameters and description) used for MCP tool spec via func_metadata.def apply( self, name_path: str, relative_path: str, body: str, ) -> str: """ Inserts the given body/content after the end of the definition of the given symbol (via the symbol's location). A typical use case is to insert a new class, function, method, field or variable assignment. :param name_path: name path of the symbol after which to insert content (definitions in the `find_symbol` tool apply) :param relative_path: the relative path to the file containing the symbol :param body: the body/content to be inserted. The inserted code shall begin with the next line after the symbol. """ code_editor = self.create_code_editor() code_editor.insert_after_symbol(name_path, relative_file_path=relative_path, body=body) return SUCCESS_RESULT
- Naming convention helper: converts InsertAfterSymbolTool class name to 'insert_after_symbol' tool name.def get_name_from_cls(cls) -> str: name = cls.__name__ if name.endswith("Tool"): name = name[:-4] # convert to snake_case name = "".join(["_" + c.lower() if c.isupper() else c for c in name]).lstrip("_") return name def get_name(self) -> str: return self.get_name_from_cls()