Compare commits

...

590 Commits

Author SHA1 Message Date
Paul Gauthier
ac26fc6d5f set version to 0.71.2.dev 2025-01-11 16:07:56 -08:00
Paul Gauthier
122088712d version bump to 0.71.1 2025-01-11 16:06:25 -08:00
Paul Gauthier
9fb09ce14d copy 2025-01-11 16:04:53 -08:00
Paul Gauthier (aider)
392fb21946 fix: ensure integer indices for list slicing in repomap.py 2025-01-11 15:49:58 -08:00
Paul Gauthier (aider)
e94b05851f style: Format test_io.py with consistent string quotes and spacing 2025-01-11 15:48:10 -08:00
Paul Gauthier (aider)
571a5962b7 test: update test to use invalid Unicode that triggers encoding error 2025-01-11 15:48:05 -08:00
Paul Gauthier (aider)
8b6863dc40 style: Format test_io.py with consistent quotes and spacing 2025-01-11 15:46:33 -08:00
Paul Gauthier (aider)
01af629399 test: add test for Unicode to ASCII fallback in tool messages 2025-01-11 15:46:28 -08:00
Paul Gauthier (aider)
4ece6d2a9b fix: handle Text objects properly in io.py for Windows Unicode encoding 2025-01-11 15:40:24 -08:00
Paul Gauthier
18d1d7af33 no chown for COPY 2025-01-11 07:46:23 -08:00
Paul Gauthier
5ada250a66 refactor: Add period to read-only file message in base_coder.py 2025-01-11 07:39:29 -08:00
Paul Gauthier (aider)
308c7ab670 feat: Add read-only file announcements to chat 2025-01-11 07:27:50 -08:00
Paul Gauthier
89d35e020a refactor: Add comment for read-only file message in base_coder.py 2025-01-11 07:27:49 -08:00
Paul Gauthier (aider)
6729570799 refactor: Simplify docker-build-test.yml to mirror release workflow with dev tags 2025-01-11 07:16:02 -08:00
Paul Gauthier (aider)
f72f5f6438 ci: Add dev tag publishing to Docker build test workflow 2025-01-11 07:12:56 -08:00
Paul Gauthier
a02e11e0bc Revert "ci: Add Docker image tests with --yes --exit args"
This reverts commit fdddfc6b1f.
2025-01-11 07:06:08 -08:00
Paul Gauthier
9ff15e1506 copy 2025-01-11 06:53:44 -08:00
Paul Gauthier (aider)
fdddfc6b1f ci: Add Docker image tests with --yes --exit args 2025-01-11 06:52:29 -08:00
Paul Gauthier (aider)
78ebb6295d fix: Restore site-packages permissions in Dockerfile for appuser access 2025-01-11 06:48:26 -08:00
Paul Gauthier
73c89e8c00 copy 2025-01-10 15:53:17 -08:00
Paul Gauthier (aider)
fcc499e401 refactor: normalize deepseek model names to deepseek-chat 2025-01-10 15:51:53 -08:00
Paul Gauthier
6e8efe22aa refactor: Combine deepseek/deepseek-coder into chat AI in model stats 2025-01-10 15:51:52 -08:00
Paul Gauthier
f9c5cb73a2 copy 2025-01-10 15:08:15 -08:00
Paul Gauthier
c939521f5f copy 2025-01-10 15:04:54 -08:00
Paul Gauthier
2640e05307 set version to 0.71.1.dev 2025-01-10 15:01:41 -08:00
Paul Gauthier
c1a371e3d3 version bump to 0.71.0 2025-01-10 15:00:02 -08:00
Paul Gauthier
5a4871155a copy 2025-01-10 14:54:42 -08:00
Paul Gauthier (aider)
d8e6dbf788 docs: clarify dual purpose of /ask, /code, and /architect commands 2025-01-10 14:51:25 -08:00
Paul Gauthier
7ea69ae4b4 refactor: Simplify map_tokens assignment logic in main.py 2025-01-10 14:49:16 -08:00
Paul Gauthier
d238ead451 copy 2025-01-10 14:44:00 -08:00
Paul Gauthier (aider)
e6b449f24d test: add tests for get_repo_map_tokens method 2025-01-10 14:39:50 -08:00
Paul Gauthier (aider)
41018d05a8 fix: remove unused max_tokens variable in get_repo_map_tokens 2025-01-10 14:38:22 -08:00
Paul Gauthier
d48008e13d refactor: Update repo map token handling and improve warning message 2025-01-10 14:38:12 -08:00
Paul Gauthier
a9cf438100 refactor: Update terminal detection message to include pretty output 2025-01-10 14:26:06 -08:00
Paul Gauthier (aider)
6c7a0d21d2 style: Remove trailing whitespace in io.py 2025-01-10 14:25:04 -08:00
Paul Gauthier (aider)
d887db4c18 fix: disable pretty output for dumb terminals 2025-01-10 14:24:59 -08:00
Paul Gauthier (aider)
e6be69ec6d test: add test case for TERM=dumb terminal handling 2025-01-10 14:24:27 -08:00
Paul Gauthier
c1ba7db8a1 refactor: Update placeholder text in cmd_run for better clarity 2025-01-10 14:23:42 -08:00
Paul Gauthier
dc5b5896a9 copy 2025-01-10 14:20:50 -08:00
Paul Gauthier
38678fafc1 refactor: Simplify fence pattern matching in base_coder.py 2025-01-10 14:20:02 -08:00
Paul Gauthier
7611211d1c copy 2025-01-10 14:19:51 -08:00
Paul Gauthier
0d9c2cd902 copy 2025-01-10 14:09:22 -08:00
Paul Gauthier (aider)
1a84c109fc feat: allow /ask, /code, /architect without args to switch modes 2025-01-10 14:07:24 -08:00
Paul Gauthier (aider)
cbedf3f8cc fix: Correct typo in variable name from model_metatdata_files to model_metadata_files 2025-01-10 14:04:54 -08:00
Paul Gauthier
50436e3106 docs: Update model usage statistics and dumb terminal message 2025-01-10 14:04:41 -08:00
Paul Gauthier (aider)
62498ec867 style: Reorder imports and fix whitespace in aider/io.py 2025-01-10 14:03:57 -08:00
Paul Gauthier (aider)
91b94bb16c feat: add dumb terminal detection and fallback handling 2025-01-10 14:03:53 -08:00
Paul Gauthier
c2bbdc503c copy 2025-01-10 13:33:00 -08:00
Paul Gauthier
babae0fa6e refactor: conditionally set stream based on main_model.streaming 2025-01-10 13:31:55 -08:00
Paul Gauthier
f047882ac1 refactor: Add InvalidGitRepositoryError to ANY_GIT_ERROR list 2025-01-09 15:01:36 -08:00
Paul Gauthier
b818d6a921 copy 2025-01-09 12:07:00 -08:00
Paul Gauthier
ba631c8451 copy 2025-01-09 12:03:17 -08:00
Paul Gauthier
2c963b389c include author in history updates 2025-01-09 12:03:05 -08:00
Paul Gauthier
8437fbc314 cleanup 2025-01-09 12:02:48 -08:00
Paul Gauthier (aider)
76404004a4 feat: include author info in git log output for history updates 2025-01-09 11:57:23 -08:00
Paul Gauthier
1b64514c2c copy 2025-01-09 11:44:40 -08:00
Paul Gauthier
6efea7d365 Merge branch 'main' of github.com:Aider-AI/aider 2025-01-09 11:44:19 -08:00
Paul Gauthier (aider)
e1a3b77d67 feat: add rootless container support with dedicated appuser 2025-01-09 11:26:06 -08:00
Paul Gauthier
cfc7ad5627 copy 2025-01-09 09:56:49 -08:00
paul-gauthier
b3cbf14ad6 Merge pull request #2809 from hydai/fix_missing_link 2025-01-09 06:39:40 -08:00
hydai
51cfbe6b00 docs: fix missing link
Signed-off-by: hydai <z54981220@gmail.com>
2025-01-09 18:46:14 +08:00
paul-gauthier
155f397d0b Merge pull request #2798 from schpet/improve-watch-description 2025-01-07 15:02:52 -08:00
Peter Schilling
4b53b8b6a1 2025-01-07 14:00:49 -08:00
Peter Schilling (aider)
dbea4a1787 aider: feat: Update watch.md description for IDE usage 2025-01-07 13:57:39 -08:00
Peter Schilling
5b6da85e68 docs: Update watch.md documentation description and comments 2025-01-07 13:57:38 -08:00
Paul Gauthier
61671e9d3f cleanup 2025-01-07 10:49:21 -08:00
Paul Gauthier
f94e05e04e Merge branch 'main' of github.com:Aider-AI/aider 2025-01-07 10:04:17 -08:00
Paul Gauthier
b5cad9a8cc copy 2025-01-07 09:58:20 -08:00
paul-gauthier
3a97d8cc82 Merge pull request #2795 from nims11/fix-discard
Fix files not being excluded in benchmark.py
2025-01-07 09:57:35 -08:00
Paul Gauthier
3c099465da refactor: Add AssertionError to ANY_GIT_ERROR tuple 2025-01-07 09:50:28 -08:00
Paul Gauthier (aider)
fcdb2591b6 fix: check prompt session is active before interrupting input 2025-01-07 09:46:48 -08:00
Paul Gauthier
b67a16e9af fix: Add AttributeError to ANY_GIT_ERROR tuple 2025-01-07 09:45:53 -08:00
Paul Gauthier (aider)
1d672616be fix: correct file export path in voice format conversion 2025-01-07 09:43:49 -08:00
Nimesh Ghelani
ed9d70903d Fix files not being excluded in benchmark.py
`.discard()` removes an item from the set. `.difference_update()` is the
correct call here.
2025-01-07 17:35:29 +00:00
Paul Gauthier
8a9bab8a46 copy 2025-01-07 09:33:00 -08:00
Paul Gauthier
fdc6a08eb4 copy 2025-01-07 09:28:34 -08:00
Paul Gauthier
154309912d delay renedering md when it gets slow 2025-01-07 06:57:38 -08:00
Paul Gauthier
a84fea86b8 copy 2025-01-07 06:57:20 -08:00
Paul Gauthier (aider)
609998bc18 style: Format floating-point division in mdstream.py 2025-01-07 06:51:59 -08:00
Paul Gauthier (aider)
891868b061 perf: adjust min_delay based on markdown render time for smoother updates 2025-01-07 06:51:56 -08:00
Paul Gauthier
3fc5cf8b9f refactor: Replace hardcoded min_delay with 1./20 for 20fps in MarkdownStream 2025-01-07 06:51:54 -08:00
Paul Gauthier (aider)
6048ed5bc1 style: Remove trailing whitespace from Lorem Ipsum text lines 2025-01-07 06:44:35 -08:00
Paul Gauthier (aider)
a1a007134c style: Break long Lorem Ipsum text into multiple lines to comply with line length limit 2025-01-07 06:44:10 -08:00
Paul Gauthier
d82f9fa432 refactor: Multiply _text by 10 in mdstream.py for testing 2025-01-07 06:44:09 -08:00
Paul Gauthier (aider)
c0074301a3 style: Remove extra blank line in mdstream.py 2025-01-07 06:42:52 -08:00
Paul Gauthier (aider)
9c2c05ad44 refactor: read io.py source file in mdstream.py main block 2025-01-07 06:42:48 -08:00
Paul Gauthier
fad230c02e refactor: Split markdown text into prefix and suffix variables 2025-01-07 06:42:46 -08:00
Paul Gauthier (aider)
ad3c95f273 style: Fix whitespace and formatting in mdstream.py 2025-01-07 06:11:58 -08:00
Paul Gauthier (aider)
684fdb6095 refactor: extract markdown rendering logic into helper method 2025-01-07 06:11:54 -08:00
Paul Gauthier
8e64f171b8 refactor: improve markdown streaming with stable/unstable line handling 2025-01-07 06:11:52 -08:00
Paul Gauthier (aider)
d616c3fed7 style: Remove trailing whitespace in MarkdownStream class docstring 2025-01-07 05:58:45 -08:00
Paul Gauthier (aider)
e07e6cd2a3 docs: Format docstring to comply with line length limits 2025-01-07 05:58:41 -08:00
Paul Gauthier (aider)
f1bd5cdb52 style: Fix whitespace and formatting in MarkdownStream class 2025-01-07 05:57:39 -08:00
Paul Gauthier (aider)
be82b6bed9 docs: add comments to explain MarkdownStream class and methods 2025-01-07 05:57:35 -08:00
Paul Gauthier
37ad4758a1 refactor: Move fname_path assignment inside try block in GitRepo.ignored_file_raw 2025-01-04 12:36:07 -08:00
Paul Gauthier (aider)
e4a238a05c style: Format code with consistent string quotes and remove trailing whitespace 2025-01-04 12:27:11 -08:00
Paul Gauthier (aider)
e5ca922ce8 fix: handle empty paths and dotfiles in get_ident_filename_matches 2025-01-04 12:27:04 -08:00
Paul Gauthier
6a1f4431d0 docs: Update HISTORY.md and FAQ.md with latest changes and model usage stats 2025-01-04 12:22:45 -08:00
Paul Gauthier (aider)
d67eda24d2 style: Remove trailing whitespace and format confirm_ask prompt 2025-01-04 12:09:53 -08:00
Paul Gauthier (aider)
bba0cc8dc5 feat: show token count in command output confirmation prompt 2025-01-04 12:09:48 -08:00
Paul Gauthier
884b52b710 refactor: Add comment for tokenizing command output in Commands class 2025-01-04 12:09:45 -08:00
Paul Gauthier
01ef2351b3 refactor: Use temporary variable for audio format to avoid state mutation 2025-01-04 12:08:05 -08:00
Paul Gauthier
de1d566e9e refactor: Simplify audio file handling and conversion logic 2025-01-04 12:06:07 -08:00
Paul Gauthier (aider)
19114a61ae style: Format print statement in voice.py for better readability 2025-01-04 12:04:13 -08:00
Paul Gauthier (aider)
36e5599ead feat: Add file size logging after audio conversion 2025-01-04 12:04:09 -08:00
Paul Gauthier (aider)
f5a82e575c style: Format print statement in voice.py for better readability 2025-01-04 12:03:32 -08:00
Paul Gauthier (aider)
1851de323d feat: add error handling and feedback for audio conversion 2025-01-04 12:03:25 -08:00
Paul Gauthier
f9408640a3 refactor: Simplify audio file size check and format conversion logic 2025-01-04 12:03:24 -08:00
Paul Gauthier (aider)
73837730fa feat: Add file size check and mp3 conversion for large audio files 2025-01-04 11:59:42 -08:00
Paul Gauthier
9b46991721 refactor: Add comment for handling large file uploads in voice.py 2025-01-04 11:59:40 -08:00
Paul Gauthier
606cd0368f refactor: remove redundant exception handling in GitRepo 2025-01-04 11:09:55 -08:00
Paul Gauthier
d9ef23ad99 Merge branch 'main' of github.com:Aider-AI/aider 2025-01-04 11:09:25 -08:00
Paul Gauthier
48b8f54c12 refactor: Move message and style initialization before try block in InputOutput 2025-01-04 11:04:32 -08:00
Paul Gauthier (aider)
cec9f90c1c style: Standardize string quotes in InputOutput class 2025-01-04 11:03:43 -08:00
Paul Gauthier (aider)
44d36f140a fix: handle UnicodeEncodeError in console output with ASCII fallback 2025-01-04 11:03:38 -08:00
paul-gauthier
f88adcfa85 Merge pull request #2764 from caseymcc/repo_index
Ignore directories in repo that have index errors
2025-01-04 13:59:32 -05:00
Paul Gauthier (aider)
c5919f0c15 refactor: improve cleanup error handling and verbose logging 2025-01-04 10:55:11 -08:00
Paul Gauthier
ac160cac12 chore: Ignore exceptions during Rust target directory cleanup 2025-01-04 10:55:09 -08:00
Paul Gauthier
867aaa5864 copy 2025-01-04 06:36:22 -08:00
Paul Gauthier
0b26505a20 Merge branch 'main' of github.com:Aider-AI/aider 2025-01-04 06:33:49 -08:00
paul-gauthier
98ad513621 Merge pull request #2753 from aweis89/fix-linting-cmd
fix: lint command with nested spaced strings
2025-01-04 09:33:38 -05:00
Paul Gauthier
591edbb003 improve prompts so that switching between ask/code works better with deepseek 2025-01-04 06:28:20 -08:00
Paul Gauthier
a17b1c2ab7 Merge branch 'main' of github.com:Aider-AI/aider 2025-01-04 06:27:42 -08:00
Paul Gauthier
648f14d95b copy 2025-01-04 06:25:19 -08:00
Paul Gauthier (aider)
2e4c2422b1 feat: Add voice format and input device initialization in Commands 2025-01-04 06:21:19 -08:00
Paul Gauthier
463fdb1ed9 refactor: Increase max chat history tokens limit from 4k to 8k 2025-01-04 06:19:38 -08:00
Paul Gauthier (aider)
d6b612a4a3 style: Break long comment line to comply with flake8 E501 2025-01-04 06:18:40 -08:00
Paul Gauthier (aider)
d24376608e refactor: generalize token calculation using division in Model class 2025-01-04 06:18:15 -08:00
Paul Gauthier
ff41f9bd9a refactor: adjust max_chat_history_tokens calculation based on max_input_tokens 2025-01-04 06:18:12 -08:00
paul-gauthier
6d3dd5c484 Merge pull request #2767 from apaz-cli/ap/suppress_streamlit
Disable streamlit email prompt
2025-01-03 16:02:02 -05:00
apaz-cli
f0bc8983b8 Disable streamlit email prompt 2025-01-03 14:43:18 -06:00
Paul Gauthier (aider)
729354b038 chore: Add cleanup for node_modules directories in benchmark tests 2025-01-03 14:19:06 -05:00
Paul Gauthier (aider)
c0be857f37 chore: Add Java build directory cleanup to test runner 2025-01-03 14:16:51 -05:00
Paul Gauthier
98b0e88ace refactor: simplify Rust target directory cleanup logic 2025-01-03 14:16:49 -05:00
Paul Gauthier (aider)
3d501df21f chore: Clean up Rust target/debug directory after all test attempts 2025-01-03 14:14:44 -05:00
Paul Gauthier
1b4abb747d style: Add blank line for readability in benchmark.py 2025-01-03 14:14:42 -05:00
Paul Gauthier
b1d418f7fb copy 2025-01-03 12:26:55 -04:00
Paul Gauthier
a702b4752b copy 2025-01-03 12:25:03 -04:00
Paul Gauthier
684ba7c0cb Merge branch 'main' of github.com:Aider-AI/aider 2025-01-03 12:16:43 -04:00
Krazer
1bcc27d2be little clean up 2025-01-03 09:07:27 -06:00
Krazer
50d3b305d4 make it a warning 2025-01-03 09:01:34 -06:00
Krazer
a341c98ec6 handle repo index errors 2025-01-03 08:58:42 -06:00
paul-gauthier
fa5c8a00e4 Merge pull request #2706 from Hambaobao/polyglot-qwen2.5-coder-32b-instruct-whole-results
Polyglot Qwen2.5-Coder-32B-Instruct Results [Whole]
2025-01-03 09:35:20 -04:00
paul-gauthier
42f6c20ada Merge branch 'main' into polyglot-qwen2.5-coder-32b-instruct-whole-results 2025-01-03 09:35:14 -04:00
paul-gauthier
787738094d Update README.md 2025-01-02 21:50:30 -04:00
Paul Gauthier
a44ebfe99f copy 2025-01-02 17:26:14 -04:00
Paul Gauthier
c5959664e4 Merge branch 'main' of github.com:Aider-AI/aider 2025-01-02 17:23:42 -04:00
Paul Gauthier
9b581268de copy 2025-01-02 17:23:10 -04:00
Aaron Weisberg
acf654c984 fix: lint command with nested spaced strings 2025-01-02 17:27:33 +01:00
paul-gauthier
94f83eb9e3 Merge pull request #2750 from bkowalik/patch-1
Document boto3 install process with aider installed by uv or one-liner
2025-01-02 09:44:22 -04:00
Bartek Kowalik
07c675ed06 Document boto3 install process with uv 2025-01-02 08:39:20 +01:00
Paul Gauthier
f292e01980 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-30 14:37:27 -04:00
Paul Gauthier (aider)
61f9123147 style: Run linter 2024-12-30 14:21:39 -04:00
Paul Gauthier (aider)
60708a7fd7 fix: Remove unused imports in commands.py 2024-12-30 14:21:35 -04:00
Paul Gauthier
761fb93aba refactor: Move test_cmd_load_with_switch_coder to test file 2024-12-30 14:21:28 -04:00
Paul Gauthier (aider)
20bc718bdc style: Format voice init for readability 2024-12-30 14:19:21 -04:00
Paul Gauthier (aider)
07337d2f41 feat: Handle voice-format command line argument 2024-12-30 14:19:14 -04:00
Paul Gauthier (aider)
3d2de00f49 style: Apply linter fixes 2024-12-30 14:17:25 -04:00
Paul Gauthier (aider)
a7242ca846 refactor: Pass voice settings to Commands as params 2024-12-30 14:17:16 -04:00
paul-gauthier
d3298ac5f2 Merge pull request #2725 from joshvera/fix-benchmark-java-ca-pkg
Install ca-certificates before openjdk-21 to resolve cacerts error
2024-12-29 15:07:51 -04:00
Josh Vera
e486243c06 Install ca-certificates before openjdk-21 to resolve cacerts error 2024-12-29 10:55:09 -08:00
Paul Gauthier (aider)
8eaefb57d3 feat: Add RevCumulative column to problem stats 2024-12-28 11:45:41 -04:00
Paul Gauthier
c21f7afdcb Merge branch 'main' of github.com:Aider-AI/aider 2024-12-28 10:24:22 -04:00
Paul Gauthier
d734dee589 copy 2024-12-28 10:24:17 -04:00
Paul Gauthier (aider)
f035c4c01a fix: Remove max_apply_update_errors from threaded call 2024-12-27 16:36:58 -04:00
Paul Gauthier (aider)
8fcdcecf36 refactor: Remove deprecated max_apply_update_errors 2024-12-27 16:36:47 -04:00
Paul Gauthier
3f9ee1ac2e refactor: Remove deprecated max_apply_update_errors 2024-12-27 16:36:46 -04:00
Paul Gauthier
188e1f788d chore: Rename exercism dir to polyglot-benchmark 2024-12-27 16:33:04 -04:00
paul-gauthier
98a0f1cf5b Merge pull request #2698 from paulmaunders/fix-macos-go-tests
Fix Go installation and benchmark tests for Apple Silicon
2024-12-27 12:31:36 -05:00
Paul Gauthier
1467a673b9 style: Remove mobile height override for blame chart 2024-12-26 20:11:14 -04:00
Paul Gauthier
889eb86d89 fix: Correct chart legend position and reverse order 2024-12-26 20:09:09 -04:00
Paul Gauthier (aider)
125da0e2db feat: Move chart legend to top-left 2024-12-26 20:04:37 -04:00
Paul Gauthier
14b274c707 style: Reduce blame chart height on website 2024-12-26 20:04:37 -04:00
Paul Gauthier (aider)
dedbc20ac6 feat: Make charts responsive and taller on mobile 2024-12-26 20:02:11 -04:00
Paul Gauthier (aider)
36cf2348d0 style: Change human bar color to light grey 2024-12-26 19:57:59 -04:00
Paul Gauthier
a19f8996b8 fix: Improve blame chart labels and stacking 2024-12-26 19:57:57 -04:00
Paul Gauthier (aider)
7293263773 fix: Stack x-axis for full width bars 2024-12-26 19:55:33 -04:00
Paul Gauthier (aider)
ed5b07374d fix: Use minus filter for subtraction in liquid template 2024-12-26 19:54:09 -04:00
Paul Gauthier (aider)
07b96bef95 feat: Create stacked bar chart for lines of code by author 2024-12-26 19:50:21 -04:00
Paul Gauthier
5c3cca157d switch to deepseek-chat instead of deepseek-coder 2024-12-26 19:40:06 -04:00
Paul Gauthier
f1f66a9b9d copy 2024-12-26 19:28:14 -04:00
Paul Gauthier
f4007210c1 set version to 0.70.1.dev 2024-12-26 19:19:51 -04:00
Paul Gauthier
77962dbd4c version bump to 0.70.0 2024-12-26 19:18:21 -04:00
Paul Gauthier
419cbae55f copy 2024-12-26 10:55:14 -05:00
Paul Gauthier
5233789c40 docs: Improve watch_code_prompt instructions 2024-12-26 10:54:25 -05:00
Paul Gauthier (aider)
70731719f7 style: Fix formatting in io.py 2024-12-26 10:52:21 -05:00
Paul Gauthier (aider)
cf4aa68f98 refactor: Use shorter abs/rel paths for readonly files 2024-12-26 10:52:16 -05:00
Paul Gauthier
6bfd89074c fix: Display shorter path for readonly files 2024-12-26 10:48:04 -05:00
Paul Gauthier
acc4893a7f fix: Update deepseek-chat max tokens 2024-12-26 10:45:14 -05:00
Paul Gauthier
ab61ae2b36 copy 2024-12-26 10:18:19 -05:00
Paul Gauthier
514b9c1c7d copy 2024-12-26 10:13:56 -05:00
Paul Gauthier
44f2cf2b24 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-26 10:12:36 -05:00
paul-gauthier
9befec5cd1 Merge pull request #2692 from mdklab/fix-issue-1802-unicode-error
Fix issue #1802: Handle UnicodeDecodeError in repo file paths
2024-12-26 10:12:33 -05:00
Paul Gauthier
7efdfe5639 added OR o1 and fix OR deepseek-chat 2024-12-26 10:11:40 -05:00
Paul Gauthier (aider)
be6811b29a fix: Correct import path for Coder in commands.py 2024-12-26 09:59:05 -05:00
Paul Gauthier (aider)
f160b8df04 fix: Move Coder import to avoid circular dependency 2024-12-26 09:58:45 -05:00
Paul Gauthier (aider)
158471b218 style: Reorder imports in aider/commands.py 2024-12-26 09:58:15 -05:00
Paul Gauthier (aider)
a383cece53 fix: Import missing modules for test 2024-12-26 09:58:11 -05:00
Paul Gauthier (aider)
0901e6ab77 fix: Correctly format long error message string 2024-12-26 09:57:56 -05:00
Paul Gauthier (aider)
e1485971d8 test: Add test for cmd_load with SwitchCoder 2024-12-26 09:57:51 -05:00
Paul Gauthier (aider)
91c9b1bfe7 fix: Handle SwitchCoder exception in cmd_load 2024-12-26 09:57:09 -05:00
Paul Gauthier
befe6be86c fix: Catch switchcoder exception in run_commands 2024-12-26 09:57:07 -05:00
Paul Gauthier
79428cf4ed copy 2024-12-26 09:49:02 -05:00
Paul Gauthier
7bde5fe893 copy 2024-12-26 09:48:18 -05:00
Paul Gauthier
2f7e024387 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-26 09:47:16 -05:00
paul-gauthier
9235cfa739 Merge pull request #2695 from gengjiawen/patch-1
add yi-lightning result
2024-12-26 07:05:41 -05:00
paul-gauthier
f1e623ec5a Merge branch 'main' into patch-1 2024-12-26 07:05:33 -05:00
柏枫
7c86dc9ac6 add polyglot-qwen2.5-coder-32b-instruct-whole-results 2024-12-26 15:01:45 +08:00
Paul Gauthier
ec2da0a399 add deepseek v3 2024-12-25 09:01:43 -05:00
Paul Gauthier
dd9b2a872c copy 2024-12-25 08:11:04 -05:00
Paul Gauthier
9767759033 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-25 08:05:55 -05:00
Paul Gauthier
7537d79311 fix: Remove .bash_history from rsync 2024-12-25 08:05:46 -05:00
Paul Maunders
b68f34eb9e feat: Fix Go installation for Apple Silicon and add tmp.benchmarks to gitignore 2024-12-24 17:30:41 +00:00
Paul Gauthier (aider)
0a23c4abd6 feat: Configure bash history to save commands immediately 2024-12-24 08:03:01 -05:00
paul-gauthier
b51768b08e Update 2024-12-21-polyglot.md 2024-12-23 18:01:03 -08:00
Jiawen Geng
4561f0c79e add yi-lightning result 2024-12-23 16:39:25 -08:00
mdk
5c92491bc0 Fix issue #1802: Handle UnicodeDecodeError in repo file paths
Added error handling for UnicodeDecodeError when decoding paths in the Git repository.
This issue arises when paths are encoded in formats other than the expected system encoding.

The error handler now provides a detailed error message, helping users identify potential encoding mismatches.

