Commit graph

890 commits

Author SHA1 Message Date
Paul Gauthier
4c220ff63f refactor to use io.read_text 2023-07-05 20:31:22 -07:00
Paul Gauthier
9cab570f87 refactor to use io.read_text 2023-07-05 20:21:32 -07:00
Paul Gauthier
5f9947a727 aider: Add read_text function to InputOutput class and --encoding command-line switch.
# Context:
USER: Add a read_text function to the InputOutput class. It takes the file name as argument, and returns the text for that file. Internally, if we get a Unicode error or a FileNotFound error, it prints ToolErrorOutput to notify the user, and then returns None. Add a command-line switch, and dash-dash encoding, which defaults to UTF-8. That's the encoding which will be used by the read_text function.

ASSISTANT: To implement the requested changes, we need to modify the following files:

1. `aider/io.py`: To add the `read_text` function to the `InputOutput` class.
2. `aider/main.py`: To add the `--encoding` command-line switch.

Let's start with the changes to `aider/io.py`:

```python
aider/io.py
<<<<<<< ORIGINAL
class InputOutput:
    num_error_outputs = 0
    num_user_asks = 0

    def __init__(
        self,
        pretty=True,
        yes=False,
        input_history_file=None,
        chat_history_file=None,
        input=None,
        output=None,
        user_input_color="blue",
        tool_output_color=None,
        tool_error_color="red",
    ):
        no_color = os.environ.get("NO_COLOR")
        if no_color is not None and no_color != "":
            pretty = False

        self.user_input_color = user_input_color if pretty else None
        self.tool_output_color = tool_output_color if pretty else None
        self.tool_error_color = tool_error_color if pretty else None

        self.input = input
        self.output = output

        self.pretty = pretty
        if self.output:
            self.pretty = False

        self.yes = yes

        self.input_history_file = input_history_file
        if chat_history_file is not None:
            self.chat_history_file = Path(chat_history_file)
        else:
            self.chat_history_file = None

        if pretty:
            self.console = Console()
        else:
            self.console = Console(force_terminal=False, no_color=True)

        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.append_chat_history(f"\n# aider chat started at {current_time}\n\n")
=======
class InputOutput:
    num_error_outputs = 0
    num_user_asks = 0

    def __init__(
        self,
        pretty=True,
        yes=False,
        input_history_file=None,
        chat_history_file=None,
        input=None,
        output=None,
        user_input_color="blue",
        tool_output_color=None,
        tool_error_color="red",
        encoding="utf-8",
    ):
        no_color = os.environ.get("NO_COLOR")
        if no_color is not None and no_color != "":
            pretty = False

        self.user_input_color = user_input_color if pretty else None
        self.tool_output_color = tool_output_color if pretty else None
        self.tool_error_color = tool_error_color if pretty else None

        self.input = input
        self.output = output

        self.pretty = pretty
        if self.output:
            self.pretty = False

        self.yes = yes

        self.input_history_file = input_history_file
        if chat_history_file is not None:
            self.chat_history_file = Path(chat_history_file)
        else:
            self.chat_history_file = None

        self.encoding = encoding

        if pretty:
            self.console = Console()
        else:
            self.console = Console(force_terminal=False, no_color=True)

        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.append_chat_history(f"\n# aider chat started at {current_time}\n\n")

    def read_text(self, filename):
        try:
            with open(filename, "r", encoding=self.encoding) as f:
                return f.read()
        except (FileNotFoundError, UnicodeError) as e:
            self.tool_error(str(e))
            return None
>>>>>>> UPDATED
```

Now, let's add the `--encoding` command-line switch to `aider/main.py`:

```python
aider/main.py
<<<<<<< ORIGINAL
    parser.add_argument(
        "--no-dirty-commits",
        action="store_false",
        dest="dirty_commits",
        help="Disable commits when repo is found dirty",
    )
    parser.add_argument(
        "--openai-api-key",
        metavar="OPENAI_API_KEY",
        help="Specify the OpenAI API key",
        env_var="OPENAI_API_KEY",
    )
    parser.add_argument(
        "--openai-api-base",
        metavar="OPENAI_API_BASE",
        default="https://api.openai.com/v1",
        help="Specify the OpenAI API base endpoint (default: https://api.openai.com/v1)",
    )
=======
    parser.add_argument(
        "--no-dirty-commits",
        action="store_false",
        dest="dirty_commits",
        help="Disable commits when repo is found dirty",
    )
    parser.add_argument(
        "--encoding",
        default="utf-8",
        help="Specify the encoding to use when reading files (default: utf-8)",
    )
    parser.add_argument(
        "--openai-api-key",
        metavar="OPENAI_API_KEY",
        help="Specify the OpenAI API key",
        env_var="OPENAI_API_KEY",
    )
    parser.add_argument(
        "--openai-api-base",
        metavar="OPENAI_API_BASE",
        default="https://api.openai.com/v1",
        help="Specify the OpenAI API base endpoint (default: https://api.openai.com/v1)",
    )
>>>>>>> UPDATED
```

