Commit graph

10395 commits

Author SHA1 Message Date
Paul Gauthier
27db4c038f bugfix 2023-06-05 08:29:08 -07:00
Paul Gauthier
a3075d2da0 Added networkx==3.1 2023-06-05 08:27:39 -07:00
Paul Gauthier
93ca588bab sssh 2023-06-05 08:24:02 -07:00
Paul Gauthier
41ac5b056d Merge branch 'call-graph' into gpt-35 2023-06-04 15:39:49 -07:00
Paul Gauthier
140b03314e Merge branch 'main' into call-graph 2023-06-04 15:39:42 -07:00
Paul Gauthier
6398e5ef18 Support worktrees 2023-06-04 15:37:20 -07:00
Paul Gauthier
0256b8e260 Merge branch 'call-graph' into gpt-35 2023-06-04 15:03:46 -07:00
Paul Gauthier
6b62756703 Merge branch 'main' into call-graph 2023-06-04 15:03:18 -07:00
Paul Gauthier
c0bf25d05b undo trailing newline "fix" 2023-06-04 15:03:13 -07:00
Paul Gauthier
53e8c65745 Return files without any tags at all at the tail of the ranked_tags list 2023-06-04 14:53:14 -07:00
Paul Gauthier
dfcf813ad6 include individual files in the ranked tags list, following specific ranked idents 2023-06-04 14:45:57 -07:00
Paul Gauthier
d1cc4b93be Merge branch 'call-graph' into gpt-35 2023-06-04 14:30:35 -07:00
Paul Gauthier
dedf3fbebb Merge branch 'main' into call-graph 2023-06-04 14:30:27 -07:00
Paul Gauthier
f47f611e65 Handle empty replacement text too 2023-06-04 14:30:22 -07:00
Paul Gauthier
b339df3f70 Merge branch 'call-graph' into gpt-35 2023-06-04 14:28:28 -07:00
Paul Gauthier
1cf29a0166 Merge branch 'main' into call-graph 2023-06-04 14:28:19 -07:00
Paul Gauthier
fe1271114f Avoid stripping a newline when doing nearest search/replace 2023-06-04 14:28:03 -07:00
Paul Gauthier
d12d8ff69a lint 2023-06-04 14:16:06 -07:00
Paul Gauthier
5a61e6acd2 aider: Added a new file that imports MyClass and calls both its methods to test_get_repo_map_with_identifiers.
# Context:
USER: in `test_get_repo_map_with_identifiers` make a 2nd file that imports MyClass and calls both its methods. add that to `other_files`
ASSISTANT: Here are the changes you need to make:

1. Modify `test_get_repo_map_with_identifiers` in `tests/test_repomap.py` to add a new file that imports `MyClass` and calls both its methods:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
    def test_get_repo_map_with_identifiers(self):
        # Create a temporary directory with a sample Python file containing identifiers
        test_file = "test_file_with_identifiers.py"
        file_content = """\
class MyClass:
    def my_method(self, arg1, arg2):
        return arg1 + arg2

def my_function(arg1, arg2):
    return arg1 * arg2
"""

        with tempfile.TemporaryDirectory() as temp_dir:
            with open(os.path.join(temp_dir, test_file), "w") as f:
                f.write(file_content)

            repo_map = RepoMap(root=temp_dir)
            other_files = [os.path.join(temp_dir, test_file), os.path.join(temp_dir, "test_file_import.py")]
            result = repo_map.get_repo_map([], other_files)

            # Check if the result contains the expected tags map with identifiers
            self.assertIn("test_file_with_identifiers.py", result)
            self.assertIn("MyClass", result)
            self.assertIn("my_method", result)
            self.assertIn("my_function", result)
