Commit graph

49 commits

Author SHA1 Message Date
Paul Gauthier
810aeccf94 fix: Replace extra_headers and extra_body with extra_params in Coder, ChatSummary, and GitRepo 2024-09-27 13:09:43 -07:00
Paul Gauthier (aider)
b7dff0450c style: Improve code formatting in history.py 2024-08-23 14:18:17 -07:00
Paul Gauthier (aider)
b97006e123 feat: Pass model's extra_headers to simple_send_with_retries 2024-08-23 14:18:14 -07:00
Paul Gauthier
da3e507ec4 Revert "rename simple_send_with_retries -> send_with_retries"
This reverts commit d619edf6e9.
2024-08-02 10:49:44 -03:00
Paul Gauthier
d619edf6e9 rename simple_send_with_retries -> send_with_retries 2024-08-02 10:35:10 -03:00
Paul Gauthier (aider)
41772ccef6 Ensure ChatSummary has at least one model available and use the first model's max input tokens for summarization 2024-07-30 20:37:30 -03:00
Paul Gauthier (aider)
0980985338 Add fallback to second model when first model fails in ChatSummary 2024-07-30 12:16:32 -03:00
Paul Gauthier (aider)
4fe8cca0e9 Fix ChatSummary to take a list of models and work down the list until one succeeds. 2024-07-30 11:57:36 -03:00
Paul Gauthier
2e4de1a0d3 Add support for multiple models in ChatSummary class 2024-07-30 11:57:34 -03:00
Paul Gauthier
af29e633b2 Handle max_input_tokens set with None #757 2024-07-02 19:42:31 -03:00
Paul Gauthier
602a0c7c31 refac utils.split_chat_history_markdown 2024-05-11 07:52:06 -07:00
Paul Gauthier
e61857ef09 summarize as many messages as will fit into the summarizer context 2024-05-06 09:47:14 -07:00
Paul Gauthier
e51e0219ee aider: Add tqdm progress bar to summarize_chat_history_markdown loop.
# Aider chat conversation:

USER: add a tqdm to `summarize_chat_history_markdown` loop

ASSISTANT: ```diff
--- aider/history.py
+++ aider/history.py
@@ ... @@
 from aider.sendchat import simple_send_with_retries
+from tqdm import tqdm

 class ChatSummary:
     def __init__(self, model=None, max_tokens=1024):
@@ ... @@
     def summarize_chat_history_markdown(self, text):
         messages = []
         assistant = []
+        lines = text.splitlines(keepends=True)
+        for line in tqdm(lines, desc="Summarizing chat history"):
-        for line in text.splitlines(keepends=True):
             if line.startswith("# "):
                 continue
             if line.startswith(">"):
                 continue
             if line.startswith("#### /"):
                 continue

             if line.startswith("#### "):
                 if assistant:
                     assistant = "".join(assistant)
                     if assistant.strip():
                         messages.append(dict(role="assistant", content=assistant))
                     assistant = []

                 content = line[5:]
                 if content.strip() and content.strip() != "<blank>":
                     messages.append(dict(role="user", content=line[5:]))
                 continue

             assistant.append(line)

         summary = self.summarize(messages[-40:])
         return summary
```

This diff adds the `tqdm` progress bar to the `summarize_chat_history_markdown` method in the `aider/history.py` file. It wraps the loop that processes the chat history lines with `tqdm`, providing a description for the progress bar.
2024-05-06 09:31:32 -07:00
Paul Gauthier
cd84cc0d3e refactored summarize_chat_history_markdown 2024-05-05 18:58:16 -07:00
Paul Gauthier
30c095349a Don't assume gpt-3.5-turbo as the weak model, use main_model if unsure 2024-04-22 10:57:50 -07:00
Paul Gauthier
4e50f0d095 Support weak_model=False 2024-04-19 14:05:58 -07:00
Paul Gauthier
547ae142ba refactor tokenizer 2024-04-19 12:08:35 -07:00
Paul Gauthier
7ec4de865d Added --weak-model 2024-04-19 10:57:21 -07:00
Paul Gauthier
cf2a48b21f get_weak_model 2024-04-18 13:55:43 -07:00
Paul Gauthier
c770fc4380 cleaned up client refs 2024-04-17 15:47:07 -07:00
Paul Gauthier
c9bb22d6d5 roughed in tokenizer, dropped openai, openrouter 2024-04-17 15:22:35 -07:00
Paul Gauthier
57ab2cc9da Revert "implement deployment id"
This reverts commit b107db98fa.
2023-12-06 09:20:53 -08:00
Paul Gauthier
b107db98fa implement deployment id 2023-12-05 11:31:17 -08:00
Paul Gauthier
6ebc142377 roughed in openai 1.x 2023-12-05 07:37:05 -08:00
Paul Gauthier
bfbd7b8416 Merge remote-tracking branch 'origin/main' 2023-09-08 08:26:23 -07:00
Joshua Vial
98097005c7 small fix for better error handling if the summarizer ever fails
- fix #231
2023-09-06 15:03:54 +12:00
Paul Gauthier
9b22b39a8d lint 2023-09-01 15:55:36 -07:00
Paul Gauthier
3045c5e94d aider: Removed unused imports and changed comparison to None to use is instead of == in aider/history.py, aider/models/__init__.py, and aider/models/openrouter.py.
# Aider chat conversation:

USER: I ran this command:

 pre-commit run --all-files

And got this output:

isort....................................................................Passed
black....................................................................Passed
flake8...................................................................Failed
- hook id: flake8
- exit code: 1

aider/history.py:4:1: F401 'tiktoken' imported but unused
import tiktoken
^
aider/models/__init__.py:2:1: F401 '.openai.OpenAIModel' imported but unused
from .openai import OpenAIModel
^
aider/models/__init__.py:3:1: F401 '.openrouter.OpenRouterModel' imported but unused
from .openrouter import OpenRouterModel
^
aider/models/openrouter.py:26:33: E711 comparison to None should be 'if cond is None:'
        if cached_model_details == None:
                                ^

ASSISTANT: It seems like there are some unused imports and a comparison to None that is not following the Pythonic way. To fix these issues, we need to modify the following files:

1. `aider/history.py`
2. `aider/models/__init__.py`
3. `aider/models/openrouter.py`

Please add these files to the chat so I can propose the necessary changes.

USER: I added these *read-write* files: aider/history.py, aider/models/openrouter.py, aider/models/__init__.py

ASSISTANT: Great! Now, let's make the necessary changes to these files.

First, in `aider/history.py`, we need to remove the unused import `tiktoken`.

```python
aider/history.py
<<<<<<< HEAD
import tiktoken
=======
>>>>>>> updated
```

Next, in `aider/models/__init__.py`, we need to remove the unused imports `OpenAIModel` and `OpenRouterModel`.

```python
aider/models/__init__.py
<<<<<<< HEAD
from .openai import OpenAIModel
from .openrouter import OpenRouterModel
=======
>>>>>>> updated
```

Finally, in `aider/models/openrouter.py`, we need to change the comparison to None to use `is` instead of `==`.

```python
aider/models/openrouter.py
<<<<<<< HEAD
        if cached_model_details == None:
=======
        if cached_model_details is None:
>>>>>>> updated
```

These changes should resolve the issues reported by the `flake8` linter.
2023-09-01 15:54:22 -07:00
Joshua Vial
abbc93678b finishing openrouter integration 2023-08-23 21:26:27 +12:00
JV
1fc2abe3d0 save model to ChatSummary 2023-08-23 14:39:12 +12:00
JV
041f3a4a38 initial code for working with openrouter 2023-08-23 14:39:12 +12:00
Paul Gauthier
7eab7b54b8 Improved summarization split logic 2023-08-10 12:21:51 -03:00
Paul Gauthier
fa2da0ef70 bound the summarize() recursion 2023-08-09 12:04:10 -03:00
Paul Gauthier
d1d498bb24 cleanup 2023-07-27 22:34:41 -03:00
Paul Gauthier
05c1b3bc99 cleanup 2023-07-25 09:13:07 -03:00
Paul Gauthier
4e348102bf wip 2023-07-25 07:46:05 -03:00
Paul Gauthier
f0ec6cb36a Expand the tail to ensure head ends with assistant msg 2023-07-25 06:58:41 -03:00
Paul Gauthier
4b41eb7525 aider: Fix variable name error in summarize method in history.py.
# Aider chat conversation:

USER:   File "/Users/gauthier/Projects/aider/aider/coders/base_coder.py", line 395, in run_loop
    return self.send_new_user_message(inp)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/gauthier/Projects/aider/aider/coders/base_coder.py", line 479, in send_new_user_message
    self.move_back_cur_messages(saved_message)
  File "/Users/gauthier/Projects/aider/aider/coders/base_coder.py", line 365, in move_back_cur_messages
    self.done_messages = self.summarizer.summarize(self.done_messages)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/gauthier/Projects/aider/aider/history.py", line 60, in summarize
    tail_tokens = sum(tokens for tokens, msg in sized[num:])
                                                      ^^^