These changes should implement the requested functionality. Please review and let me know if any further changes are needed.
2023-07-05 19:33:59 -07:00
Paul Gauthier
d9f2c32aa9 Merge branch 'main' into encodings 2023-07-05 17:16:36 -07:00
Paul Gauthier
5dba1624c7 fix broken test 2023-07-05 17:11:39 -07:00
Paul Gauthier
e996c56a51 more robust get_tracked_files with pathlib 2023-07-05 16:55:37 -07:00
Paul Gauthier
c6696e7245 Added a test case to fail if git posix paths are not turned into windows paths 2023-07-05 16:53:43 -07:00
Paul Gauthier
bc60e7fd1c use Path.touch() to create new files 2023-07-05 15:44:12 -07:00
Paul Gauthier
f2a814d536 be more careful about ensuring self.root is an abspath 2023-07-05 15:16:57 -07:00
Paul Gauthier
a0774bf46a resolve cmd line files to abs path 2023-07-05 15:14:09 -07:00
Paul Gauthier
55b1634811 added debug output 2023-07-05 15:08:11 -07:00
Paul Gauthier
43103978b5 cleanup 2023-07-05 14:44:45 -07:00
Paul Gauthier
640a463a9c no pretty when output 2023-07-05 14:42:42 -07:00
Paul Gauthier
e34078da04 force_terminal=False 2023-07-05 14:38:35 -07:00
Paul Gauthier
e1e8e8e10a Turn off fancy Console if self.output 2023-07-05 14:36:13 -07:00
Paul Gauthier
ae5b4057e8 Merge remote-tracking branch 'origin/main' 2023-07-05 13:39:49 -07:00
Paul Gauthier
9ed19e63d0 bugfix 2023-07-05 13:36:00 -07:00
Paul Gauthier
21efc8d59e convert git.ls_files() to appropriate os.sep, since git always normalizes to / 2023-07-05 13:29:13 -07:00
Paul Gauthier
77a230f005 improved windows instructions, error message 2023-07-05 10:27:07 -07:00
kwmiebach
b80c83c6cb Add program argument for syntax highlighting theme.
The source code output in the chat will be colored in the given
color scheme. Syntax highlighting is powered by pygments, which
supports many styles out of the box. For example:

- default (the default)
- dracula
- emacs
- github-dark
- monokai
- vim
- solarized-dark
- solarized-light

See https://pygments.org/styles/
2023-07-05 00:29:40 +02:00
Paul Gauthier
61247ec499 Added recheck_abs_fnames to notice if files go missing 2023-07-04 14:11:05 -07:00
Paul Gauthier
5d18ebd724 fixed file not found in autocompleter, issue #30 2023-07-04 12:38:36 -07:00
Paul Gauthier
1f16b15f92 Added more clear error messages when universal-ctags is disabled per issue #31 2023-07-03 10:31:04 -07:00
Paul Gauthier
e98db7dfce possible fix for #38 2023-07-03 09:59:03 -07:00
Paul Gauthier
4ec3203b91 fix for issue #33 2023-07-02 17:53:40 -07:00
Paul Gauthier
bad642afa4 bugfix 2023-07-02 17:52:28 -07:00
Paul Gauthier
cbe59b85c2 refactor the jsonschema check into base 2023-07-02 17:44:26 -07:00
Paul Gauthier
ecb739ed07 validate all jsonschemas 2023-07-02 06:36:42 -07:00
Paul Gauthier
717236d235 Make sure wholefile does not try and use the repo map 2023-07-01 13:47:37 -07:00
Paul Gauthier
bc7610cdda retry on Timeout 2023-07-01 07:38:24 -07:00
Paul Gauthier
1251285ac8 cleaner logging, avoid func formats with old models 2023-07-01 06:59:18 -07:00
Paul Gauthier
059bfc75ab accept diff-func(-list,-string,) 2023-07-01 06:17:55 -07:00
Paul Gauthier
ddac41f106 singlewholefile-func 2023-06-29 18:13:42 -07:00
Paul Gauthier
271807123a Handle missing response text 2023-06-29 15:49:41 -07:00
Paul Gauthier
b11a6fa7ee track num_exhausted_context_windows 2023-06-29 15:32:45 -07:00
Paul Gauthier
995fdc3415 accept lists even when we asked for strings 2023-06-29 15:17:52 -07:00
Paul Gauthier
1571f34fa3 added "unique lines" to the prompt 2023-06-29 15:16:33 -07:00
Paul Gauthier
87dc262214 roughed in diff-func-string 2023-06-29 15:11:59 -07:00
Paul Gauthier
58e763cee7 roughed in diff-func-string 2023-06-29 15:10:33 -07:00
Paul Gauthier
dbdccc42a2 prompt 2023-06-28 15:29:59 -07:00
Paul Gauthier
6c87d5be1c better 2023-06-28 13:52:43 -07:00
Paul Gauthier
2691c80ac2 aider: Change original_lines and updated_lines properties in EditBlockFunctionCoder class to be an array of strings instead of a single string.
# Context:
USER: change the `functions` jsonschema so that `original_lines` is a list of strings and so is `update_files`
ASSISTANT: To make the requested changes, we need to modify the `functions` JSON schema in the `EditBlockFunctionCoder` class in the `aider/coders/editblock_func_coder.py` file.

