Skip to content

Commit

Permalink
added repeat command and accompanying test hat - 100% aider written
Browse files Browse the repository at this point in the history
  • Loading branch information
hux committed Jan 19, 2025
1 parent c395be2 commit 61a6f00
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
23 changes: 23 additions & 0 deletions aider/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,29 @@ def cmd_editor(self, initial_content=""):
if user_input.strip():
self.io.set_placeholder(user_input.rstrip())

def cmd_repeat(self, args):
"Repeat a prompt multiple times, using each assistant response as context for the next prompt"

# Parse args into count and message
try:
count_str, *message_parts = args.strip().split(maxsplit=1)
count = int(count_str)
if count < 1:
raise ValueError("Count must be positive")
message = message_parts[0] if message_parts else ""
except (ValueError, IndexError) as e:
self.io.tool_error("Usage: /repeat N 'message' - where N is a positive number")
return

if not message:
self.io.tool_error("Please provide a message to repeat")
return

# Run the prompt multiple times
for i in range(count):
self.io.tool_output(f"\nRepeat {i+1}/{count}: {message}")
self.coder.run(message)

def cmd_copy_context(self, args=None):
"""Copy the current chat context as markdown, suitable to paste into a web UI"""

Expand Down
60 changes: 60 additions & 0 deletions tests/basic/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1722,6 +1722,66 @@ def test_cmd_reset(self):
del coder
del commands

def test_cmd_repeat_happy_path(self):
# Initialize the Commands and InputOutput objects
io = InputOutput(pretty=False, fancy_input=False, yes=True)
coder = Coder.create(self.GPT35, None, io)
commands = Commands(io, coder)

# Mock coder.run to track calls
with mock.patch.object(coder, 'run') as mock_run:
commands.cmd_repeat("3 fix the tests")

# Verify coder.run was called 3 times with the same message
self.assertEqual(mock_run.call_count, 3)
mock_run.assert_has_calls([
mock.call("fix the tests"),
mock.call("fix the tests"),
mock.call("fix the tests")
])

def test_cmd_repeat_invalid_count(self):
io = InputOutput(pretty=False, fancy_input=False, yes=True)
coder = Coder.create(self.GPT35, None, io)
commands = Commands(io, coder)

# Test invalid inputs
invalid_inputs = [
"abc fix tests", # non-numeric count
"-1 fix tests", # negative count
"0 fix tests", # zero count
"", # empty input
]

with mock.patch.object(io, 'tool_error') as mock_error:
for invalid_input in invalid_inputs:
commands.cmd_repeat(invalid_input)
mock_error.assert_called_with("Usage: /repeat N 'message' - where N is a positive number")
mock_error.reset_mock()

def test_cmd_repeat_no_message(self):
io = InputOutput(pretty=False, fancy_input=False, yes=True)
coder = Coder.create(self.GPT35, None, io)
commands = Commands(io, coder)

with mock.patch.object(io, 'tool_error') as mock_error:
commands.cmd_repeat("3")
mock_error.assert_called_with("Please provide a message to repeat")

def test_cmd_repeat_with_quoted_message(self):
io = InputOutput(pretty=False, fancy_input=False, yes=True)
coder = Coder.create(self.GPT35, None, io)
commands = Commands(io, coder)

with mock.patch.object(coder, 'run') as mock_run:
commands.cmd_repeat('2 "fix the tests please"')

self.assertEqual(mock_run.call_count, 2)
mock_run.assert_has_calls([
mock.call("fix the tests please"),
mock.call("fix the tests please")
])

def test_cmd_load_with_switch_coder(self):
with GitTemporaryDirectory() as repo_dir:
io = InputOutput(pretty=False, fancy_input=False, yes=True)
Expand Down

0 comments on commit 61a6f00

Please sign in to comment.