=======
    def test_get_repo_map_with_identifiers(self):
        # Create a temporary directory with a sample Python file containing identifiers
        test_file1 = "test_file_with_identifiers.py"
        file_content1 = """\
class MyClass:
    def my_method(self, arg1, arg2):
        return arg1 + arg2

def my_function(arg1, arg2):
    return arg1 * arg2
"""

        test_file2 = "test_file_import.py"
        file_content2 = """\
from test_file_with_identifiers import MyClass

obj = MyClass()
print(obj.my_method(1, 2))
print(my_function(3, 4))
"""

        with tempfile.TemporaryDirectory() as temp_dir:
            with open(os.path.join(temp_dir, test_file1), "w") as f:
                f.write(file_content1)

            with open(os.path.join(temp_dir, test_file2), "w") as f:
                f.write(file_content2)

            repo_map = RepoMap(root=temp_dir)
            other_files = [os.path.join(temp_dir, test_file1), os.path.join(temp_dir, test_file2)]
            result = repo_map.get_repo_map([], other_files)

            # Check if the result contains the expected tags map with identifiers
            self.assertIn("test_file_with_identifiers.py", result)
            self.assertIn("MyClass", result)
            self.assertIn("my_method", result)
            self.assertIn("my_function", result)
>>>>>>> UPDATED
```

2. Run the tests to make sure everything is working as expected.
2023-06-04 14:15:25 -07:00
Paul Gauthier
95cb482938 bugfix 2023-06-04 14:13:56 -07:00
Paul Gauthier
676dcd8fd1 fixed some tests 2023-06-04 14:07:50 -07:00
Paul Gauthier
56d2aa59ee 3.5 prompts 2023-06-04 13:59:43 -07:00
Paul Gauthier
2bdfdb11bb Don't add gpt-3.5 replies to the history if they contain edits 2023-06-04 13:44:04 -07:00
Paul Gauthier
05c4f5654f clean up initial status messages 2023-06-04 13:34:06 -07:00
Paul Gauthier
b9ce79909e copy 2023-06-04 13:22:38 -07:00
Paul Gauthier
94767f73a1 Merge branch 'call-graph' into gpt-35 2023-06-04 13:20:52 -07:00
Paul Gauthier
5cc28bae15 Merge branch 'main' into call-graph 2023-06-04 13:20:44 -07:00
Paul Gauthier
87df24bcd9 period 2023-06-04 13:20:35 -07:00
Paul Gauthier
e627d8282f apply edits from 3.5 2023-06-04 13:18:33 -07:00
Paul Gauthier
b310bdf44b prompt 2023-06-04 12:07:30 -07:00
Paul Gauthier
9168331f4b bugfix 2023-06-04 12:04:51 -07:00
Paul Gauthier
cdfc0a38ee refac 2023-06-04 11:50:56 -07:00
Paul Gauthier
9d821dbca6 cleanup 2023-06-04 11:45:59 -07:00
Paul Gauthier
b02000caa9 Force showing diffs and disabling ctags/repo-maps 2023-06-04 11:43:03 -07:00
Paul Gauthier
9088d139b2 refactor prompts 2023-06-04 11:36:50 -07:00
Paul Gauthier
1ae29a820c Merge branch 'call-graph' into gpt-35 2023-06-04 09:53:26 -07:00
Paul Gauthier
12512df707 Handle the case where there is no rank flow 2023-06-04 09:53:09 -07:00
Paul Gauthier
7305e9d457 Added new files to the git repo: aider/diffs.py 2023-06-04 09:50:30 -07:00
Paul Gauthier
414b6a3b3e noop 2023-06-04 09:49:49 -07:00
Paul Gauthier
345c3daaa2 wip 2023-06-04 08:57:39 -07:00
Paul Gauthier
91f48dfdf1 aider: Added a check for an empty tags list in to_tree function.
# Context:
USER:  File "/Users/gauthier/Projects/aider/aider/repomap.py", line 107, in choose_files_listing
    files_listing = self.get_ranked_tags_map(chat_files, other_files)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/gauthier/Projects/aider/aider/repomap.py", line 318, in get_ranked_tags_map
    tree = to_tree(ranked_tags[:middle])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/gauthier/Projects/aider/aider/repomap.py", line 26, in to_tree
    last = [None] * len(tags[0])
                        ~~~~^^^
ASSISTANT: I see the code snippets from the `aider/repomap.py` file. Please let me know what changes you would like to make, and make sure to provide me with the *read-write* access to the file.
USER: I added these *read-write* files: aider/repomap.py
ASSISTANT: Great! Now, please let me know what changes you would like to make in the `aider/repomap.py` file.
USER:   File "/Users/gauthier/Projects/aider/aider/repomap.py", line 318, in get_ranked_tags_map
    tree = to_tree(ranked_tags[:middle])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/gauthier/Projects/aider/aider/repomap.py", line 26, in to_tree
    last = [None] * len(tags[0])
                        ~~~~^^^
IndexError: list index out of range
ASSISTANT: It seems like you are encountering an IndexError due to an empty `tags` list. To fix this issue, you can add a check to ensure that the `tags` list is not empty before accessing its elements. Here's the change you need to make in the `aider/repomap.py` file:

```python
aider/repomap.py
<<<<<<< ORIGINAL
def to_tree(tags):
    tags = sorted(tags)

    output = ""
    last = [None] * len(tags[0])
