Compare commits

...

693 Commits

Author SHA1 Message Date
Paul Gauthier
29471b8019 set version to 0.69.1.dev 2024-12-13 11:42:00 -08:00
Paul Gauthier
cad661f0c8 version bump to 0.69.0 2024-12-13 11:40:25 -08:00
Paul Gauthier
261d770482 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-13 11:39:41 -08:00
Paul Gauthier
a75c9c74fd copy 2024-12-13 11:39:37 -08:00
paul-gauthier
8b5bdf9a16 Merge pull request #2623 from damms005/patch-1
Update conventions.md to fix url
2024-12-13 10:42:54 -08:00
Damilola Emmanuel Olowookere
e35eba2d51 Update conventions.md to fix url 2024-12-13 18:36:10 +00:00
Paul Gauthier (aider)
df8c88cef4 style: Fix line length in issues.py 2024-12-13 08:46:57 -08:00
Paul Gauthier (aider)
844e12769c feat: Handle "bug" label like "enhancement" for closing 2024-12-13 08:46:53 -08:00
Paul Gauthier (aider)
b982626ac4 style: Fix line length in comment 2024-12-13 08:46:02 -08:00
Paul Gauthier (aider)
517b2b42a6 fix: Fix long lines in closing comment 2024-12-13 08:45:58 -08:00
Paul Gauthier (aider)
6778c33628 style: Apply linter fixes 2024-12-13 08:45:47 -08:00
Paul Gauthier (aider)
bc0b11e1ef feat: Add fixed enhancement issue closing 2024-12-13 08:45:43 -08:00
Paul Gauthier
6b0d4b9c93 copy 2024-12-13 08:23:42 -08:00
Paul Gauthier
7d4e4f029e copy 2024-12-13 08:13:36 -08:00
Paul Gauthier
1fbdb629ff add gemini-2.0-flash-exp metadata 2024-12-13 08:12:06 -08:00
Paul Gauthier
a437237947 copy 2024-12-13 07:37:15 -08:00
Paul Gauthier
910637c549 5% analytics 2024-12-13 06:51:50 -08:00
Paul Gauthier
e8974a3e69 copy 2024-12-12 19:08:21 -08:00
Paul Gauthier
6c98310f7f copy 2024-12-12 19:08:16 -08:00
Paul Gauthier
72aed0d26d fix: Disable complete_while_typing in prompt_session 2024-12-12 12:27:14 -08:00
Paul Gauthier
e10ef8b9e0 feat: Add instructions to /copy-context command 2024-12-12 12:08:29 -08:00
Paul Gauthier
39fa8ba831 copy 2024-12-12 07:54:54 -08:00
Paul Gauthier (aider)
8ee8279044 fix: Correct emacs auto-save gitignore pattern 2024-12-11 20:44:02 -08:00
Paul Gauthier (aider)
c3f85c3bb2 test: Fix gitignore pattern matching and add ai comment test 2024-12-11 20:43:07 -08:00
Paul Gauthier (aider)
ad59c4cbf3 test: Add comprehensive gitignore pattern tests 2024-12-11 20:43:03 -08:00
Paul Gauthier
26bc981981 chore: Add comment about testing gitignore patterns 2024-12-11 20:43:02 -08:00
Paul Gauthier
514c34b242 copy 2024-12-11 20:41:24 -08:00
Paul Gauthier (aider)
6f266c0090 fix: Skip test fixture watch files in blame script 2024-12-11 20:38:11 -08:00
Paul Gauthier
baa7352ca6 chore: Skip test fixture files in blame script 2024-12-11 20:38:11 -08:00
Paul Gauthier (aider)
fdb1c8d99a chore: Remove comment about skipping test files 2024-12-11 20:37:29 -08:00
Paul Gauthier
79f5dba094 chore: Skip test fixture files in blame script 2024-12-11 20:37:28 -08:00
Paul Gauthier
2134965f16 initial 2024-12-11 20:34:00 -08:00
Paul Gauthier
77b7a59a27 copy 2024-12-11 20:33:30 -08:00
Paul Gauthier
365e7126d0 refactor: Remove is_source_file function and check in FileWatcher 2024-12-11 20:30:47 -08:00
Paul Gauthier (aider)
d3daf9d159 feat: Add IDE, env, log, and cache patterns to ignore list 2024-12-11 20:30:17 -08:00
Paul Gauthier
8d59a519a6 chore: Add comment about gitignore patterns 2024-12-11 20:29:28 -08:00
Paul Gauthier (aider)
239262f360 style: Format gitignore patterns for readability 2024-12-11 20:28:07 -08:00
Paul Gauthier (aider)
9eb938fd6f feat: Expand gitignore patterns to include editor temp files 2024-12-11 20:28:03 -08:00
Paul Gauthier
3fcbf1a43f feat: Add text editor temp files to gitignore 2024-12-11 20:28:02 -08:00
Paul Gauthier
2b7ee271df copy 2024-12-11 20:24:08 -08:00
Paul Gauthier
11512c6281 feat: Add support for ! and ? action comments 2024-12-11 20:23:29 -08:00
Paul Gauthier (aider)
b16ba547ab test: Add assertion for line count in test_ai_comment_pattern 2024-12-11 20:21:50 -08:00
Paul Gauthier (aider)
e5b8899b4c fix: Remove extra comment in test_watch.py 2024-12-11 20:21:46 -08:00
Paul Gauthier (aider)
fee3e9e63b feat: Add test for watch_question.js fixture 2024-12-11 20:21:42 -08:00
Paul Gauthier
57a24d30b5 test: Add test for watch_question.js ai comments 2024-12-11 20:21:41 -08:00
Paul Gauthier (aider)
5a83610fb1 refactor: Update ai comment action handling to support '?' 2024-12-11 20:16:10 -08:00
Paul Gauthier
96086f12c6 fix: Correct ai comment regex to match ai? and ai! 2024-12-11 20:16:09 -08:00
Paul Gauthier
a6ee3ce07f cleanup 2024-12-11 20:12:26 -08:00
Paul Gauthier (aider)
5f36ddd425 test: Fix multiline mode tests and add toggle test 2024-12-11 20:10:30 -08:00
Paul Gauthier (aider)
bec67074e0 feat: Add tests for multiline input mode 2024-12-11 20:10:26 -08:00
Paul Gauthier (aider)
895c92cdae fix: Remove unused import buffer_has_focus 2024-12-11 20:05:04 -08:00
Paul Gauthier
7406a5bc26 refactor: Move is_searching filter to top level 2024-12-11 20:05:01 -08:00
Paul Gauthier (aider)
ef97714404 fix: Reorder imports to satisfy linter 2024-12-11 20:00:00 -08:00
Paul Gauthier (aider)
6d6daee511 fix: Use correct filter for custom enter keybinding 2024-12-11 19:59:56 -08:00
Paul Gauthier (aider)
32cd1c2a65 fix: Fix Ctrl-R reverse search enter key selection 2024-12-11 19:55:08 -08:00
Paul Gauthier
abad920a8a feat: Add gemini-2.0-flash-exp model settings 2024-12-11 19:47:44 -08:00
Paul Gauthier
e1ab49e100 copy 2024-12-11 19:43:31 -08:00
Paul Gauthier
df300e89a2 refac prompt out 2024-12-11 19:42:01 -08:00
Paul Gauthier
9a278bed21 feat: Add gemini flash model alias 2024-12-11 16:00:31 -08:00
Paul Gauthier
4a7fc084ce refactor: move watch prompt text to separate module 2024-12-11 15:07:30 -08:00
Paul Gauthier
2649e736fb chore: update model name in leaderboard to include date 2024-12-11 15:00:18 -08:00
Paul Gauthier
42ac891e28 docs: add bash syntax highlighting to code blocks in docs 2024-12-11 14:49:22 -08:00
Paul Gauthier
4dc3b9072e feat: increase retry timeout for benchmarking 2024-12-11 14:26:28 -08:00
Paul Gauthier
ae3235b099 feat: add Gemini 2.0 Flash model leaderboard entry 2024-12-11 13:55:52 -08:00
Paul Gauthier
7cc5e0d577 docs: add Yi Lightning model test results to leaderboard 2024-12-11 13:54:39 -08:00
Paul Gauthier
f6b956dc8e refactor: simplify voice command and improve installation docs 2024-12-11 13:52:33 -08:00
Paul Gauthier (aider)
fcb2bacd1e style: format benchmark.py with black 2024-12-11 13:09:52 -08:00
Paul Gauthier (aider)
a9401e921e feat: add sleep option between tests in single-threaded mode 2024-12-11 13:09:45 -08:00
Paul Gauthier
02e7e315b2 copy 2024-12-11 12:54:50 -08:00
Paul Gauthier
def72a64e0 copy 2024-12-11 12:45:56 -08:00
Paul Gauthier
46e7672197 copy 2024-12-11 12:42:19 -08:00
Paul Gauthier
2f8a5ce935 copy 2024-12-11 12:40:13 -08:00
Paul Gauthier (aider)
730e5bd831 fix: add error handling for clipboard operations in copy_context command 2024-12-11 12:10:12 -08:00
Paul Gauthier
b7984a05af copy 2024-12-11 09:51:51 -08:00
Paul Gauthier
5d4af67186 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-11 07:21:18 -08:00
paul-gauthier
370e08cf4d Merge pull request #2601 from miradnanali/multiline-mode
Implement /multiline-mode, swaps Enter & Meta-Enter
2024-12-11 07:21:09 -08:00
Mir Adnan ALI
aaf7e3f943 Implement multiline-mode, swaps Enter & Meta-Enter 2024-12-11 09:09:58 -05:00
Paul Gauthier
fbde0936e7 revert 2024-12-10 11:20:25 -08:00
Paul Gauthier (aider)
af48f7bab4 fix: update artifact upload path to match Jekyll build directory 2024-12-10 11:12:23 -08:00
Paul Gauthier
61def89878 ci: downgrade upload-pages-artifact action to v3 2024-12-10 11:07:42 -08:00
Paul Gauthier (aider)
88e86cee77 chore: upgrade upload-pages-artifact action to v4 2024-12-10 11:04:46 -08:00
Paul Gauthier
acc1625406 Merge branch 'main' of github.com:Aider-AI/aider 2024-12-10 11:03:20 -08:00
Paul Gauthier
502f448053 copy 2024-12-10 09:59:56 -08:00
paul-gauthier
55b081884c Merge pull request #2592 from JeongJuhyeon/patch-1
Add '?' to set of punctuations to strip for file mentions
2024-12-10 08:41:38 -08:00
Paul Gauthier
fd67171908 copy 2024-12-10 08:21:28 -08:00
Paul Gauthier
16a53aa641 set version to 0.68.1.dev 2024-12-10 08:19:44 -08:00
Paul Gauthier
4aec676950 version bump to 0.68.0 2024-12-10 08:18:06 -08:00
Paul Gauthier
d8fff0e90a copy 2024-12-10 08:01:18 -08:00
Paul Gauthier
57ad6cc3ea Update shell cmd prompt: no multi-line, run from project root 2024-12-10 07:59:24 -08:00
Paul Gauthier
2b46a8b9c9 copy 2024-12-10 07:39:58 -08:00
Paul Gauthier
4d1a2e8c53 copy 2024-12-10 07:19:00 -08:00
Paul Gauthier
58b1409bd2 copy 2024-12-10 07:02:26 -08:00
Paul Gauthier
a2525dbf56 docs: remove deprecated label from DeepSeek model names 2024-12-10 06:59:58 -08:00
Paul Gauthier
36eb2a31b5 docs: add DeepSeek-V2.5-1210 model leaderboard results 2024-12-10 06:57:18 -08:00
Paul Gauthier
0483bfc9cb docs: add Gemini whole file edit experiment results to leaderboard 2024-12-10 06:47:41 -08:00
JeongJuhyeon
3f63a64254 Add '?' to set of punctuations to strip for file mentions 2024-12-10 22:10:00 +09:00
Paul Gauthier
16332b285f copy 2024-12-09 20:27:38 -08:00
Paul Gauthier
f7371f6faf copy 2024-12-09 20:27:32 -08:00
Paul Gauthier
92d29805f1 copy 2024-12-09 20:06:36 -08:00
Paul Gauthier
4a37d07acb fix: skip context copy when using placeholder input 2024-12-09 18:46:44 -08:00
Paul Gauthier
bb4c61e9cc copy 2024-12-09 15:38:40 -08:00
Paul Gauthier
f4e5515c82 docs: clarify read-only command description and behavior 2024-12-09 15:37:48 -08:00
Paul Gauthier (aider)
141a2df19c test: add test for bulk conversion to read-only mode 2024-12-09 15:36:03 -08:00
Paul Gauthier (aider)
e2385b4922 feat: add bulk conversion to read-only mode when no files specified 2024-12-09 15:34:59 -08:00
Paul Gauthier
9974fb50f7 feat: add auto-conversion of /added files to read-only mode 2024-12-09 15:34:57 -08:00
Paul Gauthier
c5d51d62c4 feat: add architect command and improve coder class documentation 2024-12-09 15:30:01 -08:00
Paul Gauthier
4fcbf28f91 Restore interactive shell #2415 2024-12-09 15:23:39 -08:00
Paul Gauthier
f678b664ff refactor: Move website files list to global scope 2024-12-09 15:01:12 -08:00
Paul Gauthier (aider)
4206920a7d style: fix whitespace in blame.py 2024-12-09 15:00:47 -08:00
Paul Gauthier (aider)
ad2e5ead54 refactor: extract website files into dedicated list 2024-12-09 15:00:41 -08:00
Paul Gauthier
eb72719117 chore: add website file to blame script and improve comments 2024-12-09 15:00:40 -08:00
Paul Gauthier (aider)
20b46afbf2 style: update cookie consent box colors to dark grey 2024-12-09 14:41:12 -08:00
Paul Gauthier (aider)
1925e4a7f4 feat: add cookie persistence config to consent banner 2024-12-09 14:39:19 -08:00
Paul Gauthier (aider)
1a12322354 feat: add GDPR-compliant cookie consent for PostHog analytics 2024-12-09 14:33:54 -08:00
Paul Gauthier
73f3f4ec7e feat: add analytics events for copy-paste mode and AI comments 2024-12-09 10:47:30 -08:00
Paul Gauthier (aider)
a8c42f453a style: format FileWatcher instantiation for better readability 2024-12-09 10:32:08 -08:00
Paul Gauthier (aider)
79dd0c5ba6 feat: add analytics events for file watching and AI comments 2024-12-09 10:31:59 -08:00
Paul Gauthier
89bc3b6b16 feat: add analytics event hooks to file watcher 2024-12-09 10:31:57 -08:00
Paul Gauthier (aider)
a997dd6c49 fix: use LiteLLMExceptions class instead of undefined litellm_ex 2024-12-09 07:46:09 -08:00
Paul Gauthier (aider)
6aa80d2a4c feat: handle cost calculation differently for context window vs other errors 2024-12-09 07:45:50 -08:00
Paul Gauthier
f009e8fb14 add pip as a req 2024-12-09 06:51:06 -08:00
Paul Gauthier
a8dde17155 add posthog 2024-12-09 06:50:58 -08:00
Paul Gauthier
cbcbff341b style: format voice.py and suppress syntax warnings 2024-12-08 18:14:30 -08:00
Paul Gauthier (aider)
e50992bb93 style: remove unused shutil import 2024-12-08 18:12:36 -08:00
Paul Gauthier
fa6c3068c0 refactor: simplify pip install command by using sys.executable directly 2024-12-08 18:12:30 -08:00
Paul Gauthier
dd9bdca572 copy 2024-12-08 14:44:51 -08:00
Paul Gauthier
3f7dffe47d copy 2024-12-08 14:30:31 -08:00
Paul Gauthier
c7fde14458 copy 2024-12-08 12:05:41 -08:00
Paul Gauthier
57f4186cad refactor: optimize analytics event tracking with system info as super properties 2024-12-08 11:49:12 -08:00
Paul Gauthier
fa5a6021b1 copy 2024-12-08 11:49:01 -08:00
Paul Gauthier
42ae279b91 fix: update test cases to use Model wrapper class 2024-12-07 15:09:04 -08:00
Paul Gauthier
a74cdbfc28 test: update test_sendchat to use Model class and fix assertion 2024-12-07 15:07:39 -08:00
Paul Gauthier (aider)
a56fa567dd test: update print call count assertions in sendchat tests 2024-12-07 13:44:08 -08:00
Paul Gauthier (aider)
c9c2d5ab6f test: update test assertions to check model objects instead of names 2024-12-07 13:38:57 -08:00
Paul Gauthier (aider)
ccf460c1f7 refactor: update simple_send_with_retries to use model object and handle temperature 2024-12-07 13:37:14 -08:00
Paul Gauthier
2325f542b8 copy 2024-12-07 13:04:06 -08:00
Paul Gauthier (aider)
63fdf3f3f6 style: format git blame command arguments for better readability 2024-12-07 11:54:14 -08:00
Paul Gauthier (aider)
efa83bdf34 feat: add git blame move/copy detection for better attribution 2024-12-07 11:54:10 -08:00
Paul Gauthier
5705bda818 style: Update settings section headings to use lowercase 2024-12-07 11:51:19 -08:00
Paul Gauthier
20042334ff refactor: reorganize command line arguments and improve help messages 2024-12-07 11:45:20 -08:00
Paul Gauthier (aider)
7ae9569816 docs: update deprecated OpenAI args help text to suggest --set-env 2024-12-07 11:23:05 -08:00
Paul Gauthier
cacba526b3 refactor: reorganize API key and environment settings arguments 2024-12-07 11:23:03 -08:00
Paul Gauthier
50f203cc8a cleanup 2024-12-07 11:07:59 -08:00
Paul Gauthier
3efcd154f3 refactor: consolidate API key and environment variable handling 2024-12-07 10:55:29 -08:00
Paul Gauthier (aider)
bdb08d7c78 style: format long lines in main.py 2024-12-07 10:52:27 -08:00
Paul Gauthier (aider)
f3874dd40a feat: add deprecation warnings for legacy API key arguments 2024-12-07 10:52:21 -08:00
Paul Gauthier
935c39e341 refactor: move API key handling earlier in startup sequence 2024-12-07 10:52:19 -08:00
Paul Gauthier (aider)
7ddcc30e8d style: format test_main.py line breaks 2024-12-07 08:23:58 -08:00
Paul Gauthier (aider)
13ff038e58 feat: add --api-key flag to set provider API keys as env vars 2024-12-07 08:23:50 -08:00
Paul Gauthier
1d4918dfbf refactor: Remove analytics event for invalid env var format 2024-12-07 08:11:10 -08:00
Paul Gauthier (aider)
ba14ab96da refactor: update env format test to check return value instead of SystemExit 2024-12-07 08:09:56 -08:00
Paul Gauthier
054e0820b7 refactor: Move --set-env processing after IO initialization 2024-12-07 08:09:52 -08:00
Paul Gauthier (aider)
af3d8dd6a7 style: format test_main.py with black 2024-12-07 08:08:40 -08:00
Paul Gauthier (aider)
e10d06cb47 test: add test coverage for --set-env functionality 2024-12-07 08:08:35 -08:00
Paul Gauthier (aider)
87a1469c1e style: fix string quote consistency in env setting split 2024-12-07 08:07:28 -08:00
Paul Gauthier (aider)
2492f1635c refactor: remove --set-env argument processing from main function 2024-12-07 08:07:23 -08:00
Paul Gauthier (aider)
b3305e6e19 refactor: move env var processing after IO initialization 2024-12-07 08:07:14 -08:00
Paul Gauthier (aider)
491d3e6606 style: fix string quote consistency in env setting split 2024-12-07 08:06:04 -08:00
Paul Gauthier (aider)
e41bf67f73 feat: add --set-env flag to set environment variables from command line 2024-12-07 08:05:57 -08:00
Paul Gauthier
66b99c4fa0 bumped deps to pickup litellm that supports OPENAI_ORGANIZATION 2024-12-07 07:57:29 -08:00
Paul Gauthier (aider)
f2f2645fe6 style: fix linting issues in watch.py 2024-12-07 07:54:24 -08:00
Paul Gauthier (aider)
4c77d0509a feat: add shell dotfile extensions to source file detection 2024-12-07 07:54:20 -08:00
Paul Gauthier
33d77f4355 feat: add shell script file extensions to source file detection 2024-12-07 07:54:18 -08:00
Paul Gauthier
ecf8617246 copy 2024-12-06 17:41:34 -08:00
Paul Gauthier
bec216d72a feat: add experimental Gemini model settings 2024-12-06 17:41:11 -08:00
Paul Gauthier (aider)
374e8c3307 feat: add video file exclusions to linkchecker 2024-12-06 15:12:12 -08:00
Paul Gauthier
b5eff8a9dd copy 2024-12-06 14:52:50 -08:00
Paul Gauthier (aider)
d53002a494 feat: add legend to chart showing diff and whole format patterns 2024-12-06 14:46:43 -08:00
Paul Gauthier (aider)
04662f0875 feat: add y-axis label to leaderboard charts 2024-12-06 14:45:25 -08:00
Paul Gauthier
aec92c7c17 refactor: update highlighted model name to 1206 2024-12-06 14:45:23 -08:00
Paul Gauthier (aider)
f7a7976923 feat: add red striped pattern for highlighted model with whole edit format 2024-12-06 14:43:05 -08:00
Paul Gauthier
1b50d4507f feat: update highlighted model to Qwen in leaderboard 2024-12-06 14:43:02 -08:00
Paul Gauthier (aider)
045cf887df feat: add pattern background for whole edit format bars in chart 2024-12-06 14:39:05 -08:00
Paul Gauthier (aider)
277d7c0e04 perf: cache diagonal pattern and optimize label access in chart rendering 2024-12-06 14:36:34 -08:00
Paul Gauthier (aider)
0e2c703e77 fix: add chart render call to ensure pattern reappears after row selection 2024-12-06 14:33:31 -08:00
Paul Gauthier (aider)
62b3f38f00 feat: add Patternomaly script tags for chart patterns 2024-12-06 14:31:52 -08:00
Paul Gauthier (aider)
422658293d fix: remove redundant pattern initialization and add Patternomaly script 2024-12-06 14:31:29 -08:00
Paul Gauthier (aider)
74cfd05642 feat: add edit format field and striped pattern for whole edits 2024-12-06 14:29:36 -08:00
Paul Gauthier (aider)
80586f1de3 feat: add line breaks for long x-axis labels in leaderboard chart 2024-12-06 14:22:54 -08:00
Paul Gauthier
a933177ac0 copy 2024-12-06 14:19:00 -08:00
Paul Gauthier
ade2db696b add emini-exp-1206 2024-12-06 14:14:07 -08:00
Paul Gauthier
cf266037ff copy 2024-12-06 14:10:11 -08:00
Paul Gauthier
5f14277fbf Remove -i when running shell commands, as it tosses local env 2024-12-06 13:56:57 -08:00
Paul Gauthier
b677349ec9 copy 2024-12-06 13:55:53 -08:00
Paul Gauthier
7f72d2a703 reraise EOFError to fix control-d 2024-12-06 13:55:41 -08:00
Paul Gauthier
779983cb85 feat: add missing dependency hints for Gemini and Bedrock 2024-12-06 13:43:49 -08:00
Paul Gauthier
f2d2ab51b1 copy 2024-12-06 13:27:26 -08:00
Paul Gauthier
0a54f8c4a7 copy 2024-12-06 12:25:45 -08:00
Paul Gauthier
881527ddd0 handle and test for trailing whitespace after ai 2024-12-06 12:23:27 -08:00
Paul Gauthier
cca4f894a8 style: fix indentation and remove redundant comment 2024-12-06 12:20:23 -08:00
Paul Gauthier (aider)
20dae33be5 fix: remove duplicate TreeContext parameters causing syntax error 2024-12-06 12:15:59 -08:00
Paul Gauthier (aider)
fd301c519d feat: add error handling for TreeContext with fallback to raw comments 2024-12-06 12:15:46 -08:00
Paul Gauthier
a96d87814b fix: handle ValueError in TreeContext by including raw comments 2024-12-06 12:15:45 -08:00
Paul Gauthier
2a3eefc5be copy 2024-12-06 12:09:20 -08:00
Paul Gauthier
c5dc10e3cd copy 2024-12-06 11:24:26 -08:00
Paul Gauthier
c251a93609 fix --test to automatically fix errors 2024-12-06 11:23:15 -08:00
Paul Gauthier
2df509effd added llama 3.3 70b 2024-12-06 10:47:40 -08:00
Paul Gauthier
53e0d670b3 copy 2024-12-06 09:45:41 -08:00
Paul Gauthier
ccd19d2c96 copy 2024-12-06 09:24:13 -08:00
Paul Gauthier
b69f084db9 copy 2024-12-06 09:10:35 -08:00
Paul Gauthier
9639395937 feat: improve AI comment handling and documentation 2024-12-06 08:46:52 -08:00
Paul Gauthier
117b7afd81 copy 2024-12-06 07:17:21 -08:00
Paul Gauthier
009c4dc8db copy 2024-12-06 07:02:06 -08:00
Paul Gauthier
0fdf3fc851 Merge branch 'copypaste' 2024-12-06 07:01:40 -08:00
Paul Gauthier
ffc2d91cef copy 2024-12-06 06:44:23 -08:00
Paul Gauthier
99975c8ff7 set version to 0.67.1.dev 2024-12-06 06:33:11 -08:00
Paul Gauthier
d44fd6b46d version bump to 0.67.0 2024-12-06 06:31:40 -08:00
Paul Gauthier
bd0a1426d7 copy 2024-12-06 06:31:30 -08:00
Paul Gauthier
353d144039 copy 2024-12-06 06:26:24 -08:00
Paul Gauthier
6efdf8a7f4 refactor: rename copypaste flag to copy-paste and update help text 2024-12-05 20:43:14 -08:00
Paul Gauthier
623770e24b refactor: move clipboard context functionality to commands.py 2024-12-05 20:41:40 -08:00
Paul Gauthier (aider)
402940a215 fix: store clipboard watcher instance in coder object 2024-12-05 20:36:04 -08:00
Paul Gauthier (aider)
7fea85cdcd style: reorder imports alphabetically 2024-12-05 20:35:51 -08:00
Paul Gauthier (aider)
93b3b7a184 feat: set auto-copy-context based on copypaste argument 2024-12-05 20:35:46 -08:00
Paul Gauthier
8f2a84629a refactor: move ClipboardWatcher import to top level 2024-12-05 20:35:44 -08:00
Paul Gauthier (aider)
7a1c1982f0 feat: implement auto copy context functionality 2024-12-05 20:35:04 -08:00
Paul Gauthier
75d8982b23 feat: add auto copy context feature with empty implementation 2024-12-05 20:35:02 -08:00
Paul Gauthier (aider)
87dbb56d7e style: fix trailing comma in system prompt dictionary 2024-12-05 18:57:50 -08:00
Paul Gauthier (aider)
aa217a3a43 fix: handle system reminder message construction properly 2024-12-05 18:57:47 -08:00
Paul Gauthier (aider)
22fc961dc0 fix: add empty list check before accessing last chat chunk 2024-12-05 18:57:24 -08:00
Paul Gauthier (aider)
8f57186945 style: remove trailing whitespace in editor_editblock_coder.py 2024-12-05 18:55:54 -08:00
Paul Gauthier (aider)
f8277c55a8 feat: add format_chat_markdown method to EditorEditBlockCoder 2024-12-05 18:55:50 -08:00
Paul Gauthier (aider)
6163713e34 style: fix linting issues in clipboard watcher initialization 2024-12-05 18:44:57 -08:00
Paul Gauthier (aider)
d2d5887936 feat: add clipboard watcher with --copypaste flag 2024-12-05 18:44:50 -08:00
Paul Gauthier (aider)
2a1065efc1 style: fix linting issues in copypaste.py 2024-12-05 18:43:16 -08:00
Paul Gauthier (aider)
6f36a97c4a feat: add clipboard watcher to monitor and update IO placeholder 2024-12-05 18:43:12 -08:00
Paul Gauthier
eeed79009a feat: add copypaste module for code manipulation 2024-12-05 18:43:09 -08:00
Paul Gauthier
9930057171 copy 2024-12-05 16:34:58 -08:00
Paul Gauthier (aider)
e14c84f2fb feat: add silent mode to read_text method 2024-12-05 16:22:44 -08:00
Paul Gauthier
a664c3dd47 feat: add silent mode option for read_text function 2024-12-05 16:22:42 -08:00
Paul Gauthier
73205b1f8c refactor: Move charset test to separate method in Spinner class 2024-12-05 14:57:13 -08:00
Paul Gauthier (aider)
3016d7b8f3 style: fix whitespace in utils.py 2024-12-05 14:46:37 -08:00
Paul Gauthier (aider)
beb3ddaa1f feat: add __main__ block to utils.py 2024-12-05 14:46:33 -08:00
Paul Gauthier
8db48fb4f1 refactor: simplify comment in utils.py 2024-12-05 14:46:31 -08:00
Paul Gauthier (aider)
6eb3641c1d feat: add main function with spinner demo 2024-12-05 14:45:50 -08:00
Paul Gauthier
8cfd64a7be chore: add comment for future spinner implementation 2024-12-05 14:45:47 -08:00
Paul Gauthier (aider)
e8d9ef269b style: fix linting issues in base_coder.py 2024-12-05 09:28:28 -08:00
Paul Gauthier (aider)
80f83da9b8 chore: remove debug dump() calls 2024-12-05 09:28:18 -08:00
Paul Gauthier
6b8e235f88 feat: add file watcher support to coder cloning 2024-12-05 09:28:16 -08:00
Paul Gauthier
a1d558a960 copy 2024-12-05 07:21:14 -08:00
Paul Gauthier
071ec80e2a copy 2024-12-05 07:06:43 -08:00
Paul Gauthier
995541db2e test: update GitHub Copilot model temperature test assertions 2024-12-05 07:04:17 -08:00
Paul Gauthier
9121026856 test: reorganize model test cases for better readability 2024-12-05 06:50:49 -08:00
Paul Gauthier (aider)
341419788e fix: update test to use correct temperature attribute name 2024-12-05 06:47:58 -08:00
Paul Gauthier (aider)
f8f69fadc4 style: Remove trailing whitespace in test_models.py 2024-12-05 06:47:33 -08:00
Paul Gauthier (aider)
4830d82a73 test: add temperature validation for GitHub Copilot models 2024-12-05 06:47:28 -08:00
Paul Gauthier
f3a228c79a feat: enable automatic exception capture in Posthog analytics 2024-12-04 19:55:56 -08:00
Paul Gauthier
4bf96aaca0 copy 2024-12-04 15:16:22 -08:00
Paul Gauthier
a8a026d509 copy 2024-12-04 15:10:21 -08:00
Paul Gauthier
e1fd506269 feat: add direct git diff output for pretty mode 2024-12-04 15:09:14 -08:00
Paul Gauthier
63e86b5673 copy 2024-12-04 14:27:53 -08:00
Paul Gauthier
238299c759 Add nova pro to leaderboard 2024-12-04 14:12:05 -08:00
Paul Gauthier
4e9272e31c copy 2024-12-04 14:09:01 -08:00
Paul Gauthier
8f92c32693 bumped deps to pickup litellm that supports bedrock nova 2024-12-04 14:06:27 -08:00
Paul Gauthier (aider)
699e283890 fix: add error handling for logfile writes in Analytics 2024-12-04 13:51:06 -08:00
Paul Gauthier
c51afc952c chore: add comment about ignoring OsErrors in analytics logging 2024-12-04 13:51:05 -08:00
Paul Gauthier
8fc030ba83 copy 2024-12-04 13:25:40 -08:00
Paul Gauthier
b754757c94 copy 2024-12-04 12:38:46 -08:00
Paul Gauthier (aider)
16bb40406a docs: add direct download link for watch demo video 2024-12-04 12:13:26 -08:00
Paul Gauthier (aider)
290ae04988 docs: add video demo of IDE watch mode functionality 2024-12-04 12:13:22 -08:00
Paul Gauthier
5c6f0e4d32 docs: add watch mode documentation 2024-12-04 12:13:20 -08:00
Paul Gauthier
14143243b1 test: remove mixpanel assertions from analytics tests 2024-12-04 11:58:35 -08:00
Paul Gauthier (aider)
0e2c0c78f2 style: fix indentation in analytics test file 2024-12-04 11:57:29 -08:00
Paul Gauthier
2a8e1f41d0 fix: Correct indentation in analytics test file 2024-12-04 11:57:26 -08:00
Paul Gauthier (aider)
4e1d18e206 style: remove unused Mixpanel import 2024-12-04 11:46:35 -08:00
Paul Gauthier
ff5a947a16 refactor: disable Mixpanel and add PostHog error handling 2024-12-04 11:46:27 -08:00
Paul Gauthier
26ddb1e479 prompt 2024-12-04 10:23:29 -08:00
Paul Gauthier
b2ddfd21c1 prompt 2024-12-04 10:20:18 -08:00
Paul Gauthier
efe9268bcb fix: add null check for filename in lint_edited method 2024-12-04 10:03:22 -08:00
Paul Gauthier
974e618541 refactor: remove debug prints and add lazy litellm loading verbosity flag 2024-12-04 09:38:20 -08:00
Paul Gauthier
d09d281a8d fix: update version file path and add debug logging for version checks 2024-12-04 09:09:56 -08:00
Paul Gauthier
43f3f54063 copy 2024-12-04 07:28:45 -08:00
Paul Gauthier
2b303e162c copy 2024-12-04 07:27:11 -08:00
Paul Gauthier
3947a755b1 initial 2024-12-04 07:27:09 -08:00
Paul Gauthier
0b764f4cb8 copy 2024-12-04 07:23:29 -08:00
Paul Gauthier
a0101c14a6 copy 2024-12-04 07:22:09 -08:00
Paul Gauthier
a4dcde2fc2 copy 2024-12-04 07:05:49 -08:00
Paul Gauthier (aider)
f6f5955753 style: fix whitespace in Spinner class 2024-12-04 07:04:04 -08:00
Paul Gauthier (aider)
d87f9fbd79 fix: add fallback to ASCII spinner when Unicode is not supported 2024-12-04 07:03:59 -08:00
Paul Gauthier
4c2bc47bf3 copy 2024-12-04 06:42:18 -08:00
Paul Gauthier
0d983d504b copy 2024-12-04 06:38:38 -08:00
Paul Gauthier (aider)
f26ccfa3e9 fix: preserve plus sign at end of line in chart labels 2024-12-04 06:31:56 -08:00
Paul Gauthier (aider)
1ec6ba35e0 feat: add linebreaks to x-axis labels using callback function 2024-12-04 06:25:32 -08:00
Paul Gauthier (aider)
0378ea40e7 style: fix import order and quote style 2024-12-04 06:20:01 -08:00
Paul Gauthier (aider)
656250dd33 feat: add ctrl-z support for process suspension 2024-12-04 06:19:56 -08:00
Paul Gauthier
b914fa6da8 copy 2024-12-03 19:00:41 -08:00
Paul Gauthier
db77ec43a7 copy 2024-12-03 19:00:28 -08:00
Paul Gauthier
1a9d4bfb1c initial 2024-12-03 18:51:03 -08:00
Paul Gauthier (aider)
7180cb049c feat: add QwQ to solo model color conditions in chart 2024-12-03 18:14:01 -08:00
Paul Gauthier
7e2769d8df fix: Update Qwen2.5 Coder model name in chart 2024-12-03 18:13:59 -08:00
Paul Gauthier (aider)
23faeeb5d0 style: update chart colors to include o1 models in solo category 2024-12-03 17:41:53 -08:00
Paul Gauthier (aider)
1e689a69a8 style: standardize legend text color to match chart defaults 2024-12-03 16:47:18 -08:00
Paul Gauthier (aider)
19004c0bad fix: consolidate datasets and add custom legend to prevent empty columns 2024-12-03 16:33:27 -08:00
Paul Gauthier (aider)
82059bb454 feat: add color-coded legend to chart for model types 2024-12-03 16:32:11 -08:00
Paul Gauthier (aider)
3fc846471e style: unify Qwen and Sonnet chart colors to green 2024-12-03 16:31:14 -08:00
Paul Gauthier (aider)
5379d45184 fix: correct color mapping for Qwen and Sonnet models in chart 2024-12-03 16:30:49 -08:00
Paul Gauthier
65b8bf6834 style: Update QWQ chart colors and font sizes 2024-12-03 16:30:47 -08:00
Paul Gauthier (aider)
107dfcac65 style: update Sonnet bar color to green in chart 2024-12-03 16:14:49 -08:00
Paul Gauthier (aider)
2a29d077ee feat: add distinct color for Qwen2.5 bar in chart 2024-12-03 16:11:54 -08:00
Paul Gauthier
3d7f1f39ce feat: add QWQ chart component for website visualization 2024-12-03 16:11:53 -08:00
Paul Gauthier
51c02da206 feat: add placeholder prompt when command fails with add flag 2024-12-03 08:43:54 -08:00
Paul Gauthier
16250e1b7c fix: Update model name assertion in test case 2024-12-03 08:35:38 -08:00
Paul Gauthier
3e02c5e4a8 copy 2024-12-03 08:28:32 -08:00
Paul Gauthier (aider)
40da942bfe fix: add expanduser() to properly handle tilde in paths 2024-12-03 08:25:58 -08:00
Paul Gauthier
44909912cd refactor: update GPT-4o model name to simpler format 2024-12-03 07:50:19 -08:00
Paul Gauthier
631ee98738 fix: add interactive flag to shell spawn in pexpect command 2024-12-03 07:45:46 -08:00
Paul Gauthier (aider)
0b68eea44a ci: add scheduled workflow to process GitHub issues every 12 hours 2024-12-03 06:53:40 -08:00
Paul Gauthier (aider)
47743e7f90 fix: add missing os import in test_browser.py 2024-12-02 17:56:50 -08:00
Paul Gauthier
b2da3545f9 test: disable analytics in test environment 2024-12-02 17:56:45 -08:00
Paul Gauthier
fb005dd01b fix: improve AI comment detection with case-insensitive matching 2024-12-02 08:57:50 -08:00
Paul Gauthier
5b2bd90071 fix: ensure consistent handling of "ai!" comment detection 2024-12-02 07:26:51 -08:00
Paul Gauthier
25e258e26a copy 2024-12-02 06:54:30 -08:00
Paul Gauthier (aider)
75d24974ec style: fix linting issues in watch.py 2024-12-01 18:25:23 -08:00
Paul Gauthier (aider)
981bd950da feat: add support for -- style comments in file watcher 2024-12-01 18:25:18 -08:00
Paul Gauthier
0ca1886695 refactor: add comment marker for AI-related code section 2024-12-01 18:25:17 -08:00
Paul Gauthier
bf2f9e0f7e add watchfiles dep 2024-12-01 16:44:57 -08:00
Paul Gauthier
d74f1c22ff un-format the py fixture 2024-12-01 16:27:10 -08:00
Paul Gauthier
882e09f253 copy 2024-12-01 15:57:41 -08:00
Paul Gauthier
ce05c0e13d refactor: remove unused FileWatcher import 2024-12-01 15:31:54 -08:00
Paul Gauthier (aider)
45c92f0868 style: add noqa comment to silence unused import warning 2024-12-01 15:31:38 -08:00
Paul Gauthier
e952f90b4c style: remove noqa comment from FileWatcher import 2024-12-01 15:31:28 -08:00
Paul Gauthier
97bf5e8d69 fix: improve AI comment detection accuracy in FileWatcher 2024-12-01 15:26:45 -08:00
Paul Gauthier (aider)
ee7bb71a05 style: fix import order and remove extra blank lines 2024-12-01 15:25:52 -08:00
Paul Gauthier (aider)
791cbab6f6 refactor: use get_ai_comments() instead of duplicating pattern matching 2024-12-01 15:25:47 -08:00
Paul Gauthier
e001b7fb46 fix: improve AI comment regex pattern to match end of line 2024-12-01 15:25:46 -08:00
Paul Gauthier (aider)
d8a75bef48 fix: update test to count unique AI comments instead of raw lines 2024-12-01 10:30:57 -08:00
Paul Gauthier (aider)
cfc4b79a05 style: fix whitespace in test_watch.py 2024-12-01 10:29:35 -08:00
Paul Gauthier (aider)
fb3e5c9aab test: add minimal coder instance for FileWatcher test 2024-12-01 10:29:32 -08:00
Paul Gauthier (aider)
6796d8f124 style: fix linting issues in test_watch.py 2024-12-01 10:28:32 -08:00
Paul Gauthier (aider)
154cb463e5 refactor: update test to use get_ai_comments method 2024-12-01 10:28:29 -08:00
Paul Gauthier (aider)
e9ce04ffe9 style: Fix linting issues in test_watch.py 2024-12-01 10:04:40 -08:00
Paul Gauthier (aider)
7a3fd11b6b refactor: update test to read AI comments from fixture files 2024-12-01 10:04:37 -08:00
Paul Gauthier (aider)
e885f848a6 fix: remove unused Path import from test_watch.py 2024-12-01 10:03:15 -08:00
Paul Gauthier (aider)
8343f074a2 style: fix trailing whitespace in test file 2024-12-01 10:02:57 -08:00
Paul Gauthier (aider)
cbadfd59db test: add JavaScript fixture and update comment pattern tests 2024-12-01 10:02:53 -08:00
Paul Gauthier (aider)
5d5fed62f2 style: Fix linting issues in test_watch.py 2024-12-01 10:01:59 -08:00
Paul Gauthier (aider)
c3d6484f6c test: add test cases for AI comment pattern matching 2024-12-01 10:01:53 -08:00
Paul Gauthier
315abec49c test: add watch module tests and fixtures 2024-12-01 10:01:52 -08:00
Paul Gauthier
221b382e69 refactor: improve AI comment pattern regex for better matching 2024-12-01 09:58:02 -08:00
Paul Gauthier (aider)
5fdbfef028 style: sort imports alphabetically in watch.py 2024-12-01 09:50:54 -08:00
Paul Gauthier (aider)
2cc671df75 refactor: update regex to only match ai comments at end of line 2024-12-01 09:50:50 -08:00
Paul Gauthier
ddbe2853ea refactor: improve AI comment processing in FileWatcher 2024-12-01 09:50:49 -08:00
Paul Gauthier (aider)
2ab1b4b1c2 style: fix linting issues and add missing newline 2024-12-01 09:43:47 -08:00
Paul Gauthier (aider)
c5adc92f8b chore: remove unnecessary comment from io.py 2024-12-01 09:43:43 -08:00
Paul Gauthier
96b6056411 chore: remove unused comment in io.py 2024-12-01 09:43:42 -08:00
Paul Gauthier (aider)
1108566e99 style: fix linting error by adding newline before error handling 2024-12-01 09:41:17 -08:00
Paul Gauthier (aider)
a54a5ee80d chore: remove comment from error handling block 2024-12-01 09:41:12 -08:00
Paul Gauthier
d57bc3ff01 chore: remove unused comment in io.py 2024-12-01 09:41:11 -08:00
Paul Gauthier (aider)
f02dca2dd8 style: fix linting error by adding newline before error handling 2024-12-01 09:40:25 -08:00
Paul Gauthier (aider)
ad186701d3 feat: add traceback printing for better error handling 2024-12-01 09:40:20 -08:00
Paul Gauthier
a04b9ea053 fix: handle file watcher operations only when it exists 2024-12-01 09:40:19 -08:00
Paul Gauthier
41e6fb961b feat: disable watch-files by default and update help text 2024-12-01 09:35:28 -08:00
Paul Gauthier (aider)
b2b43d2bd3 fix: only initialize FileWatcher when watch_files flag is set 2024-12-01 09:34:40 -08:00
Paul Gauthier
90339f9741 refactor: make FileWatcher initialization conditional on --watch-files flag 2024-12-01 09:34:39 -08:00
Paul Gauthier (aider)
260806053b style: fix linting issues and whitespace in args.py 2024-12-01 09:34:03 -08:00
Paul Gauthier (aider)
93c9bdcec7 feat: add --watch-files switch to control FileWatcher 2024-12-01 09:33:58 -08:00
Paul Gauthier
935832028a feat: add --watch-files switch for FileWatcher control 2024-12-01 09:33:56 -08:00
Paul Gauthier
c08f09b06b Merge branch 'main' into watch 2024-12-01 09:24:49 -08:00
Paul Gauthier
16410cf263 copy 2024-12-01 09:23:13 -08:00
Paul Gauthier
c62dde4c9c set version to 0.66.1.dev 2024-12-01 09:15:58 -08:00
Paul Gauthier
3fef1babcb version bump to 0.66.0 2024-12-01 09:14:21 -08:00
Paul Gauthier
59af7ed3bb refactor: improve file path handling and remove debug code 2024-12-01 08:27:15 -08:00
Paul Gauthier (aider)
ee4206099a chore: remove AI comment from watch.py 2024-12-01 08:26:39 -08:00
Paul Gauthier
8c1d9bffcd style: standardize AI comment format in watch.py 2024-12-01 08:26:38 -08:00
Paul Gauthier
a3a510308c style: fix indentation in comment instructions template 2024-12-01 08:26:21 -08:00
Paul Gauthier (aider)
97e292e251 chore: remove AI comment from FileWatcher class 2024-12-01 08:25:39 -08:00
Paul Gauthier
4c5aa6a326 chore: remove unused comment in FileWatcher class 2024-12-01 08:25:37 -08:00
Paul Gauthier (aider)
d1dd40590f feat: use TreeContext to show AI comments in file context 2024-12-01 08:25:06 -08:00
Paul Gauthier
c4764fa4d8 refactor: Add TODO for TreeContext-based comment rendering 2024-12-01 08:25:04 -08:00
Paul Gauthier (aider)
5dedb39048 chore: remove AI comment from FileWatcher class 2024-12-01 08:24:14 -08:00
Paul Gauthier
bc759a32e3 style: improve comment clarity in FileWatcher class 2024-12-01 08:24:13 -08:00
Paul Gauthier (aider)
dcc0841443 style: remove unused exception variable in FileWatcher 2024-12-01 08:23:51 -08:00
Paul Gauthier (aider)
9b0388d00a chore: remove AI-related comments from code 2024-12-01 08:23:36 -08:00
Paul Gauthier
99a1e42381 refactor: improve AI comment detection and file handling 2024-12-01 08:23:35 -08:00
Paul Gauthier
9b4df54432 refactor: simplify file change handling and interrupt logic 2024-12-01 08:14:18 -08:00
Paul Gauthier (aider)
aac0c0f037 feat: extend AI comment regex to match "ai!" suffix 2024-12-01 08:11:08 -08:00
Paul Gauthier
a8f20196b2 feat: extend AI comment regex to match 'ai!' suffix 2024-12-01 08:11:07 -08:00
Paul Gauthier (aider)
a8bae3fb01 style: format gitignore path loading for better readability 2024-12-01 08:09:16 -08:00
Paul Gauthier (aider)
e8ccc030c0 refactor: simplify file watcher filter function implementation 2024-12-01 08:09:13 -08:00
Paul Gauthier
aa6d9779d3 refactor: simplify gitignore filter function creation 2024-12-01 08:08:54 -08:00
Paul Gauthier (aider)
b1dbf340b8 fix: correct undefined filter_func and remove unnecessary f-string 2024-12-01 08:07:48 -08:00
Paul Gauthier (aider)
27540d16ed refactor: remove ignore_func parameter from FileWatcher.start() 2024-12-01 08:07:21 -08:00
Paul Gauthier
2e63f62215 refactor: remove unused ignore_func parameter from FileWatcher.start method 2024-12-01 08:07:20 -08:00
Paul Gauthier (aider)
633ba293a3 style: remove extra whitespace and newlines 2024-12-01 08:06:24 -08:00
Paul Gauthier (aider)
679c960ea1 refactor: move filter_func creation to FileWatcher.__init__ 2024-12-01 08:06:20 -08:00
Paul Gauthier
cf91101a48 refactor: simplify file watcher and improve AI comment handling 2024-12-01 08:06:18 -08:00
Paul Gauthier (aider)
344d90aea0 style: fix whitespace in FileWatcher class 2024-12-01 07:55:43 -08:00
Paul Gauthier (aider)
8b7fa6f845 refactor: move bang checking logic earlier in file processing flow 2024-12-01 07:55:39 -08:00
Paul Gauthier
2eb7f78248 refactor: Move bang check logic to file change detection 2024-12-01 07:55:38 -08:00
Paul Gauthier (aider)
9a5925b1ad refactor: fix has_bangs initialization and use |= operator 2024-12-01 07:54:44 -08:00
Paul Gauthier
60f2da370f fix: correct comment about AI bang operator logic 2024-12-01 07:54:42 -08:00
Paul Gauthier (aider)
7ee69628a3 refactor: update get_ai_comments to return line nums, comments and bang status 2024-12-01 07:54:11 -08:00
Paul Gauthier
a64f14db51 refactor: modify get_ai_comments to return line nums, comments and has_bang 2024-12-01 07:54:09 -08:00
Paul Gauthier (aider)
1c84fc97a1 refactor: remove try/except block and AI comment from watch.py 2024-12-01 07:52:47 -08:00
Paul Gauthier
8b371ead92 refactor: remove unnecessary try/except block in FileWatcher 2024-12-01 07:50:17 -08:00
Paul Gauthier (aider)
14417f70af style: fix linting issue in list comprehension spacing 2024-12-01 07:49:17 -08:00
Paul Gauthier (aider)
96c6d408fb refactor: simplify get_ai_comments to return only line numbers and bang status 2024-12-01 07:49:14 -08:00
Paul Gauthier
cd922e919e refactor: simplify get_ai_comments to return only line numbers and bang status 2024-12-01 07:49:11 -08:00
Paul Gauthier (aider)
c56f06fbcb style: fix string quote consistency in comment parsing 2024-12-01 07:48:39 -08:00
Paul Gauthier (aider)
21dffa26b9 refactor: rename and enhance get_ai_comments to track line numbers and bang status 2024-12-01 07:48:35 -08:00
Paul Gauthier
a131d5ad35 refactor: simplify AI comment detection and improve comment handling 2024-12-01 07:48:33 -08:00
Paul Gauthier (aider)
b5dbb1d39d refactor: simplify file content check using direct io.read_text and regex search 2024-12-01 07:28:37 -08:00
Paul Gauthier
bd3231d8dd refactor: add comment about using io.read_text for AI marker detection 2024-12-01 07:28:35 -08:00
Paul Gauthier (aider)
4d96de3514 refactor: compile regex pattern as class attribute for better performance 2024-12-01 07:26:23 -08:00
Paul Gauthier
c9df6c11c5 refactor: extract regex pattern into compiled class attribute 2024-12-01 07:26:21 -08:00
Paul Gauthier (aider)
56aaa08224 refactor: use get_ai_comment method instead of direct regex matching 2024-12-01 07:25:51 -08:00
Paul Gauthier
014aeccde6 style: add comment to use self.ai_comments() method 2024-12-01 07:25:50 -08:00
Paul Gauthier (aider)
dcfa993806 feat: implement AI comment refresh and processing in FileWatcher 2024-12-01 07:24:55 -08:00
Paul Gauthier
69688cffd6 refactor: Add placeholder for AI comments refresh in FileWatcher 2024-12-01 07:24:53 -08:00
Paul Gauthier (aider)
769a31b7e3 refactor: remove redundant encoding parameter from FileWatcher 2024-12-01 07:22:40 -08:00
Paul Gauthier (aider)
78c20a8c25 style: fix linting issues in watch.py 2024-12-01 07:22:16 -08:00
Paul Gauthier (aider)
bb1b3fdca1 refactor: replace file operations with io.read_text() 2024-12-01 07:22:12 -08:00
Paul Gauthier
f872b20a97 refactor: improve file watcher change detection and comment handling 2024-12-01 07:22:11 -08:00
Paul Gauthier (aider)
f36239712f refactor: replace global VERBOSE with instance variable in FileWatcher 2024-12-01 06:13:01 -08:00
Paul Gauthier
74108dd680 Merge branch 'main' into watch 2024-12-01 06:09:21 -08:00
Paul Gauthier
16af1751a6 copy 2024-12-01 06:09:11 -08:00
Paul Gauthier
b0e138952e libportaudio2 2024-12-01 06:06:42 -08:00
Paul Gauthier (aider)
1271c037ef ci: add PortAudio system dependency for Ubuntu tests 2024-12-01 06:06:03 -08:00
Paul Gauthier
36b59ba617 copy 2024-12-01 06:04:49 -08:00
Paul Gauthier (aider)
b671db7108 fix: correct sounddevice module mocking in voice tests 2024-11-30 19:15:58 -08:00
Paul Gauthier (aider)
9304b80b69 fix: update sounddevice mocking in voice tests 2024-11-30 19:15:40 -08:00
Paul Gauthier (aider)
03c2964364 style: Format code with black and sort imports 2024-11-30 19:15:20 -08:00
Paul Gauthier (aider)
49c78f2797 test: update voice tests to mock audio dependencies properly 2024-11-30 19:15:16 -08:00
Paul Gauthier
1a8d112055 copy 2024-11-30 18:38:40 -08:00
Paul Gauthier (aider)
7b193d693f docs: clarify Control-Up/Down for message history navigation 2024-11-30 18:23:34 -08:00
Paul Gauthier (aider)
e8fa5c36c2 feat: add ctrl-up/down bindings for history navigation 2024-11-30 18:21:47 -08:00
Paul Gauthier
c9a27ba6ac Merge branch 'main' into watch 2024-11-30 15:48:19 -08:00
Paul Gauthier (aider)
a6e162c37a refactor: remove unused Mock import from test_voice.py 2024-11-30 15:43:18 -08:00
Paul Gauthier (aider)
9c55b7a317 style: Remove extra blank line in test_voice.py 2024-11-30 15:43:13 -08:00
Paul Gauthier (aider)
4ef4e8cd72 test: remove test_record_and_transcribe test case 2024-11-30 15:43:10 -08:00
Paul Gauthier (aider)
e9942737c6 style: remove trailing whitespace in test_voice.py 2024-11-30 15:42:45 -08:00
Paul Gauthier (aider)
5c208dba41 fix: improve voice test mocking to handle async prompt behavior 2024-11-30 15:42:42 -08:00
Paul Gauthier (aider)
ba032ce60e fix: update voice tests to match expected behavior 2024-11-30 15:42:12 -08:00
Paul Gauthier (aider)
2fe0dda8af style: remove unused tempfile import from test_voice.py 2024-11-30 15:41:38 -08:00
Paul Gauthier (aider)
97daff4a10 style: format test_voice.py with black and sort imports 2024-11-30 15:41:19 -08:00
Paul Gauthier (aider)
caeceb58a5 test: add voice input device tests with mocked hardware dependencies 2024-11-30 15:41:15 -08:00
Paul Gauthier
3739d48e52 test: add basic voice tests 2024-11-30 15:41:11 -08:00
Paul Gauthier
858fdb02ec copy 2024-11-30 14:05:51 -08:00
Paul Gauthier (aider)
b0cbb071e6 style: fix line wrapping in update-history.py 2024-11-30 14:01:25 -08:00
Paul Gauthier (aider)
f222739b0d fix: preserve older entries when updating HISTORY.md 2024-11-30 14:01:21 -08:00
Paul Gauthier (aider)
a280f5d5b2 style: remove trailing whitespace in update-history.py 2024-11-30 13:59:57 -08:00
Paul Gauthier (aider)
cef333a01c feat: extract history content up to end of base version section 2024-11-30 13:59:51 -08:00
Paul Gauthier (aider)
24bd016a1a style: Fix whitespace in update-history script 2024-11-30 13:59:09 -08:00
Paul Gauthier (aider)
3c44f824cb refactor: optimize HISTORY.md processing to work with relevant portion only 2024-11-30 13:59:05 -08:00
Paul Gauthier
3ee78ef557 skip ph.shutdown for faster exit 2024-11-30 13:29:39 -08:00
Paul Gauthier
d9b1bcbdcc remove no-op vscode detection 2024-11-30 13:25:13 -08:00
Paul Gauthier
283dd0b1f1 test: refactor read-only file path handling in command tests 2024-11-30 13:18:49 -08:00
Paul Gauthier (aider)
56345ddef9 test: add cross-platform test for relative path handling in drop command 2024-11-30 13:15:19 -08:00
Paul Gauthier (aider)
4631008f8c style: fix whitespace in commands.py 2024-11-30 13:12:37 -08:00
Paul Gauthier (aider)
e2ebde75be fix: improve /drop handling of relative paths with samefile check 2024-11-30 13:12:31 -08:00
Paul Gauthier
91613fcbf7 copy 2024-11-30 13:07:58 -08:00
Paul Gauthier
0b279143cc copy 2024-11-30 13:03:28 -08:00
Paul Gauthier
ade4847c61 feat: add timeout configuration for litellm requests 2024-11-30 13:03:20 -08:00
Paul Gauthier (aider)
a3e7203331 refactor: change timeout argument type from float to int 2024-11-30 13:00:24 -08:00
Paul Gauthier (aider)
bbabd38a48 feat: add timeout option for API calls 2024-11-30 12:59:39 -08:00
Paul Gauthier
eb996c1e42 copy 2024-11-30 12:19:55 -08:00
Paul Gauthier
bf0ad4cda1 test: simplify browser flag test by removing analytics flags 2024-11-30 12:18:18 -08:00
Paul Gauthier (aider)
c32af6536a ci: add fetch-depth: 0 to all checkout actions 2024-11-30 12:16:34 -08:00
Paul Gauthier (aider)
2437f9b051 chore: update actions/checkout to v4 in pages workflow 2024-11-30 12:16:07 -08:00
Paul Gauthier
0b781174bd ci: remove redundant AIDER_ANALYTICS_LOG environment variable 2024-11-30 11:37:33 -08:00
Paul Gauthier
f448d3e2db chore: add pytest-env and remove debug dump from tests 2024-11-30 11:35:40 -08:00
Paul Gauthier (aider)
6b4222ec48 test: add verification for pytest.ini environment variables 2024-11-30 11:32:49 -08:00
Paul Gauthier
3f770cc5c0 test: remove analytics env vars and add debug dump 2024-11-30 11:32:48 -08:00
Paul Gauthier (aider)
14902f5b9a ci: add analytics env vars to GitHub Actions workflows 2024-11-30 11:25:39 -08:00
Paul Gauthier (aider)
efdeb13bf5 test: disable analytics during test execution 2024-11-30 11:24:46 -08:00
Paul Gauthier
62558291b6 test: disable analytics in test environment 2024-11-30 10:59:46 -08:00
Paul Gauthier
edb0120bbf test: add analytics flags to browser test 2024-11-30 10:58:06 -08:00
Paul Gauthier
0dbaec553f refactor: Improve version handling and cleanup version-related files 2024-11-30 10:10:03 -08:00
Paul Gauthier
295040c94c feat: add exit event tracking for Control-C and /exit commands 2024-11-30 09:53:44 -08:00
Paul Gauthier
c1c4193b1d feat: add event tracking for message sending lifecycle 2024-11-30 09:49:07 -08:00
Paul Gauthier
d17f0a9e1f copy 2024-11-30 09:45:17 -08:00
Paul Gauthier
871030dadb fix: normalize path in cmd_drop test for cross-platform compatibility 2024-11-30 09:36:21 -08:00
Paul Gauthier
0ee9b74c0f Merge branch 'main' of github.com:Aider-AI/aider 2024-11-30 09:33:06 -08:00
paul-gauthier
82929f650c Merge pull request #2497 from preynal/main
feat: ability to select audio input device
2024-11-30 09:33:00 -08:00
Paul Gauthier
37b31c46bd copy 2024-11-30 09:19:22 -08:00
Paul Gauthier
c682bd858a copy 2024-11-30 09:19:01 -08:00
Paul Gauthier
2439891ee0 better handle __version__ errors 2024-11-30 09:18:17 -08:00
Philippe de Reynal
23825cafe7 fix options diff + missing docs 2024-11-30 11:33:10 +01:00
Philippe de Reynal
a8f6f1fce2 Merge branch 'Aider-AI:main' into main 2024-11-30 11:24:58 +01:00
Philippe de Reynal
e11faadf39 feat: ability to select audio input device 2024-11-30 11:24:34 +01:00
Paul Gauthier
2c7251f4b9 copy 2024-11-29 09:23:57 -08:00
Paul Gauthier
fb9f18fc9c copy 2024-11-29 09:23:14 -08:00
Paul Gauthier (aider)
93cd3d0d8b feat: add git diff output to history update script 2024-11-29 09:23:01 -08:00
Paul Gauthier
ed2479ea82 refactor: consolidate analytics exit events in main function 2024-11-29 09:20:52 -08:00
Paul Gauthier (aider)
accde0bfd0 feat: add analytics events before each return statement in main() 2024-11-29 09:17:16 -08:00
Paul Gauthier
7b34d9e4f4 copy 2024-11-28 15:53:00 -08:00
Paul Gauthier (aider)
6af71951af style: fix whitespace in benchmark.py 2024-11-28 14:01:50 -08:00
Paul Gauthier (aider)
3eed45dc3e fix: improve benchmark directory selection based on latest .md file timestamp 2024-11-28 14:01:45 -08:00
Paul Gauthier (aider)
320b059bc7 perf: optimize benchmark dir search by filtering on timestamp first 2024-11-28 14:00:12 -08:00
Paul Gauthier
a89ce06377 fix: correct glob pattern for finding latest benchmark directory 2024-11-28 14:00:10 -08:00
Paul Gauthier
e4a1d6fe89 copy 2024-11-28 11:21:37 -08:00
Paul Gauthier
93c625bb81 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-28 11:19:19 -08:00
Paul Gauthier
87f84fb82d copy 2024-11-28 11:18:30 -08:00
paul-gauthier
ce9e76a7dc Merge pull request #2489 from itlackey/benchmark/20241127
Benchmark/20241127
2024-11-28 11:01:54 -08:00
Paul Gauthier
4f3f1c5e23 better 2024-11-28 10:51:53 -08:00
itlackey
22076d401f Added ollama/granite3-dense:8b 2024-11-28 10:49:51 -06:00
itlackey
79ea82f147 Updated ollama/qwen2.5-coder:32b, added ollama/tulu3 2024-11-28 10:49:50 -06:00
Paul Gauthier
3785415632 copy 2024-11-27 17:49:35 -08:00
Paul Gauthier
35eda73ad1 Merge branch 'main' of github.com:Aider-AI/aider 2024-11-27 17:49:22 -08:00
Paul Gauthier (aider)
c8282fc8d3 style: fix whitespace in test_commands.py 2024-11-27 17:39:00 -08:00
Paul Gauthier (aider)
5030881934 test: add tests for /drop command with and without glob patterns 2024-11-27 17:38:54 -08:00
Paul Gauthier (aider)
bc1e3a7059 style: format list comprehension to single line 2024-11-27 17:35:11 -08:00
Paul Gauthier (aider)
ba17dceb4d feat: make /drop use substring matching for non-glob patterns 2024-11-27 17:35:05 -08:00
Paul Gauthier (aider)
4e689e20e9 style: add noqa comment to silence flake8 warning for FileWatcher import 2024-11-27 17:32:22 -08:00
Paul Gauthier
2f78b6f7f3 refactor: move FileWatcher initialization to main.py 2024-11-27 17:32:12 -08:00
Paul Gauthier (aider)
920917a47e feat: add .aider* to default gitignore patterns 2024-11-27 17:28:39 -08:00
Paul Gauthier
c1a7784781 fix: update file watcher to use absolute paths for changed files 2024-11-27 17:28:37 -08:00
paul-gauthier
62109f4ab1 Merge pull request #2480 from itlackey/benchmark/ollama-qwen2.5-14b 2024-11-27 16:51:50 -08:00
Paul Gauthier (aider)
c3a9c05455 fix: convert absolute paths to relative paths in file watcher 2024-11-27 16:31:48 -08:00
Paul Gauthier
333e4aa362 fix: update comment about relative filenames in FileWatcher 2024-11-27 16:31:41 -08:00
Paul Gauthier (aider)
59ce26f28a feat: update coder tracked files when AI comments detected 2024-11-27 16:31:19 -08:00
Paul Gauthier
2ff63aaebf refactor: simplify file change handling in FileWatcher 2024-11-27 16:31:18 -08:00
Paul Gauthier (aider)
8cf72a4409 refactor: simplify directory handling in FileWatcher class 2024-11-27 16:29:26 -08:00
Paul Gauthier
496b92536f feat: add input interruption on file changes in FileWatcher 2024-11-27 16:29:24 -08:00
Paul Gauthier (aider)
ac7900ecd7 style: sort imports alphabetically in main.py 2024-11-27 16:23:01 -08:00
Paul Gauthier (aider)
310832f111 feat: add FileWatcher import to fix undefined name error 2024-11-27 16:22:57 -08:00
Paul Gauthier
f69dd0ef8d fix: correct aiderignore path handling for file watching 2024-11-27 16:22:55 -08:00
Paul Gauthier (aider)
4b51bb2334 feat: add aiderignore support to FileWatcher initialization 2024-11-27 16:22:08 -08:00
Paul Gauthier
0d4f9f00ee refactor: Improve FileWatcher initialization with gitignore handling 2024-11-27 16:22:07 -08:00
Paul Gauthier (aider)
4a0100271f refactor: conditionally use git root and gitignore in FileWatcher initialization 2024-11-27 16:19:55 -08:00
Paul Gauthier
52a467806a feat: add gitignore support to FileWatcher initialization 2024-11-27 16:19:53 -08:00
Paul Gauthier (aider)
0fedecff58 refactor: move gitignores from FileWatcher.start() to constructor 2024-11-27 16:16:02 -08:00
Paul Gauthier
da4cb0aa62 refactor: move gitignore handling from start() to FileWatcher constructor 2024-11-27 16:16:00 -08:00
Paul Gauthier
3b8a771909 refactor: Move FileWatcher initialization to __init__ method 2024-11-27 16:15:08 -08:00
Paul Gauthier (aider)
f9bcfa14e0 refactor: update file watcher to use class-based implementation 2024-11-27 16:13:42 -08:00
Paul Gauthier (aider)
11c2eab967 style: fix code formatting and whitespace 2024-11-27 16:13:07 -08:00
Paul Gauthier (aider)
094d2e12a4 refactor: create FileWatcher class to encapsulate file watching logic 2024-11-27 16:13:00 -08:00
Paul Gauthier
af195a610c refactor: consolidate file watching code into dedicated class 2024-11-27 16:12:59 -08:00
Paul Gauthier
f7a05cf077 Merge branch 'main' into watch 2024-11-27 15:55:01 -08:00
Paul Gauthier
d54fbd6592 copy 2024-11-27 15:23:13 -08:00
Paul Gauthier
41b0868165 Merge branch 'main' into watch 2024-11-27 15:04:26 -08:00
Paul Gauthier
a1f5bfb746 copy 2024-11-27 09:36:17 -08:00
Paul Gauthier
3ab1018c66 copy 2024-11-27 09:29:35 -08:00
Paul Gauthier
62e96372fa bumped deps to pickup grep-ast 0.4.1 and disable Dart 2024-11-27 09:29:22 -08:00
Paul Gauthier
945d10f554 add event for repo size 2024-11-27 09:27:23 -08:00
Paul Gauthier
f44e5ae5f9 cleanup 2024-11-27 07:46:47 -08:00
Paul Gauthier
a67b665846 copy 2024-11-27 07:37:33 -08:00
Paul Gauthier
8fb23b414c rename 2024-11-27 07:18:21 -08:00
Paul Gauthier (aider)
f5100626a8 refactor: update language file extensions and paths in test code 2024-11-27 07:18:04 -08:00
Paul Gauthier (aider)
9ab46fade7 style: fix linting issues in test_repomap.py 2024-11-27 07:11:49 -08:00
Paul Gauthier (aider)
2ce01b157b refactor: simplify language test map and read from fixture files 2024-11-27 07:11:45 -08:00
itlackey
f714e42e11 Added qwen2.5-coder:14b running via ollama 2024-11-27 09:11:33 -06:00
Paul Gauthier (aider)
447b7af573 refactor: use fixture file for Java test instead of embedded code 2024-11-27 07:10:38 -08:00
Paul Gauthier (aider)
ec2b635a1a refactor: use fixture files for C, C++, and Elixir test content 2024-11-27 07:09:28 -08:00
Paul Gauthier (aider)
7465b4bf91 refactor: move TypeScript and TSX test code to fixture files 2024-11-27 07:06:50 -08:00
Paul Gauthier (aider)
4580fac6fa refactor: move test code samples to fixture files 2024-11-27 07:05:36 -08:00
Paul Gauthier (aider)
8c218e9edc refactor: move remaining language examples to fixture files 2024-11-27 07:05:10 -08:00
Paul Gauthier (aider)
44ceb8f1a0 style: Fix import order and add proper line spacing 2024-11-27 07:04:29 -08:00
Paul Gauthier (aider)
642c1c50fb refactor: move remaining test examples to fixture files 2024-11-27 07:04:23 -08:00
Paul Gauthier (aider)
4de8c25a3f refactor: move language examples to fixture files 2024-11-27 07:03:20 -08:00
Paul Gauthier
565f08a8e9 refactor: clean up test cases and remove redundant language examples 2024-11-27 07:03:18 -08:00
Paul Gauthier (aider)
a85ae206c9 refactor: add initial language test fixtures for C, C++, Elixir and Java 2024-11-27 06:59:58 -08:00
Paul Gauthier (aider)
9e9b5e8d46 feat: enhance language test snippets with comprehensive examples 2024-11-27 06:58:15 -08:00
Paul Gauthier
b623141a8f refactor: reorder test language cases in repomap tests 2024-11-27 06:58:13 -08:00
Paul Gauthier (aider)
631cdc37c4 test: enhance C# test case with more language features and symbols 2024-11-27 06:56:16 -08:00
Paul Gauthier
8d50bc0ef1 fix: correct key symbol in TypeScript test from UserGreeting to UserProps 2024-11-27 06:56:15 -08:00
Paul Gauthier (aider)
ae395fbb8f test: enhance TSX test fixture with more symbols and hooks 2024-11-27 06:54:37 -08:00
Paul Gauthier (aider)
10877a99f1 test: enhance Rust test snippet with trait and struct examples 2024-11-27 06:53:41 -08:00
Paul Gauthier (aider)
0faff91c72 test: enhance Python test case with class and type annotations 2024-11-27 06:52:31 -08:00
Paul Gauthier (aider)
00f79fecd0 test: enhance OCaml test case with module and type definitions 2024-11-27 06:51:53 -08:00
Paul Gauthier (aider)
203128d935 test: enhance Java test case with interface and implementation 2024-11-27 06:51:22 -08:00
Paul Gauthier
4f6e52aed0 test: add assertion for minimum result length in repomap test 2024-11-27 06:51:20 -08:00
Paul Gauthier (aider)
7bc7b2e3da style: Fix line length violations in test_repomap.py 2024-11-27 06:48:17 -08:00
Paul Gauthier (aider)
27f0ca3b08 feat: enhance JavaScript test snippet with class and module exports 2024-11-27 06:48:12 -08:00
Paul Gauthier
2337b2bb3e test: refactor repo map language test to run each language separately 2024-11-27 06:48:10 -08:00
Paul Gauthier (aider)
48ea13e130 style: format code with black and add trailing commas 2024-11-27 06:23:25 -08:00
Paul Gauthier (aider)
5c73ab26c0 test: add key symbol checks for each language parser 2024-11-27 06:23:21 -08:00
Paul Gauthier
947e4ce71d copy 2024-11-26 20:43:09 -08:00
Paul Gauthier (aider)
200295e3ee fix: add error handling for input history file permissions 2024-11-26 20:41:59 -08:00
Paul Gauthier (aider)
ded5fe5ec0 style: remove trailing whitespace in analytics.py 2024-11-26 20:37:34 -08:00
Paul Gauthier (aider)
7dffa943fa fix: handle analytics file access errors gracefully 2024-11-26 20:37:29 -08:00
Paul Gauthier
f702f67e27 copy 2024-11-26 20:28:48 -08:00
Paul Gauthier
a64956406d fix: improve PDF support detection and update model suggestions 2024-11-26 20:26:44 -08:00
Paul Gauthier
9c8bde2cff copy 2024-11-26 20:13:33 -08:00
Paul Gauthier
70a282ebf1 copy 2024-11-26 20:11:12 -08:00
Paul Gauthier (aider)
415652d38e style: reorder subprocess args to keep cwd consistent 2024-11-26 19:55:07 -08:00
Paul Gauthier (aider)
1a745e4fa9 fix: set cwd to repo root for shell commands in cmd_run 2024-11-26 19:53:09 -08:00
Paul Gauthier (aider)
973e86df27 fix: use cwd=root when executing shell commands 2024-11-26 19:52:46 -08:00
Paul Gauthier (aider)
1f2917681f feat: add cwd parameter to run_cmd for directory control 2024-11-26 19:52:06 -08:00
Paul Gauthier (aider)
28d1feacf5 refactor: simplify image file processing to use provided filenames directly 2024-11-26 19:49:53 -08:00
Paul Gauthier (aider)
cf4ef8605d style: remove trailing whitespace in base_coder.py 2024-11-26 19:48:48 -08:00
Paul Gauthier (aider)
4be3728273 feat: add image file support for read-only files 2024-11-26 19:48:42 -08:00
Paul Gauthier (aider)
34b8c3f47c fix: add dummy message to prevent empty cur_messages in test 2024-11-26 19:46:51 -08:00
Paul Gauthier (aider)
309893fd1e test: verify image file presence in LLM messages for read-only command 2024-11-26 19:45:01 -08:00
Paul Gauthier
705eb06e8d copy 2024-11-26 17:28:15 -08:00
Paul Gauthier
5cfcf255e9 fix: override PDF support detection for Claude 3.5 Sonnet 2024-11-26 17:27:05 -08:00
Paul Gauthier
b8f36c8277 feat: add PDF file support and refactor image handling 2024-11-26 17:19:28 -08:00
Paul Gauthier (aider)
73c1dc697f style: remove trailing whitespace in base_coder.py 2024-11-26 17:16:50 -08:00
Paul Gauthier (aider)
a9c4647461 feat: add support for both images and PDFs based on model capabilities 2024-11-26 17:16:43 -08:00
Paul Gauthier
aaeaa24153 feat: add PDF support and improve image handling in chat messages 2024-11-26 17:16:41 -08:00
Paul Gauthier
59a7494770 Merge branch 'main' into watch 2024-11-26 16:03:06 -08:00
Paul Gauthier
b2232cda7b refactor: modify check_for_urls to return modified input string 2024-11-26 15:04:19 -08:00
Paul Gauthier (aider)
3ba4aca268 refactor: improve error handling for .gitignore file operations 2024-11-26 15:01:50 -08:00
Paul Gauthier (aider)
f45533e20b style: fix line length and whitespace in gitignore handling 2024-11-26 15:00:38 -08:00
Paul Gauthier (aider)
2e7c5d6cfa fix: handle permission error when writing to .gitignore 2024-11-26 15:00:33 -08:00
Paul Gauthier
476acc7715 copy 2024-11-26 14:23:18 -08:00
Paul Gauthier
ab3b50296c copy 2024-11-26 14:12:16 -08:00
Paul Gauthier
60c29b2839 copy 2024-11-26 13:36:48 -08:00
Paul Gauthier
7972f5f4bc copy 2024-11-26 12:37:58 -08:00
Paul Gauthier
83a6865eb3 set version to 0.65.2.dev 2024-11-26 12:37:24 -08:00
Paul Gauthier
29a9b650ed version bump to 0.65.1 2024-11-26 12:35:54 -08:00
Paul Gauthier
dd48b740f9 test: update Claude model name tests to use 3.5 version 2024-11-26 12:33:58 -08:00
Paul Gauthier
401ce7a63d copy 2024-11-26 12:32:08 -08:00
Paul Gauthier
8218d085f7 fix: update Claude 3 model aliases to 3.5 versions 2024-11-26 12:31:54 -08:00
Paul Gauthier
abb3c936f7 refactor: simplify input interruption using placeholder variable 2024-11-26 10:58:22 -08:00
Paul Gauthier
0cb5aca81e Merge branch 'main' into watch 2024-11-26 10:47:38 -08:00
Paul Gauthier (aider)
554d274fff style: fix string quote consistency in blame.py 2024-11-26 10:47:04 -08:00
Paul Gauthier (aider)
13318219db feat: add YAML update capability to blame.py for --all-since 2024-11-26 10:46:55 -08:00
Paul Gauthier (aider)
474944fe74 style: fix string quote consistency in blame.py 2024-11-26 10:45:12 -08:00
Paul Gauthier (aider)
d1a49cd9ce feat: add YAML update capability to blame.py for --all-since 2024-11-26 10:45:08 -08:00
Paul Gauthier
139d89d817 Merge branch 'main' into watch 2024-11-26 10:30:25 -08:00
Paul Gauthier
61759f984c copy 2024-11-26 09:16:46 -08:00
Paul Gauthier
fedaede3b0 Merge branch 'main' into watch 2024-11-14 06:47:58 -08:00
Paul Gauthier
94ff9dc0a4 Merge branch 'main' into watch 2024-11-11 14:51:38 -08:00
Paul Gauthier
d4a88d08e4 Merge branch 'main' into watch 2024-11-07 13:44:51 -08:00
Paul Gauthier
7fc7ea6aba Merge branch 'main' into watch 2024-11-05 07:01:17 -08:00
Paul Gauthier
b57ad6929c Merge branch 'main' into watch 2024-11-01 11:27:29 -07:00
Paul Gauthier
550d274941 copy 2024-10-31 14:23:18 -07:00
Paul Gauthier
5a974483b9 Merge branch 'main' into watch 2024-10-31 14:19:37 -07:00
Paul Gauthier
34f34879c9 Merge branch 'main' into watch 2024-10-28 15:13:20 -07:00
Paul Gauthier
5c4b75909e refac 2024-10-26 07:31:28 -07:00
Paul Gauthier (aider)
41f126cad7 chore: disable verbose mode in watch.py 2024-10-25 16:23:45 -07:00
Paul Gauthier
c26d7d23b5 fix: improve regex pattern for AI comment detection 2024-10-25 16:23:44 -07:00
Paul Gauthier (aider)
4298ae00a9 style: fix linting issue in watch.py comment spacing 2024-10-25 16:21:25 -07:00
Paul Gauthier (aider)
47296e4294 fix: correct regex pattern for AI comment detection 2024-10-25 16:21:21 -07:00
Paul Gauthier
f6daab0728 feat: add support for inline AI comments in code files 2024-10-25 16:21:20 -07:00
Paul Gauthier (aider)
25dd9f1f35 style: fix linting issues and whitespace in watch.py 2024-10-25 16:20:57 -07:00
Paul Gauthier (aider)
130aedc474 fix: update regex pattern to match standalone "#ai" comments 2024-10-25 16:20:53 -07:00
Paul Gauthier
e958f40bd9 refactor: simplify file change processing and enable verbose mode 2024-10-25 16:20:52 -07:00
Paul Gauthier (aider)
ed2a2d7dc3 style: fix linting issues and format code 2024-10-25 16:10:56 -07:00
Paul Gauthier (aider)
0890b32425 refactor: move file change processing logic from io.py to watch.py 2024-10-25 16:10:49 -07:00
Paul Gauthier
2e5981ecb3 fix: extract AI comment content without prefix in file watcher 2024-10-25 16:10:48 -07:00
Paul Gauthier (aider)
ec00bb988c style: format nested list comprehension for better readability 2024-10-25 16:09:17 -07:00
Paul Gauthier (aider)
14a62586cc feat: add special handling for comments containing exclamation marks 2024-10-25 16:09:13 -07:00
Paul Gauthier
a8fe84acc7 fix: update changed_files handling to use dict keys instead of direct list 2024-10-25 16:09:12 -07:00
Paul Gauthier (aider)
144ba783a8 style: fix linting issues in watch.py 2024-10-25 16:05:55 -07:00
Paul Gauthier (aider)
8d81ef811e refactor: return full match including prefix in get_ai_comment function 2024-10-25 16:05:51 -07:00
Paul Gauthier
3d8ec25a33 fix: update AI comment extraction to include full match 2024-10-25 16:05:50 -07:00
Paul Gauthier (aider)
77f636f949 style: fix linting issues in watch.py 2024-10-25 16:03:42 -07:00
Paul Gauthier (aider)
aa86f02b1a feat: collect all AI comments from files instead of just first one 2024-10-25 16:03:39 -07:00
Paul Gauthier
05daab24a2 fix: update regex pattern for AI comment detection 2024-10-25 16:03:37 -07:00
Paul Gauthier (aider)
0960663811 style: add spacing between functions in watch.py 2024-10-25 16:00:59 -07:00
Paul Gauthier (aider)
150cc56b35 feat: add AI comment extraction from changed files 2024-10-25 16:00:55 -07:00
Paul Gauthier
7a9091fcae refactor: disable verbose mode and add comment for changed_file handling 2024-10-25 16:00:53 -07:00
Paul Gauthier (aider)
e6215d969d style: fix linting issues in watch.py 2024-10-25 15:58:45 -07:00
Paul Gauthier (aider)
9f1b8347f5 refactor: simplify regex pattern for matching AI comments 2024-10-25 15:58:41 -07:00
Paul Gauthier
311e1568d9 feat: improve file watching with verbose debug output and error handling 2024-10-25 15:58:39 -07:00
Paul Gauthier
c2dadd8054 Merge branch 'main' into watch 2024-10-25 15:54:31 -07:00
Paul Gauthier
88bdfd6548 cleanup 2024-10-25 15:11:02 -07:00
Paul Gauthier (aider)
70edb62a6b feat: pass encoding parameter to watch_source_files function 2024-10-25 13:24:06 -07:00
Paul Gauthier
6c2e0ccce5 refactor: remove interrupted_partial_input parameter from InputOutput class 2024-10-25 13:24:05 -07:00
Paul Gauthier (aider)
fc6e0dfa65 style: fix linting issues in watch.py 2024-10-25 13:23:49 -07:00
Paul Gauthier (aider)
54aebb7d98 feat: add encoding param to watch_source_files with error handling 2024-10-25 13:23:46 -07:00
Paul Gauthier (aider)
378c67d51f fix: update regex pattern to use word boundary instead of word character 2024-10-25 13:22:38 -07:00
Paul Gauthier (aider)
d535035bdd style: fix string quotes in regex pattern 2024-10-25 13:22:17 -07:00
Paul Gauthier (aider)
43790db48e feat: add AI marker detection in source file watcher 2024-10-25 13:22:13 -07:00
Paul Gauthier
d957adf062 refactor: remove debug dump() call from watch_source_files function 2024-10-25 13:22:11 -07:00
Paul Gauthier (aider)
ff8f3eb8c2 style: fix linting issues in io.py 2024-10-25 13:17:58 -07:00
Paul Gauthier (aider)
88c54c918c feat: store partial input when interrupting prompt 2024-10-25 13:17:54 -07:00
Paul Gauthier
1261a335f4 refactor: improve file change handling in input loop 2024-10-25 13:17:53 -07:00
Paul Gauthier (aider)
7587d76fd1 refactor: simplify file watcher thread cleanup by removing timeout 2024-10-25 12:59:09 -07:00
Paul Gauthier
8e81300f37 fix: improve error handling in input interruption flow 2024-10-25 12:59:07 -07:00
Paul Gauthier (aider)
a999020038 style: fix line length in watch_files function 2024-10-25 12:56:25 -07:00
Paul Gauthier (aider)
bc4664d62c feat: pass gitignore path to watch_source_files function 2024-10-25 12:56:20 -07:00
Paul Gauthier
6a1754aa6a feat: add file change monitoring with gitignore support 2024-10-25 12:56:19 -07:00
Paul Gauthier (aider)
da7bb312c2 style: remove extra blank lines in io.py 2024-10-25 12:52:45 -07:00
Paul Gauthier (aider)
5b7f813f81 feat: add watch_source_files import to io.py 2024-10-25 12:52:41 -07:00
Paul Gauthier
923d9a0df2 fix: move file watcher cleanup to correct finally block 2024-10-25 12:52:39 -07:00
Paul Gauthier
c16224b37a wip 2024-10-25 12:49:52 -07:00
Paul Gauthier (aider)
01b5bdc829 style: fix indentation in get_input method 2024-10-25 12:48:54 -07:00
Paul Gauthier
5a0d66141f fix: change /edit to /add command for file changes 2024-10-25 12:48:53 -07:00
Paul Gauthier (aider)
8e873e7450 feat: return edit command when input interrupted by file change 2024-10-25 12:47:06 -07:00
Paul Gauthier (aider)
add3fa43c6 style: format watch_source_files function signature 2024-10-25 12:43:37 -07:00
Paul Gauthier (aider)
b985a8d47a feat: add clean shutdown for file watcher thread 2024-10-25 12:43:31 -07:00
Paul Gauthier (aider)
3db3150a7e feat: add input interruption from background threads 2024-10-25 12:33:07 -07:00
Paul Gauthier
17ce2a3cad Merge branch 'main' into watch 2024-10-25 10:59:02 -07:00
Paul Gauthier
e239304d89 refactor: simplify file change output format 2024-10-25 10:53:10 -07:00
Paul Gauthier
893f3f343f refactor: optimize file path handling in watch_source_files function 2024-10-25 10:51:09 -07:00
Paul Gauthier
5918a18dee ignore emacs tmp files 2024-10-25 10:50:35 -07:00
Paul Gauthier (aider)
c08dcff56d style: fix linting issues in watch.py 2024-10-25 09:55:54 -07:00
Paul Gauthier (aider)
f33cd4e419 refactor: improve path handling in watch_source_files filter function 2024-10-25 09:55:50 -07:00
Paul Gauthier
a625426a28 fix: improve path handling in file watcher filter function 2024-10-25 09:55:49 -07:00
Paul Gauthier (aider)
24e66337ff style: fix line length in watch.py by wrapping function call 2024-10-25 09:51:55 -07:00
Paul Gauthier (aider)
d06f1ecf19 feat: add optional ignore function to watch_source_files 2024-10-25 09:51:52 -07:00
Paul Gauthier (aider)
9c6831c360 style: format argparse argument for better readability 2024-10-25 09:47:53 -07:00
Paul Gauthier (aider)
64ec0708c4 feat: support multiple gitignore files in file watcher 2024-10-25 09:47:50 -07:00
Paul Gauthier (aider)
34aa1e8de0 fix: handle paths outside watched directory in file watcher 2024-10-25 09:46:59 -07:00
Paul Gauthier (aider)
b0f31d8296 refactor: remove unused sys import from watch.py 2024-10-25 09:43:04 -07:00
Paul Gauthier (aider)
e5fe5199a3 style: fix import order and whitespace per linting rules 2024-10-25 09:42:51 -07:00
Paul Gauthier (aider)
45e95d1d00 feat: add gitignore support to file watcher 2024-10-25 09:42:47 -07:00
Paul Gauthier (aider)
21876e72fe style: Format watch.py with black and add newlines between functions 2024-10-25 09:41:33 -07:00
Paul Gauthier (aider)
81903598a8 feat: add file watcher for source code files with # or // comments 2024-10-25 09:41:30 -07:00
Paul Gauthier
290500ae17 feat: add file watcher module for monitoring changes 2024-10-25 09:41:27 -07:00
133 changed files with 6894 additions and 2879 deletions