Closes #1802
2024-12-23 20:01:08 +01:00
paul-gauthier
083605e2d7 Merge pull request #2690 from apaz-cli/ap/rephrase_dirwarning 2024-12-23 08:27:59 -08:00
apaz-cli
d28e2f0f56 Rephrase home dir warning 2024-12-23 08:50:25 -06:00
Paul Gauthier
87a964355b copy 2024-12-23 08:00:25 -05:00
Paul Gauthier
fbc3f0cef5 copy 2024-12-22 21:23:39 -05:00
Paul Gauthier
2b1625e3a8 copy 2024-12-22 18:07:25 -05:00
Paul Gauthier (aider)
6230df749e fix: Create table rows if they don't exist 2024-12-22 18:04:01 -05:00
Paul Gauthier
e62003c0ce copy 2024-12-22 17:52:57 -05:00
Paul Gauthier
d0f092f7ae copy 2024-12-22 17:51:38 -05:00
Paul Gauthier
9e2e07e8a7 copy 2024-12-22 16:58:29 -05:00
Paul Gauthier
4154d47c07 copy 2024-12-22 16:56:38 -05:00
Paul Gauthier
62e0cba7bd copy 2024-12-22 16:52:51 -05:00
Paul Gauthier
39d5c785d5 copy 2024-12-22 16:51:44 -05:00
Paul Gauthier
e5cb81c11f copy 2024-12-22 16:47:58 -05:00
Paul Gauthier
3abb8d38ec copy 2024-12-22 16:46:41 -05:00
Paul Gauthier
7f0860d5d0 copy 2024-12-22 16:41:20 -05:00
Paul Gauthier
8c74c8ab6f add o1-mini 2024-12-22 16:39:18 -05:00
Paul Gauthier
37df899ada copy 2024-12-22 16:17:16 -05:00
Paul Gauthier
f55181e447 copy 2024-12-22 16:14:33 -05:00
Paul Gauthier
b1bc2f8c5c test: Remove user_id check from need_to_ask test 2024-12-22 09:52:45 -05:00
Paul Gauthier (aider)
350df7ca55 fix: Test check_gitignore with and without .env file 2024-12-22 09:51:20 -05:00
Paul Gauthier
8768a8aca6 copy 2024-12-22 09:15:59 -05:00
Paul Gauthier (aider)
0f8bb016f4 fix: Correct misspelled HIGHLIGHT_MODEL in leaderboard.js 2024-12-22 09:07:10 -05:00
Paul Gauthier (aider)
eb30791ff4 feat: Make highlight model configurable via assign 2024-12-22 09:06:05 -05:00
Paul Gauthier
7b37bf0f48 copy 2024-12-22 09:02:01 -05:00
Paul Gauthier
fff67a5917 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-22 09:00:52 -05:00
paul-gauthier
3dbe91577c Merge pull request #2675 from apaz-cli/ap/dotenv_dne
Don't add .env to gitignore when it doesn't exist.
2024-12-22 06:00:47 -08:00
Paul Gauthier
0e05b64ebc copy 2024-12-22 08:59:38 -05:00
Paul Gauthier
c895e99306 copy 2024-12-22 08:43:59 -05:00
Paul Gauthier
6d7e8beaaa other o1 variants 2024-12-21 14:14:21 -08:00
Paul Gauthier
8b62d8a6c5 copy 2024-12-21 14:11:54 -08:00
Paul Gauthier
ec44850646 copy 2024-12-21 14:11:21 -08:00
Paul Gauthier
2ea5a98ee0 rename 2024-12-21 11:53:43 -08:00
Paul Gauthier
80928b90a5 cleanup 2024-12-21 11:52:18 -08:00
Paul Gauthier
b28174aba1 delete refac js 2024-12-21 11:51:23 -08:00
Paul Gauthier (aider)
da170bab3a fix: Use configured pass_rate for graph data in search 2024-12-21 11:49:36 -08:00
Paul Gauthier (aider)
49a2f998dd refactor: Unify leaderboard scripts and use config variables 2024-12-21 11:47:29 -08:00
Paul Gauthier
4efdc8b4f7 refactor: Rename benchmark dir, improve rsync, fix problem stats 2024-12-21 11:09:52 -08:00
Paul Gauthier (aider)
a75507980a fix: Pass stats_languages to summarize_results and show_stats 2024-12-20 16:04:00 -08:00
Paul Gauthier (aider)
8d0decc17a style: Apply linter formatting 2024-12-20 16:03:44 -08:00
Paul Gauthier (aider)
e334cbb5d4 fix: Correct indentation in load_results function 2024-12-20 16:03:40 -08:00
Paul Gauthier (aider)
e3ac8ab19d feat: Add --stats-languages option to filter results 2024-12-20 16:03:19 -08:00
Paul Gauthier
bddf6e9017 fix: Handle missing attributes in show_stats and empty models 2024-12-20 16:03:19 -08:00
apaz-cli
bcdc0217b3 Don't add .env to gitignore when it doesn't exist. 2024-12-20 10:09:07 -06:00
Paul Gauthier
521841b447 fix: Skip redoing tests if results exist 2024-12-19 16:25:54 -08:00
Paul Gauthier (aider)
c53cd336f9 style: Fix linting issues 2024-12-19 15:59:03 -08:00
Paul Gauthier (aider)
a8226989c8 feat: Remove @Disabled annotations from Java test files 2024-12-19 15:58:59 -08:00
Paul Gauthier
114b156d74 fix: Use relative paths for ignored files, remove redundant try 2024-12-19 15:56:16 -08:00
Paul Gauthier (aider)
def2d4bac9 style: Fix string formatting in problem stats 2024-12-19 15:50:14 -08:00
Paul Gauthier (aider)
250e2ab6aa feat: Print never solved exercises with full path 2024-12-19 15:50:11 -08:00
Paul Gauthier
6185ddf76a feat: Print never solved exercises and remove dumps 2024-12-19 15:50:10 -08:00
Paul Gauthier (aider)
dddf192e5a fix: Check for testcase key in results 2024-12-19 15:49:16 -08:00
Paul Gauthier (aider)
2d32f77ed0 feat: Print list of exercises never solved by any model 2024-12-19 15:49:13 -08:00
Paul Gauthier
7eb7533d42 fix: Handle missing testcase in results and bad json 2024-12-19 15:49:12 -08:00
Paul Gauthier (aider)
bb711fe255 style: Run linter 2024-12-19 14:39:23 -08:00
Paul Gauthier (aider)
14a8759b82 feat: Disqualify exercises with >=4 parse errors 2024-12-19 14:39:18 -08:00
Paul Gauthier
5a0d4eff71 fix: Correctly handle zero hard set problems 2024-12-19 14:39:17 -08:00
Paul Gauthier (aider)
805d6bbc8c chore: Create remote ~/aider dir before rsync 2024-12-19 12:03:37 -08:00
Paul Gauthier
a0004ab892 chore: Make rsync.sh executable and add remote dir creation 2024-12-19 12:03:36 -08:00
Paul Gauthier (aider)
46a444dc21 fix: Improve docker group addition and instructions 2024-12-19 11:56:03 -08:00
Paul Gauthier (aider)
aefb5c37fe feat: Add newgrp to apply docker group changes in session 2024-12-19 11:53:44 -08:00
Paul Gauthier (aider)
2216978726 feat: Start and enable docker service after install 2024-12-19 11:52:23 -08:00
Paul Gauthier
3a2d8edb53 chore: Make install-docker-ubuntu.sh executable 2024-12-19 11:52:22 -08:00
Paul Gauthier (aider)
e0d57b7713 feat: Add script to install docker on ubuntu 2024-12-19 11:51:06 -08:00
Paul Gauthier
3a9912c01e feat: Add install docker script for ubuntu 2024-12-19 11:51:05 -08:00
Paul Gauthier (aider)
6cadee31bf feat: Create script to clone exercism repos 2024-12-19 11:47:16 -08:00
Paul Gauthier
678845dfda feat: Add clone-exercism benchmark script 2024-12-19 11:47:15 -08:00
Paul Gauthier (aider)
7f7e218504 feat: Add rsync script to sync repo to remote host 2024-12-19 11:43:51 -08:00
Paul Gauthier
256a9951f5 feat: Add rsync benchmark script 2024-12-19 11:43:50 -08:00
Paul Gauthier (aider)
370b45bb35 feat: Ignore files in .meta and .docs directories 2024-12-19 07:23:28 -08:00
Paul Gauthier
616c4a9a53 chore: Add comment about ignoring meta and docs files 2024-12-19 07:23:27 -08:00
Paul Gauthier
821f7d6694 fix: Use extra_body for reasoning_effort, fix test counts 2024-12-19 07:10:20 -08:00
Paul Gauthier (aider)
bc89be6187 feat: Add OpenJDK 21 and TBB dev packages to Dockerfile 2024-12-19 07:01:01 -08:00
Paul Gauthier (aider)
86b6a4cefd fix: Only create build dir if it doesn't exist 2024-12-19 06:49:18 -08:00
Paul Gauthier
1f9a53a454 feat: Add cpp benchmark test script 2024-12-19 06:49:18 -08:00
Paul Gauthier (aider)
f22d112da2 feat: Add cmake to Dockerfile 2024-12-19 06:46:44 -08:00
Paul Gauthier
c36c06ab99 fix: Retry tests on parse or timeout, add gpt-4o params 2024-12-18 15:56:38 -08:00
Paul Gauthier
a915c60999 feat: Add pass_num to benchmark results, fix hard set percent 2024-12-18 13:36:37 -08:00
Paul Gauthier (aider)
6ddb8a7d88 feat: Add hard set problem counts by language 2024-12-18 13:18:31 -08:00
Paul Gauthier (aider)
50bb2cb1e6 feat: Add total column to unsolved problems table 2024-12-18 13:17:38 -08:00
Paul Gauthier (aider)
e1571dda9b style: Run linter 2024-12-18 13:16:45 -08:00
Paul Gauthier (aider)
7410c6216c feat: Count and display copied exercises per language 2024-12-18 13:16:41 -08:00
Paul Gauthier (aider)
8f84df44ab style: Run linter 2024-12-18 13:16:08 -08:00
Paul Gauthier (aider)
82f21b6734 fix: Copy hard set problems by language and exercise 2024-12-18 13:16:04 -08:00
Paul Gauthier (aider)
892fd5a6ef style: Run linter 2024-12-18 13:13:55 -08:00
Paul Gauthier (aider)
3069db0cfd feat: Add --copy-hard-set switch to copy hard set problems 2024-12-18 13:13:51 -08:00
Paul Gauthier (aider)
b71c9d539e feat: Calculate and display unsolved problem percentages by language 2024-12-18 13:11:20 -08:00
Paul Gauthier (aider)
78e643970d style: Fix linting issues 2024-12-18 13:09:46 -08:00
Paul Gauthier (aider)
34da3dd3d7 feat: Show percent of unsolved problems per language 2024-12-18 13:09:42 -08:00
Paul Gauthier (aider)
817cb0d363 fix: Remove unused List, Optional imports 2024-12-18 13:09:13 -08:00
Paul Gauthier (aider)
01088e214c style: Run linter on problem_stats.py 2024-12-18 13:08:51 -08:00
Paul Gauthier (aider)
3e4500f9fd feat: Print hard set problem counts by language 2024-12-18 13:08:48 -08:00
Paul Gauthier
d4b62608a9 chore: Move HARD_SET_NUM definition 2024-12-18 13:08:47 -08:00
Paul Gauthier (aider)
e6bfc1c2fc refactor: Use constant for hard set threshold 2024-12-18 13:06:03 -08:00
Paul Gauthier
051cabed69 style: Adjust model column width in problem stats 2024-12-18 13:06:02 -08:00
Paul Gauthier (aider)
04916a6e97 style: Run linter on problem_stats.py 2024-12-18 13:03:31 -08:00
Paul Gauthier (aider)
f3be2fa66b feat: Add hard set analysis to problem_stats.py 2024-12-18 13:03:27 -08:00
Paul Gauthier (aider)
c36087cc0c style: Apply linter formatting 2024-12-18 12:55:47 -08:00
Paul Gauthier (aider)
e35909ac7d refactor: Subsort exercises by name when solve rates are equal 2024-12-18 12:55:43 -08:00
Paul Gauthier
e5a693ab94 fix: Correctly format testcase/language in stats 2024-12-18 12:55:42 -08:00
Paul Gauthier (aider)
9e9cfb4600 fix: Calculate max name length after cleaning paths 2024-12-18 12:49:23 -08:00
Paul Gauthier (aider)
5dddaac006 style: Fix linting issues in problem_stats.py 2024-12-18 12:48:44 -08:00
Paul Gauthier (aider)
14af6f1fba fix: Remove duplicate language prefix in problem stats 2024-12-18 12:48:40 -08:00
Paul Gauthier (aider)
e88064fdc9 style: Run linter 2024-12-18 12:47:17 -08:00
Paul Gauthier (aider)
6badf5ea1d feat: Add cumulative sum column to distribution table 2024-12-18 12:47:14 -08:00
Paul Gauthier
20f5f3da24 chore: Remove unused import 2024-12-18 12:47:13 -08:00
Paul Gauthier (aider)
8c1b147705 style: Fix string formatting in problem stats 2024-12-18 12:46:02 -08:00
Paul Gauthier (aider)
366155b828 fix: Correct language lookup in problem_stats.py 2024-12-18 12:45:58 -08:00
Paul Gauthier (aider)
2c7d1897eb style: Fix linting issues in problem_stats.py 2024-12-18 12:43:08 -08:00
Paul Gauthier (aider)
26ccb23402 feat: Add table showing exercise solution distribution 2024-12-18 12:43:04 -08:00
Paul Gauthier
d9e2471fcd refactor: Remove unused dump calls in benchmark script 2024-12-18 12:43:03 -08:00
Paul Gauthier (aider)
8302b351dd style: Fix line length in problem_stats.py 2024-12-18 12:38:45 -08:00
Paul Gauthier (aider)
b8647c0481 feat: Show exercises solved by all and total breakdown 2024-12-18 12:38:41 -08:00
Paul Gauthier
a168403d68 fix: Correctly extract language and testcase from results 2024-12-18 12:38:40 -08:00
Paul Gauthier (aider)
42d8650058 fix: Remove "exercises/" prefix from testcase output 2024-12-18 12:33:41 -08:00
Paul Gauthier (aider)
7ad0d46c11 style: Format problem_stats.py with linter 2024-12-18 12:31:54 -08:00
Paul Gauthier (aider)
58812f7f1f refactor: Sort all exercises by solve rate, not by language 2024-12-18 12:31:50 -08:00
Paul Gauthier (aider)
65133b2aef fix: Handle missing testcase key in problem stats 2024-12-18 12:29:38 -08:00
Paul Gauthier (aider)
291d8cd335 style: Run linter 2024-12-18 12:29:20 -08:00
Paul Gauthier (aider)
7a27e2b94b fix: Handle missing testcase key in problem stats 2024-12-18 12:29:15 -08:00
Paul Gauthier
57a8eab1c3 chore: Add dump for debugging 2024-12-18 12:29:14 -08:00
Paul Gauthier (aider)
236a7f68e9 fix: Handle empty results in problem_stats.py 2024-12-18 12:26:51 -08:00
Paul Gauthier (aider)
81d424f475 fix: Remove unused max_lang_len variable 2024-12-18 12:25:47 -08:00
Paul Gauthier (aider)
687ba8c9a2 style: Apply linter fixes 2024-12-18 12:25:39 -08:00
Paul Gauthier (aider)
6d74a564e6 feat: Handle new exercise dir layout and add language info 2024-12-18 12:25:33 -08:00
Paul Gauthier (aider)
0a3e0665ab style: Apply linter formatting 2024-12-18 12:21:19 -08:00
Paul Gauthier (aider)
a19f1fbc67 feat: Allow specifying dirs on cmd line for problem_stats 2024-12-18 12:21:13 -08:00
Paul Gauthier
2aa4615c78 feat: Add openrouter/openai/o1 model and update prompts 2024-12-18 06:59:14 -08:00
Paul Gauthier (aider)
7dd1346878 fix: Remove stray ] causing syntax error 2024-12-17 20:34:33 -08:00
Paul Gauthier (aider)
31f8c7d9cb fix: Handle JSON decode errors when loading results 2024-12-17 20:34:21 -08:00
Paul Gauthier
914ce0b94d feat: Add total_tests to summary, handle JSON decode errors 2024-12-17 20:34:20 -08:00
Paul Gauthier (aider)
664f09111e feat: Pass original_dname to tests, copy test files 2024-12-17 20:11:58 -08:00
Paul Gauthier (aider)
6141f414fd chore: Remove comment from run_unit_tests 2024-12-17 20:11:29 -08:00
Paul Gauthier
8911f0f217 fix: Correctly find benchmark markdown files 2024-12-17 20:11:29 -08:00
Paul Gauthier (aider)
5af108ccee style: Format benchmark code with black 2024-12-17 20:01:45 -08:00
Paul Gauthier (aider)
94e4169445 fix: Update stats to handle nested exercise directories 2024-12-17 20:01:40 -08:00
Paul Gauthier
479b5b7064 fix: Use shell=True for npm test and fix path 2024-12-17 20:01:39 -08:00
Paul Gauthier (aider)
674e935cf5 fix: Create symlinks only if they don't exist 2024-12-17 19:07:09 -08:00
Paul Gauthier
6b4982d75b chore: Add npm test benchmark script 2024-12-17 19:07:08 -08:00
Paul Gauthier (aider)
4167743a34 feat: Install npm packages in /npm-install directory 2024-12-17 19:01:24 -08:00
Paul Gauthier
ba289f6db4 build: Install nodejs and npm packages in Dockerfile 2024-12-17 19:01:22 -08:00
Paul Gauthier (aider)
422fd11f4d feat: Install all npm dependencies in Dockerfile 2024-12-17 18:50:04 -08:00
Paul Gauthier (aider)
614d9c9b0d feat: Install jest in Dockerfile 2024-12-17 18:40:30 -08:00
Paul Gauthier
f91be86662 build: Use uv for faster pip installs in Dockerfile 2024-12-17 18:40:28 -08:00
Paul Gauthier (aider)
72f05544e8 feat: Install Node.js in Dockerfile 2024-12-17 18:26:16 -08:00
Paul Gauthier (aider)
81f55820be refactor: Use ADD to fetch rustup installer in Dockerfile 2024-12-17 18:24:38 -08:00
Paul Gauthier (aider)
b9c14e1d65 feat: Add Go installation to Dockerfile 2024-12-17 18:22:41 -08:00
Paul Gauthier (aider)
5c55453a0e fix: Correctly calculate and display never solved exercises 2024-12-17 18:14:48 -08:00
Paul Gauthier
12491c4983 wip 2024-12-17 17:47:17 -08:00
Paul Gauthier (aider)
77d379c021 refactor: Use full path for test names in benchmark 2024-12-17 17:43:52 -08:00
Paul Gauthier (aider)
1a12a59e91 chore: Remove comment about test_dnames 2024-12-17 17:41:29 -08:00
Paul Gauthier
0b970dd9c7 fix: Ensure test_dnames include full path 2024-12-17 17:41:27 -08:00
Paul Gauthier (aider)
93ac2bd53e feat: Copy only practice subdirs with exercises 2024-12-17 17:36:03 -08:00
Paul Gauthier (aider)
f9646ac47a chore: Remove comment about practice subdirs 2024-12-17 17:35:17 -08:00
Paul Gauthier
e8ed3b9e23 chore: Add comment about copying practice subdirs 2024-12-17 17:35:16 -08:00
Paul Gauthier (aider)
6238a07c8f style: Run linter on benchmark.py 2024-12-17 17:33:28 -08:00
Paul Gauthier (aider)
1fb33f0c47 feat: Add language filter and multi-lang support 2024-12-17 17:33:23 -08:00
Paul Gauthier (aider)
a842f41627 style: Fix linting issues in benchmark.py 2024-12-17 16:49:50 -08:00
Paul Gauthier (aider)
c4c135e678 refactor: Use dict for test commands based on file extensions 2024-12-17 16:49:46 -08:00
Paul Gauthier (aider)
f36f2fdea2 style: Fix typo in test file extension check 2024-12-17 16:48:37 -08:00
Paul Gauthier (aider)
e3f0a67584 feat: Choose test command based on file extensions 2024-12-17 16:48:32 -08:00
Paul Gauthier
f6f05fa0c6 fix: Use cargo test for rust tests 2024-12-17 16:48:31 -08:00
Paul Gauthier (aider)
54ca7ceac8 feat: Use buildpack-deps, python3.12, and rust in Dockerfile 2024-12-17 16:39:30 -08:00
Paul Gauthier (aider)
cf5b38d4f5 style: Fix linting issues in benchmark.py 2024-12-17 16:35:20 -08:00
Paul Gauthier (aider)
b23669400f fix: Correct syntax error in cleanup_test_output 2024-12-17 16:35:16 -08:00
Paul Gauthier
aaacd00ecf refactor: Use pytest instead of unittest for running tests 2024-12-17 16:35:08 -08:00
Paul Gauthier (aider)
03aa22ba84 feat: Read config.json, copy solution/test files, no fallback 2024-12-17 16:18:10 -08:00
Paul Gauthier
1493b8703f fix: Skip unparseable results files in real test 2024-12-17 16:18:09 -08:00
Paul Gauthier (aider)
59308c20c6 feat: Number exercises in the table 2024-12-17 14:15:40 -08:00
Paul Gauthier (aider)
cac5d8e716 style: Apply linter formatting 2024-12-17 14:15:06 -08:00
Paul Gauthier (aider)
7f16757bbe fix: Handle missing results in topn leaderboard calculation 2024-12-17 14:15:02 -08:00
Paul Gauthier (aider)
674e3846e2 fix: Correctly sort leaderboard by pass rate 2024-12-17 14:13:43 -08:00
Paul Gauthier (aider)
3a0be0cca9 style: Apply linter formatting 2024-12-17 14:13:19 -08:00
Paul Gauthier (aider)
00d7c3a05a feat: Add --topn argument to limit models by pass rate 2024-12-17 14:13:16 -08:00
Paul Gauthier (aider)
91f5fca5e9 feat: Include never solved exercises in stats 2024-12-17 14:10:47 -08:00
Paul Gauthier (aider)
1d7cb0c119 feat: Format problem stats output as a table with percentages 2024-12-17 14:10:00 -08:00
Paul Gauthier (aider)
24599aa64f style: Run linter on problem_stats.py 2024-12-17 14:09:20 -08:00
Paul Gauthier (aider)
54c1553892 refactor: Remove distribution of solutions table 2024-12-17 14:09:17 -08:00
Paul Gauthier (aider)
0ae53ce1a1 feat: Output per-exercise stats, sort by solvers 2024-12-17 14:08:47 -08:00
Paul Gauthier
c69ffe02f8 chore: Make problem_stats.py executable 2024-12-17 14:08:46 -08:00
Paul Gauthier (aider)
7bfc2e0e74 style: Run linter on benchmark script 2024-12-17 14:06:56 -08:00
Paul Gauthier (aider)
9cc674c283 feat: Add script to analyze exercise solution stats 2024-12-17 14:06:53 -08:00
Paul Gauthier
66e597a05c feat: Add problem stats benchmark 2024-12-17 14:06:52 -08:00
Paul Gauthier
074c636e53 copy 2024-12-17 14:03:46 -08:00
Paul Gauthier
4ec44936f6 analytics to 10% 2024-12-17 14:01:13 -08:00
Paul Gauthier
eb9c41f2a0 feat: Enable complete_while_typing in prompt_session 2024-12-17 13:42:59 -08:00
Paul Gauthier (aider)
04afb99c54 fix: Use module-level function in test_is_uuid_in_percentage 2024-12-17 13:33:33 -08:00
Paul Gauthier
2124e7b221 copy 2024-12-17 13:30:30 -08:00
Paul Gauthier
2416a8bf96 fix: Handle empty file content in FileWatcher 2024-12-17 13:30:10 -08:00
Paul Gauthier (aider)
408a40f78b style: Format with linter 2024-12-17 13:24:55 -08:00
Paul Gauthier (aider)
195ae5ce4b feat: Pass cwd as root to FileWatcher when subtree_only 2024-12-17 13:24:50 -08:00
Paul Gauthier
9bebb1e9a9 fix: Pass root to FileWatcher 2024-12-17 13:24:49 -08:00
Paul Gauthier
e7bec5be1d feat: Allow setting root path for file watcher 2024-12-17 13:23:55 -08:00
Paul Gauthier
c708e8ba8e refactor: Move PERCENT constant to top level 2024-12-17 13:02:07 -08:00
Paul Gauthier (aider)
60f26cc067 refactor: Move is_uuid_in_percentage and fix import 2024-12-17 12:55:43 -08:00
Paul Gauthier (aider)
64fa058bc7 style: Apply linter fixes 2024-12-17 12:55:29 -08:00
Paul Gauthier (aider)
9a770eeae9 refactor: Move uuid percentage check to standalone functions 2024-12-17 12:55:26 -08:00
Paul Gauthier
ffc2c5a26e refactor: Move uuid percentage check to function 2024-12-17 12:55:24 -08:00
Paul Gauthier
b6c5bd552e Merge branch 'main' of github.com:Aider-AI/aider 2024-12-17 12:39:07 -08:00
paul-gauthier
05147a3199 Merge pull request #2652 from evannjohnson/docs-code-themes
Document that Pygments styles can be used for --code-theme
2024-12-17 12:39:04 -08:00
Evan Johnson
7f0d08ad77 doc that Pygments styles can be used for --code-theme 2024-12-17 13:18:31 -07:00
Paul Gauthier
64f95af833 copy 2024-12-17 10:56:23 -08:00
Paul Gauthier
7cd2662355 disable website analytics 2024-12-17 08:48:47 -08:00
Paul Gauthier (aider)
154d485c9e feat: Add analytics config and toggle to _config.yml 2024-12-17 08:32:12 -08:00
Paul Gauthier
5f6821c7e2 copy 2024-12-17 08:28:51 -08:00
Paul Gauthier (aider)
59cf823d56 style: Run linter on blame.py 2024-12-17 08:25:08 -08:00
Paul Gauthier (aider)
70312c58be feat: Add exclude_files list and filter in blame script 2024-12-17 08:25:04 -08:00
Paul Gauthier
4942366271 feat: Add exclude_files list to blame script 2024-12-17 08:25:03 -08:00
Paul Gauthier
f237d0f212 copy 2024-12-16 19:57:10 -08:00
Paul Gauthier
9b424e0fe7 copy 2024-12-16 16:29:43 -08:00
Paul Gauthier
81b75d178b copy 2024-12-16 16:27:55 -08:00
Paul Gauthier
410e732eb3 copy 2024-12-16 16:21:55 -08:00
Paul Gauthier
2ca93cd93d copy 2024-12-16 16:18:50 -08:00
Paul Gauthier
50c806286e copy 2024-12-16 16:12:30 -08:00
Paul Gauthier
59de835b42 copy 2024-12-16 16:08:02 -08:00
Paul Gauthier
ecbac76cba copy 2024-12-16 16:06:06 -08:00
Paul Gauthier (aider)
9b16f2139d feat: Install aider-chat using uv after uv install 2024-12-16 16:02:49 -08:00
Paul Gauthier
ef14df5ba2 feat: Add install script for website 2024-12-16 16:02:48 -08:00
Paul Gauthier
b4be9875b2 copy 2024-12-16 15:58:29 -08:00
Paul Gauthier
8d0c962f42 copy 2024-12-16 15:57:13 -08:00
Paul Gauthier
5e0cb8d658 add install.ps1 2024-12-16 15:34:08 -08:00
Paul Gauthier
1869ab94fe copy 2024-12-16 13:01:25 -08:00
Paul Gauthier
2627c5baaf refac leaderboard 2024-12-16 12:57:56 -08:00
Paul Gauthier (aider)
e4e16b8f77 fix: Correctly select table body element 2024-12-16 12:56:49 -08:00
Paul Gauthier
85218d74d4 don't block pre-commit for faq cog 2024-12-16 12:47:06 -08:00
Paul Gauthier
47d5b66986 copy 2024-12-16 12:44:21 -08:00
Paul Gauthier
ecfb133de2 copy 2024-12-16 12:40:29 -08:00
Paul Gauthier
23c95d24f1 copy 2024-12-16 12:38:01 -08:00
Paul Gauthier
b37d89bd08 copy 2024-12-16 12:37:10 -08:00
Paul Gauthier
5c848d59b2 set version to 0.69.2.dev 2024-12-16 12:36:28 -08:00
Paul Gauthier
b1c04dece9 version bump to 0.69.1 2024-12-16 12:34:51 -08:00
Paul Gauthier
b87c7987bb copy 2024-12-16 12:29:10 -08:00
Paul Gauthier
0bef52ae7d fix: Only show AI comment help once per file add 2024-12-16 12:27:19 -08:00
Paul Gauthier (aider)
9ae04cf1ec style: Format tool output message 2024-12-16 12:13:35 -08:00
Paul Gauthier (aider)
0f7c4a8d4f feat: Add help message for first-time AI usage 2024-12-16 12:13:32 -08:00
Paul Gauthier
07353207c0 feat: Output "Use AI!" if no action triggered 2024-12-16 12:13:31 -08:00
Paul Gauthier
d89be83414 copy 2024-12-16 12:10:34 -08:00
Paul Gauthier
01382527f5 cleanup cog of toml 2024-12-16 12:08:08 -08:00
Paul Gauthier
dece2193fc Switch to MANIFEST.in to exclude aider/website/assets/ and other from whl build file 2024-12-16 12:07:02 -08:00
Paul Gauthier
d298f864fa works? 2024-12-16 11:55:24 -08:00
Paul Gauthier (aider)
ff37d8c691 feat: Add include-package-data to pyproject.toml 2024-12-16 08:28:10 -08:00
Paul Gauthier
f7f305a564 fix: Update include pattern for assets 2024-12-16 08:28:09 -08:00
Paul Gauthier (aider)
86f38e11cd feat: Add MANIFEST.in to exclude website assets 2024-12-16 08:27:02 -08:00
Paul Gauthier
0b60c48253 fixed gemini metadata keys 2024-12-15 16:00:40 -08:00
Paul Gauthier
024b9840f0 copy 2024-12-15 09:34:51 -08:00
Paul Gauthier
2f4f59d82f copy 2024-12-15 09:29:21 -08:00
Paul Gauthier
830d5ee763 copy 2024-12-15 09:27:22 -08:00
Paul Gauthier
5bc63f7a33 copy 2024-12-15 09:25:29 -08:00
Paul Gauthier
b54f970e12 copy 2024-12-15 09:16:42 -08:00
Paul Gauthier
0cc8c54152 copy 2024-12-15 09:01:13 -08:00
Paul Gauthier
241e1e27d0 copy 2024-12-15 08:50:28 -08:00
Paul Gauthier
0145e86202 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-15 08:48:12 -08:00
Paul Gauthier
4d50e1e373 copy 2024-12-15 08:46:44 -08:00
Paul Gauthier
4b6ae34800 updated keys config docs 2024-12-15 08:46:20 -08:00
Paul Gauthier
2feb85e831 api keys 2024-12-15 08:40:02 -08:00
Paul Gauthier
a67ac81265 updated install instructions 2024-12-15 08:39:53 -08:00
paul-gauthier
dab536c9e8 Merge pull request #2633 from you-n-g/patch-1 2024-12-15 07:04:51 -08:00
you-n-g
64cf298521 docs: Update watch.md 2024-12-15 13:35:14 +08:00
Paul Gauthier
10b5aaa6a5 copy 2024-12-14 20:52:20 -08:00
Paul Gauthier
8c79e5ccfb copy 2024-12-14 20:09:51 -08:00
Paul Gauthier
2ef536a342 copy 2024-12-14 17:42:22 -08:00
Paul Gauthier
85b1303460 fix: Remove always-true condition for Windows env var message 2024-12-14 09:50:26 -08:00
Paul Gauthier
60aca3a241 Merge branch 'no-git' 2024-12-14 09:49:41 -08:00
Paul Gauthier
db98381a86 refactor: Move git check after env loading 2024-12-14 09:44:42 -08:00
Paul Gauthier
f62ef34715 fix: Handle missing git module gracefully 2024-12-14 09:42:54 -08:00
Paul Gauthier
f95a6c1a5a recommend aider-install 2024-12-14 09:42:32 -08:00
Paul Gauthier
65555b5dd0 copy 2024-12-13 13:43:15 -08:00
Paul Gauthier
9f6331a35e copy 2024-12-13 13:34:18 -08:00
Paul Gauthier (aider)
8c10cb6230 style: Fix linting issues in my_models.py 2024-12-13 13:22:59 -08:00
Paul Gauthier (aider)
c8894bcead feat: Conditionally add redacted model note to script 2024-12-13 13:22:55 -08:00
Paul Gauthier
edc602c33a copy 2024-12-13 12:55:33 -08:00
Paul Gauthier (aider)
abfb2ca810 fix: Correct import path for my_models in faq.md 2024-12-13 12:49:01 -08:00
Paul Gauthier (aider)
9967efe45a fix: Correct import path in cog block for model stats 2024-12-13 12:48:29 -08:00
Paul Gauthier
e77d80bda5 docs: Add FAQ about LLMs used to build aider 2024-12-13 12:48:28 -08:00
Paul Gauthier (aider)
a691d1750a style: Apply linter formatting 2024-12-13 12:34:34 -08:00
Paul Gauthier (aider)
834e2f9304 refactor: Separate data, text, and HTML formatting into functions 2024-12-13 12:34:31 -08:00
Paul Gauthier (aider)
66e5e9c1ce feat: Add percentage column to model token usage summary 2024-12-13 12:33:14 -08:00
Paul Gauthier (aider)
2d5f613984 feat: Process only last 1000 lines of analytics file 2024-12-13 12:32:28 -08:00
Paul Gauthier (aider)
868e7a278f feat: Sort model token usage by count descending 2024-12-13 12:31:38 -08:00
Paul Gauthier
f953d17889 chore: Make my_models.py executable 2024-12-13 12:31:37 -08:00
Paul Gauthier (aider)
3473969aae fix: Remove unused os import in my_models.py 2024-12-13 12:31:09 -08:00
Paul Gauthier (aider)
ec11ae7c40 style: Fix linting issues in my_models.py 2024-12-13 12:31:03 -08:00
Paul Gauthier (aider)
8217ee1bbb feat: Add script to analyze model token usage 2024-12-13 12:30:59 -08:00
Paul Gauthier
1ad3ee0aec feat: Add my_models.py script 2024-12-13 12:30:59 -08:00
Paul Gauthier (aider)
b3e9a2fede feat: Allow version arg for blame script, default to v0.1.0 2024-12-13 11:49:15 -08:00
Paul Gauthier
2f5d6bf909 feat: Take version as optional arg for blame script 2024-12-13 11:49:14 -08:00
Paul Gauthier
cd79f479e9 copy 2024-12-13 11:48:14 -08:00
Paul Gauthier
12c0f675ce copy 2024-12-13 11:46:44 -08:00
Paul Gauthier
29471b8019 set version to 0.69.1.dev 2024-12-13 11:42:00 -08:00
Paul Gauthier
cad661f0c8 version bump to 0.69.0 2024-12-13 11:40:25 -08:00
Paul Gauthier
261d770482 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-13 11:39:41 -08:00
Paul Gauthier
a75c9c74fd copy 2024-12-13 11:39:37 -08:00
paul-gauthier
8b5bdf9a16 Merge pull request #2623 from damms005/patch-1
Update conventions.md to fix url
2024-12-13 10:42:54 -08:00
Damilola Emmanuel Olowookere
e35eba2d51 Update conventions.md to fix url 2024-12-13 18:36:10 +00:00
Paul Gauthier (aider)
df8c88cef4 style: Fix line length in issues.py 2024-12-13 08:46:57 -08:00
Paul Gauthier (aider)
844e12769c feat: Handle "bug" label like "enhancement" for closing 2024-12-13 08:46:53 -08:00
Paul Gauthier (aider)
b982626ac4 style: Fix line length in comment 2024-12-13 08:46:02 -08:00
Paul Gauthier (aider)
517b2b42a6 fix: Fix long lines in closing comment 2024-12-13 08:45:58 -08:00
Paul Gauthier (aider)
6778c33628 style: Apply linter fixes 2024-12-13 08:45:47 -08:00
Paul Gauthier (aider)
bc0b11e1ef feat: Add fixed enhancement issue closing 2024-12-13 08:45:43 -08:00
Paul Gauthier
6b0d4b9c93 copy 2024-12-13 08:23:42 -08:00
Paul Gauthier
7d4e4f029e copy 2024-12-13 08:13:36 -08:00
Paul Gauthier
1fbdb629ff add gemini-2.0-flash-exp metadata 2024-12-13 08:12:06 -08:00
Paul Gauthier
a437237947 copy 2024-12-13 07:37:15 -08:00
Paul Gauthier
910637c549 5% analytics 2024-12-13 06:51:50 -08:00
Paul Gauthier
e8974a3e69 copy 2024-12-12 19:08:21 -08:00
Paul Gauthier
6c98310f7f copy 2024-12-12 19:08:16 -08:00
Paul Gauthier
72aed0d26d fix: Disable complete_while_typing in prompt_session 2024-12-12 12:27:14 -08:00
Paul Gauthier
e10ef8b9e0 feat: Add instructions to /copy-context command 2024-12-12 12:08:29 -08:00
Paul Gauthier
39fa8ba831 copy 2024-12-12 07:54:54 -08:00
Paul Gauthier (aider)
8ee8279044 fix: Correct emacs auto-save gitignore pattern 2024-12-11 20:44:02 -08:00
Paul Gauthier (aider)
c3f85c3bb2 test: Fix gitignore pattern matching and add ai comment test 2024-12-11 20:43:07 -08:00
Paul Gauthier (aider)
ad59c4cbf3 test: Add comprehensive gitignore pattern tests 2024-12-11 20:43:03 -08:00
Paul Gauthier
26bc981981 chore: Add comment about testing gitignore patterns 2024-12-11 20:43:02 -08:00
Paul Gauthier
514c34b242 copy 2024-12-11 20:41:24 -08:00
Paul Gauthier (aider)
6f266c0090 fix: Skip test fixture watch files in blame script 2024-12-11 20:38:11 -08:00
Paul Gauthier
baa7352ca6 chore: Skip test fixture files in blame script 2024-12-11 20:38:11 -08:00
Paul Gauthier (aider)
fdb1c8d99a chore: Remove comment about skipping test files 2024-12-11 20:37:29 -08:00
Paul Gauthier
79f5dba094 chore: Skip test fixture files in blame script 2024-12-11 20:37:28 -08:00
Paul Gauthier
2134965f16 initial 2024-12-11 20:34:00 -08:00
Paul Gauthier
77b7a59a27 copy 2024-12-11 20:33:30 -08:00
Paul Gauthier
365e7126d0 refactor: Remove is_source_file function and check in FileWatcher 2024-12-11 20:30:47 -08:00
Paul Gauthier (aider)
d3daf9d159 feat: Add IDE, env, log, and cache patterns to ignore list 2024-12-11 20:30:17 -08:00
Paul Gauthier
8d59a519a6 chore: Add comment about gitignore patterns 2024-12-11 20:29:28 -08:00
Paul Gauthier (aider)
239262f360 style: Format gitignore patterns for readability 2024-12-11 20:28:07 -08:00
Paul Gauthier (aider)
9eb938fd6f feat: Expand gitignore patterns to include editor temp files 2024-12-11 20:28:03 -08:00
Paul Gauthier
3fcbf1a43f feat: Add text editor temp files to gitignore 2024-12-11 20:28:02 -08:00
Paul Gauthier
2b7ee271df copy 2024-12-11 20:24:08 -08:00
Paul Gauthier
11512c6281 feat: Add support for ! and ? action comments 2024-12-11 20:23:29 -08:00
Paul Gauthier (aider)
b16ba547ab test: Add assertion for line count in test_ai_comment_pattern 2024-12-11 20:21:50 -08:00
Paul Gauthier (aider)
e5b8899b4c fix: Remove extra comment in test_watch.py 2024-12-11 20:21:46 -08:00
Paul Gauthier (aider)
fee3e9e63b feat: Add test for watch_question.js fixture 2024-12-11 20:21:42 -08:00
Paul Gauthier
57a24d30b5 test: Add test for watch_question.js ai comments 2024-12-11 20:21:41 -08:00
Paul Gauthier (aider)
5a83610fb1 refactor: Update ai comment action handling to support '?' 2024-12-11 20:16:10 -08:00
Paul Gauthier
96086f12c6 fix: Correct ai comment regex to match ai? and ai! 2024-12-11 20:16:09 -08:00
Paul Gauthier
a6ee3ce07f cleanup 2024-12-11 20:12:26 -08:00
Paul Gauthier (aider)
5f36ddd425 test: Fix multiline mode tests and add toggle test 2024-12-11 20:10:30 -08:00
Paul Gauthier (aider)
bec67074e0 feat: Add tests for multiline input mode 2024-12-11 20:10:26 -08:00
Paul Gauthier (aider)
895c92cdae fix: Remove unused import buffer_has_focus 2024-12-11 20:05:04 -08:00
Paul Gauthier
7406a5bc26 refactor: Move is_searching filter to top level 2024-12-11 20:05:01 -08:00
Paul Gauthier (aider)
ef97714404 fix: Reorder imports to satisfy linter 2024-12-11 20:00:00 -08:00
Paul Gauthier (aider)
6d6daee511 fix: Use correct filter for custom enter keybinding 2024-12-11 19:59:56 -08:00
Paul Gauthier (aider)
32cd1c2a65 fix: Fix Ctrl-R reverse search enter key selection 2024-12-11 19:55:08 -08:00
Paul Gauthier
abad920a8a feat: Add gemini-2.0-flash-exp model settings 2024-12-11 19:47:44 -08:00
Paul Gauthier
e1ab49e100 copy 2024-12-11 19:43:31 -08:00
Paul Gauthier
df300e89a2 refac prompt out 2024-12-11 19:42:01 -08:00
Paul Gauthier
9a278bed21 feat: Add gemini flash model alias 2024-12-11 16:00:31 -08:00
Paul Gauthier
4a7fc084ce refactor: move watch prompt text to separate module 2024-12-11 15:07:30 -08:00
Paul Gauthier
2649e736fb chore: update model name in leaderboard to include date 2024-12-11 15:00:18 -08:00
Paul Gauthier
42ac891e28 docs: add bash syntax highlighting to code blocks in docs 2024-12-11 14:49:22 -08:00
Paul Gauthier
4dc3b9072e feat: increase retry timeout for benchmarking 2024-12-11 14:26:28 -08:00
Paul Gauthier
ae3235b099 feat: add Gemini 2.0 Flash model leaderboard entry 2024-12-11 13:55:52 -08:00
Paul Gauthier
7cc5e0d577 docs: add Yi Lightning model test results to leaderboard 2024-12-11 13:54:39 -08:00
Paul Gauthier
f6b956dc8e refactor: simplify voice command and improve installation docs 2024-12-11 13:52:33 -08:00
Paul Gauthier (aider)
fcb2bacd1e style: format benchmark.py with black 2024-12-11 13:09:52 -08:00
Paul Gauthier (aider)
a9401e921e feat: add sleep option between tests in single-threaded mode 2024-12-11 13:09:45 -08:00
Paul Gauthier
02e7e315b2 copy 2024-12-11 12:54:50 -08:00
Paul Gauthier
def72a64e0 copy 2024-12-11 12:45:56 -08:00
Paul Gauthier
46e7672197 copy 2024-12-11 12:42:19 -08:00
Paul Gauthier
2f8a5ce935 copy 2024-12-11 12:40:13 -08:00
Paul Gauthier (aider)
730e5bd831 fix: add error handling for clipboard operations in copy_context command 2024-12-11 12:10:12 -08:00
Paul Gauthier
b7984a05af copy 2024-12-11 09:51:51 -08:00
Paul Gauthier
5d4af67186 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-11 07:21:18 -08:00
paul-gauthier
370e08cf4d Merge pull request #2601 from miradnanali/multiline-mode
Implement /multiline-mode, swaps Enter & Meta-Enter
2024-12-11 07:21:09 -08:00
Mir Adnan ALI
aaf7e3f943 Implement multiline-mode, swaps Enter & Meta-Enter 2024-12-11 09:09:58 -05:00
Paul Gauthier
fbde0936e7 revert 2024-12-10 11:20:25 -08:00
Paul Gauthier (aider)
af48f7bab4 fix: update artifact upload path to match Jekyll build directory 2024-12-10 11:12:23 -08:00
Paul Gauthier
61def89878 ci: downgrade upload-pages-artifact action to v3 2024-12-10 11:07:42 -08:00
Paul Gauthier (aider)
88e86cee77 chore: upgrade upload-pages-artifact action to v4 2024-12-10 11:04:46 -08:00
Paul Gauthier
acc1625406 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-10 11:03:20 -08:00
Paul Gauthier
502f448053 copy 2024-12-10 09:59:56 -08:00
paul-gauthier
55b081884c Merge pull request #2592 from JeongJuhyeon/patch-1
Add '?' to set of punctuations to strip for file mentions
2024-12-10 08:41:38 -08:00
Paul Gauthier
fd67171908 copy 2024-12-10 08:21:28 -08:00
JeongJuhyeon
3f63a64254 Add '?' to set of punctuations to strip for file mentions 2024-12-10 22:10:00 +09:00
118 changed files with 7755 additions and 2228 deletions