Here is the change:

```python
aider/coders/editblock_func_coder.py
<<<<<<< ORIGINAL
                            properties=dict(
                                path=dict(
                                    type="string",
                                    description="Path of file to edit",
                                ),
                                original_lines=dict(
                                    type="string",
                                    description=(
                                        "Lines from the original file, including all"
                                        " whitespace, newlines, without skipping any lines"
                                    ),
                                ),
                                updated_lines=dict(
                                    type="string",
                                    description="New content to replace the `original_lines` with",
                                ),
                            ),
=======
                            properties=dict(
                                path=dict(
                                    type="string",
                                    description="Path of file to edit",
                                ),
                                original_lines=dict(
                                    type="array",
                                    items=dict(
                                        type="string",
                                    ),
                                    description=(
                                        "Lines from the original file, including all"
                                        " whitespace, newlines, without skipping any lines"
                                    ),
                                ),
                                updated_lines=dict(
                                    type="array",
                                    items=dict(
                                        type="string",
                                    ),
                                    description="New content to replace the `original_lines` with",
                                ),
                            ),
>>>>>>> UPDATED
```

This change modifies the `original_lines` and `updated_lines` properties to be an array of strings instead of a single string. This allows for multiple lines to be specified in the `original_lines` and `updated_lines` fields.
2023-06-28 11:03:59 -07:00
Paul Gauthier
777f179c6d better 2023-06-28 10:54:58 -07:00
Paul Gauthier
1ac366aa62 works 2023-06-27 19:38:14 -07:00
Paul Gauthier
f22ccf6195 fixed json schema 2023-06-27 19:07:45 -07:00
Paul Gauthier
2358b638b8 wip 2023-06-27 18:59:15 -07:00
Paul Gauthier
582143d563 wip 2023-06-27 18:34:52 -07:00
Paul Gauthier
9cfebc0b60 record response hashes too 2023-06-27 16:11:05 -07:00
Paul Gauthier
974d96973c move the empty list into init 2023-06-27 15:00:49 -07:00
Paul Gauthier
64e16c8ad1 aider: Added SHA1 hash of kwargs to chat_completion_call_hashes in send_with_retries method.
# Context:
USER: when calling `ChatCompletion`, take a sha1 hash of dict with all the args and append it to a list self.chat_completion_call_hashes
ASSISTANT: To implement this change, we need to modify the `send_with_retries` method in the `Coder` class in the `aider/coders/base_coder.py` file. We will import the `hashlib` module to generate the SHA1 hash. We will also add a new attribute `chat_completion_call_hashes` to the `Coder` class to store the hashes.

Here are the changes:

```python
aider/coders/base_coder.py
<<<<<<< ORIGINAL
import json
import os
import sys
import traceback
from json.decoder import JSONDecodeError
from pathlib import Path
=======
import hashlib
import json
import os
import sys
import traceback
from json.decoder import JSONDecodeError
from pathlib import Path
>>>>>>> UPDATED
```

```python
aider/coders/base_coder.py
<<<<<<< ORIGINAL
class Coder:
    abs_fnames = None
    repo = None
    last_aider_commit_hash = None
    last_asked_for_commit_time = 0
    repo_map = None
    functions = None
    total_cost = 0.0
=======
class Coder:
    abs_fnames = None
    repo = None
    last_aider_commit_hash = None
    last_asked_for_commit_time = 0
    repo_map = None
    functions = None
    total_cost = 0.0
    chat_completion_call_hashes = []
>>>>>>> UPDATED
```

```python
aider/coders/base_coder.py
<<<<<<< ORIGINAL
    def send_with_retries(self, model, messages, functions):
        kwargs = dict(
            model=model,
            messages=messages,
            temperature=0,
            stream=self.stream,
        )
        if functions is not None:
            kwargs["functions"] = self.functions

        res = openai.ChatCompletion.create(**kwargs)
        return res
=======
    def send_with_retries(self, model, messages, functions):
        kwargs = dict(
            model=model,
            messages=messages,
            temperature=0,
            stream=self.stream,
        )
        if functions is not None:
            kwargs["functions"] = self.functions

        # Generate SHA1 hash of kwargs and append it to chat_completion_call_hashes
        hash_object = hashlib.sha1(json.dumps(kwargs, sort_keys=True).encode())
        self.chat_completion_call_hashes.append(hash_object.hexdigest())

        res = openai.ChatCompletion.create(**kwargs)
        return res
>>>>>>> UPDATED
```
2023-06-27 14:59:58 -07:00