View File

@@ -24,6 +24,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

View File

@@ -12,6 +12,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

29
.github/workflows/issues.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Process GitHub Issues
on:
schedule:
- cron: '0 */12 * * *' # Run every 12 hours
workflow_dispatch: # Allow manual triggers
jobs:
process-issues:
runs-on: ubuntu-latest
permissions:
issues: write # Required to modify issues
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests python-dotenv tqdm
- name: Run issues script
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python scripts/issues.py --yes

View File

@@ -36,7 +36,9 @@ jobs:
working-directory: aider/website
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
@@ -82,4 +84,4 @@ jobs:
- name: Run linkchecker
run: |
linkchecker https://aider.chat
linkchecker --ignore-url='.+\.(mp4|mov|avi)' https://aider.chat

View File

@@ -12,6 +12,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5

View File

@@ -25,12 +25,19 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libportaudio2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
@@ -38,5 +45,7 @@ jobs:
pip install .
- name: Run tests
env:
AIDER_ANALYTICS: false
run: |
pytest

View File

@@ -25,6 +25,8 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
@@ -38,6 +40,8 @@ jobs:
pip install .
- name: Run tests
env:
AIDER_ANALYTICS: false
run: |
pytest

2
.gitignore vendored
View File

@@ -11,5 +11,7 @@ _site
.jekyll-cache/
.jekyll-metadata
aider/__version__.py
aider/_version.py
.venv/
.#*
.gitattributes