NameError: name 'num' is not defined. Did you mean: 'sum'?

ASSISTANT: It seems like there's a typo in the code. The variable `num` is not defined in the current scope. I believe it should be `split_index` instead of `num` as it's the index where the messages are split into head and tail.

Here's the change that needs to be made in the `aider/history.py` file:

```python
aider/history.py
<<<<<<< ORIGINAL
        tail_tokens = sum(tokens for tokens, msg in sized[num:])
=======
        tail_tokens = sum(tokens for tokens, msg in sized[split_index:])
>>>>>>> UPDATED
```

Please confirm if this is the change you want to make.
2023-07-24 19:10:58 -03:00
Paul Gauthier
3c656fe3be aider: Ensure the head ends with an assistant message.
# Aider chat conversation:

USER: but we want the head to end with an assistant msg

ASSISTANT: To ensure that the head ends with an assistant message, we need to modify the `summarize` method in the `ChatSummary` class in the `aider/history.py` file.

After splitting the messages based on the token count, we need to check if the last message in the head is from the assistant. If not, we need to move messages from the head to the tail until we find an assistant message.

Here is the *edit block* for this change:

```python
aider/history.py
<<<<<<< ORIGINAL
    def summarize(self, messages):
        if len(messages) < 2:
            return messages

        sized = self.tokenize(messages)
        total = sum(tokens for tokens, _msg in sized)
        if total <= self.max_tokens:
            return messages

        tail_tokens = 0
        split_index = len(messages)
        half_max_tokens = self.max_tokens // 2

        # Iterate over the messages in reverse order
        for i in range(len(sized)-1, -1, -1):
            tokens, _msg = sized[i]
            if tail_tokens + tokens < half_max_tokens:
                tail_tokens += tokens
                split_index = i
            else:
                break

        head = messages[:split_index]
        tail = messages[split_index:]
=======
    def summarize(self, messages):
        if len(messages) < 2:
            return messages

        sized = self.tokenize(messages)
        total = sum(tokens for tokens, _msg in sized)
        if total <= self.max_tokens:
            return messages

        tail_tokens = 0
        split_index = len(messages)
        half_max_tokens = self.max_tokens // 2

        # Iterate over the messages in reverse order
        for i in range(len(sized)-1, -1, -1):
            tokens, _msg = sized[i]
            if tail_tokens + tokens < half_max_tokens:
                tail_tokens += tokens
                split_index = i
            else:
                break

        # Ensure the head ends with an assistant message
        while messages[split_index - 1]["role"] != "assistant" and split_index < len(messages):
            split_index += 1

        head = messages[:split_index]
        tail = messages[split_index:]
>>>>>>> UPDATED
```

This change ensures that the head of the messages ends with an assistant message.
2023-07-24 19:08:51 -03:00
Paul Gauthier
270ea21c05 aider: Change the summarize method in the ChatSummary class to split the messages so that the tail holds as close as possible but less than max_tokens//2 tokens and the head holds the rest.
# Aider chat conversation:

USER: instead of splitting the history in half based on the msg number, split it in half based on the token count

ASSISTANT: To implement this change, we need to modify the `summarize` method in the `ChatSummary` class in the `aider/history.py` file.

The current implementation splits the messages in half based on the number of messages. We need to change this to split the messages based on the token count.

Here are the steps to implement this change:

1. Calculate the total token count of all messages.
2. Iterate over the messages and keep a running total of the token count.
3. Once the running total exceeds half of the total token count, split the messages at that point.

Here is the *edit block* for this change:

```python
aider/history.py
<<<<<<< ORIGINAL
    def summarize(self, messages):
        num = len(messages)
        dump(num)
        if num < 2:
            return messages

        sized = self.tokenize(messages)
        total = sum(tokens for tokens, _msg in sized)
        if total <= self.max_tokens:
            return messages

        num = num // 2

        # we want the head to end with an assistant msg
        while messages[num]["role"] == "assistant" and num < len(messages) - 1:
            num += 1

        head = messages[:num]
        tail = messages[num:]
=======
    def summarize(self, messages):

^C KeyboardInterrupt

USER: instead of splitting the history in half based on the msg number, split it so that the tail holds as close as possible but less than `max_tokens`//2 tokens and head holds the rest

ASSISTANT: To implement this change, we need to modify the `summarize` method in the `ChatSummary` class in the `aider/history.py` file.

The current implementation splits the messages in half based on the number of messages. We need to change this to split the messages so that the tail holds as close as possible but less than `max_tokens`//2 tokens and head holds the rest.

Here are the steps to implement this change:

1. Iterate over the messages in reverse order and keep a running total of the token count.
2. Once the running total exceeds `max_tokens`//2, split the messages at that point.

Here is the *edit block* for this change:

```python
aider/history.py
<<<<<<< ORIGINAL
    def summarize(self, messages):
        num = len(messages)
        dump(num)
        if num < 2:
            return messages

        sized = self.tokenize(messages)
        total = sum(tokens for tokens, _msg in sized)
        if total <= self.max_tokens:
            return messages

        num = num // 2

        # we want the head to end with an assistant msg
        while messages[num]["role"] == "assistant" and num < len(messages) - 1:
            num += 1

        head = messages[:num]
        tail = messages[num:]
=======
    def summarize(self, messages):
        if len(messages) < 2:
            return messages

        sized = self.tokenize(messages)
        total = sum(tokens for tokens, _msg in sized)
        if total <= self.max_tokens:
            return messages

        tail_tokens = 0
        split_index = len(messages)
        half_max_tokens = self.max_tokens // 2

        # Iterate over the messages in reverse order
        for i in range(len(sized)-1, -1, -1):
            tokens, _msg = sized[i]
            if tail_tokens + tokens < half_max_tokens:
                tail_tokens += tokens
                split_index = i
            else:
                break

        head = messages[:split_index]
        tail = messages[split_index:]
>>>>>>> UPDATED
```

This change ensures that the tail of the messages holds as close as possible but less than `max_tokens`//2 tokens and the head holds the rest.
2023-07-24 19:08:13 -03:00
Paul Gauthier
0db9d210d7 Advise the user when chat history is being summarized 2023-07-24 19:05:57 -03:00
Paul Gauthier
e5ffb78224 wip 2023-07-22 16:09:57 -03:00
Paul Gauthier
69aea3e745 Add summary prefix 2023-07-22 12:11:01 -03:00
Paul Gauthier
c26917851f Added a ChatSummary object to Coder class and used it to summarize chat history. 2023-07-22 10:34:48 -03:00
Paul Gauthier
0d0ac4f61f works 2023-07-22 10:32:32 -03:00
Paul Gauthier
a2ce9c4403 feed markdown into summarizer 2023-07-22 09:58:57 -03:00
Paul Gauthier
c8e8967d45 wip 2023-07-22 09:50:41 -03:00
Paul Gauthier
6c7b6fc9e4 aider: Added a main function to aider/history.py that accepts a filename as a command-line argument, reads the file, and parses the markdown structure.
# Aider chat conversation:

USER: when run as a script, take a filename on the cmd line. read markdown from the file. parse the markdown structure, so we can iterate through # and #### seactions and do things like discard quoted text > sections easily.

ASSISTANT: To achieve this, we need to modify the `aider/history.py` file to include a main function that accepts a filename as a command-line argument, reads the file, and parses the markdown structure. We will use the `argparse` module to handle command-line arguments and the `markdown` module to parse the markdown file.

Here are the changes:

```python
aider/history.py
<<<<<<< ORIGINAL
import json

import tiktoken
from prompt_toolkit.completion import Completion

from aider import prompts

from .dump import dump  # noqa: F401
=======
import argparse
import json
import markdown

import tiktoken
from prompt_toolkit.completion import Completion

from aider import prompts

from .dump import dump  # noqa: F401

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("filename", help="Markdown file to parse")
    args = parser.parse_args()

    with open(args.filename, 'r') as f:
        text = f.read()

    md = markdown.Markdown()
    tree = md.parse(text)

    for element in tree.getiterator():
        if element.tag in ['h1', 'h4'] and element.text is not None:
            print(element.text)
        elif element.tag == 'blockquote':
            continue
        else:
            print(element.text)

if __name__ == "__main__":
    main()
>>>>>>> UPDATED
```

This script will print the text of all `#` and `####` sections and ignore quoted text `>` sections. Other text will be printed as is. If you want to handle other markdown elements differently, you can add more conditions in the for loop.
2023-07-22 09:44:58 -03:00
Paul Gauthier
78e7b5c3db wip 2023-07-22 08:45:40 -03:00