From f9ba8e7b41ac697d2fefcee5c9a140f715cba957 Mon Sep 17 00:00:00 2001 From: Joshua Vial Date: Mon, 11 Dec 2023 21:53:53 +1300 Subject: [PATCH] Remove unnecessary comment and method call in Commands class. --- aider/coders/base_coder.py | 10 ++++++---- aider/commands.py | 7 ++++--- aider/io.py | 7 ++----- aider/sendchat.py | 4 +++- aider/utils.py | 10 ++++++++++ 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 6e99a1839..6c6dc2c19 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -24,6 +24,7 @@ from aider.repo import GitRepo from aider.repomap import RepoMap from aider.sendchat import send_with_retries +from aider.utils import is_image_file from ..dump import dump # noqa: F401 @@ -38,8 +39,6 @@ class ExhaustedContextWindow(Exception): def wrap_fence(name): return f"<{name}>", f"" -#NOTE currently duplicated in io.py -IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff', '.webp'} class Coder: client = None @@ -294,7 +293,7 @@ class Coder: prompt = "" for fname, content in self.get_abs_fnames_content(): - if not any(fname.lower().endswith(ext) for ext in IMAGE_EXTENSIONS): + if not is_image_file(fname): relative_fname = self.get_rel_fname(fname) prompt += "\n" prompt += relative_fname @@ -341,9 +340,12 @@ class Coder: return files_messages def get_images_message(self): + if not utils.is_gpt4_with_openai_base_url(self.main_model.name, self.client): + return None + image_messages = [] for fname, content in self.get_abs_fnames_content(): - if any(fname.lower().endswith(ext) for ext in IMAGE_EXTENSIONS): + if is_image_file(fname): image_url = f"data:image/{Path(fname).suffix.lstrip('.')};base64,{content}" image_messages.append({ "type": "image_url", diff --git a/aider/commands.py b/aider/commands.py index 30960c1d8..ef9e83f3c 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -140,7 +140,6 @@ class Commands: relative_fname = self.coder.get_rel_fname(fname) content = self.io.read_text(fname) if is_image_file(relative_fname): - # If the file is an image, use the token_count_for_image method tokens = self.coder.main_model.token_count_for_image(fname) else: # approximate @@ -172,8 +171,10 @@ class Commands: self.io.tool_output("=" * (width + cost_width + 1)) self.io.tool_output(f"${total_cost:5.2f} {fmt(total)} tokens total") - # Check if any images are in the chat and override the max context window size if so - image_in_chat = any(relative_fname.endswith(ext) for ext in IMAGE_EXTENSIONS for relative_fname in self.coder.get_inchat_relative_files()) + # Set image_in_chat to False unless is_gpt4_with_openai_base_url returns True + image_in_chat = False + if utils.is_gpt4_with_openai_base_url(self.coder.main_model.name, self.coder.client): + image_in_chat = any(is_image_file(relative_fname) for relative_fname in self.coder.get_inchat_relative_files()) limit = 128000 if image_in_chat else self.coder.main_model.max_context_tokens remaining = limit - total if remaining > 1024: diff --git a/aider/io.py b/aider/io.py index 255efbd79..410d72e20 100644 --- a/aider/io.py +++ b/aider/io.py @@ -16,11 +16,9 @@ from pygments.util import ClassNotFound from rich.console import Console from rich.text import Text +from .utils import is_image_file from .dump import dump # noqa: F401 -#QUESTION what image extensions do we want to support? -#QUESTION where should this live? Currently duplicated in base_coder -IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff', '.webp'} class AutoCompleter(Completer): def __init__(self, root, rel_fnames, addable_rel_fnames, commands, encoding): @@ -160,8 +158,7 @@ class InputOutput: return def read_text(self, filename): - file_extension = Path(filename).suffix.lower() - if file_extension in IMAGE_EXTENSIONS: + if is_image_file(filename): return self.read_image(filename) try: diff --git a/aider/sendchat.py b/aider/sendchat.py index d8ac92625..18956b83c 100644 --- a/aider/sendchat.py +++ b/aider/sendchat.py @@ -41,8 +41,10 @@ def send_with_retries(client, model_name, messages, functions, stream): if functions is not None: kwargs["functions"] = functions + from aider.utils import is_gpt4_with_openai_base_url + # Check conditions to switch to gpt-4-vision-preview or strip out image_url messages - if client and model_name.startswith("gpt-4") and "api.openai.com" in client.base_url.host: + if client and is_gpt4_with_openai_base_url(model_name, client): if any(isinstance(msg.get("content"), list) and any("image_url" in item for item in msg.get("content") if isinstance(item, dict)) for msg in messages): kwargs['model'] = "gpt-4-vision-preview" # gpt-4-vision is limited to max tokens of 4096 diff --git a/aider/utils.py b/aider/utils.py index 0753ad4ea..2b02f7bdb 100644 --- a/aider/utils.py +++ b/aider/utils.py @@ -1,4 +1,5 @@ from pathlib import Path +from openai import OpenAIError # Set of image file extensions IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff', '.webp'} @@ -41,3 +42,12 @@ def show_messages(messages, title=None, functions=None): if functions: dump(functions) +def is_gpt4_with_openai_base_url(model_name, client): + """ + Check if the model_name starts with 'gpt-4' and the client base URL includes 'api.openai.com'. + + :param model_name: The name of the model to check. + :param client: The OpenAI client instance. + :return: True if conditions are met, False otherwise. + """ + return model_name.startswith("gpt-4") and "api.openai.com" in client.base_url.host