View File

@@ -1,6 +1,79 @@
# Release history
### main branch
### Aider v0.69.0
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
- Now watches *all* files, not just certain source files.
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
- Full support for Gemini Flash 2.0 Exp:
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
- Improved clipboard error handling with helpful requirements install info.
- Ask 5% of users if they want to opt-in to analytics.
- `/voice` now lets you edit the transcribed text before sending.
- Disabled auto-complete in Y/N prompts.
- Aider wrote 60% of the code in this release.
### Aider v0.68.0
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
- New `--copy-paste` mode.
- New `/copy-context` command.
- [Set API keys and other environment variables for all providers from command line or yaml conf file](https://aider.chat/docs/config/aider_conf.html#storing-llm-keys).
- New `--api-key provider=key` setting.
- New `--set-env VAR=value` setting.
- Added bash and zsh support to `--watch-files`.
- Better error messages when missing dependencies for Gemini and Bedrock models.
- Control-D now properly exits the program.
- Don't count token costs when API provider returns a hard error.
- Bugfix so watch files works with files that don't have tree-sitter support.
- Bugfix so o1 models can be used as weak model.
- Updated shell command prompt.
- Added docstrings for all Coders.
- Reorganized command line arguments with improved help messages and grouping.
- Use the exact `sys.python` for self-upgrades.
- Added experimental Gemini models.
- Aider wrote 71% of the code in this release.
### Aider v0.67.0
- [Use aider in your IDE or editor](https://aider.chat/docs/usage/watch.html).
- Run `aider --watch-files` and it will watch for instructions you add to your source files.
- One-liner `# ...` or `// ...` comments that start or end with "AI" are instructions to aider.
- When aider sees "AI!" it reads and follows all the instructions in AI comments.
- Support for new Amazon Bedrock Nova models.
- When `/run` or `/test` have non-zero exit codes, pre-fill "Fix that" into the next message prompt.
- `/diff` now invokes `git diff` to use your preferred diff tool.
- Added Ctrl-Z support for process suspension.
- Spinner now falls back to ASCII art if fancy symbols throw unicode errors.
- `--read` now expands `~` home dirs.
- Enabled exception capture in analytics.
- [Aider wrote 61% of the code in this release.](https://aider.chat/HISTORY.html)
### Aider v0.66.0
- PDF support for Sonnet and Gemini models.
- Added `--voice-input-device` to select audio input device for voice recording, by @preynal.
- Added `--timeout` option to configure API call timeouts.
- Set cwd to repo root when running shell commands.
- Added Ctrl-Up/Down keyboard shortcuts for per-message history navigation.
- Improved error handling for failed .gitignore file operations.
- Improved error handling for input history file permissions.
- Improved error handling for analytics file access.
- Removed spurious warning about disabling pretty in VSCode.
- Removed broken support for Dart.
- Bugfix when scraping URLs found in chat messages.
- Better handling of __version__ import errors.
- Improved `/drop` command to support substring matching for non-glob patterns.
- Aider wrote 82% of the code in this release.
### Aider v0.65.1
- Bugfix to `--alias`.
### Aider v0.65.0
- 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.

View File

@@ -45,7 +45,7 @@ cog.out(open("aider/website/_includes/get-started.md").read())
You can get started quickly like this:
```
```bash
python -m pip install -U aider-chat
# Change directory into a git repo

View File

@@ -1,6 +1,20 @@
from packaging import version
__version__ = "0.69.1.dev"
safe_version = __version__
try:
from aider.__version__ import __version__
from aider._version import __version__
except Exception:
__version__ = "0.65.1.dev"
__version__ = safe_version + "+import"
if type(__version__) is not str:
__version__ = safe_version + "+type"
else:
try:
if version.parse(__version__) < version.parse(safe_version):
__version__ = safe_version + "+less"
except Exception:
__version__ = safe_version + "+parse"
__all__ = [__version__]

View File

@@ -5,7 +5,7 @@ import time
import uuid
from pathlib import Path
from mixpanel import Mixpanel, MixpanelException
from mixpanel import MixpanelException
from posthog import Posthog
from aider import __version__
@@ -50,8 +50,14 @@ class Analytics:
self.disable(False)
return
self.mp = Mixpanel(mixpanel_project_token)
self.ph = Posthog(project_api_key=posthog_project_api_key, host=posthog_host)
# self.mp = Mixpanel(mixpanel_project_token)
self.ph = Posthog(
project_api_key=posthog_project_api_key,
host=posthog_host,
on_error=self.posthog_error,
enable_exception_autocapture=True,
super_properties=self.get_system_info(), # Add system info to all events
)
def disable(self, permanently):
self.mp = None
@@ -78,7 +84,7 @@ class Analytics:
if not self.user_id:
return False
PERCENT = 2.5
PERCENT = 5
return self.is_uuid_in_percentage(self.user_id, PERCENT)
def is_uuid_in_percentage(self, uuid_str, percent):
@@ -105,9 +111,14 @@ class Analytics:
return uuid_str[:6] <= threshold
def get_data_file_path(self):
data_file = Path.home() / ".aider" / "analytics.json"
data_file.parent.mkdir(parents=True, exist_ok=True)
return data_file
try:
data_file = Path.home() / ".aider" / "analytics.json"
data_file.parent.mkdir(parents=True, exist_ok=True)
return data_file
except OSError:
# If we can't create/access the directory, just disable analytics
self.disable(permanently=False)
return None
def get_or_create_uuid(self):
self.load_data()
@@ -119,6 +130,9 @@ class Analytics:
def load_data(self):
data_file = self.get_data_file_path()
if not data_file:
return
if data_file.exists():
try:
data = json.loads(data_file.read_text())
@@ -130,14 +144,20 @@ class Analytics:
def save_data(self):
data_file = self.get_data_file_path()
if not data_file:
return
data = dict(
uuid=self.user_id,
permanently_disable=self.permanently_disable,
asked_opt_in=self.asked_opt_in,
)
# Allow exceptions; crash if we can't record permanently_disabled=True, etc
data_file.write_text(json.dumps(data, indent=4))
try:
data_file.write_text(json.dumps(data, indent=4))
except OSError:
# If we can't write the file, just disable analytics
self.disable(permanently=False)
def get_system_info(self):
return {
@@ -145,6 +165,7 @@ class Analytics:
"os_platform": platform.system(),
"os_release": platform.release(),
"machine": platform.machine(),
"aider_version": __version__,
}
def _redact_model_name(self, model):
@@ -158,6 +179,13 @@ class Analytics:
return model.name.split("/")[0] + "/REDACTED"
return None
def posthog_error(self):
"""disable posthog if we get an error"""
print("X" * 100)
# https://github.com/PostHog/posthog-python/blob/9e1bb8c58afaa229da24c4fb576c08bb88a75752/posthog/consumer.py#L86
# https://github.com/Aider-AI/aider/issues/2532
self.ph = None
def event(self, event_name, main_model=None, **kwargs):
if not self.mp and not self.ph and not self.logfile:
return
@@ -170,7 +198,6 @@ class Analytics:
properties["editor_model"] = self._redact_model_name(main_model.editor_model)
properties.update(kwargs)
properties.update(self.get_system_info()) # Add system info to all events
# Handle numeric values
for key, value in properties.items():
@@ -179,8 +206,6 @@ class Analytics:
else:
properties[key] = str(value)
properties["aider_version"] = __version__
if self.mp:
try:
self.mp.track(self.user_id, event_name, dict(properties))
@@ -197,10 +222,9 @@ class Analytics:
"user_id": self.user_id,
"time": int(time.time()),
}
with open(self.logfile, "a") as f:
json.dump(log_entry, f)
f.write("\n")
def __del__(self):
if self.ph:
self.ph.shutdown()
try:
with open(self.logfile, "a") as f:
json.dump(log_entry, f)
f.write("\n")
except OSError:
pass # Ignore OS errors when writing to logfile

View File

@@ -28,22 +28,10 @@ def get_parser(default_config_files, git_root):
config_file_parser_class=configargparse.YAMLConfigFileParser,
auto_env_var_prefix="AIDER_",
)
group = parser.add_argument_group("Main")
group = parser.add_argument_group("Main model")
group.add_argument(
"files", metavar="FILE", nargs="*", help="files to edit with an LLM (optional)"
)
group.add_argument(
"--openai-api-key",
metavar="OPENAI_API_KEY",
env_var="OPENAI_API_KEY",
help="Specify the OpenAI API key",
)
group.add_argument(
"--anthropic-api-key",
metavar="ANTHROPIC_API_KEY",
env_var="ANTHROPIC_API_KEY",
help="Specify the Anthropic API key",
)
group.add_argument(
"--model",
metavar="MODEL",
@@ -83,7 +71,7 @@ def get_parser(default_config_files, git_root):
const=gpt_4_model,
help=f"Use {gpt_4_model} model for the main chat",
)
gpt_4o_model = "gpt-4o-2024-08-06"
gpt_4o_model = "gpt-4o"
group.add_argument(
"--4o",
action="store_const",
@@ -144,43 +132,59 @@ def get_parser(default_config_files, git_root):
)
##########
group = parser.add_argument_group("Model Settings")
group = parser.add_argument_group("API Keys and settings")
group.add_argument(
"--openai-api-key",
help="Specify the OpenAI API key",
)
group.add_argument(
"--anthropic-api-key",
help="Specify the Anthropic API key",
)
group.add_argument(
"--openai-api-base",
help="Specify the api base url",
)
group.add_argument(
"--openai-api-type",
help="(deprecated, use --set-env OPENAI_API_TYPE=<value>)",
)
group.add_argument(
"--openai-api-version",
help="(deprecated, use --set-env OPENAI_API_VERSION=<value>)",
)
group.add_argument(
"--openai-api-deployment-id",
help="(deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)",
)
group.add_argument(
"--openai-organization-id",
help="(deprecated, use --set-env OPENAI_ORGANIZATION=<value>)",
)
group.add_argument(
"--set-env",
action="append",
metavar="ENV_VAR_NAME=value",
help="Set an environment variable (to control API settings, can be used multiple times)",
default=[],
)
group.add_argument(
"--api-key",
action="append",
metavar="PROVIDER=KEY",
help=(
"Set an API key for a provider (eg: --api-key provider=<key> sets"
" PROVIDER_API_KEY=<key>)"
),
default=[],
)
group = parser.add_argument_group("Model settings")
group.add_argument(
"--list-models",
"--models",
metavar="MODEL",
help="List known models which match the (partial) MODEL name",
)
group.add_argument(
"--openai-api-base",
metavar="OPENAI_API_BASE",
env_var="OPENAI_API_BASE",
help="Specify the api base url",
)
group.add_argument(
"--openai-api-type",
metavar="OPENAI_API_TYPE",
env_var="OPENAI_API_TYPE",
help="Specify the api_type",
)
group.add_argument(
"--openai-api-version",
metavar="OPENAI_API_VERSION",
env_var="OPENAI_API_VERSION",
help="Specify the api_version",
)
group.add_argument(
"--openai-api-deployment-id",
metavar="OPENAI_API_DEPLOYMENT_ID",
env_var="OPENAI_API_DEPLOYMENT_ID",
help="Specify the deployment_id",
)
group.add_argument(
"--openai-organization-id",
metavar="OPENAI_ORGANIZATION_ID",
env_var="OPENAI_ORGANIZATION_ID",
help="Specify the OpenAI organization ID",
)
group.add_argument(
"--model-settings-file",
metavar="MODEL_SETTINGS_FILE",
@@ -205,6 +209,12 @@ def get_parser(default_config_files, git_root):
default=True,
help="Verify the SSL cert when connecting to models (default: True)",
)
group.add_argument(
"--timeout",
type=int,
default=None,
help="Timeout in seconds for API calls (default: None)",
)
group.add_argument(
"--edit-format",
"--chat-mode",
@@ -255,17 +265,9 @@ def get_parser(default_config_files, git_root):
" If unspecified, defaults to the model's max_chat_history_tokens."
),
)
# This is a duplicate of the argument in the preparser and is a no-op by this time of
# argument parsing, but it's here so that the help is displayed as expected.
group.add_argument(
"--env-file",
metavar="ENV_FILE",
default=default_env_file(git_root),
help="Specify the .env file to load (default: .env in git root)",
)
##########
group = parser.add_argument_group("Cache Settings")
group = parser.add_argument_group("Cache settings")
group.add_argument(
"--cache-prompts",
action=argparse.BooleanOptionalAction,
@@ -280,7 +282,7 @@ def get_parser(default_config_files, git_root):
)
##########
group = parser.add_argument_group("Repomap Settings")
group = parser.add_argument_group("Repomap settings")
group.add_argument(
"--map-tokens",
type=int,
@@ -337,7 +339,7 @@ def get_parser(default_config_files, git_root):
)
##########
group = parser.add_argument_group("Output Settings")
group = parser.add_argument_group("Output settings")
group.add_argument(
"--dark-mode",
action="store_true",
@@ -436,7 +438,7 @@ def get_parser(default_config_files, git_root):
)
##########
group = parser.add_argument_group("Git Settings")
group = parser.add_argument_group("Git settings")
group.add_argument(
"--git",
action=argparse.BooleanOptionalAction,
@@ -523,6 +525,12 @@ def get_parser(default_config_files, git_root):
help="Skip the sanity check for the git repository (default: False)",
default=False,
)
group.add_argument(
"--watch-files",
action=argparse.BooleanOptionalAction,
default=False,
help="Enable/disable watching files for ai coding comments (default: False)",
)
group = parser.add_argument_group("Fixing and committing")
group.add_argument(
"--lint",
@@ -559,7 +567,7 @@ def get_parser(default_config_files, git_root):
group.add_argument(
"--test",
action="store_true",
help="Run tests and fix problems found",
help="Run tests, fix problems found and then exit",
default=False,
)
@@ -583,37 +591,8 @@ def get_parser(default_config_files, git_root):
default=False,
)
group = parser.add_argument_group("Other Settings")
group.add_argument(
"--file",
action="append",
metavar="FILE",
help="specify a file to edit (can be used multiple times)",
)
group.add_argument(
"--read",
action="append",
metavar="FILE",
help="specify a read-only file (can be used multiple times)",
)
group.add_argument(
"--vim",
action="store_true",
help="Use VI editing mode in the terminal (default: False)",
default=False,
)
group.add_argument(
"--chat-language",
metavar="CHAT_LANGUAGE",
default=None,
help="Specify the language to use in the chat (default: None, uses system settings)",
)
group.add_argument(
"--version",
action="version",
version=f"%(prog)s {__version__}",
help="Show the version number and exit",
)
#########
group = parser.add_argument_group("Upgrading")
group.add_argument(
"--just-check-update",
action="store_true",
@@ -646,47 +625,14 @@ def get_parser(default_config_files, git_root):
default=False,
)
group.add_argument(
"--apply",
metavar="FILE",
help="Apply the changes from the given file instead of running the chat (debug)",
)
group.add_argument(
"--apply-clipboard-edits",
action="store_true",
help="Apply clipboard contents as edits using the main model's editor format",
default=False,
)
group.add_argument(
"--yes-always",
action="store_true",
help="Always say yes to every confirmation",
default=None,
)
group.add_argument(
"-v",
"--verbose",
action="store_true",
help="Enable verbose output",
default=False,
)
group.add_argument(
"--show-repo-map",
action="store_true",
help="Print the repo map and exit (debug)",
default=False,
)
group.add_argument(
"--show-prompts",
action="store_true",
help="Print the system prompts and exit (debug)",
default=False,
)
group.add_argument(
"--exit",
action="store_true",
help="Do all startup activities then exit before accepting user input (debug)",
default=False,
"--version",
action="version",
version=f"%(prog)s {__version__}",
help="Show the version number and exit",
)
##########
group = parser.add_argument_group("Modes")
group.add_argument(
"--message",
"--msg",
@@ -705,6 +651,110 @@ def get_parser(default_config_files, git_root):
" (disables chat mode)"
),
)
group.add_argument(
"--gui",
"--browser",
action=argparse.BooleanOptionalAction,
help="Run aider in your browser (default: False)",
default=False,
)
group.add_argument(
"--copy-paste",
action=argparse.BooleanOptionalAction,
default=False,
help="Enable automatic copy/paste of chat between aider and web UI (default: False)",
)
group.add_argument(
"--apply",
metavar="FILE",
help="Apply the changes from the given file instead of running the chat (debug)",
)
group.add_argument(
"--apply-clipboard-edits",
action="store_true",
help="Apply clipboard contents as edits using the main model's editor format",
default=False,
)
group.add_argument(
"--exit",
action="store_true",
help="Do all startup activities then exit before accepting user input (debug)",
default=False,
)
group.add_argument(
"--show-repo-map",
action="store_true",
help="Print the repo map and exit (debug)",
default=False,
)
group.add_argument(
"--show-prompts",
action="store_true",
help="Print the system prompts and exit (debug)",
default=False,
)
##########
group = parser.add_argument_group("Voice settings")
group.add_argument(
"--voice-format",
metavar="VOICE_FORMAT",
default="wav",
choices=["wav", "mp3", "webm"],
help="Audio format for voice recording (default: wav). webm and mp3 require ffmpeg",
)
group.add_argument(
"--voice-language",
metavar="VOICE_LANGUAGE",
default="en",
help="Specify the language for voice using ISO 639-1 code (default: auto)",
)
group.add_argument(
"--voice-input-device",
metavar="VOICE_INPUT_DEVICE",
default=None,
help="Specify the input device name for voice recording",
)
######
group = parser.add_argument_group("Other settings")
group.add_argument(
"--file",
action="append",
metavar="FILE",
help="specify a file to edit (can be used multiple times)",
)
group.add_argument(
"--read",
action="append",
metavar="FILE",
help="specify a read-only file (can be used multiple times)",
)
group.add_argument(
"--vim",
action="store_true",
help="Use VI editing mode in the terminal (default: False)",
default=False,
)
group.add_argument(
"--chat-language",
metavar="CHAT_LANGUAGE",
default=None,
help="Specify the language to use in the chat (default: None, uses system settings)",
)
group.add_argument(
"--yes-always",
action="store_true",
help="Always say yes to every confirmation",
default=None,
)
group.add_argument(
"-v",
"--verbose",
action="store_true",
help="Enable verbose output",
default=False,
)
group.add_argument(
"--load",
metavar="LOAD_FILE",
@@ -725,12 +775,13 @@ def get_parser(default_config_files, git_root):
" or home directory)"
),
)
# This is a duplicate of the argument in the preparser and is a no-op by this time of
# argument parsing, but it's here so that the help is displayed as expected.
group.add_argument(
"--gui",
"--browser",
action=argparse.BooleanOptionalAction,
help="Run aider in your browser (default: False)",
default=False,
"--env-file",
metavar="ENV_FILE",
default=default_env_file(git_root),
help="Specify the .env file to load (default: .env in git root)",
)
group.add_argument(
"--suggest-shell-commands",
@@ -744,6 +795,12 @@ def get_parser(default_config_files, git_root):
default=True,
help="Enable/disable fancy input with history and completion (default: True)",
)
group.add_argument(
"--multiline",
action=argparse.BooleanOptionalAction,
default=False,
help="Enable/disable multi-line input mode with Meta-Enter to submit (default: False)",
)
group.add_argument(
"--detect-urls",
action=argparse.BooleanOptionalAction,
@@ -755,22 +812,6 @@ def get_parser(default_config_files, git_root):
help="Specify which editor to use for the /editor command",
)
##########
group = parser.add_argument_group("Voice Settings")
group.add_argument(
"--voice-format",
metavar="VOICE_FORMAT",
default="wav",
choices=["wav", "mp3", "webm"],
help="Audio format for voice recording (default: wav). webm and mp3 require ffmpeg",
)
group.add_argument(
"--voice-language",
metavar="VOICE_LANGUAGE",
default="en",
help="Specify the language for voice using ISO 639-1 code (default: auto)",
)
return parser

