diff --git a/README.md b/README.md index fa11cbc56..2a168fc94 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ It also has features that [help GPT understand and modify larger codebases](http ![aider screencast](assets/screencast.svg) -- [Example chat transcripts](#example-chat-transcripts) - [Getting started](#getting-started) +- [Example chat transcripts](#example-chat-transcripts) - [Features](#features) - [Installation](#installation) - [Usage](#usage) @@ -17,6 +17,19 @@ It also has features that [help GPT understand and modify larger codebases](http - [Tips](#tips) - [Limitations](#limitations) +## Getting started + +``` +$ pip install git+https://github.com/paul-gauthier/aider.git +$ export OPENAI_API_KEY=sk-... +$ aider myapp.py + +Added myapp.py to the chat +Using git repo: .git + +myapp.py> change the fibonacci function from recursion to iteration +``` + ## Example chat transcripts Here are some example transcripts that show how you can chat with `aider` to write and edit code with GPT-4. @@ -30,22 +43,8 @@ Here are some example transcripts that show how you can chat with `aider` to wri * [**Create a Black Box Test Case**](https://aider.chat/examples/add-test.html): GPT creates a "black box" test case without access to the source of the method being tested, using only a [high level map of the repository based on ctags](https://aider.chat/docs/ctags.html). -* [**Honor the NO_COLOR env var**](https://aider.chat/examples/no-color.html): The user pastes the NO_COLOR spec from no-color.org into the chat, and GPT-4 modifies the application to conform. - You can find more chat transcripts on the [examples page](https://aider.chat/examples/). -## Getting started - -``` -$ pip install git+https://github.com/paul-gauthier/aider.git -$ aider filename.py - -Added filename.py to the chat -Using git repo: .git - -filename.py> switch the fibonacci function from recursion to iteration -``` - ## Features * Chat with GPT-4 about your code by launching `aider` from the command line with set of source files to discuss and edit together. GPT can see and edit the content of those files. @@ -71,7 +70,7 @@ which helps it understand and modify large codebases. * From GitHub: `pip install git+https://github.com/paul-gauthier/aider.git` * From your local copy of the repo in develop mode to pick up local edits immediately: `pip install -e .` -2. Set up your OpenAI API key as an environment variable `OPENAI_API_KEY` or by including `openai-api-key: sk-` in an `.aider.config.yml` file (see `aider --help`). +2. Set up your OpenAI API key as an environment variable `OPENAI_API_KEY` or by including `openai-api-key: sk-...` in an `.aider.config.yml` file (see `aider --help`). 3. Optionally, install [universal ctags](https://github.com/universal-ctags/ctags). This is helpful if you plan to work with repositories with more than a handful of files. This allows `aider --ctags` to build a [map of your entire git repo](https://aider.chat/docs/ctags.html) and share it with GPT to help it better understand and modify large codebases. diff --git a/aider/coder.py b/aider/coder.py index af761d62f..acb807813 100755 --- a/aider/coder.py +++ b/aider/coder.py @@ -29,6 +29,11 @@ class Coder: last_aider_commit_hash = None last_asked_for_commit_time = 0 + def check_model_availability(self, main_model): + available_models = openai.Model.list() + model_ids = [model.id for model in available_models["data"]] + return main_model in model_ids + def __init__( self, io, @@ -64,10 +69,16 @@ class Coder: self.console = Console(force_terminal=True, no_color=True) self.commands = Commands(self.io, self) + if not self.check_model_availability(main_model): + self.io.tool_error( + f"Your openai key does not support {main_model}, using gpt-3.5-turbo." + ) + main_model = "gpt-3.5-turbo" + self.main_model = main_model if main_model == "gpt-3.5-turbo": self.io.tool_error( - f"aider doesn't work well with {main_model}, use gpt-4 for best results." + f"Aider doesn't work well with {main_model}, use gpt-4 for best results." ) self.set_repo(fnames) diff --git a/tests/test_coder.py b/tests/test_coder.py index 52ffabdb9..f703969e3 100644 --- a/tests/test_coder.py +++ b/tests/test_coder.py @@ -1,11 +1,19 @@ import os import unittest -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch from aider.coder import Coder class TestCoder(unittest.TestCase): + def setUp(self): + self.patcher = patch("aider.coder.Coder.check_model_availability") + self.mock_check = self.patcher.start() + self.mock_check.return_value = True + + def tearDown(self): + self.patcher.stop() + def test_check_for_file_mentions(self): # Mock the IO object mock_io = MagicMock() diff --git a/tests/test_commands.py b/tests/test_commands.py index 5f3d596d1..223c33acd 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2,6 +2,7 @@ import os import shutil import tempfile from unittest import TestCase +from unittest.mock import patch from aider.commands import Commands from aider.io import InputOutput @@ -13,10 +14,16 @@ class TestCommands(TestCase): self.tempdir = tempfile.mkdtemp() os.chdir(self.tempdir) + self.patcher = patch("aider.coder.Coder.check_model_availability") + self.mock_check = self.patcher.start() + self.mock_check.return_value = True + def tearDown(self): os.chdir(self.original_cwd) shutil.rmtree(self.tempdir) + self.patcher.stop() + def test_cmd_add(self): # Initialize the Commands and InputOutput objects io = InputOutput(pretty=False, yes=True) diff --git a/tests/test_main.py b/tests/test_main.py index eb35435dc..097063208 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -18,10 +18,14 @@ class TestMain(TestCase): self.original_cwd = os.getcwd() self.tempdir = tempfile.mkdtemp() os.chdir(self.tempdir) + self.patcher = patch("aider.main.Coder.check_model_availability") + self.mock_check = self.patcher.start() + self.mock_check.return_value = True def tearDown(self): os.chdir(self.original_cwd) shutil.rmtree(self.tempdir) + self.patcher.stop() def test_main_with_empty_dir_no_files_on_command(self): pipe_input = create_input(StringIO(""))