Aider-AI / aider

aider is AI pair programming in your terminal
https://aider.chat/
Apache License 2.0
21.22k stars 1.97k forks source link

TypeError when adding a .jpg file to the chat #1088

Closed Sjlver closed 2 months ago

Sjlver commented 2 months ago

Issue

I get the following error message after having added a .jpg image to the chat:

Traceback (most recent call last):
  File "[redacted]/.local/bin/aider", line 8, in <module>
    sys.exit(main())
  File "[redacted]/.local/lib/python3.10/site-packages/aider/main.py", line 620, in main
    coder.run()
  File "[redacted]/.local/lib/python3.10/site-packages/aider/coders/base_coder.py", line 693, in run
    self.run_one(user_message, preproc)
  File "[redacted]/.local/lib/python3.10/site-packages/aider/coders/base_coder.py", line 734, in run_one
    list(self.send_message(message))
  File "[redacted]/.local/lib/python3.10/site-packages/aider/coders/base_coder.py", line 956, in send_message
    messages = self.format_messages()
  File "[redacted]/.local/lib/python3.10/site-packages/aider/coders/base_coder.py", line 915, in format_messages
    messages_tokens = self.main_model.token_count(messages)
  File "[redacted]/.local/lib/python3.10/site-packages/aider/models.py", line 519, in token_count
    return litellm.token_counter(model=self.name, messages=messages)
  File "[redacted]/.local/lib/python3.10/site-packages/litellm/utils.py", line 1994, in token_counter
    num_tokens += calculage_img_tokens(
  File "[redacted]/.local/lib/python3.10/site-packages/litellm/utils.py", line 1841, in calculage_img_tokens
    resized_width, resized_height = resize_image_high_res(
  File "[redacted]/.local/lib/python3.10/site-packages/litellm/utils.py", line 1758, in resize_image_high_res
    if width <= 768 and height <= 768:
TypeError: '<=' not supported between instances of 'NoneType' and 'int'

I did the following:

Version and model info

Aider v0.50.1 Models: claude-3-5-sonnet-20240620 with ♾️ diff edit format, weak model claude-3-haiku-20240307 Git repo: .git with 201 files Repo-map: using 1024 tokens

Command line switches: --no-auto-commit --no-auto-lint

Sjlver commented 2 months ago

Note that width and height come from this function:

def get_image_dimensions(data):
    img_data = None

    # Check if data is a URL by trying to parse it
    try:
        response = requests.get(data)
        response.raise_for_status()  # Check if the request was successful
        img_data = response.content
    except Exception:
        # Data is not a URL, handle as base64
        header, encoded = data.split(",", 1)
        img_data = base64.b64decode(encoded)

    # Try to determine dimensions from headers
    # This is a very simplistic check, primarily works with PNG and non-progressive JPEG
    if img_data[:8] == b"\x89PNG\r\n\x1a\n":
        # PNG Image; width and height are 4 bytes each and start at offset 16
        width, height = struct.unpack(">ii", img_data[16:24])
        return width, height
    elif img_data[:2] == b"\xff\xd8":
        # JPEG Image; for dimensions, SOF0 block (0xC0) gives dimensions at offset 3 for length, and then 5 and 7 for height and width
        # This will NOT find dimensions for all JPEGs (e.g., progressive JPEGs)
        # Find SOF0 marker (0xFF followed by 0xC0)
        sof = re.search(b"\xff\xc0....", img_data)
        if sof:
            # Parse SOF0 block to find dimensions
            height, width = struct.unpack(">HH", sof.group()[5:9])
            return width, height
        else:
            return None, None
    else:
        # Unsupported format
        return None, None

It is possible that my JPG file does not have the corresponding marker? I appreciate it that litellm tries to reduce its dependencies... but it might make sense to use an image library for this :)

You can find the jpg file at https://blog.purpureus.net/assets/blog/personal_key_rotation/simplified-asset-graph.jpg

paul-gauthier commented 2 months ago

There's a workaround in the main branch now, which will prevent crashing.

The change is available in the main branch. You can get it by installing the latest version from github:

python -m pip install --upgrade git+https://github.com/paul-gauthier/aider.git

If you have a chance to try it, let me know if it works better for you.

Sjlver commented 2 months ago

This seems to work now. There are hints about the problem still, but nothing blocking:

Here's the transcript of the new version:

Aider v0.50.2-dev
Models: claude-3-5-sonnet-20240620 with ♾️ diff edit format, weak model claude-3-haiku-20240307
Git repo: .git with 201 files
Repo-map: using 1024 tokens
Use /help <question> for help, run "aider --help" to see cmd line args
─────────────────────────────────────────────
> /add public/assets/blog/personal_key_rotation/simplified-asset-graph.jpg

Added [redacted]/public/assets/blog/personal_key_rotation/simplified-asset-graph.jpg to the chat
─────────────────────────────────────────────
public/assets/blog/personal_key_rotation/simplified-asset-graph.jpg
> Please transcribe the content of the simplified-asset-graph.jpg file. It contains a handdrawn sketch of a graph. Print the
 corresponding graphviz representation.

Unable to count tokens: '<=' not supported between instances of 'NoneType' and 'int'

Certainly! I'll transcribe the content of the simplified-asset-graph.jpg file into a Graphviz representation. I'll create a
new file called simplified-asset-graph.dot to store this representation.                                                    
simplified-asset-graph.dot

 <<<<<<< SEARCH
 =======
 digraph AssetGraph {
     // Node definitions
    [redacted]
 }
 >>>>>>> REPLACE

Unable to count tokens: '<=' not supported between instances of 'NoneType' and 'int'

This Graphviz representation captures the structure and relationships shown in the hand-drawn sketch. It includes all the
[redacted]

Tokens: 0 sent, 557 received. Cost: $0.0084 message, $0.0084 session.

Allow creation of new file simplified-asset-graph.dot? n
Skipping edits to simplified-asset-graph.dot

Thanks for the quick fix!

paul-gauthier commented 2 months ago

This should be fixed properly if you upgrade to the main branch.

The change is available in the main branch. You can get it by installing the latest version from github:

python -m pip install --upgrade git+https://github.com/paul-gauthier/aider.git

If you have a chance to try it, let me know if it works better for you.