=======
def to_tree(tags):
    if not tags:
        return ""

    tags = sorted(tags)

    output = ""
    last = [None] * len(tags[0])
>>>>>>> UPDATED
```

This change adds a check for an empty `tags` list and returns an empty string if the list is empty, preventing the IndexError.
2023-06-04 06:43:30 -07:00
Paul Gauthier
6da3c3943e Merge branch 'main' into call-graph 2023-06-04 06:33:48 -07:00
Paul Gauthier
8aba2376ce added backoff==2.2.1 2023-06-04 06:22:26 -07:00
Paul Gauthier
106eab7a7a Merge branch 'main' into call-graph 2023-06-04 06:10:22 -07:00
Paul Gauthier
84421d8651 aider: Replaced patching of aider.coder.backoff.expo with patching of the print function and updated the assertions accordingly.
# Context:
USER: instead of patching and checking that aider.coder.backoff.expo, patch and check "print"
ASSISTANT: To patch and check the `print` function instead of `aider.coder.backoff.expo`, you can modify the `test_send_with_retries_rate_limit_error` and `test_send_with_retries_connection_error` test cases in the `tests/test_coder.py` file. Here are the changes:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
    @patch("aider.coder.openai.ChatCompletion.create")
    @patch("aider.coder.backoff.expo")
    def test_send_with_retries_rate_limit_error(self, mock_backoff_expo, mock_chat_completion_create):
=======
    @patch("aider.coder.openai.ChatCompletion.create")
    @patch("builtins.print")
    def test_send_with_retries_rate_limit_error(self, mock_print, mock_chat_completion_create):
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Assert that backoff.expo was called once
        mock_backoff_expo.assert_called_once()
=======
        # Assert that print was called once
        mock_print.assert_called_once()
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
    @patch("aider.coder.openai.ChatCompletion.create")
    @patch("aider.coder.backoff.expo")
    def test_send_with_retries_connection_error(self, mock_backoff_expo, mock_chat_completion_create):
=======
    @patch("aider.coder.openai.ChatCompletion.create")
    @patch("builtins.print")
    def test_send_with_retries_connection_error(self, mock_print, mock_chat_completion_create):
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Assert that backoff.expo was called once
        mock_backoff_expo.assert_called_once()
=======
        # Assert that print was called once
        mock_print.assert_called_once()
>>>>>>> UPDATED
```

These changes replace the patching of `aider.coder.backoff.expo` with patching of the `print` function and update the assertions accordingly.
2023-06-04 06:05:48 -07:00
Paul Gauthier
0abbf43466 just print 2023-06-04 06:04:32 -07:00
Paul Gauthier
091bcaa1a2 aider: Updated test_send_with_retries tests to use backoff library instead of time.sleep.
# Context:
USER: `tests/test_coder.py` `aider/coder.py` Fix the test_send_with_retries tests since we no longer use time.sleep but backoff instead
ASSISTANT: To fix the test_send_with_retries tests in `tests/test_coder.py`, we need to update the tests to use the backoff library instead of time.sleep. Here's how to do it:

1. Replace the `@patch("aider.coder.time.sleep")` with `@patch("aider.coder.backoff.expo")` in both test_send_with_retries_rate_limit_error and test_send_with_retries_connection_error tests.
2. Update the test_send_with_retries_rate_limit_error and test_send_with_retries_connection_error tests to assert that backoff.expo was called once instead of time.sleep.

