feat(memory): implement str_replace command
This commit is contained in:
@@ -367,10 +367,55 @@ class MemoryTool20250818(BaseAnthropicTool):
|
||||
)
|
||||
|
||||
async def _str_replace(
|
||||
self, path: str | None, old_str: str | None, new_str: str | None
|
||||
self,
|
||||
path: str | None,
|
||||
old_str: str | None,
|
||||
new_str: str | None,
|
||||
) -> CLIResult:
|
||||
"""Placeholder for str_replace command."""
|
||||
return CLIResult(exit_code=1, output="", error="Not implemented yet")
|
||||
"""Replace unique occurrence of old_str with new_str."""
|
||||
if path is None or old_str is None or new_str is None:
|
||||
return CLIResult(
|
||||
exit_code=1,
|
||||
output="",
|
||||
error="Error: old_str and new_str are required for str_replace command"
|
||||
)
|
||||
|
||||
path_str = path
|
||||
validated_path = self._validate_memory_path(path)
|
||||
|
||||
if not validated_path.exists() or validated_path.is_dir():
|
||||
return CLIResult(
|
||||
exit_code=1,
|
||||
output="",
|
||||
error=f"Error: The path {path_str} does not exist. Please provide a valid path."
|
||||
)
|
||||
|
||||
content = validated_path.read_text()
|
||||
count = content.count(old_str)
|
||||
|
||||
if count == 0:
|
||||
return CLIResult(
|
||||
exit_code=1,
|
||||
output="",
|
||||
error=f"No replacement was performed, old_str `{old_str}` did not appear verbatim in {path_str}."
|
||||
)
|
||||
elif count > 1:
|
||||
lines = content.splitlines()
|
||||
line_nums = [i + 1 for i, line in enumerate(lines) if old_str in line]
|
||||
return CLIResult(
|
||||
exit_code=1,
|
||||
output="",
|
||||
error=f"No replacement was performed. Multiple occurrences of old_str `{old_str}` in lines: {line_nums}. Please ensure it is unique"
|
||||
)
|
||||
|
||||
new_content = content.replace(old_str, new_str, 1)
|
||||
validated_path.write_text(new_content)
|
||||
|
||||
return CLIResult(
|
||||
exit_code=0,
|
||||
output="The memory file has been edited.",
|
||||
error=""
|
||||
)
|
||||
|
||||
async def _insert(
|
||||
self, path: str | None, insert_line: int | None, insert_text: str | None
|
||||
|
||||
@@ -179,3 +179,61 @@ async def test_create_file_missing_text(memory_tool):
|
||||
assert result.exit_code == 1
|
||||
assert result.output == ""
|
||||
assert "Error: file_text is required for create command" in result.error
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_str_replace_success(memory_tool, temp_workspace):
|
||||
"""Test replacing unique string in a file."""
|
||||
test_file = temp_workspace / "memories" / "config.txt"
|
||||
test_file.write_text("color: blue\nsize: large\n")
|
||||
|
||||
result = await memory_tool(
|
||||
command="str_replace",
|
||||
path="/memories/config.txt",
|
||||
old_str="blue",
|
||||
new_str="green"
|
||||
)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert result.error == ""
|
||||
assert "The memory file has been edited." in result.output
|
||||
|
||||
# Verify file was modified
|
||||
assert test_file.read_text() == "color: green\nsize: large\n"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_str_replace_not_found(memory_tool, temp_workspace):
|
||||
"""Test replacing string that doesn't exist."""
|
||||
test_file = temp_workspace / "memories" / "config.txt"
|
||||
test_file.write_text("color: blue\n")
|
||||
|
||||
result = await memory_tool(
|
||||
command="str_replace",
|
||||
path="/memories/config.txt",
|
||||
old_str="red",
|
||||
new_str="green"
|
||||
)
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert result.output == ""
|
||||
assert "No replacement was performed, old_str `red` did not appear verbatim" in result.error
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_str_replace_duplicate(memory_tool, temp_workspace):
|
||||
"""Test replacing string that appears multiple times."""
|
||||
test_file = temp_workspace / "memories" / "config.txt"
|
||||
test_file.write_text("color: blue\nbackground: blue\n")
|
||||
|
||||
result = await memory_tool(
|
||||
command="str_replace",
|
||||
path="/memories/config.txt",
|
||||
old_str="blue",
|
||||
new_str="green"
|
||||
)
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert result.output == ""
|
||||
assert "Multiple occurrences of old_str `blue`" in result.error
|
||||
assert "Please ensure it is unique" in result.error
|
||||
|
||||
Reference in New Issue
Block a user