View File

@@ -15,12 +15,9 @@ on:
branches:
- main
# copy most of these steps from release.yml, but push: false and no tags:
jobs:
build:
docker_build_and_push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -29,24 +26,32 @@ jobs:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker standard image
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Build and push Docker images
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile
platforms: linux/amd64,linux/arm64
push: false
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/aider:dev
target: aider
- name: Build Docker full image
- name: Build and push Docker full image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile
platforms: linux/amd64,linux/arm64
push: false
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/aider-full:dev
target: aider-full

1
.gitignore vendored
View File

@@ -15,3 +15,4 @@ aider/_version.py
.venv/
.#*
.gitattributes
tmp.benchmarks/

View File

@@ -56,13 +56,6 @@ It is recommended to create a virtual environment outside of the repository to k
python -m venv /path/to/venv
```
#### Using `virtualenv` (for older Python versions)
```
pip install virtualenv
virtualenv /path/to/venv
```
### Activate the Virtual Environment
#### On Windows

View File

@@ -1,6 +1,73 @@
# Release history
### main branch
### Aider v0.71.1
- Fix permissions issue in Docker images.
- Added read-only file announcements to chat.
- Bugfix: ASCII fallback for unicode errors.
- Bugfix: integer indices for list slicing in repomap calculations.
- Aider wrote 83% of the code in this release.
### Aider v0.71.0
- Prompts to help DeepSeek work better when alternating between `/ask` and `/code`.
- Streaming pretty LLM responses is smoother and faster for long replies.
- Streaming automatically turns of for model that don't support it
- Can now switch to/from `/model o1` and a streaming model
- Pretty output remains enabled even when editing files with triple-backtick fences
- Bare `/ask`, `/code` and `/architect` commands now switch the chat mode.
- Increased default size of the repomap.
- Increased max chat history tokens limit from 4k to 8k.
- Turn off fancy input and watch files if terminal is dumb.
- Added support for custom voice format and input device settings.
- Disabled Streamlit email prompt, by apaz-cli.
- Docker container runs as non-root user.
- Fixed lint command handling of nested spaced strings, by Aaron Weisberg.
- Added token count feedback when adding command output to chat.
- Improved error handling for large audio files with automatic format conversion.
- Improved handling of git repo index errors, by Krazer.
- Improved unicode handling in console output with ASCII fallback.
- Added AssertionError, AttributeError to git error handling.
- Aider wrote 60% of the code in this release.
### Aider v0.70.0
- Full support for o1 models.
- Watch files now honors `--subtree-only`, and only watches that subtree.
- Improved prompting for watch files, to work more reliably with more models.
- New install methods via uv, including one-liners.
- Support for openrouter/deepseek/deepseek-chat model.
- Better error handling when interactive commands are attempted via `/load` or `--load`.
- Display read-only files with abs path if its shorter than rel path.
- Ask 10% of users to opt-in to analytics.
- Bugfix for auto-suggest.
- Gracefully handle unicode errors in git path names.
- Aider wrote 74% of the code in this release.
### Aider v0.69.1
- Fix for gemini model names in model metadata.
- Show hints about AI! and AI? when user makes AI comments.
- Support for running without git installed.
- Improved environment variable setup messages on Windows.
### Aider v0.69.0
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
- Now watches *all* files, not just certain source files.
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
- Full support for Gemini Flash 2.0 Exp:
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
- Improved clipboard error handling with helpful requirements install info.
- Ask 5% of users if they want to opt-in to analytics.
- `/voice` now lets you edit the transcribed text before sending.
- Disabled auto-complete in Y/N prompts.
- Aider wrote 68% of the code in this release.
### Aider v0.68.0
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
- New `--copy-paste` mode.

20
MANIFEST.in Normal file
View File

@@ -0,0 +1,20 @@
# This needs to sync with aider/help_pats.py
global-exclude .DS_Store
recursive-exclude aider/website/examples *
recursive-exclude aider/website/_posts *
exclude aider/website/HISTORY.md
exclude aider/website/docs/benchmarks*.md
exclude aider/website/docs/ctags.md
exclude aider/website/docs/unified-diffs.md
exclude aider/website/install.ps1
exclude aider/website/install.sh
recursive-exclude aider/website/docs/leaderboards *
recursive-exclude aider/website/assets *
recursive-exclude aider/website *.js
recursive-exclude aider/website *.html
recursive-exclude aider/website *.yml

View File

@@ -5,9 +5,9 @@
Aider lets you pair program with LLMs,
to edit code in your local git repository.
Start a new project or work with an existing git repo.
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
[connect to almost any LLM](https://aider.chat/docs/llms.html).
Start a new project or work with an existing code base.
Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
<!-- SCREENCAST START -->
<p align="center">
@@ -43,28 +43,27 @@ VIDEO END -->
cog.out(open("aider/website/_includes/get-started.md").read())
]]]-->
You can get started quickly like this:
If you already have python 3.8-3.13 installed, you can get started quickly like this:
```
python -m pip install -U aider-chat
```bash
python -m pip install aider-install
aider-install
# Change directory into a git repo
cd /to/your/git/repo
# Change directory into your code base
cd /to/your/project
# Work with Claude 3.5 Sonnet on your repo
export ANTHROPIC_API_KEY=your-key-goes-here
aider
# Work with Claude 3.5 Sonnet on your code
aider --model sonnet --anthropic-api-key your-key-goes-here
# Work with GPT-4o on your repo
export OPENAI_API_KEY=your-key-goes-here
aider
# Work with GPT-4o on your code
aider --model gpt-4o --openai-api-key your-key-goes-here
```
<!--[[[end]]]-->
See the
[installation instructions](https://aider.chat/docs/install.html)
and other
[documentation](https://aider.chat/docs/usage.html)
and
[usage documentation](https://aider.chat/docs/usage.html)
for more details.
## Features
@@ -78,16 +77,17 @@ for more details.
- Update docs.
- Aider will edit your files to complete your request.
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
- [Use aider inside your favorite editor or IDE](https://aider.chat/docs/usage/watch.html).
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
- Aider works best with GPT-4o & Claude 3.5 Sonnet and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
- Aider can edit multiple files at once for complex requests.
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
- Edit files in your editor while chatting with aider,
- Edit files in your editor or IDE while chatting with aider,
and it will always use the latest version.
Pair program with AI.
- [Add images to the chat](https://aider.chat/docs/usage/images-urls.html) (GPT-4o, Claude 3.5 Sonnet, etc).
- [Add URLs to the chat](https://aider.chat/docs/usage/images-urls.html) and aider will read their content.
- [Code with your voice](https://aider.chat/docs/usage/voice.html).
- Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
## Top tier performance

View File

@@ -1,6 +1,6 @@
from packaging import version
__version__ = "0.68.1.dev"
__version__ = "0.71.2.dev"
safe_version = __version__
try:

View File

@@ -12,6 +12,46 @@ from aider import __version__
from aider.dump import dump # noqa: F401
from aider.models import model_info_manager
PERCENT = 10
def compute_hex_threshold(percent):
"""Convert percentage to 6-digit hex threshold.
Args:
percent: Percentage threshold (0-100)
Returns:
str: 6-digit hex threshold
"""
return format(int(0xFFFFFF * percent / 100), "06x")
def is_uuid_in_percentage(uuid_str, percent):
"""Check if a UUID string falls within the first X percent of the UUID space.
Args:
uuid_str: UUID string to test
percent: Percentage threshold (0-100)
Returns:
bool: True if UUID falls within the first X percent
"""
if not (0 <= percent <= 100):
raise ValueError("Percentage must be between 0 and 100")
if not uuid_str:
return False
# Convert percentage to hex threshold (1% = "04...", 10% = "1a...", etc)
# Using first 6 hex digits
if percent == 0:
return False
threshold = compute_hex_threshold(percent)
return uuid_str[:6] <= threshold
mixpanel_project_token = "6da9a43058a5d1b9f3353153921fb04d"
posthog_project_api_key = "phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv"
posthog_host = "https://us.i.posthog.com"
@@ -84,31 +124,7 @@ class Analytics:
if not self.user_id:
return False
PERCENT = 2.5
return self.is_uuid_in_percentage(self.user_id, PERCENT)
def is_uuid_in_percentage(self, uuid_str, percent):
"""Check if a UUID string falls within the first X percent of the UUID space.
Args:
uuid_str: UUID string to test
percent: Percentage threshold (0-100)
Returns:
bool: True if UUID falls within the first X percent
"""
if not (0 <= percent <= 100):
raise ValueError("Percentage must be between 0 and 100")
if not uuid_str:
return False
# Convert percentage to hex threshold (1% = "04...", 10% = "1a...", etc)
# Using first 6 hex digits
if percent == 0:
return False
threshold = format(int(0xFFFFFF * percent / 100), "06x")
return uuid_str[:6] <= threshold
return is_uuid_in_percentage(self.user_id, PERCENT)
def get_data_file_path(self):
try:
@@ -181,6 +197,7 @@ class Analytics:
def posthog_error(self):
"""disable posthog if we get an error"""
print("X" * 100)
# https://github.com/PostHog/posthog-python/blob/9e1bb8c58afaa229da24c4fb576c08bb88a75752/posthog/consumer.py#L86
# https://github.com/Aider-AI/aider/issues/2532
self.ph = None
@@ -227,3 +244,7 @@ class Analytics:
f.write("\n")
except OSError:
pass # Ignore OS errors when writing to logfile
if __name__ == "__main__":
dump(compute_hex_threshold(PERCENT))

View File

@@ -106,7 +106,7 @@ def get_parser(default_config_files, git_root):
const=gpt_3_model_name,
help=f"Use {gpt_3_model_name} model for the main chat",
)
deepseek_model = "deepseek/deepseek-coder"
deepseek_model = "deepseek/deepseek-chat"
group.add_argument(
"--deepseek",
action="store_const",
@@ -287,7 +287,7 @@ def get_parser(default_config_files, git_root):
"--map-tokens",
type=int,
default=None,
help="Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)",
help="Suggested number of tokens to use for repo map, use 0 to disable",
)
group.add_argument(
"--map-refresh",
@@ -427,7 +427,8 @@ def get_parser(default_config_files, git_root):
default="default",
help=(
"Set the markdown code theme (default: default, other options include monokai,"
" solarized-dark, solarized-light)"
" solarized-dark, solarized-light, or a Pygments builtin style,"
" see https://pygments.org/styles for available themes)"
),
)
group.add_argument(
@@ -795,6 +796,12 @@ def get_parser(default_config_files, git_root):
default=True,
help="Enable/disable fancy input with history and completion (default: True)",
)
group.add_argument(
"--multiline",
action=argparse.BooleanOptionalAction,
default=False,
help="Enable/disable multi-line input mode with Meta-Enter to submit (default: False)",
)
group.add_argument(
"--detect-urls",
action=argparse.BooleanOptionalAction,

View File

@@ -7,6 +7,8 @@ class AskPrompts(CoderPrompts):
main_system = """Act as an expert code analyst.
Answer questions about the supplied code.
Always reply to the user in {language}.
Describe code changes however you like. Don't use SEARCH/REPLACE blocks!
"""
example_messages = []

View File

@@ -59,7 +59,8 @@ def wrap_fence(name):
all_fences = [
("``" + "`", "``" + "`"),
("`" * 3, "`" * 3),
("`" * 4, "`" * 4),
wrap_fence("source"),
wrap_fence("code"),
wrap_fence("pre"),
@@ -230,10 +231,10 @@ class Coder:
if map_tokens > 0:
refresh = self.repo_map.refresh
lines.append(f"Repo-map: using {map_tokens} tokens, {refresh} refresh")
max_map_tokens = 2048
max_map_tokens = self.main_model.get_repo_map_tokens() * 2
if map_tokens > max_map_tokens:
lines.append(
f"Warning: map-tokens > {max_map_tokens} is not recommended as too much"
f"Warning: map-tokens > {max_map_tokens} is not recommended. Too much"
" irrelevant code can confuse LLMs."
)
else:
@@ -245,9 +246,16 @@ class Coder:
for fname in self.get_inchat_relative_files():
lines.append(f"Added {fname} to the chat.")
for fname in self.abs_read_only_fnames:
rel_fname = self.get_rel_fname(fname)
lines.append(f"Added {rel_fname} to the chat (read-only).")
if self.done_messages:
lines.append("Restored previous conversation history.")
if self.io.multiline_mode:
lines.append("Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text")
return lines
def __init__(
@@ -345,7 +353,6 @@ class Coder:
self.done_messages = []
self.io = io
self.stream = stream
self.shell_commands = []
@@ -360,6 +367,8 @@ class Coder:
self.main_model = main_model
self.stream = stream and main_model.streaming
if cache_prompts and self.main_model.cache_control:
self.add_cache_headers = True
@@ -516,7 +525,7 @@ class Coder:
return False
# only show pretty output if fences are the normal triple-backtick
if self.fence != self.fences[0]:
if self.fence[0][0] != "`":
return False
return True
@@ -610,9 +619,19 @@ class Coder:
def get_ident_filename_matches(self, idents):
all_fnames = defaultdict(set)
for fname in self.get_all_relative_files():
base = Path(fname).with_suffix("").name.lower()
if len(base) >= 5:
all_fnames[base].add(fname)
# Skip empty paths or just '.'
if not fname or fname == ".":
continue
try:
# Handle dotfiles properly
path = Path(fname)
base = path.stem.lower() # Use stem instead of with_suffix("").name
if len(base) >= 5:
all_fnames[base].add(fname)
except ValueError:
# Skip paths that can't be processed
continue
matches = set()
for ident in idents:
@@ -1471,7 +1490,7 @@ class Coder:
words = set(word for word in content.split())
# drop sentence punctuation from the end
words = set(word.rstrip(",.!;:") for word in words)
words = set(word.rstrip(",.!;:?") for word in words)
# strip away all kinds of quotes
quotes = "".join(['"', "'", "`"])

View File

@@ -183,6 +183,9 @@ If you want to put code in a new file, use a *SEARCH/REPLACE block* with:
To rename files which have been added to the chat, use shell commands at the end of your response.
If the user just says something like "ok" or "go ahead" or "do that" they probably want you to make SEARCH/REPLACE blocks for the code changes you just proposed.
The user will say when they've applied your edits. If they haven't explicitly confirmed the edits have been applied, they probably want proper SEARCH/REPLACE blocks.
{lazy_prompt}
ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
{shell_cmd_reminder}

View File

@@ -3,7 +3,11 @@
import sys
from pathlib import Path
import git
try:
import git
except ImportError:
git = None
from diff_match_patch import diff_match_patch
from tqdm import tqdm

View File

@@ -52,6 +52,8 @@ class Commands:
io,
coder,
voice_language=None,
voice_input_device=None,
voice_format=None,
verify_ssl=True,
args=None,
parser=None,
@@ -69,6 +71,8 @@ class Commands:
voice_language = None
self.voice_language = voice_language
self.voice_format = voice_format
self.voice_input_device = voice_input_device
self.help = None
self.editor = editor
@@ -914,10 +918,14 @@ class Commands:
if combined_output is None:
return
# Calculate token count of output
token_count = self.coder.main_model.token_count(combined_output)
k_tokens = token_count / 1000
if add_on_nonzero_exit:
add = exit_status != 0
else:
add = self.io.confirm_ask("Add command output to the chat?")
add = self.io.confirm_ask(f"Add {k_tokens:.1f}k tokens of command output to the chat?")
if add:
num_lines = len(combined_output.strip().splitlines())
@@ -935,7 +943,7 @@ class Commands:
]
if add and exit_status != 0:
self.io.placeholder = "Fix that"
self.io.placeholder = "What's wrong? Fix"
def cmd_exit(self, args):
"Exit the application"
@@ -1009,7 +1017,7 @@ class Commands:
return
self.coder.event("interactive help")
from aider.coders import Coder
from aider.coders.base_coder import Coder
if not self.help:
res = install_help_extra(self.io)
@@ -1053,23 +1061,23 @@ class Commands:
)
def cmd_ask(self, args):
"Ask questions about the code base without editing any files"
"""Ask questions about the code base without editing any files. If no prompt provided, switches to ask mode.""" # noqa
return self._generic_chat_command(args, "ask")
def cmd_code(self, args):
"Ask for changes to your code"
"""Ask for changes to your code. If no prompt provided, switches to code mode.""" # noqa
return self._generic_chat_command(args, self.coder.main_model.edit_format)
def cmd_architect(self, args):
"Enter architect mode to discuss high-level design and architecture"
"""Enter architect mode to discuss high-level design and architecture. If no prompt provided, switches to architect mode.""" # noqa
return self._generic_chat_command(args, "architect")
def _generic_chat_command(self, args, edit_format):
if not args.strip():
self.io.tool_error(f"Please provide a question or topic for the {edit_format} chat.")
return
# Switch to the corresponding chat mode if no args provided
return self.cmd_chat_mode(edit_format)
from aider.coders import Coder
from aider.coders.base_coder import Coder
coder = Coder.create(
io=self.io,
@@ -1117,7 +1125,7 @@ class Commands:
return
try:
self.voice = voice.Voice(
audio_format=self.args.voice_format, device_name=self.args.voice_input_device
audio_format=self.voice_format or "wav", device_name=self.voice_input_device
)
except voice.SoundDeviceError:
self.io.tool_error(
@@ -1125,36 +1133,14 @@ class Commands:
)
return
history_iter = self.io.get_input_history()
history = []
size = 0
for line in history_iter:
if line.startswith("/"):
continue
if line in history:
continue
if size + len(line) > 1024:
break
size += len(line)
history.append(line)
history.reverse()
history = "\n".join(history)
try:
text = self.voice.record_and_transcribe(history, language=self.voice_language)
text = self.voice.record_and_transcribe(None, language=self.voice_language)
except litellm.OpenAIError as err:
self.io.tool_error(f"Unable to use OpenAI whisper model: {err}")
return
if text:
self.io.add_to_input_history(text)
self.io.print()
self.io.user_input(text, log_only=False)
self.io.print()
return text
self.io.placeholder = text
def cmd_paste(self, args):
"""Paste image/text from the clipboard into the chat.\
@@ -1331,7 +1317,12 @@ class Commands:
continue
self.io.tool_output(f"\nExecuting: {cmd}")
self.run(cmd)
try:
self.run(cmd)
except SwitchCoder:
self.io.tool_error(
f"Command '{cmd}' is only supported in interactive mode, skipping."
)
def completions_raw_save(self, document, complete_event):
return self.completions_raw_read_only(document, complete_event)
@@ -1363,6 +1354,10 @@ class Commands:
except Exception as e:
self.io.tool_error(f"Error saving commands to file: {e}")
def cmd_multiline_mode(self, args):
"Toggle multiline mode (swaps behavior of Enter and Meta+Enter)"
self.io.toggle_multiline_mode()
def cmd_copy(self, args):
"Copy the last assistant message to the clipboard"
all_messages = self.coder.done_messages + self.coder.cur_messages
@@ -1435,16 +1430,25 @@ class Commands:
else:
markdown += content + "\n\n"
markdown += """
args = args or ""
markdown += f"""
Just tell me how to edit the files to make the changes.
Don't give me back entire files.
Just show me the edits I need to make.
{args}
"""
pyperclip.copy(markdown)
self.io.tool_output("Copied code context to clipboard.")
try:
pyperclip.copy(markdown)
self.io.tool_output("Copied code context to clipboard.")
except pyperclip.PyperclipException as e:
self.io.tool_error(f"Failed to copy to clipboard: {str(e)}")
self.io.tool_output(
"You may need to install xclip or xsel on Linux, or pbcopy on macOS."
)
except Exception as e:
self.io.tool_error(f"An unexpected error occurred while copying to clipboard: {str(e)}")
def expand_subdir(file_path):

View File

@@ -1,4 +1,7 @@
# This needs to sync with MANIFEST.in
exclude_website_pats = [
"**/.DS_Store",
"examples/**",
"_posts/**",
"HISTORY.md",
@@ -7,5 +10,4 @@ exclude_website_pats = [
"docs/unified-diffs.md",
"docs/leaderboards/index.md",
"assets/**",
"**/.DS_Store",
]

View File

@@ -12,11 +12,12 @@ from pathlib import Path
from prompt_toolkit.completion import Completer, Completion, ThreadedCompleter
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
from prompt_toolkit.enums import EditingMode
from prompt_toolkit.filters import Condition
from prompt_toolkit.filters import Condition, is_searching
from prompt_toolkit.history import FileHistory
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.keys import Keys
from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.output.vt100 import is_dumb_terminal
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
from prompt_toolkit.styles import Style
from pygments.lexers import MarkdownLexer, guess_lexer_for_filename
@@ -202,11 +203,14 @@ class InputOutput:
editingmode=EditingMode.EMACS,
fancy_input=True,
file_watcher=None,
multiline_mode=False,
root=".",
):
self.placeholder = None
self.interrupted = False
self.never_prompts = set()
self.editingmode = editingmode
self.multiline_mode = multiline_mode
no_color = os.environ.get("NO_COLOR")
if no_color is not None and no_color != "":
pretty = False
@@ -246,8 +250,14 @@ class InputOutput:
self.append_chat_history(f"\n# aider chat started at {current_time}\n\n")
self.prompt_session = None
self.is_dumb_terminal = is_dumb_terminal()
if self.is_dumb_terminal:
self.pretty = False
fancy_input = False
if fancy_input:
# Initialize PromptSession
# Initialize PromptSession only if we have a capable terminal
session_kwargs = {
"input": self.input,
"output": self.output,
@@ -266,8 +276,11 @@ class InputOutput:
self.tool_error(f"Can't initialize prompt toolkit: {err}") # non-pretty
else:
self.console = Console(force_terminal=False, no_color=True) # non-pretty
if self.is_dumb_terminal:
self.tool_output("Detected dumb terminal, disabling fancy input and pretty output.")
self.file_watcher = file_watcher
self.root = root
def _get_style(self):
style_dict = {}
@@ -412,6 +425,8 @@ class InputOutput:
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
if edit_format:
show += edit_format
if self.multiline_mode:
show += (" " if edit_format else "") + "multi"
show += "> "
inp = ""
@@ -456,9 +471,25 @@ class InputOutput:
"Navigate forward through history"
event.current_buffer.history_forward()
@kb.add("escape", "c-m", eager=True)
@kb.add("enter", eager=True, filter=~is_searching)
def _(event):
event.current_buffer.insert_text("\n")
"Handle Enter key press"
if self.multiline_mode:
# In multiline mode, Enter adds a newline
event.current_buffer.insert_text("\n")
else:
# In normal mode, Enter submits
event.current_buffer.validate_and_handle()
@kb.add("escape", "enter", eager=True, filter=~is_searching) # This is Alt+Enter
def _(event):
"Handle Alt+Enter key press"
if self.multiline_mode:
# In multiline mode, Alt+Enter submits
event.current_buffer.validate_and_handle()
else:
# In normal mode, Alt+Enter adds a newline
event.current_buffer.insert_text("\n")
while True:
if multiline_input:
@@ -485,6 +516,7 @@ class InputOutput:
complete_style=CompleteStyle.MULTI_COLUMN,
style=style,
key_bindings=kb,
complete_while_typing=True,
)
else:
line = input(show)
@@ -629,6 +661,9 @@ class InputOutput:
group=None,
allow_never=False,
):
# Temporarily disable multiline mode for yes/no prompts
orig_multiline = self.multiline_mode
self.multiline_mode = False
self.num_user_asks += 1
question_id = (question, subject)
@@ -686,6 +721,7 @@ class InputOutput:
res = self.prompt_session.prompt(
question,
style=style,
complete_while_typing=False,
)
else:
res = input(question)
@@ -726,9 +762,15 @@ class InputOutput:
hist = f"{question.strip()} {res}"
self.append_chat_history(hist, linebreak=True, blockquote=True)
# Restore original multiline mode
self.multiline_mode = orig_multiline
return is_yes
def prompt_ask(self, question, default="", subject=None):
# Temporarily disable multiline mode for prompts
orig_multiline = self.multiline_mode
self.multiline_mode = False
self.num_user_asks += 1
if subject:
@@ -743,7 +785,12 @@ class InputOutput:
res = "no"
else:
if self.prompt_session:
res = self.prompt_session.prompt(question + " ", default=default, style=style)
res = self.prompt_session.prompt(
question + " ",
default=default,
style=style,
complete_while_typing=True,
)
else:
res = input(question + " ")
@@ -752,6 +799,9 @@ class InputOutput:
if self.yes in (True, False):
self.tool_output(hist)
# Restore original multiline mode
self.multiline_mode = orig_multiline
return res
def _tool_message(self, message="", strip=True, color=None):
@@ -763,9 +813,17 @@ class InputOutput:
hist = message.strip() if strip else message
self.append_chat_history(hist, linebreak=True, blockquote=True)
message = Text(message)
if not isinstance(message, Text):
message = Text(message)
style = dict(style=color) if self.pretty and color else dict()
self.console.print(message, **style)
try:
self.console.print(message, **style)
except UnicodeEncodeError:
# Fallback to ASCII-safe output
if isinstance(message, Text):
message = message.plain
message = str(message).encode("ascii", errors="replace").decode("ascii")
self.console.print(message, **style)
def tool_error(self, message="", strip=True):
self.num_error_outputs += 1
@@ -821,6 +879,18 @@ class InputOutput:
def print(self, message=""):
print(message)
def toggle_multiline_mode(self):
"""Toggle between normal and multiline input modes"""
self.multiline_mode = not self.multiline_mode
if self.multiline_mode:
self.tool_output(
"Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text"
)
else:
self.tool_output(
"Multiline mode: Disabled. Alt-Enter inserts newline, Enter submits text"
)
def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True):
if blockquote:
if strip:
@@ -862,7 +932,13 @@ class InputOutput:
editable_files = [f for f in sorted(rel_fnames) if f not in rel_read_only_fnames]
if read_only_files:
files_with_label = ["Readonly:"] + read_only_files
# Use shorter of abs/rel paths for readonly files
ro_paths = []
for rel_path in read_only_files:
abs_path = os.path.abspath(os.path.join(self.root, rel_path))
ro_paths.append(abs_path if len(abs_path) < len(rel_path) else rel_path)
files_with_label = ["Readonly:"] + ro_paths
read_only_output = StringIO()
Console(file=read_only_output, force_terminal=False).print(Columns(files_with_label))
read_only_lines = read_only_output.getvalue().splitlines()

View File

@@ -11,6 +11,7 @@ from grep_ast import TreeContext, filename_to_lang
from tree_sitter_languages import get_parser # noqa: E402
from aider.dump import dump # noqa: F401
from aider.run_cmd import run_cmd_subprocess # noqa: F401
# tree_sitter is throwing a FutureWarning
warnings.simplefilter("ignore", category=FutureWarning)
@@ -44,26 +45,22 @@ class Linter:
def run_cmd(self, cmd, rel_fname, code):
cmd += " " + rel_fname
cmd = cmd.split()
returncode = 0
stdout = ""
try:
process = subprocess.Popen(
returncode, stdout = run_cmd_subprocess(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding=self.encoding,
errors="replace",
cwd=self.root,
encoding=self.encoding,
)
except OSError as err:
print(f"Unable to execute lint command: {err}")
return
stdout, _ = process.communicate()
errors = stdout
if process.returncode == 0:
if returncode == 0:
return # zero exit status
cmd = " ".join(cmd)
res = f"## Running: {cmd}\n\n"
res += errors

View File

@@ -9,7 +9,11 @@ import webbrowser
from dataclasses import fields
from pathlib import Path
import git
try:
import git
except ImportError:
git = None
import importlib_resources
from dotenv import load_dotenv
from prompt_toolkit.enums import EditingMode
@@ -93,6 +97,9 @@ def make_new_repo(git_root, io):
def setup_git(git_root, io):
if git is None:
return
try:
cwd = Path.cwd()
except OSError:
@@ -106,7 +113,9 @@ def setup_git(git_root, io):
except ANY_GIT_ERROR:
pass
elif cwd == Path.home():
io.tool_warning("You should probably run aider in a directory, not your home dir.")
io.tool_warning(
"You should probably run aider in your project's directory, not your home dir."
)
return
elif cwd and io.confirm_ask(
"No git repo found, create one to track aider's changes (recommended)?"
@@ -166,7 +175,8 @@ def check_gitignore(git_root, io, ask=True):
existing_lines = content.splitlines()
for pat in patterns:
if pat not in existing_lines:
patterns_to_add.append(pat)
if "*" in pat or (Path(git_root) / pat).exists():
patterns_to_add.append(pat)
except OSError as e:
io.tool_error(f"Error when trying to read {gitignore_file}: {e}")
return
@@ -205,6 +215,22 @@ def check_streamlit_install(io):
)
def write_streamlit_credentials():
from streamlit.file_util import get_streamlit_file_path
# See https://github.com/Aider-AI/aider/issues/772
credential_path = Path(get_streamlit_file_path()) / "credentials.toml"
if not os.path.exists(credential_path):
empty_creds = '[general]\nemail = ""\n'
os.makedirs(os.path.dirname(credential_path), exist_ok=True)
with open(credential_path, "w") as f:
f.write(empty_creds)
else:
print("Streamlit credentials already exist.")
def launch_gui(args):
from streamlit.web import cli
@@ -213,6 +239,9 @@ def launch_gui(args):
print()
print("CONTROL-C to exit...")
# Necessary so streamlit does not prompt the user for an email address.
write_streamlit_credentials()
target = gui.__file__
st_args = ["run", target]
@@ -350,18 +379,18 @@ def load_dotenv_files(git_root, dotenv_fname, encoding="utf-8"):
def register_litellm_models(git_root, model_metadata_fname, io, verbose=False):
model_metatdata_files = []
model_metadata_files = []
# Add the resource file path
resource_metadata = importlib_resources.files("aider.resources").joinpath("model-metadata.json")
model_metatdata_files.append(str(resource_metadata))
model_metadata_files.append(str(resource_metadata))
model_metatdata_files += generate_search_path_list(
model_metadata_files += generate_search_path_list(
".aider.model.metadata.json", git_root, model_metadata_fname
)
try:
model_metadata_files_loaded = models.register_litellm_models(model_metatdata_files)
model_metadata_files_loaded = models.register_litellm_models(model_metadata_files)
if len(model_metadata_files_loaded) > 0 and verbose:
io.tool_output("Loaded model metadata from:")
for model_metadata_file in model_metadata_files_loaded:
@@ -385,6 +414,12 @@ def sanity_check_repo(repo, io):
if not repo.git_repo_error:
return True
error_msg = str(repo.git_repo_error)
except UnicodeDecodeError as exc:
error_msg = (
"Failed to read the Git repository. This issue is likely caused by a path encoded "
f'in a format different from the expected encoding "{sys.getfilesystemencoding()}".\n'
f"Internal error: {str(exc)}"
)
except ANY_GIT_ERROR as exc:
error_msg = str(exc)
bad_ver = "version in (1, 2)" in error_msg
@@ -410,7 +445,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if argv is None:
argv = sys.argv[1:]
if force_git_root:
if git is None:
git_root = None
elif force_git_root:
git_root = force_git_root
else:
git_root = get_git_root()
@@ -457,6 +494,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
# Parse again to include any arguments that might have been defined in .env
args = parser.parse_args(argv)
if git is None:
args.git = False
if args.analytics_disable:
analytics = Analytics(permanently_disable=True)
print("Analytics have been permanently disabled.")
@@ -515,6 +555,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
llm_history_file=args.llm_history_file,
editingmode=editing_mode,
fancy_input=args.fancy_input,
multiline_mode=args.multiline,
)
io = get_io(args.pretty)
@@ -645,7 +686,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
# We can't know the git repo for sure until after parsing the args.
# If we guessed wrong, reparse because that changes things like
# the location of the config.yml and history files.
if args.git and not force_git_root:
if args.git and not force_git_root and git is not None:
right_repo_root = guessed_wrong_repo(io, git_root, fnames, git_dname)
if right_repo_root:
analytics.event("exit", reason="Recursing with correct repo")
@@ -782,6 +823,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
commands = Commands(
io,
None,
voice_language=args.voice_language,
voice_input_device=args.voice_input_device,
voice_format=args.voice_format,
verify_ssl=args.verify_ssl,
args=args,
parser=parser,
@@ -804,6 +848,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
)
args.stream = False
if args.map_tokens is None:
map_tokens = main_model.get_repo_map_tokens()
else:
map_tokens = args.map_tokens
try:
coder = Coder.create(
main_model=main_model,
@@ -816,7 +865,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
auto_commits=args.auto_commits,
dirty_commits=args.dirty_commits,
dry_run=args.dry_run,
map_tokens=args.map_tokens,
map_tokens=map_tokens,
verbose=args.verbose,
stream=args.stream,
use_git=args.git,
@@ -859,7 +908,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if args.watch_files:
file_watcher = FileWatcher(
coder, gitignores=ignores, verbose=args.verbose, analytics=analytics
coder,
gitignores=ignores,
verbose=args.verbose,
analytics=analytics,
root=str(Path.cwd()) if args.subtree_only else None,
)
coder.file_watcher = file_watcher

View File

@@ -10,10 +10,17 @@ from rich.text import Text
from aider.dump import dump # noqa: F401
_text = """
_text_prefix = """
# Header
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type
specimen book. It has survived not only five centuries, but also the leap into
electronic typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
and more recently with desktop publishing software like Aldus PageMaker
including versions of Lorem Ipsum.
@@ -27,10 +34,9 @@ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem
```python
import sys
"""
def greeting():
print("Hello world!")
_text_suffix = """
```
## Sub header too
@@ -41,81 +47,146 @@ The end.
class MarkdownStream:
live = None
when = 0
min_delay = 0.050
live_window = 6
"""Streaming markdown renderer that progressively displays content with a live updating window.
Uses rich.console and rich.live to render markdown content with smooth scrolling
and partial updates. Maintains a sliding window of visible content while streaming
in new markdown text.
"""
live = None # Rich Live display instance
when = 0 # Timestamp of last update
min_delay = 1.0 / 20 # Minimum time between updates (20fps)
live_window = 6 # Number of lines to keep visible at bottom during streaming
def __init__(self, mdargs=None):
self.printed = []
"""Initialize the markdown stream.
Args:
mdargs (dict, optional): Additional arguments to pass to rich Markdown renderer
"""
self.printed = [] # Stores lines that have already been printed
if mdargs:
self.mdargs = mdargs
else:
self.mdargs = dict()
# Initialize rich Live display with empty text
self.live = Live(Text(""), refresh_per_second=1.0 / self.min_delay)
self.live.start()
def _render_markdown_to_lines(self, text):
"""Render markdown text to a list of lines.
Args:
text (str): Markdown text to render
Returns:
list: List of rendered lines with line endings preserved
"""
# Render the markdown to a string buffer
string_io = io.StringIO()
console = Console(file=string_io, force_terminal=True)
markdown = Markdown(text, **self.mdargs)
console.print(markdown)
output = string_io.getvalue()
# Split rendered output into lines
return output.splitlines(keepends=True)
def __del__(self):
"""Destructor to ensure Live display is properly cleaned up."""
if self.live:
try:
self.live.stop()
except Exception:
pass
pass # Ignore any errors during cleanup
def update(self, text, final=False):
"""Update the displayed markdown content.
Args:
text (str): The markdown text received so far
final (bool): If True, this is the final update and we should clean up
Splits the output into "stable" older lines and the "last few" lines
which aren't considered stable. They may shift around as new chunks
are appended to the markdown text.
The stable lines emit to the console above the Live window.
The unstable lines emit into the Live window so they can be repainted.
Markdown going to the console works better in terminal scrollback buffers.
The live window doesn't play nice with terminal scrollback.
"""
now = time.time()
# Throttle updates to maintain smooth rendering
if not final and now - self.when < self.min_delay:
return
self.when = now
string_io = io.StringIO()
console = Console(file=string_io, force_terminal=True)
# Measure render time and adjust min_delay to maintain smooth rendering
start = time.time()
lines = self._render_markdown_to_lines(text)
render_time = time.time() - start
markdown = Markdown(text, **self.mdargs)
# Set min_delay to render time plus a small buffer
self.min_delay = min(max(render_time * 10, 1.0 / 20), 2)
console.print(markdown)
output = string_io.getvalue()
lines = output.splitlines(keepends=True)
num_lines = len(lines)
# How many lines have "left" the live window and are now considered stable?
# Or if final, consider all lines to be stable.
if not final:
num_lines -= self.live_window
# If we have stable content to display...
if final or num_lines > 0:
# How many stable lines do we need to newly show above the live window?
num_printed = len(self.printed)
show = num_lines - num_printed
# Skip if no new lines to show above live window
if show <= 0:
return
# Get the new lines and display them
show = lines[num_printed:num_lines]
show = "".join(show)
show = Text.from_ansi(show)
self.live.console.print(show)
self.live.console.print(show) # to the console above the live area
# Update our record of printed lines
self.printed = lines[:num_lines]
# Handle final update cleanup
if final:
self.live.update(Text(""))
self.live.stop()
self.live = None
else:
rest = lines[num_lines:]
rest = "".join(rest)
# rest = '...\n' + rest
rest = Text.from_ansi(rest)
self.live.update(rest)
return
# Update the live window with remaining lines
rest = lines[num_lines:]
rest = "".join(rest)
rest = Text.from_ansi(rest)
self.live.update(rest)
def find_minimal_suffix(self, text, match_lines=50):
"""
Splits text into chunks on blank lines "\n\n".
"""
if __name__ == "__main__":
_text = 5 * _text
with open("aider/io.py", "r") as f:
code = f.read()
_text = _text_prefix + code + _text_suffix
_text = _text * 10
pm = MarkdownStream()
for i in range(6, len(_text)):
for i in range(6, len(_text), 5):
pm.update(_text[:i])
time.sleep(0.01)

View File

@@ -75,7 +75,8 @@ MODEL_ALIASES = {
"35-turbo": "gpt-3.5-turbo",
"3": "gpt-3.5-turbo",
# Other models
"deepseek": "deepseek/deepseek-coder",
"deepseek": "deepseek/deepseek-chat",
"flash": "gemini/gemini-2.0-flash-exp",
}
@@ -609,6 +610,12 @@ MODEL_SETTINGS = [
use_repo_map=False,
send_undo_reply=False,
),
ModelSettings(
"gemini/gemini-2.0-flash-exp",
"diff",
use_repo_map=True,
send_undo_reply=False,
),
ModelSettings(
"deepseek/deepseek-chat",
"diff",
@@ -658,6 +665,13 @@ MODEL_SETTINGS = [
examples_as_sys_msg=True,
reminder="sys",
),
ModelSettings(
"openrouter/deepseek/deepseek-chat",
"diff",
use_repo_map=True,
examples_as_sys_msg=True,
reminder="sys",
),
ModelSettings(
"openrouter/openai/gpt-4o",
"diff",
@@ -757,6 +771,39 @@ MODEL_SETTINGS = [
use_temperature=False,
streaming=False,
),
ModelSettings(
"openrouter/openai/o1",
"diff",
weak_model_name="openrouter/openai/gpt-4o-mini",
editor_model_name="openrouter/openai/gpt-4o",
editor_edit_format="editor-diff",
use_repo_map=True,
streaming=False,
use_temperature=False,
# extra_params=dict(extra_body=dict(reasoning_effort="high")),
),
ModelSettings(
"openai/o1",
"diff",
weak_model_name="openai/gpt-4o-mini",
editor_model_name="openai/gpt-4o",
editor_edit_format="editor-diff",
use_repo_map=True,
streaming=False,
use_temperature=False,
# extra_params=dict(extra_body=dict(reasoning_effort="high")),
),
ModelSettings(
"o1",
"diff",
weak_model_name="gpt-4o-mini",
editor_model_name="gpt-4o",
editor_edit_format="editor-diff",
use_repo_map=True,
streaming=False,
use_temperature=False,
# extra_params=dict(extra_body=dict(reasoning_effort="high")),
),
ModelSettings(
"openrouter/qwen/qwen-2.5-coder-32b-instruct",
"diff",
@@ -873,10 +920,9 @@ class Model(ModelSettings):
self.keys_in_environment = res.get("keys_in_environment")
max_input_tokens = self.info.get("max_input_tokens") or 0
if max_input_tokens < 32 * 1024:
self.max_chat_history_tokens = 1024
else:
self.max_chat_history_tokens = 2 * 1024
# Calculate max_chat_history_tokens as 1/16th of max_input_tokens,
# with minimum 1k and maximum 8k
self.max_chat_history_tokens = min(max(max_input_tokens / 16, 1024), 8192)
self.configure_model_settings(model)
if weak_model is False:
@@ -1131,6 +1177,15 @@ class Model(ModelSettings):
return res
def get_repo_map_tokens(self):
map_tokens = 1024
max_inp_tokens = self.info.get("max_input_tokens")
if max_inp_tokens:
map_tokens = max_inp_tokens / 8
map_tokens = min(map_tokens, 4096)
map_tokens = max(map_tokens, 1024)
return map_tokens
def register_models(model_settings_fnames):
files_loaded = []
@@ -1225,10 +1280,10 @@ def sanity_check_model(io, model):
status = "Set" if value else "Not set"
io.tool_output(f"- {key}: {status}")
if platform.system() == "Windows" or True:
if platform.system() == "Windows":
io.tool_output(
"If you just set these environment variables using `setx` you may need to restart"
" your terminal or command prompt for the changes to take effect."
"Note: You may need to restart your terminal or command prompt for `setx` to take"
" effect."
)
elif not model.keys_in_environment:

View File

@@ -2,7 +2,18 @@ import os
import time
from pathlib import Path, PurePosixPath
import git
try:
import git
ANY_GIT_ERROR = [
git.exc.ODBError,
git.exc.GitError,
git.exc.InvalidGitRepositoryError,
]
except ImportError:
git = None
ANY_GIT_ERROR = []
import pathspec
from aider import prompts, utils
@@ -10,15 +21,16 @@ from aider.sendchat import simple_send_with_retries
from .dump import dump # noqa: F401
ANY_GIT_ERROR = (
git.exc.ODBError,
git.exc.GitError,
ANY_GIT_ERROR += [
OSError,
IndexError,
BufferError,
TypeError,
ValueError,
)
AttributeError,
AssertionError,
]
ANY_GIT_ERROR = tuple(ANY_GIT_ERROR)
class GitRepo:
@@ -276,9 +288,17 @@ class GitRepo:
files = self.tree_files[commit]
else:
try:
for blob in commit.tree.traverse():
if blob.type == "blob": # blob is a file
files.add(blob.path)
iterator = commit.tree.traverse()
while True:
try:
blob = next(iterator)
if blob.type == "blob": # blob is a file
files.add(blob.path)
except IndexError:
self.io.tool_warning(f"GitRepo: read error skipping {blob.path}")
continue
except StopIteration:
break
except ANY_GIT_ERROR as err:
self.git_repo_error = err
self.io.tool_error(f"Unable to list files in git repo: {err}")
@@ -350,8 +370,8 @@ class GitRepo:
def ignored_file_raw(self, fname):
if self.subtree_only:
fname_path = Path(self.normalize_path(fname))
try:
fname_path = Path(self.normalize_path(fname))
cwd_path = Path.cwd().resolve().relative_to(Path(self.root).resolve())
except ValueError:
# Issue #1524

View File

@@ -605,7 +605,7 @@ class RepoMap:
self.tree_cache = dict()
middle = min(max_map_tokens // 25, num_tags)
middle = min(int(max_map_tokens // 25), num_tags)
while lower_bound <= upper_bound:
# dump(lower_bound, middle, upper_bound)
@@ -628,7 +628,7 @@ class RepoMap:
else:
upper_bound = middle - 1
middle = (lower_bound + upper_bound) // 2
middle = int((lower_bound + upper_bound) // 2)
spin.end()
return best_tree

View File

@@ -0,0 +1,2 @@
{
}

View File

@@ -39,7 +39,7 @@ def get_windows_parent_process_name():
return None
def run_cmd_subprocess(command, verbose=False, cwd=None):
def run_cmd_subprocess(command, verbose=False, cwd=None, encoding=sys.stdout.encoding):
if verbose:
print("Using run_cmd_subprocess:", command)
@@ -65,7 +65,7 @@ def run_cmd_subprocess(command, verbose=False, cwd=None):
stderr=subprocess.STDOUT,
text=True,
shell=True,
encoding=sys.stdout.encoding,
encoding=encoding,
errors="replace",
bufsize=0, # Set bufsize to 0 for unbuffered output
universal_newlines=True,

View File

@@ -8,8 +8,6 @@ import tempfile
import time
from pathlib import Path
import git
from aider.dump import dump # noqa: F401
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp", ".pdf"}
@@ -73,6 +71,8 @@ class GitTemporaryDirectory(ChdirTemporaryDirectory):
def make_repo(path=None):
import git
if not path:
path = "."
repo = git.Repo.init(path)
@@ -300,12 +300,15 @@ class Spinner:
def find_common_root(abs_fnames):
if len(abs_fnames) == 1:
return safe_abs_path(os.path.dirname(list(abs_fnames)[0]))
elif abs_fnames:
return safe_abs_path(os.path.commonpath(list(abs_fnames)))
else:
return safe_abs_path(os.getcwd())
try:
if len(abs_fnames) == 1:
return safe_abs_path(os.path.dirname(list(abs_fnames)[0]))
elif abs_fnames:
return safe_abs_path(os.path.commonpath(list(abs_fnames)))
except OSError:
pass
return safe_abs_path(os.getcwd())
def format_tokens(count):

View File

@@ -18,6 +18,7 @@ warnings.filterwarnings("ignore", category=SyntaxWarning)
from pydub import AudioSegment # noqa
from pydub.exceptions import CouldntDecodeError, CouldntEncodeError # noqa
try:
import soundfile as sf
@@ -140,13 +141,28 @@ class Voice:
while not self.q.empty():
file.write(self.q.get())
if self.audio_format != "wav":
filename = tempfile.mktemp(suffix=f".{self.audio_format}")
audio = AudioSegment.from_wav(temp_wav)
audio.export(filename, format=self.audio_format)
os.remove(temp_wav)
else:
filename = temp_wav
use_audio_format = self.audio_format
# Check file size and offer to convert to mp3 if too large
file_size = os.path.getsize(temp_wav)
if file_size > 24.9 * 1024 * 1024 and self.audio_format == "wav":
print("\nWarning: {temp_wav} is too large, switching to mp3 format.")
use_audio_format = "mp3"
filename = temp_wav
if use_audio_format != "wav":
try:
new_filename = tempfile.mktemp(suffix=f".{use_audio_format}")
audio = AudioSegment.from_wav(temp_wav)
audio.export(new_filename, format=use_audio_format)
os.remove(temp_wav)
filename = new_filename
except (CouldntDecodeError, CouldntEncodeError) as e:
print(f"Error converting audio: {e}")
except (OSError, FileNotFoundError) as e:
print(f"File system error during conversion: {e}")
except Exception as e:
print(f"Unexpected error during audio conversion: {e}")
with open(filename, "rb") as fh:
try:
@@ -157,7 +173,7 @@ class Voice:
print(f"Unable to transcribe {filename}: {err}")
return
if self.audio_format != "wav":
if filename != temp_wav:
os.remove(filename)
text = transcript.text

View File

@@ -9,59 +9,7 @@ from pathspec.patterns import GitWildMatchPattern
from watchfiles import watch
from aider.dump import dump # noqa
def is_source_file(path: Path) -> bool:
"""
Check if a file is a source file that uses # or // style comments.
This includes Python, JavaScript, TypeScript, C, C++, etc.
"""
COMMENT_STYLE_EXTENSIONS = {
# # style comments
".py",
".r",
".rb",
".pl",
".pm",
".sh",
".bash",
".zsh",
".bashrc",
".bash_profile",
".bash_login",
".bash_logout",
".zshrc",
".zprofile",
".zlogin",
".zlogout",
".profile",
".yaml",
".yml",
# // style comments
".js",
".ts",
".jsx",
".tsx",
".cpp",
".c",
".h",
".hpp",
".java",
".swift",
".kt",
".cs",
".go",
".rs",
".php",
# -- style comments
".sql",
".hs", # Haskell
".lua",
".elm",
".vhd", # VHDL
".vhdl",
}
return path.suffix.lower() in COMMENT_STYLE_EXTENSIONS
from aider.watch_prompts import watch_ask_prompt, watch_code_prompt
def load_gitignores(gitignore_paths: list[Path]) -> Optional[PathSpec]:
@@ -69,7 +17,41 @@ def load_gitignores(gitignore_paths: list[Path]) -> Optional[PathSpec]:
if not gitignore_paths:
return None
patterns = [".aider*", ".git"] # Always ignore
patterns = [
".aider*",
".git",
# Common editor backup/temp files
"*~", # Emacs/vim backup
"*.bak", # Generic backup
"*.swp", # Vim swap
"*.swo", # Vim swap
"\\#*\\#", # Emacs auto-save
".#*", # Emacs lock files
"*.tmp", # Generic temp files
"*.temp", # Generic temp files
"*.orig", # Merge conflict originals
"*.pyc", # Python bytecode
"__pycache__/", # Python cache dir
".DS_Store", # macOS metadata
"Thumbs.db", # Windows thumbnail cache
# IDE files
".idea/", # JetBrains IDEs
".vscode/", # VS Code
"*.sublime-*", # Sublime Text
".project", # Eclipse
".settings/", # Eclipse
"*.code-workspace", # VS Code workspace
# Environment files
".env", # Environment variables
".venv/", # Python virtual environments
"node_modules/", # Node.js dependencies
"vendor/", # Various dependencies
# Logs and caches
"*.log", # Log files
".cache/", # Cache directories
".pytest_cache/", # Python test cache
"coverage/", # Code coverage reports
] # Always ignore
for path in gitignore_paths:
if path.exists():
with open(path) as f:
@@ -82,12 +64,12 @@ class FileWatcher:
"""Watches source files for changes and AI comments"""
# Compiled regex pattern for AI comments
ai_comment_pattern = re.compile(r"(?:#|//|--) *(ai\b.*|ai\b.*|.*\bai!?) *$", re.IGNORECASE)
ai_comment_pattern = re.compile(r"(?:#|//|--) *(ai\b.*|ai\b.*|.*\bai[?!]?) *$", re.IGNORECASE)
def __init__(self, coder, gitignores=None, verbose=False, analytics=None):
def __init__(self, coder, gitignores=None, verbose=False, analytics=None, root=None):
self.coder = coder
self.io = coder.io
self.root = Path(coder.root)
self.root = Path(root) if root else Path(coder.root)
self.verbose = verbose
self.analytics = analytics
self.stop_event = None
@@ -116,9 +98,6 @@ class FileWatcher:
if self.gitignore_spec and self.gitignore_spec.match_file(str(rel_path)):
return False
if not is_source_file(path_obj):
return False
if self.verbose:
dump("ok", rel_path)
@@ -165,10 +144,12 @@ class FileWatcher:
def process_changes(self):
"""Get any detected file changes"""
has_bangs = False
has_action = None
added = False
for fname in self.changed_files:
_, _, has_bang = self.get_ai_comments(fname)
has_bangs |= has_bang
_, _, action = self.get_ai_comments(fname)
if action in ("!", "?"):
has_action = action
if fname in self.coder.abs_fnames:
continue
@@ -176,26 +157,30 @@ class FileWatcher:
self.analytics.event("ai-comments file-add")
self.coder.abs_fnames.add(fname)
rel_fname = self.coder.get_rel_fname(fname)
if not added:
self.io.tool_output()
added = True
self.io.tool_output(f"Added {rel_fname} to the chat")
self.io.tool_output()
if not has_bangs:
if not has_action:
if added:
self.io.tool_output(
"End your comment with AI! to request changes or AI? to ask questions"
)
return ""
if self.analytics:
self.analytics.event("ai-comments execute")
self.io.tool_output("Processing your request...")
res = """
The "AI" comments below marked with █ can be found in the code files I've shared with you.
They contain your instructions.
Make the requested changes.
Be sure to remove all these "AI" comments from the code!
"""
if has_action == "!":
res = watch_code_prompt
elif has_action == "?":
res = watch_ask_prompt
# Refresh all AI comments from tracked files
for fname in self.coder.abs_fnames:
line_nums, comments, _has_bang = self.get_ai_comments(fname)
line_nums, comments, _action = self.get_ai_comments(fname)
if not line_nums:
continue
@@ -233,11 +218,14 @@ Be sure to remove all these "AI" comments from the code!
return res
def get_ai_comments(self, filepath):
"""Extract AI comment line numbers, comments and bang status from a file"""
"""Extract AI comment line numbers, comments and action status from a file"""
line_nums = []
comments = []
has_bang = False
has_action = None # None, "!" or "?"
content = self.io.read_text(filepath, silent=True)
if not content:
return None, None, None
for i, line in enumerate(content.splitlines(), 1):
if match := self.ai_comment_pattern.search(line):
comment = match.group(0).strip()
@@ -248,10 +236,12 @@ Be sure to remove all these "AI" comments from the code!
comment = comment.lstrip("/#-")
comment = comment.strip()
if comment.startswith("ai!") or comment.endswith("ai!"):
has_bang = True
has_action = "!"
elif comment.startswith("ai?") or comment.endswith("ai?"):
has_action = "?"
if not line_nums:
return None, None, False
return line_nums, comments, has_bang
return None, None, None
return line_nums, comments, has_action
def main():

12
aider/watch_prompts.py Normal file
View File

@@ -0,0 +1,12 @@
watch_code_prompt = """
I've written your instructions in comments in the code and marked them with "ai"
You can see the "AI" comments shown below (marked with █).
Find them in the code files I've shared with you, and follow their instructions.
After completing those instructions, also be sure to remove all the "AI" comments from the code too.
"""
watch_ask_prompt = """/ask
Find the "AI" comments below (marked with █) in the code files I've shared with you.
They contain my questions that I need you to answer and other instructions for you.
"""

View File

@@ -1,7 +1,6 @@
---
title: Release history
parent: More info
nav_order: 900
nav_order: 925
highlight_image: /assets/blame.jpg
description: Release notes and stats on aider writing its own code.
---
@@ -24,7 +23,74 @@ cog.out(text)
]]]-->
### main branch
### Aider v0.71.1
- Fix permissions issue in Docker images.
- Added read-only file announcements to chat.
- Bugfix: ASCII fallback for unicode errors.
- Bugfix: integer indices for list slicing in repomap calculations.
- Aider wrote 83% of the code in this release.
### Aider v0.71.0
- Prompts to help DeepSeek work better when alternating between `/ask` and `/code`.
- Streaming pretty LLM responses is smoother and faster for long replies.
- Streaming automatically turns of for model that don't support it
- Can now switch to/from `/model o1` and a streaming model
- Pretty output remains enabled even when editing files with triple-backtick fences
- Bare `/ask`, `/code` and `/architect` commands now switch the chat mode.
- Increased default size of the repomap.
- Increased max chat history tokens limit from 4k to 8k.
- Turn off fancy input and watch files if terminal is dumb.
- Added support for custom voice format and input device settings.
- Disabled Streamlit email prompt, by apaz-cli.
- Docker container runs as non-root user.
- Fixed lint command handling of nested spaced strings, by Aaron Weisberg.
- Added token count feedback when adding command output to chat.
- Improved error handling for large audio files with automatic format conversion.
- Improved handling of git repo index errors, by Krazer.
- Improved unicode handling in console output with ASCII fallback.
- Added AssertionError, AttributeError to git error handling.
- Aider wrote 60% of the code in this release.
### Aider v0.70.0
- Full support for o1 models.
- Watch files now honors `--subtree-only`, and only watches that subtree.
- Improved prompting for watch files, to work more reliably with more models.
- New install methods via uv, including one-liners.
- Support for openrouter/deepseek/deepseek-chat model.
- Better error handling when interactive commands are attempted via `/load` or `--load`.
- Display read-only files with abs path if its shorter than rel path.
- Ask 10% of users to opt-in to analytics.
- Bugfix for auto-suggest.
- Gracefully handle unicode errors in git path names.
- Aider wrote 74% of the code in this release.
### Aider v0.69.1
- Fix for gemini model names in model metadata.
- Show hints about AI! and AI? when user makes AI comments.
- Support for running without git installed.
- Improved environment variable setup messages on Windows.
### Aider v0.69.0
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
- Now watches *all* files, not just certain source files.
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
- Full support for Gemini Flash 2.0 Exp:
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
- Improved clipboard error handling with helpful requirements install info.
- Ask 5% of users if they want to opt-in to analytics.
- `/voice` now lets you edit the transcribed text before sending.
- Disabled auto-complete in Y/N prompts.
- Aider wrote 68% of the code in this release.
### Aider v0.68.0
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
- New `--copy-paste` mode.

View File

@@ -1,6 +1,12 @@
theme: just-the-docs
url: "https://aider.chat"
# Analytics configuration
analytics:
enabled: false # Single switch to control analytics and cookie consent
posthog_key: 'phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv'
posthog_host: 'https://us.i.posthog.com'
plugins:
- jekyll-redirect-from
- jekyll-sitemap
@@ -45,4 +51,4 @@ callouts:
note:
title: Note
color: yellow

View File

@@ -3252,8 +3252,8 @@
Philippe de Reynal: 30
start_tag: v0.65.0
total_lines: 703
- aider_percentage: 65.29
aider_total: 457
- aider_percentage: 67.86
aider_total: 437
end_date: '2024-12-06'
end_tag: v0.67.0
file_counts:
@@ -3314,14 +3314,234 @@
tests/browser/test_browser.py:
Paul Gauthier: 2
Paul Gauthier (aider): 1
tests/fixtures/watch.js:
Paul Gauthier: 19
Paul Gauthier (aider): 16
tests/fixtures/watch.py:
Paul Gauthier: 17
Paul Gauthier (aider): 4
grand_total:
Paul Gauthier: 243
Paul Gauthier (aider): 457
Paul Gauthier: 207
Paul Gauthier (aider): 437
start_tag: v0.66.0
total_lines: 700
total_lines: 644
- aider_percentage: 71.57
aider_total: 428
end_date: '2024-12-10'
end_tag: v0.68.0
file_counts:
.github/workflows/pages.yml:
Paul Gauthier (aider): 1
aider/__init__.py:
Paul Gauthier: 1
aider/analytics.py:
Paul Gauthier: 2
aider/args.py:
Paul Gauthier: 30
Paul Gauthier (aider): 15
aider/coders/base_coder.py:
Paul Gauthier: 12
Paul Gauthier (aider): 10
aider/coders/editor_editblock_coder.py:
Paul Gauthier: 1
aider/coders/editor_whole_coder.py:
Paul Gauthier: 1
aider/commands.py:
Paul Gauthier: 24
Paul Gauthier (aider): 25
aider/copypaste.py:
Paul Gauthier: 4
Paul Gauthier (aider): 68
aider/exceptions.py:
Paul Gauthier: 9
aider/history.py:
Paul Gauthier (aider): 1
aider/io.py:
Paul Gauthier: 13
aider/main.py:
Paul Gauthier: 17
Paul Gauthier (aider): 29
aider/models.py:
Paul Gauthier: 15
aider/repo.py:
Paul Gauthier (aider): 1
aider/run_cmd.py:
Paul Gauthier: 1
aider/sendchat.py:
Paul Gauthier (aider): 4
aider/utils.py:
Paul Gauthier: 1
aider/voice.py:
Paul Gauthier: 9
aider/watch.py:
Paul Gauthier: 6
Paul Gauthier (aider): 35
aider/website/_includes/edit-leaderboard.js:
Paul Gauthier: 2
Paul Gauthier (aider): 90
aider/website/_includes/head_custom.html:
Paul Gauthier: 7
Paul Gauthier (aider): 53
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
Paul Gauthier (aider): 2
scripts/blame.py:
Paul Gauthier: 6
Paul Gauthier (aider): 17
scripts/pip-compile.sh:
Paul Gauthier: 2
tests/basic/test_commands.py:
Paul Gauthier (aider): 24
tests/basic/test_history.py:
Paul Gauthier (aider): 3
tests/basic/test_main.py:
Paul Gauthier (aider): 46
tests/basic/test_repo.py:
Paul Gauthier (aider): 3
tests/basic/test_sendchat.py:
Paul Gauthier: 5
Paul Gauthier (aider): 1
tests/basic/test_watch.py:
Paul Gauthier: 1
grand_total:
Paul Gauthier: 170
Paul Gauthier (aider): 428
start_tag: v0.67.0
total_lines: 598
- aider_percentage: 67.87
aider_total: 207
end_date: '2024-12-13'
end_tag: v0.69.0
file_counts:
.github/workflows/pages.yml:
Paul Gauthier: 2
aider/__init__.py:
Paul Gauthier: 1
aider/analytics.py:
Paul Gauthier: 2
aider/args.py:
Mir Adnan ALI: 3
Paul Gauthier: 1
aider/coders/base_coder.py:
JeongJuhyeon: 1
Mir Adnan ALI: 3
aider/commands.py:
Mir Adnan ALI: 4
Paul Gauthier: 5
Paul Gauthier (aider): 3
aider/io.py:
Mir Adnan ALI: 37
Paul Gauthier: 8
Paul Gauthier (aider): 3
aider/main.py:
Mir Adnan ALI: 1
aider/models.py:
Paul Gauthier: 7
aider/watch.py:
Paul Gauthier: 7
Paul Gauthier (aider): 47
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
benchmark/benchmark.py:
Paul Gauthier: 7
Paul Gauthier (aider): 7
scripts/blame.py:
Paul Gauthier (aider): 1
scripts/issues.py:
Paul Gauthier (aider): 58
scripts/update-history.py:
Paul Gauthier: 3
tests/basic/test_io.py:
Paul Gauthier (aider): 20
tests/basic/test_watch.py:
Paul Gauthier: 5
Paul Gauthier (aider): 68
grand_total:
JeongJuhyeon: 1
Mir Adnan ALI: 48
Paul Gauthier: 49
Paul Gauthier (aider): 207
start_tag: v0.68.0
total_lines: 305
- aider_percentage: 74.22
aider_total: 875
end_date: '2024-12-26'
end_tag: v0.70.0
file_counts:
aider/__init__.py:
Paul Gauthier: 1
aider/analytics.py:
Paul Gauthier: 6
Paul Gauthier (aider): 41
aider/args.py:
Evan Johnson: 2
aider/coders/search_replace.py:
Paul Gauthier: 5
aider/commands.py:
Paul Gauthier (aider): 41
aider/help_pats.py:
Paul Gauthier: 3
aider/io.py:
Paul Gauthier: 7
Paul Gauthier (aider): 9
aider/main.py:
Paul Gauthier: 15
Paul Gauthier (aider): 5
apaz-cli: 3
mdk: 6
aider/models.py:
Paul Gauthier: 29
aider/repo.py:
Paul Gauthier: 14
aider/utils.py:
Paul Gauthier: 2
aider/watch.py:
Paul Gauthier: 13
aider/website/_includes/head_custom.html:
Paul Gauthier (aider): 4
aider/website/_includes/leaderboard.js:
Paul Gauthier (aider): 14
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 28
Paul Gauthier (aider): 2
benchmark/Dockerfile:
Paul Gauthier: 8
Paul Gauthier (aider): 43
benchmark/benchmark.py:
Paul Gauthier: 69
Paul Gauthier (aider): 153
benchmark/clone-exercism.sh:
Paul Gauthier: 2
Paul Gauthier (aider): 18
benchmark/cpp-test.sh:
Paul Gauthier: 10
Paul Gauthier (aider): 1
benchmark/docker.sh:
Paul Gauthier (aider): 4
benchmark/install-docker-ubuntu.sh:
Paul Gauthier (aider): 63
benchmark/npm-test.sh:
Paul Gauthier: 10
Paul Gauthier (aider): 3
benchmark/problem_stats.py:
Paul Gauthier: 35
Paul Gauthier (aider): 318
benchmark/rsync.sh:
Paul Gauthier: 7
Paul Gauthier (aider): 26
scripts/blame.py:
Paul Gauthier (aider): 6
scripts/my_models.py:
Paul Gauthier (aider): 95
scripts/update-blame.sh:
Paul Gauthier (aider): 3
scripts/update-docs.sh:
Paul Gauthier: 1
tests/basic/test_analytics.py:
Paul Gauthier (aider): 19
tests/basic/test_main.py:
Paul Gauthier (aider): 7
tests/basic/test_sanity_check_repo.py:
mdk: 28
grand_total:
Evan Johnson: 2
Paul Gauthier: 265
Paul Gauthier (aider): 875
apaz-cli: 3
mdk: 34
start_tag: v0.69.0
total_lines: 1179

View File

@@ -1232,7 +1232,7 @@
- dirname: 2024-09-24-16-33-23--gemini-1.5-flash-002-whole
test_cases: 133
model: gemini-1.5-flash-002
model: gemini-1.5-flash-002 (0924)
edit_format: whole
commit_hash: 3edcd71
pass_rate_1: 37.6
@@ -2134,4 +2134,99 @@
date: 2024-12-10
versions: 0.67.1.dev
seconds_per_case: 32.7
total_cost: 0.1106
total_cost: 0.1106
- dirname: 2024-12-11-00-37-08--yi-test
test_cases: 133
model: yi-lightning
edit_format: whole
commit_hash: e909a3d-dirty
pass_rate_1: 49.6
pass_rate_2: 65.4
percent_cases_well_formed: 97.0
error_outputs: 304
num_malformed_responses: 5
num_with_malformed_responses: 4
user_asks: 34
lazy_comments: 2
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
command: aider --model openai/yi-lightning
date: 2024-12-11
versions: 0.67.1.dev
seconds_per_case: 57.8
total_cost: 0.0000
- dirname: 2024-12-11-21-07-00--gemini-2-flash-diff
test_cases: 133
model: gemini-2.0-flash-exp
edit_format: diff
commit_hash: fcb2bac-dirty, 02e7e31-dirty
pass_rate_1: 56.4
pass_rate_2: 69.9
percent_cases_well_formed: 97.0
error_outputs: 10
num_malformed_responses: 6
num_with_malformed_responses: 4
user_asks: 8
lazy_comments: 0
syntax_errors: 1
indentation_errors: 0
exhausted_context_windows: 2
test_timeouts: 1
command: aider --model gemini/gemini-2.0-flash-exp
date: 2024-12-11
versions: 0.68.1.dev
seconds_per_case: 7.3
total_cost: 0.0000
- dirname: 2024-12-18-01-50-08--o1
test_cases: 133
model: o1
edit_format: diff
commit_hash: 074c636-dirty
pass_rate_1: 65.4
pass_rate_2: 84.2
percent_cases_well_formed: 99.2
error_outputs: 1
num_malformed_responses: 1
num_with_malformed_responses: 1
user_asks: 0
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
command: aider --model openrouter/openai/o1
date: 2024-12-18
versions: 0.69.2.dev
seconds_per_case: 29.9
total_cost: 0.0000
- dirname: 2024-12-21-22-06-01--polyglot-o1-mini-whole
test_cases: 225
model: o1-mini-2024-09-12
edit_format: whole
commit_hash: a755079-dirty
pass_rate_1: 8.9
pass_rate_2: 27.1
pass_num_1: 20
pass_num_2: 61
percent_cases_well_formed: 95.6
error_outputs: 15
num_malformed_responses: 14
num_with_malformed_responses: 10
user_asks: 37
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 5
total_tests: 225
command: aider --model o1-mini
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 34.3
total_cost: 17.6270

View File

@@ -0,0 +1,259 @@
- dirname: 2024-12-21-18-41-18--polyglot-gpt-4o-mini
test_cases: 225
model: gpt-4o-mini-2024-07-18
edit_format: whole
commit_hash: a755079-dirty
pass_rate_1: 0.9
pass_rate_2: 3.6
pass_num_1: 2
pass_num_2: 8
percent_cases_well_formed: 100.0
error_outputs: 0
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 36
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
total_tests: 225
command: aider --model gpt-4o-mini-2024-07-18
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 17.3
total_cost: 0.3236
- dirname: 2024-12-21-18-44-28--polyglot-sonnet
test_cases: 225
model: claude-3-5-sonnet-20241022
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 18.7
pass_rate_2: 45.3
pass_num_1: 42
pass_num_2: 102
percent_cases_well_formed: 100.0
error_outputs: 1
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 14
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 12
total_tests: 225
command: aider --model claude-3-5-sonnet-20241022
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 30.8
total_cost: 13.4847
- dirname: 2024-12-21-18-52-34--polyglot-gpt-4o-diff
test_cases: 225
model: gpt-4o-2024-11-20
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 4.9
pass_rate_2: 15.1
pass_num_1: 11
pass_num_2: 34
percent_cases_well_formed: 96.0
error_outputs: 12
num_malformed_responses: 11
num_with_malformed_responses: 9
user_asks: 34
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 19
total_tests: 225
command: aider --model gpt-4o-2024-11-20
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 22.2
total_cost: 7.1835
- dirname: 2024-12-21-19-23-03--polyglot-o1-hard-diff
test_cases: 224
model: o1-2024-12-17 (high)
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 23.7
pass_rate_2: 61.7
pass_num_1: 53
pass_num_2: 139
percent_cases_well_formed: 91.5
error_outputs: 25
num_malformed_responses: 24
num_with_malformed_responses: 19
user_asks: 16
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
total_tests: 225
command: aider --model openrouter/openai/o1
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 133.2
total_cost: 0.0000
- dirname: 2024-12-21-20-56-21--polyglot-deepseek-diff
test_cases: 225
model: DeepSeek Chat V2.5
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 5.3
pass_rate_2: 17.8
pass_num_1: 12
pass_num_2: 40
percent_cases_well_formed: 92.9
error_outputs: 42
num_malformed_responses: 37
num_with_malformed_responses: 16
user_asks: 23
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 5
test_timeouts: 5
total_tests: 225
command: aider --model deepseek/deepseek-chat
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 184.0
total_cost: 0.5101
- dirname: 2024-12-21-21-46-27--polyglot-haiku-diff
test_cases: 225
model: claude-3-5-haiku-20241022
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 7.1
pass_rate_2: 28.0
pass_num_1: 16
pass_num_2: 63
percent_cases_well_formed: 91.1
error_outputs: 31
num_malformed_responses: 30
num_with_malformed_responses: 20
user_asks: 13
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 9
total_tests: 225
command: aider --model claude-3-5-haiku-20241022
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 31.8
total_cost: 6.0583
- dirname: 2024-12-22-13-22-32--polyglot-qwen-diff
test_cases: 225
model: Qwen2.5-Coder-32B-Instruct
edit_format: diff
commit_hash: 6d7e8be-dirty
pass_rate_1: 4.4
pass_rate_2: 8.0
pass_num_1: 10
pass_num_2: 18
percent_cases_well_formed: 71.6
error_outputs: 158
num_malformed_responses: 148
num_with_malformed_responses: 64
user_asks: 132
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 2
total_tests: 225
command: "aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct # via hyperbolic"
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 84.4
total_cost: 0.0000
- dirname: 2024-12-22-21-26-35--polyglot-o1mini-whole
test_cases: 225
model: o1-mini-2024-09-12
edit_format: whole
commit_hash: 37df899
pass_rate_1: 5.8
pass_rate_2: 32.9
pass_num_1: 13
pass_num_2: 74
percent_cases_well_formed: 96.9
error_outputs: 8
num_malformed_responses: 8
num_with_malformed_responses: 7
user_asks: 27
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
total_tests: 225
command: aider --model o1-mini
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 34.7
total_cost: 18.5770
- dirname: 2024-12-22-18-43-25--gemini-exp-1206-polyglot-whole-2
test_cases: 225
model: gemini-exp-1206
edit_format: whole
commit_hash: b1bc2f8
pass_rate_1: 19.6
pass_rate_2: 38.2
pass_num_1: 44
pass_num_2: 86
percent_cases_well_formed: 98.2
error_outputs: 8
num_malformed_responses: 8
num_with_malformed_responses: 4
user_asks: 32
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 9
total_tests: 225
command: aider --model gemini/gemini-exp-1206
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 45.5
total_cost: 0.0000
- dirname: 2024-12-22-20-08-13--gemini-2.0-flash-exp-polyglot-whole
test_cases: 225
model: gemini-2.0-flash-exp
edit_format: whole
commit_hash: b1bc2f8
pass_rate_1: 11.6
pass_rate_2: 22.2
pass_num_1: 26
pass_num_2: 50
percent_cases_well_formed: 100.0
error_outputs: 1
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 9
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 8
total_tests: 225
command: aider --model gemini/gemini-2.0-flash-exp
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 12.2
total_cost: 0.0000

View File

@@ -0,0 +1,338 @@
- dirname: 2024-12-21-18-41-18--polyglot-gpt-4o-mini
test_cases: 225
model: gpt-4o-mini-2024-07-18
edit_format: whole
commit_hash: a755079-dirty
pass_rate_1: 0.9
pass_rate_2: 3.6
pass_num_1: 2
pass_num_2: 8
percent_cases_well_formed: 100.0
error_outputs: 0
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 36
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
total_tests: 225
command: aider --model gpt-4o-mini-2024-07-18
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 17.3
total_cost: 0.3236
- dirname: 2024-12-21-18-44-28--polyglot-sonnet
test_cases: 225
model: claude-3-5-sonnet-20241022
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 18.7
pass_rate_2: 45.3
pass_num_1: 42
pass_num_2: 102
percent_cases_well_formed: 100.0
error_outputs: 1
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 14
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 12
total_tests: 225
command: aider --model claude-3-5-sonnet-20241022
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 30.8
total_cost: 13.4847
- dirname: 2024-12-21-18-52-34--polyglot-gpt-4o-diff
test_cases: 225
model: gpt-4o-2024-11-20
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 4.9
pass_rate_2: 15.1
pass_num_1: 11
pass_num_2: 34
percent_cases_well_formed: 96.0
error_outputs: 12
num_malformed_responses: 11
num_with_malformed_responses: 9
user_asks: 34
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 19
total_tests: 225
command: aider --model gpt-4o-2024-11-20
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 22.2
total_cost: 7.1835
- dirname: 2024-12-21-19-23-03--polyglot-o1-hard-diff
test_cases: 224
model: o1-2024-12-17 (high)
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 23.7
pass_rate_2: 61.7
pass_num_1: 53
pass_num_2: 139
percent_cases_well_formed: 91.5
error_outputs: 25
num_malformed_responses: 24
num_with_malformed_responses: 19
user_asks: 16
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
total_tests: 225
command: aider --model openrouter/openai/o1
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 133.2
total_cost: 0.0000
- dirname: 2024-12-21-20-56-21--polyglot-deepseek-diff
test_cases: 225
model: DeepSeek Chat V2.5
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 5.3
pass_rate_2: 17.8
pass_num_1: 12
pass_num_2: 40
percent_cases_well_formed: 92.9
error_outputs: 42
num_malformed_responses: 37
num_with_malformed_responses: 16
user_asks: 23
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 5
test_timeouts: 5
total_tests: 225
command: aider --model deepseek/deepseek-chat
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 184.0
total_cost: 0.5101
- dirname: 2024-12-21-21-46-27--polyglot-haiku-diff
test_cases: 225
model: claude-3-5-haiku-20241022
edit_format: diff
commit_hash: a755079-dirty
pass_rate_1: 7.1
pass_rate_2: 28.0
pass_num_1: 16
pass_num_2: 63
percent_cases_well_formed: 91.1
error_outputs: 31
num_malformed_responses: 30
num_with_malformed_responses: 20
user_asks: 13
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 9
total_tests: 225
command: aider --model claude-3-5-haiku-20241022
date: 2024-12-21
versions: 0.69.2.dev
seconds_per_case: 31.8
total_cost: 6.0583
- dirname: 2024-12-22-13-22-32--polyglot-qwen-diff
test_cases: 225
model: Qwen2.5-Coder-32B-Instruct
edit_format: diff
commit_hash: 6d7e8be-dirty
pass_rate_1: 4.4
pass_rate_2: 8.0
pass_num_1: 10
pass_num_2: 18
percent_cases_well_formed: 71.6
error_outputs: 158
num_malformed_responses: 148
num_with_malformed_responses: 64
user_asks: 132
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 2
total_tests: 225
command: "aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct # via hyperbolic"
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 84.4
total_cost: 0.0000
- dirname: 2024-12-22-21-26-35--polyglot-o1mini-whole
test_cases: 225
model: o1-mini-2024-09-12
edit_format: whole
commit_hash: 37df899
pass_rate_1: 5.8
pass_rate_2: 32.9
pass_num_1: 13
pass_num_2: 74
percent_cases_well_formed: 96.9
error_outputs: 8
num_malformed_responses: 8
num_with_malformed_responses: 7
user_asks: 27
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
total_tests: 225
command: aider --model o1-mini
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 34.7
total_cost: 18.5770
- dirname: 2024-12-22-18-43-25--gemini-exp-1206-polyglot-whole-2
test_cases: 225
model: gemini-exp-1206
edit_format: whole
commit_hash: b1bc2f8
pass_rate_1: 19.6
pass_rate_2: 38.2
pass_num_1: 44
pass_num_2: 86
percent_cases_well_formed: 98.2
error_outputs: 8
num_malformed_responses: 8
num_with_malformed_responses: 4
user_asks: 32
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 9
total_tests: 225
command: aider --model gemini/gemini-exp-1206
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 45.5
total_cost: 0.0000
- dirname: 2024-12-22-20-08-13--gemini-2.0-flash-exp-polyglot-whole
test_cases: 225
model: gemini-2.0-flash-exp
edit_format: whole
commit_hash: b1bc2f8
pass_rate_1: 11.6
pass_rate_2: 22.2
pass_num_1: 26
pass_num_2: 50
percent_cases_well_formed: 100.0
error_outputs: 1
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 9
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 8
total_tests: 225
command: aider --model gemini/gemini-2.0-flash-exp
date: 2024-12-22
versions: 0.69.2.dev
seconds_per_case: 12.2
total_cost: 0.0000
- dirname: 2024-12-23-01-11-56--yi-test
test_cases: 225
model: yi-lightning
edit_format: whole
commit_hash: 2b1625e
pass_rate_1: 5.8
pass_rate_2: 12.9
pass_num_1: 13
pass_num_2: 29
percent_cases_well_formed: 92.9
error_outputs: 87
num_malformed_responses: 72
num_with_malformed_responses: 16
user_asks: 107
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 6
total_tests: 225
command: aider --model openai/yi-lightning
date: 2024-12-23
versions: 0.69.2.dev
seconds_per_case: 146.7
total_cost: 0.0000
- dirname: 2024-12-25-13-31-51--deepseekv3preview-diff2
test_cases: 225
model: DeepSeek Chat V3
edit_format: diff
commit_hash: 0a23c4a-dirty
pass_rate_1: 22.7
pass_rate_2: 48.4
pass_num_1: 51
pass_num_2: 109
percent_cases_well_formed: 98.7
error_outputs: 7
num_malformed_responses: 7
num_with_malformed_responses: 3
user_asks: 19
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 8
total_tests: 225
command: aider --model deepseek/deepseek-chat
date: 2024-12-25
versions: 0.69.2.dev
seconds_per_case: 34.8
total_cost: 0.3369
- dirname: 2024-12-26-00-55-20--Qwen2.5-Coder-32B-Instruct
test_cases: 225
model: openai/Qwen2.5-Coder-32B-Instruct
edit_format: whole
commit_hash: b51768b0
pass_rate_1: 4.9
pass_rate_2: 16.4
pass_num_1: 11
pass_num_2: 37
percent_cases_well_formed: 99.6
error_outputs: 1
num_malformed_responses: 1
num_with_malformed_responses: 1
user_asks: 33
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 6
total_tests: 225
command: aider --model openai/Qwen2.5-Coder-32B-Instruct
date: 2024-12-26
versions: 0.69.2.dev
seconds_per_case: 42.0
total_cost: 0.0000

View File

@@ -1,5 +1,18 @@
<canvas id="blameChart" width="800" height="360" style="margin-top: 20px"></canvas>
<canvas id="linesChart" width="800" height="360" style="margin-top: 20px"></canvas>
<div class="chart-container">
<canvas id="blameChart" style="margin-top: 20px"></canvas>
</div>
<div class="chart-container">
<canvas id="linesChart" style="margin-top: 20px"></canvas>
</div>
<style>
.chart-container {
position: relative;
width: 100%;
height: 300px;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
@@ -24,10 +37,17 @@ document.addEventListener('DOMContentLoaded', function () {
var linesData = {
labels: labels,
datasets: [{
label: 'Aider\'s lines of new code',
label: 'Aider',
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.aider_total }} },{% endfor %}],
backgroundColor: 'rgba(255, 99, 132, 0.8)',
borderColor: 'rgba(255, 99, 132, 1)',
backgroundColor: 'rgba(54, 162, 235, 0.8)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
},
{
label: 'Human',
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.total_lines | minus: row.aider_total }} },{% endfor %}],
backgroundColor: 'rgba(200, 200, 200, 0.8)',
borderColor: 'rgba(200, 200, 200, 1)',
borderWidth: 1
}]
};
@@ -36,6 +56,7 @@ document.addEventListener('DOMContentLoaded', function () {
type: 'bar',
data: blameData,
options: {
maintainAspectRatio: false,
scales: {
x: {
type: 'category',
@@ -85,9 +106,11 @@ document.addEventListener('DOMContentLoaded', function () {
type: 'bar',
data: linesData,
options: {
maintainAspectRatio: false,
scales: {
x: {
type: 'category',
stacked: true,
title: {
display: true,
text: 'Version'
@@ -98,6 +121,7 @@ document.addEventListener('DOMContentLoaded', function () {
}
},
y: {
stacked: true,
title: {
display: true,
text: 'Lines of new code'
@@ -107,12 +131,14 @@ document.addEventListener('DOMContentLoaded', function () {
},
plugins: {
legend: {
display: false
display: true,
position: 'chartArea',
reverse: true
},
tooltip: {
callbacks: {
label: function(context) {
var label = 'New lines of code by aider';
var label = context.dataset.label;
var value = context.parsed.y || 0;
return `${label}: ${value}`;
}
@@ -120,7 +146,7 @@ document.addEventListener('DOMContentLoaded', function () {
},
title: {
display: true,
text: 'Lines of new code written by aider, by release',
text: 'Lines of new code, by release',
font: {
size: 16
}

View File

@@ -1,185 +0,0 @@
document.addEventListener('DOMContentLoaded', function () {
var ctx = document.getElementById('editChart').getContext('2d');
const blueDiagonalPattern = pattern.draw('diagonal', 'rgba(54, 162, 235, 0.2)');
const redDiagonalPattern = pattern.draw('diagonal', 'rgba(255, 99, 132, 0.2)');
let displayedData = [];
const HIGHTLIGHT_MODEL = 'no no no';
var leaderboardData = {
labels: [],
datasets: [{
label: 'Percent completed correctly',
data: [],
backgroundColor: function(context) {
const row = allData[context.dataIndex];
if (row && row.edit_format === 'whole') {
return diagonalPattern;
}
const label = leaderboardData.labels[context.dataIndex] || '';
return (label && label.includes(HIGHTLIGHT_MODEL)) ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)';
},
borderColor: function(context) {
const label = context.chart.data.labels[context.dataIndex] || '';
return (label && label.includes(HIGHTLIGHT_MODEL)) ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)';
},
borderWidth: 1
}]
};
var allData = [];
{% for row in edit_sorted %}
allData.push({
model: '{{ row.model }}',
pass_rate_2: {{ row.pass_rate_2 }},
percent_cases_well_formed: {{ row.percent_cases_well_formed }},
edit_format: '{{ row.edit_format }}'
});
{% endfor %}
function updateChart() {
var selectedRows = document.querySelectorAll('tr.selected');
var showAll = selectedRows.length === 0;
displayedData = [];
leaderboardData.labels = [];
leaderboardData.datasets[0].data = [];
allData.forEach(function(row, index) {
var rowElement = document.getElementById('edit-row-' + index);
if (showAll) {
rowElement.classList.remove('selected');
}
if (showAll || rowElement.classList.contains('selected')) {
displayedData.push(row);
leaderboardData.labels.push(row.model);
leaderboardData.datasets[0].data.push(row.pass_rate_2);
}
});
leaderboardChart.update();
leaderboardChart.render();
}
// Use displayedData in the backgroundColor callback instead of allData
leaderboardData.datasets[0].backgroundColor = function(context) {
const row = displayedData[context.dataIndex];
const label = leaderboardData.labels[context.dataIndex] || '';
if (label && label.includes(HIGHTLIGHT_MODEL)) {
if (row && row.edit_format === 'whole') return redDiagonalPattern;
else return 'rgba(255, 99, 132, 0.2)';
} else if (row && row.edit_format === 'whole') {
return blueDiagonalPattern;
} else {
return 'rgba(54, 162, 235, 0.2)';
}
};
var tableBody = document.querySelector('table tbody');
allData.forEach(function(row, index) {
var tr = tableBody.children[index];
tr.id = 'edit-row-' + index;
tr.style.cursor = 'pointer';
tr.onclick = function() {
this.classList.toggle('selected');
updateChart();
};
});
var leaderboardChart = new Chart(ctx, {
type: 'bar',
data: leaderboardData,
options: {
plugins: {
legend: {
display: true,
labels: {
generateLabels: function(chart) {
return [
{
text: 'Diff-like format',
fillStyle: 'rgba(54, 162, 235, 0.2)',
strokeStyle: 'rgba(54, 162, 235, 1)',
lineWidth: 1
},
{
text: 'Whole format',
fillStyle: blueDiagonalPattern,
strokeStyle: 'rgba(54, 162, 235, 1)',
lineWidth: 1
}
];
}
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Percent completed correctly'
}
},
x: {
ticks: {
callback: function(value, index) {
const label = this.getLabelForValue(value);
if (label.length <= "claude-3-5-sonnet".length) {
return label;
}
// Find all possible split positions
const splitPositions = [];
for (let i = 0; i < label.length; i++) {
if (label[i] === '-' || label[i] === ' ') {
splitPositions.push(i);
}
}
if (splitPositions.length === 0) {
return label;
}
// Find split position closest to middle
const middle = label.length / 2;
const splitIndex = splitPositions.reduce((closest, current) => {
return Math.abs(current - middle) < Math.abs(closest - middle) ? current : closest;
});
return [
label.slice(0, splitIndex),
label.slice(splitIndex + 1)
];
}
}
}
}
}
});
updateChart();
// Add search functionality for edit table
document.getElementById('editSearchInput').addEventListener('keyup', function() {
var searchWords = this.value.toLowerCase().split(' ').filter(word => word.length > 0);
var tableBody = document.querySelector('table:first-of-type tbody');
var rows = tableBody.getElementsByTagName('tr');
displayedData = [];
leaderboardData.labels = [];
leaderboardData.datasets[0].data = [];
for (var i = 0; i < rows.length; i++) {
var rowText = rows[i].textContent;
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
rows[i].style.display = '';
displayedData.push(allData[i]);
leaderboardData.labels.push(allData[i].model);
leaderboardData.datasets[0].data.push(allData[i].pass_rate_2);
} else {
rows[i].style.display = 'none';
}
}
leaderboardChart.update();
});
});

View File

@@ -1,5 +0,0 @@
{: .tip }
All API keys can be stored in a
[.env file](/docs/config/dotenv.html#storing-llm-keys)
or in a [YAML config file](/docs/config/aider_conf.html#storing-llm-keys).

View File

@@ -1,17 +1,16 @@
You can get started quickly like this:
If you already have python 3.8-3.13 installed, you can get started quickly like this:
```
python -m pip install -U aider-chat
# Change directory into a git repo
cd /to/your/git/repo
# Work with Claude 3.5 Sonnet on your repo
export ANTHROPIC_API_KEY=your-key-goes-here
aider
# Work with GPT-4o on your repo
export OPENAI_API_KEY=your-key-goes-here
aider
```bash
python -m pip install aider-install
aider-install
# Change directory into your code base
cd /to/your/project
# Work with Claude 3.5 Sonnet on your code
aider --model sonnet --anthropic-api-key your-key-goes-here
# Work with GPT-4o on your code
aider --model gpt-4o --openai-api-key your-key-goes-here
```

View File

@@ -19,6 +19,7 @@
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
{% if site.analytics.enabled %}
<!-- Cookie Consent -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css" />
<script src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js" data-cfasync="false"></script>
@@ -72,9 +73,10 @@ window.addEventListener('load', function(){
// PostHog initialization function
function initPostHog() {
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv', {
api_host:'https://us.i.posthog.com',
posthog.init('{{ site.analytics.posthog_key }}', {
api_host: '{{ site.analytics.posthog_host }}',
person_profiles: 'identified_only'
})
}
</script>
{% endif %}

View File

@@ -0,0 +1,4 @@
{: .tip :}
See the
[API key configuration docs](/docs/config/api-keys.html)
for information on how to configure and store your API keys.

View File

@@ -0,0 +1,190 @@
document.addEventListener('DOMContentLoaded', function () {
var ctx = document.getElementById('editChart').getContext('2d');
const blueDiagonalPattern = pattern.draw('diagonal', 'rgba(54, 162, 235, 0.2)');
const redDiagonalPattern = pattern.draw('diagonal', 'rgba(255, 99, 132, 0.2)');
let displayedData = [];
const HIGHLIGHT_MODEL = '{{ highlight_model | default: "no no no" }}';
var leaderboardData = {
labels: [],
datasets: [{
label: 'Percent completed correctly',
data: [],
backgroundColor: function(context) {
const row = allData[context.dataIndex];
if (row && row.edit_format === 'whole') {
return diagonalPattern;
}
const label = leaderboardData.labels[context.dataIndex] || '';
return (label && label.includes(HIGHLIGHT_MODEL)) ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)';
},
borderColor: function(context) {
const label = context.chart.data.labels[context.dataIndex] || '';
return (label && label.includes(HIGHLIGHT_MODEL)) ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)';
},
borderWidth: 1
}]
};
var allData = [];
{% for row in data_source %}
allData.push({
model: '{{ row.model }}',
pass_rate: {{ row[pass_rate_field] }},
percent_cases_well_formed: {{ row.percent_cases_well_formed }},
edit_format: '{{ row.edit_format | default: "diff" }}'
});
{% endfor %}
function updateChart() {
var selectedRows = document.querySelectorAll('tr.selected');
var showAll = selectedRows.length === 0;
displayedData = [];
leaderboardData.labels = [];
leaderboardData.datasets[0].data = [];
allData.forEach(function(row, index) {
var rowElement = document.getElementById('edit-row-' + index);
if (showAll) {
rowElement.classList.remove('selected');
}
if (showAll || rowElement.classList.contains('selected')) {
displayedData.push(row);
leaderboardData.labels.push(row.model);
leaderboardData.datasets[0].data.push(row.pass_rate);
}
});
leaderboardChart.update();
leaderboardChart.render();
}
// Use displayedData in the backgroundColor callback instead of allData
leaderboardData.datasets[0].backgroundColor = function(context) {
const row = displayedData[context.dataIndex];
const label = leaderboardData.labels[context.dataIndex] || '';
if (label && label.includes(HIGHLIGHT_MODEL)) {
if (row && row.edit_format === 'whole') return redDiagonalPattern;
else return 'rgba(255, 99, 132, 0.2)';
} else if (row && row.edit_format === 'whole') {
return blueDiagonalPattern;
} else {
return 'rgba(54, 162, 235, 0.2)';
}
};
var tableBody = document.querySelector('table tbody');
allData.forEach(function(row, index) {
var tr = tableBody.children[index];
if (!tr) {
// If the row doesn't exist, create it
tr = document.createElement('tr');
tableBody.appendChild(tr);
}
tr.id = 'edit-row-' + index;
tr.style.cursor = 'pointer';
tr.onclick = function() {
this.classList.toggle('selected');
updateChart();
};
});
var leaderboardChart = new Chart(ctx, {
type: 'bar',
data: leaderboardData,
options: {
plugins: {
legend: {
display: true,
labels: {
generateLabels: function(chart) {
return [
{
text: 'Diff-like format',
fillStyle: 'rgba(54, 162, 235, 0.2)',
strokeStyle: 'rgba(54, 162, 235, 1)',
lineWidth: 1
},
{
text: 'Whole format',
fillStyle: blueDiagonalPattern,
strokeStyle: 'rgba(54, 162, 235, 1)',
lineWidth: 1
}
];
}
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Percent completed correctly'
}
},
x: {
ticks: {
callback: function(value, index) {
const label = this.getLabelForValue(value);
if (label.length <= "claude-3-5-sonnet".length) {
return label;
}
// Find all possible split positions
const splitPositions = [];
for (let i = 0; i < label.length; i++) {
if (label[i] === '-' || label[i] === ' ') {
splitPositions.push(i);
}
}
if (splitPositions.length === 0) {
return label;
}
// Find split position closest to middle
const middle = label.length / 2;
const splitIndex = splitPositions.reduce((closest, current) => {
return Math.abs(current - middle) < Math.abs(closest - middle) ? current : closest;
});
return [
label.slice(0, splitIndex),
label.slice(splitIndex + 1)
];
}
}
}
}
}
});
updateChart();
// Add search functionality for edit table
document.getElementById('editSearchInput').addEventListener('keyup', function() {
var searchWords = this.value.toLowerCase().split(' ').filter(word => word.length > 0);
var tableBody = document.querySelector('table:first-of-type tbody');
var rows = tableBody.getElementsByTagName('tr');
displayedData = [];
leaderboardData.labels = [];
leaderboardData.datasets[0].data = [];
for (var i = 0; i < rows.length; i++) {
var rowText = rows[i].textContent;
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
rows[i].style.display = '';
displayedData.push(allData[i]);
leaderboardData.labels.push(allData[i].model);
leaderboardData.datasets[0].data.push(allData[i].pass_rate);
} else {
rows[i].style.display = 'none';
}
}
leaderboardChart.update();
});
});

View File

@@ -5,7 +5,10 @@ You can send long, multi-line messages in the chat in a few ways:
- Use Meta-ENTER to start a new line without sending the message (Esc+ENTER in some environments).
- Use `/paste` to paste text from the clipboard into the chat.
- Use the `/editor` command to open your editor to create the next chat message. See [editor configuration docs](/docs/config/editor.html) for more info.
- Use multiline-mode, which swaps the function of Meta-Enter and Enter, so that Enter inserts a newline, and Meta-Enter submits your command. To enable multiline mode:
- Use the `/multiline-mode` command to toggle it during a session.
- Use the `--multiline` switch.
Example with a tag:
```
{python

View File

@@ -1,90 +0,0 @@
document.addEventListener('DOMContentLoaded', function () {
var ctx = document.getElementById('refacChart').getContext('2d');
var leaderboardData = {
labels: [],
datasets: [{
label: 'Percent completed correctly',
data: [],
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
};
var allData = [];
{% for row in refac_sorted %}
allData.push({
model: '{{ row.model }}',
pass_rate_1: {{ row.pass_rate_1 }},
percent_cases_well_formed: {{ row.percent_cases_well_formed }}
});
{% endfor %}
function updateChart() {
var selectedRows = document.querySelectorAll('tr.selected');
var showAll = selectedRows.length === 0;
leaderboardData.labels = [];
leaderboardData.datasets[0].data = [];
allData.forEach(function(row, index) {
var rowElement = document.getElementById('refac-row-' + index);
if (showAll) {
rowElement.classList.remove('selected');
}
if (showAll || rowElement.classList.contains('selected')) {
leaderboardData.labels.push(row.model);
leaderboardData.datasets[0].data.push(row.pass_rate_1);
}
});
leaderboardChart.update();
}
var tableBody = document.querySelectorAll('table tbody')[1];
allData.forEach(function(row, index) {
var tr = tableBody.children[index];
tr.id = 'refac-row-' + index;
tr.style.cursor = 'pointer';
tr.onclick = function() {
this.classList.toggle('selected');
updateChart();
};
});
var leaderboardChart = new Chart(ctx, {
type: 'bar',
data: leaderboardData,
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
updateChart();
// Add search functionality for refactoring table
document.getElementById('refacSearchInput').addEventListener('keyup', function() {
var searchWords = this.value.toLowerCase().split(' ').filter(word => word.length > 0);
var tableBody = document.querySelectorAll('table tbody')[1];
var rows = tableBody.getElementsByTagName('tr');
leaderboardData.labels = [];
leaderboardData.datasets[0].data = [];
for (var i = 0; i < rows.length; i++) {
var rowText = rows[i].textContent;
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
rows[i].style.display = '';
leaderboardData.labels.push(allData[i].model);
leaderboardData.datasets[0].data.push(allData[i].pass_rate_1);
} else {
rows[i].style.display = 'none';
}
}
leaderboardChart.update();
});
});

View File

@@ -1,6 +1,6 @@
To use aider with pipx on replit, you can run these commands in the replit shell:
```
```bash
pip install pipx
pipx run aider-chat ...normal aider args...
```

View File

@@ -1,49 +0,0 @@
Aider has special support for providing
OpenAI and Anthropic API keys
via dedicated
[command line switches](/docs/config/options.html#api-keys-and-settings)
`--openai-api-key` and `--anthropic-api-key`.
You can also set those API keys via special entries in the
[yaml config file](/docs/config/aider_conf.html), like this:
```yaml
openai-api-key: <key>
anthropic-api-key: <key>
```
All other LLM providers can use one of the following methods to set their
keys:
### API keys on the command line
{: .no_toc }
Use `--api-key provider=<key>` which has the effect of setting the environment variable `PROVIDER_API_KEY=<key>`. So `--api-key gemini=xxx` would set `GEMINI_API_KEY=xxx`.
### API keys in a .env file
{: .no_toc }
The [.env file](/docs/config/dotenv.html)
is a great place to set API keys and other provider API environment variables:
```bash
GEMINI_API_KEY=foo
OPENROUTER_API_KEY=bar
DEEPSEEK_API_KEY=baz
```
### API keys in .aider.conf.yml
{: .no_toc }
Or you can set API keys in the
[`.aider.conf.yml` file](/docs/config/aider_conf.html)
via the `api-key` entry:
```
api-key:
- gemini=foo # Sets env var GEMINI_API_KEY=foo
- openrouter=bar # Sets env var OPENROUTER_API_KEY=bar
- deepseek=baz # Sets env var DEEPSEEK_API_KEY=baz
```

View File

@@ -1,7 +0,0 @@
{: .tip }
Using a Python
[virtual environment](https://docs.python.org/3/library/venv.html){:target="_blank"}
is recommended.
Or, you could
[use pipx to install aider](/docs/install/pipx.html)
once for your whole system.

View File

@@ -1,2 +1 @@
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
[connect to almost any LLM](https://aider.chat/docs/llms.html).
Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).

View File

@@ -1,6 +1,6 @@
---
title: Aider has written 7% of its own code
excerpt: Aider has written 7% of its own code, via 600+ commits that inserted 4.8K and deleted 1.5K lines of code.
title: Aider has written 7% of its own code (outdated, now 70%)
excerpt: This article is quite out dated. Aider is currently writing about 70% of the new code in each release.
highlight_image: /assets/self-assembly.jpg
nav_exclude: true
---
@@ -8,13 +8,16 @@ nav_exclude: true
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
{% endif %}
# Aider has written 7% of its own code
# Aider has written 7% of its own code (outdated, now 70%)
[![self assembly](/assets/self-assembly.jpg)](https://aider.chat/assets/self-assembly.jpg)
{: .note }
This article is quite out dated. For current statistics, see
[aider's release history](/HISTORY.html).
This article is quite old and outdated.
Aider is currently writing about 70% of the new code
in each release.
See
[aider's release history](/HISTORY.html) for the latest statistics.
The
[aider git repo](https://github.com/Aider-AI/aider)

View File

@@ -0,0 +1,216 @@
---
title: o1 tops aider's new polyglot leaderboard
excerpt: o1 scores the top result on aider's new multi-language, more challenging coding benchmark.
highlight_image: /assets/o1-polyglot.jpg
draft: false
nav_exclude: true
---
{% if page.date %}
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
{% endif %}
# o1 tops aider's new polyglot leaderboard
{: .no_toc }
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
OpenAI's new o1 model with "high" reasoning effort
gets the top score on the
new
[aider polyglot leaderboard](/docs/leaderboards/), significantly ahead of
other top LLMs.
The new polyglot benchmark uses many popular coding languages
and was designed to be
*much more challenging* than aider's original
[code editing benchmark](/docs/leaderboards/edit.html).
This more clearly distinguishes
the performance of
today's strongest coding models and
leaves headroom for future LLMs.
{: .note :}
See the main
[aider leaderboard](https://aider.chat/docs/leaderboards/)
for benchmark results from more models.
This article only contains a snapshot
of results at the time of publication.
## The polyglot benchmark
Like aider's original code editing benchmark,
the new polyglot benchmark is based on Exercism
coding exercises.
The new polyglot benchmark:
- Contains coding problems in C++, Go, Java, JavaScript, Python and Rust.
The old benchmark was solely based on Python exercises.
- Focuses on the *most difficult* 225 exercises out of the 697 that
Exercism provides for those languages.
The old benchmark simply included all 133 Python exercises,
regardless of difficulty.
## Motivation and goals
Aider's original code editing benchmark was
saturating as the top scores approached and then surpassed 80%.
Sonnet's score of 84.2% was based on solving 112 of the 133
exercises, leaving only 21 unsolved exercises.
New champions were advancing the top score by
solving just 1-2 more problems than the previous record.
This made it hard to clearly
measure the
difference in code editing skill between these top models.
Part of the problem is that many of the original
133 Python problems are very easy
and provide
little challenge to today's frontier LLMs.
Models as old as GPT 3.5 Turbo were able to solve half of the
133 problems.
Such easy problems simply inflate the benchmark scores
of modern LLMs without
providing any data about which models are better or worse.
The main goal for a new benchmark
was to re-calibrate the scale so that
today's top coding LLMs
would occupy a wide range of scores between about 5% and 50%.
This should leave headroom for future LLMs and
make it possible to
more clearly compare the relative performance of top models.
## Designing the polyglot benchmark
The new benchmark:
- Tests LLMs with more coding languages, to increase diversity and source a larger pool of problems.
- Includes just the most challenging coding problems and excludes easy problems that are solvable by most of today's top coding LLMs.
- Includes more total coding problems, to enable more granularity of comparison.
The new benchmark is based on Exercism coding problems
from 6 of the most popular programming languages:
- C++
- Go
- Java
- JavaScript
- Python
- Rust
Exercism provides a total of 697 coding problems in those 6 languages.
A set of 7 of today's top coding models each attempted all 697 of
the Exercism problems:
- Sonnet
- Haiku
- o1 Mini
- DeepSeek
- GPT-4o
- Qwen 32B Coder Instruct
- GPT-4o Mini
Depending on the difficulty of the problems,
a different number of solutions were found by the collection of
7 models:
| Solutions<br>found | Number of<br>problems | Cumulative number<br>of problems |
|--------|-----------|------------|
| 0 | 66 | 66 |
| 1 | 61 | 127 |
| 2 | 50 | 177 |
| 3 | 48 | 225 |
| 4 | 53 | 278 |
| 5 | 71 | 349 |
| 6 | 90 | 439 |
| 7 | 258 | 697 |
In the table above, you can see that 258 of the problems were solved
by all 7 LLMs.
These problems are far too easy, and wouldn't be good choices for the new benchmark.
Instead, we need hard problems like the
66 that none of the 7 models were able to solve.
The new benchmark uses
the 225 problems that were solved by 3 or fewer models.
This achieves a balance between hard and moderate problems,
and provides a large but not excessive total pool of problems.
It also represents a good diversity of coding languages:
| Language | Problems |
|-------------|----------|
| C++ | 26 |
| Go | 39 |
| Java | 47 |
| JavaScript | 49 |
| Python | 34 |
| Rust | 30 |
| **Total** | **225** |
## o1
OpenAI's new o1 model established a very strong
top score of 62% on the new benchmark.
This still leaves 86 problems of headroom for future models
to solve.
Given the incredible pace of recent advancements, it
will be interesting to see
how long it will take for this new benchmark to saturate.
## Benchmark problems
The 225 coding problems are available in the
[aider polyglot benchmark repo](https://github.com/Aider-AI/polyglot-benchmark)
on GitHub.
## Results
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
<thead style="background-color: #f2f2f2;">
<tr>
<th style="padding: 8px; text-align: left;">Model</th>
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
<th style="padding: 8px; text-align: left;">Command</th>
<th style="padding: 8px; text-align: center;">Edit format</th>
</tr>
</thead>
<tbody>
{% assign edit_sorted = site.data.o1_polyglot_leaderboard | sort: 'pass_rate_2' | reverse %}
{% for row in edit_sorted %}
<tr style="border-bottom: 1px solid #ddd;">
<td style="padding: 8px;">{{ row.model }}</td>
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_2 }}%</td>
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% assign data_source = edit_sorted %}
{% assign pass_rate_field = "pass_rate_2" %}
{% assign highlight_model = "o1-2024" %}
{% include leaderboard.js %}
</script>
<style>
tr.selected {
color: #0056b3;
}
table {
table-layout: fixed;
}
td, th {
word-wrap: break-word;
overflow-wrap: break-word;
}
td:nth-child(3), td:nth-child(4) {
font-size: 12px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -44,7 +44,7 @@
## Use gpt-3.5-turbo model for the main chat
#35turbo: false
## Use deepseek/deepseek-coder model for the main chat
## Use deepseek/deepseek-chat model for the main chat
#deepseek: false
## Use o1-mini model for the main chat
@@ -152,7 +152,7 @@
###################
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
## Suggested number of tokens to use for repo map, use 0 to disable
#map-tokens: xxx
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
@@ -218,7 +218,7 @@
## Set the background color for the current item in the completion menu (default: terminal's default text color)
#completion-menu-current-bg-color: xxx
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
#code-theme: default
## Show diffs when committing changes (default: False)
@@ -422,6 +422,9 @@
## Enable/disable fancy input with history and completion (default: True)
#fancy-input: true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#multiline: false
## Enable/disable detection and offering to add URLs to chat (default: True)
#detect-urls: true

View File

@@ -48,7 +48,7 @@
## Use gpt-3.5-turbo model for the main chat
#AIDER_35TURBO=
## Use deepseek/deepseek-coder model for the main chat
## Use deepseek/deepseek-chat model for the main chat
#AIDER_DEEPSEEK=
## Use o1-mini model for the main chat
@@ -141,7 +141,7 @@
###################
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
## Suggested number of tokens to use for repo map, use 0 to disable
#AIDER_MAP_TOKENS=
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
@@ -207,7 +207,7 @@
## Set the background color for the current item in the completion menu (default: terminal's default text color)
#AIDER_COMPLETION_MENU_CURRENT_BG_COLOR=
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
#AIDER_CODE_THEME=default
## Show diffs when committing changes (default: False)
@@ -390,6 +390,9 @@
## Enable/disable fancy input with history and completion (default: True)
#AIDER_FANCY_INPUT=true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#AIDER_MULTILINE=false
## Enable/disable detection and offering to add URLs to chat (default: True)
#AIDER_DETECT_URLS=true

View File

@@ -40,5 +40,5 @@ Using an `.env` file:
AIDER_DARK_MODE=true
```
{% include env-keys-tip.md %}
{% include keys.md %}

View File

@@ -50,6 +50,7 @@ The json file should be a dictionary with an entry for each model, as follows:
Use a fully qualified model name with a `provider/` at the front
in the `.aider.model.metadata.json` file.
For example, use `deepseek/deepseek-chat`, not just `deepseek-chat`.
That prefix should match the `litellm_provider` field.
### Contribute model metadata
@@ -1062,6 +1063,22 @@ cog.out("```\n")
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: null
editor_model_name: null
examples_as_sys_msg: false
extra_params: null
lazy: false
name: gemini/gemini-2.0-flash-exp
reminder: user
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
@@ -1146,6 +1163,22 @@ cog.out("```\n")
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: null
editor_model_name: null
examples_as_sys_msg: true
extra_params: null
lazy: false
name: openrouter/deepseek/deepseek-chat
reminder: sys
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
@@ -1290,6 +1323,54 @@ cog.out("```\n")
use_system_prompt: false
use_temperature: false
weak_model_name: openrouter/openai/gpt-4o-mini
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: editor-diff
editor_model_name: openrouter/openai/gpt-4o
examples_as_sys_msg: false
extra_params: null
lazy: false
name: openrouter/openai/o1
reminder: user
send_undo_reply: false
streaming: false
use_repo_map: true
use_system_prompt: true
use_temperature: false
weak_model_name: openrouter/openai/gpt-4o-mini
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: editor-diff
editor_model_name: openai/gpt-4o
examples_as_sys_msg: false
extra_params: null
lazy: false
name: openai/o1
reminder: user
send_undo_reply: false
streaming: false
use_repo_map: true
use_system_prompt: true
use_temperature: false
weak_model_name: openai/gpt-4o-mini
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: editor-diff
editor_model_name: gpt-4o
examples_as_sys_msg: false
extra_params: null
lazy: false
name: o1
reminder: user
send_undo_reply: false
streaming: false
use_repo_map: true
use_system_prompt: true
use_temperature: false
weak_model_name: gpt-4o-mini
- cache_control: false
caches_by_default: false
edit_format: diff

View File

@@ -15,11 +15,7 @@ load whichever is found first.
- The root of your git repo.
- Your home directory.
## Storing LLM keys
{% include special-keys.md %}
{% include env-keys-tip.md %}
{% include keys.md %}
## A note on lists
@@ -100,7 +96,7 @@ cog.outl("```")
## Use gpt-3.5-turbo model for the main chat
#35turbo: false
## Use deepseek/deepseek-coder model for the main chat
## Use deepseek/deepseek-chat model for the main chat
#deepseek: false
## Use o1-mini model for the main chat
@@ -208,7 +204,7 @@ cog.outl("```")
###################
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
## Suggested number of tokens to use for repo map, use 0 to disable
#map-tokens: xxx
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
@@ -274,7 +270,7 @@ cog.outl("```")
## Set the background color for the current item in the completion menu (default: terminal's default text color)
#completion-menu-current-bg-color: xxx
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
#code-theme: default
## Show diffs when committing changes (default: False)
@@ -478,6 +474,9 @@ cog.outl("```")
## Enable/disable fancy input with history and completion (default: True)
#fancy-input: true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#multiline: false
## Enable/disable detection and offering to add URLs to chat (default: True)
#detect-urls: true

View File

@@ -0,0 +1,90 @@
---
parent: Configuration
nav_order: 5
description: Setting API keys for API providers.
---
# API Keys
Aider lets you specify API keys in a few ways:
- On the command line
- As environment variables
- In a `.env` file
- In your `.aider.conf.yml` config file
---
## OpenAI and Anthropic
Aider has special support for providing
OpenAI and Anthropic API keys
via dedicated switches and configuration options.
Settings keys for other providers works a bit differently, see below.
#### Command line
You can set OpenAI and Anthropic API keys via
[command line switches](/docs/config/options.html#api-keys-and-settings)
`--openai-api-key` and `--anthropic-api-key`.
#### Environment variables or .env file
You can also store them in environment variables or a
[.env file](/docs/config/dotenv.html), which also works
for every API provider:
```
OPENAI_API_KEY=<key>
ANTHROPIC_API_KEY=<key>
```
#### Yaml config file
You can also set those API keys via special entries in the
[yaml config file](/docs/config/aider_conf.html), like this:
```yaml
openai-api-key: <key>
anthropic-api-key: <key>
```
---
## Other API providers
All other LLM providers can use one of these other methods to set their API keys.
#### Command line
{: .no_toc }
Use `--api-key provider=<key>` which has the effect of setting the environment variable `PROVIDER_API_KEY=<key>`. So `--api-key gemini=xxx` would set `GEMINI_API_KEY=xxx`.
#### Environment variables or .env file
{: .no_toc }
You can set API keys in environment variables.
The [.env file](/docs/config/dotenv.html)
is a great place to store your API keys and other provider API environment variables:
```bash
GEMINI_API_KEY=foo
OPENROUTER_API_KEY=bar
DEEPSEEK_API_KEY=baz
```
#### Yaml config file
You can also set API keys in the
[`.aider.conf.yml` file](/docs/config/aider_conf.html)
via the `api-key` entry:
```
api-key:
- gemini=foo # Sets env var GEMINI_API_KEY=foo
- openrouter=bar # Sets env var OPENROUTER_API_KEY=bar
- deepseek=baz # Sets env var DEEPSEEK_API_KEY=baz
```

View File

@@ -20,11 +20,7 @@ Aider will look for a `.env` file in these locations:
If the files above exist, they will be loaded in that order. Files loaded last will take priority.
## Storing LLM keys
{% include special-keys.md %}
{% include env-keys-tip.md %}
{% include keys.md %}
## Sample .env file
@@ -92,7 +88,7 @@ cog.outl("```")
## Use gpt-3.5-turbo model for the main chat
#AIDER_35TURBO=
## Use deepseek/deepseek-coder model for the main chat
## Use deepseek/deepseek-chat model for the main chat
#AIDER_DEEPSEEK=
## Use o1-mini model for the main chat
@@ -185,7 +181,7 @@ cog.outl("```")
###################
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
## Suggested number of tokens to use for repo map, use 0 to disable
#AIDER_MAP_TOKENS=
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
@@ -251,7 +247,7 @@ cog.outl("```")
## Set the background color for the current item in the completion menu (default: terminal's default text color)
#AIDER_COMPLETION_MENU_CURRENT_BG_COLOR=
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
#AIDER_CODE_THEME=default
## Show diffs when committing changes (default: False)
@@ -434,6 +430,9 @@ cog.outl("```")
## Enable/disable fancy input with history and completion (default: True)
#AIDER_FANCY_INPUT=true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#AIDER_MULTILINE=false
## Enable/disable detection and offering to add URLs to chat (default: True)
#AIDER_DETECT_URLS=true

View File

@@ -55,7 +55,8 @@ for alias, model in sorted(MODEL_ALIASES.items()):
- `4`: gpt-4-0613
- `4-turbo`: gpt-4-1106-preview
- `4o`: gpt-4o
- `deepseek`: deepseek/deepseek-coder
- `deepseek`: deepseek/deepseek-chat
- `flash`: gemini/gemini-2.0-flash-exp
- `haiku`: claude-3-5-haiku-20241022
- `opus`: claude-3-opus-20240229
- `sonnet`: claude-3-5-sonnet-20241022

View File

@@ -13,9 +13,7 @@ or review them below.
- TOC
{:toc}
## LLM keys
{% include special-keys.md %}
{% include keys.md %}
## Usage summary
@@ -78,6 +76,7 @@ usage: aider [-h] [--model] [--opus] [--sonnet] [--haiku] [--4]
[--encoding] [-c] [--env-file]
[--suggest-shell-commands | --no-suggest-shell-commands]
[--fancy-input | --no-fancy-input]
[--multiline | --no-multiline]
[--detect-urls | --no-detect-urls] [--editor]
```
@@ -137,7 +136,7 @@ Aliases:
- `-3`
### `--deepseek`
Use deepseek/deepseek-coder model for the main chat
Use deepseek/deepseek-chat model for the main chat
Environment variable: `AIDER_DEEPSEEK`
### `--o1-mini`
@@ -276,7 +275,7 @@ Environment variable: `AIDER_CACHE_KEEPALIVE_PINGS`
## Repomap settings:
### `--map-tokens VALUE`
Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
Suggested number of tokens to use for repo map, use 0 to disable
Environment variable: `AIDER_MAP_TOKENS`
### `--map-refresh VALUE`
@@ -382,7 +381,7 @@ Set the background color for the current item in the completion menu (default: t
Environment variable: `AIDER_COMPLETION_MENU_CURRENT_BG_COLOR`
### `--code-theme VALUE`
Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
Default: default
Environment variable: `AIDER_CODE_THEME`
@@ -733,6 +732,14 @@ Aliases:
- `--fancy-input`
- `--no-fancy-input`
### `--multiline`
Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
Default: False
Environment variable: `AIDER_MULTILINE`
Aliases:
- `--multiline`
- `--no-multiline`
### `--detect-urls`
Enable/disable detection and offering to add URLs to chat (default: True)
Default: True

View File

@@ -209,6 +209,39 @@ all the raw information being sent to/from the LLM in the conversation.
You can also refer to the
[instructions for installing a development version of aider](https://aider.chat/docs/install/optional.html#install-the-development-version-of-aider).
## What LLMs do you use to build aider?
Aider writes a lot of its own code, usually about 70% of the new code in each
release.
People often ask which LLMs I use with aider, when writing aider.
Below is a table showing the models I have used recently,
extracted from the
[public log](https://github.com/aider-ai/aider/blob/main/aider/website/assets/sample-analytics.jsonl)
of my
[aider analytics](https://aider.chat/docs/more/analytics.html).
<!--[[[cog
import sys
sys.path.append(".")
import scripts.my_models as my_models
stats = my_models.collect_model_stats()
html = my_models.format_html_table(stats)
cog.out(html)
]]]-->
<style>
table { border-collapse: collapse; width: 100%; }
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
th { background-color: #f2f2f2; }
tr:hover { background-color: #f5f5f5; }
.right { text-align: right; }
</style>
<table>
<tr><th>Model Name</th><th class='right'>Total Tokens</th><th class='right'>Percent</th></tr>
<tr><td>deepseek/deepseek-chat</td><td class='right'>1,258,436</td><td class='right'>86.2%</td></tr>
<tr><td>claude-3-5-sonnet-20241022</td><td class='right'>178,352</td><td class='right'>12.2%</td></tr>
<tr><td>o1</td><td class='right'>22,748</td><td class='right'>1.6%</td></tr>
</table>
<!--[[[end]]]-->
## How are the "aider wrote xx% of code" stats computed?
@@ -220,6 +253,31 @@ by doing something like `git blame` on the repo,
and counting up who wrote all the new lines of code in each release.
Only lines in source code files are counted, not documentation or prompt files.
## Why does aider sometimes stop highlighting code in its replies?
Aider displays the markdown responses that are coming back from the LLM.
Usually, the LLM will reply with code in a markdown "code block" with
triple backtick fences, like this:
````
Here's some code:
```
print("hello")
```
````
But if you've added files to the chat that contain triple backticks,
aider needs to tell the LLM to use a different set of fences.
Otherwise, the LLM can't safely include your code's triple backticks
inside the code blocks that it returns with edits.
Aider will use fences like `<source>...</source>` in this case.
A side effect of this is that the code that aider outputs may no
longer be properly highlighted.
You will most often notice this if you add markdown files
to you chats that contain code blocks.
## Why is the LLM speaking to me in an unexpected language?
Aider goes to some effort to prompt the model to use the language that is configured

View File

@@ -5,41 +5,118 @@ nav_order: 20
description: How to install and get started pair programming with aider.
---
# Quick start
# Installation
{: .no_toc }
## Get started quickly with aider-install
{% include get-started.md %}
Or see the
[full installation instructions](/docs/install/install.html)
for more details,
or the
[usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
This will install aider in its own separate python environment.
If needed,
aider-install will also install a separate version of python 3.12 to use with aider.
Once aider is installed,
there are also some [optional install steps](/docs/install/optional.html).
See the [usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
## One-liners
These one-liners will install aider, along with python 3.12 if needed.
They are based on the
[uv installers](https://docs.astral.sh/uv/getting-started/installation/).
#### Windows
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://aider.chat/install.ps1 | iex"
```
#### Mac & Linux
Use curl to download the script and execute it with sh:
```bash
curl -LsSf https://aider.chat/install.sh | sh
```
If your system doesn't have curl, you can use wget:
```bash
wget -qO- https://aider.chat/install.sh | sh
```
## Install with uv
You can install aider with uv:
```bash
python -m pip install uv # If you need to install uv
uv tool install --force --python python3.12 aider-chat@latest
```
This will install uv using your existing python version 3.8-3.13,
and use it to install aider.
If needed,
uv will automatically install a separate python 3.12 to use with aider.
Also see the
[docs on other methods for installing uv itself](https://docs.astral.sh/uv/getting-started/installation/).
## Install with pipx
You can install aider with pipx:
```bash
python -m pip install pipx # If you need to install pipx
pipx install aider-chat
```
You can use pipx to install aider with python versions 3.9-3.12.
Also see the
[docs on other methods for installing pipx itself](https://pipx.pypa.io/stable/installation/).
## Other install methods
You can install aider with the methods described below, but one of the above
methods is usually safer.
#### Install with pip
If you install with pip, you should consider
using a
[virtual environment](https://docs.python.org/3/library/venv.html)
to keep aider's dependencies separated.
You can use pip to install aider with python versions 3.9-3.12.
```bash
# Install aider
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
# To work with GPT-4o:
aider --4o --openai-api-key sk-xxx...
# To work with Claude 3.5 Sonnet:
aider --sonnet --anthropic-api-key sk-xxx...
```
{% include python-m-aider.md %}
<div class="video-container">
<video controls poster="/assets/install.jpg">
<source src="/assets/install.mp4" type="video/mp4">
<a href="/assets/install.mp4">Installing aider</a>
</video>
</div>
#### Installing with package managers
<style>
.video-container {
position: relative;
padding-bottom: 76.2711864407%;
height: 0;
overflow: hidden;
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
It's best to install aider using one of methods
recommended above.
While aider is available in a number of system package managers,
they often install aider with incorrect dependencies.
## Next steps...
There are some [optional install steps](/docs/install/optional.html) you could consider.
See the [usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.

View File

@@ -8,9 +8,9 @@ nav_order: 900
You can use aider in GitHub Codespaces via the built-in Terminal pane.
See below for an example,
but you can see the
but you can just follow the
[main install instructions](/docs/install.html)
for all the details.
inside your codespace terminal.
<div class="video-container">

View File

@@ -1,70 +0,0 @@
---
parent: Installation
nav_order: 10
---
# Installing aider
{: .no_toc }
- TOC
{:toc}
## Python version
Aider currently works with python 3.9-3.12.
## Install git
Make sure you have git installed.
Here are
[instructions for installing git in various environments](https://github.com/git-guides/install-git).
## Get your API key
To work with OpenAI's models like GPT-4o or GPT-3.5 you need a paid
[OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key).
Note that this is different than being a "ChatGPT Plus" subscriber.
To work with Anthropic's models like Claude 3.5 Sonnet you need a paid
[Anthropic API key](https://docs.anthropic.com/claude/reference/getting-started-with-the-api).
{% include venv-pipx.md %}
## Mac/Linux install
```
# Install aider
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
# To work with GPT-4o:
$ aider --4o --openai-api-key sk-xxx...
# To work with Claude 3.5 Sonnet:
$ aider --sonnet --anthropic-api-key sk-xxx...
```
## Windows install
```
# Install aider
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
# To work with GPT-4o:
$ aider --4o --openai-api-key sk-xxx...
# To work with Claude 3.5 Sonnet:
$ aider --sonnet --anthropic-api-key sk-xxx...
```
{% include python-m-aider.md %}
## Working with other LLMs
{% include works-best.md %}
## You are done!
There are some [optional install steps](/docs/install/optional.html) you could consider.
See the [usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.

View File

@@ -11,10 +11,29 @@ The steps below are completely optional.
- TOC
{:toc}
## Install git
## Store your api keys
Aider works best if you have git installed.
Here are
[instructions for installing git in various environments](https://github.com/git-guides/install-git).
You can [store your api keys in a .env file](/docs/config/dotenv.html)
## Get your API key
To work with OpenAI's models like GPT-4o or o1-preview you need a paid
[OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key).
Note that this is different than being a "ChatGPT Plus" subscriber.
To work with Anthropic's models like Claude 3.5 Sonnet you need a paid
[Anthropic API key](https://docs.anthropic.com/claude/reference/getting-started-with-the-api).
### Working with other LLMs
{% include works-best.md %}
### Store your api keys
You can [store your api keys in configuration or env files](/docs/config/api-keys.html)
and they will be loaded automatically whenever you run aider.
## Enable Playwright
@@ -55,13 +74,17 @@ Installing PortAudio is completely optional, but can usually be accomplished lik
- For Linux, do `sudo apt-get install libportaudio2`
- Some linux environments may also need `sudo apt install libasound2-plugins`
## Add aider to your editor
## Add aider to your IDE/editor
Other projects have integrated aider into some IDE/editors.
It's not clear if they are tracking the latest
You can use
[aider's `--watch-files` mode](https://aider.chat/docs/usage/watch.html)
to integrate with any IDE or editor.
There are a number of 3rd party aider plugins for various IDE/editors.
It's not clear how well they are tracking the latest
versions of aider,
so it may be best to just run the latest
aider in a terminal alongside your editor.
aider in a terminal alongside your editor and use `--watch-files`.
### NeoVim
@@ -71,29 +94,22 @@ aider in a terminal alongside your editor.
### VS Code
joshuavial also confirmed that aider works inside a VS Code terminal window.
Aider detects if it is running inside VSCode and turns off pretty/color output,
since the VSCode terminal doesn't seem to support it well.
You can run aider inside a VS Code terminal window.
There are a number of 3rd party
[aider plugins for VSCode](https://marketplace.visualstudio.com/search?term=aider%20-kodu&target=VSCode&category=All%20categories&sortBy=Relevance).
### Other editors
If you are interested in creating an aider plugin for your favorite editor,
please let me know by opening a
please let us know by opening a
[GitHub issue](https://github.com/Aider-AI/aider/issues).
## Install the development version of aider
If you want the very latest development version of aider
you can install directly from GitHub:
you can install it like this:
```
python -m pip install --upgrade git+https://github.com/Aider-AI/aider.git
aider --install-main-branch
```
If you've git cloned the aider repository already, you can install "live" from your local copy. This is mostly useful if you are developing aider and want your current modifications to take effect immediately.
```
python -m pip install -e .
```

View File

@@ -1,33 +0,0 @@
---
parent: Installation
nav_order: 100
---
# Install with pipx
If you are using aider to work on a python project, sometimes your project will require
specific versions of python packages which conflict with the versions that aider
requires.
If this happens, the `python -m pip install` command may return errors like these:
```
aider-chat 0.23.0 requires somepackage==X.Y.Z, but you have somepackage U.W.V which is incompatible.
```
You can avoid this problem by installing aider using `pipx`,
which will install it globally on your system
within its own python environment.
This way you can use aider to work on any python project,
even if that project has conflicting dependencies.
Install [pipx](https://pipx.pypa.io/stable/) then just do:
```
pipx install aider-chat
```
## pipx on replit
{% include replit-pipx.md %}

View File

@@ -0,0 +1,8 @@
---
parent: Installation
nav_order: 900
---
### Replit
{% include replit-pipx.md %}

View File

@@ -0,0 +1,10 @@
---
title: Scores by release date
parent: Aider LLM Leaderboards
nav_order: 200
---
## LLM code editing skill by model release date
[![connecting to many LLMs](/assets/models-over-time.svg)](https://aider.chat/assets/models-over-time.svg)

View File

@@ -0,0 +1,14 @@
---
parent: Aider LLM Leaderboards
nav_order: 900
---
# Contributing results
Contributions of benchmark results are welcome!
See the
[benchmark README](https://github.com/Aider-AI/aider/blob/main/benchmark/README.md)
for information on running aider's code editing benchmarks.
Submit results by opening a PR with edits to the
[benchmark results data files](https://github.com/Aider-AI/aider/blob/main/aider/website/_data/).

View File

@@ -0,0 +1,134 @@
---
parent: Aider LLM Leaderboards
highlight_image: /assets/leaderboard.jpg
nav_order: 50
description: Quantitative benchmark of basic LLM code editing skill.
---
# Code editing leaderboard
{: .note :}
This old
[aider code editing leaderboard](edit.html)
has been replaced by the
new, much more challenging
[polyglot leaderboard](/docs/leaderboards/).
[Aider's code editing benchmark](/docs/benchmarks.html#the-benchmark) asks the LLM to edit python source files to complete 133 small coding exercises
from Exercism.
This measures the LLM's coding ability, and whether it can
write new code that integrates into existing code.
The model also has to successfully apply all its changes to the source file without human intervention.
<input type="text" id="editSearchInput" placeholder="Search..." style="width: 100%; max-width: 800px; margin: 10px auto; padding: 8px; display: block; border: 1px solid #ddd; border-radius: 4px;">
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
<thead style="background-color: #f2f2f2;">
<tr>
<th style="padding: 8px; text-align: left;">Model</th>
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
<th style="padding: 8px; text-align: left;">Command</th>
<th style="padding: 8px; text-align: center;">Edit format</th>
</tr>
</thead>
<tbody>
{% assign edit_sorted = site.data.edit_leaderboard | sort: 'pass_rate_2' | reverse %}
{% for row in edit_sorted %}
<tr style="border-bottom: 1px solid #ddd;">
<td style="padding: 8px;">{{ row.model }}</td>
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_2 }}%</td>
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% assign data_source = edit_sorted %}
{% assign pass_rate_field = "pass_rate_2" %}
{% include leaderboard.js %}
</script>
<style>
tr.selected {
color: #0056b3;
}
table {
table-layout: fixed;
}
td, th {
word-wrap: break-word;
overflow-wrap: break-word;
}
td:nth-child(3), td:nth-child(4) {
font-size: 12px;
}
</style>
## Notes on benchmarking results
The key benchmarking results are:
- **Percent completed correctly** - Measures what percentage of the coding tasks that the LLM completed successfully. To complete a task, the LLM must solve the programming assignment *and* edit the code to implement that solution.
- **Percent using correct edit format** - Measures the percent of coding tasks where the LLM complied with the edit format specified in the system prompt. If the LLM makes edit mistakes, aider will give it feedback and ask for a fixed copy of the edit. The best models can reliably conform to the edit format, without making errors.
## Notes on the edit format
Aider uses different "edit formats" to collect code edits from different LLMs.
The "whole" format is the easiest for an LLM to use, but it uses a lot of tokens
and may limit how large a file can be edited.
Models which can use one of the diff formats are much more efficient,
using far fewer tokens.
Models that use a diff-like format are able to
edit larger files with less cost and without hitting token limits.
Aider is configured to use the best edit format for the popular OpenAI and Anthropic models
and the [other models recommended on the LLM page](/docs/llms.html).
For lesser known models aider will default to using the "whole" editing format
since it is the easiest format for an LLM to use.
## Contributing benchmark results
Contributions of benchmark results are welcome!
See the
[benchmark README](https://github.com/Aider-AI/aider/blob/main/benchmark/README.md)
for information on running aider's code editing benchmarks.
Submit results by opening a PR with edits to the
[benchmark results data files](https://github.com/Aider-AI/aider/blob/main/aider/website/_data/).
<p class="post-date">
By Paul Gauthier,
last updated
<!--[[[cog
import subprocess
import datetime
files = [
'aider/website/docs/leaderboards/index.md',
'aider/website/_data/edit_leaderboard.yml',
'aider/website/_data/refactor_leaderboard.yml'
]
def get_last_modified_date(file):
result = subprocess.run(['git', 'log', '-1', '--format=%ct', file], capture_output=True, text=True)
if result.returncode == 0:
timestamp = int(result.stdout.strip())
return datetime.datetime.fromtimestamp(timestamp)
return datetime.datetime.min
mod_dates = [get_last_modified_date(file) for file in files]
latest_mod_date = max(mod_dates)
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
]]]-->
December 16, 2024.
<!--[[[end]]]-->
</p>

View File

@@ -2,32 +2,43 @@
highlight_image: /assets/leaderboard.jpg
nav_order: 950
description: Quantitative benchmarks of LLM code editing skill.
has_children: true
---
# Aider LLM Leaderboards
{: .no_toc }
Aider works best with LLMs which are good at *editing* code, not just good at writing
code.
To evaluate an LLM's editing skill, aider uses a pair of benchmarks that
To evaluate an LLM's editing skill, aider uses benchmarks that
assess a model's ability to consistently follow the system prompt
to successfully edit code.
The leaderboards below report the results from a number of popular LLMs.
The leaderboards report the results from a number of popular LLMs.
While [aider can connect to almost any LLM](/docs/llms.html),
it works best with models that score well on the benchmarks.
See the following sections for benchmark
results and additional information:
- TOC
{:toc}
## Code editing leaderboard
{: .note :}
The
[original aider code editing leaderboard](edit.html)
has been replaced by this
new, much more challenging
[polyglot leaderboard](https://aider.chat/2024/12/21/polyglot.html).
[Aider's code editing benchmark](/docs/benchmarks.html#the-benchmark) asks the LLM to edit python source files to complete 133 small coding exercises
## Polyglot leaderboard
[Aider's polyglot benchmark](/docs/benchmarks.html#the-benchmark)
asks the LLM to edit source files to complete 225 coding exercises
from Exercism.
This measures the LLM's coding ability, and whether it can
It contains exercises in many popular programming languages:
C++, Go, Java, JavaScript, Python and Rust.
The 225 exercises were purposely selected to be the *hardest*
that Exercism offered in those languages, to provide
a strong coding challenge to LLMs.
This benchmark measures the LLM's coding ability in popular languages,
and whether it can
write new code that integrates into existing code.
The model also has to successfully apply all its changes to the source file without human intervention.
@@ -44,7 +55,7 @@ The model also has to successfully apply all its changes to the source file with
</tr>
</thead>
<tbody>
{% assign edit_sorted = site.data.edit_leaderboard | sort: 'pass_rate_2' | reverse %}
{% assign edit_sorted = site.data.polyglot_leaderboard | sort: 'pass_rate_2' | reverse %}
{% for row in edit_sorted %}
<tr style="border-bottom: 1px solid #ddd;">
<td style="padding: 8px;">{{ row.model }}</td>
@@ -57,11 +68,16 @@ The model also has to successfully apply all its changes to the source file with
</tbody>
</table>
### Aider polyglot benchmark results
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% include edit-leaderboard.js %}
{% assign data_source = edit_sorted %}
{% assign pass_rate_field = "pass_rate_2" %}
{% assign highlight_model = "xxxxxxxxxxx" %}
{% include leaderboard.js %}
</script>
<style>
tr.selected {
@@ -79,84 +95,7 @@ The model also has to successfully apply all its changes to the source file with
}
</style>
## Code refactoring leaderboard
[Aider's refactoring benchmark](https://github.com/Aider-AI/refactor-benchmark) asks the LLM to refactor 89 large methods from large python classes. This is a more challenging benchmark, which tests the model's ability to output long chunks of code without skipping sections or making mistakes. It was developed to provoke and measure [GPT-4 Turbo's "lazy coding" habit](/2023/12/21/unified-diffs.html).
The refactoring benchmark requires a large context window to
work with large source files.
Therefore, results are available for fewer models.
<input type="text" id="refacSearchInput" placeholder="Search..." style="width: 100%; max-width: 800px; margin: 10px auto; padding: 8px; display: block; border: 1px solid #ddd; border-radius: 4px;">
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
<thead style="background-color: #f2f2f2;">
<tr>
<th style="padding: 8px; text-align: left;">Model</th>
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
<th style="padding: 8px; text-align: left;">Command</th>
<th style="padding: 8px; text-align: center;">Edit format</th>
</tr>
</thead>
<tbody>
{% assign refac_sorted = site.data.refactor_leaderboard | sort: 'pass_rate_1' | reverse %}
{% for row in refac_sorted %}
<tr style="border-bottom: 1px solid #ddd;">
<td style="padding: 8px;">{{ row.model }}</td>
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_1 }}%</td>
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<canvas id="refacChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% include refactor-leaderboard.js %}
</script>
## LLM code editing skill by model release date
[![connecting to many LLMs](/assets/models-over-time.svg)](https://aider.chat/assets/models-over-time.svg)
## Notes on benchmarking results
The key benchmarking results are:
- **Percent completed correctly** - Measures what percentage of the coding tasks that the LLM completed successfully. To complete a task, the LLM must solve the programming assignment *and* edit the code to implement that solution.
- **Percent using correct edit format** - Measures the percent of coding tasks where the LLM complied with the edit format specified in the system prompt. If the LLM makes edit mistakes, aider will give it feedback and ask for a fixed copy of the edit. The best models can reliably conform to the edit format, without making errors.
## Notes on the edit format
Aider uses different "edit formats" to collect code edits from different LLMs.
The "whole" format is the easiest for an LLM to use, but it uses a lot of tokens
and may limit how large a file can be edited.
Models which can use one of the diff formats are much more efficient,
using far fewer tokens.
Models that use a diff-like format are able to
edit larger files with less cost and without hitting token limits.
Aider is configured to use the best edit format for the popular OpenAI and Anthropic models
and the [other models recommended on the LLM page](/docs/llms.html).
For lesser known models aider will default to using the "whole" editing format
since it is the easiest format for an LLM to use.
## Contributing benchmark results
Contributions of benchmark results are welcome!
See the
[benchmark README](https://github.com/Aider-AI/aider/blob/main/benchmark/README.md)
for information on running aider's code editing benchmarks.
Submit results by opening a PR with edits to the
[benchmark results data files](https://github.com/Aider-AI/aider/blob/main/aider/website/_data/).
<p class="post-date">
@@ -183,6 +122,6 @@ mod_dates = [get_last_modified_date(file) for file in files]
latest_mod_date = max(mod_dates)
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
]]]-->
December 10, 2024.
December 26, 2024.
<!--[[[end]]]-->
</p>

View File

@@ -0,0 +1,29 @@
---
parent: Aider LLM Leaderboards
nav_order: 800
---
# Benchmark notes
## Notes on benchmarking results
The key benchmarking results are:
- **Percent completed correctly** - Measures what percentage of the coding tasks that the LLM completed successfully. To complete a task, the LLM must solve the programming assignment *and* edit the code to implement that solution.
- **Percent using correct edit format** - Measures the percent of coding tasks where the LLM complied with the edit format specified in the system prompt. If the LLM makes edit mistakes, aider will give it feedback and ask for a fixed copy of the edit. The best models can reliably conform to the edit format, without making errors.
## Notes on the edit format
Aider uses different "edit formats" to collect code edits from different LLMs.
The "whole" format is the easiest for an LLM to use, but it uses a lot of tokens
and may limit how large a file can be edited.
Models which can use one of the diff formats are much more efficient,
using far fewer tokens.
Models that use a diff-like format are able to
edit larger files with less cost and without hitting token limits.
Aider is configured to use the best edit format for the popular OpenAI and Anthropic models
and the [other models recommended on the LLM page](/docs/llms.html).
For lesser known models aider will default to using the "whole" editing format
since it is the easiest format for an LLM to use.

View File

@@ -0,0 +1,52 @@
---
parent: Aider LLM Leaderboards
highlight_image: /assets/leaderboard.jpg
nav_order: 100
description: Quantitative benchmark of LLM code refactoring skill.
---
## Refactoring leaderboard
[Aider's refactoring benchmark](https://github.com/Aider-AI/refactor-benchmark) asks the LLM to refactor 89 large methods from large python classes. This is a more challenging benchmark, which tests the model's ability to output long chunks of code without skipping sections or making mistakes. It was developed to provoke and measure [GPT-4 Turbo's "lazy coding" habit](/2023/12/21/unified-diffs.html).
The refactoring benchmark requires a large context window to
work with large source files.
Therefore, results are available for fewer models.
<input type="text" id="editSearchInput" placeholder="Search..." style="width: 100%; max-width: 800px; margin: 10px auto; padding: 8px; display: block; border: 1px solid #ddd; border-radius: 4px;">
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
<thead style="background-color: #f2f2f2;">
<tr>
<th style="padding: 8px; text-align: left;">Model</th>
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
<th style="padding: 8px; text-align: left;">Command</th>
<th style="padding: 8px; text-align: center;">Edit format</th>
</tr>
</thead>
<tbody>
{% assign refac_sorted = site.data.refactor_leaderboard | sort: 'pass_rate_1' | reverse %}
{% for row in refac_sorted %}
<tr style="border-bottom: 1px solid #ddd;">
<td style="padding: 8px;">{{ row.model }}</td>
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_1 }}%</td>
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% assign data_source = refac_sorted %}
{% assign pass_rate_field = "pass_rate_1" %}
{% include leaderboard.js %}
</script>

View File

@@ -53,6 +53,12 @@ To use aider installed via `pipx` with AWS Bedrock, you must add the `boto3` dep
pipx inject aider-chat boto3
```
You must install `boto3` dependency to aider's virtual environment installed via one-liner or uv by running
```bash
uv tool run --from aider-chat pip install boto3
```
## Running Aider with Bedrock

View File

@@ -95,6 +95,8 @@ cog.out(''.join(lines))
- TOGETHERAI_API_KEY
- VOLCENGINE_API_KEY
- VOYAGE_API_KEY
- WATSONX_API_KEY
- WX_API_KEY
- XAI_API_KEY
- XINFERENCE_API_KEY
<!--[[[end]]]-->

View File

@@ -20,7 +20,7 @@ copy of each source file that needs changes.
While simple, it can be slow and costly because the LLM has to return
the *entire file* even if just a few lines are edited.
The format expects the file path just before the fenced file content:
The whole format expects the file path just before the fenced file content:
````
show_greeting.py
@@ -28,7 +28,7 @@ show_greeting.py
import sys
def greeting(name):
print(f"Hey {{name}}")
print("Hey", name)
if __name__ == '__main__':
greeting(sys.argv[1])
@@ -42,7 +42,7 @@ The "diff" edit format asks the LLM to specify file edits as a series of search/
This is an efficient format, because the model only needs to return parts of the file
which have changes.
They are formatted using a syntax similar to the git merge conflict resolution markings,
Edits are formatted using a syntax similar to the git merge conflict resolution markings,
with the file path right before a fenced block:
````
@@ -62,7 +62,7 @@ from flask import Flask
The "diff-fenced" edit format is based on the diff format, but
the file path is placed inside the fence.
It is primarily used with the Gemini family of models,
which often fail to conform to fencing approach specified in the diff format.
which often fail to conform to the fencing approach specified in the diff format.
````
```
@@ -84,7 +84,10 @@ This is an efficient format, because the model only needs to return parts of the
which have changes.
It was mainly used to the GPT-4 Turbo family of models,
to reduce their "lazy coding" tendencies with other edit formats.
because it reduced their "lazy coding" tendencies.
With other edit formats the GPT-4 Turbo models tended to elide
large sections of code and replace them with "# ... original code here ..."
style comments.
````
@@ -104,3 +107,10 @@ to reduce their "lazy coding" tendencies with other edit formats.
These are streamlined versions of the diff and whole formats, intended to be used
with `--editor-edit-format` when using
[architect mode](/docs/usage/modes.html).
The actual edit format is the same, but aider uses a simpler prompt that
is more narrowly focused on just editing the file as opposed to
solving the coding task.
The architect model resolves the coding task and
provides plain text instructions about which file changes need to be made.
The editor interprets those instructions to produce the
syntactically correct diff or whole edits.

View File

@@ -65,14 +65,15 @@ cog.out(model_list)
- claude-3-sonnet-20240229
- codestral/codestral-2405
- codestral/codestral-latest
- deepseek-chat
- deepseek-coder
- deepseek/deepseek-chat
- deepseek/deepseek-coder
- eu.anthropic.claude-3-5-sonnet-20241022-v2:0
- mistral/codestral-2405
- mistral/codestral-latest
- mistral/codestral-mamba-latest
- mistral/mistral-large-2402
- mistral/mistral-large-2407
- mistral/mistral-large-2411
- mistral/mistral-large-latest
- mistral/mistral-medium
- mistral/mistral-medium-2312
@@ -87,6 +88,8 @@ cog.out(model_list)
- mistral/open-mixtral-8x22b
- mistral/open-mixtral-8x7b
- mistral/pixtral-12b-2409
- mistral/pixtral-large-2411
- mistral/pixtral-large-latest
- openrouter/anthropic/claude-3.5-sonnet
- us.anthropic.claude-3-5-haiku-20241022-v1:0
- us.anthropic.claude-3-5-sonnet-20241022-v2:0

View File

@@ -14,12 +14,11 @@ You may see an error message like this:
> aider: The term 'aider' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Below is the most fail safe way to install and run aider in these situations:
Below is the most fail safe way to run aider in these situations:
```
python -m pip install -U aider-chat
python -m aider
```
{% include venv-pipx.md %}
You should also consider
[installing aider using aider-install, uv or pipx](/docs/install.html).

View File

@@ -5,7 +5,7 @@ nav_order: 28
# Dependency versions
Aider expects to be installed via `pip` or `pipx`, which will install
Aider expects to be installed with the
correct versions of all of its required dependencies.
If you've been linked to this doc from a GitHub issue,
@@ -13,43 +13,38 @@ or if aider is reporting `ImportErrors`
it is likely that your
aider install is using incorrect dependencies.
## Install with pipx
## Avoid package conflicts
If you are using aider to work on a python project, sometimes your project will require
specific versions of python packages which conflict with the versions that aider
requires.
If this happens, you may see errors like these when running pip installs:
```
aider-chat 0.23.0 requires somepackage==X.Y.Z, but you have somepackage U.W.V which is incompatible.
```
## Install with aider-install, uv or pipx
If you are having dependency problems you should consider
[installing aider using pipx](/docs/install/pipx.html).
[installing aider using aider-install, uv or pipx](/docs/install.html).
This will ensure that aider is installed in its own python environment,
with the correct set of dependencies.
Try re-installing cleanly:
```
pipx uninstall aider-chat
pipx install aider-chat
```
## Package managers like Homebrew, AUR, ports
Package managers often install aider with the wrong dependencies, leading
to import errors and other problems.
The recommended way to
install aider is with
[pip](/docs/install/install.html).
Be sure to use the `--upgrade-strategy only-if-needed` switch so that the correct
versions of dependencies will be installed.
It is recommended to
[install aider using aider-install, uv or pipx](/docs/install.html).
```
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
```
A very safe way is to
[install aider using pipx](/docs/install/pipx.html),
which will ensure it is installed in a stand alone virtual environment.
## Dependency versions matter
Aider pins its dependencies and is tested to work with those specific versions.
If you are installing aider with pip (rather than pipx),
If you are installing aider directly with pip
you should be careful about upgrading or downgrading the python packages that
aider uses.
@@ -64,9 +59,4 @@ and sometimes introduces bugs or backwards incompatible changes.
## Replit
You can `pip install -U aider-chat` on replit.
Or you can install aider with
pipx as follows:
{% include replit-pipx.md %}

View File

@@ -22,11 +22,11 @@ cog.out(get_help_md())
|Command|Description|
|:------|:----------|
| **/add** | Add files to the chat so aider can edit them or review them in detail |
| **/architect** | Enter architect mode to discuss high-level design and architecture |
| **/ask** | Ask questions about the code base without editing any files |
| **/architect** | Enter architect mode to discuss high-level design and architecture. If no prompt provided, switches to architect mode. |
| **/ask** | Ask questions about the code base without editing any files. If no prompt provided, switches to ask mode. |
| **/chat-mode** | Switch to a new chat mode |
| **/clear** | Clear the chat history |
| **/code** | Ask for changes to your code |
| **/code** | Ask for changes to your code. If no prompt provided, switches to code mode. |
| **/commit** | Commit edits to the repo made outside the chat (commit message optional) |
| **/copy** | Copy the last assistant message to the clipboard |
| **/copy-context** | Copy the current chat context as markdown, suitable to paste into a web UI |
@@ -43,6 +43,7 @@ cog.out(get_help_md())
| **/map-refresh** | Force a refresh of the repository map |
| **/model** | Switch to a new LLM |
| **/models** | Search the list of available models |
| **/multiline-mode** | Toggle multiline mode (swaps behavior of Enter and Meta+Enter) |
| **/paste** | Paste image/text from the clipboard into the chat. Optionally provide a name for the image. |
| **/quit** | Exit the application |
| **/read-only** | Add files to the chat that are for reference only, or turn added files to read-only |

View File

@@ -28,6 +28,11 @@ or `aider --read CONVENTIONS.md`.
This way it is marked as read-only, and cached if prompt caching
is enabled.
## Community contributed conventions
You can check the [aider conventions repository](https://github.com/Aider-AI/conventions)
to find or contribute conventions files.
## Always load conventions
You can also configure aider to always load your conventions file

View File

@@ -54,13 +54,14 @@ that o1-preview is suggesting in the web chat.
### Copy aider's code context to your clipboard, paste into the web UI
The `/copy-context` command can be used in chat to copy aider's code context to your clipboard.
The `/copy-context <instructions>` command can be used in chat to copy aider's code context to your clipboard.
It will include:
- All the files which have been added to the chat via `/add`.
- Any read only files which have been added via `/read`.
- Aider's [repository map](https://aider.chat/docs/repomap.html) that brings in code context related to the above files from elsewhere in your git repo.
- Some instructions to the LLM that ask it to output change instructions concisely.
- If you include `<instructions>`, they will be copied too.
You can paste the context into your browser, and start interacting with the LLM web chat to
ask for code changes.

View File

@@ -29,6 +29,14 @@ with the `/chat-mode <mode>` command:
/chat-mode help
```
Or you can switch between coding modes using these commands without arguments:
```
/code
/architect
/ask
```
Or you can launch aider in one of the modes with the `--chat-mode <mode>` switch.
There is also a special shortcut `--architect` to launch in `--chat-mode architect`.

View File

@@ -3,7 +3,7 @@ title: Aider in your IDE
#highlight_image: /assets/browser.jpg
parent: Usage
nav_order: 750
description: Aider can run in your browser, not just on the command line.
description: Aider can watch your files and respond to AI comments you add in your favorite IDE or text editor.
---
# Aider in your IDE
@@ -34,13 +34,14 @@ description: Aider can run in your browser, not just on the command line.
## AI comments
If you run aider with `--watch-files`, it will watch all files in your repo
If you run aider with `--watch-files`, it will watch all files in your repo
and look for any AI coding instructions you add using your favorite IDE or text editor.
Specifically, aider looks for one-liner comments (# ... or // ...) that either start or end with `AI` or `AI!`, like these:
Specifically, aider looks for one-liner comments (# ... or // ...) that either start or end with `AI`, `AI!` or `AI?` like these:
```python
# Make a snake game. AI!
# What is the purpose of this method AI?
```
Or in `//` comment languages...
@@ -49,11 +50,16 @@ Or in `//` comment languages...
// Write a protein folding prediction engine. AI!
```
Aider will take note of all the comments that start or end with `AI`, but
a comment that includes `AI!` with an exclamation point is special.
That triggers aider to take action to collect *all* the AI comments and use them as instructions to make code changes.
Aider will take note of all the comments that start or end with `AI`.
Comments that include `AI!` with an exclamation point or `AI?` with a question
mark are special.
They triggers aider to take action to collect *all* the AI comments and use them
as your instructions.
See the demo video above that shows aider working with AI comments in VSCode.
- `AI!` triggers aider to make changes to your code.
- `AI?` triggers aider to answer your question.
See the demo video above that shows aider working with AI comments in VSCode.
## Example
@@ -76,6 +82,19 @@ function factorial(n) {
}
```
## Comment styles
Aider only watches for these types of **one-liner** comments:
```
# Python and bash style
// Javascript style
-- SQL style
```
Aider will look for those comment types in all files.
You can use them into any code file you're editing, even if they aren't the
correct comment syntax for that language.
## Multiple uses
@@ -83,7 +102,7 @@ This capability is quite flexible and powerful, and can be used in many ways.
### In-context instructions
You can add an AI comment in the function you want changed,
You can add an AI comment in the function you want changed,
explaining the change request in-context right where you want the changes.
```javascript
@@ -110,15 +129,15 @@ Just use `AI!` last, to trigger aider.
def factorial(n):
if n < 0:
return jsonify(error="Factorial is not defined for negative numbers"), 400
# AI: Refactor this code...
result = 1
for i in range(1, n + 1):
result *= i
# ... into to a compute_factorial() function. AI!
return jsonify(result=result)
```
@@ -161,7 +180,7 @@ many of aider's more advanced features:
- Use `/undo` to revert changes you don't like. Although you may also be able to use your IDE's undo function to step back in the file history.
- Use [chat modes](https://aider.chat/docs/usage/modes.html) to ask questions or get help.
- Manage the chat context with `/tokens`, `/clear`, `/drop`, `/reset`.
Adding an AI comment will add the file to the chat.
Adding an AI comment will add the file to the chat.
Periodically, you may want remove extra context that is no longer needed.
- [Fix lint and test errors](https://aider.chat/docs/usage/lint-test.html).
- Run shell commands.
@@ -175,14 +194,14 @@ comments with full sentences, proper capitalization, punctuation, etc.
This was done to help explain how AI comments work, but is not needed in practice.
Most LLMs are perfectly capable of dealing with ambiguity and
inferring implied intent.
inferring implied intent.
This often allows you to be quite lazy with your AI comments.
In particular, you can start and end comments with lowercase `ai` and `ai!`,
but you can also be much more terse with the request itself.
Below are simpler versions of some of the examples given above.
When the context clearly implies the needed action, `ai!` might be all you
need. For example, to implement a factorial function
need. For example, to implement a factorial function
in a program full of other math functions either of these
approaches would probably work:
@@ -218,15 +237,15 @@ Similarly, this refactor probably could have been requested with fewer words, li
def factorial(n):
if n < 0:
return jsonify(error="Factorial is not defined for negative numbers"), 400
# ai refactor...
result = 1
for i in range(1, n + 1):
result *= i
# ... to compute_factorial() ai!
return jsonify(result=result)
```
@@ -270,7 +289,6 @@ todo_app.py:
#### Credits
*This feature was inspired by
*This feature was inspired by
the way [Override](https://github.com/oi-overide) watches for file changes
to find prompts embedded within `//> a specific set of delimiters <//`.*

View File

@@ -32,9 +32,9 @@ cog.out(text)
Aider lets you pair program with LLMs,
to edit code in your local git repository.
Start a new project or work with an existing git repo.
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
[connect to almost any LLM](https://aider.chat/docs/llms.html).
Start a new project or work with an existing code base.
Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
<!--
<p align="center">
@@ -70,28 +70,27 @@ Aider works best with GPT-4o & Claude 3.5 Sonnet and can
cog.out(open("aider/website/_includes/get-started.md").read())
-->
You can get started quickly like this:
If you already have python 3.8-3.13 installed, you can get started quickly like this:
```
python -m pip install -U aider-chat
```bash
python -m pip install aider-install
aider-install
# Change directory into a git repo
cd /to/your/git/repo
# Change directory into your code base
cd /to/your/project
# Work with Claude 3.5 Sonnet on your repo
export ANTHROPIC_API_KEY=your-key-goes-here
aider
# Work with Claude 3.5 Sonnet on your code
aider --model sonnet --anthropic-api-key your-key-goes-here
# Work with GPT-4o on your repo
export OPENAI_API_KEY=your-key-goes-here
aider
# Work with GPT-4o on your code
aider --model gpt-4o --openai-api-key your-key-goes-here
```
<!-- NOOP -->
See the
[installation instructions](https://aider.chat/docs/install.html)
and other
[documentation](https://aider.chat/docs/usage.html)
and
[usage documentation](https://aider.chat/docs/usage.html)
for more details.
## Features
@@ -105,16 +104,17 @@ for more details.
- Update docs.
- Aider will edit your files to complete your request.
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
- [Use aider inside your favorite editor or IDE](https://aider.chat/docs/usage/watch.html).
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
- Aider works best with GPT-4o & Claude 3.5 Sonnet and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
- Aider can edit multiple files at once for complex requests.
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
- Edit files in your editor while chatting with aider,
- Edit files in your editor or IDE while chatting with aider,
and it will always use the latest version.
Pair program with AI.
- [Add images to the chat](https://aider.chat/docs/usage/images-urls.html) (GPT-4o, Claude 3.5 Sonnet, etc).
- [Add URLs to the chat](https://aider.chat/docs/usage/images-urls.html) and aider will read their content.
- [Code with your voice](https://aider.chat/docs/usage/voice.html).
- Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
## Top tier performance

559
aider/website/install.ps1 Normal file
View File

@@ -0,0 +1,559 @@
# Licensed under the MIT license
# <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
<#
.SYNOPSIS
The installer for uv 0.5.9
.DESCRIPTION
This script detects what platform you're on and fetches an appropriate archive from
https://github.com/astral-sh/uv/releases/download/0.5.9
then unpacks the binaries and installs them to the first of the following locations
$env:XDG_BIN_HOME
$env:XDG_DATA_HOME/../bin
$HOME/.local/bin
It will then add that dir to PATH by editing your Environment.Path registry key
.PARAMETER ArtifactDownloadUrl
The URL of the directory where artifacts can be fetched from
.PARAMETER NoModifyPath
Don't add the install directory to PATH
.PARAMETER Help
Print help
#>
param (
[Parameter(HelpMessage = "The URL of the directory where artifacts can be fetched from")]
[string]$ArtifactDownloadUrl = 'https://github.com/astral-sh/uv/releases/download/0.5.9',
[Parameter(HelpMessage = "Don't add the install directory to PATH")]
[switch]$NoModifyPath,
[Parameter(HelpMessage = "Print Help")]
[switch]$Help
)
$app_name = 'uv'
$app_version = '0.5.9'
if ($env:UV_INSTALLER_GHE_BASE_URL) {
$installer_base_url = $env:UV_INSTALLER_GHE_BASE_URL
} elseif ($env:UV_INSTALLER_GITHUB_BASE_URL) {
$installer_base_url = $env:UV_INSTALLER_GITHUB_BASE_URL
} else {
$installer_base_url = "https://github.com"
}
if ($env:INSTALLER_DOWNLOAD_URL) {
$ArtifactDownloadUrl = $env:INSTALLER_DOWNLOAD_URL
} else {
$ArtifactDownloadUrl = "$installer_base_url/astral-sh/uv/releases/download/0.5.9"
}
$receipt = @"
{"binaries":["CARGO_DIST_BINS"],"binary_aliases":{},"cdylibs":["CARGO_DIST_DYLIBS"],"cstaticlibs":["CARGO_DIST_STATICLIBS"],"install_layout":"unspecified","install_prefix":"AXO_INSTALL_PREFIX","modify_path":true,"provider":{"source":"cargo-dist","version":"0.25.2-prerelease.3"},"source":{"app_name":"uv","name":"uv","owner":"astral-sh","release_type":"github"},"version":"0.5.9"}
"@
$receipt_home = "${env:LOCALAPPDATA}\uv"
if ($env:UV_DISABLE_UPDATE) {
$install_updater = $false
} else {
$install_updater = $true
}
if ($NoModifyPath) {
Write-Information "-NoModifyPath has been deprecated; please set UV_NO_MODIFY_PATH=1 in the environment"
}
if ($env:UV_NO_MODIFY_PATH) {
$NoModifyPath = $true
}
$unmanaged_install = $env:UV_UNMANAGED_INSTALL
if ($unmanaged_install) {
$NoModifyPath = $true
$install_updater = $false
}
function Install-Binary($install_args) {
if ($Help) {
Get-Help $PSCommandPath -Detailed
Exit
}
Initialize-Environment
# Platform info injected by dist
$platforms = @{
"aarch64-pc-windows-msvc" = @{
"artifact_name" = "uv-x86_64-pc-windows-msvc.zip"
"bins" = @("uv.exe", "uvx.exe")
"libs" = @()
"staticlibs" = @()
"zip_ext" = ".zip"
"aliases" = @{
}
"aliases_json" = '{}'
}
"i686-pc-windows-msvc" = @{
"artifact_name" = "uv-i686-pc-windows-msvc.zip"
"bins" = @("uv.exe", "uvx.exe")
"libs" = @()
"staticlibs" = @()
"zip_ext" = ".zip"
"aliases" = @{
}
"aliases_json" = '{}'
}
"x86_64-pc-windows-msvc" = @{
"artifact_name" = "uv-x86_64-pc-windows-msvc.zip"
"bins" = @("uv.exe", "uvx.exe")
"libs" = @()
"staticlibs" = @()
"zip_ext" = ".zip"
"aliases" = @{
}
"aliases_json" = '{}'
}
}
$fetched = Download "$ArtifactDownloadUrl" $platforms
# FIXME: add a flag that lets the user not do this step
try {
Invoke-Installer -artifacts $fetched -platforms $platforms "$install_args"
} catch {
throw @"
We encountered an error trying to perform the installation;
please review the error messages below.
$_
"@
}
}
function Get-TargetTriple() {
try {
# NOTE: this might return X64 on ARM64 Windows, which is OK since emulation is available.
# It works correctly starting in PowerShell Core 7.3 and Windows PowerShell in Win 11 22H2.
# Ideally this would just be
# [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
# but that gets a type from the wrong assembly on Windows PowerShell (i.e. not Core)
$a = [System.Reflection.Assembly]::LoadWithPartialName("System.Runtime.InteropServices.RuntimeInformation")
$t = $a.GetType("System.Runtime.InteropServices.RuntimeInformation")
$p = $t.GetProperty("OSArchitecture")
# Possible OSArchitecture Values: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.architecture
# Rust supported platforms: https://doc.rust-lang.org/stable/rustc/platform-support.html
switch ($p.GetValue($null).ToString())
{
"X86" { return "i686-pc-windows-msvc" }
"X64" { return "x86_64-pc-windows-msvc" }
"Arm" { return "thumbv7a-pc-windows-msvc" }
"Arm64" { return "aarch64-pc-windows-msvc" }
}
} catch {
# The above was added in .NET 4.7.1, so Windows PowerShell in versions of Windows
# prior to Windows 10 v1709 may not have this API.
Write-Verbose "Get-TargetTriple: Exception when trying to determine OS architecture."
Write-Verbose $_
}
# This is available in .NET 4.0. We already checked for PS 5, which requires .NET 4.5.
Write-Verbose("Get-TargetTriple: falling back to Is64BitOperatingSystem.")
if ([System.Environment]::Is64BitOperatingSystem) {
return "x86_64-pc-windows-msvc"
} else {
return "i686-pc-windows-msvc"
}
}
function Download($download_url, $platforms) {
$arch = Get-TargetTriple
if (-not $platforms.ContainsKey($arch)) {
$platforms_json = ConvertTo-Json $platforms
throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json"
}
# Lookup what we expect this platform to look like
$info = $platforms[$arch]
$zip_ext = $info["zip_ext"]
$bin_names = $info["bins"]
$lib_names = $info["libs"]
$staticlib_names = $info["staticlibs"]
$artifact_name = $info["artifact_name"]
# Make a new temp dir to unpack things to
$tmp = New-Temp-Dir
$dir_path = "$tmp\$app_name$zip_ext"
# Download and unpack!
$url = "$download_url/$artifact_name"
Write-Information "Downloading $app_name $app_version ($arch)"
Write-Verbose " from $url"
Write-Verbose " to $dir_path"
$wc = New-Object Net.Webclient
$wc.downloadFile($url, $dir_path)
Write-Verbose "Unpacking to $tmp"
# Select the tool to unpack the files with.
#
# As of windows 10(?), powershell comes with tar preinstalled, but in practice
# it only seems to support .tar.gz, and not xz/zstd. Still, we should try to
# forward all tars to it in case the user has a machine that can handle it!
switch -Wildcard ($zip_ext) {
".zip" {
Expand-Archive -Path $dir_path -DestinationPath "$tmp";
Break
}
".tar.*" {
tar xf $dir_path --strip-components 1 -C "$tmp";
Break
}
Default {
throw "ERROR: unknown archive format $zip_ext"
}
}
# Let the next step know what to copy
$bin_paths = @()
foreach ($bin_name in $bin_names) {
Write-Verbose " Unpacked $bin_name"
$bin_paths += "$tmp\$bin_name"
}
$lib_paths = @()
foreach ($lib_name in $lib_names) {
Write-Verbose " Unpacked $lib_name"
$lib_paths += "$tmp\$lib_name"
}
$staticlib_paths = @()
foreach ($lib_name in $staticlib_names) {
Write-Verbose " Unpacked $lib_name"
$staticlib_paths += "$tmp\$lib_name"
}
if (($null -ne $info["updater"]) -and $install_updater) {
$updater_id = $info["updater"]["artifact_name"]
$updater_url = "$download_url/$updater_id"
$out_name = "$tmp\uv-update.exe"
$wc.downloadFile($updater_url, $out_name)
$bin_paths += $out_name
}
return @{
"bin_paths" = $bin_paths
"lib_paths" = $lib_paths
"staticlib_paths" = $staticlib_paths
}
}
function Invoke-Installer($artifacts, $platforms) {
# Replaces the placeholder binary entry with the actual list of binaries
$arch = Get-TargetTriple
if (-not $platforms.ContainsKey($arch)) {
$platforms_json = ConvertTo-Json $platforms
throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json"
}
$info = $platforms[$arch]
# Forces the install to occur at this path, not the default
$force_install_dir = $null
$install_layout = "unspecified"
# Check the newer app-specific variable before falling back
# to the older generic one
if (($env:UV_INSTALL_DIR)) {
$force_install_dir = $env:UV_INSTALL_DIR
$install_layout = "flat"
} elseif (($env:CARGO_DIST_FORCE_INSTALL_DIR)) {
$force_install_dir = $env:CARGO_DIST_FORCE_INSTALL_DIR
$install_layout = "flat"
} elseif ($unmanaged_install) {
$force_install_dir = $unmanaged_install
$install_layout = "flat"
}
# Check if the install layout should be changed from `flat` to `cargo-home`
# for backwards compatible updates of applications that switched layouts.
if (($force_install_dir) -and ($install_layout -eq "flat")) {
# If the install directory is targeting the Cargo home directory, then
# we assume this application was previously installed that layout
# Note the installer passes the path with `\\` separators, but here they are
# `\` so we normalize for comparison. We don't use `Resolve-Path` because they
# may not exist.
$cargo_home = if ($env:CARGO_HOME) { $env:CARGO_HOME } else {
Join-Path $(if ($HOME) { $HOME } else { "." }) ".cargo"
}
if ($force_install_dir.Replace('\\', '\') -eq $cargo_home) {
$install_layout = "cargo-home"
}
}
# The actual path we're going to install to
$dest_dir = $null
$dest_dir_lib = $null
# The install prefix we write to the receipt.
# For organized install methods like CargoHome, which have
# subdirectories, this is the root without `/bin`. For other
# methods, this is the same as `_install_dir`.
$receipt_dest_dir = $null
# Before actually consulting the configured install strategy, see
# if we're overriding it.
if (($force_install_dir)) {
switch ($install_layout) {
"hierarchical" {
$dest_dir = Join-Path $force_install_dir "bin"
$dest_dir_lib = Join-Path $force_install_dir "lib"
}
"cargo-home" {
$dest_dir = Join-Path $force_install_dir "bin"
$dest_dir_lib = $dest_dir
}
"flat" {
$dest_dir = $force_install_dir
$dest_dir_lib = $dest_dir
}
Default {
throw "Error: unrecognized installation layout: $install_layout"
}
}
$receipt_dest_dir = $force_install_dir
}
if (-Not $dest_dir) {
# Install to $env:XDG_BIN_HOME
$dest_dir = if (($base_dir = $env:XDG_BIN_HOME)) {
Join-Path $base_dir ""
}
$dest_dir_lib = $dest_dir
$receipt_dest_dir = $dest_dir
$install_layout = "flat"
}
if (-Not $dest_dir) {
# Install to $env:XDG_DATA_HOME/../bin
$dest_dir = if (($base_dir = $env:XDG_DATA_HOME)) {
Join-Path $base_dir "../bin"
}
$dest_dir_lib = $dest_dir
$receipt_dest_dir = $dest_dir
$install_layout = "flat"
}
if (-Not $dest_dir) {
# Install to $HOME/.local/bin
$dest_dir = if (($base_dir = $HOME)) {
Join-Path $base_dir ".local/bin"
}
$dest_dir_lib = $dest_dir
$receipt_dest_dir = $dest_dir
$install_layout = "flat"
}
# Looks like all of the above assignments failed
if (-Not $dest_dir) {
throw "ERROR: could not find a valid path to install to; please check the installation instructions"
}
# The replace call here ensures proper escaping is inlined into the receipt
$receipt = $receipt.Replace('AXO_INSTALL_PREFIX', $receipt_dest_dir.replace("\", "\\"))
$receipt = $receipt.Replace('"install_layout":"unspecified"', -join('"install_layout":"', $install_layout, '"'))
$dest_dir = New-Item -Force -ItemType Directory -Path $dest_dir
$dest_dir_lib = New-Item -Force -ItemType Directory -Path $dest_dir_lib
Write-Information "Installing to $dest_dir"
# Just copy the binaries from the temp location to the install dir
foreach ($bin_path in $artifacts["bin_paths"]) {
$installed_file = Split-Path -Path "$bin_path" -Leaf
Copy-Item "$bin_path" -Destination "$dest_dir" -ErrorAction Stop
Remove-Item "$bin_path" -Recurse -Force -ErrorAction Stop
Write-Information " $installed_file"
if (($dests = $info["aliases"][$installed_file])) {
$source = Join-Path "$dest_dir" "$installed_file"
foreach ($dest_name in $dests) {
$dest = Join-Path $dest_dir $dest_name
$null = New-Item -ItemType HardLink -Target "$source" -Path "$dest" -Force -ErrorAction Stop
}
}
}
foreach ($lib_path in $artifacts["lib_paths"]) {
$installed_file = Split-Path -Path "$lib_path" -Leaf
Copy-Item "$lib_path" -Destination "$dest_dir_lib" -ErrorAction Stop
Remove-Item "$lib_path" -Recurse -Force -ErrorAction Stop
Write-Information " $installed_file"
}
foreach ($lib_path in $artifacts["staticlib_paths"]) {
$installed_file = Split-Path -Path "$lib_path" -Leaf
Copy-Item "$lib_path" -Destination "$dest_dir_lib" -ErrorAction Stop
Remove-Item "$lib_path" -Recurse -Force -ErrorAction Stop
Write-Information " $installed_file"
}
$formatted_bins = ($info["bins"] | ForEach-Object { '"' + $_ + '"' }) -join ","
$receipt = $receipt.Replace('"CARGO_DIST_BINS"', $formatted_bins)
$formatted_libs = ($info["libs"] | ForEach-Object { '"' + $_ + '"' }) -join ","
$receipt = $receipt.Replace('"CARGO_DIST_DYLIBS"', $formatted_libs)
$formatted_staticlibs = ($info["staticlibs"] | ForEach-Object { '"' + $_ + '"' }) -join ","
$receipt = $receipt.Replace('"CARGO_DIST_STATICLIBS"', $formatted_staticlibs)
# Also replace the aliases with the arch-specific one
$receipt = $receipt.Replace('"binary_aliases":{}', -join('"binary_aliases":', $info['aliases_json']))
if ($NoModifyPath) {
$receipt = $receipt.Replace('"modify_path":true', '"modify_path":false')
}
# Write the install receipt
if ($install_updater) {
$null = New-Item -Path $receipt_home -ItemType "directory" -ErrorAction SilentlyContinue
# Trying to get Powershell 5.1 (not 6+, which is fake and lies) to write utf8 is a crime
# because "Out-File -Encoding utf8" actually still means utf8BOM, so we need to pull out
# .NET's APIs which actually do what you tell them (also apparently utf8NoBOM is the
# default in newer .NETs but I'd rather not rely on that at this point).
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[IO.File]::WriteAllLines("$receipt_home/uv-receipt.json", "$receipt", $Utf8NoBomEncoding)
}
# Respect the environment, but CLI takes precedence
if ($null -eq $NoModifyPath) {
$NoModifyPath = $env:INSTALLER_NO_MODIFY_PATH
}
Write-Information ""
Write-Information "Installing aider-chat..."
& "$dest_dir\uv.exe" tool install --force --python python3.12 aider-chat@latest
if (-not $NoModifyPath) {
Add-Ci-Path $dest_dir
if (Add-Path $dest_dir) {
Write-Information ""
Write-Information "You need to add $dest_dir to your PATH. Either restart your system or run:"
Write-Information ""
Write-Information " set Path=$dest_dir;%Path% (cmd)"
Write-Information " `$env:Path = `"$dest_dir;`$env:Path`" (powershell)"
}
}
}
# Attempt to do CI-specific rituals to get the install-dir on PATH faster
function Add-Ci-Path($OrigPathToAdd) {
# If GITHUB_PATH is present, then write install_dir to the file it refs.
# After each GitHub Action, the contents will be added to PATH.
# So if you put a curl | sh for this script in its own "run" step,
# the next step will have this dir on PATH.
#
# Note that GITHUB_PATH will not resolve any variables, so we in fact
# want to write the install dir and not an expression that evals to it
if (($gh_path = $env:GITHUB_PATH)) {
Write-Output "$OrigPathToAdd" | Out-File -FilePath "$gh_path" -Encoding utf8 -Append
}
}
# Try to add the given path to PATH via the registry
#
# Returns true if the registry was modified, otherwise returns false
# (indicating it was already on PATH)
function Add-Path($OrigPathToAdd) {
Write-Verbose "Adding $OrigPathToAdd to your PATH"
$RegistryPath = "HKCU:\Environment"
$PropertyName = "Path"
$PathToAdd = $OrigPathToAdd
$Item = if (Test-Path $RegistryPath) {
# If the registry key exists, get it
Get-Item -Path $RegistryPath
} else {
# If the registry key doesn't exist, create it
Write-Verbose "Creating $RegistryPath"
New-Item -Path $RegistryPath -Force
}
$OldPath = ""
try {
# Try to get the old PATH value. If that fails, assume we're making it from scratch.
# Otherwise assume there's already paths in here and use a ; separator
$OldPath = $Item | Get-ItemPropertyValue -Name $PropertyName
$PathToAdd = "$PathToAdd;"
} catch {
# We'll be creating the PATH from scratch
Write-Verbose "No $PropertyName Property exists on $RegistryPath (we'll make one)"
}
# Check if the path is already there
#
# We don't want to incorrectly match "C:\blah\" to "C:\blah\blah\", so we include the semicolon
# delimiters when searching, ensuring exact matches. To avoid corner cases we add semicolons to
# both sides of the input, allowing us to pretend we're always in the middle of a list.
Write-Verbose "Old $PropertyName Property is $OldPath"
if (";$OldPath;" -like "*;$OrigPathToAdd;*") {
# Already on path, nothing to do
Write-Verbose "install dir already on PATH, all done!"
return $false
} else {
# Actually update PATH
Write-Verbose "Actually mutating $PropertyName Property"
$NewPath = $PathToAdd + $OldPath
# We use -Force here to make the value already existing not be an error
$Item | New-ItemProperty -Name $PropertyName -Value $NewPath -PropertyType String -Force | Out-Null
return $true
}
}
function Initialize-Environment() {
If (($PSVersionTable.PSVersion.Major) -lt 5) {
throw @"
Error: PowerShell 5 or later is required to install $app_name.
Upgrade PowerShell:
https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell
"@
}
# show notification to change execution policy:
$allowedExecutionPolicy = @('Unrestricted', 'RemoteSigned', 'ByPass')
If ((Get-ExecutionPolicy).ToString() -notin $allowedExecutionPolicy) {
throw @"
Error: PowerShell requires an execution policy in [$($allowedExecutionPolicy -join ", ")] to run $app_name. For example, to set the execution policy to 'RemoteSigned' please run:
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
"@
}
# GitHub requires TLS 1.2
If ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -notcontains 'Tls12') {
throw @"
Error: Installing $app_name requires at least .NET Framework 4.5
Please download and install it first:
https://www.microsoft.com/net/download
"@
}
}
function New-Temp-Dir() {
[CmdletBinding(SupportsShouldProcess)]
param()
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
New-Item -ItemType Directory -Path (Join-Path $parent $name)
}
# PSScriptAnalyzer doesn't like how we use our params as globals, this calms it
$Null = $ArtifactDownloadUrl, $NoModifyPath, $Help
# Make Write-Information statements be visible
$InformationPreference = "Continue"
# The default interactive handler
try {
Install-Binary "$Args"
} catch {
Write-Information $_
exit 1
}

1832
aider/website/install.sh Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,63 @@
FROM python:3.10-slim
RUN apt-get update
RUN apt-get install -y less git build-essential
FROM buildpack-deps:jammy
# Install Python 3.11
RUN apt-get update && apt-get install -y \
software-properties-common \
cmake \
&& add-apt-repository ppa:deadsnakes/ppa \
&& apt-get update \
&& apt-get install -y \
python3.11 \
python3.11-venv \
python3.11-dev \
python3-pip \
ca-certificates-java \
openjdk-21-jdk \
libtbb-dev \
&& rm -rf /var/lib/apt/lists/*
# Make python3.11 the default python3
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
# Install Go with architecture detection
RUN ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
GOARCH="amd64"; \
elif [ "$ARCH" = "aarch64" ]; then \
GOARCH="arm64"; \
else \
false; \
fi && \
curl -L "https://golang.org/dl/go1.21.5.linux-$GOARCH.tar.gz" -o go.tar.gz && \
tar -C /usr/local -xzf go.tar.gz && \
rm go.tar.gz
ENV PATH="/usr/local/go/bin:${PATH}"
# Install Rust
ADD https://sh.rustup.rs /tmp/rustup.sh
RUN chmod +x /tmp/rustup.sh && /tmp/rustup.sh -y && rm /tmp/rustup.sh
ENV PATH="/root/.cargo/bin:${PATH}"
# Install Node.js and dependencies
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y nodejs && \
rm -rf /var/lib/apt/lists/* && \
mkdir -p /npm-install && \
cd /npm-install && \
npm init -y && \
npm install \
jest \
@babel/core@7.25.2 \
@exercism/babel-preset-javascript@0.2.1 \
@exercism/eslint-config-javascript@0.6.0 \
@types/jest@29.5.12 \
@types/node@20.12.12 \
babel-jest@29.6.4 \
core-js@3.37.1 \
eslint@8.49.0
COPY . /aider
RUN pip install --no-cache-dir --upgrade pip
RUN pip install --no-cache-dir -e /aider[dev]
RUN pip3 install --no-cache-dir --upgrade pip uv
RUN uv pip install --system --no-cache-dir -e /aider[dev]
RUN git config --global --add safe.directory /aider
WORKDIR /aider

View File

@@ -1,24 +1,23 @@
# Aider code editing benchmark harness
# Aider benchmark harness
Aider uses a "code editing" benchmark to quantitatively measure how well it works
with the GPT-3.5 and GPT-4 models.
Aider uses benchmarks to quantitatively measure how well it works
with various LLMs.
This directory holds the harness and tools needed to run the benchmarking suite.
## Background
The benchmark is based on the [Exercism
python](https://github.com/exercism/python) coding exercises.
The benchmark is based on the [Exercism](https://github.com/exercism/python) coding exercises.
This
benchmark evaluates how effectively aider and GPT can translate a
benchmark evaluates how effectively aider and LLMs can translate a
natural language coding request into executable code saved into
files that pass unit tests.
It provides an end-to-end evaluation of not just
GPT's coding ability, but also its capacity to *edit existing code*
the LLM's coding ability, but also its capacity to *edit existing code*
and *format those code edits* so that aider can save the
edits to the local source files.
See [this writeup for a longer discussion about the benchmark and how to interpret the results](https://aider.chat/docs/benchmarks.html).
See [this writeup for a longer discussion about the benchmark](https://aider.chat/2024/12/21/polyglot.html).
The benchmark is intended to be run *inside a docker container*.
This is because the benchmarking harness will be
@@ -33,7 +32,7 @@ There are 3 main tasks involved in benchmarking aider:
1. Install and setup for benchmarking.
2. Run the benchmark to measure performance across the 133 exercises.
2. Run the benchmark to measure performance across all the exercises.
3. Generate a summary report of how many of the exercises succeeded or failed.
@@ -50,11 +49,8 @@ git clone git@github.com:Aider-AI/aider.git
cd aider
mkdir tmp.benchmarks
# Clone the exercism repo
git clone git@github.com:exercism/python.git
# Copy the practice exercises into the benchmark scratch dir
cp -rp python/exercises/practice tmp.benchmarks/exercism-python
# Clone the repo with the exercises
git clone https://github.com/Aider-AI/polyglot-benchmark tmp.benchmarks/polyglot-benchmark
# Build the docker container
./benchmark/docker_build.sh
@@ -70,21 +66,21 @@ Launch the docker container and run the benchmark inside it:
# Inside the container, install aider as a development build.
# This way you're running the code that you cloned above, including any local changes.
pip install -e .
pip install -e .[dev]
# Run the benchmark:
./benchmark/benchmark.py a-helpful-name-for-this-run --model gpt-3.5-turbo --edit-format whole --threads 10
./benchmark/benchmark.py a-helpful-name-for-this-run --model gpt-3.5-turbo --edit-format whole --threads 10 --exercises-dir polyglot-benchmark
```
The above will create a folder `tmp.benchmarks/YYYY-MM-DD-HH-MM-SS--a-helpful-name-for-this-run` with benchmarking results.
Run like this, the script will run all 133 exercises in a random order.
Run like this, the script will run all the exercises in a random order.
You can run `./benchmark/benchmark.py --help` for a list of all the arguments, but here are the most useful to keep in mind:
- `--model` is the name of the model, same as you would pass directly to `aider`.
- `--edit-format` is the name of the edit format, same as you would pass directly to `aider`. When working with an experimental LLM, I recommend starting with `whole`
- `--threads` specifies how many exercises to benchmark in parallel. Start with a single thread if you are working out the kinks on your benchmarking setup or working with a new model, etc. Once you are getting reliable results, you can speed up the process by running with more threads. 10 works well against the OpenAI APIs.
- `--num-tests` specifies how many of the 133 tests to run before stopping. This is another way to start gently as you debug your benchmarking setup.
- `--num-tests` specifies how many of the tests to run before stopping. This is another way to start gently as you debug your benchmarking setup.
- `--keywords` filters the tests to run to only the ones whose name match the supplied argument (similar to `pytest -k xxxx`).
### Benchmark report
@@ -102,7 +98,7 @@ The benchmark report is a yaml record with statistics about the run:
```yaml
- dirname: 2024-07-04-14-32-08--claude-3.5-sonnet-diff-continue
test_cases: 133
test_cases: 225
model: claude-3.5-sonnet
edit_format: diff
commit_hash: 35f21b5
@@ -143,7 +139,6 @@ You can see examples of the benchmark report yaml in the
## Limitations, notes
- Benchmarking all 133 exercises against Claude 3.5 Sonnet will cost about $4.
- Contributions of benchmark results are welcome! Submit results by opening a PR with edits to the
[aider leaderboard data files](https://github.com/Aider-AI/aider/blob/main/aider/website/_data/).
- These scripts are not intended for use by typical aider end users.

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import datetime
import json
import os
@@ -24,20 +24,18 @@ from dotenv import load_dotenv
from plots import plot_refactoring
from rich.console import Console
from aider import models
from aider.coders import Coder
from aider import models, sendchat
from aider.coders import Coder, base_coder
from aider.dump import dump # noqa: F401
from aider.io import InputOutput
BENCHMARK_DNAME = Path(os.environ.get("AIDER_BENCHMARK_DIR", "tmp.benchmarks"))
EXERCISES_DIR_DEFAULT = "exercism-python"
EXERCISES_DIR_DEFAULT = "polyglot-benchmark"
app = typer.Typer(add_completion=False, pretty_exceptions_enable=False)
NUM_TESTS = (89, 133)
load_dotenv(override=True)
@@ -74,7 +72,7 @@ def find_latest_benchmark_dir():
for d in recent_dirs:
# Look for .md files in subdirectories
for md_file in d.glob("*/.*.md"):
for md_file in d.glob("*/exercises/practice/*/.*.md"):
if md_file.is_file():
mtime = md_file.stat().st_mtime
if mtime > latest_time:
@@ -89,10 +87,10 @@ def find_latest_benchmark_dir():
return latest_dir
def show_stats(dirnames, graphs):
def show_stats(dirnames, graphs, stats_languages=None):
raw_rows = []
for dirname in dirnames:
row = summarize_results(dirname)
row = summarize_results(dirname, stats_languages)
raw_rows.append(row)
# return
@@ -103,10 +101,16 @@ def show_stats(dirnames, graphs):
if not row:
continue
if row.completed_tests not in NUM_TESTS:
print(f"Warning: {row.dir_name} is incomplete: {row.completed_tests}")
if row.completed_tests != row.total_tests:
print(
f"Warning: {row.dir_name} is incomplete: {row.completed_tests} of {row.total_tests}"
)
try:
kind = (row.model, row.edit_format)
except AttributeError:
return
kind = (row.model, row.edit_format)
if kind in seen:
dump(row.dir_name)
dump(seen[kind])
@@ -158,6 +162,12 @@ def main(
dirnames: Optional[List[str]] = typer.Argument(None, help="Directory names"),
graphs: bool = typer.Option(False, "--graphs", help="Generate graphs"),
model: str = typer.Option("gpt-3.5-turbo", "--model", "-m", help="Model name"),
sleep: float = typer.Option(
0, "--sleep", help="Sleep seconds between tests when single threaded"
),
languages: str = typer.Option(
None, "--languages", "-l", help="Only run tests for specific languages (comma separated)"
),
edit_format: str = typer.Option(None, "--edit-format", "-e", help="Edit format"),
editor_model: str = typer.Option(None, "--editor-model", help="Editor model name"),
editor_edit_format: str = typer.Option(None, "--editor-edit-format", help="Editor edit format"),
@@ -166,11 +176,6 @@ def main(
"--replay",
help="Replay previous .aider.chat.history.md responses from previous benchmark run",
),
max_apply_update_errors: int = typer.Option(
3,
"--max-apply-update-errors",
help="Maximum number of apply update errors before stopping the test",
),
keywords: str = typer.Option(
None, "--keywords", "-k", help="Only run tests that contain keywords (comma sep)"
),
@@ -185,6 +190,11 @@ def main(
stats_only: bool = typer.Option(
False, "--stats", "-s", help="Do not run tests, just collect stats on completed tests"
),
stats_languages: str = typer.Option(
None,
"--stats-languages",
help="Only include stats for specific languages (comma separated)",
),
diffs_only: bool = typer.Option(False, "--diffs", help="Just diff the provided stats dirs"),
tries: int = typer.Option(2, "--tries", "-r", help="Number of tries for running tests"),
threads: int = typer.Option(1, "--threads", "-t", help="Number of threads to run in parallel"),
@@ -221,7 +231,7 @@ def main(
updated_dirnames.append(dirname)
if stats_only:
return show_stats(updated_dirnames, graphs)
return show_stats(updated_dirnames, graphs, stats_languages)
if diffs_only:
return show_diffs(updated_dirnames)
@@ -234,9 +244,41 @@ def main(
return
assert BENCHMARK_DNAME.exists() and BENCHMARK_DNAME.is_dir(), BENCHMARK_DNAME
def get_exercise_dirs(base_dir, languages=None):
"""Get all exercise directories for specified languages (or all if none specified)"""
base_dir = Path(base_dir)
# Get available language dirs
lang_dirs = [d for d in base_dir.iterdir() if d.is_dir()]
# Filter to requested languages if specified
if languages:
requested = set(lang.strip().lower() for lang in languages.split(","))
lang_dirs = [d for d in lang_dirs if d.name.lower() in requested]
dump(lang_dirs)
if not lang_dirs:
print(f"No matching language directories found for: {languages}")
return []
# Get all exercise dirs under exercises/practice for each language
exercise_dirs = []
for lang_dir in lang_dirs:
practice_dir = lang_dir / "exercises" / "practice"
if practice_dir.exists():
exercise_dirs.extend(d for d in practice_dir.iterdir() if d.is_dir())
return exercise_dirs
original_dname = BENCHMARK_DNAME / exercises_dir
assert original_dname.exists() and original_dname.is_dir(), original_dname
exercise_dirs = get_exercise_dirs(original_dname, languages)
if not exercise_dirs:
print("No exercise directories found")
return 1
if clean and dirname.exists():
print("Cleaning up and replacing", dirname)
dir_files = set(fn.name for fn in dirname.glob("*"))
@@ -254,10 +296,19 @@ def main(
if not dirname.exists():
print(f"Copying {original_dname} -> {dirname} ...")
shutil.copytree(original_dname, dirname)
# Only copy the practice subdirs with exercises
os.makedirs(dirname, exist_ok=True)
for lang_dir in original_dname.iterdir():
if not lang_dir.is_dir():
continue
practice_dir = lang_dir / "exercises" / "practice"
if practice_dir.exists():
dest_lang_dir = dirname / lang_dir.name / "exercises" / "practice"
os.makedirs(dest_lang_dir.parent, exist_ok=True)
shutil.copytree(practice_dir, dest_lang_dir)
print("...done")
test_dnames = sorted(os.listdir(dirname))
test_dnames = sorted(str(d.relative_to(original_dname)) for d in exercise_dirs)
if keywords:
keywords = keywords.split(",")
@@ -267,12 +318,17 @@ def main(
if num_tests > 0:
test_dnames = test_dnames[:num_tests]
# Don't give up when benchmarking
LONG_TIMEOUT = 24 * 60 * 60
sendchat.RETRY_TIMEOUT = LONG_TIMEOUT
base_coder.RETRY_TIMEOUT = LONG_TIMEOUT
if threads == 1:
all_results = []
for testname in test_dnames:
for test_path in test_dnames:
results = run_test(
original_dname,
dirname / testname,
dirname / test_path,
model,
edit_format,
tries,
@@ -281,20 +337,22 @@ def main(
verbose,
commit_hash,
replay,
max_apply_update_errors,
editor_model,
editor_edit_format,
num_ctx,
sleep,
)
all_results.append(results)
summarize_results(dirname)
if sleep:
time.sleep(sleep)
else:
run_test_threaded = lox.thread(threads)(run_test)
for testname in test_dnames:
for test_path in test_dnames:
run_test_threaded.scatter(
original_dname,
dirname / testname,
dirname / test_path,
model,
edit_format,
tries,
@@ -303,7 +361,6 @@ def main(
verbose,
commit_hash,
replay,
max_apply_update_errors,
editor_model,
editor_edit_format,
)
@@ -354,17 +411,32 @@ def show_diffs(dirnames):
print("unchanged:", len(unchanged), ",".join(sorted(unchanged)))
def load_results(dirname):
def load_results(dirname, stats_languages=None):
dirname = Path(dirname)
all_results = [json.loads(fname.read_text()) for fname in dirname.glob("*/.aider.results.json")]
all_results = []
if stats_languages:
languages = [lang.strip().lower() for lang in stats_languages.split(",")]
glob_patterns = [f"{lang}/exercises/practice/*/.aider.results.json" for lang in languages]
else:
glob_patterns = ["*/exercises/practice/*/.aider.results.json"]
for pattern in glob_patterns:
for fname in dirname.glob(pattern):
try:
results = json.loads(fname.read_text())
all_results.append(results)
except json.JSONDecodeError:
print("json.JSONDecodeError", fname)
continue
return all_results
def summarize_results(dirname):
all_results = load_results(dirname)
def summarize_results(dirname, stats_languages=None):
all_results = load_results(dirname, stats_languages)
res = SimpleNamespace()
res.total_tests = len(list(Path(dirname).glob("*")))
res.total_tests = len(list(Path(dirname).glob("*/exercises/practice/*")))
try:
tries = max(len(results.get("tests_outcomes", [])) for results in all_results if results)
@@ -445,9 +517,10 @@ def summarize_results(dirname):
percents[i] = pass_rate
# console.print(f"{pass_rate:.1f}% correct after try {i+1}")
setattr(res, f"pass_rate_{i + 1}", f"{pass_rate:.1f}")
setattr(res, f"pass_num_{i + 1}", passed_tests[i])
print(f"- dirname: {dirname.name}")
style = None if res.completed_tests in NUM_TESTS else "red"
style = None if res.completed_tests == res.total_tests else "red"
console.print(f" test_cases: {res.completed_tests}", style=style)
for key, val in variants.items():
if len(val) > 1:
@@ -460,6 +533,8 @@ def summarize_results(dirname):
for i in range(tries):
print(f" pass_rate_{i + 1}: {percents[i]:.1f}")
for i in range(tries):
print(f" pass_num_{i + 1}: {passed_tests[i]}")
pct_well_formed = 1.0 - res.num_with_malformed_responses / res.completed_tests
print(f" percent_cases_well_formed: {pct_well_formed * 100:.1f}")
@@ -473,10 +548,12 @@ def summarize_results(dirname):
show("indentation_errors")
show("exhausted_context_windows")
show("test_timeouts")
print(f" total_tests: {res.total_tests}")
a_model = set(variants["model"]).pop()
command = f"aider --model {a_model}"
print(f" command: {command}")
if variants["model"]:
a_model = set(variants["model"]).pop()
command = f"aider --model {a_model}"
print(f" command: {command}")
print(f" date: {date}")
print(" versions:", ",".join(versions))
@@ -561,10 +638,10 @@ def run_test_real(
verbose,
commit_hash,
replay,
max_apply_update_errors,
editor_model,
editor_edit_format,
num_ctx=None,
sleep=0,
):
if not os.path.isdir(testdir):
print("Not a dir:", testdir)
@@ -578,25 +655,78 @@ def run_test_real(
if results_fname.exists():
try:
res = json.loads(results_fname.read_text())
# if res.get("test_timeouts", 0) > 0:
# print(f"{results_fname} test timeouts, redoing...")
# else:
return res
except JSONDecodeError:
print(f"{results_fname} failed to parse, skipping")
return
print(f"{results_fname} failed to parse, redoing...")
# Read solution and test files from config
fnames = []
for fname in testdir.glob("*"):
if (
"test" not in fname.name
and fname.is_file()
and fname.name[0] != "."
and fname.suffix == ".py"
):
fnames.append(fname)
config_file = testdir / ".meta/config.json"
if not config_file.exists():
raise ValueError(f"No config file found: {config_file}")
with open(config_file) as f:
config = json.loads(f.read())
# Get file sets from config
test_files = config.get("files", {}).get("test", [])
example_files = config.get("files", {}).get("example", [])
solution_files = set(config.get("files", {}).get("solution", []))
# Forcibly ignore certain files not covered by test_files and example_files
ignore_files = set(
[
"CMakeLists.txt",
"Cargo.toml",
]
)
# Add all files under .meta and .docs directories
ignore_files.update(str(p.relative_to(testdir)) for p in testdir.glob(".meta/**/*"))
ignore_files.update(str(p.relative_to(testdir)) for p in testdir.glob(".docs/**/*"))
# Also ignore test & example files
ignore_files.update(test_files)
ignore_files.update(example_files)
# Remove any ignore files from the solution set that LLM will edit
solution_files.difference_update(ignore_files)
# Copy all solution files
for file_path in solution_files:
src = testdir / Path(file_path)
if src.exists():
fnames.append(src)
# restore the original file, in case we interrupted a prev run
# after it had saved changes
original_fname = original_dname / testdir.name / fname.name
shutil.copy(original_fname, fname)
# Find the original file in the language-specific practice dir
lang_part = str(testdir).split("/exercises/practice/")[0]
original_fname = (
original_dname
/ Path(lang_part).name
/ "exercises"
/ "practice"
/ testdir.name
/ file_path
)
if original_fname.exists():
os.makedirs(src.parent, exist_ok=True)
shutil.copy(original_fname, src)
else:
print(f"Warning: Solution file not found: {src}")
# Copy all test files
for file_path in test_files:
src = testdir / Path(file_path)
if src.exists():
original_fname = original_dname / testdir.name / file_path
if original_fname.exists():
os.makedirs(src.parent, exist_ok=True)
shutil.copy(original_fname, src)
else:
print(f"Warning: Test file not found: {src}")
file_list = " ".join(fname.name for fname in fnames)
@@ -650,8 +780,10 @@ def run_test_real(
# auto_lint=False, # disabled for code-in-json experiments
cache_prompts=True,
suggest_shell_commands=False,
ignore_mentions=ignore_files,
)
coder.max_apply_update_errors = max_apply_update_errors
dump(coder.ignore_mentions)
coder.show_announcements()
timeouts = 0
@@ -677,6 +809,7 @@ def run_test_real(
coder.apply_updates()
else:
response = coder.run(with_message=instructions, preproc=False)
dur += time.time() - start
if not no_aider:
@@ -693,8 +826,11 @@ def run_test_real(
break
try:
errors = run_unit_tests(testdir, history_fname)
errors = run_unit_tests(original_dname, testdir, history_fname, test_files)
except subprocess.TimeoutExpired:
# try:
# errors = run_unit_tests(original_dname, testdir, history_fname, test_files)
# except subprocess.TimeoutExpired:
errors = "Tests timed out!"
timeouts += 1
@@ -713,11 +849,44 @@ def run_test_real(
indentation_errors += sum(1 for line in errors if line.startswith("IndentationError"))
print(errors[-1])
errors = errors[:50]
errors = "\n".join(errors)
instructions = errors
instructions += prompts.test_failures.format(file_list=file_list)
# Clean up build directories after all attempts
# Rust target/debug
target_dir = testdir / "target" / "debug"
if target_dir.exists():
try:
shutil.rmtree(target_dir)
if verbose:
print(f"Cleaned up Rust target/debug directory: {target_dir}")
except (OSError, shutil.Error, PermissionError) as e:
if verbose:
print(f"Failed to clean up Rust target/debug directory: {e}")
# Java build directories
java_build_dir = testdir / "build"
if java_build_dir.exists():
try:
shutil.rmtree(java_build_dir)
if verbose:
print(f"Cleaned up Java build directory: {java_build_dir}")
except (OSError, shutil.Error, PermissionError) as e:
if verbose:
print(f"Failed to clean up Java build directory: {e}")
# Node.js node_modules directories
node_modules_dir = testdir / "node_modules"
if node_modules_dir.exists():
try:
shutil.rmtree(node_modules_dir)
if verbose:
print(f"Cleaned up Node.js node_modules directory: {node_modules_dir}")
except (OSError, shutil.Error, PermissionError) as e:
if verbose:
print(f"Failed to clean up Node.js node_modules directory: {e}")
results = dict(
testdir=str(testdir),
testcase=testdir.name,
@@ -753,22 +922,50 @@ def run_test_real(
return results
def run_unit_tests(testdir, history_fname):
command = [
"python",
"-m",
"unittest",
"discover",
"-s",
str(testdir),
"-t",
str(testdir),
"-p",
"*_test.py",
]
print(" ".join(command))
def run_unit_tests(original_dname, testdir, history_fname, test_files):
timeout = 60 * 3
timeout = 60
# Remove @Disabled annotations from Java test files
for file_path in test_files:
if file_path.endswith(".java"):
test_file = testdir / file_path
if test_file.exists():
content = test_file.read_text()
content = re.sub(r"@Disabled\([^)]*\)\s*\n", "", content)
test_file.write_text(content)
# Map of file extensions to test commands
TEST_COMMANDS = {
".py": ["pytest"],
".rs": ["cargo", "test", "--", "--include-ignored"],
".go": ["go", "test", "./..."],
".js": ["/aider/benchmark/npm-test.sh"],
".cpp": ["/aider/benchmark/cpp-test.sh"],
".java": ["./gradlew", "test"],
}
# Get unique file extensions from test files
extensions = {Path(f).suffix for f in test_files}
# Find matching test command
command = None
for ext in extensions:
if ext in TEST_COMMANDS:
command = TEST_COMMANDS[ext]
break
if not command:
raise ValueError(f"No test command found for files with extensions: {extensions}")
# Copy test files from original directory
for file_path in test_files:
src = original_dname / testdir.name / file_path
dst = testdir / file_path
if src.exists():
os.makedirs(dst.parent, exist_ok=True)
shutil.copy(src, dst)
print(" ".join(command))
result = subprocess.run(
command,
@@ -776,11 +973,13 @@ def run_unit_tests(testdir, history_fname):
stderr=subprocess.STDOUT,
text=True,
timeout=timeout,
cwd=testdir,
)
success = result.returncode == 0
res = result.stdout
res = cleanup_test_output(res, testdir)
dump(res)
with history_fname.open("a") as fh:
fh.write(f"```\n{res}\n```")
@@ -792,25 +991,7 @@ def run_unit_tests(testdir, history_fname):
def cleanup_test_output(output, testdir):
# remove timing info, to avoid randomizing the response to GPT
res = re.sub(
r"^Ran \d+ tests in \d+\.\d+s$",
"",
output,
flags=re.MULTILINE,
)
res = re.sub(
r"^====*$",
"====",
res,
flags=re.MULTILINE,
)
res = re.sub(
r"^----*$",
"----",
res,
flags=re.MULTILINE,
)
res = re.sub(r"\bin \d+\.\d+s\b", "", output)
res = res.replace(str(testdir), str(testdir.name))
return res

20
benchmark/clone-exercism.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Create directories if they don't exist
mkdir -p tmp.benchmarks/exercism
# Change to the exercism directory
cd tmp.benchmarks/exercism
# List of languages to clone
languages=("cpp" "go" "java" "javascript" "python" "rust")
# Clone each repository
for lang in "${languages[@]}"; do
if [ ! -d "$lang" ]; then
echo "Cloning $lang repository..."
git clone "https://github.com/exercism/$lang"
else
echo "$lang repository already exists"
fi
done

11
benchmark/cpp-test.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
# exit when any command fails
set -e
[ ! -d "build" ] && mkdir build
cd build
cmake -G "Unix Makefiles" ..
make

View File

@@ -7,6 +7,10 @@ docker run \
-v `pwd`/tmp.benchmarks/.:/benchmarks \
-e OPENAI_API_KEY=$OPENAI_API_KEY \
-e HISTFILE=/aider/.bash_history \
-e PROMPT_COMMAND='history -a' \
-e HISTCONTROL=ignoredups \
-e HISTSIZE=10000 \
-e HISTFILESIZE=20000 \
-e AIDER_DOCKER=1 \
-e AIDER_BENCHMARK_DIR=/benchmarks \
aider-benchmark \

View File

@@ -0,0 +1,63 @@
#!/bin/bash
# Exit on error
set -e
# Update package index
echo "Updating package index..."
sudo apt-get update
# Install prerequisites
echo "Installing prerequisites..."
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# Add Docker's official GPG key
echo "Adding Docker's GPG key..."
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up the repository
echo "Setting up Docker repository..."
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update package index again
sudo apt-get update
# Install Docker Engine
echo "Installing Docker Engine..."
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Add current user to docker group and verify
echo "Adding current user to docker group..."
sudo usermod -aG docker $USER
# Verify group addition
if getent group docker | grep -q "\b${USER}\b"; then
echo "Successfully added $USER to docker group"
else
echo "Failed to add $USER to docker group. Retrying..."
# Force group addition
sudo gpasswd -a $USER docker
fi
# Print success message and instructions
echo "Docker installation completed successfully!"
# Start Docker service
echo "Starting Docker service..."
sudo systemctl start docker
sudo systemctl enable docker
# Verify Docker installation and service status
echo "Docker version:"
docker --version
echo "Docker Compose version:"
docker compose version

13
benchmark/npm-test.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
# exit when any command fails
set -e
# Create symlinks if they don't exist
[ ! -e node_modules ] && ln -s /npm-install/node_modules .
[ ! -e package-lock.json ] && ln -s /npm-install/package-lock.json .
sed -i 's/\bxtest(/test(/g' *.spec.js
npm run test

355
benchmark/problem_stats.py Executable file
View File

@@ -0,0 +1,355 @@
#!/usr/bin/env python
import argparse
import json
import shutil
from collections import defaultdict
from pathlib import Path
import yaml
from aider.dump import dump # noqa
HARD_SET_NUM = 3 # Number of models that defines the hard set threshold
def get_dirs_from_leaderboard():
# Load the leaderboard data
with open("aider/website/_data/edit_leaderboard.yml") as f:
leaderboard = yaml.safe_load(f)
return [(entry["dirname"], entry["model"]) for entry in leaderboard]
def load_results(dirname):
"""Load all result files from a benchmark directory"""
dirname = Path(dirname)
benchmark_dir = dirname
if not benchmark_dir.exists():
benchmark_dir = Path("tmp.benchmarks") / dirname
if not benchmark_dir.exists():
return None
all_results = []
parse_errors = [] # Track which exercises had parse errors for this model
# Look in language subdirectories under exercises/practice
for fname in benchmark_dir.glob("*/exercises/practice/*/.aider.results.json"):
error = False
try:
results = json.loads(fname.read_text())
error = "testcase" not in results
if not error:
# Add language info to results
lang = fname.parts[-5] # Get language from path
results["language"] = lang
all_results.append(results)
except json.JSONDecodeError:
error = True
if error:
# Track the parse error for this exercise/model combination
lang = fname.parts[-5]
exercise = f"{fname.parts[-2]}/{lang}" # Use directory name as testcase
parse_errors.append(exercise)
print(f"Bad results file {fname}")
continue
return all_results, parse_errors
def analyze_exercise_solutions(dirs=None, topn=None, copy_hard_set=False):
PARSE_ERROR_M = 4 # Threshold for number of parse errors to DQ an exercise
if dirs is None:
# Use leaderboard data if no directories specified
dir_entries = get_dirs_from_leaderboard()
else:
# Use provided directories, with dirname as model name
dir_entries = [(d, d) for d in dirs]
# Filter out entries that don't load and sort by pass rate
valid_entries = []
parse_errors_by_model = {} # Track which exercises had parse errors for each model
dump(dir_entries)
for dirname, model in dir_entries:
results_data = load_results(dirname)
if results_data:
results, model_parse_errors = results_data
parse_errors_by_model[model] = set(model_parse_errors)
# Calculate pass rate for sorting when using custom dirs
if dirs is not None:
pass_rate = sum(
1 for r in results if r.get("tests_outcomes", []) and r["tests_outcomes"][-1]
) / len(results)
else:
# Use existing pass rate from leaderboard
pass_rate = next(
(
entry["pass_rate_2"]
for entry in yaml.safe_load(
open("aider/website/_data/edit_leaderboard.yml")
)
if entry["dirname"] == dirname
),
0,
)
valid_entries.append(((dirname, model), results, float(pass_rate)))
# Sort by pass rate and take top N if specified
valid_entries.sort(key=lambda x: x[2], reverse=True)
if topn:
valid_entries = valid_entries[:topn]
# Get all exercise names from a complete run
all_exercises = set()
exercise_solutions = defaultdict(list)
# Get all unique exercise names from all results
all_exercises = set()
for (dirname, model), results, _ in valid_entries:
if results:
for result in results:
try:
all_exercises.add(result["testcase"] + "/" + result["language"])
except KeyError:
print(f"Warning: Missing testcase in {dirname}", json.dumps(result, indent=4))
for (dirname, model), results, _ in valid_entries:
if not results:
print(f"Could not load results for {dirname}")
continue
for result in results:
testcase = result.get("testcase")
if not testcase:
continue
lang = result.get("language")
if not lang:
continue
testcase = f"{testcase}/{lang}"
# Consider it solved if the last test attempt passed
tests_outcomes = result.get("tests_outcomes", [])
if tests_outcomes and tests_outcomes[-1]:
exercise_solutions[testcase].append(model)
# Calculate never solved exercises
never_solved = len(all_exercises - set(exercise_solutions.keys()))
# Print per-exercise statistics
print("\nExercise Solution Statistics:")
print("-" * 40)
# Add exercises that were never solved
for exercise in all_exercises:
if exercise not in exercise_solutions:
exercise_solutions[exercise] = []
# Create list of (language, exercise) pairs with solution stats
exercise_stats = []
total_models = len(valid_entries)
for testcase in all_exercises:
# Language is already in the testcase string
lang = testcase.split("/")[0] # First part is the language
models = exercise_solutions[testcase]
num_solved = len(models)
percent = (num_solved / total_models) * 100
testcase = testcase.replace("exercises/", "") # Remove the exercises/ prefix
# Remove duplicate language prefix (e.g. javascript/javascript/ -> javascript/)
if testcase.startswith(f"{lang}/{lang}/"):
testcase = testcase[len(lang) + 1 :]
exercise_stats.append((lang, testcase, num_solved, percent))
# Sort all exercises by solve rate, then by exercise name
exercise_stats.sort(
key=lambda x: (-x[2], x[1])
) # -x[2] for descending solve rate, x[1] for ascending exercise name
# Calculate max lengths for alignment after cleaning up paths
max_name_len = max(len(f"{lang}/{testcase}") for lang, testcase, _, _ in exercise_stats)
# Print all exercises sorted by solve rate
print("\nAll Exercises (sorted by solve rate):")
for i, (lang, testcase, num_solved, percent) in enumerate(exercise_stats, 1):
print(f"{i:>3}. {testcase:<{max_name_len}} : {num_solved:>3} solved ({percent:>5.1f}%)")
print("\nSummary:")
solved_at_least_once = len([ex for ex, models in exercise_solutions.items() if models])
solved_by_none = never_solved
solved_by_all = len(
[ex for ex, models in exercise_solutions.items() if len(models) == total_models]
)
print(f"Total exercises solved at least once: {solved_at_least_once}")
print(f"Never solved by any model: {solved_by_none}")
if solved_by_none > 0:
print("\nExercises never solved by any model:")
unsolved = [ex for ex, models in exercise_solutions.items() if not models]
for ex in sorted(unsolved):
# Split into language and exercise parts
lang, exercise = ex.split("/")
# Reconstruct path in desired format
formatted_path = f"{lang}/exercises/practice/{exercise}"
print(f" {formatted_path}")
print(f"\nSolved by all models: {solved_by_all}")
print(
f"Total exercises: {len(all_exercises)} = {solved_by_none} (none) + {solved_by_all} (all) +"
f" {len(all_exercises) - solved_by_none - solved_by_all} (some)"
)
# Distribution table of how many models solved each exercise
print("\nDistribution of solutions:")
print("Models Exercises Cumulative RevCumulative")
print("-" * 50)
counts = [0] * (total_models + 1)
for ex, models in exercise_solutions.items():
counts[len(models)] += 1
cumsum = 0
revcumsum = sum(counts) # Start with total number of exercises
for i, count in enumerate(counts):
cumsum += count
print(f"{i:>6d} {count:>9d} {cumsum:>10d} {revcumsum:>12d}")
revcumsum -= count # Decrement the reverse cumulative sum
# Count parse errors per exercise
parse_error_counts = defaultdict(int)
for model_errors in parse_errors_by_model.values():
for exercise in model_errors:
parse_error_counts[exercise] += 1
# Find exercises to disqualify based on parse error threshold
disqualified_exercises = {
exercise for exercise, count in parse_error_counts.items() if count >= PARSE_ERROR_M
}
if disqualified_exercises:
print(
f"\nDisqualified {len(disqualified_exercises)} exercises with {PARSE_ERROR_M}+ parse"
" errors:"
)
for ex in sorted(disqualified_exercises):
print(f" {ex} ({parse_error_counts[ex]} parse errors)")
# Collect the hard set (exercises solved by HARD_SET_NUM or fewer models)
print(f"\nHard Set Analysis (exercises solved by ≤{HARD_SET_NUM} models):")
print("-" * 60)
hard_set = {
ex
for ex, models in exercise_solutions.items()
if len(models) <= HARD_SET_NUM and ex not in disqualified_exercises
}
print(f"Total hard set exercises: {len(hard_set)}")
# Count total problems, unsolved problems, and hard set problems by language
lang_totals = defaultdict(int)
lang_unsolved = defaultdict(int)
lang_hard_set = defaultdict(int)
for exercise in all_exercises:
lang = exercise.split("/")[1] # Get language from path
lang_totals[lang] += 1
if not exercise_solutions[exercise]: # No models solved this exercise
lang_unsolved[lang] += 1
if exercise in hard_set: # Exercise is in the hard set
lang_hard_set[lang] += 1
print("\nUnsolved and hard set problems by language:")
print(f"{'Language':<12} {'Unsolved':>8} {'Hard Set':>9} {'Total':>7} {'%hardUnsolved':>8}")
print("-" * 47)
for lang in sorted(lang_totals.keys()):
count = lang_unsolved[lang]
hard = lang_hard_set[lang]
total = lang_totals[lang]
pct = (count / hard) * 100 if hard else -1
print(f"{lang:<12} {count:>8} {hard:>9} {total:>7} {pct:>7.1f}%")
print()
# For each model, compute performance on hard set
model_hard_stats = []
for (dirname, model), results, _ in valid_entries:
if not results:
continue
solved_hard = 0
for result in results:
testcase = result.get("testcase")
if not testcase:
continue
lang = result.get("language")
if not lang:
continue
testcase = f"{testcase}/{lang}"
if testcase in hard_set:
tests_outcomes = result.get("tests_outcomes", [])
if tests_outcomes and tests_outcomes[-1]:
solved_hard += 1
pct = (solved_hard / len(hard_set)) * 100
model_hard_stats.append((model, solved_hard, pct))
# Sort by number solved
model_hard_stats.sort(key=lambda x: x[1], reverse=True)
print("\nModel performance on hard set:")
print(f"{'Model':<55} {'Solved':<8} {'Percent':>7}")
print("-" * 50)
for model, solved, pct in model_hard_stats:
print(f"{model:<55} {solved:>6d} {pct:>6.1f}%")
if copy_hard_set:
# Create hard set directory
src_dir = Path("tmp.benchmarks/exercism")
dst_dir = Path("tmp.benchmarks/exercism-polyglot")
if dst_dir.exists():
print(f"\nError: Destination directory {dst_dir} already exists")
return
print(f"\nCopying hard set problems to {dst_dir}...")
# Create a set of (exercise, language) pairs from hard_set
hard_set_pairs = {tuple(exercise.split("/")) for exercise in hard_set}
# Copy each hard set problem's directory
copied_by_lang = defaultdict(int)
for lang_dir in src_dir.glob("*/exercises/practice"):
if not lang_dir.is_dir():
continue
lang = lang_dir.parts[-3] # Get language from path
for problem_dir in lang_dir.glob("*"):
if (problem_dir.name, lang) in hard_set_pairs:
rel_path = problem_dir.relative_to(src_dir)
dst_path = dst_dir / rel_path
dst_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copytree(problem_dir, dst_path)
copied_by_lang[lang] += 1
total_copied = sum(copied_by_lang.values())
print(f"\nCopied {total_copied} hard set problems:")
for lang in sorted(copied_by_lang):
print(f" {lang}: {copied_by_lang[lang]}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--topn", type=int, help="Only consider top N models by pass rate")
parser.add_argument(
"dirs", nargs="*", help="Directories to analyze (optional, defaults to leaderboard entries)"
)
parser.add_argument(
"--copy-hard-set",
action="store_true",
help="Copy hard set problems to tmp.benchmarks/exercism-polygot",
)
args = parser.parse_args()
analyze_exercise_solutions(args.dirs if args.dirs else None, args.topn, args.copy_hard_set)

View File

@@ -3,7 +3,7 @@ instructions_addendum = """
Use the above instructions to modify the supplied files: {file_list}
Don't change the names of existing functions or classes, as they may be referenced from other code like unit tests, etc.
Only use standard python libraries, don't suggest installing any packages.
Only use standard libraries, don't suggest installing any packages.
""" # noqa: E501
@@ -11,6 +11,6 @@ test_failures = """
####
See the testing errors above.
The tests are correct.
The tests are correct, don't try and change them.
Fix the code in {file_list} to resolve the errors.
"""

33
benchmark/rsync.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
set -e
if [ $# -ne 1 ]; then
echo "Usage: $0 user@host"
exit 1
fi
DEST="$1"
REPO_ROOT="$(git rev-parse --show-toplevel)"
# Create a temporary file for rsync exclude patterns
EXCLUDE_FILE=$(mktemp)
# Convert .gitignore patterns to rsync exclude patterns
git -C "$REPO_ROOT" ls-files --exclude-standard --others --ignored --directory > "$EXCLUDE_FILE"
# Create remote directory if needed
ssh "$DEST" "mkdir -p ~/aider"
# Sync the repository
rsync -avz --delete \
--exclude-from="$EXCLUDE_FILE" \
"$REPO_ROOT/" \
"$DEST:~/aider/"
rsync -a .env .gitignore "$DEST:~/aider/."
rsync -a ~/dotfiles/screenrc "$DEST:.screenrc"
# Clean up
rm "$EXCLUDE_FILE"

View File

@@ -1,23 +1,26 @@
FROM python:3.10-slim AS base
# Install system dependencies
RUN apt-get update && \
apt-get install --no-install-recommends -y build-essential git libportaudio2 pandoc && \
rm -rf /var/lib/apt/lists/*
# Create app user with UID 1000
RUN useradd -m -u 1000 -s /bin/bash appuser
WORKDIR /app
# Create virtual environment
RUN python -m venv /venv
ENV PATH="/venv/bin:$PATH"
# https://playwright.dev/python/docs/browsers
ENV PLAYWRIGHT_BROWSERS_PATH=/pw-browsers
# Playwright browser settings
ENV PLAYWRIGHT_BROWSERS_PATH=/home/appuser/pw-browsers
ENV PLAYWRIGHT_SKIP_BROWSER_GC=1
# Permission kludges to support `docker run --user xxx`
RUN chmod a+rwx /venv /venv/bin /venv/include /venv/lib /venv/lib/python3.10/site-packages
RUN mkdir /.aider /.cache /pw-browsers
RUN chmod a+rwx /.aider /.cache /pw-browsers
# Create directories with proper permissions
RUN mkdir -p /home/appuser/.aider /home/appuser/.cache /home/appuser/pw-browsers && \
chown -R appuser:appuser /home/appuser /app /venv
# So git doesn't complain about unusual permissions
RUN git config --system --add safe.directory /app
@@ -28,14 +31,22 @@ FROM base AS aider-full
ENV AIDER_DOCKER_IMAGE=paulgauthier/aider-full
COPY . /tmp/aider
RUN /venv/bin/python -m pip install --upgrade --no-cache-dir pip \
&& /venv/bin/python -m pip install --no-cache-dir /tmp/aider[help,browser,playwright] \
--extra-index-url https://download.pytorch.org/whl/cpu \
&& rm -rf /tmp/aider
# Install dependencies as root
RUN /venv/bin/python -m pip install --upgrade --no-cache-dir pip && \
/venv/bin/python -m pip install --no-cache-dir /tmp/aider[help,browser,playwright] \
--extra-index-url https://download.pytorch.org/whl/cpu && \
rm -rf /tmp/aider
# Install playwright browsers
RUN /venv/bin/python -m playwright install --with-deps chromium
# Fix site-packages permissions
RUN find /venv/lib/python3.10/site-packages \( -type d -exec chmod a+rwx {} + \) -o \( -type f -exec chmod a+rw {} + \)
# Switch to appuser
USER appuser
ENTRYPOINT ["/venv/bin/aider"]
#########################
@@ -44,12 +55,20 @@ FROM base AS aider
ENV AIDER_DOCKER_IMAGE=paulgauthier/aider
COPY . /tmp/aider
RUN /venv/bin/python -m pip install --upgrade --no-cache-dir pip \
&& /venv/bin/python -m pip install --no-cache-dir /tmp/aider[playwright] \
--extra-index-url https://download.pytorch.org/whl/cpu \
&& rm -rf /tmp/aider
# Install dependencies as root
RUN /venv/bin/python -m pip install --upgrade --no-cache-dir pip && \
/venv/bin/python -m pip install --no-cache-dir /tmp/aider[playwright] \
--extra-index-url https://download.pytorch.org/whl/cpu && \
rm -rf /tmp/aider
# Install playwright browsers
RUN /venv/bin/python -m playwright install --with-deps chromium
# Fix site-packages permissions
RUN find /venv/lib/python3.10/site-packages \( -type d -exec chmod a+rwx {} + \) -o \( -type f -exec chmod a+rw {} + \)
# Switch to appuser
USER appuser
ENTRYPOINT ["/venv/bin/aider"]

View File

@@ -1,7 +1,3 @@
# [[[cog
# from aider.help_pats import exclude_website_pats
# ]]]
# [[[end]]]
[project]
name = "aider-chat"
@@ -38,29 +34,11 @@ help = { file = "requirements/requirements-help.txt" }
browser = { file = "requirements/requirements-browser.txt" }
playwright = { file = "requirements/requirements-playwright.txt" }
[tool.setuptools]
include-package-data = true
[tool.setuptools.packages.find]
include = ["aider*", "aider.website"]
[tool.setuptools.package-data]
"aider" = ["queries/*.scm"]
"aider.website" = ["**/*.md"]
[tool.setuptools.exclude-package-data]
"aider.website" = [
# [[[cog
# cog.out("\n".join(f' "{pat}",' for pat in exclude_website_pats))
# ]]]
"examples/**",
"_posts/**",
"HISTORY.md",
"docs/benchmarks*md",
"docs/ctags.md",
"docs/unified-diffs.md",
"docs/leaderboards/index.md",
"assets/**",
"**/.DS_Store",
# [[[end]]]
]
include = ["aider"]
[build-system]
requires = ["setuptools>=68", "setuptools_scm[toml]>=8"]

Some files were not shown because too many files have changed in this diff Show More