View File

@@ -103,6 +103,7 @@ class Coder:
detect_urls = True
ignore_mentions = None
chat_language = None
file_watcher = None
@classmethod
def create(
@@ -153,8 +154,9 @@ class Coder:
aider_commit_hashes=from_coder.aider_commit_hashes,
commands=from_coder.commands.clone(),
total_cost=from_coder.total_cost,
ignore_mentions=from_coder.ignore_mentions,
file_watcher=from_coder.file_watcher,
)
use_kwargs.update(update) # override to complete the switch
use_kwargs.update(kwargs) # override passed kwargs
@@ -175,7 +177,6 @@ class Coder:
def clone(self, **kwargs):
new_coder = Coder.create(from_coder=self, **kwargs)
new_coder.ignore_mentions = self.ignore_mentions
return new_coder
def get_announcements(self):
@@ -247,6 +248,9 @@ class Coder:
if self.done_messages:
lines.append("Restored previous conversation history.")
if self.io.multiline_mode:
lines.append("Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text")
return lines
def __init__(
@@ -283,6 +287,9 @@ class Coder:
suggest_shell_commands=True,
chat_language=None,
detect_urls=True,
ignore_mentions=None,
file_watcher=None,
auto_copy_context=False,
):
# Fill in a dummy Analytics if needed, but it is never .enable()'d
self.analytics = analytics if analytics is not None else Analytics()
@@ -293,7 +300,16 @@ class Coder:
self.aider_commit_hashes = set()
self.rejected_urls = set()
self.abs_root_path_cache = {}
self.ignore_mentions = set()
self.auto_copy_context = auto_copy_context
self.ignore_mentions = ignore_mentions
if not self.ignore_mentions:
self.ignore_mentions = set()
self.file_watcher = file_watcher
if self.file_watcher:
self.file_watcher.coder = self
self.suggest_shell_commands = suggest_shell_commands
self.detect_urls = detect_urls
@@ -665,6 +681,8 @@ class Coder:
def get_readonly_files_messages(self):
readonly_messages = []
# Handle non-image files
read_only_content = self.get_read_only_files_content()
if read_only_content:
readonly_messages += [
@@ -676,6 +694,15 @@ class Coder:
content="Ok, I will use these files as references.",
),
]
# Handle image files
images_message = self.get_images_message(self.abs_read_only_fnames)
if images_message is not None:
readonly_messages += [
images_message,
dict(role="assistant", content="Ok, I will use these images as references."),
]
return readonly_messages
def get_chat_files_messages(self):
@@ -697,7 +724,7 @@ class Coder:
dict(role="assistant", content=files_reply),
]
images_message = self.get_images_message()
images_message = self.get_images_message(self.abs_fnames)
if images_message is not None:
chat_files_messages += [
images_message,
@@ -706,23 +733,42 @@ class Coder:
return chat_files_messages
def get_images_message(self):
if not self.main_model.info.get("supports_vision"):
def get_images_message(self, fnames):
supports_images = self.main_model.info.get("supports_vision")
supports_pdfs = self.main_model.info.get("supports_pdf_input") or self.main_model.info.get(
"max_pdf_size_mb"
)
# https://github.com/BerriAI/litellm/pull/6928
supports_pdfs = supports_pdfs or "claude-3-5-sonnet-20241022" in self.main_model.name
if not (supports_images or supports_pdfs):
return None
image_messages = []
for fname, content in self.get_abs_fnames_content():
if is_image_file(fname):
with open(fname, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
mime_type, _ = mimetypes.guess_type(fname)
if mime_type and mime_type.startswith("image/"):
image_url = f"data:{mime_type};base64,{encoded_string}"
rel_fname = self.get_rel_fname(fname)
image_messages += [
{"type": "text", "text": f"Image file: {rel_fname}"},
{"type": "image_url", "image_url": {"url": image_url, "detail": "high"}},
]
for fname in fnames:
if not is_image_file(fname):
continue
mime_type, _ = mimetypes.guess_type(fname)
if not mime_type:
continue
with open(fname, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
image_url = f"data:{mime_type};base64,{encoded_string}"
rel_fname = self.get_rel_fname(fname)
if mime_type.startswith("image/") and supports_images:
image_messages += [
{"type": "text", "text": f"Image file: {rel_fname}"},
{"type": "image_url", "image_url": {"url": image_url, "detail": "high"}},
]
elif mime_type == "application/pdf" and supports_pdfs:
image_messages += [
{"type": "text", "text": f"PDF file: {rel_fname}"},
{"type": "image_url", "image_url": image_url},
]
if not image_messages:
return None
@@ -741,6 +787,7 @@ class Coder:
self.lint_outcome = None
self.test_outcome = None
self.shell_commands = []
self.message_cost = 0
if self.repo:
self.commit_before_message.append(self.repo.get_head_commit_sha())
@@ -751,9 +798,10 @@ class Coder:
self.io.user_input(with_message)
self.run_one(with_message, preproc)
return self.partial_response_content
while True:
try:
if not self.io.placeholder:
self.copy_context()
user_message = self.get_input()
self.run_one(user_message, preproc)
self.show_undo_hint()
@@ -762,6 +810,10 @@ class Coder:
except EOFError:
return
def copy_context(self):
if self.auto_copy_context:
self.commands.cmd_copy_context()
def get_input(self):
inchat_files = self.get_inchat_relative_files()
read_only_files = [self.get_rel_fname(fname) for fname in self.abs_read_only_fnames]
@@ -784,7 +836,7 @@ class Coder:
return self.commands.run(inp)
self.check_for_file_mentions(inp)
self.check_for_urls(inp)
inp = self.check_for_urls(inp)
return inp
@@ -830,11 +882,10 @@ 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 []
return inp
url_pattern = re.compile(r"(https?://[^\s/$.?#].[^\s]*[^\s,.])")
urls = list(set(url_pattern.findall(inp))) # Use set to remove duplicates
added_urls = []
group = ConfirmGroup(urls)
for url in urls:
if url not in self.rejected_urls:
@@ -844,11 +895,10 @@ class Coder:
):
inp += "\n\n"
inp += self.commands.cmd_web(url, return_content=True)
added_urls.append(url)
else:
self.rejected_urls.add(url)
return added_urls
return inp
def keyboard_interrupt(self):
now = time.time()
@@ -856,6 +906,7 @@ class Coder:
thresh = 2 # seconds
if self.last_keyboard_interrupt and now - self.last_keyboard_interrupt < thresh:
self.io.tool_warning("\n\n^C KeyboardInterrupt")
self.event("exit", reason="Control-C")
sys.exit()
self.io.tool_warning("\n\n^C again to exit")
@@ -1074,7 +1125,10 @@ class Coder:
# add the reminder anyway
total_tokens = 0
final = chunks.cur[-1]
if chunks.cur:
final = chunks.cur[-1]
else:
final = None
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.
@@ -1085,7 +1139,7 @@ class Coder:
):
if self.main_model.reminder == "sys":
chunks.reminder = reminder_message
elif self.main_model.reminder == "user" and final["role"] == "user":
elif self.main_model.reminder == "user" and final and final["role"] == "user":
# stuff it into the user message
new_content = (
final["content"]
@@ -1157,6 +1211,8 @@ class Coder:
return chunks
def send_message(self, inp):
self.event("message_send_starting")
self.cur_messages += [
dict(role="user", content=inp),
]
@@ -1236,6 +1292,7 @@ class Coder:
lines = traceback.format_exception(type(err), err, err.__traceback__)
self.io.tool_warning("".join(lines))
self.io.tool_error(str(err))
self.event("message_send_exception", exception=str(err))
return
finally:
if self.mdstream:
@@ -1370,9 +1427,7 @@ class Coder:
res.append("- Ask for smaller changes in each request.")
res.append("- Break your code into smaller source files.")
if "diff" not in self.main_model.edit_format:
res.append(
"- Use a stronger model like gpt-4o, sonnet or opus that can return diffs."
)
res.append("- Use a stronger model that can return diffs.")
if input_tokens >= max_input_tokens or total_tokens >= max_input_tokens:
res.append("")
@@ -1389,6 +1444,8 @@ class Coder:
def lint_edited(self, fnames):
res = ""
for fname in fnames:
if not fname:
continue
errors = self.linter.lint(self.abs_root_path(fname))
if errors:
@@ -1417,7 +1474,7 @@ class Coder:
words = set(word for word in content.split())
# drop sentence punctuation from the end
words = set(word.rstrip(",.!;:") for word in words)
words = set(word.rstrip(",.!;:?") for word in words)
# strip away all kinds of quotes
quotes = "".join(['"', "'", "`"])
@@ -1506,6 +1563,16 @@ class Coder:
yield from self.show_send_output_stream(completion)
else:
self.show_send_output(completion)
# Calculate costs for successful responses
self.calculate_and_show_tokens_and_cost(messages, completion)
except LiteLLMExceptions().exceptions_tuple() as err:
ex_info = LiteLLMExceptions().get_ex_info(err)
if ex_info.name == "ContextWindowExceededError":
# Still calculate costs for context window errors
self.calculate_and_show_tokens_and_cost(messages, completion)
raise
except KeyboardInterrupt as kbi:
self.keyboard_interrupt()
raise kbi
@@ -1523,8 +1590,6 @@ class Coder:
if args:
self.io.ai_output(json.dumps(args, indent=4))
self.calculate_and_show_tokens_and_cost(messages, completion)
def show_send_output(self, completion):
if self.verbose:
print(completion)
@@ -2086,7 +2151,7 @@ class Coder:
self.io.tool_output(f"Running {command}")
# Add the command to input history
self.io.add_to_input_history(f"/run {command.strip()}")
exit_status, output = run_cmd(command, error_print=self.io.tool_error)
exit_status, output = run_cmd(command, error_print=self.io.tool_error, cwd=self.root)
if output:
accumulated_output += f"Output from {command}\n{output}\n"

View File

@@ -35,7 +35,9 @@ ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
Just suggest shell commands this way, not example code.
Only suggest complete shell commands that are ready to execute, without placeholders.
Only suggest at most a few shell commands at a time, not more than 1-3.
Only suggest at most a few shell commands at a time, not more than 1-3, one per line.
Do not suggest multi-line shell commands.
All shell commands will run from the root directory of the user's project.
Use the appropriate shell based on the user's system info:
{platform}

View File

@@ -3,5 +3,6 @@ from .editor_editblock_prompts import EditorEditBlockPrompts
class EditorEditBlockCoder(EditBlockCoder):
"A coder that uses search/replace blocks, focused purely on editing files."
edit_format = "editor-diff"
gpt_prompts = EditorEditBlockPrompts()

View File

@@ -3,5 +3,6 @@ from .wholefile_coder import WholeFileCoder
class EditorWholeFileCoder(WholeFileCoder):
"A coder that operates on entire files, focused purely on editing files."
edit_format = "editor-whole"
gpt_prompts = EditorWholeFilePrompts()

View File

@@ -43,6 +43,8 @@ class Commands:
verify_ssl=self.verify_ssl,
args=self.args,
parser=self.parser,
verbose=self.verbose,
editor=self.editor,
)
def __init__(
@@ -101,6 +103,13 @@ class Commands:
("help", "Get help about using aider (usage, config, troubleshoot)."),
("ask", "Ask questions about your code without making any changes."),
("code", "Ask for changes to your code (using the best edit format)."),
(
"architect",
(
"Work with an architect model to design code changes, and an editor to make"
" them."
),
),
]
)
@@ -588,6 +597,10 @@ class Commands:
self.io.tool_output(f"Diff since {commit_before_message[:7]}...")
if self.coder.pretty:
run_cmd(f"git diff {commit_before_message}")
return
diff = self.coder.repo.diff_commits(
self.coder.pretty,
commit_before_message,
@@ -785,7 +798,8 @@ class Commands:
self.io.tool_error(f"Unable to read {matched_file}")
else:
self.coder.abs_fnames.add(abs_file_path)
self.io.tool_output(f"Added {matched_file} to the chat")
fname = self.coder.get_rel_fname(abs_file_path)
self.io.tool_output(f"Added {fname} to the chat")
self.coder.check_added_files()
def completions_drop(self):
@@ -808,15 +822,33 @@ class Commands:
# Expand tilde in the path
expanded_word = os.path.expanduser(word)
# Handle read-only files separately, without glob_filtered_to_repo
read_only_matched = [f for f in self.coder.abs_read_only_fnames if expanded_word in f]
# Handle read-only files with substring matching and samefile check
read_only_matched = []
for f in self.coder.abs_read_only_fnames:
if expanded_word in f:
read_only_matched.append(f)
continue
if read_only_matched:
for matched_file in read_only_matched:
self.coder.abs_read_only_fnames.remove(matched_file)
self.io.tool_output(f"Removed read-only file {matched_file} from the chat")
# Try samefile comparison for relative paths
try:
abs_word = os.path.abspath(expanded_word)
if os.path.samefile(abs_word, f):
read_only_matched.append(f)
except (FileNotFoundError, OSError):
continue
matched_files = self.glob_filtered_to_repo(expanded_word)
for matched_file in read_only_matched:
self.coder.abs_read_only_fnames.remove(matched_file)
self.io.tool_output(f"Removed read-only file {matched_file} from the chat")
# For editable files, use glob if word contains glob chars, otherwise use substring
if any(c in expanded_word for c in "*?[]"):
matched_files = self.glob_filtered_to_repo(expanded_word)
else:
# Use substring matching like we do for read-only files
matched_files = [
self.coder.get_rel_fname(f) for f in self.coder.abs_fnames if expanded_word in f
]
if not matched_files:
matched_files.append(expanded_word)
@@ -876,7 +908,7 @@ class Commands:
def cmd_run(self, args, add_on_nonzero_exit=False):
"Run a shell command and optionally add the output to the chat (alias: !)"
exit_status, combined_output = run_cmd(
args, verbose=self.verbose, error_print=self.io.tool_error
args, verbose=self.verbose, error_print=self.io.tool_error, cwd=self.coder.root
)
if combined_output is None:
@@ -902,13 +934,17 @@ class Commands:
dict(role="assistant", content="Ok."),
]
if add and exit_status != 0:
self.io.placeholder = "Fix that"
def cmd_exit(self, args):
"Exit the application"
self.coder.event("exit", reason="/exit")
sys.exit()
def cmd_quit(self, args):
"Exit the application"
sys.exit()
self.cmd_exit(args)
def cmd_ls(self, args):
"List all known files and indicate which are included in the chat session"
@@ -1080,43 +1116,23 @@ class Commands:
self.io.tool_error("To use /voice you must provide an OpenAI API key.")
return
try:
self.voice = voice.Voice(audio_format=self.args.voice_format)
self.voice = voice.Voice(
audio_format=self.args.voice_format, device_name=self.args.voice_input_device
)
except voice.SoundDeviceError:
self.io.tool_error(
"Unable to import `sounddevice` and/or `soundfile`, is portaudio installed?"
)
return
history_iter = self.io.get_input_history()
history = []
size = 0
for line in history_iter:
if line.startswith("/"):
continue
if line in history:
continue
if size + len(line) > 1024:
break
size += len(line)
history.append(line)
history.reverse()
history = "\n".join(history)
try:
text = self.voice.record_and_transcribe(history, language=self.voice_language)
text = self.voice.record_and_transcribe(None, language=self.voice_language)
except litellm.OpenAIError as err:
self.io.tool_error(f"Unable to use OpenAI whisper model: {err}")
return
if text:
self.io.add_to_input_history(text)
self.io.print()
self.io.user_input(text, log_only=False)
self.io.print()
return text
self.io.placeholder = text
def cmd_paste(self, args):
"""Paste image/text from the clipboard into the chat.\
@@ -1169,9 +1185,14 @@ class Commands:
self.io.tool_error(f"Error processing clipboard content: {e}")
def cmd_read_only(self, args):
"Add files to the chat that are for reference, not to be edited"
"Add files to the chat that are for reference only, or turn added files to read-only"
if not args.strip():
self.io.tool_error("Please provide filenames or directories to read.")
# Convert all files in chat to read-only
for fname in list(self.coder.abs_fnames):
self.coder.abs_fnames.remove(fname)
self.coder.abs_read_only_fnames.add(fname)
rel_fname = self.coder.get_rel_fname(fname)
self.io.tool_output(f"Converted {rel_fname} to read-only")
return
filenames = parse_quoted_filenames(args)
@@ -1320,6 +1341,10 @@ class Commands:
except Exception as e:
self.io.tool_error(f"Error saving commands to file: {e}")
def cmd_multiline_mode(self, args):
"Toggle multiline mode (swaps behavior of Enter and Meta+Enter)"
self.io.toggle_multiline_mode()
def cmd_copy(self, args):
"Copy the last assistant message to the clipboard"
all_messages = self.coder.done_messages + self.coder.cur_messages
@@ -1368,6 +1393,50 @@ class Commands:
if user_input.strip():
self.io.set_placeholder(user_input.rstrip())
def cmd_copy_context(self, args=None):
"""Copy the current chat context as markdown, suitable to paste into a web UI"""
chunks = self.coder.format_chat_chunks()
markdown = ""
# Only include specified chunks in order
for messages in [chunks.repo, chunks.readonly_files, chunks.chat_files]:
for msg in messages:
# Only include user messages
if msg["role"] != "user":
continue
content = msg["content"]
# Handle image/multipart content
if isinstance(content, list):
for part in content:
if part.get("type") == "text":
markdown += part["text"] + "\n\n"
else:
markdown += content + "\n\n"
args = args or ""
markdown += f"""
Just tell me how to edit the files to make the changes.
Don't give me back entire files.
Just show me the edits I need to make.
{args}
"""
try:
pyperclip.copy(markdown)
self.io.tool_output("Copied code context to clipboard.")
except pyperclip.PyperclipException as e:
self.io.tool_error(f"Failed to copy to clipboard: {str(e)}")
self.io.tool_output(
"You may need to install xclip or xsel on Linux, or pbcopy on macOS."
)
except Exception as e:
self.io.tool_error(f"An unexpected error occurred while copying to clipboard: {str(e)}")
def expand_subdir(file_path):
if file_path.is_file():

72
aider/copypaste.py Normal file
View File

@@ -0,0 +1,72 @@
import threading
import time
import pyperclip
class ClipboardWatcher:
"""Watches clipboard for changes and updates IO placeholder"""
def __init__(self, io, verbose=False):
self.io = io
self.verbose = verbose
self.stop_event = None
self.watcher_thread = None
self.last_clipboard = None
self.io.clipboard_watcher = self
def start(self):
"""Start watching clipboard for changes"""
self.stop_event = threading.Event()
self.last_clipboard = pyperclip.paste()
def watch_clipboard():
while not self.stop_event.is_set():
try:
current = pyperclip.paste()
if current != self.last_clipboard:
self.last_clipboard = current
self.io.interrupt_input()
self.io.placeholder = current
if len(current.splitlines()) > 1:
self.io.placeholder = "\n" + self.io.placeholder + "\n"
time.sleep(0.5)
except Exception as e:
if self.verbose:
from aider.dump import dump
dump(f"Clipboard watcher error: {e}")
continue
self.watcher_thread = threading.Thread(target=watch_clipboard, daemon=True)
self.watcher_thread.start()
def stop(self):
"""Stop watching clipboard for changes"""
if self.stop_event:
self.stop_event.set()
if self.watcher_thread:
self.watcher_thread.join()
self.watcher_thread = None
self.stop_event = None
def main():
"""Example usage of the clipboard watcher"""
from aider.io import InputOutput
io = InputOutput()
watcher = ClipboardWatcher(io, verbose=True)
try:
watcher.start()
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nStopped watching clipboard")
watcher.stop()
if __name__ == "__main__":
main()

View File

@@ -78,4 +78,13 @@ class LiteLLMExceptions:
def get_ex_info(self, ex):
"""Return the ExInfo for a given exception instance"""
import litellm
if ex.__class__ is litellm.APIConnectionError:
if "google.auth" in str(ex):
return ExInfo(
"APIConnectionError", False, "You need to: pip install google-generativeai"
)
if "boto3" in str(ex):
return ExInfo("APIConnectionError", False, "You need to: pip install boto3")
return self.exceptions.get(ex.__class__, ExInfo(None, None, None))

View File

@@ -108,9 +108,7 @@ class ChatSummary:
for model in self.models:
try:
summary = simple_send_with_retries(
model.name, summarize_messages, extra_params=model.extra_params
)
summary = simple_send_with_retries(model, summarize_messages)
if summary is not None:
summary = prompts.summary_prefix + summary
return [dict(role="user", content=summary)]

View File

@@ -1,5 +1,6 @@
import base64
import os
import signal
import time
import webbrowser
from collections import defaultdict
@@ -11,8 +12,10 @@ from pathlib import Path
from prompt_toolkit.completion import Completer, Completion, ThreadedCompleter
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
from prompt_toolkit.enums import EditingMode
from prompt_toolkit.filters import Condition, is_searching
from prompt_toolkit.history import FileHistory
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.keys import Keys
from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
from prompt_toolkit.styles import Style
@@ -173,6 +176,7 @@ class AutoCompleter(Completer):
class InputOutput:
num_error_outputs = 0
num_user_asks = 0
clipboard_watcher = None
def __init__(
self,
@@ -197,10 +201,14 @@ class InputOutput:
llm_history_file=None,
editingmode=EditingMode.EMACS,
fancy_input=True,
file_watcher=None,
multiline_mode=False,
):
self.placeholder = None
self.interrupted = False
self.never_prompts = set()
self.editingmode = editingmode
self.multiline_mode = multiline_mode
no_color = os.environ.get("NO_COLOR")
if no_color is not None and no_color != "":
pretty = False
@@ -261,6 +269,8 @@ class InputOutput:
else:
self.console = Console(force_terminal=False, no_color=True) # non-pretty
self.file_watcher = file_watcher
def _get_style(self):
style_dict = {}
if not self.pretty:
@@ -314,7 +324,7 @@ class InputOutput:
self.tool_error(f"{filename}: {e}")
return
def read_text(self, filename):
def read_text(self, filename, silent=False):
if is_image_file(filename):
return self.read_image(filename)
@@ -322,17 +332,21 @@ class InputOutput:
with open(str(filename), "r", encoding=self.encoding) as f:
return f.read()
except OSError as err:
self.tool_error(f"{filename}: unable to read: {err}")
if not silent:
self.tool_error(f"{filename}: unable to read: {err}")
return
except FileNotFoundError:
self.tool_error(f"{filename}: file not found error")
if not silent:
self.tool_error(f"{filename}: file not found error")
return
except IsADirectoryError:
self.tool_error(f"{filename}: is a directory")
if not silent:
self.tool_error(f"{filename}: is a directory")
return
except UnicodeError as e:
self.tool_error(f"{filename}: {e}")
self.tool_error("Use --encoding to set the unicode encoding.")
if not silent:
self.tool_error(f"{filename}: {e}")
self.tool_error("Use --encoding to set the unicode encoding.")
return
def write_text(self, filename, content, max_retries=5, initial_delay=0.1):
@@ -373,6 +387,13 @@ class InputOutput:
else:
print()
def interrupt_input(self):
if self.prompt_session and self.prompt_session.app:
# Store any partial input before interrupting
self.placeholder = self.prompt_session.app.current_buffer.text
self.interrupted = True
self.prompt_session.app.exit()
def get_input(
self,
root,
@@ -393,6 +414,8 @@ class InputOutput:
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
if edit_format:
show += edit_format
if self.multiline_mode:
show += (" " if edit_format else "") + "multi"
show += "> "
inp = ""
@@ -411,16 +434,51 @@ class InputOutput:
)
)
def suspend_to_bg(event):
"""Suspend currently running application."""
event.app.suspend_to_background()
kb = KeyBindings()
@kb.add(Keys.ControlZ, filter=Condition(lambda: hasattr(signal, "SIGTSTP")))
def _(event):
"Suspend to background with ctrl-z"
suspend_to_bg(event)
@kb.add("c-space")
def _(event):
"Ignore Ctrl when pressing space bar"
event.current_buffer.insert_text(" ")
@kb.add("escape", "c-m", eager=True)
@kb.add("c-up")
def _(event):
event.current_buffer.insert_text("\n")
"Navigate backward through history"
event.current_buffer.history_backward()
@kb.add("c-down")
def _(event):
"Navigate forward through history"
event.current_buffer.history_forward()
@kb.add("enter", eager=True, filter=~is_searching)
def _(event):
"Handle Enter key press"
if self.multiline_mode:
# In multiline mode, Enter adds a newline
event.current_buffer.insert_text("\n")
else:
# In normal mode, Enter submits
event.current_buffer.validate_and_handle()
@kb.add("escape", "enter", eager=True, filter=~is_searching) # This is Alt+Enter
def _(event):
"Handle Alt+Enter key press"
if self.multiline_mode:
# In multiline mode, Alt+Enter submits
event.current_buffer.validate_and_handle()
else:
# In normal mode, Alt+Enter adds a newline
event.current_buffer.insert_text("\n")
while True:
if multiline_input:
@@ -432,6 +490,13 @@ class InputOutput:
default = self.placeholder or ""
self.placeholder = None
self.interrupted = False
if not multiline_input:
if self.file_watcher:
self.file_watcher.start()
if self.clipboard_watcher:
self.clipboard_watcher.start()
line = self.prompt_session.prompt(
show,
default=default,
@@ -443,9 +508,30 @@ class InputOutput:
)
else:
line = input(show)
# Check if we were interrupted by a file change
if self.interrupted:
line = line or ""
if self.file_watcher:
cmd = self.file_watcher.process_changes()
return cmd
except EOFError:
raise
except Exception as err:
import traceback
self.tool_error(str(err))
self.tool_error(traceback.format_exc())
return ""
except UnicodeEncodeError as err:
self.tool_error(str(err))
return ""
finally:
if self.file_watcher:
self.file_watcher.stop()
if self.clipboard_watcher:
self.clipboard_watcher.stop()
if line.strip("\r\n") and not multiline_input:
stripped = line.strip("\r\n")
@@ -492,10 +578,13 @@ class InputOutput:
def add_to_input_history(self, inp):
if not self.input_history_file:
return
FileHistory(self.input_history_file).append_string(inp)
# Also add to the in-memory history if it exists
if self.prompt_session and self.prompt_session.history:
self.prompt_session.history.append_string(inp)
try:
FileHistory(self.input_history_file).append_string(inp)
# Also add to the in-memory history if it exists
if self.prompt_session and self.prompt_session.history:
self.prompt_session.history.append_string(inp)
except OSError as err:
self.tool_warning(f"Unable to write to input history file: {err}")
def get_input_history(self):
if not self.input_history_file:
@@ -560,6 +649,9 @@ class InputOutput:
group=None,
allow_never=False,
):
# Temporarily disable multiline mode for yes/no prompts
orig_multiline = self.multiline_mode
self.multiline_mode = False
self.num_user_asks += 1
question_id = (question, subject)
@@ -617,6 +709,7 @@ class InputOutput:
res = self.prompt_session.prompt(
question,
style=style,
complete_while_typing=False,
)
else:
res = input(question)
@@ -657,9 +750,15 @@ class InputOutput:
hist = f"{question.strip()} {res}"
self.append_chat_history(hist, linebreak=True, blockquote=True)
# Restore original multiline mode
self.multiline_mode = orig_multiline
return is_yes
def prompt_ask(self, question, default="", subject=None):
# Temporarily disable multiline mode for prompts
orig_multiline = self.multiline_mode
self.multiline_mode = False
self.num_user_asks += 1
if subject:
@@ -683,6 +782,9 @@ class InputOutput:
if self.yes in (True, False):
self.tool_output(hist)
# Restore original multiline mode
self.multiline_mode = orig_multiline
return res
def _tool_message(self, message="", strip=True, color=None):
@@ -752,6 +854,18 @@ class InputOutput:
def print(self, message=""):
print(message)
def toggle_multiline_mode(self):
"""Toggle between normal and multiline input modes"""
self.multiline_mode = not self.multiline_mode
if self.multiline_mode:
self.tool_output(
"Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text"
)
else:
self.tool_output(
"Multiline mode: Disabled. Alt-Enter inserts newline, Enter submits text"
)
def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True):
if blockquote:
if strip:

View File

@@ -49,11 +49,11 @@ class Linter:
try:
process = subprocess.Popen(
cmd,
cwd=self.root,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding=self.encoding,
errors="replace",
cwd=self.root,
)
except OSError as err:
print(f"Unable to execute lint command: {err}")
@@ -152,12 +152,12 @@ class Linter:
try:
result = subprocess.run(
flake8_cmd,
cwd=self.root,
capture_output=True,
text=True,
check=False,
encoding=self.encoding,
errors="replace",
cwd=self.root,
)
errors = result.stdout + result.stderr
except Exception as e:

View File

@@ -13,6 +13,8 @@ os.environ["LITELLM_MODE"] = "PRODUCTION"
# `import litellm` takes 1.5 seconds, defer it!
VERBOSE = False
class LazyLiteLLM:
_lazy_module = None
@@ -27,6 +29,9 @@ class LazyLiteLLM:
if self._lazy_module is not None:
return
if VERBOSE:
print("Loading litellm...")
self._lazy_module = importlib.import_module("litellm")
self._lazy_module.suppress_debug_info = True

View File

@@ -20,6 +20,7 @@ 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.copypaste import ClipboardWatcher
from aider.format_settings import format_settings, scrub_sensitive_info
from aider.history import ChatSummary
from aider.io import InputOutput
@@ -28,6 +29,7 @@ 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
from aider.watch import FileWatcher
from .dump import dump # noqa: F401
@@ -157,13 +159,17 @@ def check_gitignore(git_root, io, ask=True):
gitignore_file = Path(git_root) / ".gitignore"
if gitignore_file.exists():
content = io.read_text(gitignore_file)
if content is None:
try:
content = io.read_text(gitignore_file)
if content is None:
return
existing_lines = content.splitlines()
for pat in patterns:
if pat not in existing_lines:
patterns_to_add.append(pat)
except OSError as e:
io.tool_error(f"Error when trying to read {gitignore_file}: {e}")
return
existing_lines = content.splitlines()
for pat in patterns:
if pat not in existing_lines:
patterns_to_add.append(pat)
else:
content = ""
patterns_to_add = patterns
@@ -177,9 +183,17 @@ def check_gitignore(git_root, io, ask=True):
if content and not content.endswith("\n"):
content += "\n"
content += "\n".join(patterns_to_add) + "\n"
io.write_text(gitignore_file, content)
io.tool_output(f"Added {', '.join(patterns_to_add)} to .gitignore")
try:
io.write_text(gitignore_file, content)
io.tool_output(f"Added {', '.join(patterns_to_add)} to .gitignore")
except OSError as e:
io.tool_error(f"Error when trying to write to {gitignore_file}: {e}")
io.tool_output(
"Try running with appropriate permissions or manually add these patterns to .gitignore:"
)
for pattern in patterns_to_add:
io.tool_output(f" {pattern}")
def check_streamlit_install(io):
@@ -455,6 +469,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
litellm._lazy_module.client_session = httpx.Client(verify=False)
litellm._lazy_module.aclient_session = httpx.AsyncClient(verify=False)
if args.timeout:
litellm._load_litellm()
litellm._lazy_module.request_timeout = args.timeout
if args.dark_mode:
args.user_input_color = "#32FF32"
args.tool_error_color = "#FF3333"
@@ -497,6 +515,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
llm_history_file=args.llm_history_file,
editingmode=editing_mode,
fancy_input=args.fancy_input,
multiline_mode=args.multiline,
)
io = get_io(args.pretty)
@@ -508,6 +527,50 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
io = get_io(False)
io.tool_warning("Terminal does not support pretty output (UnicodeDecodeError)")
# Process any environment variables set via --set-env
if args.set_env:
for env_setting in args.set_env:
try:
name, value = env_setting.split("=", 1)
os.environ[name.strip()] = value.strip()
except ValueError:
io.tool_error(f"Invalid --set-env format: {env_setting}")
io.tool_output("Format should be: ENV_VAR_NAME=value")
return 1
# Process any API keys set via --api-key
if args.api_key:
for api_setting in args.api_key:
try:
provider, key = api_setting.split("=", 1)
env_var = f"{provider.strip().upper()}_API_KEY"
os.environ[env_var] = key.strip()
except ValueError:
io.tool_error(f"Invalid --api-key format: {api_setting}")
io.tool_output("Format should be: provider=key")
return 1
if args.anthropic_api_key:
os.environ["ANTHROPIC_API_KEY"] = args.anthropic_api_key
if args.openai_api_key:
os.environ["OPENAI_API_KEY"] = args.openai_api_key
if args.openai_api_base:
os.environ["OPENAI_API_BASE"] = args.openai_api_base
if args.openai_api_version:
io.tool_warning(
"--openai-api-version is deprecated, use --set-env OPENAI_API_VERSION=<value>"
)
os.environ["OPENAI_API_VERSION"] = args.openai_api_version
if args.openai_api_type:
io.tool_warning("--openai-api-type is deprecated, use --set-env OPENAI_API_TYPE=<value>")
os.environ["OPENAI_API_TYPE"] = args.openai_api_type
if args.openai_organization_id:
io.tool_warning(
"--openai-organization-id is deprecated, use --set-env OPENAI_ORGANIZATION=<value>"
)
os.environ["OPENAI_ORGANIZATION"] = args.openai_organization_id
analytics = Analytics(logfile=args.analytics_log, permanently_disable=args.analytics_disable)
if args.analytics is not False:
if analytics.need_to_ask(args.analytics):
@@ -535,9 +598,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if args.gui and not return_coder:
if not check_streamlit_install(io):
analytics.event("exit", reason="Streamlit not installed")
return
analytics.event("gui session")
launch_gui(argv)
analytics.event("exit", reason="GUI session ended")
return
if args.verbose:
@@ -548,7 +613,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
fnames = [str(Path(fn).resolve()) for fn in all_files]
read_only_fnames = []
for fn in args.read or []:
path = Path(fn).resolve()
path = Path(fn).expanduser().resolve()
if path.is_dir():
read_only_fnames.extend(str(f) for f in path.rglob("*") if f.is_file())
else:
@@ -564,6 +629,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
io.tool_output(
"Provide either a single directory of a git repo, or a list of one or more files."
)
analytics.event("exit", reason="Invalid directory input")
return 1
git_dname = None
@@ -574,6 +640,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
fnames = []
else:
io.tool_error(f"{all_files[0]} is a directory, but --no-git selected.")
analytics.event("exit", reason="Directory with --no-git")
return 1
# We can't know the git repo for sure until after parsing the args.
@@ -582,18 +649,22 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if args.git and not force_git_root:
right_repo_root = guessed_wrong_repo(io, git_root, fnames, git_dname)
if right_repo_root:
analytics.event("exit", reason="Recursing with correct repo")
return main(argv, input, output, right_repo_root, return_coder=return_coder)
if args.just_check_update:
update_available = check_version(io, just_check=True, verbose=args.verbose)
analytics.event("exit", reason="Just checking update")
return 0 if not update_available else 1
if args.install_main_branch:
success = install_from_main_branch(io)
analytics.event("exit", reason="Installed main branch")
return 0 if success else 1
if args.upgrade:
success = install_upgrade(io)
analytics.event("exit", reason="Upgrade completed")
return 0 if success else 1
if args.check_update:
@@ -601,6 +672,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if args.list_models:
models.print_matching_models(io, args.list_models)
analytics.event("exit", reason="Listed models")
return 0
if args.git:
@@ -619,20 +691,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
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
if args.openai_api_key:
os.environ["OPENAI_API_KEY"] = args.openai_api_key
if args.openai_api_base:
os.environ["OPENAI_API_BASE"] = args.openai_api_base
if args.openai_api_version:
os.environ["OPENAI_API_VERSION"] = args.openai_api_version
if args.openai_api_type:
os.environ["OPENAI_API_TYPE"] = args.openai_api_type
if args.openai_organization_id:
os.environ["OPENAI_ORGANIZATION"] = args.openai_organization_id
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)
@@ -644,6 +702,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if len(parts) != 2:
io.tool_error(f"Invalid alias format: {alias_def}")
io.tool_output("Format should be: alias:model-name")
analytics.event("exit", reason="Invalid alias format error")
return 1
alias, model = parts
models.MODEL_ALIASES[alias.strip()] = model.strip()
@@ -660,6 +719,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
editor_edit_format=args.editor_edit_format,
)
if args.copy_paste and args.edit_format is None:
if main_model.edit_format in ("diff", "whole"):
main_model.edit_format = "editor-" + main_model.edit_format
if args.verbose:
io.tool_output("Model metadata:")
io.tool_output(json.dumps(main_model.info, indent=4))
@@ -672,6 +735,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
if lint_cmds is None:
analytics.event("exit", reason="Invalid lint command format")
return 1
if args.show_model_warnings:
@@ -684,6 +748,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
io.offer_url(urls.model_warnings, "Open documentation url for more info?")
io.tool_output()
except KeyboardInterrupt:
analytics.event("exit", reason="Keyboard interrupt during model warnings")
return 1
repo = None
@@ -707,8 +772,14 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if not args.skip_sanity_check_repo:
if not sanity_check_repo(repo, io):
analytics.event("exit", reason="Repository sanity check failed")
return 1
if repo:
analytics.event("repo", num_files=len(repo.get_tracked_files()))
else:
analytics.event("no-repo")
commands = Commands(
io,
None,
@@ -765,18 +836,38 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
suggest_shell_commands=args.suggest_shell_commands,
chat_language=args.chat_language,
detect_urls=args.detect_urls,
auto_copy_context=args.copy_paste,
)
except UnknownEditFormat as err:
io.tool_error(str(err))
io.offer_url(urls.edit_formats, "Open documentation about edit formats?")
analytics.event("exit", reason="Unknown edit format")
return 1
except ValueError as err:
io.tool_error(str(err))
analytics.event("exit", reason="ValueError during coder creation")
return 1
if return_coder:
analytics.event("exit", reason="Returning coder object")
return coder
ignores = []
if git_root:
ignores.append(str(Path(git_root) / ".gitignore"))
if args.aiderignore:
ignores.append(args.aiderignore)
if args.watch_files:
file_watcher = FileWatcher(
coder, gitignores=ignores, verbose=args.verbose, analytics=analytics
)
coder.file_watcher = file_watcher
if args.copy_paste:
analytics.event("copy-paste mode")
ClipboardWatcher(coder.io, verbose=args.verbose)
coder.show_announcements()
if args.show_prompts:
@@ -785,6 +876,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
]
messages = coder.format_messages().all_messages()
utils.show_messages(messages)
analytics.event("exit", reason="Showed prompts")
return
if args.lint:
@@ -793,10 +885,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
if args.test:
if not args.test_cmd:
io.tool_error("No --test-cmd provided.")
analytics.event("exit", reason="No test command provided")
return 1
test_errors = coder.commands.cmd_test(args.test_cmd)
if test_errors:
coder.run(test_errors)
coder.commands.cmd_test(args.test_cmd)
if io.placeholder:
coder.run(io.placeholder)
if args.commit:
if args.dry_run:
@@ -805,32 +898,30 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
coder.commands.cmd_commit()
if args.lint or args.test or args.commit:
analytics.event("exit", reason="Completed lint/test/commit")
return
if args.show_repo_map:
repo_map = coder.get_repo_map()
if repo_map:
io.tool_output(repo_map)
analytics.event("exit", reason="Showed repo map")
return
if args.apply:
content = io.read_text(args.apply)
if content is None:
analytics.event("exit", reason="Failed to read apply content")
return
coder.partial_response_content = content
coder.apply_updates()
analytics.event("exit", reason="Applied updates")
return
if args.apply_clipboard_edits:
args.edit_format = main_model.editor_edit_format
args.message = "/paste"
if "VSCODE_GIT_IPC_HANDLE" in os.environ:
args.pretty = False
io.tool_output("VSCode terminal detected, pretty output has been disabled.")
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()
@@ -862,6 +953,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
coder.run(with_message=args.message)
except SwitchCoder:
pass
analytics.event("exit", reason="Completed --message")
return
if args.message_file:
@@ -871,13 +963,18 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
coder.run(with_message=message_from_file)
except FileNotFoundError:
io.tool_error(f"Message file not found: {args.message_file}")
analytics.event("exit", reason="Message file not found")
return 1
except IOError as e:
io.tool_error(f"Error reading message file: {e}")
analytics.event("exit", reason="Message file IO error")
return 1
analytics.event("exit", reason="Completed --message-file")
return
if args.exit:
analytics.event("exit", reason="Exit flag set")
return
analytics.event("cli session", main_model=main_model, edit_format=main_model.edit_format)
@@ -885,6 +982,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
while True:
try:
coder.run()
analytics.event("exit", reason="Completed main CLI coder.run")
return
except SwitchCoder as switch:
kwargs = dict(io=io, from_coder=coder)
@@ -903,6 +1001,10 @@ def is_first_run_of_new_version(io, verbose=False):
installs_file = Path.home() / ".aider" / "installs.json"
key = (__version__, sys.executable)
# Never show notes for .dev versions
if ".dev" in __version__:
return False
if verbose:
io.tool_output(
f"Checking imports for version {__version__} and executable {sys.executable}"

View File

@@ -17,7 +17,7 @@ from aider.dump import dump # noqa: F401
from aider.llm import litellm
DEFAULT_MODEL_NAME = "gpt-4o"
ANTHROPIC_BETA_HEADER = "prompt-caching-2024-07-31"
ANTHROPIC_BETA_HEADER = "prompt-caching-2024-07-31,pdfs-2024-09-25"
OPENAI_MODELS = """
gpt-4
@@ -64,18 +64,19 @@ ANTHROPIC_MODELS = [ln.strip() for ln in ANTHROPIC_MODELS.splitlines() if ln.str
# Mapping of model aliases to their canonical names
MODEL_ALIASES = {
# Claude models
"sonnet": "claude-3-sonnet-20241022",
"haiku": "claude-3-haiku-20241022",
"sonnet": "claude-3-5-sonnet-20241022",
"haiku": "claude-3-5-haiku-20241022",
"opus": "claude-3-opus-20240229",
# GPT models
"4": "gpt-4-0613",
"4o": "gpt-4o-2024-08-06",
"4o": "gpt-4o",
"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",
"flash": "gemini/gemini-2.0-flash-exp",
}
@@ -583,6 +584,21 @@ MODEL_SETTINGS = [
"diff-fenced",
use_repo_map=True,
),
ModelSettings(
"gemini/gemini-exp-1206",
"diff",
use_repo_map=True,
),
ModelSettings(
"gemini/gemini-exp-1114",
"diff",
use_repo_map=True,
),
ModelSettings(
"gemini/gemini-exp-1121",
"diff",
use_repo_map=True,
),
ModelSettings(
"vertex_ai/gemini-pro-experimental",
"diff-fenced",
@@ -594,6 +610,12 @@ MODEL_SETTINGS = [
use_repo_map=False,
send_undo_reply=False,
),
ModelSettings(
"gemini/gemini-2.0-flash-exp",
"diff",
use_repo_map=True,
send_undo_reply=False,
),
ModelSettings(
"deepseek/deepseek-chat",
"diff",
@@ -837,7 +859,10 @@ model_info_manager = ModelInfoManager()
class Model(ModelSettings):
def __init__(self, model, weak_model=None, editor_model=None, editor_edit_format=None):
# Map any alias to its canonical name
self.name = MODEL_ALIASES.get(model, model)
model = MODEL_ALIASES.get(model, model)
self.name = model
self.max_chat_history_tokens = 1024
self.weak_model = None
self.editor_model = None

View File

@@ -192,9 +192,7 @@ class GitRepo:
max_tokens = model.info.get("max_input_tokens") or 0
if max_tokens and num_tokens > max_tokens:
continue
commit_message = simple_send_with_retries(
model.name, messages, extra_params=model.extra_params
)
commit_message = simple_send_with_retries(model, messages)
if commit_message:
break

View File

@@ -0,0 +1,38 @@
{
"gemini-2.0-flash-exp": {
"max_tokens": 8192,
"max_input_tokens": 1048576,
"max_output_tokens": 8192,
"max_images_per_prompt": 3000,
"max_videos_per_prompt": 10,
"max_video_length": 1,
"max_audio_length_hours": 8.4,
"max_audio_per_prompt": 1,
"max_pdf_size_mb": 30,
"litellm_provider": "vertex_ai-language-models",
"mode": "chat",
"supports_system_messages": true,
"supports_function_calling": true,
"supports_vision": true,
"supports_response_schema": true,
"source": "https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2"
},
"gemini-2.0-flash-exp": {
"max_tokens": 8192,
"max_input_tokens": 1048576,
"max_output_tokens": 8192,
"max_images_per_prompt": 3000,
"max_videos_per_prompt": 10,
"max_video_length": 1,
"max_audio_length_hours": 8.4,
"max_audio_per_prompt": 1,
"max_pdf_size_mb": 30,
"litellm_provider": "gemini",
"mode": "chat",
"supports_system_messages": true,
"supports_function_calling": true,
"supports_vision": true,
"supports_response_schema": true,
"source": "https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2"
},
}

View File

@@ -8,12 +8,12 @@ import pexpect
import psutil
def run_cmd(command, verbose=False, error_print=None):
def run_cmd(command, verbose=False, error_print=None, cwd=None):
try:
if sys.stdin.isatty() and hasattr(pexpect, "spawn") and platform.system() != "Windows":
return run_cmd_pexpect(command, verbose)
return run_cmd_pexpect(command, verbose, cwd)
return run_cmd_subprocess(command, verbose)
return run_cmd_subprocess(command, verbose, cwd)
except OSError as e:
error_message = f"Error occurred while running command '{command}': {str(e)}"
if error_print is None:
@@ -39,7 +39,7 @@ def get_windows_parent_process_name():
return None
def run_cmd_subprocess(command, verbose=False):
def run_cmd_subprocess(command, verbose=False, cwd=None):
if verbose:
print("Using run_cmd_subprocess:", command)
@@ -69,6 +69,7 @@ def run_cmd_subprocess(command, verbose=False):
errors="replace",
bufsize=0, # Set bufsize to 0 for unbuffered output
universal_newlines=True,
cwd=cwd,
)
output = []
@@ -85,7 +86,7 @@ def run_cmd_subprocess(command, verbose=False):
return 1, str(e)
def run_cmd_pexpect(command, verbose=False):
def run_cmd_pexpect(command, verbose=False, cwd=None):
"""
Run a shell command interactively using pexpect, capturing all output.
@@ -112,12 +113,12 @@ def run_cmd_pexpect(command, verbose=False):
# Use the shell from SHELL environment variable
if verbose:
print("Running pexpect.spawn with shell:", shell)
child = pexpect.spawn(shell, args=["-c", command], encoding="utf-8")
child = pexpect.spawn(shell, args=["-i", "-c", command], encoding="utf-8", cwd=cwd)
else:
# Fall back to spawning the command directly
if verbose:
print("Running pexpect.spawn without shell.")
child = pexpect.spawn(command, encoding="utf-8")
child = pexpect.spawn(command, encoding="utf-8", cwd=cwd)
# Transfer control to the user, capturing output
child.interact(output_filter=output_callback)

View File

@@ -56,18 +56,19 @@ def send_completion(
return hash_object, res
def simple_send_with_retries(model_name, messages, extra_params=None):
def simple_send_with_retries(model, messages):
litellm_ex = LiteLLMExceptions()
retry_delay = 0.125
while True:
try:
kwargs = {
"model_name": model_name,
"model_name": model.name,
"messages": messages,
"functions": None,
"stream": False,
"extra_params": extra_params,
"temperature": None if not model.use_temperature else 0,
"extra_params": model.extra_params,
}
_hash, response = send_completion(**kwargs)

View File

@@ -2,7 +2,6 @@ import itertools
import os
import platform
import shlex
import shutil
import subprocess
import sys
import tempfile
@@ -13,7 +12,7 @@ import git
from aider.dump import dump # noqa: F401
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp"}
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp", ".pdf"}
class IgnorantTemporaryDirectory:
@@ -194,25 +193,9 @@ def split_chat_history_markdown(text, include_tool=False):
return messages
# Copied from pip, MIT license
# https://github.com/pypa/pip/blob/b989e6ef04810bbd4033a3683020bd4ddcbdb627/src/pip/_internal/utils/entrypoints.py#L73
def get_best_invocation_for_this_python() -> str:
"""Try to figure out the best way to invoke the current Python."""
exe = sys.executable
exe_name = os.path.basename(exe)
# Try to use the basename, if it's the first executable.
found_executable = shutil.which(exe_name)
if found_executable and os.path.samefile(found_executable, exe):
return exe_name
# Use the full executable name, because we couldn't find something simpler.
return exe
def get_pip_install(args):
cmd = [
get_best_invocation_for_this_python(),
sys.executable,
"-m",
"pip",
"install",
@@ -268,7 +251,8 @@ def run_install(cmd):
class Spinner:
spinner_chars = itertools.cycle(["", "", "", "", "", "", "", "", "", ""])
unicode_spinner = ["", "", "", "", "", "", "", "", "", ""]
ascii_spinner = ["|", "/", "-", "\\"]
def __init__(self, text):
self.text = text
@@ -276,6 +260,20 @@ class Spinner:
self.last_update = 0
self.visible = False
self.is_tty = sys.stdout.isatty()
self.tested = False
def test_charset(self):
if self.tested:
return
self.tested = True
# Try unicode first, fall back to ascii if needed
try:
# Test if we can print unicode characters
print(self.unicode_spinner[0], end="", flush=True)
print("\r", end="", flush=True)
self.spinner_chars = itertools.cycle(self.unicode_spinner)
except UnicodeEncodeError:
self.spinner_chars = itertools.cycle(self.ascii_spinner)
def step(self):
if not self.is_tty:
@@ -293,6 +291,7 @@ class Spinner:
if not self.visible:
return
self.test_charset()
print(f"\r{self.text} {next(self.spinner_chars)}\r{self.text} ", end="", flush=True)
def end(self):
@@ -382,3 +381,15 @@ def printable_shell_command(cmd_list):
return subprocess.list2cmdline(cmd_list)
else:
return shlex.join(cmd_list)
def main():
spinner = Spinner("Running spinner...")
for _ in range(40): # 40 steps * 0.25 seconds = 10 seconds
time.sleep(0.25)
spinner.step()
spinner.end()
if __name__ == "__main__":
main()

View File

@@ -14,6 +14,8 @@ from .dump import dump # noqa: F401
warnings.filterwarnings(
"ignore", message="Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work"
)
warnings.filterwarnings("ignore", category=SyntaxWarning)
from pydub import AudioSegment # noqa
@@ -34,7 +36,7 @@ class Voice:
threshold = 0.15
def __init__(self, audio_format="wav"):
def __init__(self, audio_format="wav", device_name=None):
if sf is None:
raise SoundDeviceError
try:
@@ -42,6 +44,29 @@ class Voice:
import sounddevice as sd
self.sd = sd
devices = sd.query_devices()
if device_name:
# Find the device with matching name
device_id = None
for i, device in enumerate(devices):
if device_name in device["name"]:
device_id = i
break
if device_id is None:
available_inputs = [d["name"] for d in devices if d["max_input_channels"] > 0]
raise ValueError(
f"Device '{device_name}' not found. Available input devices:"
f" {available_inputs}"
)
print(f"Using input device: {device_name} (ID: {device_id})")
self.device_id = device_id
else:
self.device_id = None
except (OSError, ModuleNotFoundError):
raise SoundDeviceError
if audio_format not in ["wav", "mp3", "webm"]:
@@ -93,7 +118,7 @@ class Voice:
temp_wav = tempfile.mktemp(suffix=".wav")
try:
sample_rate = int(self.sd.query_devices(None, "input")["default_samplerate"])
sample_rate = int(self.sd.query_devices(self.device_id, "input")["default_samplerate"])
except (TypeError, ValueError):
sample_rate = 16000 # fallback to 16kHz if unable to query device
except self.sd.PortAudioError:
@@ -104,7 +129,9 @@ class Voice:
self.start_time = time.time()
try:
with self.sd.InputStream(samplerate=sample_rate, channels=1, callback=self.callback):
with self.sd.InputStream(
samplerate=sample_rate, channels=1, callback=self.callback, device=self.device_id
):
prompt(self.get_prompt, refresh_interval=0.1)
except self.sd.PortAudioError as err:
raise SoundDeviceError(f"Error accessing audio input device: {err}")

271
aider/watch.py Normal file
View File

@@ -0,0 +1,271 @@
import re
import threading
from pathlib import Path
from typing import Optional
from grep_ast import TreeContext
from pathspec import PathSpec
from pathspec.patterns import GitWildMatchPattern
from watchfiles import watch
from aider.dump import dump # noqa
from aider.watch_prompts import watch_ask_prompt, watch_code_prompt
def load_gitignores(gitignore_paths: list[Path]) -> Optional[PathSpec]:
"""Load and parse multiple .gitignore files into a single PathSpec"""
if not gitignore_paths:
return None
patterns = [
".aider*",
".git",
# Common editor backup/temp files
"*~", # Emacs/vim backup
"*.bak", # Generic backup
"*.swp", # Vim swap
"*.swo", # Vim swap
"\\#*\\#", # Emacs auto-save
".#*", # Emacs lock files
"*.tmp", # Generic temp files
"*.temp", # Generic temp files
"*.orig", # Merge conflict originals
"*.pyc", # Python bytecode
"__pycache__/", # Python cache dir
".DS_Store", # macOS metadata
"Thumbs.db", # Windows thumbnail cache
# IDE files
".idea/", # JetBrains IDEs
".vscode/", # VS Code
"*.sublime-*", # Sublime Text
".project", # Eclipse
".settings/", # Eclipse
"*.code-workspace", # VS Code workspace
# Environment files
".env", # Environment variables
".venv/", # Python virtual environments
"node_modules/", # Node.js dependencies
"vendor/", # Various dependencies
# Logs and caches
"*.log", # Log files
".cache/", # Cache directories
".pytest_cache/", # Python test cache
"coverage/", # Code coverage reports
] # Always ignore
for path in gitignore_paths:
if path.exists():
with open(path) as f:
patterns.extend(f.readlines())
return PathSpec.from_lines(GitWildMatchPattern, patterns) if patterns else None
class FileWatcher:
"""Watches source files for changes and AI comments"""
# Compiled regex pattern for AI comments
ai_comment_pattern = re.compile(r"(?:#|//|--) *(ai\b.*|ai\b.*|.*\bai[?!]?) *$", re.IGNORECASE)
def __init__(self, coder, gitignores=None, verbose=False, analytics=None):
self.coder = coder
self.io = coder.io
self.root = Path(coder.root)
self.verbose = verbose
self.analytics = analytics
self.stop_event = None
self.watcher_thread = None
self.changed_files = set()
self.gitignores = gitignores
self.gitignore_spec = load_gitignores(
[Path(g) for g in self.gitignores] if self.gitignores else []
)
coder.io.file_watcher = self
def filter_func(self, change_type, path):
"""Filter function for the file watcher"""
path_obj = Path(path)
path_abs = path_obj.absolute()
if not path_abs.is_relative_to(self.root.absolute()):
return False
rel_path = path_abs.relative_to(self.root)
if self.verbose:
dump(rel_path)
if self.gitignore_spec and self.gitignore_spec.match_file(str(rel_path)):
return False
if self.verbose:
dump("ok", rel_path)
# Check if file contains AI markers
try:
comments, _, _ = self.get_ai_comments(str(path_abs))
return bool(comments)
except Exception:
return
def start(self):
"""Start watching for file changes"""
self.stop_event = threading.Event()
self.changed_files = set()
def watch_files():
try:
for changes in watch(
str(self.root), watch_filter=self.filter_func, stop_event=self.stop_event
):
if not changes:
continue
changed_files = {str(Path(change[1])) for change in changes}
self.changed_files.update(changed_files)
self.io.interrupt_input()
return
except Exception as e:
if self.verbose:
dump(f"File watcher error: {e}")
raise e
self.watcher_thread = threading.Thread(target=watch_files, daemon=True)
self.watcher_thread.start()
def stop(self):
"""Stop watching for file changes"""
if self.stop_event:
self.stop_event.set()
if self.watcher_thread:
self.watcher_thread.join()
self.watcher_thread = None
self.stop_event = None
def process_changes(self):
"""Get any detected file changes"""
has_action = None
for fname in self.changed_files:
_, _, action = self.get_ai_comments(fname)
if action in ("!", "?"):
has_action = action
if fname in self.coder.abs_fnames:
continue
if self.analytics:
self.analytics.event("ai-comments file-add")
self.coder.abs_fnames.add(fname)
rel_fname = self.coder.get_rel_fname(fname)
self.io.tool_output(f"Added {rel_fname} to the chat")
self.io.tool_output()
if not has_action:
return ""
if self.analytics:
self.analytics.event("ai-comments execute")
self.io.tool_output("Processing your request...")
if has_action == "!":
res = watch_code_prompt
elif has_action == "?":
res = watch_ask_prompt
# Refresh all AI comments from tracked files
for fname in self.coder.abs_fnames:
line_nums, comments, _action = self.get_ai_comments(fname)
if not line_nums:
continue
code = self.io.read_text(fname)
if not code:
continue
rel_fname = self.coder.get_rel_fname(fname)
res += f"\n{rel_fname}:\n"
# Convert comment line numbers to line indices (0-based)
lois = [ln - 1 for ln, _ in zip(line_nums, comments) if ln > 0]
try:
context = TreeContext(
rel_fname,
code,
color=False,
line_number=False,
child_context=False,
last_line=False,
margin=0,
mark_lois=True,
loi_pad=3,
show_top_of_file_parent_scope=False,
)
context.lines_of_interest = set()
context.add_lines_of_interest(lois)
context.add_context()
res += context.format()
except ValueError:
for ln, comment in zip(line_nums, comments):
res += f" Line {ln}: {comment}\n"
return res
def get_ai_comments(self, filepath):
"""Extract AI comment line numbers, comments and action status from a file"""
line_nums = []
comments = []
has_action = None # None, "!" or "?"
content = self.io.read_text(filepath, silent=True)
for i, line in enumerate(content.splitlines(), 1):
if match := self.ai_comment_pattern.search(line):
comment = match.group(0).strip()
if comment:
line_nums.append(i)
comments.append(comment)
comment = comment.lower()
comment = comment.lstrip("/#-")
comment = comment.strip()
if comment.startswith("ai!") or comment.endswith("ai!"):
has_action = "!"
elif comment.startswith("ai?") or comment.endswith("ai?"):
has_action = "?"
if not line_nums:
return None, None, None
return line_nums, comments, has_action
def main():
"""Example usage of the file watcher"""
import argparse
parser = argparse.ArgumentParser(description="Watch source files for changes")
parser.add_argument("directory", help="Directory to watch")
parser.add_argument(
"--gitignore",
action="append",
help="Path to .gitignore file (can be specified multiple times)",
)
args = parser.parse_args()
directory = args.directory
print(f"Watching source files in {directory}...")
# Example ignore function that ignores files with "test" in the name
def ignore_test_files(path):
return "test" in path.name.lower()
watcher = FileWatcher(directory, gitignores=args.gitignore)
try:
watcher.start()
while True:
if changes := watcher.get_changes():
for file in sorted(changes.keys()):
print(file)
watcher.changed_files = None
except KeyboardInterrupt:
print("\nStopped watching files")
watcher.stop()
if __name__ == "__main__":
main()

11
aider/watch_prompts.py Normal file
View File

@@ -0,0 +1,11 @@
watch_code_prompt = """
Find the "AI" comments below (marked with █) in the code files I've shared with you.
They contain your instructions.
Make the requested changes.
Be sure to remove all these "AI" comments from the code!
"""
watch_ask_prompt = """/ask
Find the "AI" comments below (marked with █) in the code files I've shared with you.
They contain your questions you need to answer and other instructions.
"""

View File

@@ -1,7 +1,6 @@
---
title: Release history
parent: More info
nav_order: 900
nav_order: 925
highlight_image: /assets/blame.jpg
description: Release notes and stats on aider writing its own code.
---
@@ -24,7 +23,80 @@ cog.out(text)
]]]-->
### main branch
### Aider v0.69.0
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
- Now watches *all* files, not just certain source files.
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
- Full support for Gemini Flash 2.0 Exp:
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
- Improved clipboard error handling with helpful requirements install info.
- Ask 5% of users if they want to opt-in to analytics.
- `/voice` now lets you edit the transcribed text before sending.
- Disabled auto-complete in Y/N prompts.
- Aider wrote 60% of the code in this release.
### Aider v0.68.0
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
- New `--copy-paste` mode.
- New `/copy-context` command.
- [Set API keys and other environment variables for all providers from command line or yaml conf file](https://aider.chat/docs/config/aider_conf.html#storing-llm-keys).
- New `--api-key provider=key` setting.
- New `--set-env VAR=value` setting.
- Added bash and zsh support to `--watch-files`.
- Better error messages when missing dependencies for Gemini and Bedrock models.
- Control-D now properly exits the program.
- Don't count token costs when API provider returns a hard error.
- Bugfix so watch files works with files that don't have tree-sitter support.
- Bugfix so o1 models can be used as weak model.
- Updated shell command prompt.
- Added docstrings for all Coders.
- Reorganized command line arguments with improved help messages and grouping.
- Use the exact `sys.python` for self-upgrades.
- Added experimental Gemini models.
- Aider wrote 71% of the code in this release.
### Aider v0.67.0
- [Use aider in your IDE or editor](https://aider.chat/docs/usage/watch.html).
- Run `aider --watch-files` and it will watch for instructions you add to your source files.
- One-liner `# ...` or `// ...` comments that start or end with "AI" are instructions to aider.
- When aider sees "AI!" it reads and follows all the instructions in AI comments.
- Support for new Amazon Bedrock Nova models.
- When `/run` or `/test` have non-zero exit codes, pre-fill "Fix that" into the next message prompt.
- `/diff` now invokes `git diff` to use your preferred diff tool.
- Added Ctrl-Z support for process suspension.
- Spinner now falls back to ASCII art if fancy symbols throw unicode errors.
- `--read` now expands `~` home dirs.
- Enabled exception capture in analytics.
- [Aider wrote 61% of the code in this release.](https://aider.chat/HISTORY.html)
### Aider v0.66.0
- PDF support for Sonnet and Gemini models.
- Added `--voice-input-device` to select audio input device for voice recording, by @preynal.
- Added `--timeout` option to configure API call timeouts.
- Set cwd to repo root when running shell commands.
- Added Ctrl-Up/Down keyboard shortcuts for per-message history navigation.
- Improved error handling for failed .gitignore file operations.
- Improved error handling for input history file permissions.
- Improved error handling for analytics file access.
- Removed spurious warning about disabling pretty in VSCode.
- Removed broken support for Dart.
- Bugfix when scraping URLs found in chat messages.
- Better handling of __version__ import errors.
- Improved `/drop` command to support substring matching for non-glob patterns.
- Aider wrote 82% of the code in this release.
### Aider v0.65.1
- Bugfix to `--alias`.
### Aider v0.65.0
- 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.

File diff suppressed because it is too large Load Diff

View File

@@ -644,7 +644,7 @@
- dirname: 2024-07-19-08-57-13--openrouter-deepseek-chat-v2-0628
test_cases: 133
model: DeepSeek Chat V2 0628 (deprecated)
model: DeepSeek Chat V2 0628
edit_format: diff
commit_hash: 96ff06e-dirty
pass_rate_1: 60.9
@@ -716,7 +716,7 @@
- dirname: 2024-07-24-07-10-58--deepseek-coder2-0724-diff-direct
test_cases: 133
model: DeepSeek Coder V2 0724 (deprecated)
model: DeepSeek Coder V2 0724
edit_format: diff
commit_hash: 89965bf
pass_rate_1: 57.9
@@ -1232,7 +1232,7 @@
- dirname: 2024-09-24-16-33-23--gemini-1.5-flash-002-whole
test_cases: 133
model: gemini-1.5-flash-002
model: gemini-1.5-flash-002 (0924)
edit_format: whole
commit_hash: 3edcd71
pass_rate_1: 37.6
@@ -1945,4 +1945,239 @@
command: aider --model gemini/gemini-exp-1114
date: 2024-11-15
versions: 0.63.2.dev
seconds_per_case: 38.6
seconds_per_case: 38.6
- dirname: 2024-11-27-07-41-51--qwen2.5-coder-14b-whole-1
test_cases: 133
model: ollama/qwen2.5-coder:14b
edit_format: whole
commit_hash: 200295e
pass_rate_1: 53.4
pass_rate_2: 61.7
percent_cases_well_formed: 98.5
error_outputs: 4
num_malformed_responses: 4
num_with_malformed_responses: 2
user_asks: 48
lazy_comments: 0
syntax_errors: 2
indentation_errors: 2
exhausted_context_windows: 0
test_timeouts: 2
command: aider --model ollama/qwen2.5-coder:14b
date: 2024-11-27
versions: 0.65.2.dev
seconds_per_case: 58.0
total_cost: 0.0000
- dirname: 2024-11-28-07-42-56--qwen2.5-coder-32b-whole-4
test_cases: 133
model: ollama/qwen2.5-coder:32b
edit_format: whole
commit_hash: 200295e
pass_rate_1: 58.6
pass_rate_2: 72.9
percent_cases_well_formed: 100.0
num_malformed_responses: 0
num_with_malformed_responses: 0
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
command: aider --model ollama/qwen2.5-coder:32b
date: 2024-11-28
versions: 0.65.2.dev
seconds_per_case: 147.5
total_cost: 0.0000
- dirname: 2024-11-28-13-14-00--tulu3-whole-2
test_cases: 133
model: ollama/tulu3
edit_format: whole
commit_hash: 200295e
pass_rate_1: 21.8
pass_rate_2: 26.3
percent_cases_well_formed: 100.0
error_outputs: 0
num_malformed_responses: 0
num_with_malformed_responses: 0
exhausted_context_windows: 0
command: aider --model ollama/tulu3
date: 2024-11-28
versions: 0.65.2.dev
seconds_per_case: 35.8
total_cost: 0.0000
- dirname: 2024-11-28-14-41-46--granite3-dense-8b-whole-1
test_cases: 133
model: ollama/granite3-dense:8b
edit_format: whole
commit_hash: 200295e
pass_rate_1: 17.3
pass_rate_2: 20.3
percent_cases_well_formed: 78.9
exhausted_context_windows: 0
command: aider --model ollama/granite3-dense:8b
date: 2024-11-28
versions: 0.65.2.dev
seconds_per_case: 38.1
total_cost: 0.0000
- dirname: 2024-12-04-13-53-03--nova-whole
test_cases: 133
model: Nova Pro
edit_format: whole
commit_hash: 699e283
pass_rate_1: 44.4
pass_rate_2: 54.1
percent_cases_well_formed: 100.0
error_outputs: 0
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 7
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 4
command: aider --model bedrock/us.amazon.nova-pro-v1:0
date: 2024-12-04
versions: 0.66.1.dev
seconds_per_case: 8.7
total_cost: 0.0000
- dirname: 2024-12-06-18-27-47--llama33-diff
test_cases: 133
model: llama-3.3-70b-instruct
edit_format: diff
commit_hash: 53e0d67
pass_rate_1: 42.1
pass_rate_2: 59.4
percent_cases_well_formed: 88.7
error_outputs: 33
num_malformed_responses: 33
num_with_malformed_responses: 15
user_asks: 3
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 3
command: aider --model openrouter/meta-llama/llama-3.3-70b-instruct
date: 2024-12-06
versions: 0.67.1.dev
seconds_per_case: 20.2
total_cost: 0.0000
- dirname: 2024-12-06-21-35-50--gemini-exp-1206-diff
test_cases: 133
model: gemini-exp-1206 (diff)
edit_format: diff
commit_hash: f2d2ab5
pass_rate_1: 55.6
pass_rate_2: 69.2
percent_cases_well_formed: 84.2
error_outputs: 68
num_malformed_responses: 68
num_with_malformed_responses: 21
user_asks: 5
lazy_comments: 0
syntax_errors: 2
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 0
command: aider --model gemini/gemini-exp-1206
date: 2024-12-06
versions: 0.67.1.dev
seconds_per_case: 32.1
total_cost: 0.0000
- dirname: 2024-12-08-21-39-06--gemini-exp-1206-whole
test_cases: 133
model: gemini-exp-1206 (whole)
edit_format: whole
commit_hash: f2d2ab5
pass_rate_1: 60.9
pass_rate_2: 80.5
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: 3
command: aider --model gemini/gemini-exp-1206
date: 2024-12-08
versions: 0.67.1.dev
seconds_per_case: 64.2
total_cost: 0.0000
- dirname: 2024-12-10-14-45-21--deepseek-1210-diff
test_cases: 133
model: DeepSeek-V2.5-1210
edit_format: diff
commit_hash: 16332b2
pass_rate_1: 58.6
pass_rate_2: 72.2
percent_cases_well_formed: 99.2
error_outputs: 1
num_malformed_responses: 1
num_with_malformed_responses: 1
user_asks: 2
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
command: aider --model deepseek/deepseek-chat
date: 2024-12-10
versions: 0.67.1.dev
seconds_per_case: 32.7
total_cost: 0.1106
- dirname: 2024-12-11-00-37-08--yi-test
test_cases: 133
model: yi-lightning
edit_format: whole
commit_hash: e909a3d-dirty
pass_rate_1: 49.6
pass_rate_2: 65.4
percent_cases_well_formed: 97.0
error_outputs: 304
num_malformed_responses: 5
num_with_malformed_responses: 4
user_asks: 34
lazy_comments: 2
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 2
command: aider --model openai/yi-lightning
date: 2024-12-11
versions: 0.67.1.dev
seconds_per_case: 57.8
total_cost: 0.0000
- dirname: 2024-12-11-21-07-00--gemini-2-flash-diff
test_cases: 133
model: gemini-2.0-flash-exp
edit_format: diff
commit_hash: fcb2bac-dirty, 02e7e31-dirty
pass_rate_1: 56.4
pass_rate_2: 69.9
percent_cases_well_formed: 97.0
error_outputs: 10
num_malformed_responses: 6
num_with_malformed_responses: 4
user_asks: 8
lazy_comments: 0
syntax_errors: 1
indentation_errors: 0
exhausted_context_windows: 2
test_timeouts: 1
command: aider --model gemini/gemini-2.0-flash-exp
date: 2024-12-11
versions: 0.68.1.dev
seconds_per_case: 7.3
total_cost: 0.0000

View File

@@ -296,4 +296,27 @@
date: 2024-11-24
versions: 0.64.2.dev
seconds_per_case: 28.5
total_cost: 0.1390
total_cost: 0.1390
- dirname: 2024-11-26-03-15-06--ollama-qwen2.5-coder:32b-instruct-fp16-2kctx
test_cases: 132
model: "Ollama: fp16, 2k ctx"
edit_format: diff
commit_hash: 68be6c5-dirty, 554d274, 2ff3a23, 2ff3a23-dirty, 61759f9, dd48b74, 3ebd47d-dirty
pass_rate_1: 43.2
pass_rate_2: 51.9
percent_cases_well_formed: 46.2
error_outputs: 171
num_malformed_responses: 165
num_with_malformed_responses: 71
user_asks: 97
lazy_comments: 2
syntax_errors: 4
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 0
command: "aider --model ollama/qwen2.5-coder:32b-instruct-fp16 # num_ctx: 2048"
date: 2024-11-26
versions: 0.64.2.dev,0.65.1.dev
seconds_per_case: 188.6
total_cost: 0.0000

170
aider/website/_data/qwq.yml Normal file
View File

@@ -0,0 +1,170 @@
- dirname: 2024-11-28-21-38-50--architect-qwq-haiku-whole
test_cases: 133
model: QwQ + Haiku
edit_format: architect
commit_hash: e4a1d6f
editor_model: claude-3-5-haiku-20241022
editor_edit_format: editor-whole
pass_rate_1: 54.1
pass_rate_2: 71.4
percent_cases_well_formed: 100.0
error_outputs: 4
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 196
lazy_comments: 4
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 0
command: aider --model openrouter/qwen/qwq-32b-preview --editor-model claude-3-5-haiku-20241022 --edit-format editor-whole
date: 2024-11-28
versions: 0.65.2.dev
seconds_per_case: 154.7
total_cost: 1.4196
- dirname: 2024-11-28-19-24-35--architect-qwq-deepseek-whole
test_cases: 133
model: QwQ + DeepSeek V2.5
edit_format: architect
commit_hash: e4a1d6f
editor_model: deepseek/deepseek-chat
editor_edit_format: editor-whole
pass_rate_1: 55.6
pass_rate_2: 67.7
percent_cases_well_formed: 100.0
error_outputs: 3
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 193
lazy_comments: 2
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 0
command: aider --model openrouter/qwen/qwq-32b-preview --editor-model deepseek/deepseek-chat --edit-format editor-whole
date: 2024-11-28
versions: 0.65.2.dev
seconds_per_case: 170.3
total_cost: 0.1558
- dirname: 2024-11-09-11-09-15--Qwen2.5-Coder-32B-Instruct
test_cases: 133
model: Qwen2.5 Coder 32B-I
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 (via GLHF)
date: 2024-11-09
versions: 0.59.2.dev
seconds_per_case: 22.5
total_cost: 0.0000
- dirname: 2024-12-04-00-10-39--architect-qwq-qwen
test_cases: 132
model: QwQ + Qwen2.5 Coder 32B-I
edit_format: architect
commit_hash: 51c02da
editor_model: openrouter/qwen/qwen-2.5-coder-32b-instruct
editor_edit_format: editor-whole
pass_rate_1: 58.3
pass_rate_2: 73.6
percent_cases_well_formed: 100.0
error_outputs: 3
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 186
lazy_comments: 5
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 0
command: aider --model openrouter/qwen/qwq-32b-preview --editor-model openrouter/qwen/qwen-2.5-coder-32b-instruct --editor-edit-format editor-whole
date: 2024-12-04
versions: 0.66.1.dev
seconds_per_case: 144.1
total_cost: 0.1444
- dirname: 2024-12-04-00-42-05--qwq-alone-whole
test_cases: 133
model: QwQ
edit_format: whole
commit_hash: 19004c0
pass_rate_1: 33.1
pass_rate_2: 42.1
percent_cases_well_formed: 91.0
error_outputs: 28
num_malformed_responses: 12
num_with_malformed_responses: 12
user_asks: 119
lazy_comments: 2
syntax_errors: 22
indentation_errors: 9
exhausted_context_windows: 2
test_timeouts: 1
command: aider --model openrouter/qwen/qwq-32b-preview
date: 2024-12-04
versions: 0.66.1.dev
seconds_per_case: 414.3
total_cost: 0.0000
- dirname: 2024-09-12-19-57-35--o1-mini-whole
test_cases: 133
model: o1-mini
edit_format: whole
commit_hash: 36fa773-dirty, 291b456
pass_rate_1: 49.6
pass_rate_2: 70.7
percent_cases_well_formed: 90.0
error_outputs: 0
num_malformed_responses: 0
num_with_malformed_responses: 0
user_asks: 17
lazy_comments: 0
syntax_errors: 0
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 1
command: aider --model o1-mini
date: 2024-09-12
versions: 0.56.1.dev
seconds_per_case: 103.0
total_cost: 5.3725
- 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
pass_rate_2: 79.7
percent_cases_well_formed: 93.2
error_outputs: 11
num_malformed_responses: 11
num_with_malformed_responses: 9
user_asks: 3
lazy_comments: 0
syntax_errors: 10
indentation_errors: 0
exhausted_context_windows: 0
test_timeouts: 1
command: aider --model o1-preview
date: 2024-09-21
versions: 0.56.1.dev
seconds_per_case: 80.9
total_cost: 63.9190

View File

@@ -0,0 +1,21 @@
## Avoid package conflicts
You can avoid python package conflicts by installing aider using
[pipx](/docs/install/pipx.html)
or
[uv](/docs/install/uv.html).
If you are using aider to work on a python project, sometimes your project will require
specific versions of python packages which conflict with the versions that aider
requires.
If this happens, the `python -m pip install aide-chat` command may return errors like these:
```
aider-chat 0.23.0 requires somepackage==X.Y.Z, but you have somepackage U.W.V which is incompatible.
```
which will install it globally on your system
within its own python environment.
This way you can use aider to work on any python project,
even if that project has conflicting dependencies.

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
You can get started quickly like this:
```
```bash
python -m pip install -U aider-chat
# Change directory into a git repo

View File

@@ -18,3 +18,63 @@
<link rel="mask-icon" href="{{ '/assets/icons/safari-pinned-tab.svg' | relative_url }}" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<!-- Cookie Consent -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css" />
<script src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js" data-cfasync="false"></script>
<script>
window.addEventListener('load', function(){
window.cookieconsent.initialise({
palette: {
popup: {
background: "#333333",
text: "#ffffff"
},
button: {
background: "#ffffff",
text: "#333333"
}
},
type: "opt-in",
position: "bottom-left",
showLink: false,
dismissOnScroll: true,
cookie: {
name: 'cookieconsent_status',
path: '/',
domain: 'aider.chat',
expiryDays: 365
},
content: {
message: "This website uses analytics cookies to help us understand how you use the site.",
dismiss: "Decline",
allow: "Accept",
link: "Learn more",
href: "https://aider.chat/docs/legal/privacy.html"
},
onInitialise: function(status) {
var type = this.options.type;
var didConsent = this.hasConsented();
if (didConsent) {
initPostHog();
}
},
onStatusChange: function(status, chosenBefore) {
var type = this.options.type;
var didConsent = this.hasConsented();
if (didConsent) {
initPostHog();
}
}
})
});
// PostHog initialization function
function initPostHog() {
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv', {
api_host:'https://us.i.posthog.com',
person_profiles: 'identified_only'
})
}
</script>

View File

@@ -5,7 +5,10 @@ You can send long, multi-line messages in the chat in a few ways:
- Use Meta-ENTER to start a new line without sending the message (Esc+ENTER in some environments).
- Use `/paste` to paste text from the clipboard into the chat.
- Use the `/editor` command to open your editor to create the next chat message. See [editor configuration docs](/docs/config/editor.html) for more info.
- Use multiline-mode, which swaps the function of Meta-Enter and Enter, so that Enter inserts a newline, and Meta-Enter submits your command. To enable multiline mode:
- Use the `/multiline-mode` command to toggle it during a session.
- Use the `--multiline` switch.
Example with a tag:
```
{python
@@ -13,3 +16,7 @@ def hello():
print("Hello}") # Note: contains a brace
python}
```
{: .note }
People often ask for SHIFT-ENTER to be a soft-newline.
Unfortunately there is no portable way to detect that keystroke in terminals.

View File

@@ -0,0 +1,120 @@
document.addEventListener('DOMContentLoaded', function () {
var ctx = document.getElementById('qwqChart').getContext('2d');
var allData = [];
{% for row in site.data.qwq %}
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: [{
data: filteredData.map(row => row.pass_rate_2),
backgroundColor: filteredData.map(row =>
(row.model === 'Qwen2.5 Coder 32B-I' || row.model === 'Sonnet (SOTA)' || row.model === 'o1-mini' || row.model === 'o1-preview' || row.model === 'QwQ')
? 'rgba(75, 192, 192, 0.2)' // Green for solo models
: 'rgba(54, 162, 235, 0.2)' // Blue for architect+editor
),
borderColor: filteredData.map(row =>
(row.model === 'Qwen2.5 Coder 32B-I' || row.model === 'Sonnet (SOTA)' || row.model === 'o1-mini' || row.model === 'o1-preview' || row.model === 'QwQ')
? 'rgba(75, 192, 192, 1)' // Green border for solo models
: 'rgba(54, 162, 235, 1)' // Blue border for architect+editor
),
borderWidth: 1
}]
};
if (chart) {
chart.data = chartData;
chart.update();
} else {
chart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
plugins: {
legend: {
display: true,
position: 'top',
labels: {
font: {
size: 14
},
generateLabels: function(chart) {
return [
{
text: 'Solo model',
fillStyle: 'rgba(75, 192, 192, 0.2)',
strokeStyle: 'rgba(75, 192, 192, 1)',
lineWidth: 1,
fontColor: '#666'
},
{
text: 'Architect + Editor',
fillStyle: 'rgba(54, 162, 235, 0.2)',
strokeStyle: 'rgba(54, 162, 235, 1)',
lineWidth: 1,
fontColor: '#666'
}
];
}
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Aider code editing benchmark (%)',
font: {
size: 18
}
},
ticks: {
font: {
size: 16
}
}
},
x: {
ticks: {
font: {
size: 16
},
callback: function(value, index) {
const label = this.getLabelForValue(value);
if (label.includes(" + ")) {
const parts = label.split(" + ");
return [parts[0] + " +", parts[1]];
}
return label;
}
}
}
}
}
});
}
}
// Initial chart render
updateChart('');
// Connect search input to chart filtering
document.getElementById('qwqSearchInput').addEventListener('keyup', function() {
updateChart(this.value);
});
});

View File

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

View File

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

View File

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

View File

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

View File

@@ -12,6 +12,8 @@ nav_exclude: true
# Details matter with open source models
{: .no_toc }
<canvas id="quantChart" width="800" height="600" style="margin: 20px 0"></canvas>
Open source models like Qwen 2.5 32B Instruct are performing very well on
aider's code editing benchmark, rivaling closed source frontier models.
@@ -21,35 +23,55 @@ 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,
The graph above 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).
- Results from OpenRouter's providers, both 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) with 8k+
context windows.
- An Ollama fp16 quantization served with Ollama's default 2k context window.
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.
### Pitfalls and details
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:
This benchmarking effort highlighted a number of pitfalls and details specific to open source
models which
can have a significant impact on their 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
- **Quantization** -- Open source models are often available at dozens of different quantizations.
Most seem to only modestly decrease code editing skill, but stronger quantizations
do have a real impact.
- **Context window** -- Cloud providers can decide how large a context window to accept,
and they often choose differently. Ollama's local API server
defaults to a tiny 2k context window,
and silently discards data that exceeds it. Such a small window has
catastrophic effects on performance, without throwing obvious hard errors.
- **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
- **Buggy cloud providers** -- While benchmarking Qwen 2.5 Coder 32B Instruct
and DeepSeek V2.5, I discovered
multiple cloud providers with broken or buggy API endpoints.
They seemed
to be returning results different from expected based on the advertised
quantization and context sizes.
The harm caused to the code editing benchmark varied from serious
to catastrophic.
One provider scored 0.5% on the benchmark with DeepSeek V2.5, a highly capable model.
Closed source, proprietary models don't typically have these issues.
They are owned and operated by the organization that created them,
and typically served with specific, predictable context window and output token limits.
Their quantization level is usually unknown, but fixed and unchanging for all users.
### Conclusions
The best versions of the Qwen model rival GPT-4o, while the worst performing
quantization is more like the older GPT-4 Turbo when served competently.
Even an otherwise excellent fp16 quantization falls to GPT-3.5 Turbo levels of performance
if run with Ollama's default 2k context window.
### Sections
{: .no_toc }
@@ -59,7 +81,9 @@ quantization and context sizes.
## Benchmark results
<canvas id="quantChart" width="800" height="600" style="margin: 20px 0"></canvas>
{: .note :}
These are results from single benchmark runs, so expect normal variance of +/- 1-2%.
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% include quant-chart.js %}
@@ -134,9 +158,10 @@ 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.
Except for the single 2k context result,
all of the Ollama results above were collected with at least an 8k context window.
An 8k window is large enough to attempt all the coding problems in the benchmark.
Aider sets Ollama's context window to 8k by default, starting in aider v0.65.0.
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)

View File

@@ -0,0 +1,140 @@
---
title: QwQ is a code architect, not an editor
excerpt: QwQ is reasoning model like o1, and needs to be used as an architect with another model as editor.
highlight_image: /assets/qwq.jpg
draft: false
nav_exclude: true
---
{% if page.date %}
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
{% endif %}
# QwQ is a code architect, not an editor
{: .no_toc }
<canvas id="qwqChart" width="800" height="500" style="margin: 20px 0"></canvas>
QwQ 32B Preview is a "reasoning" model, which spends a lot of tokens thinking before
rendering a final response.
This is similar to OpenAI's o1 models, which are most effective with aider
[when paired as an architect with a traditional LLM as an editor](https://aider.chat/2024/09/26/architect.html).
In this mode, the reasoning model acts as an "architect" to propose a solution to the
coding problem without regard for how to actually make edits to the source files.
The "editor" model receives that proposal, and focuses solely on how to
edit the existing source code to implement it.
Used alone without being paired with an editor,
QwQ was unable to comply with even the simplest
[editing format](https://aider.chat/docs/more/edit-formats.html).
It was not able to reliably edit source code files.
As a result, QwQ's solo score on the benchmark was quite underwhelming
(and far worse than the o1 models performing solo).
QwQ is based on
Qwen 2.5 Coder 32B Instruct,
and does better when paired with it as an architect + editor combo.
Though this provided only a modest benchmark improvement over just using Qwen alone,
and comes with a fairly high cost in terms of latency.
Each request must wait for QwQ to return all its thinking text
and the final solution proposal.
And then one must wait for Qwen to turn that large
response into actual file edits.
Pairing QwQ with other sensible editor models performed the same or worse than
just using Qwen 2.5 Coder 32B Instruct alone.
QwQ+Qwen seems to be the best way to use QwQ, achieving a score of 74%.
That is well below the
SOTA results for this benchmark: Sonnet alone scores 84%, and
o1-preview + o1-mini as architect + editor scores 85%.
## QwQ specific editing formats
I spent some time experimenting with a variety of custom editing formats
for QwQ.
In particular, I tried to parse the QwQ response and discard the long
sections of "thinking" and retain only the "final" solution.
None of this custom work seemed to translate
into any significant improvement in the benchmark results.
## Results
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% include qwq-chart.js %}
</script>
<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 qwq_sorted = site.data.qwq | sort: 'pass_rate_2' | reverse %}
{% for row in qwq_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('qwqSearchInput').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>
## Open source model caveats
As discussed in a recent blog post,
[details matter with open source models](https://aider.chat/2024/11/21/quantization.html).
For clarity, new benchmark runs for this article were
performed against OpenRouter's endpoints for
QwQ 32B Preview and Qwen 2.5 Coder 32B Instruct.
For the other models, the benchmark was direct to their providers' APIs.
Having recently done extensive testing of OpenRouter's Qwen 2.5 Coder 32B Instruct endpoint,
it seems reliable.
The provider Mancer was blocked due to the small context window it provides.
For QwQ 32B Preview, Fireworks was blocked because of its small context window.

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -14,14 +14,8 @@
## show this help message and exit
#help: xxx
#######
# Main:
## Specify the OpenAI API key
#openai-api-key: xxx
## Specify the Anthropic API key
#anthropic-api-key: xxx
#############
# Main model:
## Specify the model to use for the main chat
#model: xxx
@@ -38,7 +32,7 @@
## Use gpt-4-0613 model for the main chat
#4: false
## Use gpt-4o-2024-08-06 model for the main chat
## Use gpt-4o model for the main chat
#4o: false
## Use gpt-4o-mini model for the main chat
@@ -59,27 +53,52 @@
## Use o1-preview model for the main chat
#o1-preview: false
#################
# Model Settings:
########################
# API Keys and settings:
## List known models which match the (partial) MODEL name
#list-models: xxx
## Specify the OpenAI API key
#openai-api-key: xxx
## Specify the Anthropic API key
#anthropic-api-key: xxx
## Specify the api base url
#openai-api-base: xxx
## Specify the api_type
## (deprecated, use --set-env OPENAI_API_TYPE=<value>)
#openai-api-type: xxx
## Specify the api_version
## (deprecated, use --set-env OPENAI_API_VERSION=<value>)
#openai-api-version: xxx
## Specify the deployment_id
## (deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)
#openai-api-deployment-id: xxx
## Specify the OpenAI organization ID
## (deprecated, use --set-env OPENAI_ORGANIZATION=<value>)
#openai-organization-id: xxx
## Set an environment variable (to control API settings, can be used multiple times)
#set-env: xxx
## Specify multiple values like this:
#set-env:
# - xxx
# - yyy
# - zzz
## Set an API key for a provider (eg: --api-key provider=<key> sets PROVIDER_API_KEY=<key>)
#api-key: xxx
## Specify multiple values like this:
#api-key:
# - xxx
# - yyy
# - zzz
#################
# Model settings:
## List known models which match the (partial) MODEL name
#list-models: xxx
## Specify a file with aider model settings for unknown models
#model-settings-file: .aider.model.settings.yml
@@ -97,6 +116,9 @@
## Verify the SSL cert when connecting to models (default: True)
#verify-ssl: true
## Timeout in seconds for API calls (default: None)
#timeout: xxx
## Specify what edit format the LLM should use (default depends on model)
#edit-format: xxx
@@ -118,11 +140,8 @@
## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens.
#max-chat-history-tokens: xxx
## Specify the .env file to load (default: .env in git root)
#env-file: .env
#################
# Cache Settings:
# Cache settings:
## Enable caching of prompts (default: False)
#cache-prompts: false
@@ -131,7 +150,7 @@
#cache-keepalive-pings: false
###################
# Repomap Settings:
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
#map-tokens: xxx
@@ -158,7 +177,7 @@
#llm-history-file: xxx
##################
# Output Settings:
# Output settings:
## Use colors suitable for a dark terminal background (default: False)
#dark-mode: false
@@ -206,7 +225,7 @@
#show-diffs: false
###############
# Git Settings:
# Git settings:
## Enable/disable looking for a git repo (default: True)
#git: true
@@ -250,6 +269,9 @@
## Skip the sanity check for the git repository (default: False)
#skip-sanity-check-repo: false
## Enable/disable watching files for ai coding comments (default: False)
#watch-files: false
########################
# Fixing and committing:
@@ -273,7 +295,7 @@
## Enable/disable automatic testing after changes (default: False)
#auto-test: false
## Run tests and fix problems found
## Run tests, fix problems found and then exit
#test: false
############
@@ -288,8 +310,71 @@
## Permanently disable analytics
#analytics-disable: false
############
# Upgrading:
## Check for updates and return status in the exit code
#just-check-update: false
## 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
## Upgrade aider to the latest version from PyPI
#upgrade: false
## Show the version number and exit
#version: xxx
########
# Modes:
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
#message: xxx
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
#message-file: xxx
## Run aider in your browser (default: False)
#gui: false
## Enable automatic copy/paste of chat between aider and web UI (default: False)
#copy-paste: false
## Apply the changes from the given file instead of running the chat (debug)
#apply: xxx
## Apply clipboard contents as edits using the main model's editor format
#apply-clipboard-edits: false
## Do all startup activities then exit before accepting user input (debug)
#exit: false
## Print the repo map and exit (debug)
#show-repo-map: false
## Print the system prompts and exit (debug)
#show-prompts: false
#################
# Other Settings:
# Voice settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#voice-format: wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#voice-language: en
## Specify the input device name for voice recording
#voice-input-device: xxx
#################
# Other settings:
## specify a file to edit (can be used multiple times)
#file: xxx
@@ -313,51 +398,12 @@
## Specify the language to use in the chat (default: None, uses system settings)
#chat-language: xxx
## Show the version number and exit
#version: xxx
## Check for updates and return status in the exit code
#just-check-update: false
## 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
## Upgrade aider to the latest version from PyPI
#upgrade: false
## Apply the changes from the given file instead of running the chat (debug)
#apply: xxx
## Apply clipboard contents as edits using the main model's editor format
#apply-clipboard-edits: false
## Always say yes to every confirmation
#yes-always: false
## Enable verbose output
#verbose: false
## Print the repo map and exit (debug)
#show-repo-map: false
## Print the system prompts and exit (debug)
#show-prompts: false
## Do all startup activities then exit before accepting user input (debug)
#exit: false
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
#message: xxx
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
#message-file: xxx
## Load and execute /commands from a file on launch
#load: xxx
@@ -367,8 +413,8 @@
## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory)
#config: xxx
## Run aider in your browser (default: False)
#gui: false
## Specify the .env file to load (default: .env in git root)
#env-file: .env
## Enable/disable suggesting shell commands (default: True)
#suggest-shell-commands: true
@@ -376,17 +422,11 @@
## Enable/disable fancy input with history and completion (default: True)
#fancy-input: true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#multiline: false
## Enable/disable detection and offering to add URLs to chat (default: True)
#detect-urls: true
## Specify which editor to use for the /editor command
#editor: xxx
#################
# Voice Settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#voice-format: wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#voice-language: en

View File

@@ -18,14 +18,8 @@
##...
#######
# Main:
## Specify the OpenAI API key
#OPENAI_API_KEY=
## Specify the Anthropic API key
#ANTHROPIC_API_KEY=
#############
# Main model:
## Specify the model to use for the main chat
#AIDER_MODEL=
@@ -42,7 +36,7 @@
## Use gpt-4-0613 model for the main chat
#AIDER_4=
## Use gpt-4o-2024-08-06 model for the main chat
## Use gpt-4o model for the main chat
#AIDER_4O=
## Use gpt-4o-mini model for the main chat
@@ -63,27 +57,42 @@
## Use o1-preview model for the main chat
#AIDER_O1_PREVIEW=
########################
# API Keys and settings:
## Specify the OpenAI API key
#AIDER_OPENAI_API_KEY=
## Specify the Anthropic API key
#AIDER_ANTHROPIC_API_KEY=
## Specify the api base url
#AIDER_OPENAI_API_BASE=
## (deprecated, use --set-env OPENAI_API_TYPE=<value>)
#AIDER_OPENAI_API_TYPE=
## (deprecated, use --set-env OPENAI_API_VERSION=<value>)
#AIDER_OPENAI_API_VERSION=
## (deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)
#AIDER_OPENAI_API_DEPLOYMENT_ID=
## (deprecated, use --set-env OPENAI_ORGANIZATION=<value>)
#AIDER_OPENAI_ORGANIZATION_ID=
## Set an environment variable (to control API settings, can be used multiple times)
#AIDER_SET_ENV=
## Set an API key for a provider (eg: --api-key provider=<key> sets PROVIDER_API_KEY=<key>)
#AIDER_API_KEY=
#################
# Model Settings:
# Model settings:
## List known models which match the (partial) MODEL name
#AIDER_LIST_MODELS=
## Specify the api base url
#OPENAI_API_BASE=
## Specify the api_type
#OPENAI_API_TYPE=
## Specify the api_version
#OPENAI_API_VERSION=
## Specify the deployment_id
#OPENAI_API_DEPLOYMENT_ID=
## Specify the OpenAI organization ID
#OPENAI_ORGANIZATION_ID=
## Specify a file with aider model settings for unknown models
#AIDER_MODEL_SETTINGS_FILE=.aider.model.settings.yml
@@ -96,6 +105,9 @@
## Verify the SSL cert when connecting to models (default: True)
#AIDER_VERIFY_SSL=true
## Timeout in seconds for API calls (default: None)
#AIDER_TIMEOUT=
## Specify what edit format the LLM should use (default depends on model)
#AIDER_EDIT_FORMAT=
@@ -117,11 +129,8 @@
## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens.
#AIDER_MAX_CHAT_HISTORY_TOKENS=
## Specify the .env file to load (default: .env in git root)
#AIDER_ENV_FILE=.env
#################
# Cache Settings:
# Cache settings:
## Enable caching of prompts (default: False)
#AIDER_CACHE_PROMPTS=false
@@ -130,7 +139,7 @@
#AIDER_CACHE_KEEPALIVE_PINGS=false
###################
# Repomap Settings:
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
#AIDER_MAP_TOKENS=
@@ -157,7 +166,7 @@
#AIDER_LLM_HISTORY_FILE=
##################
# Output Settings:
# Output settings:
## Use colors suitable for a dark terminal background (default: False)
#AIDER_DARK_MODE=false
@@ -205,7 +214,7 @@
#AIDER_SHOW_DIFFS=false
###############
# Git Settings:
# Git settings:
## Enable/disable looking for a git repo (default: True)
#AIDER_GIT=true
@@ -249,6 +258,9 @@
## Skip the sanity check for the git repository (default: False)
#AIDER_SKIP_SANITY_CHECK_REPO=false
## Enable/disable watching files for ai coding comments (default: False)
#AIDER_WATCH_FILES=false
########################
# Fixing and committing:
@@ -267,7 +279,7 @@
## Enable/disable automatic testing after changes (default: False)
#AIDER_AUTO_TEST=false
## Run tests and fix problems found
## Run tests, fix problems found and then exit
#AIDER_TEST=false
############
@@ -282,20 +294,8 @@
## Permanently disable analytics
#AIDER_ANALYTICS_DISABLE=false
#################
# Other Settings:
## specify a file to edit (can be used multiple times)
#AIDER_FILE=
## specify a read-only file (can be used multiple times)
#AIDER_READ=
## Use VI editing mode in the terminal (default: False)
#AIDER_VIM=false
## Specify the language to use in the chat (default: None, uses system settings)
#AIDER_CHAT_LANGUAGE=
############
# Upgrading:
## Check for updates and return status in the exit code
#AIDER_JUST_CHECK_UPDATE=false
@@ -312,26 +312,8 @@
## Upgrade aider to the latest version from PyPI
#AIDER_UPGRADE=false
## Apply the changes from the given file instead of running the chat (debug)
#AIDER_APPLY=
## Apply clipboard contents as edits using the main model's editor format
#AIDER_APPLY_CLIPBOARD_EDITS=false
## Always say yes to every confirmation
#AIDER_YES_ALWAYS=
## Enable verbose output
#AIDER_VERBOSE=false
## Print the repo map and exit (debug)
#AIDER_SHOW_REPO_MAP=false
## Print the system prompts and exit (debug)
#AIDER_SHOW_PROMPTS=false
## Do all startup activities then exit before accepting user input (debug)
#AIDER_EXIT=false
########
# Modes:
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
#AIDER_MESSAGE=
@@ -339,14 +321,68 @@
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
#AIDER_MESSAGE_FILE=
## Run aider in your browser (default: False)
#AIDER_GUI=false
## Enable automatic copy/paste of chat between aider and web UI (default: False)
#AIDER_COPY_PASTE=false
## Apply the changes from the given file instead of running the chat (debug)
#AIDER_APPLY=
## Apply clipboard contents as edits using the main model's editor format
#AIDER_APPLY_CLIPBOARD_EDITS=false
## Do all startup activities then exit before accepting user input (debug)
#AIDER_EXIT=false
## Print the repo map and exit (debug)
#AIDER_SHOW_REPO_MAP=false
## Print the system prompts and exit (debug)
#AIDER_SHOW_PROMPTS=false
#################
# Voice settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#AIDER_VOICE_FORMAT=wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#AIDER_VOICE_LANGUAGE=en
## Specify the input device name for voice recording
#AIDER_VOICE_INPUT_DEVICE=
#################
# Other settings:
## specify a file to edit (can be used multiple times)
#AIDER_FILE=
## specify a read-only file (can be used multiple times)
#AIDER_READ=
## Use VI editing mode in the terminal (default: False)
#AIDER_VIM=false
## Specify the language to use in the chat (default: None, uses system settings)
#AIDER_CHAT_LANGUAGE=
## Always say yes to every confirmation
#AIDER_YES_ALWAYS=
## Enable verbose output
#AIDER_VERBOSE=false
## Load and execute /commands from a file on launch
#AIDER_LOAD=
## Specify the encoding for input and output (default: utf-8)
#AIDER_ENCODING=utf-8
## Run aider in your browser (default: False)
#AIDER_GUI=false
## Specify the .env file to load (default: .env in git root)
#AIDER_ENV_FILE=.env
## Enable/disable suggesting shell commands (default: True)
#AIDER_SUGGEST_SHELL_COMMANDS=true
@@ -354,17 +390,11 @@
## Enable/disable fancy input with history and completion (default: True)
#AIDER_FANCY_INPUT=true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#AIDER_MULTILINE=false
## Enable/disable detection and offering to add URLs to chat (default: True)
#AIDER_DETECT_URLS=true
## Specify which editor to use for the /editor command
#AIDER_EDITOR=
#################
# Voice Settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#AIDER_VOICE_FORMAT=wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#AIDER_VOICE_LANGUAGE=en

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

View File

@@ -46,13 +46,19 @@ The json file should be a dictionary with an entry for each model, as follows:
}
```
See
[litellm's model_prices_and_context_window.json file](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json) for more examples.
{: .tip }
Use a fully qualified model name with a `provider/` at the front
in the `.aider.model.metadata.json` file.
For example, use `deepseek/deepseek-chat`, not just `deepseek-chat`.
That prefix should match the `litellm_provider` field.
### Contribute model metadata
Aider relies on
[litellm's model_prices_and_context_window.json file](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json)
for model metadata.
Consider submitting a PR to that file to add missing models.
## Model settings
@@ -504,7 +510,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
max_tokens: 8192
lazy: false
name: claude-3-5-sonnet-20240620
@@ -523,7 +529,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
max_tokens: 8192
lazy: false
name: anthropic/claude-3-5-sonnet-20240620
@@ -542,7 +548,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
max_tokens: 8192
lazy: false
name: anthropic/claude-3-5-sonnet-20241022
@@ -561,7 +567,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
max_tokens: 8192
lazy: false
name: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
@@ -580,7 +586,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
max_tokens: 8192
lazy: false
name: anthropic/claude-3-5-sonnet-latest
@@ -599,7 +605,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
max_tokens: 8192
lazy: false
name: claude-3-5-sonnet-20241022
@@ -618,7 +624,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
lazy: false
name: anthropic/claude-3-haiku-20240307
reminder: user
@@ -636,7 +642,7 @@ cog.out("```\n")
examples_as_sys_msg: false
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
lazy: false
name: anthropic/claude-3-5-haiku-20241022
reminder: user
@@ -654,7 +660,7 @@ cog.out("```\n")
examples_as_sys_msg: false
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
lazy: false
name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0
reminder: user
@@ -672,7 +678,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
lazy: false
name: claude-3-5-haiku-20241022
reminder: user
@@ -707,7 +713,7 @@ cog.out("```\n")
examples_as_sys_msg: true
extra_params:
extra_headers:
anthropic-beta: prompt-caching-2024-07-31
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
lazy: false
name: claude-3-haiku-20240307
reminder: user
@@ -977,6 +983,54 @@ cog.out("```\n")
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: null
editor_model_name: null
examples_as_sys_msg: false
extra_params: null
lazy: false
name: gemini/gemini-exp-1206
reminder: user
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: null
editor_model_name: null
examples_as_sys_msg: false
extra_params: null
lazy: false
name: gemini/gemini-exp-1114
reminder: user
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: null
editor_model_name: null
examples_as_sys_msg: false
extra_params: null
lazy: false
name: gemini/gemini-exp-1121
reminder: user
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff-fenced
@@ -1009,6 +1063,22 @@ cog.out("```\n")
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff
editor_edit_format: null
editor_model_name: null
examples_as_sys_msg: false
extra_params: null
lazy: false
name: gemini/gemini-2.0-flash-exp
reminder: user
send_undo_reply: false
streaming: true
use_repo_map: true
use_system_prompt: true
use_temperature: true
weak_model_name: null
- cache_control: false
caches_by_default: false
edit_format: diff

View File

@@ -70,14 +70,8 @@ cog.outl("```")
## show this help message and exit
#help: xxx
#######
# Main:
## Specify the OpenAI API key
#openai-api-key: xxx
## Specify the Anthropic API key
#anthropic-api-key: xxx
#############
# Main model:
## Specify the model to use for the main chat
#model: xxx
@@ -94,7 +88,7 @@ cog.outl("```")
## Use gpt-4-0613 model for the main chat
#4: false
## Use gpt-4o-2024-08-06 model for the main chat
## Use gpt-4o model for the main chat
#4o: false
## Use gpt-4o-mini model for the main chat
@@ -115,27 +109,52 @@ cog.outl("```")
## Use o1-preview model for the main chat
#o1-preview: false
#################
# Model Settings:
########################
# API Keys and settings:
## List known models which match the (partial) MODEL name
#list-models: xxx
## Specify the OpenAI API key
#openai-api-key: xxx
## Specify the Anthropic API key
#anthropic-api-key: xxx
## Specify the api base url
#openai-api-base: xxx
## Specify the api_type
## (deprecated, use --set-env OPENAI_API_TYPE=<value>)
#openai-api-type: xxx
## Specify the api_version
## (deprecated, use --set-env OPENAI_API_VERSION=<value>)
#openai-api-version: xxx
## Specify the deployment_id
## (deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)
#openai-api-deployment-id: xxx
## Specify the OpenAI organization ID
## (deprecated, use --set-env OPENAI_ORGANIZATION=<value>)
#openai-organization-id: xxx
## Set an environment variable (to control API settings, can be used multiple times)
#set-env: xxx
## Specify multiple values like this:
#set-env:
# - xxx
# - yyy
# - zzz
## Set an API key for a provider (eg: --api-key provider=<key> sets PROVIDER_API_KEY=<key>)
#api-key: xxx
## Specify multiple values like this:
#api-key:
# - xxx
# - yyy
# - zzz
#################
# Model settings:
## List known models which match the (partial) MODEL name
#list-models: xxx
## Specify a file with aider model settings for unknown models
#model-settings-file: .aider.model.settings.yml
@@ -153,6 +172,9 @@ cog.outl("```")
## Verify the SSL cert when connecting to models (default: True)
#verify-ssl: true
## Timeout in seconds for API calls (default: None)
#timeout: xxx
## Specify what edit format the LLM should use (default depends on model)
#edit-format: xxx
@@ -174,11 +196,8 @@ cog.outl("```")
## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens.
#max-chat-history-tokens: xxx
## Specify the .env file to load (default: .env in git root)
#env-file: .env
#################
# Cache Settings:
# Cache settings:
## Enable caching of prompts (default: False)
#cache-prompts: false
@@ -187,7 +206,7 @@ cog.outl("```")
#cache-keepalive-pings: false
###################
# Repomap Settings:
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
#map-tokens: xxx
@@ -214,7 +233,7 @@ cog.outl("```")
#llm-history-file: xxx
##################
# Output Settings:
# Output settings:
## Use colors suitable for a dark terminal background (default: False)
#dark-mode: false
@@ -262,7 +281,7 @@ cog.outl("```")
#show-diffs: false
###############
# Git Settings:
# Git settings:
## Enable/disable looking for a git repo (default: True)
#git: true
@@ -306,6 +325,9 @@ cog.outl("```")
## Skip the sanity check for the git repository (default: False)
#skip-sanity-check-repo: false
## Enable/disable watching files for ai coding comments (default: False)
#watch-files: false
########################
# Fixing and committing:
@@ -329,7 +351,7 @@ cog.outl("```")
## Enable/disable automatic testing after changes (default: False)
#auto-test: false
## Run tests and fix problems found
## Run tests, fix problems found and then exit
#test: false
############
@@ -344,8 +366,71 @@ cog.outl("```")
## Permanently disable analytics
#analytics-disable: false
############
# Upgrading:
## Check for updates and return status in the exit code
#just-check-update: false
## 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
## Upgrade aider to the latest version from PyPI
#upgrade: false
## Show the version number and exit
#version: xxx
########
# Modes:
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
#message: xxx
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
#message-file: xxx
## Run aider in your browser (default: False)
#gui: false
## Enable automatic copy/paste of chat between aider and web UI (default: False)
#copy-paste: false
## Apply the changes from the given file instead of running the chat (debug)
#apply: xxx
## Apply clipboard contents as edits using the main model's editor format
#apply-clipboard-edits: false
## Do all startup activities then exit before accepting user input (debug)
#exit: false
## Print the repo map and exit (debug)
#show-repo-map: false
## Print the system prompts and exit (debug)
#show-prompts: false
#################
# Other Settings:
# Voice settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#voice-format: wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#voice-language: en
## Specify the input device name for voice recording
#voice-input-device: xxx
#################
# Other settings:
## specify a file to edit (can be used multiple times)
#file: xxx
@@ -369,51 +454,12 @@ cog.outl("```")
## Specify the language to use in the chat (default: None, uses system settings)
#chat-language: xxx
## Show the version number and exit
#version: xxx
## Check for updates and return status in the exit code
#just-check-update: false
## 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
## Upgrade aider to the latest version from PyPI
#upgrade: false
## Apply the changes from the given file instead of running the chat (debug)
#apply: xxx
## Apply clipboard contents as edits using the main model's editor format
#apply-clipboard-edits: false
## Always say yes to every confirmation
#yes-always: false
## Enable verbose output
#verbose: false
## Print the repo map and exit (debug)
#show-repo-map: false
## Print the system prompts and exit (debug)
#show-prompts: false
## Do all startup activities then exit before accepting user input (debug)
#exit: false
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
#message: xxx
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
#message-file: xxx
## Load and execute /commands from a file on launch
#load: xxx
@@ -423,8 +469,8 @@ cog.outl("```")
## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory)
#config: xxx
## Run aider in your browser (default: False)
#gui: false
## Specify the .env file to load (default: .env in git root)
#env-file: .env
## Enable/disable suggesting shell commands (default: True)
#suggest-shell-commands: true
@@ -432,19 +478,13 @@ cog.outl("```")
## Enable/disable fancy input with history and completion (default: True)
#fancy-input: true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#multiline: false
## Enable/disable detection and offering to add URLs to chat (default: True)
#detect-urls: true
## Specify which editor to use for the /editor command
#editor: xxx
#################
# Voice Settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#voice-format: wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#voice-language: en
```
<!--[[[end]]]-->

View File

@@ -1,6 +1,6 @@
---
parent: Configuration
nav_order: 900
nav_order: 20
description: Using a .env file to store LLM API keys for aider.
---
@@ -24,6 +24,8 @@ If the files above exist, they will be loaded in that order. Files loaded last w
{% include special-keys.md %}
{% include env-keys-tip.md %}
## Sample .env file
Below is a sample `.env` file, which you
@@ -60,14 +62,8 @@ cog.outl("```")
##...
#######
# Main:
## Specify the OpenAI API key
#OPENAI_API_KEY=
## Specify the Anthropic API key
#ANTHROPIC_API_KEY=
#############
# Main model:
## Specify the model to use for the main chat
#AIDER_MODEL=
@@ -84,7 +80,7 @@ cog.outl("```")
## Use gpt-4-0613 model for the main chat
#AIDER_4=
## Use gpt-4o-2024-08-06 model for the main chat
## Use gpt-4o model for the main chat
#AIDER_4O=
## Use gpt-4o-mini model for the main chat
@@ -105,27 +101,42 @@ cog.outl("```")
## Use o1-preview model for the main chat
#AIDER_O1_PREVIEW=
########################
# API Keys and settings:
## Specify the OpenAI API key
#AIDER_OPENAI_API_KEY=
## Specify the Anthropic API key
#AIDER_ANTHROPIC_API_KEY=
## Specify the api base url
#AIDER_OPENAI_API_BASE=
## (deprecated, use --set-env OPENAI_API_TYPE=<value>)
#AIDER_OPENAI_API_TYPE=
## (deprecated, use --set-env OPENAI_API_VERSION=<value>)
#AIDER_OPENAI_API_VERSION=
## (deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)
#AIDER_OPENAI_API_DEPLOYMENT_ID=
## (deprecated, use --set-env OPENAI_ORGANIZATION=<value>)
#AIDER_OPENAI_ORGANIZATION_ID=
## Set an environment variable (to control API settings, can be used multiple times)
#AIDER_SET_ENV=
## Set an API key for a provider (eg: --api-key provider=<key> sets PROVIDER_API_KEY=<key>)
#AIDER_API_KEY=
#################
# Model Settings:
# Model settings:
## List known models which match the (partial) MODEL name
#AIDER_LIST_MODELS=
## Specify the api base url
#OPENAI_API_BASE=
## Specify the api_type
#OPENAI_API_TYPE=
## Specify the api_version
#OPENAI_API_VERSION=
## Specify the deployment_id
#OPENAI_API_DEPLOYMENT_ID=
## Specify the OpenAI organization ID
#OPENAI_ORGANIZATION_ID=
## Specify a file with aider model settings for unknown models
#AIDER_MODEL_SETTINGS_FILE=.aider.model.settings.yml
@@ -138,6 +149,9 @@ cog.outl("```")
## Verify the SSL cert when connecting to models (default: True)
#AIDER_VERIFY_SSL=true
## Timeout in seconds for API calls (default: None)
#AIDER_TIMEOUT=
## Specify what edit format the LLM should use (default depends on model)
#AIDER_EDIT_FORMAT=
@@ -159,11 +173,8 @@ cog.outl("```")
## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens.
#AIDER_MAX_CHAT_HISTORY_TOKENS=
## Specify the .env file to load (default: .env in git root)
#AIDER_ENV_FILE=.env
#################
# Cache Settings:
# Cache settings:
## Enable caching of prompts (default: False)
#AIDER_CACHE_PROMPTS=false
@@ -172,7 +183,7 @@ cog.outl("```")
#AIDER_CACHE_KEEPALIVE_PINGS=false
###################
# Repomap Settings:
# Repomap settings:
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
#AIDER_MAP_TOKENS=
@@ -199,7 +210,7 @@ cog.outl("```")
#AIDER_LLM_HISTORY_FILE=
##################
# Output Settings:
# Output settings:
## Use colors suitable for a dark terminal background (default: False)
#AIDER_DARK_MODE=false
@@ -247,7 +258,7 @@ cog.outl("```")
#AIDER_SHOW_DIFFS=false
###############
# Git Settings:
# Git settings:
## Enable/disable looking for a git repo (default: True)
#AIDER_GIT=true
@@ -291,6 +302,9 @@ cog.outl("```")
## Skip the sanity check for the git repository (default: False)
#AIDER_SKIP_SANITY_CHECK_REPO=false
## Enable/disable watching files for ai coding comments (default: False)
#AIDER_WATCH_FILES=false
########################
# Fixing and committing:
@@ -309,7 +323,7 @@ cog.outl("```")
## Enable/disable automatic testing after changes (default: False)
#AIDER_AUTO_TEST=false
## Run tests and fix problems found
## Run tests, fix problems found and then exit
#AIDER_TEST=false
############
@@ -324,20 +338,8 @@ cog.outl("```")
## Permanently disable analytics
#AIDER_ANALYTICS_DISABLE=false
#################
# Other Settings:
## specify a file to edit (can be used multiple times)
#AIDER_FILE=
## specify a read-only file (can be used multiple times)
#AIDER_READ=
## Use VI editing mode in the terminal (default: False)
#AIDER_VIM=false
## Specify the language to use in the chat (default: None, uses system settings)
#AIDER_CHAT_LANGUAGE=
############
# Upgrading:
## Check for updates and return status in the exit code
#AIDER_JUST_CHECK_UPDATE=false
@@ -354,26 +356,8 @@ cog.outl("```")
## Upgrade aider to the latest version from PyPI
#AIDER_UPGRADE=false
## Apply the changes from the given file instead of running the chat (debug)
#AIDER_APPLY=
## Apply clipboard contents as edits using the main model's editor format
#AIDER_APPLY_CLIPBOARD_EDITS=false
## Always say yes to every confirmation
#AIDER_YES_ALWAYS=
## Enable verbose output
#AIDER_VERBOSE=false
## Print the repo map and exit (debug)
#AIDER_SHOW_REPO_MAP=false
## Print the system prompts and exit (debug)
#AIDER_SHOW_PROMPTS=false
## Do all startup activities then exit before accepting user input (debug)
#AIDER_EXIT=false
########
# Modes:
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
#AIDER_MESSAGE=
@@ -381,14 +365,68 @@ cog.outl("```")
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
#AIDER_MESSAGE_FILE=
## Run aider in your browser (default: False)
#AIDER_GUI=false
## Enable automatic copy/paste of chat between aider and web UI (default: False)
#AIDER_COPY_PASTE=false
## Apply the changes from the given file instead of running the chat (debug)
#AIDER_APPLY=
## Apply clipboard contents as edits using the main model's editor format
#AIDER_APPLY_CLIPBOARD_EDITS=false
## Do all startup activities then exit before accepting user input (debug)
#AIDER_EXIT=false
## Print the repo map and exit (debug)
#AIDER_SHOW_REPO_MAP=false
## Print the system prompts and exit (debug)
#AIDER_SHOW_PROMPTS=false
#################
# Voice settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#AIDER_VOICE_FORMAT=wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#AIDER_VOICE_LANGUAGE=en
## Specify the input device name for voice recording
#AIDER_VOICE_INPUT_DEVICE=
#################
# Other settings:
## specify a file to edit (can be used multiple times)
#AIDER_FILE=
## specify a read-only file (can be used multiple times)
#AIDER_READ=
## Use VI editing mode in the terminal (default: False)
#AIDER_VIM=false
## Specify the language to use in the chat (default: None, uses system settings)
#AIDER_CHAT_LANGUAGE=
## Always say yes to every confirmation
#AIDER_YES_ALWAYS=
## Enable verbose output
#AIDER_VERBOSE=false
## Load and execute /commands from a file on launch
#AIDER_LOAD=
## Specify the encoding for input and output (default: utf-8)
#AIDER_ENCODING=utf-8
## Run aider in your browser (default: False)
#AIDER_GUI=false
## Specify the .env file to load (default: .env in git root)
#AIDER_ENV_FILE=.env
## Enable/disable suggesting shell commands (default: True)
#AIDER_SUGGEST_SHELL_COMMANDS=true
@@ -396,21 +434,13 @@ cog.outl("```")
## Enable/disable fancy input with history and completion (default: True)
#AIDER_FANCY_INPUT=true
## Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
#AIDER_MULTILINE=false
## Enable/disable detection and offering to add URLs to chat (default: True)
#AIDER_DETECT_URLS=true
## Specify which editor to use for the /editor command
#AIDER_EDITOR=
#################
# Voice Settings:
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
#AIDER_VOICE_FORMAT=wav
## Specify the language for voice using ISO 639-1 code (default: auto)
#AIDER_VOICE_LANGUAGE=en
```
<!--[[[end]]]-->

View File

@@ -1,6 +1,6 @@
---
parent: Configuration
nav_order: 15
nav_order: 100
description: How to configure a custom editor for aider's /editor command
---

View File

@@ -54,11 +54,12 @@ for alias, model in sorted(MODEL_ALIASES.items()):
- `35turbo`: gpt-3.5-turbo
- `4`: gpt-4-0613
- `4-turbo`: gpt-4-1106-preview
- `4o`: gpt-4o-2024-08-06
- `4o`: gpt-4o
- `deepseek`: deepseek/deepseek-coder
- `haiku`: claude-3-haiku-20241022
- `flash`: gemini/gemini-2.0-flash-exp
- `haiku`: claude-3-5-haiku-20241022
- `opus`: claude-3-opus-20240229
- `sonnet`: claude-3-sonnet-20241022
- `sonnet`: claude-3-5-sonnet-20241022
<!--[[[end]]]-->
## Priority

View File

@@ -14,7 +14,6 @@ or review them below.
{:toc}
## LLM keys
{: .no_toc }
{% include special-keys.md %}
@@ -25,18 +24,19 @@ from aider.args import get_md_help
cog.out(get_md_help())
]]]-->
```
usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
[--opus] [--sonnet] [--haiku] [--4] [--4o] [--mini]
[--4-turbo] [--35turbo] [--deepseek] [--o1-mini]
[--o1-preview] [--list-models] [--openai-api-base]
usage: aider [-h] [--model] [--opus] [--sonnet] [--haiku] [--4]
[--4o] [--mini] [--4-turbo] [--35turbo] [--deepseek]
[--o1-mini] [--o1-preview] [--openai-api-key]
[--anthropic-api-key] [--openai-api-base]
[--openai-api-type] [--openai-api-version]
[--openai-api-deployment-id] [--openai-organization-id]
[--set-env] [--api-key] [--list-models]
[--model-settings-file] [--model-metadata-file]
[--alias] [--verify-ssl | --no-verify-ssl]
[--alias] [--verify-ssl | --no-verify-ssl] [--timeout]
[--edit-format] [--architect] [--weak-model]
[--editor-model] [--editor-edit-format]
[--show-model-warnings | --no-show-model-warnings]
[--max-chat-history-tokens] [--env-file]
[--max-chat-history-tokens]
[--cache-prompts | --no-cache-prompts]
[--cache-keepalive-pings] [--map-tokens]
[--map-refresh] [--map-multiplier-no-files]
@@ -59,23 +59,27 @@ usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
[--attribute-commit-message-author | --no-attribute-commit-message-author]
[--attribute-commit-message-committer | --no-attribute-commit-message-committer]
[--commit] [--commit-prompt] [--dry-run | --no-dry-run]
[--skip-sanity-check-repo] [--lint] [--lint-cmd]
[--auto-lint | --no-auto-lint] [--test-cmd]
[--auto-test | --no-auto-test] [--test]
[--skip-sanity-check-repo]
[--watch-files | --no-watch-files] [--lint]
[--lint-cmd] [--auto-lint | --no-auto-lint]
[--test-cmd] [--auto-test | --no-auto-test] [--test]
[--analytics | --no-analytics] [--analytics-log]
[--analytics-disable] [--file] [--read] [--vim]
[--chat-language] [--version] [--just-check-update]
[--analytics-disable] [--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]
[--install-main-branch] [--upgrade] [--version]
[--message] [--message-file]
[--gui | --no-gui | --browser | --no-browser]
[--copy-paste | --no-copy-paste] [--apply]
[--apply-clipboard-edits] [--exit] [--show-repo-map]
[--show-prompts] [--voice-format] [--voice-language]
[--voice-input-device] [--file] [--read] [--vim]
[--chat-language] [--yes-always] [-v] [--load]
[--encoding] [-c] [--env-file]
[--suggest-shell-commands | --no-suggest-shell-commands]
[--fancy-input | --no-fancy-input]
[--multiline | --no-multiline]
[--detect-urls | --no-detect-urls] [--editor]
[--voice-format] [--voice-language]
```
@@ -87,15 +91,7 @@ Aliases:
- `-h`
- `--help`
## Main:
### `--openai-api-key OPENAI_API_KEY`
Specify the OpenAI API key
Environment variable: `OPENAI_API_KEY`
### `--anthropic-api-key ANTHROPIC_API_KEY`
Specify the Anthropic API key
Environment variable: `ANTHROPIC_API_KEY`
## Main model:
### `--model MODEL`
Specify the model to use for the main chat
@@ -121,7 +117,7 @@ Aliases:
- `-4`
### `--4o`
Use gpt-4o-2024-08-06 model for the main chat
Use gpt-4o model for the main chat
Environment variable: `AIDER_4O`
### `--mini`
@@ -153,7 +149,47 @@ Environment variable: `AIDER_O1_MINI`
Use o1-preview model for the main chat
Environment variable: `AIDER_O1_PREVIEW`
## Model Settings:
## API Keys and settings:
### `--openai-api-key VALUE`
Specify the OpenAI API key
Environment variable: `AIDER_OPENAI_API_KEY`
### `--anthropic-api-key VALUE`
Specify the Anthropic API key
Environment variable: `AIDER_ANTHROPIC_API_KEY`
### `--openai-api-base VALUE`
Specify the api base url
Environment variable: `AIDER_OPENAI_API_BASE`
### `--openai-api-type VALUE`
(deprecated, use --set-env OPENAI_API_TYPE=<value>)
Environment variable: `AIDER_OPENAI_API_TYPE`
### `--openai-api-version VALUE`
(deprecated, use --set-env OPENAI_API_VERSION=<value>)
Environment variable: `AIDER_OPENAI_API_VERSION`
### `--openai-api-deployment-id VALUE`
(deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)
Environment variable: `AIDER_OPENAI_API_DEPLOYMENT_ID`
### `--openai-organization-id VALUE`
(deprecated, use --set-env OPENAI_ORGANIZATION=<value>)
Environment variable: `AIDER_OPENAI_ORGANIZATION_ID`
### `--set-env ENV_VAR_NAME=value`
Set an environment variable (to control API settings, can be used multiple times)
Default: []
Environment variable: `AIDER_SET_ENV`
### `--api-key PROVIDER=KEY`
Set an API key for a provider (eg: --api-key provider=<key> sets PROVIDER_API_KEY=<key>)
Default: []
Environment variable: `AIDER_API_KEY`
## Model settings:
### `--list-models MODEL`
List known models which match the (partial) MODEL name
@@ -162,26 +198,6 @@ Aliases:
- `--list-models MODEL`
- `--models MODEL`
### `--openai-api-base OPENAI_API_BASE`
Specify the api base url
Environment variable: `OPENAI_API_BASE`
### `--openai-api-type OPENAI_API_TYPE`
Specify the api_type
Environment variable: `OPENAI_API_TYPE`
### `--openai-api-version OPENAI_API_VERSION`
Specify the api_version
Environment variable: `OPENAI_API_VERSION`
### `--openai-api-deployment-id OPENAI_API_DEPLOYMENT_ID`
Specify the deployment_id
Environment variable: `OPENAI_API_DEPLOYMENT_ID`
### `--openai-organization-id OPENAI_ORGANIZATION_ID`
Specify the OpenAI organization ID
Environment variable: `OPENAI_ORGANIZATION_ID`
### `--model-settings-file MODEL_SETTINGS_FILE`
Specify a file with aider model settings for unknown models
Default: .aider.model.settings.yml
@@ -204,6 +220,10 @@ Aliases:
- `--verify-ssl`
- `--no-verify-ssl`
### `--timeout VALUE`
Timeout in seconds for API calls (default: None)
Environment variable: `AIDER_TIMEOUT`
### `--edit-format EDIT_FORMAT`
Specify what edit format the LLM should use (default depends on model)
Environment variable: `AIDER_EDIT_FORMAT`
@@ -239,12 +259,7 @@ Aliases:
Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens.
Environment variable: `AIDER_MAX_CHAT_HISTORY_TOKENS`
### `--env-file ENV_FILE`
Specify the .env file to load (default: .env in git root)
Default: .env
Environment variable: `AIDER_ENV_FILE`
## Cache Settings:
## Cache settings:
### `--cache-prompts`
Enable caching of prompts (default: False)
@@ -259,7 +274,7 @@ Number of times to ping at 5min intervals to keep prompt cache warm (default: 0)
Default: 0
Environment variable: `AIDER_CACHE_KEEPALIVE_PINGS`
## Repomap Settings:
## Repomap settings:
### `--map-tokens VALUE`
Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
@@ -299,7 +314,7 @@ Aliases:
Log the conversation with the LLM to this file (for example, .aider.llm.history)
Environment variable: `AIDER_LLM_HISTORY_FILE`
## Output Settings:
## Output settings:
### `--dark-mode`
Use colors suitable for a dark terminal background (default: False)
@@ -377,7 +392,7 @@ Show diffs when committing changes (default: False)
Default: False
Environment variable: `AIDER_SHOW_DIFFS`
## Git Settings:
## Git settings:
### `--git`
Enable/disable looking for a git repo (default: True)
@@ -475,6 +490,14 @@ Skip the sanity check for the git repository (default: False)
Default: False
Environment variable: `AIDER_SKIP_SANITY_CHECK_REPO`
### `--watch-files`
Enable/disable watching files for ai coding comments (default: False)
Default: False
Environment variable: `AIDER_WATCH_FILES`
Aliases:
- `--watch-files`
- `--no-watch-files`
## Fixing and committing:
### `--lint`
@@ -509,7 +532,7 @@ Aliases:
- `--no-auto-test`
### `--test`
Run tests and fix problems found
Run tests, fix problems found and then exit
Default: False
Environment variable: `AIDER_TEST`
@@ -531,27 +554,7 @@ Permanently disable analytics
Default: False
Environment variable: `AIDER_ANALYTICS_DISABLE`
## Other Settings:
### `--file FILE`
specify a file to edit (can be used multiple times)
Environment variable: `AIDER_FILE`
### `--read FILE`
specify a read-only file (can be used multiple times)
Environment variable: `AIDER_READ`
### `--vim`
Use VI editing mode in the terminal (default: False)
Default: False
Environment variable: `AIDER_VIM`
### `--chat-language CHAT_LANGUAGE`
Specify the language to use in the chat (default: None, uses system settings)
Environment variable: `AIDER_CHAT_LANGUAGE`
### `--version`
Show the version number and exit
## Upgrading:
### `--just-check-update`
Check for updates and return status in the exit code
@@ -586,41 +589,10 @@ Aliases:
- `--upgrade`
- `--update`
### `--apply FILE`
Apply the changes from the given file instead of running the chat (debug)
Environment variable: `AIDER_APPLY`
### `--version`
Show the version number and exit
### `--apply-clipboard-edits`
Apply clipboard contents as edits using the main model's editor format
Default: False
Environment variable: `AIDER_APPLY_CLIPBOARD_EDITS`
### `--yes-always`
Always say yes to every confirmation
Environment variable: `AIDER_YES_ALWAYS`
### `--verbose`
Enable verbose output
Default: False
Environment variable: `AIDER_VERBOSE`
Aliases:
- `-v`
- `--verbose`
### `--show-repo-map`
Print the repo map and exit (debug)
Default: False
Environment variable: `AIDER_SHOW_REPO_MAP`
### `--show-prompts`
Print the system prompts and exit (debug)
Default: False
Environment variable: `AIDER_SHOW_PROMPTS`
### `--exit`
Do all startup activities then exit before accepting user input (debug)
Default: False
Environment variable: `AIDER_EXIT`
## Modes:
### `--message COMMAND`
Specify a single message to send the LLM, process reply then exit (disables chat mode)
@@ -637,6 +609,95 @@ Aliases:
- `--message-file MESSAGE_FILE`
- `-f MESSAGE_FILE`
### `--gui`
Run aider in your browser (default: False)
Default: False
Environment variable: `AIDER_GUI`
Aliases:
- `--gui`
- `--no-gui`
- `--browser`
- `--no-browser`
### `--copy-paste`
Enable automatic copy/paste of chat between aider and web UI (default: False)
Default: False
Environment variable: `AIDER_COPY_PASTE`
Aliases:
- `--copy-paste`
- `--no-copy-paste`
### `--apply FILE`
Apply the changes from the given file instead of running the chat (debug)
Environment variable: `AIDER_APPLY`
### `--apply-clipboard-edits`
Apply clipboard contents as edits using the main model's editor format
Default: False
Environment variable: `AIDER_APPLY_CLIPBOARD_EDITS`
### `--exit`
Do all startup activities then exit before accepting user input (debug)
Default: False
Environment variable: `AIDER_EXIT`
### `--show-repo-map`
Print the repo map and exit (debug)
Default: False
Environment variable: `AIDER_SHOW_REPO_MAP`
### `--show-prompts`
Print the system prompts and exit (debug)
Default: False
Environment variable: `AIDER_SHOW_PROMPTS`
## Voice settings:
### `--voice-format VOICE_FORMAT`
Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
Default: wav
Environment variable: `AIDER_VOICE_FORMAT`
### `--voice-language VOICE_LANGUAGE`
Specify the language for voice using ISO 639-1 code (default: auto)
Default: en
Environment variable: `AIDER_VOICE_LANGUAGE`
### `--voice-input-device VOICE_INPUT_DEVICE`
Specify the input device name for voice recording
Environment variable: `AIDER_VOICE_INPUT_DEVICE`
## Other settings:
### `--file FILE`
specify a file to edit (can be used multiple times)
Environment variable: `AIDER_FILE`
### `--read FILE`
specify a read-only file (can be used multiple times)
Environment variable: `AIDER_READ`
### `--vim`
Use VI editing mode in the terminal (default: False)
Default: False
Environment variable: `AIDER_VIM`
### `--chat-language CHAT_LANGUAGE`
Specify the language to use in the chat (default: None, uses system settings)
Environment variable: `AIDER_CHAT_LANGUAGE`
### `--yes-always`
Always say yes to every confirmation
Environment variable: `AIDER_YES_ALWAYS`
### `--verbose`
Enable verbose output
Default: False
Environment variable: `AIDER_VERBOSE`
Aliases:
- `-v`
- `--verbose`
### `--load LOAD_FILE`
Load and execute /commands from a file on launch
Environment variable: `AIDER_LOAD`
@@ -652,15 +713,10 @@ Aliases:
- `-c CONFIG_FILE`
- `--config CONFIG_FILE`
### `--gui`
Run aider in your browser (default: False)
Default: False
Environment variable: `AIDER_GUI`
Aliases:
- `--gui`
- `--no-gui`
- `--browser`
- `--no-browser`
### `--env-file ENV_FILE`
Specify the .env file to load (default: .env in git root)
Default: .env
Environment variable: `AIDER_ENV_FILE`
### `--suggest-shell-commands`
Enable/disable suggesting shell commands (default: True)
@@ -678,6 +734,14 @@ Aliases:
- `--fancy-input`
- `--no-fancy-input`
### `--multiline`
Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
Default: False
Environment variable: `AIDER_MULTILINE`
Aliases:
- `--multiline`
- `--no-multiline`
### `--detect-urls`
Enable/disable detection and offering to add URLs to chat (default: True)
Default: True
@@ -689,16 +753,4 @@ Aliases:
### `--editor VALUE`
Specify which editor to use for the /editor command
Environment variable: `AIDER_EDITOR`
## Voice Settings:
### `--voice-format VOICE_FORMAT`
Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
Default: wav
Environment variable: `AIDER_VOICE_FORMAT`
### `--voice-language VOICE_LANGUAGE`
Specify the language for voice using ISO 639-1 code (default: auto)
Default: en
Environment variable: `AIDER_VOICE_LANGUAGE`
<!--[[[end]]]-->

View File

@@ -169,7 +169,10 @@ python -m aider
## Can I change the system prompts that aider uses?
Aider is set up to support different system prompts and edit formats
The most convenient way to add custom instructions is to use a
[conventions file](https://aider.chat/docs/usage/conventions.html).
But, aider is set up to support different actual system prompts and edit formats
in a modular way. If you look in the `aider/coders` subdirectory, you'll
see there's a base coder with base prompts, and then there are
a number of
@@ -217,6 +220,18 @@ by doing something like `git blame` on the repo,
and counting up who wrote all the new lines of code in each release.
Only lines in source code files are counted, not documentation or prompt files.
## Why is the LLM speaking to me in an unexpected language?
Aider goes to some effort to prompt the model to use the language that is configured
for your system.
But LLMs aren't fully reliable, and they sometimes decide to speak in
an unexpected language.
Claude is especially fond of speaking French.
You can explicitly set the language that aider tells the model to use with
`--chat-language <language>`.
But the LLM may not comply.
## Can I share my aider chat transcript?
Yes, you can now share aider chat logs in a pretty way.

View File

@@ -15,7 +15,7 @@ for more details,
or the
[usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
{% include python-m-aider.md %}
{% include venv-pipx.md %}
<div class="video-container">
<video controls poster="/assets/install.jpg">

View File

@@ -33,28 +33,28 @@ To work with Anthropic's models like Claude 3.5 Sonnet you need a paid
## Mac/Linux install
```
```bash
# Install aider
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
# To work with GPT-4o:
$ aider --4o --openai-api-key sk-xxx...
aider --4o --openai-api-key sk-xxx...
# To work with Claude 3.5 Sonnet:
$ aider --sonnet --anthropic-api-key sk-xxx...
aider --sonnet --anthropic-api-key sk-xxx...
```
## Windows install
```
```bash
# Install aider
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
# To work with GPT-4o:
$ aider --4o --openai-api-key sk-xxx...
aider --4o --openai-api-key sk-xxx...
# To work with Claude 3.5 Sonnet:
$ aider --sonnet --anthropic-api-key sk-xxx...
aider --sonnet --anthropic-api-key sk-xxx...
```
{% include python-m-aider.md %}

View File

@@ -53,6 +53,7 @@ Installing PortAudio is completely optional, but can usually be accomplished lik
- For Windows, there is no need to install PortAudio.
- For Mac, do `brew install portaudio`
- For Linux, do `sudo apt-get install libportaudio2`
- Some linux environments may also need `sudo apt install libasound2-plugins`
## Add aider to your editor

View File

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

View File

@@ -0,0 +1,18 @@
---
parent: Installation
nav_order: 100
---
# Install with uv
A recommended way to install aider is with uv:
```bash
python -m pip install uv # If you need to install uv
uv tool install --python python3.12 aider-chat
```
See also the
[docs on other methods for installing uv itself](https://docs.astral.sh/uv/getting-started/installation/).
{% include conflicts.md %}

View File

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

View File

@@ -58,6 +58,7 @@ The model also has to successfully apply all its changes to the source file with
</table>
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% include edit-leaderboard.js %}
@@ -113,6 +114,7 @@ Therefore, results are available for fewer models.
</table>
<canvas id="refacChart" width="800" height="450" style="margin-top: 20px"></canvas>
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
{% include refactor-leaderboard.js %}
@@ -181,6 +183,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 24, 2024.
December 11, 2024.
<!--[[[end]]]-->
</p>

View File

@@ -69,7 +69,7 @@ We make reasonable efforts to protect your information by using physical and ele
### Childrens Privacy
We do not knowingly collect, maintain, or use personal information from children under 18 years of age, and no part of our Service(s) is directed to children. If you learn that a child has provided us with personal information in violation of this Privacy Policy, then you may alert us at [INSERT EMAIL ADDRESS].
We do not knowingly collect, maintain, or use personal information from children under 18 years of age, and no part of our Service(s) is directed to children. If you learn that a child has provided us with personal information in violation of this Privacy Policy, then you may alert us at privacy@aider.chat.
### International Visitors
@@ -98,7 +98,7 @@ if result.returncode == 0:
date = datetime.datetime.fromtimestamp(timestamp)
cog.out(f"{date.strftime('%B %d, %Y.')}")
]]]-->
October 31, 2024.
December 06, 2024.
<!--[[[end]]]-->
</p>

View File

@@ -39,12 +39,18 @@ export AWS_PROFILE=your-profile
You can add these to your
[.env file](/docs/config/dotenv.html).
## Bedrock with `pipx` installation
## Install boto3
The AWS Bedrock provider requires the `boto3` package in order to function correctly. To use aider installed via `pipx` with AWS Bedrock, you must add the `boto3` dependency to aider's virtual environment by running
The AWS Bedrock provider requires the `boto3` package in order to function correctly:
```bash
pip install boto3
```
pipx inject aider boto3
To use aider installed via `pipx` with AWS Bedrock, you must add the `boto3` dependency to aider's virtual environment by running
```bash
pipx inject aider-chat boto3
```
@@ -56,12 +62,18 @@ Once your AWS credentials are set up, you can run Aider with the `--model` comma
aider --model bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
```
Sometimes it seems to help if you prefix the model name with "us.":
```bash
aider --model bedrock/us.anthropic.claude-3-5-sonnet-20240620-v1:0
```
## Available Models
To see some models available via Bedrock, run:
```
```bash
aider --list-models bedrock/
```

View File

@@ -5,15 +5,17 @@ nav_order: 300
# Gemini
Google currently offers
[*free* API access to the Gemini 1.5 Pro model](https://ai.google.dev/pricing).
This is the most capable free model to use with aider,
with code editing capability that's comparable to GPT-3.5.
You'll need a [Gemini API key](https://aistudio.google.com/app/u/2/apikey).
```
python -m pip install -U aider-chat
# You may need to install google-generativeai
pip install -U google-generativeai
# Or with pipx...
pipx inject aider-chat google-generativeai
export GEMINI_API_KEY=<key> # Mac/Linux
setx GEMINI_API_KEY <key> # Windows, restart shell after setx

View File

@@ -96,5 +96,5 @@ coder = Coder.create(model=model, fnames=fnames, io=io)
```
{: .note }
The scripting API is not officially supported or documented and may
change without warning.
The python scripting API is not officially supported or documented,
and could change in future releases without providing backwards compatibility.

View File

@@ -12,11 +12,12 @@ Every LLM has limits on how many tokens it can process for each request:
- Each model has limit on how many **output tokens** it can
produce.
Aider will report an error if a model responds indicating that
Aider will report an error **if a model responds** indicating that
it has exceeded a token limit.
The error will include suggested actions to try and
avoid hitting token limits.
Here's an example error:
Here's an example error:
```
Model gpt-3.5-turbo has hit a token limit!
@@ -36,9 +37,7 @@ 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.
The token counts that aider reports are *estimates*.
## Input tokens & context window size

View File

@@ -29,6 +29,7 @@ cog.out(get_help_md())
| **/code** | Ask for changes to your code |
| **/commit** | Commit edits to the repo made outside the chat (commit message optional) |
| **/copy** | Copy the last assistant message to the clipboard |
| **/copy-context** | Copy the current chat context as markdown, suitable to paste into a web UI |
| **/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 |
@@ -42,9 +43,10 @@ cog.out(get_help_md())
| **/map-refresh** | Force a refresh of the repository map |
| **/model** | Switch to a new LLM |
| **/models** | Search the list of available models |
| **/multiline-mode** | Toggle multiline mode (swaps behavior of Enter and Meta+Enter) |
| **/paste** | Paste image/text from the clipboard into the chat. Optionally provide a name for the image. |
| **/quit** | Exit the application |
| **/read-only** | Add files to the chat that are for reference, not to be edited |
| **/read-only** | Add files to the chat that are for reference only, or turn added files to read-only |
| **/report** | Report a problem by opening a GitHub Issue |
| **/reset** | Drop all files and clear the chat history |
| **/run** | Run a shell command and optionally add the output to the chat (alias: !) |
@@ -77,8 +79,10 @@ The interactive prompt is built with [prompt-toolkit](https://github.com/prompt-
### Emacs
- `Up Arrow` : Scroll back through previously sent messages.
- `Down Arrow` : Scroll forward through previously sent messages.
- `Up Arrow` : Move up one line in the current message.
- `Down Arrow` : Move down one line in the current message.
- `Ctrl-Up` : Scroll back through previously sent messages.
- `Ctrl-Down` : Scroll forward through previously sent messages.
- `Ctrl-A` : Move cursor to the start of the line.
- `Ctrl-B` : Move cursor back one character.
- `Ctrl-D` : Delete the character under the cursor.
@@ -95,8 +99,10 @@ The interactive prompt is built with [prompt-toolkit](https://github.com/prompt-
To use vi/vim keybindings, run aider with the `--vim` switch.
- `Up Arrow` : Scroll back through previously sent messages.
- `Down Arrow` : Scroll forward through previously sent messages.
- `Up Arrow` : Move up one line in the current message.
- `Down Arrow` : Move down one line in the current message.
- `Ctrl-Up` : Scroll back through previously sent messages.
- `Ctrl-Down` : Scroll forward through previously sent messages.
- `Esc` : Switch to command mode.
- `i` : Switch to insert mode.
- `a` : Move cursor one character to the right and switch to insert mode.

View File

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

View File

@@ -0,0 +1,121 @@
---
title: Copy/paste with web chat
#highlight_image: /assets/browser.jpg
parent: Usage
nav_order: 850
description: Aider works with LLM web chat UIs
---
# Copy/paste with web chat
<div class="video-container">
<video controls loop poster="/assets/copypaste.jpg">
<source src="/assets/copypaste.mp4" type="video/mp4">
<a href="/assets/copypaste.mp4">Aider browser UI demo video</a>
</video>
</div>
<style>
.video-container {
position: relative;
padding-bottom: 66.34%; /* 2160 / 3256 = 0.6634 */
height: 0;
overflow: hidden;
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
## Working with an LLM web chat
[Aider can connect to most LLMs via API](https://aider.chat/docs/llms.html) and works best that way.
But there are times when you may want to work with an LLM via its web chat interface:
- Workplace policies may limit your LLM usage to a proprietary web chat system.
- The web chat LLM may have access to unique context or may have been specially fine tuned for your task.
- It may be cost prohibitive to use some models via API.
- There may not be an API available.
Aider has features for working with an LLM via its web chat interface.
This allows you to use the web chat LLM as the "big brain code architect"
while running aider with a smaller, cheaper LLM to actually make changes
to your local files.
For this "file editor" part of the process
you can run aider with many open source, free or very inexpensive LLMs.
For example, the demo video above shows aider using DeepSeek to apply the changes
that o1-preview is suggesting in the web chat.
### Copy aider's code context to your clipboard, paste into the web UI
The `/copy-context <instructions>` command can be used in chat to copy aider's code context to your clipboard.
It will include:
- All the files which have been added to the chat via `/add`.
- Any read only files which have been added via `/read`.
- Aider's [repository map](https://aider.chat/docs/repomap.html) that brings in code context related to the above files from elsewhere in your git repo.
- Some instructions to the LLM that ask it to output change instructions concisely.
- If you include `<instructions>`, they will be copied too.
You can paste the context into your browser, and start interacting with the LLM web chat to
ask for code changes.
### Paste the LLM's reply back into aider to edit your files
Once the LLM has replied, you can use the "copy response" button in the web UI to copy
the LLM's response.
Back in aider, you can run `/paste` and aider will edit your files
to implement the changes suggested by the LLM.
You can use a cheap, efficient model like GPT-4o Mini, DeepSeek or Qwen to do these edits.
This works best if you run aider with `--edit-format editor-diff` or `--edit-format editor-whole`.
### Copy/paste mode
Aider has a `--copy-paste` mode that streamlines this entire process:
- Whenever you `/add` or `/read` files, aider will automatically copy the entire, updated
code context to your clipboard.
You'll see "Copied code context to clipboard" whenever this happens.
- When you copy the LLM reply to your clipboard outside aider, aider will automatically notice
and load it into the aider chat.
Just press ENTER to send the message
and aider will apply the LLMs changes to your local files.
- Aider will automatically select the best edit format for this copy/paste functionality.
Depending on the LLM you have aider use, it will be either `editor-whole` or `editor-diff`.
## Terms of service
Be sure to review the Terms Of Service of any LLM web chat service you use with
these features.
These features are not intended to be used in violation of any service's Terms Of Service (TOS).
Aider's web chat features have been designed to be compliant with the
terms of service of most LLM web chats.
There are 4 copy/paste steps involved when coding with an LLM web chat:
1. Copy code and context from aider.
2. Paste the code and context into the LLM web chat.
3. Copy the reply from the LLM web chat.
4. Paste the LLM reply into aider.
Most LLM web chat TOS prohibit automating steps (2) and (3) where code
is copied from and pasted into the web chat.
Aider's `--copy-paste` mode leaves those as 100% manual steps for the user to complete.
It simply streamlines steps (1) and (4) that are interactions with aider,
and which should not be under the scope of an LLM web chat TOS.
If you are concerned that
the automatic interactions with aider in steps (1) and (4) may be problematic with respect to
your LLM web chat provider's TOS, you can forego `--copy-paste` mode.
Instead, manually use the `/copy-context` and `/paste` commands if that
will keep you in compliance.
Again, do not use these features in violation of any service's Terms Of Service.

View File

@@ -0,0 +1,295 @@
---
title: Aider in your IDE
#highlight_image: /assets/browser.jpg
parent: Usage
nav_order: 750
description: Aider can run in your browser, not just on the command line.
---
# Aider in your IDE
<div class="video-container">
<video controls loop poster="/assets/watch.jpg">
<source src="/assets/watch.mp4" type="video/mp4">
<a href="/assets/watch.mp4">Aider browser UI demo video</a>
</video>
</div>
<style>
.video-container {
position: relative;
padding-bottom: 102.7%; /1.027 */
height: 0;
overflow: hidden;
}
.video-container video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
## AI comments
If you run aider with `--watch-files`, it will watch all files in your repo
and look for any AI coding instructions you add using your favorite IDE or text editor.
Specifically, aider looks for one-liner comments (# ... or // ...) that either start or end with `AI`, `AI!` or `AI?1 like these:
```python
# Make a snake game. AI!
# What is the purpose of this method AI?
```
Or in `//` comment languages...
```js
// Write a protein folding prediction engine. AI!
```
Aider will take note of all the comments that start or end with `AI`.
Comments that include `AI!` with an exclamation point or `AI?` with a question
mark are special.
They triggers aider to take action to collect *all* the AI comments and use them
as your instructions.
- `AI!` triggers aider to make changes to your code.
- `AI?` triggers aider to answer your question.
See the demo video above that shows aider working with AI comments in VSCode.
## Example
For example, if you included this AI comment in your code:
```js
function factorial(n) // Implement this. AI!
```
Then aider would update the file and implement the function:
```js
function factorial(n) {
if (n === 0 || n === 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
```
## Comment styles
Aider only watches for these types of **one-liner** comments:
```
# Python and bash style
// Javascript style
-- SQL style
```
Aider will look for those comment types in all files.
You can use them into any code file you're editing, even if they aren't the
correct comment syntax for that language.
## Multiple uses
This capability is quite flexible and powerful, and can be used in many ways.
### In-context instructions
You can add an AI comment in the function you want changed,
explaining the change request in-context right where you want the changes.
```javascript
app.get('/sqrt/:n', (req, res) => {
const n = parseFloat(req.params.n);
// Add error handling for NaN and less than zero. AI!
const result = math.sqrt(n);
res.json({ result: result });
});
```
### Multiple comments
You can add multiple `AI` comments without the `!`,
before triggering aider with a final `AI!`.
Also keep in mind that you can spread the AI comments across
multiple files, if you want to coordinate changes in multiple places.
Just use `AI!` last, to trigger aider.
```python
@app.route('/factorial/<int:n>')
def factorial(n):
if n < 0:
return jsonify(error="Factorial is not defined for negative numbers"), 400
# AI: Refactor this code...
result = 1
for i in range(1, n + 1):
result *= i
# ... into to a compute_factorial() function. AI!
return jsonify(result=result)
```
### Long form instructions
You can add a block of comments, with longer instructions.
Just be sure to start or end one of the lines with `AI` or `AI!` to draw
aider's attention to the block.
```python
# Make these changes: AI!
# - Add a proper main() function
# - Use Click to process cmd line args
# - Accept --host and --port args
# - Print a welcome message that includes the listening url
if __name__ == "__main__":
app.run(debug=True)
```
### Add a file to the aider chat
Rather than using `/add` to add a file inside the aider chat, you can
simply put an `#AI` comment in it and save the file.
You can undo/remove the comment immediately if you like, the file
will still be added to the aider chat.
## Also use aider chat in the terminal
It can be really helpful to get a change started with AI comments.
But sometimes you want to build on or refine those changes.
You can of course continue to do that with AI comments,
but it can sometimes be effective to switch over to the aider terminal chat.
The chat has the history of the AI comments you just made,
so you can continue on naturally from there.
You can also use the normal aider chat in your terminal to work with
many of aider's more advanced features:
- Use `/undo` to revert changes you don't like. Although you may also be able to use your IDE's undo function to step back in the file history.
- Use [chat modes](https://aider.chat/docs/usage/modes.html) to ask questions or get help.
- Manage the chat context with `/tokens`, `/clear`, `/drop`, `/reset`.
Adding an AI comment will add the file to the chat.
Periodically, you may want remove extra context that is no longer needed.
- [Fix lint and test errors](https://aider.chat/docs/usage/lint-test.html).
- Run shell commands.
- Etc.
## You can be lazy
The examples above all show AI
comments with full sentences, proper capitalization, punctuation, etc.
This was done to help explain how AI comments work, but is not needed in practice.
Most LLMs are perfectly capable of dealing with ambiguity and
inferring implied intent.
This often allows you to be quite lazy with your AI comments.
In particular, you can start and end comments with lowercase `ai` and `ai!`,
but you can also be much more terse with the request itself.
Below are simpler versions of some of the examples given above.
When the context clearly implies the needed action, `ai!` might be all you
need. For example, to implement a factorial function
in a program full of other math functions either of these
approaches would probably work:
```js
function factorial(n) // ai!
```
Or...
```js
// add factorial() ai!
```
Rather than a long, explicit comment like "Add error handling for NaN and less than zero,"
you can let aider infer more about the request.
This simpler comment may be sufficient:
```javascript
app.get('/sqrt/:n', (req, res) => {
const n = parseFloat(req.params.n);
// add error handling ai!
const result = math.sqrt(n);
res.json({ result: result });
});
```
Similarly, this refactor probably could have been requested with fewer words, like this:
```python
@app.route('/factorial/<int:n>')
def factorial(n):
if n < 0:
return jsonify(error="Factorial is not defined for negative numbers"), 400
# ai refactor...
result = 1
for i in range(1, n + 1):
result *= i
# ... to compute_factorial() ai!
return jsonify(result=result)
```
As you use aider with your chosen LLM, you can develop a sense for how
explicit you need to make your AI comments.
## Behind the scenes
Aider sends your AI comments to the LLM with the
[repo map](https://aider.chat/docs/repomap.html)
and all the other code context you've added to the chat.
It also pulls out and highlights the AI comments with specific context, showing the LLM
exactly how they fit into the code base.
```
The "AI" comments below marked with █ can be found in the code files I've shared with you.
They contain your instructions.
Make the requested changes.
Be sure to remove all these "AI" comments from the code!
todo_app.py:
⋮...
│class TodoList:
⋮...
│ def __init__(self):
│ """Initialize an empty todo list"""
⋮...
│ def list_tasks(self):
│ """Display all tasks"""
█ # Implement this. AI!
│def main():
│ todo = TodoList()
⋮...
```
--------
#### Credits
*This feature was inspired by
the way [Override](https://github.com/oi-overide) watches for file changes
to find prompts embedded within `//> a specific set of delimiters <//`.*

View File

@@ -72,7 +72,7 @@ cog.out(open("aider/website/_includes/get-started.md").read())
You can get started quickly like this:
```
```bash
python -m pip install -U aider-chat
# Change directory into a git repo

View File

@@ -24,8 +24,8 @@ from dotenv import load_dotenv
from plots import plot_refactoring
from rich.console import Console
from aider import models
from aider.coders import Coder
from aider import models, sendchat
from aider.coders import Coder, base_coder
from aider.dump import dump # noqa: F401
from aider.io import InputOutput
@@ -47,10 +47,44 @@ def find_latest_benchmark_dir():
print("Error: No benchmark directories found under tmp.benchmarks.")
sys.exit(1)
latest_dir = max(
benchmark_dirs,
key=lambda d: next((f.stat().st_mtime for f in d.rglob("*.md") if f.is_file()), 0),
)
# Get current time and 24 hours ago
now = datetime.datetime.now()
day_ago = now - datetime.timedelta(days=1)
# Filter directories by name pattern YYYY-MM-DD-HH-MM-SS--
recent_dirs = []
for d in benchmark_dirs:
try:
# Extract datetime from directory name
date_str = d.name[:19] # Takes YYYY-MM-DD-HH-MM-SS
dir_date = datetime.datetime.strptime(date_str, "%Y-%m-%d-%H-%M-%S")
if dir_date >= day_ago:
recent_dirs.append(d)
except ValueError:
# Skip directories that don't match the expected format
continue
if not recent_dirs:
print("Error: No benchmark directories found from the last 24 hours.")
sys.exit(1)
# Find directory with most recently modified .md file
latest_dir = None
latest_time = 0
for d in recent_dirs:
# Look for .md files in subdirectories
for md_file in d.glob("*/.*.md"):
if md_file.is_file():
mtime = md_file.stat().st_mtime
if mtime > latest_time:
latest_time = mtime
latest_dir = d
if not latest_dir:
print("Error: No .md files found in recent benchmark directories.")
sys.exit(1)
print(f"Using the most recently updated benchmark directory: {latest_dir.name}")
return latest_dir
@@ -124,6 +158,9 @@ def main(
dirnames: Optional[List[str]] = typer.Argument(None, help="Directory names"),
graphs: bool = typer.Option(False, "--graphs", help="Generate graphs"),
model: str = typer.Option("gpt-3.5-turbo", "--model", "-m", help="Model name"),
sleep: float = typer.Option(
0, "--sleep", help="Sleep seconds between tests when single threaded"
),
edit_format: str = typer.Option(None, "--edit-format", "-e", help="Edit format"),
editor_model: str = typer.Option(None, "--editor-model", help="Editor model name"),
editor_edit_format: str = typer.Option(None, "--editor-edit-format", help="Editor edit format"),
@@ -233,6 +270,11 @@ def main(
if num_tests > 0:
test_dnames = test_dnames[:num_tests]
# Don't give up when benchmarking
LONG_TIMEOUT = 24 * 60 * 60
sendchat.RETRY_TIMEOUT = LONG_TIMEOUT
base_coder.RETRY_TIMEOUT = LONG_TIMEOUT
if threads == 1:
all_results = []
for testname in test_dnames:
@@ -251,10 +293,13 @@ def main(
editor_model,
editor_edit_format,
num_ctx,
sleep,
)
all_results.append(results)
summarize_results(dirname)
if sleep:
time.sleep(sleep)
else:
run_test_threaded = lox.thread(threads)(run_test)
for testname in test_dnames:
@@ -531,6 +576,7 @@ def run_test_real(
editor_model,
editor_edit_format,
num_ctx=None,
sleep=0,
):
if not os.path.isdir(testdir):
print("Not a dir:", testdir)

View File

@@ -67,7 +67,7 @@ requires = ["setuptools>=68", "setuptools_scm[toml]>=8"]
build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
write_to = "aider/__version__.py"
write_to = "aider/_version.py"
[tool.codespell]
skip = "*.svg,Gemfile.lock"

View File

@@ -6,5 +6,7 @@ testpaths =
tests/help
tests/browser
tests/scrape
env =
AIDER_ANALYTICS=false

View File

@@ -2,20 +2,21 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --output-file=requirements.txt requirements/requirements.in
# pip-compile --allow-unsafe --output-file=requirements.txt requirements/requirements.in
#
aiohappyeyeballs==2.4.3
aiohappyeyeballs==2.4.4
# via aiohttp
aiohttp==3.11.7
aiohttp==3.11.10
# via litellm
aiosignal==1.3.1
# via aiohttp
annotated-types==0.7.0
# via pydantic
anyio==4.6.2.post1
anyio==4.7.0
# via
# httpx
# openai
# watchfiles
attrs==24.2.0
# via
# aiohttp
@@ -62,15 +63,17 @@ gitdb==4.0.11
# via gitpython
gitpython==3.1.43
# via -r requirements/requirements.in
grep-ast==0.4.0
grep-ast==0.4.1
# via -r requirements/requirements.in
h11==0.14.0
# via httpcore
httpcore==1.0.7
# via httpx
httpx==0.27.2
# via openai
huggingface-hub==0.26.2
# via
# litellm
# openai
huggingface-hub==0.26.5
# via tokenizers
idna==3.10
# via
@@ -86,9 +89,9 @@ importlib-resources==6.4.5
# via -r requirements/requirements.in
jinja2==3.1.4
# via litellm
jiter==0.7.1
jiter==0.8.0
# via openai
json5==0.9.28
json5==0.10.0
# via -r requirements/requirements.in
jsonschema==4.23.0
# via
@@ -96,7 +99,7 @@ jsonschema==4.23.0
# litellm
jsonschema-specifications==2024.10.1
# via jsonschema
litellm==1.52.16
litellm==1.53.9
# via -r requirements/requirements.in
markdown-it-py==3.0.0
# via rich
@@ -120,7 +123,7 @@ numpy==1.26.4
# via
# -r requirements/requirements.in
# scipy
openai==1.55.1
openai==1.57.0
# via litellm
packaging==24.2
# via
@@ -134,11 +137,11 @@ pexpect==4.9.0
# via -r requirements/requirements.in
pillow==10.4.0
# via -r requirements/requirements.in
posthog==3.7.3
posthog==3.7.4
# via -r requirements/requirements.in
prompt-toolkit==3.0.48
# via -r requirements/requirements.in
propcache==0.2.0
propcache==0.2.1
# via
# aiohttp
# yarl
@@ -150,7 +153,7 @@ pycodestyle==2.12.1
# via flake8
pycparser==2.22
# via cffi
pydantic==2.10.2
pydantic==2.10.3
# via
# litellm
# openai
@@ -189,13 +192,13 @@ requests==2.32.3
# tiktoken
rich==13.9.4
# via -r requirements/requirements.in
rpds-py==0.21.0
rpds-py==0.22.3
# via
# jsonschema
# referencing
scipy==1.13.1
# via -r requirements/requirements.in
six==1.16.0
six==1.17.0
# via
# mixpanel
# posthog
@@ -231,6 +234,7 @@ tree-sitter-languages==1.10.2
# via grep-ast
typing-extensions==4.12.2
# via
# anyio
# huggingface-hub
# openai
# pydantic
@@ -239,9 +243,15 @@ urllib3==2.2.3
# via
# mixpanel
# requests
watchfiles==1.0.0
# via -r requirements/requirements.in
wcwidth==0.2.13
# via prompt-toolkit
yarl==1.18.0
yarl==1.18.3
# via aiohttp
zipp==3.21.0
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
pip==24.3.1
# via -r requirements/requirements.in

View File

@@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# 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
# pip-compile --allow-unsafe --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.5.0
# via streamlit
@@ -92,7 +92,7 @@ mdurl==0.1.2
# -c requirements.txt
# -c requirements/requirements-dev.txt
# markdown-it-py
narwhals==1.14.2
narwhals==1.16.0
# via altair
numpy==1.26.4
# via
@@ -122,7 +122,7 @@ pillow==10.4.0
# -c requirements/requirements-dev.txt
# -c requirements/requirements-help.txt
# streamlit
protobuf==5.28.3
protobuf==5.29.1
# via streamlit
pyarrow==18.1.0
# via streamlit
@@ -163,13 +163,13 @@ rich==13.9.4
# -c requirements.txt
# -c requirements/requirements-dev.txt
# streamlit
rpds-py==0.21.0
rpds-py==0.22.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# jsonschema
# referencing
six==1.16.0
six==1.17.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt

View File

@@ -3,6 +3,7 @@
# pip-compile --output-file=requirements-dev.txt requirements-dev.in --upgrade
#
pytest
pytest-env
pip-tools
lox
matplotlib

View File

@@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --constraint=requirements.txt --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in
# pip-compile --allow-unsafe --constraint=requirements.txt --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in
#
alabaster==1.0.0
# via sphinx
@@ -51,7 +51,7 @@ filelock==3.16.1
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# virtualenv
fonttools==4.55.0
fonttools==4.55.2
# via matplotlib
identify==2.6.3
# via pre-commit
@@ -85,7 +85,7 @@ markupsafe==3.0.2
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# jinja2
matplotlib==3.9.2
matplotlib==3.9.3
# via -r requirements/requirements-dev.in
mdurl==0.1.2
# via
@@ -144,7 +144,11 @@ pyproject-hooks==1.2.0
# via
# build
# pip-tools
pytest==8.3.3
pytest==8.3.4
# via
# -r requirements/requirements-dev.in
# pytest-env
pytest-env==1.1.5
# via -r requirements/requirements-dev.in
python-dateutil==2.9.0.post0
# via
@@ -173,7 +177,7 @@ semver==3.0.2
# via -r requirements/requirements-dev.in
shellingham==1.5.4
# via typer
six==1.16.0
six==1.17.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
@@ -200,7 +204,7 @@ sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
typer==0.13.1
typer==0.15.1
# via -r requirements/requirements-dev.in
typing-extensions==4.12.2
# via
@@ -220,5 +224,10 @@ wheel==0.45.1
# via pip-tools
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools
pip==24.3.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# pip-tools
setuptools==75.6.0
# via pip-tools

View File

@@ -2,14 +2,14 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --output-file=requirements/requirements-help.txt requirements/requirements-help.in
# pip-compile --allow-unsafe --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --output-file=requirements/requirements-help.txt requirements/requirements-help.in
#
aiohappyeyeballs==2.4.3
aiohappyeyeballs==2.4.4
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# aiohttp
aiohttp==3.11.7
aiohttp==3.11.10
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
@@ -25,7 +25,7 @@ annotated-types==0.7.0
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# pydantic
anyio==4.6.2.post1
anyio==4.7.0
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
@@ -103,7 +103,7 @@ httpx==0.27.2
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# llama-index-core
huggingface-hub[inference]==0.26.2
huggingface-hub[inference]==0.26.5
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
@@ -188,13 +188,13 @@ pillow==10.4.0
# -c requirements/requirements-dev.txt
# llama-index-core
# sentence-transformers
propcache==0.2.0
propcache==0.2.1
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# aiohttp
# yarl
pydantic==2.10.2
pydantic==2.10.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
@@ -284,6 +284,7 @@ typing-extensions==4.12.2
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt
# -c requirements/requirements-dev.txt
# anyio
# huggingface-hub
# llama-index-core
# pydantic
@@ -305,7 +306,7 @@ wrapt==1.17.0
# via
# deprecated
# llama-index-core
yarl==1.18.0
yarl==1.18.3
# via
# -c /Users/gauthier/Projects/aider/requirements.txt
# -c requirements.txt

View File

@@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --constraint=requirements.txt --constraint=requirements/requirements-browser.txt --constraint=requirements/requirements-dev.txt --constraint=requirements/requirements-help.txt --output-file=requirements/requirements-playwright.txt requirements/requirements-playwright.in
# pip-compile --allow-unsafe --constraint=requirements.txt --constraint=requirements/requirements-browser.txt --constraint=requirements/requirements-dev.txt --constraint=requirements/requirements-help.txt --output-file=requirements/requirements-playwright.txt requirements/requirements-playwright.in
#
greenlet==3.0.3
# via

View File

@@ -28,6 +28,8 @@ mixpanel
pexpect
json5
psutil
watchfiles
pip
# The proper dependency is networkx[default], but this brings
# in matplotlib and a bunch of other deps

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import argparse
import os
import subprocess
import sys
from collections import defaultdict
@@ -11,6 +12,12 @@ import semver
import yaml
from tqdm import tqdm
website_files = [
"aider/website/share/index.md",
"aider/website/_includes/head_custom.html",
"aider/website/docs/leaderboards/index.md",
]
def blame(start_tag, end_tag=None):
commits = get_all_commit_hashes_between_tags(start_tag, end_tag)
@@ -25,10 +32,10 @@ def blame(start_tag, end_tag=None):
for f in files
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"
or f in website_files
]
files = [f for f in files if not f.endswith("prompts.py")]
files = [f for f in files if not f.startswith("tests/fixtures/watch")]
all_file_counts = {}
grand_total = defaultdict(int)
@@ -143,8 +150,31 @@ def main():
return
if args.all_since:
results = process_all_tags_since(args.start_tag)
yaml_output = yaml.dump(results, sort_keys=True)
new_results = process_all_tags_since(args.start_tag)
# If output file exists, read and update it
existing_results = []
if args.output and os.path.exists(args.output):
with open(args.output, "r") as f:
existing_results = yaml.safe_load(f) or []
# Create a map of start_tag->end_tag to result for existing entries
existing_map = {(r["start_tag"], r["end_tag"]): i for i, r in enumerate(existing_results)}
# Update or append new results
for new_result in new_results:
key = (new_result["start_tag"], new_result["end_tag"])
if key in existing_map:
# Replace existing entry
existing_results[existing_map[key]] = new_result
else:
# Append new entry
existing_results.append(new_result)
# Sort results by start_tag
existing_results.sort(key=lambda x: semver.Version.parse(x["start_tag"][1:]))
yaml_output = yaml.dump(existing_results, sort_keys=True)
else:
all_file_counts, grand_total, total_lines, aider_total, aider_percentage, end_date = blame(
args.start_tag, args.end_tag
@@ -179,9 +209,23 @@ def main():
def get_counts_for_file(start_tag, end_tag, authors, fname):
try:
if end_tag:
text = run(["git", "blame", f"{start_tag}..{end_tag}", "--", fname])
text = run(
[
"git",
"blame",
"-M",
"-C",
"-C",
"--abbrev=9",
f"{start_tag}..{end_tag}",
"--",
fname,
]
)
else:
text = run(["git", "blame", f"{start_tag}..HEAD", "--", fname])
text = run(
["git", "blame", "-M", "-C", "-C", "--abbrev=9", f"{start_tag}..HEAD", "--", fname]
)
if not text:
return None
text = text.splitlines()

View File

@@ -0,0 +1,16 @@
history_prompt = """
Update the history with changes shown in the diffs.
Describe actual user-facing changes, not every single commit that was made implementing them.
Only add new items not already listed.
Do NOT edit or update existing history entries.
Do NOT add duplicate entries for changes that have existing history entries.
End each bullet with a period.
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

View File

@@ -22,7 +22,9 @@ def has_been_reopened(issue_number):
# Load environment variables from .env file
load_dotenv()
BOT_SUFFIX = """Note: A [bot script](https://github.com/Aider-AI/aider/blob/main/scripts/issues.py) made these updates to the 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 = (
@@ -44,6 +46,20 @@ CLOSE_STALE_COMMENT = (
+ BOT_SUFFIX
)
CLOSE_FIXED_ENHANCEMENT_COMMENT = (
"""I'm closing this enhancement request since it has been marked as 'fixed' for over """
"""3 weeks. The requested feature should now be available in recent versions of aider.\n\n"""
"""If you find that this enhancement is still needed, please feel free to reopen this """
"""issue or create a new one.""" + BOT_SUFFIX
)
CLOSE_FIXED_BUG_COMMENT = (
"""I'm closing this bug report since it has been marked as 'fixed' for over """
"""3 weeks. This issue should be resolved in recent versions of aider.\n\n"""
"""If you find that this bug is still present, please feel free to reopen this """
"""issue or create a new one with steps to reproduce.""" + BOT_SUFFIX
)
# GitHub API configuration
GITHUB_API_URL = "https://api.github.com"
REPO_OWNER = "Aider-AI"
@@ -304,6 +320,68 @@ def handle_stale_closing(all_issues, auto_yes):
print(f" Closed issue #{issue['number']}")
def handle_fixed_issues(all_issues, auto_yes):
print("\nChecking for fixed enhancement and bug issues to close...")
for issue in all_issues:
# Skip if not open or doesn't have fixed label
labels = [label["name"] for label in issue["labels"]]
if issue["state"] != "open" or "fixed" not in labels:
continue
# Check if it's an enhancement or bug
is_enhancement = "enhancement" in labels
is_bug = "bug" in labels
if not (is_enhancement or is_bug):
continue
# Find when the fixed label was added
timeline_url = (
f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/timeline"
)
response = requests.get(timeline_url, headers=headers)
response.raise_for_status()
events = response.json()
# Find the most recent fixed label addition
fixed_events = [
event
for event in events
if event.get("event") == "labeled" and event.get("label", {}).get("name") == "fixed"
]
if not fixed_events:
continue
latest_fixed = datetime.strptime(fixed_events[-1]["created_at"], "%Y-%m-%dT%H:%M:%SZ")
days_fixed = (datetime.now() - latest_fixed).days
if days_fixed >= 21:
issue_type = "enhancement" if is_enhancement else "bug"
print(f"\nFixed {issue_type} ready for closing #{issue['number']}: {issue['title']}")
print(f" Has been marked fixed for {days_fixed} days")
if not auto_yes:
confirm = input("Close this issue? (y/n): ")
if confirm.lower() != "y":
print("Skipping this issue.")
continue
# Add closing comment
comment_url = (
f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/comments"
)
comment = CLOSE_FIXED_ENHANCEMENT_COMMENT if is_enhancement else CLOSE_FIXED_BUG_COMMENT
response = requests.post(comment_url, headers=headers, json={"body": comment})
response.raise_for_status()
# Close the issue
url = f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}"
response = requests.patch(url, headers=headers, json={"state": "closed"})
response.raise_for_status()
print(f" Closed issue #{issue['number']}")
def handle_duplicate_issues(all_issues, auto_yes):
open_issues = [issue for issue in all_issues if issue["state"] == "open"]
grouped_open_issues = group_issues_by_subject(open_issues)
@@ -361,6 +439,7 @@ def main():
handle_stale_issues(all_issues, args.yes)
handle_stale_closing(all_issues, args.yes)
handle_duplicate_issues(all_issues, args.yes)
handle_fixed_issues(all_issues, args.yes)
if __name__ == "__main__":