Here are the changes:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
    @patch("aider.coder.time.sleep")
    def test_send_with_retries_rate_limit_error(self, mock_sleep, mock_chat_completion_create):
=======
    @patch("aider.coder.backoff.expo")
    def test_send_with_retries_rate_limit_error(self, mock_backoff_expo, mock_chat_completion_create):
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Assert that time.sleep was called once
        mock_sleep.assert_called_once()
=======
        # Assert that backoff.expo was called once
        mock_backoff_expo.assert_called_once()
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
    @patch("aider.coder.time.sleep")
    def test_send_with_retries_connection_error(self, mock_sleep, mock_chat_completion_create):
=======
    @patch("aider.coder.backoff.expo")
    def test_send_with_retries_connection_error(self, mock_backoff_expo, mock_chat_completion_create):
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        # Assert that time.sleep was called once
        mock_sleep.assert_called_once()
=======
        # Assert that backoff.expo was called once
        mock_backoff_expo.assert_called_once()
>>>>>>> UPDATED
```

These changes should fix the test_send_with_retries tests in `tests/test_coder.py`.
2023-06-04 05:58:06 -07:00
Paul Gauthier
df91e9ab1c aider: Implemented backoff library to handle rate limit issues with exponential backoff and a maximum of 5 retries.
# Context:
USER: Hello there,

thanks for making this open source!
I have a request: due to being still on the free credits of OpenAI API, I run into timeouts.

fetch_starred_repos.py
Add these files to the chat? y
RateLimitError: You exceeded your current quota, please check your plan and billing details.
Retry in 1 seconds.
...
Is it possible for you to implement this library to omit that?
https://pypi.org/project/backoff/

Thanks in advance.
Greetings from Germany

ASSISTANT: Sure, I can help you implement the `backoff` library to handle the rate limit issue. First, please make the `aider/coder.py` file *read-write* so I can propose changes to it.
USER: I added these *read-write* files: aider/coder.py
ASSISTANT: Great! First, you need to install the `backoff` library. You can do this by running:

```
pip install backoff
```

Next, I will show you the changes needed in the `aider/coder.py` file to implement the `backoff` library for handling rate limit issues.

1. Import the `backoff` library at the beginning of the file.
2. Replace the `send_with_retries` method with a new method that uses the `backoff` library.

Here are the changes:

```python
aider/coder.py
<<<<<<< ORIGINAL
import os
import sys
import time
import traceback
=======
import os
import sys
import traceback
import backoff
>>>>>>> UPDATED
```

```python
aider/coder.py
<<<<<<< ORIGINAL
    def send_with_retries(self, model, messages):
        while True:
            try:
                return openai.ChatCompletion.create(
                    model=model,
                    messages=messages,
                    temperature=0,
                    stream=True,
                )
            except RateLimitError as err:
                self.io.tool_error(f"RateLimitError: {err}")
            except requests.exceptions.ConnectionError as err:
                self.io.tool_error(f"ConnectionError: {err}")

            retry_after = 1
            self.io.tool_error(f"Retry in {retry_after} seconds.")
            time.sleep(retry_after)
=======
    @backoff.on_exception(
        backoff.expo,
        (RateLimitError, requests.exceptions.ConnectionError),
        max_tries=5,
        on_backoff=lambda details: self.io.tool_error(f"Retry in {details['wait']} seconds."),
    )
    def send_with_retries(self, model, messages):
        return openai.ChatCompletion.create(
            model=model,
            messages=messages,
            temperature=0,
            stream=True,
        )
>>>>>>> UPDATED
```

These changes will implement the `backoff` library to handle rate limit issues with exponential backoff and a maximum of 5 retries. If you want to adjust the number of retries, you can change the `max_tries` parameter in the `backoff.on_exception` decorator.
2023-06-04 05:53:06 -07:00
Paul Gauthier
b4fc6c2caa sssh 2023-06-03 18:11:45 -07:00
Paul Gauthier
ca8d13f194 scrub --ctags from docs 2023-06-03 18:10:02 -07:00