edit_memory
Replace content in memory files using literal strings or regex patterns to update stored information.
Instructions
Replaces content matching a regular expression in a memory.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| memory_file_name | Yes | The name of the memory. | |
| needle | Yes | The string or regex pattern to search for. If `mode` is "literal", this string will be matched exactly. If `mode` is "regex", this string will be treated as a regular expression (syntax of Python's `re` module, with flags DOTALL and MULTILINE enabled). | |
| repl | Yes | The replacement string (verbatim). | |
| mode | Yes | Either "literal" or "regex", specifying how the `needle` parameter is to be interpreted. |
Implementation Reference
- src/serena/tools/memory_tools.py:69-91 (handler)The EditMemoryTool class provides the core handler logic for the 'edit_memory' tool. It replaces content in a project memory file using literal string or regex replacement by delegating to ReplaceContentTool.class EditMemoryTool(Tool, ToolMarkerCanEdit): def apply( self, memory_file_name: str, needle: str, repl: str, mode: Literal["literal", "regex"], ) -> str: r""" Replaces content matching a regular expression in a memory. :param memory_file_name: the name of the memory :param needle: the string or regex pattern to search for. If `mode` is "literal", this string will be matched exactly. If `mode` is "regex", this string will be treated as a regular expression (syntax of Python's `re` module, with flags DOTALL and MULTILINE enabled). :param repl: the replacement string (verbatim). :param mode: either "literal" or "regex", specifying how the `needle` parameter is to be interpreted. """ replace_content_tool = self.agent.get_tool(ReplaceContentTool) rel_path = self.memories_manager.get_memory_file_path(memory_file_name).relative_to(self.get_project_root()) return replace_content_tool.replace_content(str(rel_path), needle, repl, mode=mode, require_not_ignored=False)
- src/serena/tools/tools_base.py:358-367 (registration)ToolRegistry discovers all Tool subclasses (including EditMemoryTool) via iter_subclasses and registers them by their snake_case name (EditMemoryTool -> 'edit_memory'). This makes the tool available to the agent.self._tool_dict: dict[str, RegisteredTool] = {} for cls in iter_subclasses(Tool): if not any(cls.__module__.startswith(pkg) for pkg in tool_packages): 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)
- Defines the tool naming convention used by Tool subclasses and registry: converts 'EditMemoryTool' to 'edit_memory', which is the MCP-exposed 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()