View File

@@ -5,6 +5,7 @@ set -e
# First compile the base requirements
pip-compile \
--allow-unsafe \
requirements/requirements.in \
--output-file=requirements.txt \
$1
@@ -15,6 +16,7 @@ CONSTRAINTS="--constraint=requirements.txt"
for SUFFIX in "${SUFFIXES[@]}"; do
pip-compile \
--allow-unsafe \
requirements/requirements-${SUFFIX}.in \
--output-file=requirements/requirements-${SUFFIX}.txt \
${CONSTRAINTS} \

View File

@@ -5,6 +5,8 @@ import re
import subprocess
import tempfile
from history_prompts import history_prompt
from aider import __version__
@@ -37,35 +39,79 @@ 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
# Extract relevant portion of HISTORY.md
base_ver = get_base_version()
with open("HISTORY.md", "r") as f:
history_content = f.read()
# Find the section for this version
version_header = f"### Aider v{base_ver}"
start_idx = history_content.find("# Release history")
if start_idx == -1:
raise ValueError("Could not find start of release history")
# Find where this version's section ends
version_idx = history_content.find(version_header, start_idx)
if version_idx == -1:
raise ValueError(f"Could not find version header: {version_header}")
# Find the next version header after this one
next_version_idx = history_content.find("\n### Aider v", version_idx + len(version_header))
if next_version_idx == -1:
# No next version found, use the rest of the file
relevant_history = history_content[start_idx:]
else:
# Extract just up to the next version
relevant_history = history_content[start_idx:next_version_idx]
# Save relevant portions to temporary files
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".diff") as tmp_diff:
tmp_diff.write(diff_content)
diff_path = tmp_diff.name
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".md") as tmp_hist:
tmp_hist.write(relevant_history)
hist_path = tmp_hist.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
message = history_prompt.format(aider_line=aider_line)
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"]
cmd = ["aider", hist_path, "--read", diff_path, "--msg", message, "--no-auto-commit"]
subprocess.run(cmd)
# Read back the updated history
with open(hist_path, "r") as f:
updated_history = f.read()
# Find where the next version section would start
if next_version_idx == -1:
# No next version found, use the rest of the file
full_history = history_content[:start_idx] + updated_history
else:
# Splice the updated portion back in between the unchanged parts
full_history = (
history_content[:start_idx]
+ updated_history # Keep unchanged header
+ history_content[next_version_idx:] # Add updated portion # Keep older entries
)
# Write back the full history
with open("HISTORY.md", "w") as f:
f.write(full_history)
# Run update-docs.sh after aider
subprocess.run(["scripts/update-docs.sh"])
# Cleanup
os.unlink(tmp_path)
os.unlink(diff_path)
os.unlink(hist_path)
# Show git diff of HISTORY.md
subprocess.run(["git", "diff", "HISTORY.md"])
if __name__ == "__main__":

View File

@@ -154,8 +154,8 @@ def main():
if not dry_run:
subprocess.run(cmd, check=True)
# Remove aider/__version__.py if it exists
version_file = "aider/__version__.py"
# Remove aider/_version.py if it exists
version_file = "aider/_version.py"
if os.path.exists(version_file):
print(f"Removing {version_file}")
if not dry_run:

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