Compare commits

...

429 Commits

Author SHA1 Message Date
Paul Gauthier
a73e77a819 set version to 0.65.1.dev 2024-11-26 08:57:36 -08:00
Paul Gauthier
b5f1659382 version bump to 0.65.0 2024-11-26 08:55:57 -08:00
Paul Gauthier
beb6722f57 copy 2024-11-26 08:04:17 -08:00
Paul Gauthier
a052b89152 copy 2024-11-26 07:42:16 -08:00
Paul Gauthier
95b391350f bumped deps 2024-11-26 07:41:31 -08:00
Paul Gauthier
5773eac03f copy 2024-11-26 07:37:56 -08:00
Paul Gauthier (aider)
da4ace2875 style: Fix string quote consistency in update-history.py 2024-11-26 07:31:36 -08:00
Paul Gauthier (aider)
e507c5b502 feat: add aider contribution percentage to history updates 2024-11-26 07:31:32 -08:00
Paul Gauthier (aider)
722c2c2668 style: fix linting errors in test_repomap.py 2024-11-26 07:28:02 -08:00
Paul Gauthier (aider)
8e7bfef9f1 test: add Dart language support to repo map tests 2024-11-26 07:27:57 -08:00
Paul Gauthier
1811f0d0d5 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-26 07:27:32 -08:00
paul-gauthier
6b9d534fe2 Merge pull request #2236 from malkoG/support-dart
Add dart support
2024-11-26 07:26:43 -08:00
Paul Gauthier (aider)
dc4562a845 feat: add docs update step after aider in update-history script 2024-11-26 07:10:32 -08:00
Paul Gauthier
c15af63bc9 copy 2024-11-26 07:10:03 -08:00
Paul Gauthier
5b68c2c7d9 fix test 2024-11-26 07:09:49 -08:00
Paul Gauthier (aider)
b70e0bd1f6 test: update invalid edit format test to check return code instead of SystemExit 2024-11-26 07:07:11 -08:00
Paul Gauthier (aider)
743f0f5540 test: add test for invalid edit format handling 2024-11-26 07:06:28 -08:00
Paul Gauthier (aider)
e647a5b733 feat: add tests for UnknownEditFormat exception handling 2024-11-26 07:04:43 -08:00
Paul Gauthier (aider)
df1d259e42 style: Fix linting issues in test_coder.py 2024-11-26 07:04:21 -08:00
Paul Gauthier (aider)
e3efab7fbf test: add UnknownEditFormat exception tests 2024-11-26 07:04:15 -08:00
Paul Gauthier (aider)
cd79f7f4b0 fix: import UnknownEditFormat exception from base_coder module 2024-11-26 07:03:26 -08:00
Paul Gauthier (aider)
5d175745bf fix: handle None values in valid_formats list generation 2024-11-26 07:02:34 -08:00
Paul Gauthier (aider)
e648bac74b fix: remove circular import of UnknownEditFormat in base_coder.py 2024-11-26 07:01:55 -08:00
Paul Gauthier (aider)
e5c0ebd0a0 style: fix import order in base_coder.py 2024-11-26 07:01:21 -08:00
Paul Gauthier (aider)
608a43402c refactor: move UnknownEditFormat exception to base_coder.py 2024-11-26 07:01:14 -08:00
Paul Gauthier (aider)
75bc2dd564 feat: add custom UnknownEditFormat exception with documentation link 2024-11-26 07:00:16 -08:00
Paul Gauthier
bbd81c3cf7 copy 2024-11-26 06:56:36 -08:00
Paul Gauthier
301eb7c74d copy 2024-11-26 06:50:18 -08:00
Paul Gauthier
a756039f27 copy 2024-11-26 06:49:28 -08:00
Paul Gauthier (aider)
b4d1b71ee7 test: add test for skipping duplicate basename file mentions 2024-11-26 06:46:53 -08:00
Paul Gauthier (aider)
8d85a4754d style: fix line wrapping in base_coder.py 2024-11-26 06:46:08 -08:00
Paul Gauthier (aider)
a1b48049a9 feat: skip files with duplicate basenames in file mentions 2024-11-26 06:46:01 -08:00
Paul Gauthier
6789844c1f copy 2024-11-26 06:42:42 -08:00
Paul Gauthier
c602a839ca better update history script 2024-11-26 06:42:36 -08:00
Paul Gauthier
01c7793e90 revert changes to get_ident_filename_matches() 2024-11-26 06:41:08 -08:00
Paul Gauthier (aider)
47b013b034 docs: update changelog with recent improvements and features 2024-11-26 06:38:59 -08:00
Paul Gauthier
dc2047804a docs: update changelog with URL detection and model alias features 2024-11-26 06:38:57 -08:00
Paul Gauthier (aider)
885e5cbd7c style: fix whitespace in base_coder.py 2024-11-26 06:33:37 -08:00
Paul Gauthier (aider)
635a5196e8 fix: exclude files with same name as existing chat or read-only files 2024-11-26 06:33:29 -08:00
Paul Gauthier
cbd339190b refactor: simplify file name matching logic in get_all_relative_files 2024-11-26 06:33:28 -08:00
Paul Gauthier (aider)
266093189d style: fix linting issues in get_ident_filename_matches 2024-11-26 06:26:26 -08:00
Paul Gauthier (aider)
62b02d4370 fix: remove incorrect file name filtering in get_ident_filename_matches 2024-11-26 06:25:15 -08:00
Paul Gauthier (aider)
8546a1dc86 docs: add main branch changes to release history 2024-11-26 06:25:00 -08:00
Paul Gauthier
ae98bf237f docs: remove unreleased changes from history file 2024-11-26 06:24:59 -08:00
Paul Gauthier (aider)
0398deb005 test: add tests for filename matching with existing and read-only files 2024-11-26 06:24:11 -08:00
Paul Gauthier (aider)
3a1492977b fix: skip suggesting files with same name as existing chat files 2024-11-26 06:22:57 -08:00
Paul Gauthier (aider)
ef40a456e8 docs: add main branch section with latest changes to history 2024-11-26 06:20:04 -08:00
Paul Gauthier
583b78c0c1 docs: update release history to remove unreleased changes 2024-11-26 06:20:03 -08:00
Paul Gauthier (aider)
c0988de581 docs: update release history with v0.64.1 and v0.64.2 changes 2024-11-26 06:17:06 -08:00
Paul Gauthier
34a190e29b docs: remove v0.64.2 release notes 2024-11-26 06:17:04 -08:00
Paul Gauthier (aider)
0940598708 docs: add v0.64.2 release notes to history 2024-11-26 06:12:13 -08:00
Paul Gauthier (aider)
7e6cbb3efa style: format update-history.py with black 2024-11-26 06:10:07 -08:00
Paul Gauthier (aider)
7dc4e00c75 feat: dynamically determine base version for history updates 2024-11-26 06:10:03 -08:00
Paul Gauthier (aider)
8a598eacaf style: format update-history.py with black 2024-11-26 06:09:44 -08:00
Paul Gauthier (aider)
8592fad9cd feat: add script to automate history updates from git diffs 2024-11-26 06:09:41 -08:00
Paul Gauthier
fa72a89d35 feat: add script to update history file 2024-11-26 06:09:38 -08:00
Paul Gauthier
5e99c51d93 copy 2024-11-26 06:01:46 -08:00
Paul Gauthier (aider)
905976e765 feat: add verbose and trace flags for Jekyll debugging 2024-11-26 05:59:52 -08:00
Paul Gauthier
3ebd47d3db copy 2024-11-25 21:12:01 -08:00
Paul Gauthier
bf4c7c475a copy 2024-11-25 21:08:27 -08:00
Paul Gauthier (aider)
bf38371971 test: add test cases for model name aliases 2024-11-25 21:06:29 -08:00
Paul Gauthier
18460f4f91 copy 2024-11-25 21:05:59 -08:00
Paul Gauthier (aider)
f94e3e6aba feat: add cog script to auto-generate model aliases docs 2024-11-25 21:03:35 -08:00
Paul Gauthier
1647da2942 docs: add frontmatter to model aliases documentation 2024-11-25 21:03:34 -08:00
Paul Gauthier (aider)
86e2cdb1fb docs: add documentation for model aliases configuration 2024-11-25 21:01:11 -08:00
Paul Gauthier
764702a377 docs: add model aliases configuration documentation 2024-11-25 21:01:10 -08:00
Paul Gauthier (aider)
837a97ffdf style: fix string quote consistency in alias split 2024-11-25 20:56:10 -08:00
Paul Gauthier (aider)
217e9b96d8 feat: add command-line model alias support via --alias flag 2024-11-25 20:56:04 -08:00
Paul Gauthier (aider)
524274fcf4 refactor: consolidate model aliases into central dictionary 2024-11-25 20:54:24 -08:00
Paul Gauthier
6d5f576b92 refactor: simplify model aliases to only include Claude-3 variants 2024-11-25 20:54:23 -08:00
Paul Gauthier (aider)
445f9fa7df feat: add model name aliases with canonical mapping 2024-11-25 20:51:37 -08:00
Paul Gauthier (aider)
2ff3a23606 fix: add num_ctx parameter to run_test_real function 2024-11-25 19:21:08 -08:00
Paul Gauthier (aider)
c5ce57ea7f style: fix linting issues in benchmark.py 2024-11-25 19:20:49 -08:00
Paul Gauthier (aider)
351b8e50f0 feat: add --num-ctx flag to override model context window size 2024-11-25 19:20:43 -08:00
Paul Gauthier
68be6c5742 copy 2024-11-25 19:11:18 -08:00
Paul Gauthier
7a34a2dfa9 ask 2.5% of users to opt-in to analytics 2024-11-25 19:09:59 -08:00
Paul Gauthier
49ce9e1209 copy 2024-11-25 18:42:28 -08:00
Paul Gauthier (aider)
c84e192324 style: remove extra blank line in test_coder.py 2024-11-25 18:42:09 -08:00
Paul Gauthier (aider)
d696673f07 test: remove shell command testing from URL detection test 2024-11-25 18:42:03 -08:00
Paul Gauthier (aider)
2957d463c9 test: add assertion for suggest_shell_commands flag 2024-11-25 18:41:21 -08:00
Paul Gauthier (aider)
af48e50898 test: add tests for URL detection functionality in Coder class 2024-11-25 18:39:49 -08:00
Paul Gauthier (aider)
f4b964a4b8 test: add tests for --[no-]detect-urls CLI option 2024-11-25 18:39:10 -08:00
Paul Gauthier
a79ce7a151 fix: remove duplicate detect_urls parameter and add to coder initialization 2024-11-25 18:38:34 -08:00
Paul Gauthier (aider)
21bb83c55a fix: remove duplicate detect_urls parameter in Coder class 2024-11-25 18:36:25 -08:00
Paul Gauthier (aider)
7122ceb16c feat: add --detect-urls flag to control URL detection behavior 2024-11-25 18:34:05 -08:00
Paul Gauthier
f9bcfe341c ignore .gitattributes 2024-11-25 15:09:46 -08:00
Paul Gauthier
13c5bfdd88 copy 2024-11-25 09:05:52 -08:00
Paul Gauthier
bf79c2cb99 copy 2024-11-25 08:28:42 -08:00
Paul Gauthier
325cdfcf57 refactor: Update Ollama model detection and context window documentation 2024-11-24 16:14:34 -08:00
Paul Gauthier
7d14d4ade9 copy 2024-11-24 15:23:47 -08:00
Paul Gauthier
1b7d12194e copy 2024-11-24 15:23:42 -08:00
Paul Gauthier (aider)
91f238aded style: Organize imports and remove unused import 2024-11-24 15:20:47 -08:00
Paul Gauthier (aider)
78ff489995 feat: Add ModelSettings import to main.py 2024-11-24 15:20:43 -08:00
Paul Gauthier (aider)
ff791439e2 fix: Import fields and ModelSettings to resolve flake8 errors 2024-11-24 15:20:35 -08:00
Paul Gauthier
3f8b2d6b99 refactor: Improve model info output with detailed settings display 2024-11-24 15:20:24 -08:00
Paul Gauthier
4dcbce58ed copy 2024-11-24 14:55:02 -08:00
Paul Gauthier
0427deb897 copy 2024-11-24 14:54:19 -08:00
Paul Gauthier
f3eb3409e3 copy 2024-11-24 14:54:12 -08:00
Paul Gauthier
86619052ca copy 2024-11-24 14:52:01 -08:00
Paul Gauthier
0c59d3234e copy 2024-11-24 12:03:21 -08:00
Paul Gauthier
939d7ea3fb copy 2024-11-24 12:02:48 -08:00
Paul Gauthier
dc8761763d copy 2024-11-24 07:56:12 -08:00
Paul Gauthier
4894914db1 copy 2024-11-24 07:50:19 -08:00
Paul Gauthier
aee94a0584 copy 2024-11-24 07:14:09 -08:00
Paul Gauthier (aider)
c550422168 feat: Add x-axis label "Provider: quantization" to chart 2024-11-24 07:13:14 -08:00
Paul Gauthier (aider)
cebd9cabb3 feat: Add real-time filtering to chart based on search input 2024-11-24 07:12:39 -08:00
Paul Gauthier (aider)
3f16652d56 feat: Escape colons in model names with quotes in YAML file 2024-11-24 07:06:41 -08:00
Paul Gauthier
2ebf48ca71 feat: Update quant.yml with refined model descriptions and new test results 2024-11-24 07:06:39 -08:00
Paul Gauthier
c2f184f5bb copy 2024-11-24 06:21:58 -08:00
Paul Gauthier
e56651e5c0 copy 2024-11-23 20:27:43 -08:00
Paul Gauthier
1d09e96127 copy 2024-11-23 20:19:11 -08:00
Paul Gauthier
73de0ea8be copy 2024-11-23 20:18:19 -08:00
Paul Gauthier
757eac0579 copy 2024-11-23 18:39:20 -08:00
Paul Gauthier
bb78e2f57f default Ollama num_ctx to 8k 2024-11-23 18:14:30 -08:00
Paul Gauthier
92579243c5 copy 2024-11-23 18:13:58 -08:00
Paul Gauthier (aider)
8d0ba40d67 feat: Sort chart data by pass rate in descending order 2024-11-23 17:48:34 -08:00
Paul Gauthier
ff8c1aace9 copy 2024-11-23 15:32:09 -08:00
Paul Gauthier
cf74dc9b48 copy 2024-11-23 15:30:28 -08:00
Paul Gauthier (aider)
e63df83091 refactor: Consolidate subprocess.call mock in test_pipe_editor 2024-11-23 14:23:26 -08:00
Paul Gauthier
14522dbbcd copy 2024-11-23 14:20:58 -08:00
Paul Gauthier
91daea9e01 simplify if 2024-11-23 14:15:36 -08:00
Paul Gauthier (aider)
12b789fc4e fix: Handle Mixpanel connection errors by disabling tracking 2024-11-23 14:14:11 -08:00
Paul Gauthier
baa13351a6 refactor: Improve model registration and settings handling 2024-11-23 12:57:24 -08:00
Paul Gauthier
8f83204f0f Merge branch 'main' of github.com:Aider-AI/aider 2024-11-23 12:37:26 -08:00
paul-gauthier
80f5b60e1d Merge pull request #2440 from ivanfioravanti/main
MLX 4bit and 8bit diff added
2024-11-23 12:36:18 -08:00
Paul Gauthier
54525f6696 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-23 12:35:36 -08:00
Ivan Fioravanti
3dc50216b5 Merge branch 'Aider-AI:main' into main 2024-11-23 19:52:23 +01:00
ivanfioravanti
324430a696 quant.yml mlx-community/Qwen2.5-Coder-32B-Instruct-8bit added 2024-11-23 19:51:48 +01:00
paul-gauthier
65d7957610 Update modes.md 2024-11-23 09:36:43 -08:00
paul-gauthier
6ac4993cf2 Update modes.md 2024-11-23 09:36:26 -08:00
ivanfioravanti
100744a952 Article updated to reflect change in mlx test 2024-11-23 17:34:01 +01:00
ivanfioravanti
3a331e55dc mlx 4bit diff 2024-11-23 17:32:08 +01:00
Paul Gauthier
a57f81ba5f copy 2024-11-23 07:02:58 -08:00
Paul Gauthier
ca0b55fbbf copy 2024-11-23 06:53:54 -08:00
Paul Gauthier
38a3cf98dd gemini 2024-11-22 19:45:52 -08:00
Paul Gauthier
1234ad92e5 gemini-exp-1114 2024-11-22 19:43:26 -08:00
Paul Gauthier
488edc24ce gemini-exp-1121 2024-11-22 19:42:11 -08:00
Paul Gauthier
307c23631a copy 2024-11-22 17:20:38 -08:00
Paul Gauthier
83d2241883 copy 2024-11-22 16:40:47 -08:00
Paul Gauthier
f9126416e8 copy 2024-11-22 16:38:02 -08:00
Paul Gauthier
4e9ae16cb3 copy 2024-11-22 15:42:10 -08:00
Paul Gauthier
ef8bfdffa7 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-22 15:41:27 -08:00
paul-gauthier
bfb090331f Merge pull request #2432 from ivanfioravanti/main 2024-11-22 15:40:42 -08:00
Paul Gauthier
5506d0f25b fixed xai docs 2024-11-22 14:21:00 -08:00
Ivan Fioravanti
6ebd2d0883 mlx Qwen2.5-Coder-32B-Instruct-4bit added to quant blog
mlx Qwen2.5-Coder-32B-Instruct-4bit added to quant blog
2024-11-22 22:24:13 +01:00
Paul Gauthier
a16dcaba4e copy 2024-11-22 11:38:14 -08:00
Paul Gauthier
f06452c6c5 copy 2024-11-22 10:56:33 -08:00
Paul Gauthier (aider)
6a0a97cb41 feat: Add host.docker.internal gateway to enable Ollama server access from container 2024-11-22 10:07:47 -08:00
Paul Gauthier
711102b438 copy 2024-11-22 09:39:23 -08:00
Paul Gauthier (aider)
6d53eb0aaa style: Increase canvas height for taller graph aspect ratio 2024-11-22 07:40:46 -08:00
Paul Gauthier
0ccf04a2c5 copy 2024-11-22 07:32:25 -08:00
Paul Gauthier
070ce35b44 copy 2024-11-22 07:32:00 -08:00
Paul Gauthier
a8296e5de5 copy 2024-11-22 07:29:50 -08:00
Paul Gauthier (aider)
d17f25e975 feat: Add interactive table with quantization model performance data 2024-11-22 07:17:23 -08:00
Paul Gauthier
23095ada85 docs: Update Qwen 2.5 Coder 32B Instruct model comparison with Hyperbolic labs API 2024-11-22 07:16:01 -08:00
Paul Gauthier
f9ef161991 copy 2024-11-22 07:07:41 -08:00
Paul Gauthier
28004bae2f copy 2024-11-22 07:06:43 -08:00
Paul Gauthier
17aef7be7d copy 2024-11-22 06:09:32 -08:00
Paul Gauthier
ebba8f5110 fix ollama models included in quant blog 2024-11-22 06:01:01 -08:00
Paul Gauthier
dbd7f51f5c fix ollama models included in quant blog 2024-11-22 05:56:03 -08:00
Paul Gauthier
fbadfcfa7c refactor: Remove unnecessary input logging and history tracking in pipe_editor command 2024-11-21 18:37:51 -08:00
Paul Gauthier
2c12234604 refactor: Update input handling to set and use placeholder text 2024-11-21 18:34:24 -08:00
Paul Gauthier (aider)
13cb6a315c style: Apply linter formatting to io.py 2024-11-21 18:32:03 -08:00
Paul Gauthier (aider)
48e7376002 feat: Add placeholder functionality to input prompts 2024-11-21 18:31:57 -08:00
Paul Gauthier
60d82eddee added Qwen2 72B Instruct to over time 2024-11-21 16:49:24 -08:00
Paul Gauthier (aider)
30ee89c7e9 style: Fix linting issues in over_time.py 2024-11-21 16:45:11 -08:00
Paul Gauthier (aider)
25bcea6aec feat: Add print of model release dates and names in sorted order 2024-11-21 16:45:07 -08:00
Paul Gauthier
488c88da91 update over time graphs 2024-11-21 14:19:31 -08:00
Paul Gauthier (aider)
8fdcd92260 feat: Update plot save paths to website assets directory 2024-11-21 14:19:05 -08:00
Paul Gauthier
781a40df52 fix: Update Gemini Pro legend label to Gemini 1.5 Pro 2024-11-21 14:19:03 -08:00
Paul Gauthier
2412c81d92 copy 2024-11-21 14:09:34 -08:00
Paul Gauthier (aider)
a7fc0f9d2e feat: Add color and legend support for Gemini Pro models 2024-11-21 14:02:27 -08:00
Paul Gauthier
9eab021a50 refactor: Modify offer_url method and release notes handling in main 2024-11-21 14:02:01 -08:00
Paul Gauthier (aider)
c189a52e5e style: Organize imports and apply linter formatting 2024-11-21 14:00:24 -08:00
Paul Gauthier (aider)
6d6d763dd3 refactor: Restructure benchmark plotting script for improved maintainability 2024-11-21 14:00:20 -08:00
Paul Gauthier
3cfbaa0ed6 copy 2024-11-21 13:07:18 -08:00
Paul Gauthier
e1b4571fdf set version to 0.64.2.dev 2024-11-21 12:58:23 -08:00
Paul Gauthier
08027ea9c4 version bump to 0.64.1 2024-11-21 12:56:49 -08:00
Paul Gauthier
d0528a00c1 copy 2024-11-21 12:55:10 -08:00
Paul Gauthier
7ae6a2ba9a disable o1 streaming on openrouter 2024-11-21 12:54:23 -08:00
Paul Gauthier
ad0e5c4770 copy 2024-11-21 12:53:21 -08:00
Paul Gauthier
51b181d5fb set version to 0.64.1.dev 2024-11-21 12:37:05 -08:00
Paul Gauthier
2785b0a857 version bump to 0.64.0 2024-11-21 12:35:35 -08:00
Paul Gauthier
45a113ff9e copy 2024-11-21 12:34:12 -08:00
Paul Gauthier
cee59c2ca3 chore: Ignore .DS_Store files in exclude patterns 2024-11-21 12:32:22 -08:00
Paul Gauthier
5cb9b242e2 debug 2024-11-21 12:25:17 -08:00
Paul Gauthier
1ed48de928 wip 2024-11-21 12:22:55 -08:00
Paul Gauthier
c4e4bc71ed debug 2024-11-21 12:12:18 -08:00
Paul Gauthier
ed0763706b debug 2024-11-21 12:11:28 -08:00
Paul Gauthier
1c79d517fc refactor: Update subprocess.run with text, shell, and encoding parameters 2024-11-21 12:09:28 -08:00
Paul Gauthier
1a7a2f3088 copy 2024-11-21 11:48:29 -08:00
Paul Gauthier
4199789786 copy 2024-11-21 11:47:47 -08:00
Paul Gauthier
c9b0941d1f copy 2024-11-21 11:41:12 -08:00
Paul Gauthier (aider)
3d544136d2 style: Increase font sizes for chart labels and title 2024-11-21 11:40:02 -08:00
Paul Gauthier
8448eff1eb copy 2024-11-21 11:38:41 -08:00
Paul Gauthier (aider)
a3dde4599a refactor: Improve chart label handling by splitting model names on newline 2024-11-21 11:14:01 -08:00
Paul Gauthier
3d7440c673 refactor: Modify chart labels to include additional text 2024-11-21 11:13:48 -08:00
Paul Gauthier
8f41006eba refactor: Simplify model label processing in quant-chart.js 2024-11-21 11:11:22 -08:00
Paul Gauthier (aider)
7d1379fe9f fix: Handle line breaks in x-axis labels for chart rendering 2024-11-21 11:08:23 -08:00
Paul Gauthier (aider)
ced4f9f0d9 feat: Add chart title, y-axis label, and remove legend 2024-11-21 11:06:52 -08:00
Paul Gauthier (aider)
7fba332f58 feat: Add quantization performance chart using Chart.js and quant.yml data 2024-11-21 10:57:03 -08:00
Paul Gauthier
8eda09533d init 2024-11-21 10:55:20 -08:00
Paul Gauthier
6c42ee4edf copy 2024-11-21 10:53:28 -08:00
Paul Gauthier
3053595bfe added qwen models 2024-11-21 10:52:10 -08:00
Paul Gauthier (aider)
6cf78d1a3f feat: Implement case-insensitive search in leaderboard filtering 2024-11-21 10:41:59 -08:00
Paul Gauthier (aider)
6c0ee9d917 feat: Enhance leaderboard search to support multi-word queries 2024-11-21 10:41:35 -08:00
Paul Gauthier
50051dbfd5 copy 2024-11-21 10:34:01 -08:00
Paul Gauthier (aider)
30a8c5e12e feat: Update leaderboard charts to filter bars based on search input 2024-11-21 10:32:32 -08:00
Paul Gauthier
4498549783 refactor: Add .js file extension to blame script file filter 2024-11-21 10:31:59 -08:00
Paul Gauthier (aider)
2ce3fedbfc fix: Correct table selector for refactoring leaderboard search 2024-11-21 10:31:43 -08:00
Paul Gauthier (aider)
8e10be665c fix: Remove raw tags from leaderboard script includes 2024-11-21 10:30:41 -08:00
Paul Gauthier (aider)
80636cb8aa feat: Add raw filter to JavaScript includes in leaderboard index.md 2024-11-21 10:29:18 -08:00
Paul Gauthier (aider)
1b893da07d refactor: Move JavaScript to separate files and use Jekyll includes 2024-11-21 10:28:09 -08:00
Paul Gauthier
2f8aa3471b feat: Add leaderboard JavaScript component 2024-11-21 10:24:56 -08:00
Paul Gauthier (aider)
92a6957f0b refactor: Move refactoring search box above its table 2024-11-21 10:22:57 -08:00
Paul Gauthier (aider)
d7248b11e5 feat: Add live search functionality to leaderboard tables 2024-11-21 10:21:39 -08:00
Paul Gauthier
6f4ed00105 copy 2024-11-21 10:15:28 -08:00
Paul Gauthier (aider)
347b299bbc refactor: Enforce strict parsing of multiline input start with { or {tag} 2024-11-21 10:10:45 -08:00
Paul Gauthier (aider)
614d297f22 fix: Use strip("\r\n") for precise line ending removal 2024-11-21 10:10:14 -08:00
Paul Gauthier (aider)
59d0fe00c3 refactor: Improve multi-line input handling with strict closing tag validation 2024-11-21 10:09:36 -08:00
Paul Gauthier
d6ebdff28f copy 2024-11-21 10:07:53 -08:00
Paul Gauthier
0ec16d0eab copy 2024-11-21 10:07:01 -08:00
Paul Gauthier
3906894fde Merge branch 'main' of github.com:Aider-AI/aider 2024-11-21 10:02:06 -08:00
Paul Gauthier
a43772b21d refactor: Remove unused file_editor function from editor module 2024-11-21 10:01:08 -08:00
Paul Gauthier (aider)
cd81c2619b refactor: Remove unused file_editor import and mock in test_editor.py 2024-11-21 09:58:53 -08:00
Paul Gauthier (aider)
5abadc31a3 style: Remove extra blank lines in test_editor.py 2024-11-21 09:58:39 -08:00
Paul Gauthier (aider)
87654b698b test: Update tests for editor functionality changes 2024-11-21 09:58:35 -08:00
Paul Gauthier (aider)
2a1d2ef294 refactor: Update editor discovery to support custom editor and remove AIDER_EDITOR 2024-11-21 09:55:15 -08:00
Paul Gauthier (aider)
2a387707ef feat: Add --editor switch to specify editor for /editor command 2024-11-21 09:52:14 -08:00
paul-gauthier
ce68062290 Merge pull request #2417 from caetanominuzzo/fix-typo-in-base_coder
fix: Correct typo in base_coder by removing duplicate 'in'
2024-11-21 09:36:34 -08:00
caetanominuzzo
1b9073b085 fix: Correct typo in base_coder by removing duplicate 'in'
This corrects a grammatical error in the system prompt within `base_coder.py`. The `language` variable was previously set as:

    language = "in the same language they are using"

Which resulted in the prompt:

    "Always reply to the user IN IN the same language they are using."
2024-11-21 14:19:39 -03:00
paul-gauthier
e94961a14f Merge pull request #2414 from thehunmonkgroup/editor-doc 2024-11-21 07:37:22 -08:00
Chad Phillips
d4e77b3be4 add documentation for /editor configuration 2024-11-21 09:46:25 -05:00
Paul Gauthier
b96b36d5ea refactor: Remove unnecessary assert_newlines check for updated lines 2024-11-21 06:42:04 -08:00
Paul Gauthier
72d559a92c fix: Remove duplicate assert_newlines call on original lines 2024-11-21 06:39:39 -08:00
Paul Gauthier (aider)
9a7bdcb6db style: Fix linter warnings in test_commands.py 2024-11-21 06:36:11 -08:00
Paul Gauthier (aider)
2e4cf48e7e test: Update cmd_run test to check cur_messages instead of return value 2024-11-21 06:36:05 -08:00
Paul Gauthier
b78f8abeb4 copy 2024-11-21 06:34:08 -08:00
Paul Gauthier (aider)
7aa4e44317 fix: Correct line/lines pluralization in command output messages 2024-11-21 06:30:52 -08:00
Paul Gauthier
2619b92131 fix: Add period to output message for consistency 2024-11-21 06:30:50 -08:00
Paul Gauthier (aider)
28be59582f refactor: Simplify cmd_run to use confirm_ask and add output to cur_messages 2024-11-21 06:28:41 -08:00
Paul Gauthier
f96cc03587 feat: Add opt-in analytics and improve output logging method 2024-11-21 06:25:10 -08:00
Paul Gauthier (aider)
cbd35b0e87 feat: Implement line count for command output in chat 2024-11-21 06:23:34 -08:00
Paul Gauthier
443acbe4b5 fix: Correct command output confirmation logic in base coder 2024-11-21 06:23:32 -08:00
Paul Gauthier
1f0d26e8c7 better over time plot 2024-11-20 20:19:44 -08:00
Paul Gauthier
8302e9d0dd improved over time plot 2024-11-20 20:16:35 -08:00
Paul Gauthier (aider)
c797af020a refactor: Update fontsize to use LABEL_FONT_SIZE constant in over_time.py 2024-11-20 20:13:46 -08:00
Paul Gauthier (aider)
1c85afa320 feat: Add LABEL_FONT_SIZE constant for dot label font size 2024-11-20 20:13:33 -08:00
Paul Gauthier
eb5317f8e5 fix: Adjust annotation vertical offset for brown color in over_time plot 2024-11-20 20:13:30 -08:00
Paul Gauthier (aider)
8b860615b8 style: Increase font size for scatter plot dot labels 2024-11-20 20:10:40 -08:00
Paul Gauthier (aider)
c15ac341e2 refactor: Remove Opus and Llama model variants from legend labels 2024-11-20 20:07:52 -08:00
Paul Gauthier (aider)
c2c7ee1047 feat: Change Opus label to "Opus" in legend 2024-11-20 20:06:48 -08:00
Paul Gauthier (aider)
72c46ccec6 feat: Add labels for Claude 3 Opus, Sonnet, and O1 Preview models 2024-11-20 20:06:04 -08:00
Paul Gauthier (aider)
dd3bfaee01 style: Format code with consistent indentation and line breaks 2024-11-20 20:05:24 -08:00
Paul Gauthier (aider)
03206ad90e feat: Add line labels directly on first points instead of using legend 2024-11-20 20:05:18 -08:00
Paul Gauthier (aider)
2e00307190 feat: Add color and legend label for o1-preview models 2024-11-20 20:03:49 -08:00
Paul Gauthier (aider)
b3e29ab20e style: Apply linter formatting to benchmark code 2024-11-20 20:02:52 -08:00
Paul Gauthier (aider)
5504ac535b feat: Add simplified model names for legend labels 2024-11-20 20:02:48 -08:00
Paul Gauthier (aider)
4b3dd7f4ea style: Apply linter formatting to over_time.py 2024-11-20 19:59:43 -08:00
Paul Gauthier (aider)
8edf9540d5 feat: Add legend to plot and remove point labels 2024-11-20 19:59:38 -08:00
Paul Gauthier
1c62ecd1b5 style: Adjust x-axis label rotation angle for better readability 2024-11-20 19:59:36 -08:00
Paul Gauthier
7cf3d9f3ce style: Increase annotation font size in benchmark plot 2024-11-20 19:45:42 -08:00
Paul Gauthier
9b5a703307 updated models-over-time 2024-11-20 19:40:59 -08:00
Paul Gauthier (aider)
370993cbed style: Rotate point labels by 45 degrees in benchmark plot 2024-11-20 18:47:30 -08:00
Paul Gauthier
ddc538cdfa refactor: Adjust plot figure size and y-axis limits for better visualization 2024-11-20 18:47:28 -08:00
Paul Gauthier (aider)
062dc43c87 style: Make graph aspect ratio square 2024-11-20 18:43:18 -08:00
Paul Gauthier (aider)
7d9b986c04 feat: Add cyan color and line for Mistral models in visualization 2024-11-20 18:38:06 -08:00
Paul Gauthier
bd2b9a12ed style: Change Qwen model color from purple to darkblue 2024-11-20 18:38:04 -08:00
Paul Gauthier (aider)
2b55707738 feat: Add purple color and line for Qwen models in visualization 2024-11-20 18:35:25 -08:00
Paul Gauthier (aider)
093540507e feat: Add pink color and line for Haiku models in benchmark visualization 2024-11-20 18:33:54 -08:00
Paul Gauthier (aider)
8f1dcfda07 feat: Add brown color for DeepSeek models in benchmark visualization 2024-11-20 18:31:46 -08:00
Paul Gauthier
16b319174b refactor: Simplify model color detection logic for Sonnet models 2024-11-20 18:31:44 -08:00
Paul Gauthier (aider)
35115f5707 feat: Add orange color for Claude 3 Sonnet models in benchmark visualization 2024-11-20 18:30:09 -08:00
Paul Gauthier
e9e51db9c7 improve precision, tests 2024-11-20 18:20:18 -08:00
Paul Gauthier (aider)
ec39f018e2 test: Update test_is_uuid_in_percentage with full-length UUIDs 2024-11-20 17:58:52 -08:00
Paul Gauthier
59f4a3bcc7 test: Update UUID percentage threshold test case 2024-11-20 17:58:50 -08:00
Paul Gauthier (aider)
1a8949eea3 fix: Correct UUID percentage calculation in analytics method 2024-11-20 17:58:18 -08:00
Paul Gauthier
fa85bdceed fix: Correct sampling logic by changing <= to < in UUID comparison 2024-11-20 17:58:16 -08:00
Paul Gauthier (aider)
6b703244ec fix: Correct percentage calculation in is_uuid_in_percentage method 2024-11-20 17:56:07 -08:00
Paul Gauthier (aider)
1a1cb0d3f1 fix: Correct percentage calculation in UUID sampling method 2024-11-20 17:55:40 -08:00
Paul Gauthier (aider)
95c9863d0a style: Fix linter formatting in analytics module 2024-11-20 17:54:22 -08:00
Paul Gauthier (aider)
82187f6a71 refactor: Extract UUID percentage testing logic into a separate method with tests 2024-11-20 17:54:16 -08:00
Paul Gauthier (aider)
75f52a1324 refactor: Improve user sampling logic with configurable percentage 2024-11-20 17:52:52 -08:00
Paul Gauthier
6e076a40a9 refactor: Modify analytics sampling logic to use 1% of users 2024-11-20 17:52:50 -08:00
Paul Gauthier
ded60036cb copy 2024-11-20 17:43:51 -08:00
Paul Gauthier
539a6cde63 feat: Enhance analytics opt-in logic with user sampling and explicit control 2024-11-20 16:22:01 -08:00
Paul Gauthier
3a28e74d89 copy 2024-11-20 16:03:51 -08:00
Paul Gauthier
c93f3faed9 cleanup openrouter/qwen/qwen-2.5-coder-32b-instruct in resources 2024-11-20 15:33:00 -08:00
Paul Gauthier
1aaa3d9279 gpt-4o-2024-11-20 2024-11-20 15:31:47 -08:00
Paul Gauthier
a06a9ed7d8 show the /editor message 2024-11-20 15:31:32 -08:00
Paul Gauthier
18a88596a6 Added gpt-4o-2024-11-20 2024-11-20 11:33:16 -08:00
Paul Gauthier (aider)
2ac077603b feat: Update add_to_input_history to immediately update prompt session history 2024-11-20 08:16:55 -08:00
Paul Gauthier (aider)
3bb8b163b8 feat: Update HISTORY.md with new release notes entries 2024-11-20 08:09:53 -08:00
Paul Gauthier (aider)
aac45097ca fix: Save empty dict to cache file on download failure 2024-11-20 07:57:56 -08:00
Paul Gauthier (aider)
788956e86d refactor: Update cache TTL in ModelInfoManager even on download failure 2024-11-20 07:56:28 -08:00
Paul Gauthier
e917424f5d copy 2024-11-20 07:13:15 -08:00
Paul Gauthier
1f6a5d04d9 chore: Update edit leaderboard with new Mistral model performance data 2024-11-20 07:09:38 -08:00
Paul Gauthier (aider)
dba844c7f9 style: Format code with linter 2024-11-19 17:45:44 -08:00
Paul Gauthier (aider)
09c11ef8ad test: Add --yes flag to prevent EOFError in test cases 2024-11-19 17:45:40 -08:00
Paul Gauthier
ff21669bb5 copy 2024-11-19 17:42:34 -08:00
Paul Gauthier
a059ca2537 refactor: Improve release notes display logic and user interaction flow 2024-11-19 17:41:57 -08:00
Paul Gauthier
f4531b9434 docs: Add release notes URL and section in HISTORY.md 2024-11-19 17:38:17 -08:00
Paul Gauthier (aider)
05b350ac4b style: Fix linter formatting in main.py 2024-11-19 17:37:19 -08:00
Paul Gauthier (aider)
cfba315a85 fix: Replace utils.open_url with webbrowser.open to resolve AttributeError 2024-11-19 17:37:14 -08:00
Paul Gauthier
12188b6684 refactor: Simplify release notes display logic in main function 2024-11-19 17:37:13 -08:00
Paul Gauthier (aider)
725b2fc16f style: Apply linter formatting to main.py 2024-11-19 17:33:22 -08:00
Paul Gauthier (aider)
90a28e31e8 feat: Add --show-release-notes option to control release notes display 2024-11-19 17:33:16 -08:00
Paul Gauthier
c057b00e08 refactor: Move release notes offer after announcements in main function 2024-11-19 17:33:13 -08:00
Paul Gauthier (aider)
b0c0104ba3 feat: Implement release notes URL offer on first run 2024-11-19 17:30:30 -08:00
Paul Gauthier
855b184e91 feat: Add TODO for displaying release notes on first run 2024-11-19 17:30:29 -08:00
Paul Gauthier (aider)
bc88242dc0 refactor: Move version check to main and pass to check_and_load_imports 2024-11-19 17:27:02 -08:00
Paul Gauthier (aider)
6357cd623f style: Apply linter formatting to main.py 2024-11-19 17:25:02 -08:00
Paul Gauthier (aider)
d3e7d20e30 refactor: Extract version checking logic into separate function 2024-11-19 17:24:57 -08:00
Paul Gauthier
7b568c2df3 copy 2024-11-19 17:22:08 -08:00
Paul Gauthier
2bff0522e8 refactor: Restructure file mention check and interrupt handling in base coder 2024-11-19 16:37:02 -08:00
Paul Gauthier (aider)
77e180171c style: Break long comment into two lines for flake8 compliance 2024-11-19 14:48:22 -08:00
Paul Gauthier (aider)
1e8fc97ba4 style: Apply linter formatting to test_models.py 2024-11-19 14:48:11 -08:00
Paul Gauthier (aider)
a799851832 fix: Resolve temporary file permission issues in test_models.py 2024-11-19 14:48:06 -08:00
Paul Gauthier
2c81105bfc copy 2024-11-19 14:33:21 -08:00
Paul Gauthier
bf99ac56a0 copy 2024-11-19 12:45:56 -08:00
Paul Gauthier
8bfb47948a copy 2024-11-19 12:45:00 -08:00
Paul Gauthier (aider)
b8c41198a3 docs: Add documentation links to v0.63.3 release notes 2024-11-19 12:43:17 -08:00
Paul Gauthier (aider)
fe138ac05b feat: Update HISTORY.md with v0.63.3 release details 2024-11-19 12:42:44 -08:00
Paul Gauthier
bed62fdcb5 chore: Update HISTORY.md for Aider v0.63.2 release 2024-11-19 12:42:41 -08:00
Paul Gauthier
f068df0297 copy 2024-11-19 12:40:09 -08:00
Paul Gauthier
6a05e34d20 copy 2024-11-19 12:37:16 -08:00
Paul Gauthier (aider)
8b69b9c6a4 docs: Add documentation for new multiline tag input method 2024-11-19 12:36:55 -08:00
Paul Gauthier (aider)
10192296fe style: Format code with linter 2024-11-19 12:34:47 -08:00
Paul Gauthier (aider)
7b98db2f7d fix: Escape f-string brace in multiline input tag handling 2024-11-19 12:34:43 -08:00
Paul Gauthier (aider)
81696c2e7a feat: Add support for optional multiline input tags with matching closing tag 2024-11-19 12:34:25 -08:00
Paul Gauthier
16a4f823bd refactor: Move pipe_editor import and return user input in cmd_editor method 2024-11-19 12:30:41 -08:00
Paul Gauthier
39bbfc56a4 copy 2024-11-19 12:30:30 -08:00
Paul Gauthier (aider)
308c49b2d8 fix: Modify discover_editor to dynamically check platform system 2024-11-19 12:26:37 -08:00
Paul Gauthier (aider)
53e46a9251 refactor: Remove unused platform import from test_editor.py 2024-11-19 12:26:06 -08:00
Paul Gauthier (aider)
6075b3dc33 style: Reorder imports and add whitespace in test_editor.py 2024-11-19 12:25:50 -08:00
Paul Gauthier (aider)
860a828973 test: Add comprehensive tests for editor module functionality 2024-11-19 12:25:46 -08:00
Paul Gauthier
033eaa36c6 test: Add test_editor.py for basic editor functionality 2024-11-19 12:25:44 -08:00
Paul Gauthier
b3566f5449 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-19 12:23:12 -08:00
paul-gauthier
f1306d3301 Merge pull request #2234 from thehunmonkgroup/main
add /editor command
2024-11-19 12:22:37 -08:00
Paul Gauthier
cc18441435 refactor: Update model settings name from "aider/extra" to "aider/extra_params" 2024-11-19 12:15:11 -08:00
Paul Gauthier (aider)
7e787d93e6 docs: Add documentation for aider/extra_params pseudo-model settings 2024-11-19 12:10:28 -08:00
Paul Gauthier
b08f444e74 docs: Remove default and override settings section from documentation 2024-11-19 12:10:26 -08:00
Paul Gauthier (aider)
09c1acdbe2 fix: Update model settings override name to match test configuration 2024-11-19 12:07:42 -08:00
Paul Gauthier (aider)
7a4a956eff fix: Remove unexpected skip_name argument in _copy_fields() method 2024-11-19 12:07:08 -08:00
Paul Gauthier (aider)
aabbf5a72f refactor: Remove unused import and add ANTHROPIC_BETA_HEADER import 2024-11-19 12:06:29 -08:00
Paul Gauthier (aider)
5ed44bb174 style: Format test_models.py with consistent whitespace and trailing commas 2024-11-19 12:06:19 -08:00
Paul Gauthier (aider)
92cf2cbd47 test: Implement TODOs in test_aider_extra_model_settings 2024-11-19 12:06:15 -08:00
Paul Gauthier
34aff6c786 test: Update model settings test to check extra parameters 2024-11-19 12:06:13 -08:00
Paul Gauthier (aider)
11f10e586a fix: Remove unused functools.wraps import 2024-11-19 12:03:14 -08:00
Paul Gauthier (aider)
a31feae2bd style: Apply linter formatting to models.py 2024-11-19 12:02:49 -08:00
Paul Gauthier (aider)
3517d58f01 feat: Implement deep merge for extra model settings with nested dict support 2024-11-19 12:02:44 -08:00
Paul Gauthier
9d13fadd41 refactor: Simplify model settings configuration and remove tracking decorator 2024-11-19 12:02:42 -08:00
Paul Gauthier (aider)
c1febce528 fix: Remove unused imports and add missing register_models import 2024-11-19 11:50:12 -08:00
Paul Gauthier (aider)
e0aadbd961 style: Format code with linter and improve readability 2024-11-19 11:50:01 -08:00
Paul Gauthier (aider)
7b9a76c5ea refactor: Use temporary YAML file for model settings in test_default_and_override_settings 2024-11-19 11:49:57 -08:00
Paul Gauthier
6133fa8384 test: Update test cases with new edit_format value 2024-11-19 11:49:55 -08:00
Paul Gauthier (aider)
67cc215ed3 style: Apply linter formatting to models.py 2024-11-19 11:45:37 -08:00
Paul Gauthier (aider)
ea4ad2ea4d feat: Add track_init_fields decorator to track explicitly set fields in ModelSettings 2024-11-19 11:45:32 -08:00
Paul Gauthier
847454a4f7 fix: Remove debug dump statement in ModelSettings initialization 2024-11-19 11:45:31 -08:00
Paul Gauthier (aider)
8cba1fdd71 feat: Track and copy only explicitly set fields in ModelSettings 2024-11-19 10:11:44 -08:00
Paul Gauthier
e56112739c refactor: Add debug dump calls for edit_format in Model initialization 2024-11-19 10:11:42 -08:00
Paul Gauthier (aider)
76988b746f refactor: Remove unused call import and rename loop variable 2024-11-19 10:05:01 -08:00
Paul Gauthier (aider)
32eb365a0b style: Reorder imports in test_models.py 2024-11-19 10:04:45 -08:00
Paul Gauthier (aider)
2c5feddad5 test: Add imports for ModelSettings and MODEL_SETTINGS 2024-11-19 10:04:41 -08:00
Paul Gauthier (aider)
210500ff3e style: Apply linter formatting to test_models.py 2024-11-19 10:04:23 -08:00
Paul Gauthier (aider)
7c8f10e832 test: Add tests for default and override model settings 2024-11-19 10:04:19 -08:00
Paul Gauthier (aider)
644da2f9e4 docs: Add documentation for aider/default and aider/override model settings 2024-11-19 10:03:26 -08:00
Paul Gauthier (aider)
2a80d9c555 feat: Apply generic model settings when no exact model match found 2024-11-19 10:02:25 -08:00
Paul Gauthier
76f8791f3c refactor: Restructure model settings application with early returns and simplified logic 2024-11-19 10:02:24 -08:00
Paul Gauthier (aider)
c51a013109 refactor: Extract field copying logic into reusable _copy_fields method 2024-11-19 10:00:23 -08:00
Paul Gauthier (aider)
88c2f95ea5 style: Format code with linter 2024-11-19 09:59:27 -08:00
Paul Gauthier (aider)
062fa7de78 refactor: Enhance model settings configuration with default and override handling 2024-11-19 09:59:22 -08:00
Paul Gauthier
d6c1a41e8d feat: Add Timeout exception to handle API provider timeouts 2024-11-19 09:27:16 -08:00
Paul Gauthier
20ab5f9326 copy 2024-11-19 06:52:15 -08:00
Paul Gauthier
ab5a8b24a5 updated blame 2024-11-18 13:56:46 -08:00
Paul Gauthier (aider)
21a28623ca feat: Explicitly include specific markdown files in blame script 2024-11-18 13:46:43 -08:00
Paul Gauthier (aider)
06a5fec612 feat: Include .md files from aider/website/share/ in blame statistics 2024-11-18 13:45:50 -08:00
Paul Gauthier (aider)
46ecb8a663 feat: Enhance share page security with markdown sanitization and error handling 2024-11-18 13:40:15 -08:00
Paul Gauthier (aider)
3c9c6eef6e feat: Add URL validation and Content Security Policy to share page 2024-11-18 13:37:02 -08:00
Paul Gauthier
72734de376 copy 2024-11-18 13:28:47 -08:00
Paul Gauthier
a20ea09a6e refactor: Remove redundant streaming=False from model settings 2024-11-18 13:28:14 -08:00
Paul Gauthier (aider)
4bd7bce232 docs: Add example of using .aiderignore to focus on specific directories in monorepo 2024-11-18 13:22:55 -08:00
Paul Gauthier
8adf42216d copy 2024-11-18 07:47:30 -08:00
Paul Gauthier (aider)
5f40aaabb5 style: Lint and clean up code formatting in issues.py script 2024-11-18 07:46:28 -08:00
Paul Gauthier (aider)
5295abbb83 style: Move #noqa comments to triple-quoted strings in issues.py 2024-11-18 07:46:23 -08:00
Paul Gauthier
201abe1524 refactor: Improve code formatting and add noqa comment in issues.py script 2024-11-18 07:46:00 -08:00
Paul Gauthier (aider)
6d26051d11 style: Reformat long string literals using parentheses 2024-11-18 07:44:54 -08:00
Paul Gauthier (aider)
4613bf78d5 feat: Add BOT_SUFFIX to issue comment templates 2024-11-18 07:44:50 -08:00
Paul Gauthier
1f8fdc6f5c refactor: Update issue script comments and add bot suffix 2024-11-18 07:44:48 -08:00
Paul Gauthier
abf804cf10 set version to 0.63.3.dev 2024-11-18 07:30:21 -08:00
Paul Gauthier
d7a195706f version bump to 0.63.2 2024-11-18 07:29:05 -08:00
Paul Gauthier
569370109a copy 2024-11-18 07:11:46 -08:00
Paul Gauthier
eae3f04c83 copy 2024-11-18 06:57:35 -08:00
Paul Gauthier (aider)
ee0987f331 feat: Update HISTORY.md with recent changes since v0.63.1 2024-11-18 06:57:04 -08:00
Paul Gauthier (aider)
bdafa842bd fix: Add missing time import for time.sleep() in write_text method 2024-11-15 16:23:37 -08:00
Paul Gauthier (aider)
76c7c2562c style: Format code with linter for improved readability 2024-11-15 16:23:26 -08:00
Paul Gauthier (aider)
f7de2234f2 fix: Handle different OSError types in write_text method 2024-11-15 16:23:21 -08:00
Paul Gauthier
c725c45726 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-15 16:22:23 -08:00
paul-gauthier
383bef456d Merge pull request #2381 from mark-asymbl/write_text_file_lock_fix
Added io.py write_text exponential backoff to gracefully handle transient file locks
2024-11-15 16:21:40 -08:00
mw
7f48f3d01d Added write_text exponential backoff to
Discord thread ID: 1306776889762906123

Resolve issue where Aider fails to write multiple, consecutive changes to a single file due to Visual Studio briefly locking a file for writing after it was edited. Presumably VS is doing some sort of processing, such as for IntelliSense, behind the scenes. This solution is applicable to other, similar editor/IDE behaviors.
2024-11-15 15:04:25 -08:00
Paul Gauthier
0bf17a48f7 copy 2024-11-15 07:42:17 -08:00
Paul Gauthier (aider)
c127f8f2f0 chore: Update HISTORY.md with v0.63.1 and v0.63.2 release notes 2024-11-15 07:37:14 -08:00
Paul Gauthier
d4d5d15e18 fix: Handle missing litellm_provider in fuzzy model matching 2024-11-15 06:14:15 -08:00
Paul Gauthier
b254afa498 refactor: Modify model metadata file loading to prioritize resource file 2024-11-15 05:33:59 -08:00
Paul Gauthier
0ce5a94c15 bumped deps 2024-11-15 05:29:29 -08:00
Paul Gauthier
38a5405c65 copy 2024-11-14 15:30:49 -08:00
Paul Gauthier
ecef784686 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-14 15:27:51 -08:00
Paul Gauthier
e82b2c12b4 cleanup 2024-11-14 15:27:40 -08:00
Paul Gauthier (aider)
3c26ced8db style: Apply linter formatting to main.py 2024-11-14 15:18:54 -08:00
Paul Gauthier (aider)
2681a41abb refactor: Expand read-only file paths to include all files in directories 2024-11-14 15:18:47 -08:00
Paul Gauthier
805deb1002 feat: Add comment to expand read-only directory files 2024-11-14 15:18:45 -08:00
Paul Gauthier
6b792de802 copy 2024-11-14 15:15:23 -08:00
paul-gauthier
26f8e34dcb Merge pull request #2369 from josx/fix_contrib_pytest_filename 2024-11-14 07:33:53 -08:00
José Luis Di Biase
e0c1b2458c fix: typo pytest filename 2024-11-14 12:27:12 -03:00
Paul Gauthier
66f94d2141 set version to 0.63.2.dev 2024-11-14 06:56:43 -08:00
Paul Gauthier
503a9a0038 version bump to 0.63.1 2024-11-14 06:55:05 -08:00
Paul Gauthier
d8a5bc3ae9 Revert "Merge branch 'issue2283'"
This reverts commit e1a1e43c3a, reversing
changes made to c538817b61.
2024-11-14 06:53:21 -08:00
Paul Gauthier (aider)
94c3957d92 fix: Add error handling for git.ignored() method 2024-11-14 06:48:35 -08:00
Paul Gauthier
266350b8ce fix: Handle potential git errors in git_ignored_file method 2024-11-14 06:48:33 -08:00
Paul Gauthier (aider)
721d852cc7 feat: Add vertical spacing div to improve FAQ anchor link behavior 2024-11-13 16:23:50 -08:00
Paul Gauthier
ffbf205aba docs: Add explanation for aider code stats computation 2024-11-13 16:20:07 -08:00
Paul Gauthier
e1a1e43c3a Merge branch 'issue2283' 2024-11-13 13:43:30 -08:00
Paul Gauthier
c538817b61 updated blame 2024-11-13 13:43:05 -08:00
Paul Gauthier
71d85d2771 fix: Update Qwen 2.5 Coder 32b model configuration condition 2024-11-13 13:40:35 -08:00
Paul Gauthier
fef1b59b42 refactor: Restructure file mention check and interrupt handling in base coder 2024-11-13 12:50:17 -08:00
Chad Phillips
8801fda972 formatting fixes 2024-11-04 10:10:37 -06:00
malkoG
a8a3e2401b Update languages.md for dart support 2024-11-04 13:22:22 +09:00
malkoG
a7f59a2e2b Add tags.scm for dart 2024-11-04 12:38:27 +09:00
Chad Phillips
d8e9da35d6 add /editor command
Opens an editor for constructing a user prompt, using the currently defined chat mode.

The editor is determined as follows:

Look for the following environment variables, in order:

1. AIDER_EDITOR
2. VISUAL
3. EDITOR

If none of these are defined, use the following defaults:

Windows: notepad
OS X: vim
*nix: vi

If an editor is not found, a RuntimeError is raised.

Any arguments passed after the /editor command are inserted as content.

The temporary file used for editing has an .md extension, which can be leveraged for syntax highlighting.

NOTE: The editor used MUST block the process until the editor is closed -- the default editors all do this.
2024-11-03 20:18:57 -05:00
78 changed files with 5031 additions and 2661 deletions

3
.gitignore vendored
View File

@@ -11,4 +11,5 @@ _site
.jekyll-cache/
.jekyll-metadata
aider/__version__.py
.venv/
.venv/
.gitattributes

View File

@@ -187,8 +187,8 @@ pytest
You can also run specific test files or test cases by providing the file path or test name:
```
pytest aider/tests/test_coder.py
pytest aider/tests/test_coder.py::TestCoder::test_specific_case
pytest tests/basic/test_coder.py
pytest tests/basic/test_coder.py::TestCoder::test_specific_case
```
#### Continuous Integration

View File

@@ -1,6 +1,54 @@
# Release history
### main branch
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
- Added `--[no-]detect-urls` flag to disable detecting and offering to scrape URLs found in the chat.
- Ollama models now default to an 8k context window.
- Added [RepoMap support for Dart language](https://aider.chat/docs/languages.html) by @malkoG.
- Ask 2.5% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
- Skip suggesting files that share names with files already in chat.
- `/editor` returns and prefill the file content into the prompt, so you can use `/editor` to compose messages that start with `/commands`, etc.
- Enhanced error handling for analytics.
- Improved handling of UnknownEditFormat exceptions with helpful documentation links.
- Bumped dependencies to pick up grep-ast 0.4.0 for Dart language support.
- Aider wrote 81% of the code in this release.
### Aider v0.64.1
- Disable streaming for o1 on OpenRouter.
### Aider v0.64.0
- Added [`/editor` command](https://aider.chat/docs/usage/commands.html) to open system editor for writing prompts, by @thehunmonkgroup.
- Full support for `gpt-4o-2024-11-20`.
- Stream o1 models by default.
- `/run` and suggested shell commands are less mysterious and now confirm that they "Added XX lines of output to the chat."
- Ask 1% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
- Added support for [optional multiline input tags](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) with matching closing tags.
- Improved [model settings configuration](https://aider.chat/docs/config/adv-model-settings.html#global-extra-params) with support for global `extra_params` for `litellm.completion()`.
- Architect mode now asks to add files suggested by the LLM.
- Fixed bug in fuzzy model name matching.
- Added Timeout exception to handle API provider timeouts.
- Added `--show-release-notes` to control release notes display on first run of new version.
- Save empty dict to cache file on model metadata download failure, to delay retry.
- Improved error handling and code formatting.
- Aider wrote 74% of the code in this release.
### Aider v0.63.2
- Fixed bug in fuzzy model name matching when litellm provider info is missing.
- Modified model metadata file loading to allow override of resource file.
- Allow recursive loading of dirs using `--read`.
- Updated dependency versions to pick up litellm fix for ollama models.
- Added exponential backoff retry when writing files to handle editor file locks.
- Updated Qwen 2.5 Coder 32B model configuration.
### Aider v0.63.1
- Fixed bug in git ignored file handling.
- Improved error handling for git operations.
### Aider v0.63.0
- Support for Qwen 2.5 Coder 32B.

View File

@@ -1,6 +1,6 @@
try:
from aider.__version__ import __version__
except Exception:
__version__ = "0.63.1.dev"
__version__ = "0.65.1.dev"
__all__ = [__version__]

View File

@@ -5,7 +5,7 @@ import time
import uuid
from pathlib import Path
from mixpanel import Mixpanel
from mixpanel import Mixpanel, MixpanelException
from posthog import Posthog
from aider import __version__
@@ -62,8 +62,47 @@ class Analytics:
self.permanently_disable = True
self.save_data()
def need_to_ask(self):
return not self.asked_opt_in and not self.permanently_disable
def need_to_ask(self, args_analytics):
if args_analytics is False:
return False
could_ask = not self.asked_opt_in and not self.permanently_disable
if not could_ask:
return False
if args_analytics is True:
return True
assert args_analytics is None, args_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
def get_data_file_path(self):
data_file = Path.home() / ".aider" / "analytics.json"
@@ -120,7 +159,7 @@ class Analytics:
return None
def event(self, event_name, main_model=None, **kwargs):
if not (self.mp or self.ph) and not self.logfile:
if not self.mp and not self.ph and not self.logfile:
return
properties = {}
@@ -143,7 +182,10 @@ class Analytics:
properties["aider_version"] = __version__
if self.mp:
self.mp.track(self.user_id, event_name, dict(properties))
try:
self.mp.track(self.user_id, event_name, dict(properties))
except MixpanelException:
self.mp = None # Disable mixpanel on connection errors
if self.ph:
self.ph.capture(self.user_id, event_name, dict(properties))

View File

@@ -193,6 +193,12 @@ def get_parser(default_config_files, git_root):
default=".aider.model.metadata.json",
help="Specify a file with context window and costs for unknown models",
)
group.add_argument(
"--alias",
action="append",
metavar="ALIAS:MODEL",
help="Add a model alias (can be used multiple times)",
)
group.add_argument(
"--verify-ssl",
action=argparse.BooleanOptionalAction,
@@ -562,8 +568,8 @@ def get_parser(default_config_files, git_root):
group.add_argument(
"--analytics",
action=argparse.BooleanOptionalAction,
default=False,
help="Enable/disable analytics for one session (default: False)",
default=None,
help="Enable/disable analytics for current session (default: random)",
)
group.add_argument(
"--analytics-log",
@@ -620,6 +626,12 @@ def get_parser(default_config_files, git_root):
help="Check for new aider versions on launch",
default=True,
)
group.add_argument(
"--show-release-notes",
action=argparse.BooleanOptionalAction,
help="Show release notes on first run of new version (default: None, ask user)",
default=None,
)
group.add_argument(
"--install-main-branch",
action="store_true",
@@ -732,6 +744,16 @@ def get_parser(default_config_files, git_root):
default=True,
help="Enable/disable fancy input with history and completion (default: True)",
)
group.add_argument(
"--detect-urls",
action=argparse.BooleanOptionalAction,
default=True,
help="Enable/disable detection and offering to add URLs to chat (default: True)",
)
group.add_argument(
"--editor",
help="Specify which editor to use for the /editor command",
)
##########
group = parser.add_argument_group("Voice Settings")

View File

@@ -37,6 +37,15 @@ from ..dump import dump # noqa: F401
from .chat_chunks import ChatChunks
class UnknownEditFormat(ValueError):
def __init__(self, edit_format, valid_formats):
self.edit_format = edit_format
self.valid_formats = valid_formats
super().__init__(
f"Unknown edit format {edit_format}. Valid formats are: {', '.join(valid_formats)}"
)
class MissingAPIKeyError(ValueError):
pass
@@ -91,6 +100,7 @@ class Coder:
cache_warming_thread = None
num_cache_warming_pings = 0
suggest_shell_commands = True
detect_urls = True
ignore_mentions = None
chat_language = None
@@ -156,7 +166,12 @@ class Coder:
res.original_kwargs = dict(kwargs)
return res
raise ValueError(f"Unknown edit format {edit_format}")
valid_formats = [
str(c.edit_format)
for c in coders.__all__
if hasattr(c, "edit_format") and c.edit_format is not None
]
raise UnknownEditFormat(edit_format, valid_formats)
def clone(self, **kwargs):
new_coder = Coder.create(from_coder=self, **kwargs)
@@ -267,6 +282,7 @@ class Coder:
num_cache_warming_pings=0,
suggest_shell_commands=True,
chat_language=None,
detect_urls=True,
):
# Fill in a dummy Analytics if needed, but it is never .enable()'d
self.analytics = analytics if analytics is not None else Analytics()
@@ -280,6 +296,7 @@ class Coder:
self.ignore_mentions = set()
self.suggest_shell_commands = suggest_shell_commands
self.detect_urls = detect_urls
self.num_cache_warming_pings = num_cache_warming_pings
@@ -812,6 +829,9 @@ class Coder:
def check_for_urls(self, inp: str) -> List[str]:
"""Check input for URLs and offer to add them to the chat."""
if not self.detect_urls:
return []
url_pattern = re.compile(r"(https?://[^\s/$.?#].[^\s]*[^\s,.])")
urls = list(set(url_pattern.findall(inp))) # Use set to remove duplicates
added_urls = []
@@ -962,7 +982,7 @@ class Coder:
if self.chat_language:
language = self.chat_language
else:
language = "in the same language they are using"
language = "the same language they are using"
prompt = prompt.format(
fence=self.fence,
@@ -1059,7 +1079,7 @@ class Coder:
max_input_tokens = self.main_model.info.get("max_input_tokens") or 0
# Add the reminder prompt if we still have room to include it.
if (
max_input_tokens is None
not max_input_tokens
or total_tokens < max_input_tokens
and self.gpt_prompts.system_reminder
):
@@ -1245,10 +1265,19 @@ class Coder:
else:
content = ""
try:
self.reply_completed()
except KeyboardInterrupt:
interrupted = True
if not interrupted:
add_rel_files_message = self.check_for_file_mentions(content)
if add_rel_files_message:
if self.reflected_message:
self.reflected_message += "\n\n" + add_rel_files_message
else:
self.reflected_message = add_rel_files_message
return
try:
self.reply_completed()
except KeyboardInterrupt:
interrupted = True
if interrupted:
content += "\n^C KeyboardInterrupt"
@@ -1299,13 +1328,6 @@ class Coder:
self.update_cur_messages()
return
add_rel_files_message = self.check_for_file_mentions(content)
if add_rel_files_message:
if self.reflected_message:
self.reflected_message += "\n\n" + add_rel_files_message
else:
self.reflected_message = add_rel_files_message
def reply_completed(self):
pass
@@ -1403,9 +1425,18 @@ class Coder:
addable_rel_fnames = self.get_addable_relative_files()
# Get basenames of files already in chat or read-only
existing_basenames = {os.path.basename(f) for f in self.get_inchat_relative_files()} | {
os.path.basename(self.get_rel_fname(f)) for f in self.abs_read_only_fnames
}
mentioned_rel_fnames = set()
fname_to_rel_fnames = {}
for rel_fname in addable_rel_fnames:
# Skip files that share a basename with files already in chat
if os.path.basename(rel_fname) in existing_basenames:
continue
normalized_rel_fname = rel_fname.replace("\\", "/")
normalized_words = set(word.replace("\\", "/") for word in words)
if normalized_rel_fname in normalized_words:
@@ -2059,9 +2090,10 @@ class Coder:
if output:
accumulated_output += f"Output from {command}\n{output}\n"
if accumulated_output.strip() and not self.io.confirm_ask(
if accumulated_output.strip() and self.io.confirm_ask(
"Add command output to the chat?", allow_never=True
):
accumulated_output = ""
return accumulated_output
num_lines = len(accumulated_output.strip().splitlines())
line_plural = "line" if num_lines == 1 else "lines"
self.io.tool_output(f"Added {num_lines} {line_plural} of output to the chat.")
return accumulated_output

View File

@@ -14,6 +14,7 @@ from prompt_toolkit.completion import Completion, PathCompleter
from prompt_toolkit.document import Document
from aider import models, prompts, voice
from aider.editor import pipe_editor
from aider.format_settings import format_settings
from aider.help import Help, install_help_extra
from aider.llm import litellm
@@ -45,7 +46,15 @@ class Commands:
)
def __init__(
self, io, coder, voice_language=None, verify_ssl=True, args=None, parser=None, verbose=False
self,
io,
coder,
voice_language=None,
verify_ssl=True,
args=None,
parser=None,
verbose=False,
editor=None,
):
self.io = io
self.coder = coder
@@ -60,6 +69,7 @@ class Commands:
self.voice_language = voice_language
self.help = None
self.editor = editor
def cmd_model(self, args):
"Switch to a new LLM"
@@ -868,7 +878,6 @@ class Commands:
exit_status, combined_output = run_cmd(
args, verbose=self.verbose, error_print=self.io.tool_error
)
instructions = None
if combined_output is None:
return
@@ -876,36 +885,22 @@ class Commands:
if add_on_nonzero_exit:
add = exit_status != 0
else:
self.io.tool_output()
response = self.io.prompt_ask(
"Add the output to the chat?\n(Y)es/(n)o/message with instructions:",
).strip()
self.io.tool_output()
if response.lower() in ["yes", "y"]:
add = True
elif response.lower() in ["no", "n"]:
add = False
else:
add = True
instructions = response
if response.strip():
self.io.user_input(response, log_only=True)
self.io.add_to_input_history(response)
add = self.io.confirm_ask("Add command output to the chat?")
if add:
for line in combined_output.splitlines():
self.io.tool_output(line, log_only=True)
num_lines = len(combined_output.strip().splitlines())
line_plural = "line" if num_lines == 1 else "lines"
self.io.tool_output(f"Added {num_lines} {line_plural} of output to the chat.")
msg = prompts.run_output.format(
command=args,
output=combined_output,
)
if instructions:
msg = instructions + "\n\n" + msg
return msg
self.coder.cur_messages += [
dict(role="user", content=msg),
dict(role="assistant", content="Ok."),
]
def cmd_exit(self, args):
"Exit the application"
@@ -1366,6 +1361,13 @@ class Commands:
report_github_issue(issue_text, title=title, confirm=False)
def cmd_editor(self, initial_content=""):
"Open an editor to write a prompt"
user_input = pipe_editor(initial_content, suffix="md", editor=self.editor)
if user_input.strip():
self.io.set_placeholder(user_input.rstrip())
def expand_subdir(file_path):
if file_path.is_file():

View File

@@ -50,7 +50,6 @@ def diff_partial_update(lines_orig, lines_updated, final=False, fname=None):
# dump(lines_orig)
# dump(lines_updated)
assert_newlines(lines_orig)
assert_newlines(lines_orig)
num_orig_lines = len(lines_orig)

146
aider/editor.py Normal file
View File

@@ -0,0 +1,146 @@
"""
Editor module for handling system text editor interactions.
This module provides functionality to:
- Discover and launch the system's configured text editor
- Create and manage temporary files for editing
- Handle editor preferences from environment variables
- Support cross-platform editor operations
"""
import os
import platform
import shlex
import subprocess
import tempfile
from rich.console import Console
DEFAULT_EDITOR_NIX = "vi"
DEFAULT_EDITOR_OS_X = "vim"
DEFAULT_EDITOR_WINDOWS = "notepad"
console = Console()
def print_status_message(success, message, style=None):
"""
Print a status message with appropriate styling.
:param success: Whether the operation was successful
:param message: The message to display
:param style: Optional style override. If None, uses green for success and red for failure
"""
if style is None:
style = "bold green" if success else "bold red"
console.print(message, style=style)
print("")
def write_temp_file(
input_data="",
suffix=None,
prefix=None,
dir=None,
):
"""
Create a temporary file with the given input data.
:param input_data: Content to write to the temporary file
:param suffix: Optional file extension (without the dot)
:param prefix: Optional prefix for the temporary filename
:param dir: Optional directory to create the file in
:return: Path to the created temporary file
:raises: OSError if file creation or writing fails
"""
kwargs = {"prefix": prefix, "dir": dir}
if suffix:
kwargs["suffix"] = f".{suffix}"
fd, filepath = tempfile.mkstemp(**kwargs)
try:
with os.fdopen(fd, "w") as f:
f.write(input_data)
except Exception:
os.close(fd)
raise
return filepath
def get_environment_editor(default=None):
"""
Fetches the preferred editor from the environment variables.
This function checks the following environment variables in order to
determine the user's preferred editor:
- VISUAL
- EDITOR
:param default: The default editor to return if no environment variable is set.
:type default: str or None
:return: The preferred editor as specified by environment variables or the default value.
:rtype: str or None
"""
editor = os.environ.get("VISUAL", os.environ.get("EDITOR", default))
return editor
def discover_editor(editor_override=None):
"""
Discovers and returns the appropriate editor command as a list of arguments.
Handles cases where the editor command includes arguments, including quoted arguments
with spaces (e.g. 'vim -c "set noswapfile"').
:return: A list of command parts ready for subprocess execution
:rtype: list[str]
"""
system = platform.system()
if system == "Windows":
default_editor = DEFAULT_EDITOR_WINDOWS
elif system == "Darwin":
default_editor = DEFAULT_EDITOR_OS_X
else:
default_editor = DEFAULT_EDITOR_NIX
if editor_override:
editor = editor_override
else:
editor = get_environment_editor(default_editor)
try:
return shlex.split(editor)
except ValueError as e:
raise RuntimeError(f"Invalid editor command format '{editor}': {e}")
def pipe_editor(input_data="", suffix=None, editor=None):
"""
Opens the system editor with optional input data and returns the edited content.
This function creates a temporary file with the provided input data, opens it in
the system editor, waits for the user to make changes and close the editor, then
reads and returns the modified content. The temporary file is deleted afterwards.
:param input_data: Initial content to populate the editor with
:type input_data: str
:param suffix: Optional file extension for the temporary file (e.g. '.txt', '.md')
:type suffix: str or None
:return: The edited content after the editor is closed
:rtype: str
"""
filepath = write_temp_file(input_data, suffix)
command_parts = discover_editor(editor)
command_parts.append(filepath)
subprocess.call(command_parts)
with open(filepath, "r") as f:
output_data = f.read()
try:
os.remove(filepath)
except PermissionError:
print_status_message(
False,
(
f"WARNING: Unable to delete temporary file {filepath!r}. You may need to delete it"
" manually."
),
)
return output_data

View File

@@ -40,6 +40,11 @@ EXCEPTIONS = [
ExInfo("ServiceUnavailableError", True, "The API provider's servers are down or overloaded."),
ExInfo("UnprocessableEntityError", True, None),
ExInfo("UnsupportedParamsError", True, None),
ExInfo(
"Timeout",
True,
"The API provider timed out without returning a response. They may be down or overloaded.",
),
]

View File

@@ -7,4 +7,5 @@ exclude_website_pats = [
"docs/unified-diffs.md",
"docs/leaderboards/index.md",
"assets/**",
"**/.DS_Store",
]

View File

@@ -1,5 +1,6 @@
import base64
import os
import time
import webbrowser
from collections import defaultdict
from dataclasses import dataclass
@@ -197,6 +198,7 @@ class InputOutput:
editingmode=EditingMode.EMACS,
fancy_input=True,
):
self.placeholder = None
self.never_prompts = set()
self.editingmode = editingmode
no_color = os.environ.get("NO_COLOR")
@@ -333,14 +335,36 @@ class InputOutput:
self.tool_error("Use --encoding to set the unicode encoding.")
return
def write_text(self, filename, content):
def write_text(self, filename, content, max_retries=5, initial_delay=0.1):
"""
Writes content to a file, retrying with progressive backoff if the file is locked.
:param filename: Path to the file to write.
:param content: Content to write to the file.
:param max_retries: Maximum number of retries if a file lock is encountered.
:param initial_delay: Initial delay (in seconds) before the first retry.
"""
if self.dry_run:
return
try:
with open(str(filename), "w", encoding=self.encoding) as f:
f.write(content)
except OSError as err:
self.tool_error(f"Unable to write file {filename}: {err}")
delay = initial_delay
for attempt in range(max_retries):
try:
with open(str(filename), "w", encoding=self.encoding) as f:
f.write(content)
return # Successfully wrote the file
except PermissionError as err:
if attempt < max_retries - 1:
time.sleep(delay)
delay *= 2 # Exponential backoff
else:
self.tool_error(
f"Unable to write file {filename} after {max_retries} attempts: {err}"
)
raise
except OSError as err:
self.tool_error(f"Unable to write file {filename}: {err}")
raise
def rule(self):
if self.pretty:
@@ -404,8 +428,13 @@ class InputOutput:
try:
if self.prompt_session:
# Use placeholder if set, then clear it
default = self.placeholder or ""
self.placeholder = None
line = self.prompt_session.prompt(
show,
default=default,
completer=completer_instance,
reserve_space_for_menu=4,
complete_style=CompleteStyle.MULTI_COLUMN,
@@ -418,13 +447,38 @@ class InputOutput:
self.tool_error(str(err))
return ""
if line and line[0] == "{" and not multiline_input:
multiline_input = True
inp += line[1:] + "\n"
if line.strip("\r\n") and not multiline_input:
stripped = line.strip("\r\n")
if stripped == "{":
multiline_input = True
multiline_tag = None
inp += ""
elif stripped[0] == "{":
# Extract tag if it exists (only alphanumeric chars)
tag = "".join(c for c in stripped[1:] if c.isalnum())
if stripped == "{" + tag:
multiline_input = True
multiline_tag = tag
inp += ""
else:
inp = line
break
else:
inp = line
break
continue
elif line and line[-1] == "}" and multiline_input:
inp += line[:-1] + "\n"
break
elif multiline_input and line.strip():
if multiline_tag:
# Check if line is exactly "tag}"
if line.strip("\r\n") == f"{multiline_tag}}}":
break
else:
inp += line + "\n"
# Check if line is exactly "}"
elif line.strip("\r\n") == "}":
break
else:
inp += line + "\n"
elif multiline_input:
inp += line + "\n"
else:
@@ -440,8 +494,8 @@ class InputOutput:
return
FileHistory(self.input_history_file).append_string(inp)
# Also add to the in-memory history if it exists
if hasattr(self, "session") and hasattr(self.session, "history"):
self.session.history.append_string(inp)
if self.prompt_session and self.prompt_session.history:
self.prompt_session.history.append_string(inp)
def get_input_history(self):
if not self.input_history_file:
@@ -458,14 +512,17 @@ class InputOutput:
log_file.write(f"{role.upper()} {timestamp}\n")
log_file.write(content + "\n")
def display_user_input(self, inp):
if self.pretty and self.user_input_color:
style = dict(style=self.user_input_color)
else:
style = dict()
self.console.print(Text(inp), **style)
def user_input(self, inp, log_only=True):
if not log_only:
if self.pretty and self.user_input_color:
style = dict(style=self.user_input_color)
else:
style = dict()
self.console.print(Text(inp), **style)
self.display_user_input(inp)
prefix = "####"
if inp:
@@ -485,11 +542,11 @@ class InputOutput:
hist = "\n" + content.strip() + "\n\n"
self.append_chat_history(hist)
def offer_url(self, url, prompt="Open URL for more info?"):
def offer_url(self, url, prompt="Open URL for more info?", allow_never=True):
"""Offer to open a URL in the browser, returns True if opened."""
if url in self.never_prompts:
return False
if self.confirm_ask(prompt, subject=url, allow_never=True):
if self.confirm_ask(prompt, subject=url, allow_never=allow_never):
webbrowser.open(url)
return True
return False
@@ -688,6 +745,10 @@ class InputOutput:
self.console.print(show_resp)
def set_placeholder(self, placeholder):
"""Set a one-time placeholder text for the next input prompt."""
self.placeholder = placeholder
def print(self, message=""):
print(message)

View File

@@ -5,6 +5,8 @@ import re
import sys
import threading
import traceback
import webbrowser
from dataclasses import fields
from pathlib import Path
import git
@@ -16,11 +18,13 @@ from aider import __version__, models, urls, utils
from aider.analytics import Analytics
from aider.args import get_parser
from aider.coders import Coder
from aider.coders.base_coder import UnknownEditFormat
from aider.commands import Commands, SwitchCoder
from aider.format_settings import format_settings, scrub_sensitive_info
from aider.history import ChatSummary
from aider.io import InputOutput
from aider.llm import litellm # noqa: F401; properly init litellm on launch
from aider.models import ModelSettings
from aider.repo import ANY_GIT_ERROR, GitRepo
from aider.report import report_uncaught_exceptions
from aider.versioncheck import check_version, install_from_main_branch, install_upgrade
@@ -332,14 +336,16 @@ 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 = generate_search_path_list(
".aider.model.metadata.json", git_root, model_metadata_fname
)
model_metatdata_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_metatdata_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)
if len(model_metadata_files_loaded) > 0 and verbose:
@@ -503,8 +509,8 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
io.tool_warning("Terminal does not support pretty output (UnicodeDecodeError)")
analytics = Analytics(logfile=args.analytics_log, permanently_disable=args.analytics_disable)
if args.analytics:
if analytics.need_to_ask():
if args.analytics is not False:
if analytics.need_to_ask(args.analytics):
io.tool_output(
"Aider respects your privacy and never collects your code, chat messages, keys or"
" personal info."
@@ -540,7 +546,14 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
all_files = args.files + (args.file or [])
fnames = [str(Path(fn).resolve()) for fn in all_files]
read_only_fnames = [str(Path(fn).resolve()) for fn in (args.read or [])]
read_only_fnames = []
for fn in args.read or []:
path = Path(fn).resolve()
if path.is_dir():
read_only_fnames.extend(str(f) for f in path.rglob("*") if f.is_file())
else:
read_only_fnames.append(str(path))
if len(all_files) > 1:
good = True
for fname in all_files:
@@ -603,7 +616,8 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
cmd_line = scrub_sensitive_info(args, cmd_line)
io.tool_output(cmd_line, log_only=True)
check_and_load_imports(io, verbose=args.verbose)
is_first_run = is_first_run_of_new_version(io, verbose=args.verbose)
check_and_load_imports(io, is_first_run, verbose=args.verbose)
if args.anthropic_api_key:
os.environ["ANTHROPIC_API_KEY"] = args.anthropic_api_key
@@ -622,6 +636,18 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
register_models(git_root, args.model_settings_file, io, verbose=args.verbose)
register_litellm_models(git_root, args.model_metadata_file, io, verbose=args.verbose)
# Process any command line aliases
if args.alias:
for alias_def in args.alias:
# Split on first colon only
parts = alias_def.split(":", 1)
if len(parts) != 2:
io.tool_error(f"Invalid alias format: {alias_def}")
io.tool_output("Format should be: alias:model-name")
return 1
alias, model = parts
models.MODEL_ALIASES[alias.strip()] = model.strip()
if not args.model:
args.model = "gpt-4o-2024-08-06"
if os.environ.get("ANTHROPIC_API_KEY"):
@@ -635,9 +661,15 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
)
if args.verbose:
io.tool_output("Model info:")
io.tool_output("Model metadata:")
io.tool_output(json.dumps(main_model.info, indent=4))
io.tool_output("Model settings:")
for attr in sorted(fields(ModelSettings), key=lambda x: x.name):
val = getattr(main_model, attr.name)
val = json.dumps(val, indent=4)
io.tool_output(f"{attr.name}: {val}")
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
if lint_cmds is None:
return 1
@@ -678,7 +710,13 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
return 1
commands = Commands(
io, None, verify_ssl=args.verify_ssl, args=args, parser=parser, verbose=args.verbose
io,
None,
verify_ssl=args.verify_ssl,
args=args,
parser=parser,
verbose=args.verbose,
editor=args.editor,
)
summarizer = ChatSummary(
@@ -726,7 +764,12 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
num_cache_warming_pings=args.cache_keepalive_pings,
suggest_shell_commands=args.suggest_shell_commands,
chat_language=args.chat_language,
detect_urls=args.detect_urls,
)
except UnknownEditFormat as err:
io.tool_error(str(err))
io.offer_url(urls.edit_formats, "Open documentation about edit formats?")
return 1
except ValueError as err:
io.tool_error(str(err))
return 1
@@ -788,6 +831,18 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
io.tool_output('Use /help <question> for help, run "aider --help" to see cmd line args')
if args.show_release_notes is True:
io.tool_output(f"Opening release notes: {urls.release_notes}")
io.tool_output()
webbrowser.open(urls.release_notes)
elif args.show_release_notes is None and is_first_run:
io.tool_output()
io.offer_url(
urls.release_notes,
"Would you like to see what's new in this version?",
allow_never=False,
)
if git_root and Path.cwd().resolve() != Path(git_root).resolve():
io.tool_warning(
"Note: in-chat filenames are always relative to the git working dir, not the current"
@@ -843,7 +898,8 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
coder.show_announcements()
def check_and_load_imports(io, verbose=False):
def is_first_run_of_new_version(io, verbose=False):
"""Check if this is the first run of a new version/executable combination"""
installs_file = Path.home() / ".aider" / "installs.json"
key = (__version__, sys.executable)
@@ -864,7 +920,26 @@ def check_and_load_imports(io, verbose=False):
if verbose:
io.tool_output("Installs file does not exist, creating new dictionary")
if str(key) not in installs:
is_first_run = str(key) not in installs
if is_first_run:
installs[str(key)] = True
installs_file.parent.mkdir(parents=True, exist_ok=True)
with open(installs_file, "w") as f:
json.dump(installs, f, indent=4)
return is_first_run
except Exception as e:
io.tool_warning(f"Error checking version: {e}")
if verbose:
io.tool_output(f"Full exception details: {traceback.format_exc()}")
return True # Safer to assume it's a first run if we hit an error
def check_and_load_imports(io, is_first_run, verbose=False):
try:
if is_first_run:
if verbose:
io.tool_output(
"First run for this version and executable, loading imports synchronously"
@@ -875,13 +950,8 @@ def check_and_load_imports(io, verbose=False):
io.tool_error(str(err))
io.tool_output("Error loading required imports. Did you install aider properly?")
io.offer_url(urls.install_properly, "Open documentation url for more info?")
sys.exit(1)
installs[str(key)] = True
installs_file.parent.mkdir(parents=True, exist_ok=True)
with open(installs_file, "w") as f:
json.dump(installs, f, indent=4)
if verbose:
io.tool_output("Imports loaded and installs file updated")
else:
@@ -890,8 +960,9 @@ def check_and_load_imports(io, verbose=False):
thread = threading.Thread(target=load_slow_imports)
thread.daemon = True
thread.start()
except Exception as e:
io.tool_warning(f"Error in checking imports: {e}")
io.tool_warning(f"Error in loading imports: {e}")
if verbose:
io.tool_output(f"Full exception details: {traceback.format_exc()}")

View File

@@ -61,6 +61,23 @@ claude-3-5-sonnet-20241022
ANTHROPIC_MODELS = [ln.strip() for ln in ANTHROPIC_MODELS.splitlines() if ln.strip()]
# Mapping of model aliases to their canonical names
MODEL_ALIASES = {
# Claude models
"sonnet": "claude-3-sonnet-20241022",
"haiku": "claude-3-haiku-20241022",
"opus": "claude-3-opus-20240229",
# GPT models
"4": "gpt-4-0613",
"4o": "gpt-4o-2024-08-06",
"4-turbo": "gpt-4-1106-preview",
"35turbo": "gpt-3.5-turbo",
"35-turbo": "gpt-3.5-turbo",
"3": "gpt-3.5-turbo",
# Other models
"deepseek": "deepseek/deepseek-coder",
}
@dataclass
class ModelSettings:
@@ -161,6 +178,22 @@ MODEL_SETTINGS = [
lazy=True,
reminder="sys",
),
ModelSettings(
"gpt-4o-2024-11-20",
"diff",
weak_model_name="gpt-4o-mini",
use_repo_map=True,
lazy=True,
reminder="sys",
),
ModelSettings(
"openai/gpt-4o-2024-11-20",
"diff",
weak_model_name="gpt-4o-mini",
use_repo_map=True,
lazy=True,
reminder="sys",
),
ModelSettings(
"gpt-4o",
"diff",
@@ -629,7 +662,6 @@ MODEL_SETTINGS = [
reminder="user",
use_system_prompt=False,
use_temperature=False,
streaming=False,
),
ModelSettings(
"azure/o1-mini",
@@ -641,7 +673,6 @@ MODEL_SETTINGS = [
reminder="user",
use_system_prompt=False,
use_temperature=False,
streaming=False,
),
ModelSettings(
"o1-mini",
@@ -653,7 +684,6 @@ MODEL_SETTINGS = [
reminder="user",
use_system_prompt=False,
use_temperature=False,
streaming=False,
),
ModelSettings(
"openai/o1-preview",
@@ -665,7 +695,6 @@ MODEL_SETTINGS = [
reminder="user",
use_system_prompt=False,
use_temperature=False,
streaming=False,
),
ModelSettings(
"azure/o1-preview",
@@ -677,7 +706,6 @@ MODEL_SETTINGS = [
reminder="user",
use_system_prompt=False,
use_temperature=False,
streaming=False,
),
ModelSettings(
"o1-preview",
@@ -689,7 +717,6 @@ MODEL_SETTINGS = [
reminder="user",
use_system_prompt=False,
use_temperature=False,
streaming=False,
),
ModelSettings(
"openrouter/openai/o1-mini",
@@ -762,6 +789,11 @@ class ModelInfoManager:
pass
except Exception as ex:
print(str(ex))
try:
# Save empty dict to cache file on failure
self.cache_file.write_text("{}")
except OSError:
pass
def get_model_from_cached_json_db(self, model):
if not self.content:
@@ -804,11 +836,17 @@ model_info_manager = ModelInfoManager()
class Model(ModelSettings):
def __init__(self, model, weak_model=None, editor_model=None, editor_edit_format=None):
self.name = model
# Map any alias to its canonical name
self.name = MODEL_ALIASES.get(model, model)
self.max_chat_history_tokens = 1024
self.weak_model = None
self.editor_model = None
# Find the extra settings
self.extra_model_settings = next(
(ms for ms in MODEL_SETTINGS if ms.name == "aider/extra_params"), None
)
self.info = self.get_model_info(model)
# Are all needed keys/params available?
@@ -836,17 +874,44 @@ class Model(ModelSettings):
def get_model_info(self, model):
return model_info_manager.get_model_info(model)
def _copy_fields(self, source):
"""Helper to copy fields from a ModelSettings instance to self"""
for field in fields(ModelSettings):
val = getattr(source, field.name)
setattr(self, field.name, val)
def configure_model_settings(self, model):
# Look for exact model match
exact_match = False
for ms in MODEL_SETTINGS:
# direct match, or match "provider/<model>"
if model == ms.name:
for field in fields(ModelSettings):
val = getattr(ms, field.name)
setattr(self, field.name, val)
return # <--
self._copy_fields(ms)
exact_match = True
break # Continue to apply overrides
model = model.lower()
# If no exact match, try generic settings
if not exact_match:
self.apply_generic_model_settings(model)
# Apply override settings last if they exist
if self.extra_model_settings and self.extra_model_settings.extra_params:
# Initialize extra_params if it doesn't exist
if not self.extra_params:
self.extra_params = {}
# Deep merge the extra_params dicts
for key, value in self.extra_model_settings.extra_params.items():
if isinstance(value, dict) and isinstance(self.extra_params.get(key), dict):
# For nested dicts, merge recursively
self.extra_params[key] = {**self.extra_params[key], **value}
else:
# For non-dict values, simply update
self.extra_params[key] = value
def apply_generic_model_settings(self, model):
if ("llama3" in model or "llama-3" in model) and "70b" in model:
self.edit_format = "diff"
self.use_repo_map = True
@@ -868,27 +933,37 @@ class Model(ModelSettings):
if "gpt-3.5" in model or "gpt-4" in model:
self.reminder = "sys"
return # <--
if "3.5-sonnet" in model or "3-5-sonnet" in model:
self.edit_format = "diff"
self.use_repo_map = True
self.examples_as_sys_msg = True
self.reminder = "user"
return # <--
if model.startswith("o1-") or "/o1-" in model:
self.use_system_prompt = False
self.use_temperature = False
self.streaming = False
return # <--
if "qwen" in model and "coder" in model and ("2.5" in model or "2-5" in model):
"openrouter/qwen/qwen-2.5-coder-32b-instruct",
if (
"qwen" in model
and "coder" in model
and ("2.5" in model or "2-5" in model)
and "32b" in model
):
self.edit_format = "diff"
self.editor_edit_format = "editor-diff"
self.use_repo_map = True
if model.startswith("ollama/") or model.startswith("ollama_chat/"):
self.extra_params = dict(num_ctx=8 * 1024)
return # <--
# use the defaults
if self.edit_format == "diff":
self.use_repo_map = True
return # <--
def __str__(self):
return self.name
@@ -1045,6 +1120,9 @@ def register_models(model_settings_fnames):
if not os.path.exists(model_settings_fname):
continue
if not Path(model_settings_fname).read_text().strip():
continue
try:
with open(model_settings_fname, "r") as model_settings_file:
model_settings_list = yaml.safe_load(model_settings_file)
@@ -1162,7 +1240,10 @@ def fuzzy_match_models(name):
model = model.lower()
if attrs.get("mode") != "chat":
continue
provider = (attrs["litellm_provider"] + "/").lower()
provider = attrs.get("litellm_provider", "").lower()
if not provider:
continue
provider += "/"
if model.startswith(provider):
fq_model = model

View File

@@ -0,0 +1,91 @@
(class_definition
name: (identifier) @name.definition.class) @definition.class
(method_signature
(function_signature)) @definition.method
(type_alias
(type_identifier) @name.definition.type) @definition.type
(method_signature
(getter_signature
name: (identifier) @name.definition.method)) @definition.method
(method_signature
(setter_signature
name: (identifier) @name.definition.method)) @definition.method
(method_signature
(function_signature
name: (identifier) @name.definition.method)) @definition.method
(method_signature
(factory_constructor_signature
(identifier) @name.definition.method)) @definition.method
(method_signature
(constructor_signature
name: (identifier) @name.definition.method)) @definition.method
(method_signature
(operator_signature)) @definition.method
(method_signature) @definition.method
(mixin_declaration
(mixin)
(identifier) @name.definition.mixin) @definition.mixin
(extension_declaration
name: (identifier) @name.definition.extension) @definition.extension
(enum_declaration
name: (identifier) @name.definition.enum) @definition.enum
(function_signature
name: (identifier) @name.definition.function) @definition.function
(new_expression
(type_identifier) @name.reference.class) @reference.class
(initialized_variable_definition
name: (identifier)
value: (identifier) @name.reference.class
value: (selector
"!"?
(argument_part
(arguments
(argument)*))?)?) @reference.class
(assignment_expression
left: (assignable_expression
(identifier)
(unconditional_assignable_selector
"."
(identifier) @name.reference.call))) @reference.call
(assignment_expression
left: (assignable_expression
(identifier)
(conditional_assignable_selector
"?."
(identifier) @name.reference.call))) @reference.call
((identifier) @name
(selector
"!"?
(conditional_assignable_selector
"?." (identifier) @name.reference.call)?
(unconditional_assignable_selector
"."? (identifier) @name.reference.call)?
(argument_part
(arguments
(argument)*))?)*
(cascade_section
(cascade_selector
(identifier)) @name.reference.call
(argument_part
(arguments
(argument)*))?)?) @reference.call

View File

@@ -334,8 +334,11 @@ class GitRepo:
def git_ignored_file(self, path):
if not self.repo:
return
if self.repo.ignored(path):
return True
try:
if self.repo.ignored(path):
return True
except ANY_GIT_ERROR:
return False
def ignored_file(self, fname):
self.refresh_aider_ignore()

View File

@@ -1,11 +0,0 @@
{
"openrouter/qwen/qwen-2.5-coder-32b-instruct": {
"max_tokens": 33792,
"max_input_tokens": 33792,
"max_output_tokens": 33792,
"input_cost_per_token": 0.00000018,
"output_cost_per_token": 0.00000018,
"litellm_provider": "openrouter",
"mode": "chat",
},
}

View File

@@ -12,3 +12,5 @@ github_issues = "https://github.com/Aider-AI/aider/issues/new"
git_index_version = "https://github.com/Aider-AI/aider/issues/211"
install_properly = "https://aider.chat/docs/troubleshooting/imports.html"
analytics = "https://aider.chat/docs/more/analytics.html"
release_notes = "https://aider.chat/HISTORY.html#release-notes"
edit_formats = "https://aider.chat/docs/more/edit-formats.html"

View File

@@ -10,6 +10,12 @@ description: Release notes and stats on aider writing its own code.
{% include blame.md %}
The above
[stats are based on the git commit history](/docs/faq.html#how-are-the-aider-wrote-xx-of-code-stats-computed)
of the aider repo.
## Release notes
<!--[[[cog
# This page is a copy of HISTORY.md, adding the front matter above.
text = open("HISTORY.md").read()
@@ -18,6 +24,54 @@ cog.out(text)
]]]-->
### main branch
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
- Added `--[no-]detect-urls` flag to disable detecting and offering to scrape URLs found in the chat.
- Ollama models now default to an 8k context window.
- Added [RepoMap support for Dart language](https://aider.chat/docs/languages.html) by @malkoG.
- Ask 2.5% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
- Skip suggesting files that share names with files already in chat.
- `/editor` returns and prefill the file content into the prompt, so you can use `/editor` to compose messages that start with `/commands`, etc.
- Enhanced error handling for analytics.
- Improved handling of UnknownEditFormat exceptions with helpful documentation links.
- Bumped dependencies to pick up grep-ast 0.4.0 for Dart language support.
- Aider wrote 81% of the code in this release.
### Aider v0.64.1
- Disable streaming for o1 on OpenRouter.
### Aider v0.64.0
- Added [`/editor` command](https://aider.chat/docs/usage/commands.html) to open system editor for writing prompts, by @thehunmonkgroup.
- Full support for `gpt-4o-2024-11-20`.
- Stream o1 models by default.
- `/run` and suggested shell commands are less mysterious and now confirm that they "Added XX lines of output to the chat."
- Ask 1% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
- Added support for [optional multiline input tags](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) with matching closing tags.
- Improved [model settings configuration](https://aider.chat/docs/config/adv-model-settings.html#global-extra-params) with support for global `extra_params` for `litellm.completion()`.
- Architect mode now asks to add files suggested by the LLM.
- Fixed bug in fuzzy model name matching.
- Added Timeout exception to handle API provider timeouts.
- Added `--show-release-notes` to control release notes display on first run of new version.
- Save empty dict to cache file on model metadata download failure, to delay retry.
- Improved error handling and code formatting.
- Aider wrote 74% of the code in this release.
### Aider v0.63.2
- Fixed bug in fuzzy model name matching when litellm provider info is missing.
- Modified model metadata file loading to allow override of resource file.
- Allow recursive loading of dirs using `--read`.
- Updated dependency versions to pick up litellm fix for ollama models.
- Added exponential backoff retry when writing files to handle editor file locks.
- Updated Qwen 2.5 Coder 32B model configuration.
### Aider v0.63.1
- Fixed bug in git ignored file handling.
- Improved error handling for git operations.
### Aider v0.63.0

View File

@@ -1801,8 +1801,8 @@
Paul Gauthier (aider): 113
start_tag: v0.44.0
total_lines: 266
- aider_percentage: 47.04
aider_total: 254
- aider_percentage: 53.3
aider_total: 339
end_date: '2024-07-29'
end_tag: v0.46.0
file_counts:
@@ -1853,6 +1853,9 @@
aider/scrape.py:
Paul Gauthier: 3
Paul Gauthier (aider): 32
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 11
Paul Gauthier (aider): 85
benchmark/Dockerfile:
Your Name: 1
tests/basic/test_coder.py:
@@ -1868,13 +1871,13 @@
Paul Gauthier (aider): 73
grand_total:
Charles Joachim: 4
Paul Gauthier: 209
Paul Gauthier (aider): 204
Paul Gauthier: 220
Paul Gauthier (aider): 289
Your Name: 73
Your Name (aider): 50
start_tag: v0.45.0
total_lines: 540
- aider_percentage: 59.12
total_lines: 636
- aider_percentage: 57.16
aider_total: 415
end_date: '2024-07-31'
end_tag: v0.47.0
@@ -1920,6 +1923,8 @@
Paul Gauthier (aider): 2
aider/utils.py:
Paul Gauthier: 7
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 24
docker/Dockerfile:
Paul Gauthier: 19
Paul Gauthier (aider): 21
@@ -1944,10 +1949,10 @@
tests/basic/test_repomap.py:
Paul Gauthier: 1
grand_total:
Paul Gauthier: 287
Paul Gauthier: 311
Paul Gauthier (aider): 415
start_tag: v0.46.0
total_lines: 702
total_lines: 726
- aider_percentage: 44.44
aider_total: 276
end_date: '2024-08-06'
@@ -2011,8 +2016,8 @@
paul-gauthier: 1
start_tag: v0.47.0
total_lines: 621
- aider_percentage: 61.52
aider_total: 478
- aider_percentage: 61.2
aider_total: 489
end_date: '2024-08-10'
end_tag: v0.49.0
file_counts:
@@ -2055,6 +2060,9 @@
aider/versioncheck.py:
Paul Gauthier: 3
Paul Gauthier (aider): 11
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 11
Paul Gauthier (aider): 11
docker/Dockerfile:
Paul Gauthier: 5
Paul Gauthier (aider): 2
@@ -2075,10 +2083,10 @@
Paul Gauthier: 1
Paul Gauthier (aider): 49
grand_total:
Paul Gauthier: 299
Paul Gauthier (aider): 478
Paul Gauthier: 310
Paul Gauthier (aider): 489
start_tag: v0.48.0
total_lines: 777
total_lines: 799
- aider_percentage: 66.05
aider_total: 214
end_date: '2024-08-13'
@@ -2135,8 +2143,8 @@
Paul Gauthier (aider): 201
start_tag: v0.49.0
total_lines: 324
- aider_percentage: 56.25
aider_total: 450
- aider_percentage: 52.49
aider_total: 580
end_date: '2024-08-20'
end_tag: v0.51.0
file_counts:
@@ -2170,6 +2178,14 @@
Paul Gauthier: 3
aider/utils.py:
Paul Gauthier (aider): 6
aider/website/_includes/code-in-json-benchmark.js:
Paul Gauthier: 101
Paul Gauthier (aider): 64
aider/website/_includes/code-in-json-syntax.js:
Paul Gauthier: 73
Paul Gauthier (aider): 66
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
benchmark/benchmark.py:
Paul Gauthier: 7
benchmark/over_time.py:
@@ -2188,11 +2204,11 @@
Paul Gauthier: 15
Paul Gauthier (aider): 104
grand_total:
Paul Gauthier: 350
Paul Gauthier (aider): 450
Paul Gauthier: 525
Paul Gauthier (aider): 580
start_tag: v0.50.0
total_lines: 800
- aider_percentage: 68.19
total_lines: 1105
- aider_percentage: 68.1
aider_total: 521
end_date: '2024-08-23'
end_tag: v0.52.0
@@ -2231,6 +2247,8 @@
Paul Gauthier (aider): 9
aider/versioncheck.py:
Paul Gauthier: 2
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
benchmark/benchmark.py:
Paul Gauthier: 1
scripts/blame.py:
@@ -2250,13 +2268,13 @@
tests/basic/test_wholefile.py:
Paul Gauthier: 8
grand_total:
Paul Gauthier: 242
Paul Gauthier: 243
Paul Gauthier (aider): 521
pcamp: 1
start_tag: v0.51.0
total_lines: 764
- aider_percentage: 58.61
aider_total: 405
total_lines: 765
- aider_percentage: 61.4
aider_total: 455
end_date: '2024-08-27'
end_tag: v0.53.0
file_counts:
@@ -2321,14 +2339,16 @@
tests/basic/test_repomap.py:
Paul Gauthier: 4
Paul Gauthier (aider): 63
tests/fixtures/sample-code-base/sample.js:
Paul Gauthier (aider): 50
tests/fixtures/sample-code-base/sample.py:
Paul Gauthier (aider): 68
grand_total:
Paul Gauthier: 286
Paul Gauthier (aider): 405
Paul Gauthier (aider): 455
start_tag: v0.52.0
total_lines: 691
- aider_percentage: 63.95
total_lines: 741
- aider_percentage: 63.75
aider_total: 204
end_date: '2024-08-28'
end_tag: v0.54.0
@@ -2364,6 +2384,8 @@
aider/versioncheck.py:
Paul Gauthier: 1
Paul Gauthier (aider): 13
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
tests/basic/test_coder.py:
Paul Gauthier: 36
Paul Gauthier (aider): 27
@@ -2376,11 +2398,11 @@
Paul Gauthier: 1
grand_total:
Antti Kaihola: 4
Paul Gauthier: 111
Paul Gauthier: 112
Paul Gauthier (aider): 204
start_tag: v0.53.0
total_lines: 319
- aider_percentage: 52.9
total_lines: 320
- aider_percentage: 52.87
aider_total: 811
end_date: '2024-09-04'
end_tag: v0.55.0
@@ -2450,6 +2472,8 @@
aider/voice.py:
Paul Gauthier: 7
Paul Gauthier (aider): 9
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
scripts/versionbump.py:
Paul Gauthier: 9
tests/basic/test_coder.py:
@@ -2478,11 +2502,11 @@
grand_total:
Antti Kaihola: 12
Nikolay Sedelnikov: 45
Paul Gauthier: 665
Paul Gauthier: 666
Paul Gauthier (aider): 811
start_tag: v0.54.0
total_lines: 1533
- aider_percentage: 55.6
total_lines: 1534
- aider_percentage: 55.4
aider_total: 154
end_date: '2024-09-09'
end_tag: v0.56.0
@@ -2517,6 +2541,8 @@
aider/report.py:
Paul Gauthier: 2
Paul Gauthier (aider): 20
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
benchmark/benchmark.py:
Paul Gauthier: 1
tests/basic/test_linter.py:
@@ -2526,13 +2552,13 @@
Paul Gauthier: 2
Paul Gauthier (aider): 9
grand_total:
Paul Gauthier: 108
Paul Gauthier: 109
Paul Gauthier (aider): 154
fry69: 15
start_tag: v0.55.0
total_lines: 277
- aider_percentage: 69.98
aider_total: 394
total_lines: 278
- aider_percentage: 70.36
aider_total: 406
end_date: '2024-09-21'
end_tag: v0.57.0
file_counts:
@@ -2575,6 +2601,10 @@
Paul Gauthier: 3
aider/utils.py:
Paul Gauthier: 2
aider/website/docs/leaderboards/index.md:
Anjor Kanekar: 1
Paul Gauthier: 1
Paul Gauthier (aider): 12
benchmark/benchmark.py:
Paul Gauthier: 4
scripts/issues.py:
@@ -2592,15 +2622,16 @@
Paul Gauthier: 18
Paul Gauthier (aider): 20
grand_total:
Anjor Kanekar: 1
Christian Clauss: 2
Jay Alammar: 1
Jay Alammar (aider): 13
Krazer: 33
Paul Gauthier: 133
Paul Gauthier (aider): 381
Paul Gauthier: 134
Paul Gauthier (aider): 393
start_tag: v0.56.0
total_lines: 563
- aider_percentage: 53.45
total_lines: 577
- aider_percentage: 47.95
aider_total: 712
end_date: '2024-09-29'
end_tag: v0.58.0
@@ -2677,6 +2708,8 @@
Mike Bailey: 17
Paul Gauthier: 2
Paul Gauthier (aider): 10
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 153
benchmark/benchmark.py:
Paul Gauthier: 25
Paul Gauthier (aider): 29
@@ -2705,14 +2738,14 @@
grand_total:
Jonathan Ellis: 2
Mike Bailey: 18
Paul Gauthier: 376
Paul Gauthier: 529
Paul Gauthier (aider): 712
Stein Martin Hustad: 26
fry69: 197
rti: 1
start_tag: v0.57.0
total_lines: 1332
- aider_percentage: 76.79
total_lines: 1485
- aider_percentage: 75.44
aider_total: 172
end_date: '2024-10-04'
end_tag: v0.59.0
@@ -2747,6 +2780,8 @@
Paul Gauthier: 2
aider/versioncheck.py:
Paul Gauthier: 1
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 4
scripts/issues.py:
Paul Gauthier: 1
scripts/update-docs.sh:
@@ -2762,11 +2797,11 @@
tests/help/test_help.py:
Paul Gauthier: 1
grand_total:
Paul Gauthier: 52
Paul Gauthier: 56
Paul Gauthier (aider): 172
start_tag: v0.58.0
total_lines: 224
- aider_percentage: 49.12
total_lines: 228
- aider_percentage: 48.95
aider_total: 140
end_date: '2024-10-22'
end_tag: v0.60.0
@@ -2804,6 +2839,8 @@
Paul Gauthier: 3
aider/sendchat.py:
Paul Gauthier: 3
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
tests/basic/test_editblock.py:
Paul Gauthier: 23
tests/basic/test_main.py:
@@ -2813,12 +2850,12 @@
Paul Gauthier (aider): 46
grand_total:
Jonathan Ellis: 10
Paul Gauthier: 93
Paul Gauthier: 94
Paul Gauthier (aider): 140
Sven Grunewaldt: 24
fry69: 18
start_tag: v0.59.0
total_lines: 285
total_lines: 286
- aider_percentage: 67.61
aider_total: 860
end_date: '2024-11-01'
@@ -2895,8 +2932,8 @@
kAIto47802: 4
start_tag: v0.60.0
total_lines: 1272
- aider_percentage: 84.0
aider_total: 63
- aider_percentage: 82.42
aider_total: 75
end_date: '2024-11-04'
end_tag: v0.62.0
file_counts:
@@ -2911,8 +2948,161 @@
aider/models.py:
Paul Gauthier: 5
Paul Gauthier (aider): 45
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 4
Paul Gauthier (aider): 12
grand_total:
Paul Gauthier: 12
Paul Gauthier (aider): 63
Paul Gauthier: 16
Paul Gauthier (aider): 75
start_tag: v0.61.0
total_lines: 75
total_lines: 91
- aider_percentage: 55.08
aider_total: 385
end_date: '2024-11-13'
end_tag: v0.63.0
file_counts:
aider/__init__.py:
Paul Gauthier: 1
aider/coders/architect_coder.py:
Paul Gauthier: 3
aider/coders/base_coder.py:
Paul Gauthier: 42
Paul Gauthier (aider): 1
aider/coders/editblock_coder.py:
Paul Gauthier: 4
aider/commands.py:
Paul Gauthier: 13
aider/exceptions.py:
Paul Gauthier: 72
Paul Gauthier (aider): 4
aider/io.py:
Paul Gauthier: 3
Paul Gauthier (aider): 23
aider/main.py:
Paul Gauthier: 9
Paul Gauthier (aider): 9
aider/models.py:
Logan Attwood: 29
Paul Gauthier: 50
Paul Gauthier (aider): 7
aider/repo.py:
Paul Gauthier: 7
aider/repomap.py:
Paul Gauthier: 4
aider/sendchat.py:
Paul Gauthier: 17
Paul Gauthier (aider): 4
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
scripts/issues.py:
Paul Gauthier: 4
Paul Gauthier (aider): 195
tests/basic/test_coder.py:
Paul Gauthier: 2
tests/basic/test_commands.py:
Paul Gauthier (aider): 20
tests/basic/test_editblock.py:
Paul Gauthier: 41
tests/basic/test_exceptions.py:
Paul Gauthier (aider): 65
tests/basic/test_main.py:
Paul Gauthier: 1
tests/basic/test_sanity_check_repo.py:
Paul Gauthier: 2
Paul Gauthier (aider): 2
tests/basic/test_sendchat.py:
Paul Gauthier: 8
Paul Gauthier (aider): 55
tests/scrape/test_scrape.py:
Paul Gauthier: 1
grand_total:
Logan Attwood: 29
Paul Gauthier: 285
Paul Gauthier (aider): 385
start_tag: v0.62.0
total_lines: 699
- aider_percentage: 73.15
aider_total: 880
end_date: '2024-11-21'
end_tag: v0.64.0
file_counts:
aider/__init__.py:
Paul Gauthier: 1
aider/analytics.py:
Paul Gauthier: 20
Paul Gauthier (aider): 21
aider/args.py:
Paul Gauthier: 2
Paul Gauthier (aider): 10
aider/coders/base_coder.py:
Paul Gauthier: 15
Paul Gauthier (aider): 3
caetanominuzzo: 1
aider/commands.py:
Chad Phillips: 4
Paul Gauthier: 5
Paul Gauthier (aider): 19
aider/editor.py:
Chad Phillips: 133
Paul Gauthier (aider): 13
aider/exceptions.py:
Paul Gauthier: 5
aider/help_pats.py:
Paul Gauthier: 1
aider/io.py:
Chad Phillips: 9
Paul Gauthier (aider): 41
mw: 21
aider/main.py:
Paul Gauthier: 21
Paul Gauthier (aider): 41
aider/models.py:
Paul Gauthier: 41
Paul Gauthier (aider): 33
aider/repo.py:
Paul Gauthier (aider): 5
aider/urls.py:
Paul Gauthier: 1
aider/website/_includes/edit-leaderboard.js:
Paul Gauthier (aider): 97
aider/website/_includes/quant-chart.js:
Paul Gauthier: 3
Paul Gauthier (aider): 66
aider/website/_includes/refactor-leaderboard.js:
Paul Gauthier (aider): 90
aider/website/docs/leaderboards/index.md:
Paul Gauthier: 1
Paul Gauthier (aider): 10
aider/website/share/index.md:
Paul Gauthier (aider): 29
benchmark/over_time.py:
Paul Gauthier: 11
Paul Gauthier (aider): 162
scripts/blame.py:
Paul Gauthier: 1
Paul Gauthier (aider): 2
scripts/issues.py:
Paul Gauthier: 5
Paul Gauthier (aider): 12
scripts/versionbump.py:
Paul Gauthier: 7
tests/basic/test_analytics.py:
Paul Gauthier: 12
Paul Gauthier (aider): 30
tests/basic/test_commands.py:
Paul Gauthier (aider): 4
tests/basic/test_editor.py:
Paul Gauthier (aider): 129
tests/basic/test_main.py:
Paul Gauthier (aider): 8
tests/basic/test_models.py:
Paul Gauthier: 3
Paul Gauthier (aider): 55
grand_total:
Chad Phillips: 146
Paul Gauthier: 155
Paul Gauthier (aider): 880
caetanominuzzo: 1
mw: 21
start_tag: v0.63.0
total_lines: 1203

View File

@@ -1,7 +1,7 @@
- dirname: 2024-05-01-20-05-59--direct-opus-filenames-outside-fence
test_cases: 133
model: claude-3-opus-20240229
released: 2024-02-29
_released: 2024-02-29
edit_format: diff
commit_hash: f4b1797-dirty, f4b1797
pass_rate_1: 53.4
@@ -46,7 +46,8 @@
- dirname: 2024-05-03-20-47-24--gemini-1.5-pro-diff-fenced
test_cases: 133
model: gemini-1.5-pro-latest
released: 2024-05-03
model: gemini-1.5-pro-001
edit_format: diff-fenced
commit_hash: 3a48dfb, 5d32dd7
pass_rate_1: 45.9
@@ -274,7 +275,7 @@
- dirname: 2024-05-03-22-24-48--openrouter--llama3-diff-examples-sys-msg
test_cases: 132
model: llama3-70b-8192
released: 2024-04-18
_released: 2024-04-18
edit_format: diff
commit_hash: b5bb453
pass_rate_1: 38.6
@@ -297,7 +298,7 @@
- dirname: 2024-05-06-18-31-08--command-r-plus-whole-final
test_cases: 133
model: command-r-plus
released: 2024-04-04
_released: 2024-04-04
edit_format: whole
commit_hash: fc3a43e-dirty
pass_rate_1: 21.8
@@ -410,6 +411,7 @@
- dirname: 2024-06-08-22-37-55--qwen2-72b-instruct-whole
test_cases: 133
model: Qwen2 72B Instruct
released: 2024-06-08
edit_format: whole
commit_hash: 02c7335-dirty, 1a97498-dirty
pass_rate_1: 44.4
@@ -623,7 +625,7 @@
commit_hash: d31eef3-dirty
pass_rate_1: 40.6
pass_rate_2: 55.6
released: 2024-07-18
_released: 2024-07-18
percent_cases_well_formed: 100.0
error_outputs: 1
num_malformed_responses: 0
@@ -671,7 +673,7 @@
commit_hash: f7ce78b-dirty
pass_rate_1: 46.6
pass_rate_2: 63.9
released: 2024-07-23
_released: 2024-07-23
percent_cases_well_formed: 92.5
error_outputs: 84
num_malformed_responses: 19
@@ -691,6 +693,7 @@
- dirname: 2024-07-24-06-30-29--llama-405b-whole
test_cases: 133
model: llama-3.1-405b-instruct (whole)
_released: 2024-07-23
edit_format: whole
commit_hash: a362dea-dirty
pass_rate_1: 48.9
@@ -698,7 +701,6 @@
percent_cases_well_formed: 100.0
error_outputs: 0
num_malformed_responses: 0
released: 2024-07-23
num_with_malformed_responses: 0
user_asks: 0
lazy_comments: 0
@@ -770,7 +772,7 @@
percent_cases_well_formed: 100.0
error_outputs: 27
num_malformed_responses: 0
released: 2024-07-23
_released: 2024-07-23
num_with_malformed_responses: 0
user_asks: 23
lazy_comments: 8
@@ -796,7 +798,7 @@
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 0
released: 2024-07-23
_released: 2024-07-23
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
@@ -835,6 +837,7 @@
- dirname: 2024-08-28-07-10-50--gemini-1.5-pro-exp-0827-diff-fenced
test_cases: 133
model: gemini-1.5-pro-exp-0827
released: 2024-08-27
edit_format: diff-fenced
commit_hash: d8adc75
pass_rate_1: 54.9
@@ -946,7 +949,7 @@
versions: 0.54.13.dev
seconds_per_case: 8.3
total_cost: 0.0000
released: 2024-09-04
_released: 2024-09-04
- dirname: 2024-09-04-16-17-33--yi-coder-9b-chat-q4_0-whole
test_cases: 133
@@ -973,6 +976,7 @@
- dirname: 2024-09-05-14-50-11--deepseek-sep5-no-shell
test_cases: 133
released: 2024-09-05
model: DeepSeek V2.5
edit_format: diff
commit_hash: 1279c86
@@ -1112,6 +1116,7 @@
- dirname: 2024-09-21-16-45-11--o1-preview-flex-sr-markers
test_cases: 133
model: o1-preview
_released: 2024-09-12
edit_format: diff
commit_hash: 5493654-dirty
pass_rate_1: 57.9
@@ -1204,6 +1209,7 @@
- dirname: 2024-09-24-16-26-45--gemini-1.5-pro-002-diff-fenced
test_cases: 133
model: gemini-1.5-pro-002
released: 2024-09-24
edit_format: diff-fenced
commit_hash: 6b5fe9b, 3edcd71
pass_rate_1: 49.6
@@ -1477,6 +1483,7 @@
- dirname: 2024-10-04-16-30-08--chatgpt-4o-latest-diff-oct4
test_cases: 133
model: openai/chatgpt-4o-latest
released: 2024-10-04
edit_format: diff
commit_hash: af10953
pass_rate_1: 56.4
@@ -1592,6 +1599,7 @@
- dirname: 2024-10-22-17-45-28--sonnet-1022-diff-fixed-model-settings
test_cases: 133
model: claude-3-5-sonnet-20241022
released: 2024-10-22
edit_format: diff
commit_hash: 3b14eb9
pass_rate_1: 69.2
@@ -1615,6 +1623,7 @@
- dirname: 2024-11-04-19-19-32--haiku35-diff-ex-as-sys-false
test_cases: 133
model: claude-3-5-haiku-20241022
released: 2024-10-22
edit_format: diff
commit_hash: 03bbdb0-dirty
pass_rate_1: 61.7
@@ -1773,32 +1782,10 @@
seconds_per_case: 18.3
total_cost: 0.0000
- dirname: 2024-11-09-10-57-11--Qwen2.5-Coder-32B-Instruct
test_cases: 133
model: Qwen2.5-Coder-32B-Instruct (whole)
edit_format: whole
commit_hash: ec9982a
pass_rate_1: 60.9
pass_rate_2: 73.7
percent_cases_well_formed: 100.0
error_outputs: 1
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 1
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 1
command: aider --model openai/Qwen2.5-Coder-32B-Instruct
date: 2024-11-09
versions: 0.59.2.dev
seconds_per_case: 26.6
total_cost: 0.0000
- dirname: 2024-11-09-11-09-15--Qwen2.5-Coder-32B-Instruct
test_cases: 133
model: Qwen2.5-Coder-32B-Instruct (diff)
model: Qwen2.5-Coder-32B-Instruct
released: 2024-11-12
edit_format: diff
commit_hash: ec9982a
pass_rate_1: 59.4
@@ -1813,8 +1800,149 @@
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
command: aider --model openai/Qwen2.5-Coder-32B-Instruct
command: aider --model openai/hf:Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://glhf.chat/api/openai/v1
date: 2024-11-09
versions: 0.59.2.dev
seconds_per_case: 22.5
total_cost: 0.0000
- dirname: 2024-11-20-14-57-11--mistral-2411-direct-diff
test_cases: 133
model: Mistral Large (2411)
released: 2024-11-18
edit_format: diff
commit_hash: dba844c
pass_rate_1: 46.6
pass_rate_2: 65.4
percent_cases_well_formed: 96.2
error_outputs: 8
num_malformed_responses: 8
num_with_malformed_responses: 5
user_asks: 5
lazy_comments: 0
syntax_errors: 0
indentation_errors: 1
exhausted_context_windows: 0
test_timeouts: 1
command: aider --model mistral/mistral-large-latest
date: 2024-11-20
versions: 0.63.3.dev
seconds_per_case: 24.9
total_cost: 3.2334
- dirname: 2024-11-20-19-28-30--gpt-4o-2024-11-20
test_cases: 133
model: gpt-4o-2024-11-20
released: 2024-11-20
edit_format: diff
commit_hash: 2ac0776-dirty
pass_rate_1: 58.6
pass_rate_2: 71.4
percent_cases_well_formed: 99.2
error_outputs: 1
num_malformed_responses: 1
num_with_malformed_responses: 1
user_asks: 4
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 5
command: aider --model openai/gpt-4o-2024-11-20
date: 2024-11-20
versions: 0.63.3.dev
seconds_per_case: 6.0
total_cost: 0.0000
- dirname: 2024-09-20-21-47-17--qwen2.5-32b-instruct-q8_0-whole
test_cases: 133
model: ollama/qwen2.5:32b-instruct-q8_0
edit_format: whole
commit_hash: 2753ac6
pass_rate_1: 46.6
pass_rate_2: 58.6
percent_cases_well_formed: 100.0
error_outputs: 0
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 1
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
command: aider --model ollama/qwen2.5:32b-instruct-q8_0
date: 2024-09-20
versions: 0.56.1.dev
seconds_per_case: 1763.7
total_cost: 0.0000
- dirname: 2024-11-20-15-17-37--qwen25-32b-or-diff
test_cases: 133
model: openrouter/qwen/qwen-2.5-coder-32b-instruct
edit_format: diff
commit_hash: e917424
pass_rate_1: 49.6
pass_rate_2: 65.4
percent_cases_well_formed: 84.2
error_outputs: 43
num_malformed_responses: 31
num_with_malformed_responses: 21
user_asks: 43
lazy_comments: 0
syntax_errors: 2
indentation_errors: 2
exhausted_context_windows: 12
test_timeouts: 2
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
date: 2024-11-20
versions: 0.63.3.dev
seconds_per_case: 40.7
total_cost: 0.1497
- dirname: 2024-11-21-17-46-36--gemini-exp-1121-diff
test_cases: 133
model: gemini-exp-1121
released: 2024-11-21
edit_format: diff
commit_hash: e94961a
pass_rate_1: 46.6
pass_rate_2: 57.9
percent_cases_well_formed: 83.5
error_outputs: 101
num_malformed_responses: 101
num_with_malformed_responses: 22
user_asks: 5
lazy_comments: 0
syntax_errors: 0
indentation_errors: 2
exhausted_context_windows: 0
test_timeouts: 3
command: aider --model gemini/gemini-exp-1121
date: 2024-11-21
versions: 0.63.3.dev
seconds_per_case: 60.3
total_cost: 0.0000
- dirname: 2024-11-15-20-33-31--gemini-exp-1114-diff
test_cases: 133
model: gemini-exp-1114
released: 2024-11-14
edit_format: diff
commit_hash: 0bf17a4
pass_rate_1: 50.4
pass_rate_2: 60.9
percent_cases_well_formed: 85.7
error_outputs: 70
num_malformed_responses: 70
num_with_malformed_responses: 19
user_asks: 2
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 4
command: aider --model gemini/gemini-exp-1114
date: 2024-11-15
versions: 0.63.2.dev
seconds_per_case: 38.6

View File

@@ -0,0 +1,299 @@
- dirname: 2024-11-09-11-09-15--Qwen2.5-Coder-32B-Instruct
test_cases: 133
model: "HuggingFace via GLHF: BF16"
released: 2024-11-12
edit_format: diff
commit_hash: ec9982a
pass_rate_1: 59.4
pass_rate_2: 71.4
percent_cases_well_formed: 94.7
error_outputs: 17
num_malformed_responses: 17
num_with_malformed_responses: 7
user_asks: 1
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
command: aider --model openai/hf:Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://glhf.chat/api/openai/v1
date: 2024-11-09
versions: 0.59.2.dev
seconds_per_case: 22.5
total_cost: 0.0000
- dirname: 2024-11-22-18-56-13--ollama-qwen2.5-coder:32b-instruct-fp16
test_cases: 132
model: "Ollama: fp16"
edit_format: diff
commit_hash: f06452c-dirty, 6a0a97c-dirty, 4e9ae16-dirty, 5506d0f-dirty
pass_rate_1: 58.3
pass_rate_2: 71.4
percent_cases_well_formed: 90.2
error_outputs: 27
num_malformed_responses: 26
num_with_malformed_responses: 13
user_asks: 2
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 0
command: aider --model ollama/qwen2.5-coder:32b-instruct-fp16
date: 2024-11-22
versions: 0.64.2.dev
seconds_per_case: 119.6
total_cost: 0.0000
- dirname: 2024-11-22-14-53-26--hyperbolic-qwen25coder32binstruct
test_cases: 133
model: "Hyperbolic: BF16"
edit_format: diff
commit_hash: f9ef161, 17aef7b-dirty
pass_rate_1: 57.9
pass_rate_2: 69.2
percent_cases_well_formed: 91.7
error_outputs: 30
num_malformed_responses: 29
num_with_malformed_responses: 11
user_asks: 9
lazy_comments: 0
syntax_errors: 4
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
command: aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://api.hyperbolic.xyz/v1/
date: 2024-11-22
versions: 0.64.2.dev
seconds_per_case: 33.2
total_cost: 0.0000
- dirname: 2024-11-22-17-53-35--qwen25-coder-32b-Instruct-4bit
test_cases: 133
model: "mlx-community: 4bit"
edit_format: diff
commit_hash: a16dcab-dirty
pass_rate_1: 60.2
pass_rate_2: 72.2
percent_cases_well_formed: 88.7
error_outputs: 31
num_malformed_responses: 30
num_with_malformed_responses: 15
user_asks: 6
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 1
test_timeouts: 0
command: aider --model openai/mlx-community/Qwen2.5-Coder-32B-Instruct-4bit
date: 2024-11-23
versions: 0.64.2.dev
seconds_per_case: 53.4
total_cost: 0.0000
- dirname: 2024-11-23-15-07-20--qwen25-coder-32b-Instruct-8bit
test_cases: 133
model: "mlx-community: 8bit"
edit_format: diff
commit_hash: a16dcab-dirty
pass_rate_1: 59.4
pass_rate_2: 72.2
percent_cases_well_formed: 92.5
error_outputs: 20
num_malformed_responses: 15
num_with_malformed_responses: 10
user_asks: 7
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 5
test_timeouts: 2
command: aider --model openai/mlx-community/Qwen2.5-Coder-32B-Instruct-8bit
date: 2024-11-23
versions: 0.64.2.dev
seconds_per_case: 98.4
total_cost: 0.0000
- dirname: 2024-11-24-22-18-18--or-all-or-fixed-blank-messages2
test_cases: 133
model: "OpenRouter: multiple"
edit_format: diff
commit_hash: 0c59d32
pass_rate_1: 57.1
pass_rate_2: 67.7
percent_cases_well_formed: 95.5
error_outputs: 56
num_malformed_responses: 10
num_with_malformed_responses: 6
user_asks: 14
lazy_comments: 0
syntax_errors: 6
indentation_errors: 0
exhausted_context_windows: 3
test_timeouts: 1
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 21.2
total_cost: 0.1420
- dirname: 2024-11-23-21-08-53--ollama-qwen2.5-coder:32b-instruct-q4_K_M-8kctx
test_cases: 133
model: "Ollama: q4_K_M"
edit_format: diff
commit_hash: baa1335-dirty, e63df83-dirty, ff8c1aa-dirty
pass_rate_1: 54.9
pass_rate_2: 66.9
percent_cases_well_formed: 94.0
error_outputs: 21
num_malformed_responses: 21
num_with_malformed_responses: 8
user_asks: 5
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
command: aider --model ollama/qwen2.5-coder:32b-instruct-q4_K_M
date: 2024-11-23
versions: 0.64.2.dev
seconds_per_case: 35.7
total_cost: 0.0000
- dirname: 2024-11-24-02-23-32--deepinfra-qwen-diff
test_cases: 133
model: "Deepinfra: BF16"
edit_format: diff
commit_hash: bb78e2f
pass_rate_1: 58.6
pass_rate_2: 72.2
percent_cases_well_formed: 94.7
error_outputs: 15
num_malformed_responses: 13
num_with_malformed_responses: 7
user_asks: 3
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 2
test_timeouts: 3
command: aider --model deepinfra/Qwen/Qwen2.5-Coder-32B-Instruct
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 17.5
total_cost: 0.0000
- dirname: 2024-11-24-04-12-58--fireworks-qwen-diff
test_cases: 133
model: "Fireworks: unknown"
edit_format: diff
commit_hash: 757eac0
pass_rate_1: 57.9
pass_rate_2: 72.2
percent_cases_well_formed: 94.0
error_outputs: 23
num_malformed_responses: 19
num_with_malformed_responses: 8
user_asks: 8
lazy_comments: 0
syntax_errors: 6
indentation_errors: 0
exhausted_context_windows: 4
test_timeouts: 1
command: aider --model fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 10.4
total_cost: 0.5759
- dirname: 2024-11-24-02-04-59--ollama-qwen2.5-coder:32b-instruct-q2_K-8kctx
test_cases: 133
model: "Ollama: q2_K"
edit_format: diff
commit_hash: 757eac0, bb78e2f, 8d0ba40-dirty, 1d09e96
pass_rate_1: 48.9
pass_rate_2: 61.7
percent_cases_well_formed: 91.7
error_outputs: 32
num_malformed_responses: 32
num_with_malformed_responses: 11
user_asks: 8
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 1
command: aider --model ollama/qwen2.5-coder:32b-instruct-q2_K
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 97.8
total_cost: 0.0000
- dirname: 2024-11-24-14-56-49--qwen25-32b-or-fireworks
test_cases: 133
model: "Fireworks via OpenRouter: unknown"
edit_format: diff
commit_hash: c2f184f
pass_rate_1: 55.6
pass_rate_2: 67.7
percent_cases_well_formed: 94.0
error_outputs: 39
num_malformed_responses: 24
num_with_malformed_responses: 8
user_asks: 13
lazy_comments: 0
syntax_errors: 1
indentation_errors: 1
exhausted_context_windows: 7
test_timeouts: 4
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 16.1
total_cost: 0.1391
- dirname: 2024-11-24-22-03-19--or-hyperbolic-or-fixed-blank-messages2
test_cases: 133
model: "Hyperbolic via OpenRouter: BF16"
edit_format: diff
commit_hash: 0c59d32
pass_rate_1: 55.6
pass_rate_2: 68.4
percent_cases_well_formed: 89.5
error_outputs: 28
num_malformed_responses: 24
num_with_malformed_responses: 14
user_asks: 29
lazy_comments: 0
syntax_errors: 1
indentation_errors: 0
exhausted_context_windows: 4
test_timeouts: 1
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 41.5
total_cost: 0.1402
- dirname: 2024-11-24-15-00-50--qwen25-32b-or-deepinfra
test_cases: 133
model: "Deepinfra via OpenRouter: BF16"
edit_format: diff
commit_hash: c2f184f
pass_rate_1: 57.1
pass_rate_2: 69.9
percent_cases_well_formed: 89.5
error_outputs: 35
num_malformed_responses: 31
num_with_malformed_responses: 14
user_asks: 11
lazy_comments: 0
syntax_errors: 1
indentation_errors: 1
exhausted_context_windows: 4
test_timeouts: 1
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 28.5
total_cost: 0.1390

View File

@@ -0,0 +1,97 @@
document.addEventListener('DOMContentLoaded', function () {
var ctx = document.getElementById('editChart').getContext('2d');
const HIGHTLIGHT_MODEL = 'no no no no';
var leaderboardData = {
labels: [],
datasets: [{
label: 'Percent completed correctly',
data: [],
backgroundColor: function(context) {
const label = context.chart.data.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 }}
});
{% 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('edit-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_2);
}
});
leaderboardChart.update();
}
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: {
scales: {
y: {
beginAtZero: true
}
}
}
});
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');
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_2);
} else {
rows[i].style.display = 'none';
}
}
leaderboardChart.update();
});
});

View File

View File

@@ -1,5 +1,15 @@
You can send long, multi-line messages in the chat in a few ways:
- Paste a multi-line message directly into the chat.
- Enter `{` alone on the first line to start a multiline message and `}` alone on the last line to end it.
- Or, start with `{tag` (where "tag" is any sequence of letters/numbers) and end with `tag}`. This is useful when you need to include closing braces `}` in your message.
- 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.
Example with a tag:
```
{python
def hello():
print("Hello}") # Note: contains a brace
python}
```

View File

@@ -0,0 +1,95 @@
document.addEventListener('DOMContentLoaded', function () {
var ctx = document.getElementById('quantChart').getContext('2d');
var allData = [];
{% for row in site.data.quant %}
allData.push({
model: '{{ row.model }}',
pass_rate_2: {{ row.pass_rate_2 }}
});
{% endfor %}
// Sort data by pass_rate_2 in descending order
allData.sort((a, b) => b.pass_rate_2 - a.pass_rate_2);
var chart;
function updateChart(filterText) {
var filteredData = allData.filter(row =>
row.model.toLowerCase().includes(filterText.toLowerCase())
);
var chartData = {
labels: filteredData.map(row => row.model),
datasets: [{
label: 'Percent completed correctly',
data: filteredData.map(row => row.pass_rate_2),
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
};
if (chart) {
chart.data = chartData;
chart.update();
} else {
chart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
plugins: {
legend: {
display: false
},
title: {
display: true,
text: 'Aider code editing benchmark',
font: {
size: 16
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Percent completed correctly',
font: {
size: 14
}
},
ticks: {
font: {
size: 16
}
}
},
x: {
ticks: {
font: {
size: 16
}
},
title: {
display: true,
text: 'Provider: quantization',
font: {
size: 14
}
}
}
}
}
});
}
}
// Initial chart render
updateChart('');
// Connect search input to chart filtering
document.getElementById('quantSearchInput').addEventListener('keyup', function() {
updateChart(this.value);
});
});

View File

@@ -0,0 +1,90 @@
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

@@ -0,0 +1,169 @@
---
title: Details matter with open source models
excerpt: Open source LLMs are becoming very powerful, but pay attention to how you (or your provider) are serving the model. It can affect code editing skill.
highlight_image: /assets/quantization.jpg
draft: false
nav_exclude: true
---
{% if page.date %}
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
{% endif %}
# Details matter with open source models
{: .no_toc }
Open source models like Qwen 2.5 32B Instruct are performing very well on
aider's code editing benchmark, rivaling closed source frontier models.
But pay attention to how your model is being served and quantized,
as it can impact code editing skill.
Open source models are often available at a variety of quantizations,
and can be served with different token limits.
These details matter when working with code.
The graph and table below compares different versions of the Qwen 2.5 Coder 32B Instruct model,
served both locally and from a variety of cloud providers.
- The [HuggingFace BF16 weights](https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct) served via [glhf.chat](https://glhf.chat).
- [4bit and 8bit quants for mlx](https://t.co/cwX3DYX35D).
- The results from [OpenRouter's mix of providers](https://openrouter.ai/qwen/qwen-2.5-coder-32b-instruct/providers) which serve the model with different levels of quantization.
- Results from individual providers served via OpenRouter and directly to their own APIs.
- Ollama locally serving different quantizations from the [Ollama model library](https://ollama.com/library/qwen2.5-coder:32b-instruct-q4_K_M).
The best versions of the model rival GPT-4o, while the worst performer
is more like the older GPT-4 Turbo.
Suboptimal choices in quantization and token limits can
easily produce far worse results.
This benchmarking effort highlighted a number of pitfalls and details which
can have a significant impact on the model's ability to correctly edit code:
- Quantization -- Open source models are often available at dozens of different quantizations.
- Context window -- Cloud providers can decide how large a context window to accept,
and they often choose differently. Ollama defaults to a tiny 2k context window,
and silently discards data that exceeds it.
- Output token limits -- Open source models are often served with wildly
differing output token limits. This has a direct impact on how much code the
model can write or edit in a response.
- Buggy cloud providers -- Between Qwen and DeepSeep, there were
multiple cloud providers with broken or buggy API endpoints that seemed
to be returning result different from expected based on the advertised
quantization and context sizes.
### Sections
{: .no_toc }
- TOC
{:toc}
## Benchmark results
<canvas id="quantChart" width="800" height="600" style="margin: 20px 0"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% include quant-chart.js %}
</script>
<input type="text" id="quantSearchInput" 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 quant_sorted = site.data.quant | sort: 'pass_rate_2' | reverse %}
{% for row in quant_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>
<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>
<script>
document.getElementById('quantSearchInput').addEventListener('keyup', function() {
var input = this.value.toLowerCase();
var rows = document.querySelectorAll('tbody tr');
rows.forEach(function(row) {
var text = row.textContent.toLowerCase();
if(text.includes(input)) {
row.style.display = '';
row.classList.add('selected');
} else {
row.style.display = 'none';
row.classList.remove('selected');
}
});
});
</script>
## Setting Ollama's context window size
[Ollama uses a 2k context window by default](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-specify-the-context-window-size),
which is very small for working with aider.
Unlike most other LLM servers, Ollama does not throw an error if you submit
a request that exceeds the context window.
Instead, it just silently truncates the request by discarding the "oldest" messages
in the chat to make it fit within the context window.
All of the Ollama results above were collected with at least an 8k context window, which
is large enough to attempt all the coding problems in the benchmark.
Aider sets Ollama's context window to 8k by default.
You can change the Ollama server's context window with a
[`.aider.model.settings.yml` file](https://aider.chat/docs/config/adv-model-settings.html#model-settings)
like this:
```
- name: ollama/qwen2.5-coder:32b-instruct-fp16
extra_params:
num_ctx: 8192
```
## Choosing providers with OpenRouter
OpenRouter allows you to ignore specific providers in your
[preferences](https://openrouter.ai/settings/preferences).
This can be used to limit your OpenRouter requests to be
served by only your preferred providers.
## Notes
This article went through many revisions as I received feedback from
numerous members of the community.
Here are some of the noteworthy learnings and changes:
- The first version of this article included incorrect Ollama models.
- Earlier Ollama results used the too small default 2k context window,
artificially harming the benchmark results.
- The benchmark results appear to have uncovered a problem in the way
OpenRouter was communicating with Hyperbolic.
They fixed the issue 11/24/24, shortly after it was pointed out.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 103 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -86,6 +86,14 @@
## Specify a file with context window and costs for unknown models
#model-metadata-file: .aider.model.metadata.json
## Add a model alias (can be used multiple times)
#alias: xxx
## Specify multiple values like this:
#alias:
# - xxx
# - yyy
# - zzz
## Verify the SSL cert when connecting to models (default: True)
#verify-ssl: true
@@ -271,8 +279,8 @@
############
# Analytics:
## Enable/disable analytics for one session (default: False)
#analytics: false
## Enable/disable analytics for current session (default: random)
#analytics: xxx
## Specify a file to log analytics events
#analytics-log: xxx
@@ -314,6 +322,9 @@
## Check for new aider versions on launch
#check-update: true
## Show release notes on first run of new version (default: None, ask user)
#show-release-notes: xxx
## Install the latest version from the main branch
#install-main-branch: false
@@ -365,6 +376,12 @@
## Enable/disable fancy input with history and completion (default: True)
#fancy-input: true
## Enable/disable detection and offering to add URLs to chat (default: True)
#detect-urls: true
## Specify which editor to use for the /editor command
#editor: xxx
#################
# Voice Settings:

View File

@@ -90,6 +90,9 @@
## Specify a file with context window and costs for unknown models
#AIDER_MODEL_METADATA_FILE=.aider.model.metadata.json
## Add a model alias (can be used multiple times)
#AIDER_ALIAS=
## Verify the SSL cert when connecting to models (default: True)
#AIDER_VERIFY_SSL=true
@@ -270,8 +273,8 @@
############
# Analytics:
## Enable/disable analytics for one session (default: False)
#AIDER_ANALYTICS=false
## Enable/disable analytics for current session (default: random)
#AIDER_ANALYTICS=
## Specify a file to log analytics events
#AIDER_ANALYTICS_LOG=
@@ -300,6 +303,9 @@
## Check for new aider versions on launch
#AIDER_CHECK_UPDATE=true
## Show release notes on first run of new version (default: None, ask user)
#AIDER_SHOW_RELEASE_NOTES=
## Install the latest version from the main branch
#AIDER_INSTALL_MAIN_BRANCH=false
@@ -348,6 +354,12 @@
## Enable/disable fancy input with history and completion (default: True)
#AIDER_FANCY_INPUT=true
## Enable/disable detection and offering to add URLs to chat (default: True)
#AIDER_DETECT_URLS=true
## Specify which editor to use for the /editor command
#AIDER_EDITOR=
#################
# Voice Settings:

View File

@@ -11,6 +11,13 @@ description: Configuring advanced settings for LLMs.
In most cases, you can safely ignore aider's warning about unknown context
window size and model costs.
{: .note }
Aider never *enforces* token limits, it only *reports* token limit errors
from the API provider.
You probably don't need to
configure aider with the proper token limits
for unusual models.
But, you can register context window limits and costs for models that aren't known
to aider. Create a `.aider.model.metadata.json` file in one of these locations:
@@ -55,8 +62,10 @@ These model settings are pre-configured for most popular models.
But it can sometimes be helpful to override them or add settings for
a model that aider doesn't know about.
To do that,
create a `.aider.model.settings.yml` file in one of these locations:
### Configuration file locations
You can override or add settings for any model by creating a `.aider.model.settings.yml` file in one of these locations:
- Your home directory.
- The root if your git repo.
@@ -66,9 +75,31 @@ create a `.aider.model.settings.yml` file in one of these locations:
If the files above exist, they will be loaded in that order.
Files loaded last will take priority.
The yaml file should be a a list of dictionary objects for each model.
For example, below are all the pre-configured model settings
to give a sense for the settings which are supported.
The yaml file should be a list of dictionary objects for each model.
### Global extra params
You can use the special model name `aider/extra_params` to define
`extra_params` that will be passed to `litellm.completion()` for all models.
Only the `extra_params` dict is used from this special model name.
For example:
```yaml
- name: aider/extra_params
extra_params:
extra_headers:
Custom-Header: value
max_tokens: 8192
```
These settings will be merged with any model-specific settings, with the
`aider/extra_params` settings taking precedence for any direct conflicts.
### Example model settings
Below are all the pre-configured model settings to give a sense for the settings which are supported.
You can also look at the `ModelSettings` class in
[models.py](https://github.com/Aider-AI/aider/blob/main/aider/models.py)
@@ -241,6 +272,38 @@ cog.out("```\n")
use_system_prompt: true
use_temperature: true
weak_model_name: gpt-4o-mini
- 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: true
name: gpt-4o-2024-11-20
reminder: sys
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: gpt-4o-mini
- 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: true
name: openai/gpt-4o-2024-11-20
reminder: sys
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: gpt-4o-mini
- cache_control: false
caches_by_default: false
edit_format: diff
@@ -1057,7 +1120,7 @@ cog.out("```\n")
name: openai/o1-mini
reminder: user
send_undo_reply: false
streaming: false
streaming: true
use_repo_map: true
use_system_prompt: false
use_temperature: false
@@ -1073,7 +1136,7 @@ cog.out("```\n")
name: azure/o1-mini
reminder: user
send_undo_reply: false
streaming: false
streaming: true
use_repo_map: true
use_system_prompt: false
use_temperature: false
@@ -1089,7 +1152,7 @@ cog.out("```\n")
name: o1-mini
reminder: user
send_undo_reply: false
streaming: false
streaming: true
use_repo_map: true
use_system_prompt: false
use_temperature: false
@@ -1105,7 +1168,7 @@ cog.out("```\n")
name: openai/o1-preview
reminder: user
send_undo_reply: false
streaming: false
streaming: true
use_repo_map: true
use_system_prompt: false
use_temperature: false
@@ -1121,7 +1184,7 @@ cog.out("```\n")
name: azure/o1-preview
reminder: user
send_undo_reply: false
streaming: false
streaming: true
use_repo_map: true
use_system_prompt: false
use_temperature: false
@@ -1137,7 +1200,7 @@ cog.out("```\n")
name: o1-preview
reminder: user
send_undo_reply: false
streaming: false
streaming: true
use_repo_map: true
use_system_prompt: false
use_temperature: false

View File

@@ -142,6 +142,14 @@ cog.outl("```")
## Specify a file with context window and costs for unknown models
#model-metadata-file: .aider.model.metadata.json
## Add a model alias (can be used multiple times)
#alias: xxx
## Specify multiple values like this:
#alias:
# - xxx
# - yyy
# - zzz
## Verify the SSL cert when connecting to models (default: True)
#verify-ssl: true
@@ -327,8 +335,8 @@ cog.outl("```")
############
# Analytics:
## Enable/disable analytics for one session (default: False)
#analytics: false
## Enable/disable analytics for current session (default: random)
#analytics: xxx
## Specify a file to log analytics events
#analytics-log: xxx
@@ -370,6 +378,9 @@ cog.outl("```")
## Check for new aider versions on launch
#check-update: true
## Show release notes on first run of new version (default: None, ask user)
#show-release-notes: xxx
## Install the latest version from the main branch
#install-main-branch: false
@@ -421,6 +432,12 @@ cog.outl("```")
## Enable/disable fancy input with history and completion (default: True)
#fancy-input: true
## Enable/disable detection and offering to add URLs to chat (default: True)
#detect-urls: true
## Specify which editor to use for the /editor command
#editor: xxx
#################
# Voice Settings:

View File

@@ -132,6 +132,9 @@ cog.outl("```")
## Specify a file with context window and costs for unknown models
#AIDER_MODEL_METADATA_FILE=.aider.model.metadata.json
## Add a model alias (can be used multiple times)
#AIDER_ALIAS=
## Verify the SSL cert when connecting to models (default: True)
#AIDER_VERIFY_SSL=true
@@ -312,8 +315,8 @@ cog.outl("```")
############
# Analytics:
## Enable/disable analytics for one session (default: False)
#AIDER_ANALYTICS=false
## Enable/disable analytics for current session (default: random)
#AIDER_ANALYTICS=
## Specify a file to log analytics events
#AIDER_ANALYTICS_LOG=
@@ -342,6 +345,9 @@ cog.outl("```")
## Check for new aider versions on launch
#AIDER_CHECK_UPDATE=true
## Show release notes on first run of new version (default: None, ask user)
#AIDER_SHOW_RELEASE_NOTES=
## Install the latest version from the main branch
#AIDER_INSTALL_MAIN_BRANCH=false
@@ -390,6 +396,12 @@ cog.outl("```")
## Enable/disable fancy input with history and completion (default: True)
#AIDER_FANCY_INPUT=true
## Enable/disable detection and offering to add URLs to chat (default: True)
#AIDER_DETECT_URLS=true
## Specify which editor to use for the /editor command
#AIDER_EDITOR=
#################
# Voice Settings:

View File

@@ -0,0 +1,127 @@
---
parent: Configuration
nav_order: 15
description: How to configure a custom editor for aider's /editor command
---
# Editor configuration
Aider allows you to configure your preferred text editor for use with the `/editor` command. The editor must be capable of running in "blocking mode", meaning the command line will wait until you close the editor before proceeding.
## Using `--editor`
You can specify the text editor with the `--editor` switch or using
`editor:` in aider's
[yaml config file](https://aider.chat/docs/config/aider_conf.html).
## Environment variables
Aider checks the following environment variables in order to determine which editor to use:
1. `AIDER_EDITOR`
2. `VISUAL`
3. `EDITOR`
## Default behavior
If no editor is configured, aider will use these platform-specific defaults:
- Windows: `notepad`
- macOS: `vim`
- Linux/Unix: `vi`
## Using a custom editor
You can set your preferred editor in your shell's configuration file (e.g., `.bashrc`, `.zshrc`):
```bash
export AIDER_EDITOR=vim
```
## Popular Editors by Platform
### macOS
1. **vim**
```bash
export AIDER_EDITOR=vim
```
2. **Emacs**
```bash
export AIDER_EDITOR=emacs
```
3. **VSCode**
```bash
export AIDER_EDITOR="code --wait"
```
4. **Sublime Text**
```bash
export AIDER_EDITOR="subl --wait"
```
5. **BBEdit**
```bash
export AIDER_EDITOR="bbedit --wait"
```
### Linux
1. **vim**
```bash
export AIDER_EDITOR=vim
```
2. **Emacs**
```bash
export AIDER_EDITOR=emacs
```
3. **nano**
```bash
export AIDER_EDITOR=nano
```
4. **VSCode**
```bash
export AIDER_EDITOR="code --wait"
```
5. **Sublime Text**
```bash
export AIDER_EDITOR="subl --wait"
```
### Windows
1. **Notepad**
```bat
set AIDER_EDITOR=notepad
```
2. **VSCode**
```bat
set AIDER_EDITOR="code --wait"
```
3. **Notepad++**
```bat
set AIDER_EDITOR="notepad++ -multiInst -notabbar -nosession -noPlugin -waitForClose"
```
## Editor command arguments
Some editors require specific command-line arguments to operate in blocking mode. The `--wait` flag (or equivalent) is commonly used to make the editor block until the file is closed.
## Troubleshooting
If you encounter issues with your editor not blocking (returning to the prompt immediately), verify that:
1. Your editor supports blocking mode
2. You've included the necessary command-line arguments for blocking mode
3. The editor command is properly quoted if it contains spaces or special characters, e.g.:
```bash
export AIDER_EDITOR="code --wait"
```

View File

@@ -0,0 +1,72 @@
---
parent: Configuration
nav_order: 1000
description: Assign convenient short names to models.
---
# Model Aliases
Model aliases allow you to create shorthand names for models you frequently use. This is particularly useful for models with long names or when you want to standardize model usage across your team.
## Command Line Usage
You can define aliases when launching aider using the `--alias` option:
```bash
aider --alias "fast:gpt-3.5-turbo" --alias "smart:gpt-4"
```
Multiple aliases can be defined by using the `--alias` option multiple times. Each alias definition should be in the format `alias:model-name`.
## Configuration File
You can also define aliases in your [`.aider.conf.yml` file](https://aider.chat/docs/config/aider_conf.html):
```yaml
alias:
- "fast:gpt-3.5-turbo"
- "smart:gpt-4"
- "hacker:claude-3-sonnet-20240229"
```
## Using Aliases
Once defined, you can use the alias instead of the full model name:
```bash
aider --model fast # Uses gpt-3.5-turbo
aider --model smart # Uses gpt-4
```
## Built-in Aliases
Aider includes some built-in aliases for convenience:
<!--[[[cog
import cog
from aider.models import MODEL_ALIASES
for alias, model in sorted(MODEL_ALIASES.items()):
cog.outl(f"- `{alias}`: {model}")
]]]-->
- `3`: gpt-3.5-turbo
- `35-turbo`: gpt-3.5-turbo
- `35turbo`: gpt-3.5-turbo
- `4`: gpt-4-0613
- `4-turbo`: gpt-4-1106-preview
- `4o`: gpt-4o-2024-08-06
- `deepseek`: deepseek/deepseek-coder
- `haiku`: claude-3-haiku-20241022
- `opus`: claude-3-opus-20240229
- `sonnet`: claude-3-sonnet-20241022
<!--[[[end]]]-->
## Priority
If the same alias is defined in multiple places, the priority is:
1. Command line aliases (highest priority)
2. Configuration file aliases
3. Built-in aliases (lowest priority)
This allows you to override built-in aliases with your own preferences.

View File

@@ -32,9 +32,9 @@ usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
[--openai-api-type] [--openai-api-version]
[--openai-api-deployment-id] [--openai-organization-id]
[--model-settings-file] [--model-metadata-file]
[--verify-ssl | --no-verify-ssl] [--edit-format]
[--architect] [--weak-model] [--editor-model]
[--editor-edit-format]
[--alias] [--verify-ssl | --no-verify-ssl]
[--edit-format] [--architect] [--weak-model]
[--editor-model] [--editor-edit-format]
[--show-model-warnings | --no-show-model-warnings]
[--max-chat-history-tokens] [--env-file]
[--cache-prompts | --no-cache-prompts]
@@ -66,14 +66,16 @@ usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
[--analytics-disable] [--file] [--read] [--vim]
[--chat-language] [--version] [--just-check-update]
[--check-update | --no-check-update]
[--show-release-notes | --no-show-release-notes]
[--install-main-branch] [--upgrade] [--apply]
[--apply-clipboard-edits] [--yes-always] [-v]
[--show-repo-map] [--show-prompts] [--exit] [--message]
[--message-file] [--load] [--encoding] [-c]
[--gui | --no-gui | --browser | --no-browser]
[--suggest-shell-commands | --no-suggest-shell-commands]
[--fancy-input | --no-fancy-input] [--voice-format]
[--voice-language]
[--fancy-input | --no-fancy-input]
[--detect-urls | --no-detect-urls] [--editor]
[--voice-format] [--voice-language]
```
@@ -190,6 +192,10 @@ Specify a file with context window and costs for unknown models
Default: .aider.model.metadata.json
Environment variable: `AIDER_MODEL_METADATA_FILE`
### `--alias ALIAS:MODEL`
Add a model alias (can be used multiple times)
Environment variable: `AIDER_ALIAS`
### `--verify-ssl`
Verify the SSL cert when connecting to models (default: True)
Default: True
@@ -510,8 +516,7 @@ Environment variable: `AIDER_TEST`
## Analytics:
### `--analytics`
Enable/disable analytics for one session (default: False)
Default: False
Enable/disable analytics for current session (default: random)
Environment variable: `AIDER_ANALYTICS`
Aliases:
- `--analytics`
@@ -561,6 +566,13 @@ Aliases:
- `--check-update`
- `--no-check-update`
### `--show-release-notes`
Show release notes on first run of new version (default: None, ask user)
Environment variable: `AIDER_SHOW_RELEASE_NOTES`
Aliases:
- `--show-release-notes`
- `--no-show-release-notes`
### `--install-main-branch`
Install the latest version from the main branch
Default: False
@@ -666,6 +678,18 @@ Aliases:
- `--fancy-input`
- `--no-fancy-input`
### `--detect-urls`
Enable/disable detection and offering to add URLs to chat (default: True)
Default: True
Environment variable: `AIDER_DETECT_URLS`
Aliases:
- `--detect-urls`
- `--no-detect-urls`
### `--editor VALUE`
Specify which editor to use for the /editor command
Environment variable: `AIDER_EDITOR`
## Voice Settings:
### `--voice-format VOICE_FORMAT`

View File

@@ -60,6 +60,23 @@ directory you start in.
You can also create a `.aiderignore` file to tell aider
to ignore parts of the repo that aren't relevant to your task.
This file conforms to `.gitignore` syntax and conventions.
For example, to focus only on specific directories in a monorepo,
you could create a `.aiderignore` file with:
```
# Ignore everything
/*
# Allow specific directories and their contents
!foo/
!bar/
!baz/
# Allow nested files under these directories
!foo/**
!bar/**
!baz/**
```
You can use `--aiderignore <filename>` to name a specific file
to use for ignore patterns.
@@ -150,7 +167,6 @@ python -m aider
## Can I change the system prompts that aider uses?
Aider is set up to support different system prompts and edit formats
@@ -191,6 +207,16 @@ 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).
## How are the "aider wrote xx% of code" stats computed?
[Aider is tightly integrated with git](/docs/git.html) so all
of aider's code changes are committed to the repo with proper attribution.
The
[stats are computed](https://github.com/Aider-AI/aider/blob/main/scripts/blame.py)
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.
## Can I share my aider chat transcript?
Yes, you can now share aider chat logs in a pretty way.
@@ -213,6 +239,15 @@ This will give you a URL like this, which shows the chat history like you'd see
https://aider.chat/share/?mdurl=https://gist.github.com/Aider-AI/2087ab8b64034a078c0a209440ac8be0
```
## Can I edit files myself while aider is running?
Yes. Aider always reads the latest copy of files from the file
system when you send each message.
While you're waiting for aider's reply to complete, it's probably unwise to
edit files that you've added to the chat.
Your edits and aider's edits might conflict.
## What is Aider AI LLC?
Aider AI LLC is the company behind the aider AI coding tool.
@@ -222,11 +257,5 @@ under an
[Apache 2.0 license](https://github.com/Aider-AI/aider/blob/main/LICENSE.txt).
## Can I edit files myself while aider is running?
<div style="height:80vh"></div>
Yes. Aider always reads the latest copy of files from the file
system when you send each message.
While you're waiting for aider's reply to complete, it's probably unwise to
edit files that you've added to the chat.
Your edits and aider's edits might conflict.

View File

@@ -62,6 +62,7 @@ cog.out(get_supported_languages_md())
| cpp | .cc | ✓ | ✓ |
| cpp | .cpp | ✓ | ✓ |
| css | .css | | ✓ |
| dart | .dart | ✓ | ✓ |
| dockerfile | .dockerfile | | ✓ |
| dot | .dot | | ✓ |
| elisp | .el | ✓ | ✓ |

View File

@@ -31,6 +31,8 @@ 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>
@@ -58,81 +60,7 @@ The model also has to successfully apply all its changes to the source file with
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
var ctx = document.getElementById('editChart').getContext('2d');
const HIGHTLIGHT_MODEL = 'no no no no';
var leaderboardData = {
labels: [],
datasets: [{
label: 'Percent completed correctly',
data: [],
backgroundColor: function(context) {
const label = context.chart.data.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 }}
});
{% 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('edit-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_2);
}
});
leaderboardChart.update();
}
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: {
scales: {
y: {
beginAtZero: true
}
}
}
});
updateChart();
});
{% include edit-leaderboard.js %}
</script>
<style>
tr.selected {
@@ -158,6 +86,8 @@ 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>
@@ -185,74 +115,7 @@ Therefore, results are available for fewer models.
<canvas id="refacChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
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();
});
{% include refactor-leaderboard.js %}
</script>
@@ -318,6 +181,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.')}")
]]]-->
November 11, 2024.
November 24, 2024.
<!--[[[end]]]-->
</p>

View File

@@ -1,22 +0,0 @@
---
parent: Connecting to LLMs
nav_order: 850
---
# Editing 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](https://aider.chat/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.
If you would like to experiment with the more advanced formats, you can
use these switches: `--edit-format diff` or `--edit-format udiff`.

View File

@@ -0,0 +1,26 @@
---
parent: Connecting to LLMs
nav_order: 400
---
# LM Studio
To use LM Studio:
```
python -m pip install -U aider-chat
export LM_STUDIO_API_KEY=<key> # Mac/Linux
setx LM_STUDIO_API_KEY <key> # Windows, restart shell after setx
export LM_STUDIO_API_BASE=<url> # Mac/Linux
setx LM_STUDIO_API_BASE <url> # Windows, restart shell after setx
aider --model lm_studio/<your-model-name>
```
See the [model warnings](warnings.html)
section for information on warnings which will occur
when working with models that aider is not familiar with.

View File

@@ -20,24 +20,49 @@ python -m pip install -U aider-chat
export OLLAMA_API_BASE=http://127.0.0.1:11434 # Mac/Linux
setx OLLAMA_API_BASE http://127.0.0.1:11434 # Windows, restart shell after setx
aider --model ollama/<model>
aider --model ollama_chat/<model>
```
In particular, `llama3:70b` works well with aider:
{: .note }
Using `ollama_chat/` is recommended over `ollama/`.
```
ollama pull llama3:70b
ollama serve
# In another terminal window...
export OLLAMA_API_BASE=http://127.0.0.1:11434 # Mac/Linux
setx OLLAMA_API_BASE http://127.0.0.1:11434 # Windows, restart shell after setx
aider --model ollama/llama3:70b
```
See the [model warnings](warnings.html)
section for information on warnings which will occur
when working with models that aider is not familiar with.
## API Key
If you are using an ollama that requires an API key you can set `OLLAMA_API_KEY`:
```
export OLLAMA_API_KEY=<api-key> # Mac/Linux
setx OLLAMA_API_KEY <api-key> # Windows, restart shell after setx
```
## Setting the context window size
[Ollama uses a 2k context window by default](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-specify-the-context-window-size),
which is very small for working with aider.
Aider sets Ollama's context window to 8k by default.
If you would like
a larger context window
you can use a
[`.aider.model.settings.yml` file](https://aider.chat/docs/config/adv-model-settings.html#model-settings)
like this:
```
- name: ollama/qwen2.5-coder:32b-instruct-fp16
extra_params:
num_ctx: 8192
```
Unlike most other LLM servers, Ollama does not throw an error if you submit
a request that exceeds the context window.
Instead, it just silently truncates the request by discarding the "oldest" messages
in the chat to make it fit within the context window.
So if your context window is too small, you won't get an error.
Aider will probably just fail to work well and experience
a lot of
[file editing problems](https://aider.chat/docs/troubleshooting/edit-errors.html).

View File

@@ -0,0 +1,24 @@
---
parent: Connecting to LLMs
nav_order: 400
---
# xAI
You'll need a [xAI API key](https://console.x.ai.).
To use xAI:
```
python -m pip install -U aider-chat
export XAI_API_KEY=<key> # Mac/Linux
setx XAI_API_KEY <key> # Windows, restart shell after setx
aider --model xai/grok-beta
# List models available from xAI
aider --list-models xai/
```

View File

@@ -31,7 +31,7 @@ features and commands are most used.
It also helps uncover bugs that users are experiencing, so that they can be fixed
in upcoming releases.
## Enabling & disabling analytics
## Disabling analytics
You can opt out of analytics forever by running this command one time:
@@ -39,10 +39,27 @@ You can opt out of analytics forever by running this command one time:
aider --analytics-disable
```
To enable analytics for a single session, you can run aider with `--analytics`.
This will *not* have any effect if you have permanently disabled analytics with the previous command.
## Enabling analytics
The first time, you will need to agree to opt-in.
The `--[no-]analytics` switch controls whether analytics are enabled for the
current session:
- `--analytics` will turn on analytics for the current session.
This will *not* have any effect if you have permanently disabled analytics
with `--analytics-disable`.
If this is the first time you have enabled analytics, aider
will confirm you wish to opt-in to analytics.
- `--no-analytics` will turn off analytics for the current session.
- By default, if you don't provide `--analytics` or `--no-analytics`,
aider will enable analytics for a random subset of users.
This will never happen if you have permanently disabled analytics
with `--analytics-disable`.
Randomly selected users will be asked if they wish to opt-in to analytics.
## Opting in
The first time analytics are enabled, you will need to agree to opt-in.
```
aider --analytics
@@ -53,13 +70,8 @@ For more info: https://aider.chat/docs/more/analytics.html
Allow collection of anonymous analytics to help improve aider? (Y)es/(N)o [Yes]:
```
If you've added `analytics: true` to your
[yaml config file](/docs/config/aider_conf.html),
you can disable analytics for a single session, you can run:
If you say "no", analytics will be permanently disabled.
```
aider --no-analytics
```
## Details about data being collected

View File

@@ -57,7 +57,6 @@ cog.out(model_list)
]]]-->
- anthropic.claude-3-5-haiku-20241022-v1:0
- anthropic.claude-3-5-sonnet-20241022-v2:0
- anthropic/claude-3-5-sonnet-20241022
- claude-3-5-haiku-20241022
- claude-3-5-sonnet-20240620
- claude-3-5-sonnet-20241022
@@ -91,11 +90,17 @@ cog.out(model_list)
- openrouter/anthropic/claude-3.5-sonnet
- us.anthropic.claude-3-5-haiku-20241022-v1:0
- us.anthropic.claude-3-5-sonnet-20241022-v2:0
- vertex_ai/claude-3-5-haiku
- vertex_ai/claude-3-5-haiku@20241022
- vertex_ai/claude-3-5-sonnet
- vertex_ai/claude-3-5-sonnet-v2
- vertex_ai/claude-3-5-sonnet-v2@20241022
- vertex_ai/claude-3-5-sonnet@20240620
- vertex_ai/claude-3-haiku
- vertex_ai/claude-3-haiku@20240307
- vertex_ai/claude-3-opus
- vertex_ai/claude-3-opus@20240229
- vertex_ai/claude-3-sonnet
- vertex_ai/claude-3-sonnet@20240229
<!--[[[end]]]-->

View File

@@ -95,3 +95,6 @@ io = InputOutput(yes=True)
coder = Coder.create(model=model, fnames=fnames, io=io)
```
{: .note }
The scripting API is not officially supported or documented and may
change without warning.

View File

@@ -19,31 +19,7 @@ LLM edits that are "almost" correctly formatted.
But sometimes the LLM just won't cooperate.
In these cases, here are some things you might try.
## Use a capable model
If possible try using GPT-4o, Claude 3.5 Sonnet or Claude 3 Opus,
as they are the strongest and most capable models.
Weaker models
are more prone to
disobeying the system prompt instructions.
Most local models are just barely capable of working with aider,
so editing errors are probably unavoidable.
Local models which have been quantized are even more likely to have problems
because they are not capable enough to follow aider's system prompts.
## Try the whole format
Run aider with `--edit-format whole` if the model is using a different edit format.
You can see which edit format it is using in the announce lines:
```
Aider v0.50.2-dev
Models: claude-3-5-sonnet-20240620 with ♾️ diff edit format
```
## Reduce distractions
## Don't add too many files
Many LLMs now have very large context windows,
but filling them with irrelevant code or conversation
@@ -55,6 +31,38 @@ Aider also sends the LLM a [map of your entire git repo](https://aider.chat/docs
- Use `/clear` to remove the conversation history, again to help the LLM focus.
- Use `/tokens` to see how many tokens you are using for each message.
## Use a more capable model
If possible try using GPT-4o, Claude 3.5 Sonnet or Claude 3 Opus,
as they are the strongest and most capable models.
Weaker models
are more prone to
disobeying the system prompt instructions.
Most local models are just barely capable of working with aider,
so editing errors are probably unavoidable.
## Local models: context window and quantization
Be especially careful about the
[Ollama context window](https://aider.chat/docs/llms/ollama.html#setting-the-context-window-size)
when working with local models.
It defaults to be very small and silently discards data if you exceed it.
Local models which have been quantized are more likely to have editing problems
because they are not capable enough to follow aider's system prompts.
## Try the whole edit format
Run aider with `--edit-format whole` if were using a different edit format.
You can see which edit format it is using in the announce lines:
```
Aider v0.50.2-dev
Models: claude-3-5-sonnet-20240620 with ♾️ diff edit format
```
## More help
{% include help.md %}

View File

@@ -33,6 +33,13 @@ To reduce output tokens:
For more info: https://aider.chat/docs/token-limits.html
```
{: .note }
Aider never *enforces* token limits, it only *reports* token limit errors
from the API provider.
You probably don't need to
[configure aider with the proper token limits](http://0.0.0.0:4000/docs/config/adv-model-settings.html#context-window-size-and-token-costs)
for unusual models.
## Input tokens & context window size
The most common problem is trying to send too much data to a

View File

@@ -3,7 +3,14 @@ parent: Usage
nav_order: 50
description: Control aider with in-chat commands like /add, /model, etc.
---
# In-chat commands
{: .no_toc }
- TOC
{:toc}
## Slash commands
Aider supports commands from within the chat, which all start with `/`.
@@ -24,6 +31,7 @@ cog.out(get_help_md())
| **/copy** | Copy the last assistant message to the clipboard |
| **/diff** | Display the diff of changes since the last message |
| **/drop** | Remove files from the chat session to free up context space |
| **/editor** | Open an editor to write a prompt |
| **/exit** | Exit the application |
| **/git** | Run a git command (output excluded from chat) |
| **/help** | Ask questions about aider |

View File

@@ -1,7 +1,7 @@
---
parent: Usage
nav_order: 60
description: Using the chat, ask and help chat modes.
description: Using the code, architect, ask and help chat modes.
---
# Chat modes

View File

@@ -2,6 +2,12 @@
nav_exclude: true
---
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com;
connect-src http: https:;
style-src 'self' 'unsafe-inline';">
# Shared aider chat transcript
A user has shared the following transcript of a pair programming chat session
@@ -37,11 +43,29 @@ print("goodbye")
</div>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.6/purify.min.js"></script>
<script>
function isValidUrl(url) {
try {
const urlObj = new URL(url);
return urlObj.protocol === 'http:' || urlObj.protocol === 'https:';
} catch {
return false;
}
}
// Configure marked with secure defaults
marked.setOptions({
headerIds: false,
mangle: false
});
window.onload = function() {
var urlParams = new URLSearchParams(window.location.search);
var conv = urlParams.get('mdurl');
if (!conv) {
if (!conv || !isValidUrl(conv)) {
document.querySelector('#shared-transcript').innerHTML =
'<div style="color: red; padding: 1em;">Error: Invalid or missing URL provided</div>';
return;
}
document.getElementById('mdurl').href = conv;
@@ -63,11 +87,14 @@ window.onload = function() {
return line;
}).join('\n');
var html = marked.parse(markdown);
var sanitizedHtml = DOMPurify.sanitize(html);
var divElement = document.querySelector('#shared-transcript');
divElement.innerHTML = html;
divElement.innerHTML = sanitizedHtml;
})
.catch(error => {
console.error('Error fetching markdown:', error);
document.querySelector('#shared-transcript').innerHTML =
'<div style="color: red; padding: 1em;">Error: Failed to load chat transcript</div>';
});
}
</script>

View File

@@ -155,6 +155,9 @@ def main(
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"),
num_tests: int = typer.Option(-1, "--num-tests", "-n", help="Number of tests to run"),
num_ctx: Optional[int] = typer.Option(
None, "--num-ctx", help="Override model context window size"
),
exercises_dir: str = typer.Option(
EXERCISES_DIR_DEFAULT, "--exercises-dir", help="Directory with exercise files"
),
@@ -247,6 +250,7 @@ def main(
max_apply_update_errors,
editor_model,
editor_edit_format,
num_ctx,
)
all_results.append(results)
@@ -526,6 +530,7 @@ def run_test_real(
max_apply_update_errors,
editor_model,
editor_edit_format,
num_ctx=None,
):
if not os.path.isdir(testdir):
print("Not a dir:", testdir)
@@ -588,6 +593,11 @@ def run_test_real(
editor_model=editor_model,
editor_edit_format=editor_edit_format,
)
if num_ctx:
if not main_model.extra_params:
main_model.extra_params = {}
main_model.extra_params["num_ctx"] = num_ctx
edit_format = edit_format or main_model.edit_format
dump(main_model)

View File

@@ -2,6 +2,7 @@
docker run \
-it --rm \
--add-host=host.docker.internal:host-gateway \
-v `pwd`:/aider \
-v `pwd`/tmp.benchmarks/.:/benchmarks \
-e OPENAI_API_KEY=$OPENAI_API_KEY \

View File

@@ -1,121 +1,168 @@
from dataclasses import dataclass
from datetime import date
from typing import Dict, List, Tuple
import matplotlib.pyplot as plt
import yaml
from imgcat import imgcat
from matplotlib import rc
from aider.dump import dump # noqa: 401
@dataclass
class ModelData:
name: str
release_date: date
pass_rate: float
@property
def color(self) -> str:
model = self.name.lower()
if "gemini" in model and "pro" in model:
return "magenta"
if "qwen" in model:
return "darkblue"
if "mistral" in model:
return "cyan"
if "haiku" in model:
return "pink"
if "deepseek" in model:
return "brown"
if "sonnet" in model:
return "orange"
if "-4o" in model:
return "purple"
if "gpt-4" in model:
return "red"
if "gpt-3.5" in model:
return "green"
return "lightblue"
@property
def legend_label(self) -> str:
model = self.name.lower()
if "gemini" in model and "pro" in model:
return "Gemini 1.5 Pro"
if "claude-3-sonnet" in model:
return "Sonnet"
if "o1-preview" in model:
return "O1 Preview"
if "gpt-3.5" in model:
return "GPT-3.5 Turbo"
if "gpt-4-" in model and "-4o" not in model:
return "GPT-4"
if "qwen" in model:
return "Qwen"
if "-4o" in model:
return "GPT-4o"
if "haiku" in model:
return "Haiku"
if "deepseek" in model:
return "DeepSeek"
if "mistral" in model:
return "Mistral"
return model
def get_model_color(model):
default = "lightblue"
class BenchmarkPlotter:
LABEL_FONT_SIZE = 16
if model == "gpt-4o-mini":
return default
def __init__(self):
self.setup_plot_style()
if "-4o" in model:
return "purple"
def setup_plot_style(self):
plt.rcParams["hatch.linewidth"] = 0.5
plt.rcParams["hatch.color"] = "#444444"
rc("font", **{"family": "sans-serif", "sans-serif": ["Helvetica"], "size": 10})
plt.rcParams["text.color"] = "#444444"
if "gpt-4" in model:
return "red"
def load_data(self, yaml_file: str) -> List[ModelData]:
with open(yaml_file, "r") as file:
data = yaml.safe_load(file)
if "gpt-3.5" in model:
return "green"
models = []
for entry in data:
if "released" in entry and "pass_rate_2" in entry:
model = ModelData(
name=entry["model"].split("(")[0].strip(),
release_date=entry["released"],
pass_rate=entry["pass_rate_2"],
)
models.append(model)
return models
return default
def create_figure(self) -> Tuple[plt.Figure, plt.Axes]:
fig, ax = plt.subplots(figsize=(12, 8))
ax.grid(axis="y", zorder=0, lw=0.2)
for spine in ax.spines.values():
spine.set_edgecolor("#DDDDDD")
spine.set_linewidth(0.5)
return fig, ax
def plot_model_series(self, ax: plt.Axes, models: List[ModelData]):
# Group models by color
color_groups: Dict[str, List[ModelData]] = {}
for model in models:
if model.color not in color_groups:
color_groups[model.color] = []
color_groups[model.color].append(model)
def plot_over_time(yaml_file):
with open(yaml_file, "r") as file:
data = yaml.safe_load(file)
# Plot each color group
for color, group in color_groups.items():
sorted_group = sorted(group, key=lambda x: x.release_date)
dates = [m.release_date for m in sorted_group]
rates = [m.pass_rate for m in sorted_group]
dates = []
pass_rates = []
models = []
# Plot line
ax.plot(dates, rates, c=color, alpha=0.5, linewidth=1)
print("Debug: Raw data from YAML file:")
print(data)
# Plot points
ax.scatter(dates, rates, c=color, alpha=0.5, s=120)
for entry in data:
if "released" in entry and "pass_rate_2" in entry:
dates.append(entry["released"])
pass_rates.append(entry["pass_rate_2"])
models.append(entry["model"].split("(")[0].strip())
# Add label for first point
first_model = sorted_group[0]
ax.annotate(
first_model.legend_label,
(first_model.release_date, first_model.pass_rate),
xytext=(10, 5),
textcoords="offset points",
color=color,
alpha=0.8,
fontsize=self.LABEL_FONT_SIZE,
)
print("Debug: Processed data:")
print("Dates:", dates)
print("Pass rates:", pass_rates)
print("Models:", models)
if not dates or not pass_rates:
print(
"Error: No data to plot. Check if the YAML file is empty or if the data is in the"
" expected format."
def set_labels_and_style(self, ax: plt.Axes):
ax.set_xlabel("Model release date", fontsize=18, color="#555")
ax.set_ylabel(
"Aider code editing benchmark,\npercent completed correctly", fontsize=18, color="#555"
)
return
ax.set_title("LLM code editing skill by model release date", fontsize=20)
ax.set_ylim(30, 90)
plt.xticks(fontsize=14, rotation=45, ha="right")
plt.tight_layout(pad=1.0)
plt.rcParams["hatch.linewidth"] = 0.5
plt.rcParams["hatch.color"] = "#444444"
def save_and_display(self, fig: plt.Figure):
plt.savefig("aider/website/assets/models-over-time.png")
plt.savefig("aider/website/assets/models-over-time.svg")
imgcat(fig)
rc("font", **{"family": "sans-serif", "sans-serif": ["Helvetica"], "size": 10})
plt.rcParams["text.color"] = "#444444"
fig, ax = plt.subplots(figsize=(12, 6)) # Increase figure size for better visibility
print("Debug: Figure created. Plotting data...")
ax.grid(axis="y", zorder=0, lw=0.2)
for spine in ax.spines.values():
spine.set_edgecolor("#DDDDDD")
spine.set_linewidth(0.5)
colors = [get_model_color(model) for model in models]
# Separate data points by color
purple_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "purple"]
red_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "red"]
green_points = [(d, r) for d, r, c in zip(dates, pass_rates, colors) if c == "green"]
# Plot lines for purple, red, and green points
if purple_points:
purple_dates, purple_rates = zip(*sorted(purple_points))
ax.plot(purple_dates, purple_rates, c="purple", alpha=0.5, linewidth=1)
if red_points:
red_dates, red_rates = zip(*sorted(red_points))
ax.plot(red_dates, red_rates, c="red", alpha=0.5, linewidth=1)
if green_points:
green_dates, green_rates = zip(*sorted(green_points))
ax.plot(green_dates, green_rates, c="green", alpha=0.5, linewidth=1)
# Plot all points
ax.scatter(dates, pass_rates, c=colors, alpha=0.5, s=120)
for i, model in enumerate(models):
ax.annotate(
model,
(dates[i], pass_rates[i]),
fontsize=8,
alpha=0.75,
xytext=(5, 5),
textcoords="offset points",
)
ax.set_xlabel("Model release date", fontsize=18, color="#555")
ax.set_ylabel(
"Aider code editing benchmark,\npercent completed correctly", fontsize=18, color="#555"
)
ax.set_title("LLM code editing skill by model release date", fontsize=20)
ax.set_ylim(0, 100) # Adjust y-axis limit to accommodate higher values
plt.xticks(fontsize=14, rotation=45, ha="right") # Rotate x-axis labels for better readability
plt.tight_layout(pad=3.0)
print("Debug: Saving figures...")
plt.savefig("tmp_over_time.png")
plt.savefig("tmp_over_time.svg")
print("Debug: Displaying figure with imgcat...")
imgcat(fig)
print("Debug: Figure generation complete.")
def plot(self, yaml_file: str):
models = self.load_data(yaml_file)
fig, ax = self.create_figure()
self.plot_model_series(ax, models)
self.set_labels_and_style(ax)
self.save_and_display(fig)
# Example usage
plot_over_time("aider/website/_data/edit_leaderboard.yml")
def main():
plotter = BenchmarkPlotter()
models = plotter.load_data("aider/website/_data/edit_leaderboard.yml")
# Print release dates and model names
for model in sorted(models, key=lambda x: x.release_date):
print(f"{model.release_date}: {model.name}")
plotter.plot("aider/website/_data/edit_leaderboard.yml")
if __name__ == "__main__":
main()

View File

@@ -58,6 +58,7 @@ include = ["aider*", "aider.website"]
"docs/unified-diffs.md",
"docs/leaderboards/index.md",
"assets/**",
"**/.DS_Store",
# [[[end]]]
]

View File

@@ -6,7 +6,7 @@
#
aiohappyeyeballs==2.4.3
# via aiohttp
aiohttp==3.10.10
aiohttp==3.11.7
# via litellm
aiosignal==1.3.1
# via aiohttp
@@ -62,11 +62,11 @@ gitdb==4.0.11
# via gitpython
gitpython==3.1.43
# via -r requirements/requirements.in
grep-ast==0.3.3
grep-ast==0.4.0
# via -r requirements/requirements.in
h11==0.14.0
# via httpcore
httpcore==1.0.6
httpcore==1.0.7
# via httpx
httpx==0.27.2
# via openai
@@ -86,9 +86,9 @@ importlib-resources==6.4.5
# via -r requirements/requirements.in
jinja2==3.1.4
# via litellm
jiter==0.7.0
jiter==0.7.1
# via openai
json5==0.9.25
json5==0.9.28
# via -r requirements/requirements.in
jsonschema==4.23.0
# via
@@ -96,7 +96,7 @@ jsonschema==4.23.0
# litellm
jsonschema-specifications==2024.10.1
# via jsonschema
litellm==1.51.2
litellm==1.52.16
# via -r requirements/requirements.in
markdown-it-py==3.0.0
# via rich
@@ -120,9 +120,9 @@ numpy==1.26.4
# via
# -r requirements/requirements.in
# scipy
openai==1.53.0
openai==1.55.1
# via litellm
packaging==24.1
packaging==24.2
# via
# -r requirements/requirements.in
# huggingface-hub
@@ -134,12 +134,14 @@ pexpect==4.9.0
# via -r requirements/requirements.in
pillow==10.4.0
# via -r requirements/requirements.in
posthog==3.7.0
posthog==3.7.3
# via -r requirements/requirements.in
prompt-toolkit==3.0.48
# via -r requirements/requirements.in
propcache==0.2.0
# via yarl
# via
# aiohttp
# yarl
psutil==6.1.0
# via -r requirements/requirements.in
ptyprocess==0.7.0
@@ -148,11 +150,11 @@ pycodestyle==2.12.1
# via flake8
pycparser==2.22
# via cffi
pydantic==2.9.2
pydantic==2.10.2
# via
# litellm
# openai
pydantic-core==2.23.4
pydantic-core==2.27.1
# via pydantic
pydub==0.25.1
# via -r requirements/requirements.in
@@ -176,7 +178,7 @@ referencing==0.35.1
# via
# jsonschema
# jsonschema-specifications
regex==2024.9.11
regex==2024.11.6
# via tiktoken
requests==2.32.3
# via
@@ -185,9 +187,9 @@ requests==2.32.3
# mixpanel
# posthog
# tiktoken
rich==13.9.3
rich==13.9.4
# via -r requirements/requirements.in
rpds-py==0.20.1
rpds-py==0.21.0
# via
# jsonschema
# referencing
@@ -217,7 +219,7 @@ tokenizers==0.19.1
# via
# -r requirements/requirements.in
# litellm
tqdm==4.66.6
tqdm==4.67.1
# via
# huggingface-hub
# openai
@@ -239,7 +241,7 @@ urllib3==2.2.3
# requests
wcwidth==0.2.13
# via prompt-toolkit
yarl==1.17.1
yarl==1.18.0
# via aiohttp
zipp==3.20.2
zipp==3.21.0
# via importlib-metadata

View File

@@ -4,109 +4,109 @@
#
# pip-compile --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --constraint=requirements/requirements-help.txt --output-file=requirements/requirements-browser.txt requirements/requirements-browser.in
#
altair==5.4.1
altair==5.5.0
# via streamlit
attrs==24.2.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-help.txt
# jsonschema
# referencing
blinker==1.8.2
blinker==1.9.0
# via streamlit
cachetools==5.5.0
# via streamlit
certifi==2024.8.30
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# requests
charset-normalizer==3.4.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# requests
click==8.1.7
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# streamlit
gitdb==4.0.11
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# gitpython
gitpython==3.1.43
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# streamlit
idna==3.10
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# requests
jinja2==3.1.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# altair
# pydeck
jsonschema==4.23.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# altair
jsonschema-specifications==2024.10.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# jsonschema
markdown-it-py==3.0.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# rich
markupsafe==3.0.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# jinja2
mdurl==0.1.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# markdown-it-py
narwhals==1.12.1
narwhals==1.14.2
# via altair
numpy==1.26.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# pandas
# pydeck
# streamlit
packaging==24.1
packaging==24.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# altair
@@ -117,27 +117,27 @@ pandas==2.2.3
# streamlit
pillow==10.4.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# streamlit
protobuf==5.28.3
# via streamlit
pyarrow==18.0.0
pyarrow==18.1.0
# via streamlit
pydeck==0.9.1
# via streamlit
pygments==2.18.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# rich
python-dateutil==2.9.0.post0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# pandas
pytz==2024.2
@@ -146,41 +146,41 @@ pytz==2024.2
# pandas
referencing==0.35.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# jsonschema
# jsonschema-specifications
requests==2.32.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# streamlit
rich==13.9.3
rich==13.9.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# streamlit
rpds-py==0.20.1
rpds-py==0.21.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# jsonschema
# referencing
six==1.16.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# python-dateutil
smmap==5.0.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# gitdb
streamlit==1.39.0
streamlit==1.40.2
# via -r requirements/requirements-browser.in
tenacity==8.5.0
# via
@@ -188,12 +188,12 @@ tenacity==8.5.0
# streamlit
toml==0.10.2
# via streamlit
tornado==6.4.1
tornado==6.4.2
# via streamlit
typing-extensions==4.12.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# altair
@@ -204,8 +204,8 @@ tzdata==2024.2
# pandas
urllib3==2.2.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# requests

View File

@@ -12,27 +12,27 @@ build==1.2.2.post1
# via pip-tools
certifi==2024.8.30
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# requests
cfgv==3.4.0
# via pre-commit
charset-normalizer==3.4.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# requests
click==8.1.7
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# pip-tools
# typer
codespell==2.3.0
# via -r requirements/requirements-dev.in
cogapp==3.4.1
# via -r requirements/requirements-dev.in
contourpy==1.3.0
contourpy==1.3.1
# via matplotlib
cycler==0.12.1
# via matplotlib
@@ -48,28 +48,28 @@ docutils==0.21.2
# sphinx-rtd-theme
filelock==3.16.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# virtualenv
fonttools==4.54.1
fonttools==4.55.0
# via matplotlib
identify==2.6.1
identify==2.6.3
# via pre-commit
idna==3.10
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# requests
imagesize==1.4.1
# via sphinx
imgcat==0.5.0
imgcat==0.6.0
# via -r requirements/requirements-dev.in
iniconfig==2.0.0
# via pytest
jinja2==3.1.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# sphinx
kiwisolver==1.4.7
# via matplotlib
@@ -77,20 +77,20 @@ lox==0.12.0
# via -r requirements/requirements-dev.in
markdown-it-py==3.0.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# rich
markupsafe==3.0.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# jinja2
matplotlib==3.9.2
# via -r requirements/requirements-dev.in
mdurl==0.1.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# markdown-it-py
multiprocess==0.70.17
# via pathos
@@ -98,15 +98,15 @@ nodeenv==1.9.1
# via pre-commit
numpy==1.26.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# contourpy
# matplotlib
# pandas
packaging==24.1
packaging==24.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# build
# matplotlib
# pytest
@@ -117,8 +117,8 @@ pathos==0.3.3
# via lox
pillow==10.4.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# matplotlib
pip-tools==7.4.1
# via -r requirements/requirements-dev.in
@@ -134,8 +134,8 @@ pre-commit==4.0.1
# via -r requirements/requirements-dev.in
pygments==2.18.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# rich
# sphinx
pyparsing==3.2.0
@@ -148,26 +148,26 @@ pytest==8.3.3
# via -r requirements/requirements-dev.in
python-dateutil==2.9.0.post0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# matplotlib
# pandas
pytz==2024.2
# via pandas
pyyaml==6.0.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# pre-commit
requests==2.32.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# sphinx
rich==13.9.3
rich==13.9.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# typer
semver==3.0.2
# via -r requirements/requirements-dev.in
@@ -175,8 +175,8 @@ shellingham==1.5.4
# via typer
six==1.16.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# python-dateutil
snowballstemmer==2.2.0
# via sphinx
@@ -184,7 +184,7 @@ sphinx==8.1.3
# via
# sphinx-rtd-theme
# sphinxcontrib-jquery
sphinx-rtd-theme==3.0.1
sphinx-rtd-theme==3.0.2
# via lox
sphinxcontrib-applehelp==2.0.0
# via sphinx
@@ -200,23 +200,23 @@ sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
typer==0.12.5
typer==0.13.1
# via -r requirements/requirements-dev.in
typing-extensions==4.12.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# typer
tzdata==2024.2
# via pandas
urllib3==2.2.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# requests
virtualenv==20.27.1
virtualenv==20.28.0
# via pre-commit
wheel==0.44.0
wheel==0.45.1
# via pip-tools
# The following packages are considered to be unsafe in a requirements file:

View File

@@ -6,79 +6,81 @@
#
aiohappyeyeballs==2.4.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# aiohttp
aiohttp==3.10.10
aiohttp==3.11.7
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# huggingface-hub
# llama-index-core
aiosignal==1.3.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# aiohttp
annotated-types==0.7.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# pydantic
anyio==4.6.2.post1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# httpx
attrs==24.2.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# aiohttp
certifi==2024.8.30
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# httpcore
# httpx
# requests
charset-normalizer==3.4.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# requests
click==8.1.7
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# nltk
dataclasses-json==0.6.7
# via llama-index-core
deprecated==1.2.14
deprecated==1.2.15
# via llama-index-core
dirtyjson==1.0.8
# via llama-index-core
filelock==3.16.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# huggingface-hub
# torch
# transformers
filetype==1.2.0
# via llama-index-core
frozenlist==1.5.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# aiohttp
# aiosignal
fsspec==2024.10.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# huggingface-hub
# llama-index-core
# torch
@@ -88,31 +90,31 @@ greenlet==3.0.3
# sqlalchemy
h11==0.14.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# httpcore
httpcore==1.0.6
httpcore==1.0.7
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# httpx
httpx==0.27.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# llama-index-core
huggingface-hub[inference]==0.26.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# llama-index-embeddings-huggingface
# sentence-transformers
# tokenizers
# transformers
idna==3.10
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# anyio
# httpx
@@ -120,34 +122,34 @@ idna==3.10
# yarl
jinja2==3.1.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# torch
joblib==1.4.2
# via
# nltk
# scikit-learn
llama-index-core==0.11.21
llama-index-core==0.12.0
# via
# -r requirements/requirements-help.in
# llama-index-embeddings-huggingface
llama-index-embeddings-huggingface==0.3.1
llama-index-embeddings-huggingface==0.4.0
# via -r requirements/requirements-help.in
markupsafe==3.0.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# jinja2
marshmallow==3.23.0
marshmallow==3.23.1
# via dataclasses-json
mpmath==1.3.0
# via sympy
multidict==6.1.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# aiohttp
# yarl
mypy-extensions==1.0.0
@@ -156,70 +158,71 @@ nest-asyncio==1.6.0
# via llama-index-core
networkx==3.2.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# llama-index-core
# torch
nltk==3.9.1
# via llama-index-core
numpy==1.26.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# llama-index-core
# scikit-learn
# scipy
# transformers
packaging==24.1
packaging==24.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# huggingface-hub
# marshmallow
# transformers
pillow==10.4.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# llama-index-core
# sentence-transformers
propcache==0.2.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# aiohttp
# yarl
pydantic==2.9.2
pydantic==2.10.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# llama-index-core
pydantic-core==2.23.4
pydantic-core==2.27.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# pydantic
pyyaml==6.0.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# huggingface-hub
# llama-index-core
# transformers
regex==2024.9.11
regex==2024.11.6
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# nltk
# tiktoken
# transformers
requests==2.32.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# huggingface-hub
# llama-index-core
@@ -231,16 +234,16 @@ scikit-learn==1.5.2
# via sentence-transformers
scipy==1.13.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# scikit-learn
# sentence-transformers
sentence-transformers==3.2.1
sentence-transformers==3.3.1
# via llama-index-embeddings-huggingface
sniffio==1.3.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# anyio
# httpx
sqlalchemy[asyncio]==2.0.36
@@ -255,20 +258,20 @@ threadpoolctl==3.5.0
# via scikit-learn
tiktoken==0.8.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# llama-index-core
tokenizers==0.19.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# transformers
torch==2.2.2
# via sentence-transformers
tqdm==4.66.6
tqdm==4.67.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# huggingface-hub
# llama-index-core
# nltk
@@ -278,8 +281,8 @@ transformers==4.44.2
# via sentence-transformers
typing-extensions==4.12.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# huggingface-hub
# llama-index-core
@@ -294,16 +297,16 @@ typing-inspect==0.9.0
# llama-index-core
urllib3==2.2.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-dev.txt
# requests
wrapt==1.16.0
wrapt==1.17.0
# via
# deprecated
# llama-index-core
yarl==1.17.1
yarl==1.18.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# aiohttp

View File

@@ -15,8 +15,8 @@ pyee==12.0.0
# via playwright
typing-extensions==4.12.2
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/../requirements.txt
# -c requirements/requirements-browser.txt
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt

View File

@@ -15,6 +15,6 @@ RUN bundle install --retry 5 --jobs 20
ENTRYPOINT [ "docker-entrypoint.sh" ]
# bundle exec jekyll serve --force_polling -H 0.0.0.0 -P 4000
CMD [ "bundle", "exec", "jekyll", "serve", "--force_polling", "-H", "0.0.0.0", "-P", "4000" ]
CMD [ "bundle", "exec", "jekyll", "serve", "--verbose", "--trace", "--force_polling", "-H", "0.0.0.0", "-P", "4000" ]

View File

@@ -23,8 +23,10 @@ def blame(start_tag, end_tag=None):
files = [
f
for f in files
if f.endswith((".py", ".scm", ".sh", "Dockerfile", "Gemfile"))
if f.endswith((".js", ".py", ".scm", ".sh", "Dockerfile", "Gemfile"))
or (f.startswith(".github/workflows/") and f.endswith(".yml"))
or f == "aider/website/share/index.md"
or f == "aider/website/docs/leaderboards/index.md"
]
files = [f for f in files if not f.endswith("prompts.py")]

View File

@@ -22,15 +22,27 @@ def has_been_reopened(issue_number):
# Load environment variables from .env file
load_dotenv()
DUPLICATE_COMMENT = """Thanks for trying aider and filing this issue.
BOT_SUFFIX = """Note: A [bot script](https://github.com/Aider-AI/aider/blob/main/scripts/issues.py) made these updates to the issue.
""" # noqa
DUPLICATE_COMMENT = (
"""Thanks for trying aider and filing this issue.
This looks like a duplicate of #{oldest_issue_number}. Please see the comments there for more information, and feel free to continue the discussion within that issue.
I'm going to close this issue for now. But please let me know if you think this is actually a distinct issue and I will reopen this issue.""" # noqa
+ BOT_SUFFIX
)
STALE_COMMENT = """I'm labeling this issue as stale because it has been open for 2 weeks with no activity. If there are no additional comments, it will be closed in 7 days.""" # noqa
STALE_COMMENT = (
"""I'm labeling this issue as stale because it has been open for 2 weeks with no activity. If there are no additional comments, I will close it in 7 days.""" # noqa
+ BOT_SUFFIX
)
CLOSE_STALE_COMMENT = """I'm closing this issue because it has been stalled for 3 weeks with no activity. Feel free to add a comment here and we can re-open it. Or feel free to file a new issue at any time.""" # noqa
CLOSE_STALE_COMMENT = (
"""I'm closing this issue because it has been stalled for 3 weeks with no activity. Feel free to add a comment here and we can re-open it. Or feel free to file a new issue at any time.""" # noqa
+ BOT_SUFFIX
)
# GitHub API configuration
GITHUB_API_URL = "https://api.github.com"
@@ -279,7 +291,7 @@ def handle_stale_closing(all_issues, auto_yes):
continue
# Add closing comment
comment_url = f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/comments"
comment_url = f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/comments" # noqa
response = requests.post(
comment_url, headers=headers, json={"body": CLOSE_STALE_COMMENT}
)

View File

@@ -24,6 +24,7 @@ cog $ARG \
aider/website/docs/config/options.md \
aider/website/docs/config/aider_conf.md \
aider/website/docs/config/adv-model-settings.md \
aider/website/docs/config/model-aliases.md \
aider/website/docs/leaderboards/index.md \
aider/website/docs/llms/other.md \
aider/website/docs/more/infinite-output.md \

72
scripts/update-history.py Executable file
View File

@@ -0,0 +1,72 @@
#!/usr/bin/env python3
import os
import re
import subprocess
import tempfile
from aider import __version__
def get_base_version():
# Parse current version like "0.64.2.dev" to get major.minor
match = re.match(r"(\d+\.\d+)", __version__)
if not match:
raise ValueError(f"Could not parse version: {__version__}")
return match.group(1) + ".0"
def run_git_log():
base_ver = get_base_version()
cmd = [
"git",
"log",
"-p",
f"v{base_ver}..HEAD",
"--",
"aider/",
":!aider/website/",
":!scripts/",
":!HISTORY.md",
]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.stdout
def main():
# Get the git log output
diff_content = run_git_log()
# Save to temporary file
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".diff") as tmp:
tmp.write(diff_content)
tmp_path = tmp.name
# Run blame to get aider percentage
blame_result = subprocess.run(["python3", "scripts/blame.py"], capture_output=True, text=True)
aider_line = blame_result.stdout.strip().split("\n")[-1] # Get last line with percentage
# Construct and run the aider command
message = f"""
Update the history with changes shown in the diffs.
Describe actual user-facing changes, not every single commit that was made implementing them.
Don't edit or duplicate changes that have existing history entries, just add any new items not already listed.
Be sure to attribute changes to the proper .x version.
Changes in the .x-dev version should be listed under a "### main branch" heading
Also, add this as the last bullet under the "### main branch" section:
{aider_line}
""" # noqa
cmd = ["aider", "HISTORY.md", "--read", tmp_path, "--msg", message, "--no-auto-commit"]
subprocess.run(cmd)
# Run update-docs.sh after aider
subprocess.run(["scripts/update-docs.sh"])
# Cleanup
os.unlink(tmp_path)
if __name__ == "__main__":
main()

View File

@@ -124,7 +124,10 @@ def main():
for cmd in git_commands:
print(f"Running: {' '.join(cmd)}")
if not dry_run:
subprocess.run(cmd, check=True)
subprocess.run(
cmd,
check=True,
)
new_dev_version = f"{incremented_version}.dev"
updated_dev_content = re.sub(

View File

@@ -91,10 +91,49 @@ def test_system_info(temp_data_dir):
def test_need_to_ask(temp_data_dir):
analytics = Analytics()
assert analytics.need_to_ask() is True
assert analytics.need_to_ask(True) is True
assert analytics.need_to_ask(False) is False
analytics.user_id = "111"
assert analytics.need_to_ask(None) is False
analytics.user_id = "000"
assert analytics.need_to_ask(None) is True
analytics.asked_opt_in = True
assert analytics.need_to_ask() is False
assert analytics.need_to_ask(True) is False
analytics.permanently_disable = True
assert analytics.need_to_ask() is False
assert analytics.need_to_ask(True) is False
def test_is_uuid_in_percentage():
analytics = Analytics()
# Test basic percentage thresholds
assert analytics.is_uuid_in_percentage("00000000000000000000000000000000", 1) is True
assert analytics.is_uuid_in_percentage("01999000000000000000000000000000", 1) is True
assert analytics.is_uuid_in_percentage("02000000000000000000000000000000", 1) is True
assert analytics.is_uuid_in_percentage("02910000000000000000000000000001", 1) is False
assert analytics.is_uuid_in_percentage("03000000000000000000000000000000", 1) is False
assert analytics.is_uuid_in_percentage("ff000000000000000000000000000000", 1) is False
assert analytics.is_uuid_in_percentage("00000000000000000000000000000000", 10) is True
assert analytics.is_uuid_in_percentage("19000000000000000000000000000000", 10) is True
assert analytics.is_uuid_in_percentage("1a000000000000000000000000000000", 10) is False
assert analytics.is_uuid_in_percentage("ff000000000000000000000000000000", 10) is False
# Test edge cases
assert analytics.is_uuid_in_percentage("00000000000000000000000000000000", 0) is False
assert analytics.is_uuid_in_percentage("00000000000000000000000000000000", 100) is True
assert analytics.is_uuid_in_percentage("ffffffffffffffffffffffffffffffff", 100) is True
# Test invalid inputs
with pytest.raises(ValueError):
analytics.is_uuid_in_percentage("00000000000000000000000000000000", -1)
with pytest.raises(ValueError):
analytics.is_uuid_in_percentage("00000000000000000000000000000000", 101)
# Test empty/None UUID
assert analytics.is_uuid_in_percentage("", 50) is False
assert analytics.is_uuid_in_percentage(None, 50) is False

View File

@@ -7,6 +7,7 @@ from unittest.mock import MagicMock, patch
import git
from aider.coders import Coder
from aider.coders.base_coder import UnknownEditFormat
from aider.dump import dump # noqa: F401
from aider.io import InputOutput
from aider.models import Model
@@ -168,6 +169,37 @@ class TestCoder(unittest.TestCase):
self.assertEqual(coder.abs_fnames, set([str(fname.resolve())]))
def test_skip_duplicate_basename_mentions(self):
with GitTemporaryDirectory():
io = InputOutput(pretty=False, yes=True)
coder = Coder.create(self.GPT35, None, io)
# Create files with same basename in different directories
fname1 = Path("dir1") / "file.txt"
fname2 = Path("dir2") / "file.txt"
fname3 = Path("dir3") / "unique.txt"
for fname in [fname1, fname2, fname3]:
fname.parent.mkdir(parents=True, exist_ok=True)
fname.touch()
# Add one file to chat
coder.add_rel_fname(str(fname1))
# Mock get_tracked_files to return all files
mock = MagicMock()
mock.return_value = set([str(fname1), str(fname2), str(fname3)])
coder.repo.get_tracked_files = mock
# Check that file mentions skip files with duplicate basenames
mentioned = coder.get_file_mentions(f"Check {fname2} and {fname3}")
self.assertEqual(mentioned, {str(fname3)})
# Add a read-only file with same basename
coder.abs_read_only_fnames.add(str(fname2.resolve()))
mentioned = coder.get_file_mentions(f"Check {fname1} and {fname3}")
self.assertEqual(mentioned, {str(fname3)})
def test_check_for_file_mentions_read_only(self):
with GitTemporaryDirectory():
io = InputOutput(
@@ -821,32 +853,55 @@ This command will print 'Hello, World!' to the console."""
with GitTemporaryDirectory():
io = InputOutput(yes=True)
coder = Coder.create(self.GPT35, "diff", io=io, suggest_shell_commands=False)
self.assertFalse(coder.suggest_shell_commands)
def mock_send(*args, **kwargs):
coder.partial_response_content = """Here's a shell command to run:
def test_detect_urls_enabled(self):
with GitTemporaryDirectory():
io = InputOutput(yes=True)
coder = Coder.create(self.GPT35, "diff", io=io, detect_urls=True)
coder.commands.scraper = MagicMock()
coder.commands.scraper.scrape = MagicMock(return_value="some content")
```bash
echo "Hello, World!"
```
# Test with a message containing a URL
message = "Check out https://example.com"
coder.check_for_urls(message)
coder.commands.scraper.scrape.assert_called_once_with("https://example.com")
This command will print 'Hello, World!' to the console."""
coder.partial_response_function_call = dict()
return []
def test_detect_urls_disabled(self):
with GitTemporaryDirectory():
io = InputOutput(yes=True)
coder = Coder.create(self.GPT35, "diff", io=io, detect_urls=False)
coder.commands.scraper = MagicMock()
coder.commands.scraper.scrape = MagicMock(return_value="some content")
coder.send = mock_send
# Test with a message containing a URL
message = "Check out https://example.com"
result = coder.check_for_urls(message)
self.assertEqual(result, [])
coder.commands.scraper.scrape.assert_not_called()
# Mock the handle_shell_commands method to check if it's called
coder.handle_shell_commands = MagicMock()
def test_unknown_edit_format_exception(self):
# Test the exception message format
invalid_format = "invalid_format"
valid_formats = ["diff", "whole", "map"]
exc = UnknownEditFormat(invalid_format, valid_formats)
expected_msg = (
f"Unknown edit format {invalid_format}. Valid formats are: {', '.join(valid_formats)}"
)
self.assertEqual(str(exc), expected_msg)
# Run the coder with a message
coder.run(with_message="Suggest a shell command")
def test_unknown_edit_format_creation(self):
# Test that creating a Coder with invalid edit format raises the exception
io = InputOutput(yes=True)
invalid_format = "invalid_format"
# Check if the shell command was added to the list
self.assertEqual(len(coder.shell_commands), 1)
self.assertEqual(coder.shell_commands[0].strip(), 'echo "Hello, World!"')
with self.assertRaises(UnknownEditFormat) as cm:
Coder.create(self.GPT35, invalid_format, io=io)
# Check if handle_shell_commands was called with the correct argument
coder.handle_shell_commands.assert_not_called()
exc = cm.exception
self.assertEqual(exc.edit_format, invalid_format)
self.assertIsInstance(exc.valid_formats, list)
self.assertTrue(len(exc.valid_formats) > 0)
def test_coder_create_with_new_file_oserror(self):
with GitTemporaryDirectory():

View File

@@ -1068,8 +1068,10 @@ class TestCommands(TestCase):
io.prompt_ask = lambda *args, **kwargs: "y"
# Test the cmd_run method with a command that should not raise an error
result = commands.cmd_run("exit 1", add_on_nonzero_exit=True)
self.assertIn("I ran this command", result)
commands.cmd_run("exit 1", add_on_nonzero_exit=True)
# Check that the output was added to cur_messages
self.assertTrue(any("exit 1" in msg["content"] for msg in coder.cur_messages))
def test_cmd_add_drop_untracked_files(self):
with GitTemporaryDirectory():

129
tests/basic/test_editor.py Normal file
View File

@@ -0,0 +1,129 @@
import os
from unittest.mock import MagicMock, patch
import pytest
from aider.editor import (
DEFAULT_EDITOR_NIX,
DEFAULT_EDITOR_OS_X,
DEFAULT_EDITOR_WINDOWS,
discover_editor,
get_environment_editor,
pipe_editor,
print_status_message,
write_temp_file,
)
def test_get_environment_editor():
# Test with no environment variables set
with patch.dict(os.environ, {}, clear=True):
assert get_environment_editor("default") == "default"
# Test EDITOR precedence
with patch.dict(os.environ, {"EDITOR": "vim"}):
assert get_environment_editor() == "vim"
# Test VISUAL overrides EDITOR
with patch.dict(os.environ, {"EDITOR": "vim", "VISUAL": "code"}):
assert get_environment_editor() == "code"
def test_discover_editor_defaults():
with patch("platform.system") as mock_system:
# Test Windows default
mock_system.return_value = "Windows"
with patch.dict(os.environ, {}, clear=True):
assert discover_editor() == [DEFAULT_EDITOR_WINDOWS]
# Test macOS default
mock_system.return_value = "Darwin"
with patch.dict(os.environ, {}, clear=True):
assert discover_editor() == [DEFAULT_EDITOR_OS_X]
# Test Linux default
mock_system.return_value = "Linux"
with patch.dict(os.environ, {}, clear=True):
assert discover_editor() == [DEFAULT_EDITOR_NIX]
def test_write_temp_file():
# Test basic file creation
content = "test content"
filepath = write_temp_file(content)
assert os.path.exists(filepath)
with open(filepath, "r") as f:
assert f.read() == content
os.remove(filepath)
# Test with suffix
filepath = write_temp_file("content", suffix="txt")
assert filepath.endswith(".txt")
os.remove(filepath)
# Test with prefix
filepath = write_temp_file("content", prefix="test_")
assert os.path.basename(filepath).startswith("test_")
os.remove(filepath)
def test_print_status_message(capsys):
# Test success message
print_status_message(True, "Success!")
captured = capsys.readouterr()
assert "Success!" in captured.out
# Test failure message
print_status_message(False, "Failed!")
captured = capsys.readouterr()
assert "Failed!" in captured.out
def test_discover_editor_override():
# Test editor override
assert discover_editor("code") == ["code"]
assert discover_editor('vim -c "set noswapfile"') == ["vim", "-c", "set noswapfile"]
# Test invalid editor command
with pytest.raises(RuntimeError):
discover_editor('vim "unclosed quote')
def test_pipe_editor():
# Test with default editor
test_content = "Initial content"
modified_content = "Modified content"
# Mock the file operations and editor call
with (
patch("aider.editor.write_temp_file") as mock_write,
patch("builtins.open") as mock_open,
patch("os.remove") as mock_remove,
patch("subprocess.call") as mock_subprocess,
):
# Setup mocks
mock_write.return_value = "temp.txt"
mock_file = MagicMock()
mock_file.__enter__.return_value.read.return_value = modified_content
mock_open.return_value = mock_file
# Test with default editor
result = pipe_editor(test_content)
assert result == modified_content
mock_write.assert_called_with(test_content, None)
mock_subprocess.assert_called()
# Test with custom editor
result = pipe_editor(test_content, editor="code")
assert result == modified_content
mock_subprocess.assert_called()
# Test with suffix
result = pipe_editor(test_content, suffix="md")
assert result == modified_content
mock_write.assert_called_with(test_content, "md")
# Test cleanup on permission error
mock_remove.side_effect = PermissionError
result = pipe_editor(test_content)
assert result == modified_content

View File

@@ -45,7 +45,7 @@ class TestMain(TestCase):
self.webbrowser_patcher.stop()
def test_main_with_empty_dir_no_files_on_command(self):
main(["--no-git", "--exit"], input=DummyInput(), output=DummyOutput())
main(["--no-git", "--exit", "--yes"], input=DummyInput(), output=DummyOutput())
def test_main_with_emptqy_dir_new_file(self):
main(["foo.txt", "--yes", "--no-git", "--exit"], input=DummyInput(), output=DummyOutput())
@@ -332,7 +332,7 @@ class TestMain(TestCase):
def test_false_vals_in_env_file(self):
self.create_env_file(".env", "AIDER_SHOW_DIFFS=off")
with patch("aider.coders.Coder.create") as MockCoder:
main(["--no-git"], input=DummyInput(), output=DummyOutput())
main(["--no-git", "--yes"], input=DummyInput(), output=DummyOutput())
MockCoder.assert_called_once()
_, kwargs = MockCoder.call_args
self.assertEqual(kwargs["show_diffs"], False)
@@ -340,7 +340,7 @@ class TestMain(TestCase):
def test_true_vals_in_env_file(self):
self.create_env_file(".env", "AIDER_SHOW_DIFFS=on")
with patch("aider.coders.Coder.create") as MockCoder:
main(["--no-git"], input=DummyInput(), output=DummyOutput())
main(["--no-git", "--yes"], input=DummyInput(), output=DummyOutput())
MockCoder.assert_called_once()
_, kwargs = MockCoder.call_args
self.assertEqual(kwargs["show_diffs"], True)
@@ -381,7 +381,11 @@ class TestMain(TestCase):
def test_verbose_mode_lists_env_vars(self):
self.create_env_file(".env", "AIDER_DARK_MODE=on")
with patch("sys.stdout", new_callable=StringIO) as mock_stdout:
main(["--no-git", "--verbose", "--exit"], input=DummyInput(), output=DummyOutput())
main(
["--no-git", "--verbose", "--exit", "--yes"],
input=DummyInput(),
output=DummyOutput(),
)
output = mock_stdout.getvalue()
relevant_output = "\n".join(
line
@@ -633,6 +637,49 @@ class TestMain(TestCase):
)
self.assertTrue(coder.suggest_shell_commands)
def test_detect_urls_default(self):
with GitTemporaryDirectory():
coder = main(
["--exit", "--yes"],
input=DummyInput(),
output=DummyOutput(),
return_coder=True,
)
self.assertTrue(coder.detect_urls)
def test_detect_urls_disabled(self):
with GitTemporaryDirectory():
coder = main(
["--no-detect-urls", "--exit", "--yes"],
input=DummyInput(),
output=DummyOutput(),
return_coder=True,
)
self.assertFalse(coder.detect_urls)
def test_detect_urls_enabled(self):
with GitTemporaryDirectory():
coder = main(
["--detect-urls", "--exit", "--yes"],
input=DummyInput(),
output=DummyOutput(),
return_coder=True,
)
self.assertTrue(coder.detect_urls)
def test_invalid_edit_format(self):
with GitTemporaryDirectory():
with patch("aider.io.InputOutput.offer_url") as mock_offer_url:
result = main(
["--edit-format", "not-a-real-format", "--exit", "--yes"],
input=DummyInput(),
output=DummyOutput(),
)
self.assertEqual(result, 1) # main() should return 1 on error
mock_offer_url.assert_called_once()
args, _ = mock_offer_url.call_args
self.assertEqual(args[0], "https://aider.chat/docs/more/edit-formats.html")
def test_chat_language_spanish(self):
with GitTemporaryDirectory():
coder = main(

View File

@@ -2,8 +2,10 @@ import unittest
from unittest.mock import ANY, MagicMock, patch
from aider.models import (
ANTHROPIC_BETA_HEADER,
Model,
ModelInfoManager,
register_models,
sanity_check_model,
sanity_check_models,
)
@@ -80,7 +82,9 @@ class TestModels(unittest.TestCase):
) # Should return True because there's a problem with the editor model
mock_io.tool_warning.assert_called_with(ANY) # Ensure a warning was issued
warning_messages = [call.args[0] for call in mock_io.tool_warning.call_args_list]
warning_messages = [
warning_call.args[0] for warning_call in mock_io.tool_warning.call_args_list
]
print("Warning messages:", warning_messages) # Add this line
self.assertGreaterEqual(mock_io.tool_warning.call_count, 1) # Expect two warnings
@@ -88,6 +92,87 @@ class TestModels(unittest.TestCase):
any("bogus-model" in msg for msg in warning_messages)
) # Check that one of the warnings mentions the bogus model
def test_model_aliases(self):
# Test common aliases
model = Model("4")
self.assertEqual(model.name, "gpt-4-0613")
model = Model("4o")
self.assertEqual(model.name, "gpt-4o-2024-08-06")
model = Model("35turbo")
self.assertEqual(model.name, "gpt-3.5-turbo")
model = Model("35-turbo")
self.assertEqual(model.name, "gpt-3.5-turbo")
model = Model("3")
self.assertEqual(model.name, "gpt-3.5-turbo")
model = Model("sonnet")
self.assertEqual(model.name, "claude-3-sonnet-20241022")
model = Model("haiku")
self.assertEqual(model.name, "claude-3-haiku-20241022")
model = Model("opus")
self.assertEqual(model.name, "claude-3-opus-20240229")
# Test non-alias passes through unchanged
model = Model("gpt-4")
self.assertEqual(model.name, "gpt-4")
def test_aider_extra_model_settings(self):
import tempfile
import yaml
# Create temporary YAML file with test settings
test_settings = [
{
"name": "aider/extra_params",
"extra_params": {
"extra_headers": {"Foo": "bar"},
"some_param": "some value",
},
},
]
# Write to a regular file instead of NamedTemporaryFile
# for better cross-platform compatibility
tmp = tempfile.mktemp(suffix=".yml")
try:
with open(tmp, "w") as f:
yaml.dump(test_settings, f)
# Register the test settings
register_models([tmp])
# Test that defaults are applied when no exact match
model = Model("claude-3-5-sonnet-20240620")
# Test that both the override and existing headers are present
model = Model("claude-3-5-sonnet-20240620")
self.assertEqual(model.extra_params["extra_headers"]["Foo"], "bar")
self.assertEqual(
model.extra_params["extra_headers"]["anthropic-beta"],
ANTHROPIC_BETA_HEADER,
)
self.assertEqual(model.extra_params["some_param"], "some value")
self.assertEqual(model.extra_params["max_tokens"], 8192)
# Test that exact match overrides defaults but not overrides
model = Model("gpt-4")
self.assertEqual(model.extra_params["extra_headers"]["Foo"], "bar")
self.assertEqual(model.extra_params["some_param"], "some value")
finally:
# Clean up the temporary file
import os
try:
os.unlink(tmp)
except OSError:
pass
if __name__ == "__main__":
unittest.main()

View File

@@ -373,6 +373,19 @@ class TestRepoMapAllLanguages(unittest.TestCase):
def test_get_repo_map_all_languages(self):
language_files = {
"dart": (
"test.dart",
"""void main() {
print('Hello, World!');
}
class Greeter {
String sayHello(String name) {
return 'Hello, $name!';
}
}
""",
),
"c": (
"test.c",
(