mirror of
https://github.com/Aider-AI/aider
synced 2026-04-26 01:25:17 +02:00
Compare commits
1031 Commits
v0.66.1.de
...
v0.71.2.de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac26fc6d5f | ||
|
|
122088712d | ||
|
|
9fb09ce14d | ||
|
|
392fb21946 | ||
|
|
e94b05851f | ||
|
|
571a5962b7 | ||
|
|
8b6863dc40 | ||
|
|
01af629399 | ||
|
|
4ece6d2a9b | ||
|
|
18d1d7af33 | ||
|
|
5ada250a66 | ||
|
|
308c7ab670 | ||
|
|
89d35e020a | ||
|
|
6729570799 | ||
|
|
f72f5f6438 | ||
|
|
a02e11e0bc | ||
|
|
9ff15e1506 | ||
|
|
fdddfc6b1f | ||
|
|
78ebb6295d | ||
|
|
73c89e8c00 | ||
|
|
fcc499e401 | ||
|
|
6e8efe22aa | ||
|
|
f9c5cb73a2 | ||
|
|
c939521f5f | ||
|
|
2640e05307 | ||
|
|
c1a371e3d3 | ||
|
|
5a4871155a | ||
|
|
d8e6dbf788 | ||
|
|
7ea69ae4b4 | ||
|
|
d238ead451 | ||
|
|
e6b449f24d | ||
|
|
41018d05a8 | ||
|
|
d48008e13d | ||
|
|
a9cf438100 | ||
|
|
6c7a0d21d2 | ||
|
|
d887db4c18 | ||
|
|
e6be69ec6d | ||
|
|
c1ba7db8a1 | ||
|
|
dc5b5896a9 | ||
|
|
38678fafc1 | ||
|
|
7611211d1c | ||
|
|
0d9c2cd902 | ||
|
|
1a84c109fc | ||
|
|
cbedf3f8cc | ||
|
|
50436e3106 | ||
|
|
62498ec867 | ||
|
|
91b94bb16c | ||
|
|
c2bbdc503c | ||
|
|
babae0fa6e | ||
|
|
f047882ac1 | ||
|
|
b818d6a921 | ||
|
|
ba631c8451 | ||
|
|
2c963b389c | ||
|
|
8437fbc314 | ||
|
|
76404004a4 | ||
|
|
1b64514c2c | ||
|
|
6efea7d365 | ||
|
|
e1a3b77d67 | ||
|
|
cfc7ad5627 | ||
|
|
b3cbf14ad6 | ||
|
|
51cfbe6b00 | ||
|
|
155f397d0b | ||
|
|
4b53b8b6a1 | ||
|
|
dbea4a1787 | ||
|
|
5b6da85e68 | ||
|
|
61671e9d3f | ||
|
|
f94e05e04e | ||
|
|
b5cad9a8cc | ||
|
|
3a97d8cc82 | ||
|
|
3c099465da | ||
|
|
fcdb2591b6 | ||
|
|
b67a16e9af | ||
|
|
1d672616be | ||
|
|
ed9d70903d | ||
|
|
8a9bab8a46 | ||
|
|
fdc6a08eb4 | ||
|
|
154309912d | ||
|
|
a84fea86b8 | ||
|
|
609998bc18 | ||
|
|
891868b061 | ||
|
|
3fc5cf8b9f | ||
|
|
6048ed5bc1 | ||
|
|
a1a007134c | ||
|
|
d82f9fa432 | ||
|
|
c0074301a3 | ||
|
|
9c2c05ad44 | ||
|
|
fad230c02e | ||
|
|
ad3c95f273 | ||
|
|
684fdb6095 | ||
|
|
8e64f171b8 | ||
|
|
d616c3fed7 | ||
|
|
e07e6cd2a3 | ||
|
|
f1bd5cdb52 | ||
|
|
be82b6bed9 | ||
|
|
37ad4758a1 | ||
|
|
e4a238a05c | ||
|
|
e5ca922ce8 | ||
|
|
6a1f4431d0 | ||
|
|
d67eda24d2 | ||
|
|
bba0cc8dc5 | ||
|
|
884b52b710 | ||
|
|
01ef2351b3 | ||
|
|
de1d566e9e | ||
|
|
19114a61ae | ||
|
|
36e5599ead | ||
|
|
f5a82e575c | ||
|
|
1851de323d | ||
|
|
f9408640a3 | ||
|
|
73837730fa | ||
|
|
9b46991721 | ||
|
|
606cd0368f | ||
|
|
d9ef23ad99 | ||
|
|
48b8f54c12 | ||
|
|
cec9f90c1c | ||
|
|
44d36f140a | ||
|
|
f88adcfa85 | ||
|
|
c5919f0c15 | ||
|
|
ac160cac12 | ||
|
|
867aaa5864 | ||
|
|
0b26505a20 | ||
|
|
98ad513621 | ||
|
|
591edbb003 | ||
|
|
a17b1c2ab7 | ||
|
|
648f14d95b | ||
|
|
2e4c2422b1 | ||
|
|
463fdb1ed9 | ||
|
|
d6b612a4a3 | ||
|
|
d24376608e | ||
|
|
ff41f9bd9a | ||
|
|
6d3dd5c484 | ||
|
|
f0bc8983b8 | ||
|
|
729354b038 | ||
|
|
c0be857f37 | ||
|
|
98b0e88ace | ||
|
|
3d501df21f | ||
|
|
1b4abb747d | ||
|
|
b1d418f7fb | ||
|
|
a702b4752b | ||
|
|
684ba7c0cb | ||
|
|
1bcc27d2be | ||
|
|
50d3b305d4 | ||
|
|
a341c98ec6 | ||
|
|
fa5c8a00e4 | ||
|
|
42f6c20ada | ||
|
|
787738094d | ||
|
|
a44ebfe99f | ||
|
|
c5959664e4 | ||
|
|
9b581268de | ||
|
|
acf654c984 | ||
|
|
94f83eb9e3 | ||
|
|
07c675ed06 | ||
|
|
f292e01980 | ||
|
|
61f9123147 | ||
|
|
60708a7fd7 | ||
|
|
761fb93aba | ||
|
|
20bc718bdc | ||
|
|
07337d2f41 | ||
|
|
3d2de00f49 | ||
|
|
a7242ca846 | ||
|
|
d3298ac5f2 | ||
|
|
e486243c06 | ||
|
|
8eaefb57d3 | ||
|
|
c21f7afdcb | ||
|
|
d734dee589 | ||
|
|
f035c4c01a | ||
|
|
8fcdcecf36 | ||
|
|
3f9ee1ac2e | ||
|
|
188e1f788d | ||
|
|
98a0f1cf5b | ||
|
|
1467a673b9 | ||
|
|
889eb86d89 | ||
|
|
125da0e2db | ||
|
|
14b274c707 | ||
|
|
dedbc20ac6 | ||
|
|
36cf2348d0 | ||
|
|
a19f8996b8 | ||
|
|
7293263773 | ||
|
|
ed5b07374d | ||
|
|
07b96bef95 | ||
|
|
5c3cca157d | ||
|
|
f1f66a9b9d | ||
|
|
f4007210c1 | ||
|
|
77962dbd4c | ||
|
|
419cbae55f | ||
|
|
5233789c40 | ||
|
|
70731719f7 | ||
|
|
cf4aa68f98 | ||
|
|
6bfd89074c | ||
|
|
acc4893a7f | ||
|
|
ab61ae2b36 | ||
|
|
514b9c1c7d | ||
|
|
44f2cf2b24 | ||
|
|
9befec5cd1 | ||
|
|
7efdfe5639 | ||
|
|
be6811b29a | ||
|
|
f160b8df04 | ||
|
|
158471b218 | ||
|
|
a383cece53 | ||
|
|
0901e6ab77 | ||
|
|
e1485971d8 | ||
|
|
91c9b1bfe7 | ||
|
|
befe6be86c | ||
|
|
79428cf4ed | ||
|
|
7bde5fe893 | ||
|
|
2f7e024387 | ||
|
|
9235cfa739 | ||
|
|
f1e623ec5a | ||
|
|
7c86dc9ac6 | ||
|
|
ec2da0a399 | ||
|
|
dd9b2a872c | ||
|
|
9767759033 | ||
|
|
7537d79311 | ||
|
|
b68f34eb9e | ||
|
|
0a23c4abd6 | ||
|
|
b51768b08e | ||
|
|
4561f0c79e | ||
|
|
5c92491bc0 | ||
|
|
083605e2d7 | ||
|
|
d28e2f0f56 | ||
|
|
87a964355b | ||
|
|
fbc3f0cef5 | ||
|
|
2b1625e3a8 | ||
|
|
6230df749e | ||
|
|
e62003c0ce | ||
|
|
d0f092f7ae | ||
|
|
9e2e07e8a7 | ||
|
|
4154d47c07 | ||
|
|
62e0cba7bd | ||
|
|
39d5c785d5 | ||
|
|
e5cb81c11f | ||
|
|
3abb8d38ec | ||
|
|
7f0860d5d0 | ||
|
|
8c74c8ab6f | ||
|
|
37df899ada | ||
|
|
f55181e447 | ||
|
|
b1bc2f8c5c | ||
|
|
350df7ca55 | ||
|
|
8768a8aca6 | ||
|
|
0f8bb016f4 | ||
|
|
eb30791ff4 | ||
|
|
7b37bf0f48 | ||
|
|
fff67a5917 | ||
|
|
3dbe91577c | ||
|
|
0e05b64ebc | ||
|
|
c895e99306 | ||
|
|
6d7e8beaaa | ||
|
|
8b62d8a6c5 | ||
|
|
ec44850646 | ||
|
|
2ea5a98ee0 | ||
|
|
80928b90a5 | ||
|
|
b28174aba1 | ||
|
|
da170bab3a | ||
|
|
49a2f998dd | ||
|
|
4efdc8b4f7 | ||
|
|
a75507980a | ||
|
|
8d0decc17a | ||
|
|
e334cbb5d4 | ||
|
|
e3ac8ab19d | ||
|
|
bddf6e9017 | ||
|
|
bcdc0217b3 | ||
|
|
521841b447 | ||
|
|
c53cd336f9 | ||
|
|
a8226989c8 | ||
|
|
114b156d74 | ||
|
|
def2d4bac9 | ||
|
|
250e2ab6aa | ||
|
|
6185ddf76a | ||
|
|
dddf192e5a | ||
|
|
2d32f77ed0 | ||
|
|
7eb7533d42 | ||
|
|
bb711fe255 | ||
|
|
14a8759b82 | ||
|
|
5a0d4eff71 | ||
|
|
805d6bbc8c | ||
|
|
a0004ab892 | ||
|
|
46a444dc21 | ||
|
|
aefb5c37fe | ||
|
|
2216978726 | ||
|
|
3a2d8edb53 | ||
|
|
e0d57b7713 | ||
|
|
3a9912c01e | ||
|
|
6cadee31bf | ||
|
|
678845dfda | ||
|
|
7f7e218504 | ||
|
|
256a9951f5 | ||
|
|
370b45bb35 | ||
|
|
616c4a9a53 | ||
|
|
821f7d6694 | ||
|
|
bc89be6187 | ||
|
|
86b6a4cefd | ||
|
|
1f9a53a454 | ||
|
|
f22d112da2 | ||
|
|
c36c06ab99 | ||
|
|
a915c60999 | ||
|
|
6ddb8a7d88 | ||
|
|
50bb2cb1e6 | ||
|
|
e1571dda9b | ||
|
|
7410c6216c | ||
|
|
8f84df44ab | ||
|
|
82f21b6734 | ||
|
|
892fd5a6ef | ||
|
|
3069db0cfd | ||
|
|
b71c9d539e | ||
|
|
78e643970d | ||
|
|
34da3dd3d7 | ||
|
|
817cb0d363 | ||
|
|
01088e214c | ||
|
|
3e4500f9fd | ||
|
|
d4b62608a9 | ||
|
|
e6bfc1c2fc | ||
|
|
051cabed69 | ||
|
|
04916a6e97 | ||
|
|
f3be2fa66b | ||
|
|
c36087cc0c | ||
|
|
e35909ac7d | ||
|
|
e5a693ab94 | ||
|
|
9e9cfb4600 | ||
|
|
5dddaac006 | ||
|
|
14af6f1fba | ||
|
|
e88064fdc9 | ||
|
|
6badf5ea1d | ||
|
|
20f5f3da24 | ||
|
|
8c1b147705 | ||
|
|
366155b828 | ||
|
|
2c7d1897eb | ||
|
|
26ccb23402 | ||
|
|
d9e2471fcd | ||
|
|
8302b351dd | ||
|
|
b8647c0481 | ||
|
|
a168403d68 | ||
|
|
42d8650058 | ||
|
|
7ad0d46c11 | ||
|
|
58812f7f1f | ||
|
|
65133b2aef | ||
|
|
291d8cd335 | ||
|
|
7a27e2b94b | ||
|
|
57a8eab1c3 | ||
|
|
236a7f68e9 | ||
|
|
81d424f475 | ||
|
|
687ba8c9a2 | ||
|
|
6d74a564e6 | ||
|
|
0a3e0665ab | ||
|
|
a19f1fbc67 | ||
|
|
2aa4615c78 | ||
|
|
7dd1346878 | ||
|
|
31f8c7d9cb | ||
|
|
914ce0b94d | ||
|
|
664f09111e | ||
|
|
6141f414fd | ||
|
|
8911f0f217 | ||
|
|
5af108ccee | ||
|
|
94e4169445 | ||
|
|
479b5b7064 | ||
|
|
674e935cf5 | ||
|
|
6b4982d75b | ||
|
|
4167743a34 | ||
|
|
ba289f6db4 | ||
|
|
422fd11f4d | ||
|
|
614d9c9b0d | ||
|
|
f91be86662 | ||
|
|
72f05544e8 | ||
|
|
81f55820be | ||
|
|
b9c14e1d65 | ||
|
|
5c55453a0e | ||
|
|
12491c4983 | ||
|
|
77d379c021 | ||
|
|
1a12a59e91 | ||
|
|
0b970dd9c7 | ||
|
|
93ac2bd53e | ||
|
|
f9646ac47a | ||
|
|
e8ed3b9e23 | ||
|
|
6238a07c8f | ||
|
|
1fb33f0c47 | ||
|
|
a842f41627 | ||
|
|
c4c135e678 | ||
|
|
f36f2fdea2 | ||
|
|
e3f0a67584 | ||
|
|
f6f05fa0c6 | ||
|
|
54ca7ceac8 | ||
|
|
cf5b38d4f5 | ||
|
|
b23669400f | ||
|
|
aaacd00ecf | ||
|
|
03aa22ba84 | ||
|
|
1493b8703f | ||
|
|
59308c20c6 | ||
|
|
cac5d8e716 | ||
|
|
7f16757bbe | ||
|
|
674e3846e2 | ||
|
|
3a0be0cca9 | ||
|
|
00d7c3a05a | ||
|
|
91f5fca5e9 | ||
|
|
1d7cb0c119 | ||
|
|
24599aa64f | ||
|
|
54c1553892 | ||
|
|
0ae53ce1a1 | ||
|
|
c69ffe02f8 | ||
|
|
7bfc2e0e74 | ||
|
|
9cc674c283 | ||
|
|
66e597a05c | ||
|
|
074c636e53 | ||
|
|
4ec44936f6 | ||
|
|
eb9c41f2a0 | ||
|
|
04afb99c54 | ||
|
|
2124e7b221 | ||
|
|
2416a8bf96 | ||
|
|
408a40f78b | ||
|
|
195ae5ce4b | ||
|
|
9bebb1e9a9 | ||
|
|
e7bec5be1d | ||
|
|
c708e8ba8e | ||
|
|
60f26cc067 | ||
|
|
64fa058bc7 | ||
|
|
9a770eeae9 | ||
|
|
ffc2c5a26e | ||
|
|
b6c5bd552e | ||
|
|
05147a3199 | ||
|
|
7f0d08ad77 | ||
|
|
64f95af833 | ||
|
|
7cd2662355 | ||
|
|
154d485c9e | ||
|
|
5f6821c7e2 | ||
|
|
59cf823d56 | ||
|
|
70312c58be | ||
|
|
4942366271 | ||
|
|
f237d0f212 | ||
|
|
9b424e0fe7 | ||
|
|
81b75d178b | ||
|
|
410e732eb3 | ||
|
|
2ca93cd93d | ||
|
|
50c806286e | ||
|
|
59de835b42 | ||
|
|
ecbac76cba | ||
|
|
9b16f2139d | ||
|
|
ef14df5ba2 | ||
|
|
b4be9875b2 | ||
|
|
8d0c962f42 | ||
|
|
5e0cb8d658 | ||
|
|
1869ab94fe | ||
|
|
2627c5baaf | ||
|
|
e4e16b8f77 | ||
|
|
85218d74d4 | ||
|
|
47d5b66986 | ||
|
|
ecfb133de2 | ||
|
|
23c95d24f1 | ||
|
|
b37d89bd08 | ||
|
|
5c848d59b2 | ||
|
|
b1c04dece9 | ||
|
|
b87c7987bb | ||
|
|
0bef52ae7d | ||
|
|
9ae04cf1ec | ||
|
|
0f7c4a8d4f | ||
|
|
07353207c0 | ||
|
|
d89be83414 | ||
|
|
01382527f5 | ||
|
|
dece2193fc | ||
|
|
d298f864fa | ||
|
|
ff37d8c691 | ||
|
|
f7f305a564 | ||
|
|
86f38e11cd | ||
|
|
0b60c48253 | ||
|
|
024b9840f0 | ||
|
|
2f4f59d82f | ||
|
|
830d5ee763 | ||
|
|
5bc63f7a33 | ||
|
|
b54f970e12 | ||
|
|
0cc8c54152 | ||
|
|
241e1e27d0 | ||
|
|
0145e86202 | ||
|
|
4d50e1e373 | ||
|
|
4b6ae34800 | ||
|
|
2feb85e831 | ||
|
|
a67ac81265 | ||
|
|
dab536c9e8 | ||
|
|
64cf298521 | ||
|
|
10b5aaa6a5 | ||
|
|
8c79e5ccfb | ||
|
|
2ef536a342 | ||
|
|
85b1303460 | ||
|
|
60aca3a241 | ||
|
|
db98381a86 | ||
|
|
f62ef34715 | ||
|
|
f95a6c1a5a | ||
|
|
65555b5dd0 | ||
|
|
9f6331a35e | ||
|
|
8c10cb6230 | ||
|
|
c8894bcead | ||
|
|
edc602c33a | ||
|
|
abfb2ca810 | ||
|
|
9967efe45a | ||
|
|
e77d80bda5 | ||
|
|
a691d1750a | ||
|
|
834e2f9304 | ||
|
|
66e5e9c1ce | ||
|
|
2d5f613984 | ||
|
|
868e7a278f | ||
|
|
f953d17889 | ||
|
|
3473969aae | ||
|
|
ec11ae7c40 | ||
|
|
8217ee1bbb | ||
|
|
1ad3ee0aec | ||
|
|
b3e9a2fede | ||
|
|
2f5d6bf909 | ||
|
|
cd79f479e9 | ||
|
|
12c0f675ce | ||
|
|
29471b8019 | ||
|
|
cad661f0c8 | ||
|
|
261d770482 | ||
|
|
a75c9c74fd | ||
|
|
8b5bdf9a16 | ||
|
|
e35eba2d51 | ||
|
|
df8c88cef4 | ||
|
|
844e12769c | ||
|
|
b982626ac4 | ||
|
|
517b2b42a6 | ||
|
|
6778c33628 | ||
|
|
bc0b11e1ef | ||
|
|
6b0d4b9c93 | ||
|
|
7d4e4f029e | ||
|
|
1fbdb629ff | ||
|
|
a437237947 | ||
|
|
910637c549 | ||
|
|
e8974a3e69 | ||
|
|
6c98310f7f | ||
|
|
72aed0d26d | ||
|
|
e10ef8b9e0 | ||
|
|
39fa8ba831 | ||
|
|
8ee8279044 | ||
|
|
c3f85c3bb2 | ||
|
|
ad59c4cbf3 | ||
|
|
26bc981981 | ||
|
|
514c34b242 | ||
|
|
6f266c0090 | ||
|
|
baa7352ca6 | ||
|
|
fdb1c8d99a | ||
|
|
79f5dba094 | ||
|
|
2134965f16 | ||
|
|
77b7a59a27 | ||
|
|
365e7126d0 | ||
|
|
d3daf9d159 | ||
|
|
8d59a519a6 | ||
|
|
239262f360 | ||
|
|
9eb938fd6f | ||
|
|
3fcbf1a43f | ||
|
|
2b7ee271df | ||
|
|
11512c6281 | ||
|
|
b16ba547ab | ||
|
|
e5b8899b4c | ||
|
|
fee3e9e63b | ||
|
|
57a24d30b5 | ||
|
|
5a83610fb1 | ||
|
|
96086f12c6 | ||
|
|
a6ee3ce07f | ||
|
|
5f36ddd425 | ||
|
|
bec67074e0 | ||
|
|
895c92cdae | ||
|
|
7406a5bc26 | ||
|
|
ef97714404 | ||
|
|
6d6daee511 | ||
|
|
32cd1c2a65 | ||
|
|
abad920a8a | ||
|
|
e1ab49e100 | ||
|
|
df300e89a2 | ||
|
|
9a278bed21 | ||
|
|
4a7fc084ce | ||
|
|
2649e736fb | ||
|
|
42ac891e28 | ||
|
|
4dc3b9072e | ||
|
|
ae3235b099 | ||
|
|
7cc5e0d577 | ||
|
|
f6b956dc8e | ||
|
|
fcb2bacd1e | ||
|
|
a9401e921e | ||
|
|
02e7e315b2 | ||
|
|
def72a64e0 | ||
|
|
46e7672197 | ||
|
|
2f8a5ce935 | ||
|
|
730e5bd831 | ||
|
|
b7984a05af | ||
|
|
5d4af67186 | ||
|
|
370e08cf4d | ||
|
|
aaf7e3f943 | ||
|
|
fbde0936e7 | ||
|
|
af48f7bab4 | ||
|
|
61def89878 | ||
|
|
88e86cee77 | ||
|
|
acc1625406 | ||
|
|
502f448053 | ||
|
|
55b081884c | ||
|
|
fd67171908 | ||
|
|
16a53aa641 | ||
|
|
4aec676950 | ||
|
|
d8fff0e90a | ||
|
|
57ad6cc3ea | ||
|
|
2b46a8b9c9 | ||
|
|
4d1a2e8c53 | ||
|
|
58b1409bd2 | ||
|
|
a2525dbf56 | ||
|
|
36eb2a31b5 | ||
|
|
0483bfc9cb | ||
|
|
3f63a64254 | ||
|
|
16332b285f | ||
|
|
f7371f6faf | ||
|
|
92d29805f1 | ||
|
|
4a37d07acb | ||
|
|
bb4c61e9cc | ||
|
|
f4e5515c82 | ||
|
|
141a2df19c | ||
|
|
e2385b4922 | ||
|
|
9974fb50f7 | ||
|
|
c5d51d62c4 | ||
|
|
4fcbf28f91 | ||
|
|
f678b664ff | ||
|
|
4206920a7d | ||
|
|
ad2e5ead54 | ||
|
|
eb72719117 | ||
|
|
20b46afbf2 | ||
|
|
1925e4a7f4 | ||
|
|
1a12322354 | ||
|
|
73f3f4ec7e | ||
|
|
a8c42f453a | ||
|
|
79dd0c5ba6 | ||
|
|
89bc3b6b16 | ||
|
|
a997dd6c49 | ||
|
|
6aa80d2a4c | ||
|
|
f009e8fb14 | ||
|
|
a8dde17155 | ||
|
|
cbcbff341b | ||
|
|
e50992bb93 | ||
|
|
fa6c3068c0 | ||
|
|
dd9bdca572 | ||
|
|
3f7dffe47d | ||
|
|
c7fde14458 | ||
|
|
57f4186cad | ||
|
|
fa5a6021b1 | ||
|
|
42ae279b91 | ||
|
|
a74cdbfc28 | ||
|
|
a56fa567dd | ||
|
|
c9c2d5ab6f | ||
|
|
ccf460c1f7 | ||
|
|
2325f542b8 | ||
|
|
63fdf3f3f6 | ||
|
|
efa83bdf34 | ||
|
|
5705bda818 | ||
|
|
20042334ff | ||
|
|
7ae9569816 | ||
|
|
cacba526b3 | ||
|
|
50f203cc8a | ||
|
|
3efcd154f3 | ||
|
|
bdb08d7c78 | ||
|
|
f3874dd40a | ||
|
|
935c39e341 | ||
|
|
7ddcc30e8d | ||
|
|
13ff038e58 | ||
|
|
1d4918dfbf | ||
|
|
ba14ab96da | ||
|
|
054e0820b7 | ||
|
|
af3d8dd6a7 | ||
|
|
e10d06cb47 | ||
|
|
87a1469c1e | ||
|
|
2492f1635c | ||
|
|
b3305e6e19 | ||
|
|
491d3e6606 | ||
|
|
e41bf67f73 | ||
|
|
66b99c4fa0 | ||
|
|
f2f2645fe6 | ||
|
|
4c77d0509a | ||
|
|
33d77f4355 | ||
|
|
ecf8617246 | ||
|
|
bec216d72a | ||
|
|
374e8c3307 | ||
|
|
b5eff8a9dd | ||
|
|
d53002a494 | ||
|
|
04662f0875 | ||
|
|
aec92c7c17 | ||
|
|
f7a7976923 | ||
|
|
1b50d4507f | ||
|
|
045cf887df | ||
|
|
277d7c0e04 | ||
|
|
0e2c703e77 | ||
|
|
62b3f38f00 | ||
|
|
422658293d | ||
|
|
74cfd05642 | ||
|
|
80586f1de3 | ||
|
|
a933177ac0 | ||
|
|
ade2db696b | ||
|
|
cf266037ff | ||
|
|
5f14277fbf | ||
|
|
b677349ec9 | ||
|
|
7f72d2a703 | ||
|
|
779983cb85 | ||
|
|
f2d2ab51b1 | ||
|
|
0a54f8c4a7 | ||
|
|
881527ddd0 | ||
|
|
cca4f894a8 | ||
|
|
20dae33be5 | ||
|
|
fd301c519d | ||
|
|
a96d87814b | ||
|
|
2a3eefc5be | ||
|
|
c5dc10e3cd | ||
|
|
c251a93609 | ||
|
|
2df509effd | ||
|
|
53e0d670b3 | ||
|
|
ccd19d2c96 | ||
|
|
b69f084db9 | ||
|
|
9639395937 | ||
|
|
117b7afd81 | ||
|
|
009c4dc8db | ||
|
|
0fdf3fc851 | ||
|
|
ffc2d91cef | ||
|
|
99975c8ff7 | ||
|
|
d44fd6b46d | ||
|
|
bd0a1426d7 | ||
|
|
353d144039 | ||
|
|
6efdf8a7f4 | ||
|
|
623770e24b | ||
|
|
402940a215 | ||
|
|
7fea85cdcd | ||
|
|
93b3b7a184 | ||
|
|
8f2a84629a | ||
|
|
7a1c1982f0 | ||
|
|
75d8982b23 | ||
|
|
87dbb56d7e | ||
|
|
aa217a3a43 | ||
|
|
22fc961dc0 | ||
|
|
8f57186945 | ||
|
|
f8277c55a8 | ||
|
|
6163713e34 | ||
|
|
d2d5887936 | ||
|
|
2a1065efc1 | ||
|
|
6f36a97c4a | ||
|
|
eeed79009a | ||
|
|
9930057171 | ||
|
|
e14c84f2fb | ||
|
|
a664c3dd47 | ||
|
|
73205b1f8c | ||
|
|
3016d7b8f3 | ||
|
|
beb3ddaa1f | ||
|
|
8db48fb4f1 | ||
|
|
6eb3641c1d | ||
|
|
8cfd64a7be | ||
|
|
e8d9ef269b | ||
|
|
80f83da9b8 | ||
|
|
6b8e235f88 | ||
|
|
a1d558a960 | ||
|
|
071ec80e2a | ||
|
|
995541db2e | ||
|
|
9121026856 | ||
|
|
341419788e | ||
|
|
f8f69fadc4 | ||
|
|
4830d82a73 | ||
|
|
f3a228c79a | ||
|
|
4bf96aaca0 | ||
|
|
a8a026d509 | ||
|
|
e1fd506269 | ||
|
|
63e86b5673 | ||
|
|
238299c759 | ||
|
|
4e9272e31c | ||
|
|
8f92c32693 | ||
|
|
699e283890 | ||
|
|
c51afc952c | ||
|
|
8fc030ba83 | ||
|
|
b754757c94 | ||
|
|
16bb40406a | ||
|
|
290ae04988 | ||
|
|
5c6f0e4d32 | ||
|
|
14143243b1 | ||
|
|
0e2c0c78f2 | ||
|
|
2a8e1f41d0 | ||
|
|
4e1d18e206 | ||
|
|
ff5a947a16 | ||
|
|
26ddb1e479 | ||
|
|
b2ddfd21c1 | ||
|
|
efe9268bcb | ||
|
|
974e618541 | ||
|
|
d09d281a8d | ||
|
|
43f3f54063 | ||
|
|
2b303e162c | ||
|
|
3947a755b1 | ||
|
|
0b764f4cb8 | ||
|
|
a0101c14a6 | ||
|
|
a4dcde2fc2 | ||
|
|
f6f5955753 | ||
|
|
d87f9fbd79 | ||
|
|
4c2bc47bf3 | ||
|
|
0d983d504b | ||
|
|
f26ccfa3e9 | ||
|
|
1ec6ba35e0 | ||
|
|
0378ea40e7 | ||
|
|
656250dd33 | ||
|
|
b914fa6da8 | ||
|
|
db77ec43a7 | ||
|
|
1a9d4bfb1c | ||
|
|
7180cb049c | ||
|
|
7e2769d8df | ||
|
|
23faeeb5d0 | ||
|
|
1e689a69a8 | ||
|
|
19004c0bad | ||
|
|
82059bb454 | ||
|
|
3fc846471e | ||
|
|
5379d45184 | ||
|
|
65b8bf6834 | ||
|
|
107dfcac65 | ||
|
|
2a29d077ee | ||
|
|
3d7f1f39ce | ||
|
|
51c02da206 | ||
|
|
16250e1b7c | ||
|
|
3e02c5e4a8 | ||
|
|
40da942bfe | ||
|
|
44909912cd | ||
|
|
631ee98738 | ||
|
|
0b68eea44a | ||
|
|
47743e7f90 | ||
|
|
b2da3545f9 | ||
|
|
fb005dd01b | ||
|
|
5b2bd90071 | ||
|
|
25e258e26a | ||
|
|
75d24974ec | ||
|
|
981bd950da | ||
|
|
0ca1886695 | ||
|
|
bf2f9e0f7e | ||
|
|
d74f1c22ff | ||
|
|
882e09f253 | ||
|
|
ce05c0e13d | ||
|
|
45c92f0868 | ||
|
|
e952f90b4c | ||
|
|
97bf5e8d69 | ||
|
|
ee7bb71a05 | ||
|
|
791cbab6f6 | ||
|
|
e001b7fb46 | ||
|
|
d8a75bef48 | ||
|
|
cfc4b79a05 | ||
|
|
fb3e5c9aab | ||
|
|
6796d8f124 | ||
|
|
154cb463e5 | ||
|
|
e9ce04ffe9 | ||
|
|
7a3fd11b6b | ||
|
|
e885f848a6 | ||
|
|
8343f074a2 | ||
|
|
cbadfd59db | ||
|
|
5d5fed62f2 | ||
|
|
c3d6484f6c | ||
|
|
315abec49c | ||
|
|
221b382e69 | ||
|
|
5fdbfef028 | ||
|
|
2cc671df75 | ||
|
|
ddbe2853ea | ||
|
|
2ab1b4b1c2 | ||
|
|
c5adc92f8b | ||
|
|
96b6056411 | ||
|
|
1108566e99 | ||
|
|
a54a5ee80d | ||
|
|
d57bc3ff01 | ||
|
|
f02dca2dd8 | ||
|
|
ad186701d3 | ||
|
|
a04b9ea053 | ||
|
|
41e6fb961b | ||
|
|
b2b43d2bd3 | ||
|
|
90339f9741 | ||
|
|
260806053b | ||
|
|
93c9bdcec7 | ||
|
|
935832028a | ||
|
|
c08f09b06b | ||
|
|
16410cf263 | ||
|
|
59af7ed3bb | ||
|
|
ee4206099a | ||
|
|
8c1d9bffcd | ||
|
|
a3a510308c | ||
|
|
97e292e251 | ||
|
|
4c5aa6a326 | ||
|
|
d1dd40590f | ||
|
|
c4764fa4d8 | ||
|
|
5dedb39048 | ||
|
|
bc759a32e3 | ||
|
|
dcc0841443 | ||
|
|
9b0388d00a | ||
|
|
99a1e42381 | ||
|
|
9b4df54432 | ||
|
|
aac0c0f037 | ||
|
|
a8f20196b2 | ||
|
|
a8bae3fb01 | ||
|
|
e8ccc030c0 | ||
|
|
aa6d9779d3 | ||
|
|
b1dbf340b8 | ||
|
|
27540d16ed | ||
|
|
2e63f62215 | ||
|
|
633ba293a3 | ||
|
|
679c960ea1 | ||
|
|
cf91101a48 | ||
|
|
344d90aea0 | ||
|
|
8b7fa6f845 | ||
|
|
2eb7f78248 | ||
|
|
9a5925b1ad | ||
|
|
60f2da370f | ||
|
|
7ee69628a3 | ||
|
|
a64f14db51 | ||
|
|
1c84fc97a1 | ||
|
|
8b371ead92 | ||
|
|
14417f70af | ||
|
|
96c6d408fb | ||
|
|
cd922e919e | ||
|
|
c56f06fbcb | ||
|
|
21dffa26b9 | ||
|
|
a131d5ad35 | ||
|
|
b5dbb1d39d | ||
|
|
bd3231d8dd | ||
|
|
4d96de3514 | ||
|
|
c9df6c11c5 | ||
|
|
56aaa08224 | ||
|
|
014aeccde6 | ||
|
|
dcfa993806 | ||
|
|
69688cffd6 | ||
|
|
769a31b7e3 | ||
|
|
78c20a8c25 | ||
|
|
bb1b3fdca1 | ||
|
|
f872b20a97 | ||
|
|
f36239712f | ||
|
|
74108dd680 | ||
|
|
c9a27ba6ac | ||
|
|
4e689e20e9 | ||
|
|
2f78b6f7f3 | ||
|
|
920917a47e | ||
|
|
c1a7784781 | ||
|
|
c3a9c05455 | ||
|
|
333e4aa362 | ||
|
|
59ce26f28a | ||
|
|
2ff63aaebf | ||
|
|
8cf72a4409 | ||
|
|
496b92536f | ||
|
|
ac7900ecd7 | ||
|
|
310832f111 | ||
|
|
f69dd0ef8d | ||
|
|
4b51bb2334 | ||
|
|
0d4f9f00ee | ||
|
|
4a0100271f | ||
|
|
52a467806a | ||
|
|
0fedecff58 | ||
|
|
da4cb0aa62 | ||
|
|
3b8a771909 | ||
|
|
f9bcfa14e0 | ||
|
|
11c2eab967 | ||
|
|
094d2e12a4 | ||
|
|
af195a610c | ||
|
|
f7a05cf077 | ||
|
|
41b0868165 | ||
|
|
59a7494770 | ||
|
|
abb3c936f7 | ||
|
|
0cb5aca81e | ||
|
|
474944fe74 | ||
|
|
d1a49cd9ce | ||
|
|
139d89d817 | ||
|
|
fedaede3b0 | ||
|
|
94ff9dc0a4 | ||
|
|
d4a88d08e4 | ||
|
|
7fc7ea6aba | ||
|
|
b57ad6929c | ||
|
|
550d274941 | ||
|
|
5a974483b9 | ||
|
|
34f34879c9 | ||
|
|
5c4b75909e | ||
|
|
41f126cad7 | ||
|
|
c26d7d23b5 | ||
|
|
4298ae00a9 | ||
|
|
47296e4294 | ||
|
|
f6daab0728 | ||
|
|
25dd9f1f35 | ||
|
|
130aedc474 | ||
|
|
e958f40bd9 | ||
|
|
ed2a2d7dc3 | ||
|
|
0890b32425 | ||
|
|
2e5981ecb3 | ||
|
|
ec00bb988c | ||
|
|
14a62586cc | ||
|
|
a8fe84acc7 | ||
|
|
144ba783a8 | ||
|
|
8d81ef811e | ||
|
|
3d8ec25a33 | ||
|
|
77f636f949 | ||
|
|
aa86f02b1a | ||
|
|
05daab24a2 | ||
|
|
0960663811 | ||
|
|
150cc56b35 | ||
|
|
7a9091fcae | ||
|
|
e6215d969d | ||
|
|
9f1b8347f5 | ||
|
|
311e1568d9 | ||
|
|
c2dadd8054 | ||
|
|
88bdfd6548 | ||
|
|
70edb62a6b | ||
|
|
6c2e0ccce5 | ||
|
|
fc6e0dfa65 | ||
|
|
54aebb7d98 | ||
|
|
378c67d51f | ||
|
|
d535035bdd | ||
|
|
43790db48e | ||
|
|
d957adf062 | ||
|
|
ff8f3eb8c2 | ||
|
|
88c54c918c | ||
|
|
1261a335f4 | ||
|
|
7587d76fd1 | ||
|
|
8e81300f37 | ||
|
|
a999020038 | ||
|
|
bc4664d62c | ||
|
|
6a1754aa6a | ||
|
|
da7bb312c2 | ||
|
|
5b7f813f81 | ||
|
|
923d9a0df2 | ||
|
|
c16224b37a | ||
|
|
01b5bdc829 | ||
|
|
5a0d66141f | ||
|
|
8e873e7450 | ||
|
|
add3fa43c6 | ||
|
|
b985a8d47a | ||
|
|
3db3150a7e | ||
|
|
17ce2a3cad | ||
|
|
e239304d89 | ||
|
|
893f3f343f | ||
|
|
5918a18dee | ||
|
|
c08dcff56d | ||
|
|
f33cd4e419 | ||
|
|
a625426a28 | ||
|
|
24e66337ff | ||
|
|
d06f1ecf19 | ||
|
|
9c6831c360 | ||
|
|
64ec0708c4 | ||
|
|
34aa1e8de0 | ||
|
|
b0f31d8296 | ||
|
|
e5fe5199a3 | ||
|
|
45e95d1d00 | ||
|
|
21876e72fe | ||
|
|
81903598a8 | ||
|
|
290500ae17 |
23
.github/workflows/docker-build-test.yml
vendored
23
.github/workflows/docker-build-test.yml
vendored
@@ -15,12 +15,9 @@ on:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# copy most of these steps from release.yml, but push: false and no tags:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
docker_build_and_push:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -29,24 +26,32 @@ jobs:
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build Docker standard image
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Build and push Docker images
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: false
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/aider:dev
|
||||
target: aider
|
||||
|
||||
- name: Build Docker full image
|
||||
- name: Build and push Docker full image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: false
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/aider-full:dev
|
||||
target: aider-full
|
||||
|
||||
29
.github/workflows/issues.yml
vendored
Normal file
29
.github/workflows/issues.yml
vendored
Normal 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
|
||||
2
.github/workflows/pages.yml
vendored
2
.github/workflows/pages.yml
vendored
@@ -84,4 +84,4 @@ jobs:
|
||||
|
||||
- name: Run linkchecker
|
||||
run: |
|
||||
linkchecker https://aider.chat
|
||||
linkchecker --ignore-url='.+\.(mp4|mov|avi)' https://aider.chat
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,4 +13,6 @@ _site
|
||||
aider/__version__.py
|
||||
aider/_version.py
|
||||
.venv/
|
||||
.#*
|
||||
.gitattributes
|
||||
tmp.benchmarks/
|
||||
@@ -56,13 +56,6 @@ It is recommended to create a virtual environment outside of the repository to k
|
||||
python -m venv /path/to/venv
|
||||
```
|
||||
|
||||
#### Using `virtualenv` (for older Python versions)
|
||||
|
||||
```
|
||||
pip install virtualenv
|
||||
virtualenv /path/to/venv
|
||||
```
|
||||
|
||||
### Activate the Virtual Environment
|
||||
|
||||
#### On Windows
|
||||
|
||||
105
HISTORY.md
105
HISTORY.md
@@ -1,6 +1,109 @@
|
||||
# Release history
|
||||
|
||||
### main branch
|
||||
### Aider v0.71.1
|
||||
|
||||
- Fix permissions issue in Docker images.
|
||||
- Added read-only file announcements to chat.
|
||||
- Bugfix: ASCII fallback for unicode errors.
|
||||
- Bugfix: integer indices for list slicing in repomap calculations.
|
||||
- Aider wrote 83% of the code in this release.
|
||||
|
||||
### Aider v0.71.0
|
||||
|
||||
- Prompts to help DeepSeek work better when alternating between `/ask` and `/code`.
|
||||
- Streaming pretty LLM responses is smoother and faster for long replies.
|
||||
- Streaming automatically turns of for model that don't support it
|
||||
- Can now switch to/from `/model o1` and a streaming model
|
||||
- Pretty output remains enabled even when editing files with triple-backtick fences
|
||||
- Bare `/ask`, `/code` and `/architect` commands now switch the chat mode.
|
||||
- Increased default size of the repomap.
|
||||
- Increased max chat history tokens limit from 4k to 8k.
|
||||
- Turn off fancy input and watch files if terminal is dumb.
|
||||
- Added support for custom voice format and input device settings.
|
||||
- Disabled Streamlit email prompt, by apaz-cli.
|
||||
- Docker container runs as non-root user.
|
||||
- Fixed lint command handling of nested spaced strings, by Aaron Weisberg.
|
||||
- Added token count feedback when adding command output to chat.
|
||||
- Improved error handling for large audio files with automatic format conversion.
|
||||
- Improved handling of git repo index errors, by Krazer.
|
||||
- Improved unicode handling in console output with ASCII fallback.
|
||||
- Added AssertionError, AttributeError to git error handling.
|
||||
- Aider wrote 60% of the code in this release.
|
||||
|
||||
### Aider v0.70.0
|
||||
|
||||
- Full support for o1 models.
|
||||
- Watch files now honors `--subtree-only`, and only watches that subtree.
|
||||
- Improved prompting for watch files, to work more reliably with more models.
|
||||
- New install methods via uv, including one-liners.
|
||||
- Support for openrouter/deepseek/deepseek-chat model.
|
||||
- Better error handling when interactive commands are attempted via `/load` or `--load`.
|
||||
- Display read-only files with abs path if its shorter than rel path.
|
||||
- Ask 10% of users to opt-in to analytics.
|
||||
- Bugfix for auto-suggest.
|
||||
- Gracefully handle unicode errors in git path names.
|
||||
- Aider wrote 74% of the code in this release.
|
||||
|
||||
### Aider v0.69.1
|
||||
|
||||
- Fix for gemini model names in model metadata.
|
||||
- Show hints about AI! and AI? when user makes AI comments.
|
||||
- Support for running without git installed.
|
||||
- Improved environment variable setup messages on Windows.
|
||||
|
||||
### Aider v0.69.0
|
||||
|
||||
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
|
||||
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
|
||||
- Now watches *all* files, not just certain source files.
|
||||
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
|
||||
- Full support for Gemini Flash 2.0 Exp:
|
||||
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
|
||||
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
|
||||
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
|
||||
- Improved clipboard error handling with helpful requirements install info.
|
||||
- Ask 5% of users if they want to opt-in to analytics.
|
||||
- `/voice` now lets you edit the transcribed text before sending.
|
||||
- Disabled auto-complete in Y/N prompts.
|
||||
- Aider wrote 68% of the code in this release.
|
||||
|
||||
### Aider v0.68.0
|
||||
|
||||
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
|
||||
- New `--copy-paste` mode.
|
||||
- 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.
|
||||
|
||||
20
MANIFEST.in
Normal file
20
MANIFEST.in
Normal file
@@ -0,0 +1,20 @@
|
||||
# This needs to sync with aider/help_pats.py
|
||||
|
||||
global-exclude .DS_Store
|
||||
|
||||
recursive-exclude aider/website/examples *
|
||||
recursive-exclude aider/website/_posts *
|
||||
|
||||
exclude aider/website/HISTORY.md
|
||||
exclude aider/website/docs/benchmarks*.md
|
||||
exclude aider/website/docs/ctags.md
|
||||
exclude aider/website/docs/unified-diffs.md
|
||||
|
||||
exclude aider/website/install.ps1
|
||||
exclude aider/website/install.sh
|
||||
|
||||
recursive-exclude aider/website/docs/leaderboards *
|
||||
recursive-exclude aider/website/assets *
|
||||
recursive-exclude aider/website *.js
|
||||
recursive-exclude aider/website *.html
|
||||
recursive-exclude aider/website *.yml
|
||||
36
README.md
36
README.md
@@ -5,9 +5,9 @@
|
||||
|
||||
Aider lets you pair program with LLMs,
|
||||
to edit code in your local git repository.
|
||||
Start a new project or work with an existing git repo.
|
||||
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
|
||||
[connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
Start a new project or work with an existing code base.
|
||||
Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
|
||||
|
||||
<!-- SCREENCAST START -->
|
||||
<p align="center">
|
||||
@@ -43,28 +43,27 @@ VIDEO END -->
|
||||
cog.out(open("aider/website/_includes/get-started.md").read())
|
||||
]]]-->
|
||||
|
||||
You can get started quickly like this:
|
||||
If you already have python 3.8-3.13 installed, you can get started quickly like this:
|
||||
|
||||
```
|
||||
python -m pip install -U aider-chat
|
||||
```bash
|
||||
python -m pip install aider-install
|
||||
aider-install
|
||||
|
||||
# Change directory into a git repo
|
||||
cd /to/your/git/repo
|
||||
# Change directory into your code base
|
||||
cd /to/your/project
|
||||
|
||||
# Work with Claude 3.5 Sonnet on your repo
|
||||
export ANTHROPIC_API_KEY=your-key-goes-here
|
||||
aider
|
||||
# Work with Claude 3.5 Sonnet on your code
|
||||
aider --model sonnet --anthropic-api-key your-key-goes-here
|
||||
|
||||
# Work with GPT-4o on your repo
|
||||
export OPENAI_API_KEY=your-key-goes-here
|
||||
aider
|
||||
# Work with GPT-4o on your code
|
||||
aider --model gpt-4o --openai-api-key your-key-goes-here
|
||||
```
|
||||
<!--[[[end]]]-->
|
||||
|
||||
See the
|
||||
[installation instructions](https://aider.chat/docs/install.html)
|
||||
and other
|
||||
[documentation](https://aider.chat/docs/usage.html)
|
||||
and
|
||||
[usage documentation](https://aider.chat/docs/usage.html)
|
||||
for more details.
|
||||
|
||||
## Features
|
||||
@@ -78,16 +77,17 @@ for more details.
|
||||
- Update docs.
|
||||
- Aider will edit your files to complete your request.
|
||||
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
|
||||
- [Use aider inside your favorite editor or IDE](https://aider.chat/docs/usage/watch.html).
|
||||
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
|
||||
- Aider works best with GPT-4o & Claude 3.5 Sonnet and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
- Aider can edit multiple files at once for complex requests.
|
||||
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
|
||||
- Edit files in your editor while chatting with aider,
|
||||
- Edit files in your editor or IDE while chatting with aider,
|
||||
and it will always use the latest version.
|
||||
Pair program with AI.
|
||||
- [Add images to the chat](https://aider.chat/docs/usage/images-urls.html) (GPT-4o, Claude 3.5 Sonnet, etc).
|
||||
- [Add URLs to the chat](https://aider.chat/docs/usage/images-urls.html) and aider will read their content.
|
||||
- [Code with your voice](https://aider.chat/docs/usage/voice.html).
|
||||
- Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
|
||||
|
||||
## Top tier performance
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from packaging import version
|
||||
|
||||
__version__ = "0.66.1.dev"
|
||||
__version__ = "0.71.2.dev"
|
||||
safe_version = __version__
|
||||
|
||||
try:
|
||||
|
||||
@@ -5,13 +5,53 @@ 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__
|
||||
from aider.dump import dump # noqa: F401
|
||||
from aider.models import model_info_manager
|
||||
|
||||
PERCENT = 10
|
||||
|
||||
|
||||
def compute_hex_threshold(percent):
|
||||
"""Convert percentage to 6-digit hex threshold.
|
||||
|
||||
Args:
|
||||
percent: Percentage threshold (0-100)
|
||||
|
||||
Returns:
|
||||
str: 6-digit hex threshold
|
||||
"""
|
||||
return format(int(0xFFFFFF * percent / 100), "06x")
|
||||
|
||||
|
||||
def is_uuid_in_percentage(uuid_str, percent):
|
||||
"""Check if a UUID string falls within the first X percent of the UUID space.
|
||||
|
||||
Args:
|
||||
uuid_str: UUID string to test
|
||||
percent: Percentage threshold (0-100)
|
||||
|
||||
Returns:
|
||||
bool: True if UUID falls within the first X percent
|
||||
"""
|
||||
if not (0 <= percent <= 100):
|
||||
raise ValueError("Percentage must be between 0 and 100")
|
||||
|
||||
if not uuid_str:
|
||||
return False
|
||||
|
||||
# Convert percentage to hex threshold (1% = "04...", 10% = "1a...", etc)
|
||||
# Using first 6 hex digits
|
||||
if percent == 0:
|
||||
return False
|
||||
|
||||
threshold = compute_hex_threshold(percent)
|
||||
return uuid_str[:6] <= threshold
|
||||
|
||||
|
||||
mixpanel_project_token = "6da9a43058a5d1b9f3353153921fb04d"
|
||||
posthog_project_api_key = "phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv"
|
||||
posthog_host = "https://us.i.posthog.com"
|
||||
@@ -50,8 +90,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,31 +124,7 @@ class Analytics:
|
||||
if not self.user_id:
|
||||
return False
|
||||
|
||||
PERCENT = 2.5
|
||||
return self.is_uuid_in_percentage(self.user_id, PERCENT)
|
||||
|
||||
def is_uuid_in_percentage(self, uuid_str, percent):
|
||||
"""Check if a UUID string falls within the first X percent of the UUID space.
|
||||
|
||||
Args:
|
||||
uuid_str: UUID string to test
|
||||
percent: Percentage threshold (0-100)
|
||||
|
||||
Returns:
|
||||
bool: True if UUID falls within the first X percent
|
||||
"""
|
||||
if not (0 <= percent <= 100):
|
||||
raise ValueError("Percentage must be between 0 and 100")
|
||||
|
||||
if not uuid_str:
|
||||
return False
|
||||
|
||||
# Convert percentage to hex threshold (1% = "04...", 10% = "1a...", etc)
|
||||
# Using first 6 hex digits
|
||||
if percent == 0:
|
||||
return False
|
||||
threshold = format(int(0xFFFFFF * percent / 100), "06x")
|
||||
return uuid_str[:6] <= threshold
|
||||
return is_uuid_in_percentage(self.user_id, PERCENT)
|
||||
|
||||
def get_data_file_path(self):
|
||||
try:
|
||||
@@ -159,6 +181,7 @@ class Analytics:
|
||||
"os_platform": platform.system(),
|
||||
"os_release": platform.release(),
|
||||
"machine": platform.machine(),
|
||||
"aider_version": __version__,
|
||||
}
|
||||
|
||||
def _redact_model_name(self, model):
|
||||
@@ -172,6 +195,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
|
||||
@@ -184,7 +214,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():
|
||||
@@ -193,8 +222,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))
|
||||
@@ -211,6 +238,13 @@ 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")
|
||||
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
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
dump(compute_hex_threshold(PERCENT))
|
||||
|
||||
346
aider/args.py
346
aider/args.py
@@ -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",
|
||||
@@ -118,7 +106,7 @@ def get_parser(default_config_files, git_root):
|
||||
const=gpt_3_model_name,
|
||||
help=f"Use {gpt_3_model_name} model for the main chat",
|
||||
)
|
||||
deepseek_model = "deepseek/deepseek-coder"
|
||||
deepseek_model = "deepseek/deepseek-chat"
|
||||
group.add_argument(
|
||||
"--deepseek",
|
||||
action="store_const",
|
||||
@@ -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",
|
||||
@@ -261,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,
|
||||
@@ -286,12 +282,12 @@ 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,
|
||||
default=None,
|
||||
help="Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)",
|
||||
help="Suggested number of tokens to use for repo map, use 0 to disable",
|
||||
)
|
||||
group.add_argument(
|
||||
"--map-refresh",
|
||||
@@ -343,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",
|
||||
@@ -431,7 +427,8 @@ def get_parser(default_config_files, git_root):
|
||||
default="default",
|
||||
help=(
|
||||
"Set the markdown code theme (default: default, other options include monokai,"
|
||||
" solarized-dark, solarized-light)"
|
||||
" solarized-dark, solarized-light, or a Pygments builtin style,"
|
||||
" see https://pygments.org/styles for available themes)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
@@ -442,7 +439,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,
|
||||
@@ -529,6 +526,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",
|
||||
@@ -589,37 +592,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",
|
||||
@@ -652,47 +626,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",
|
||||
@@ -711,6 +652,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",
|
||||
@@ -731,12 +776,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",
|
||||
@@ -750,6 +796,12 @@ def get_parser(default_config_files, git_root):
|
||||
default=True,
|
||||
help="Enable/disable fancy input with history and completion (default: True)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--multiline",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=False,
|
||||
help="Enable/disable multi-line input mode with Meta-Enter to submit (default: False)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--detect-urls",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
@@ -761,28 +813,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)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--voice-input-device",
|
||||
metavar="VOICE_INPUT_DEVICE",
|
||||
default=None,
|
||||
help="Specify the input device name for voice recording",
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ class AskPrompts(CoderPrompts):
|
||||
main_system = """Act as an expert code analyst.
|
||||
Answer questions about the supplied code.
|
||||
Always reply to the user in {language}.
|
||||
|
||||
Describe code changes however you like. Don't use SEARCH/REPLACE blocks!
|
||||
"""
|
||||
|
||||
example_messages = []
|
||||
|
||||
@@ -59,7 +59,8 @@ def wrap_fence(name):
|
||||
|
||||
|
||||
all_fences = [
|
||||
("``" + "`", "``" + "`"),
|
||||
("`" * 3, "`" * 3),
|
||||
("`" * 4, "`" * 4),
|
||||
wrap_fence("source"),
|
||||
wrap_fence("code"),
|
||||
wrap_fence("pre"),
|
||||
@@ -103,6 +104,7 @@ class Coder:
|
||||
detect_urls = True
|
||||
ignore_mentions = None
|
||||
chat_language = None
|
||||
file_watcher = None
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
@@ -153,8 +155,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 +178,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):
|
||||
@@ -229,10 +231,10 @@ class Coder:
|
||||
if map_tokens > 0:
|
||||
refresh = self.repo_map.refresh
|
||||
lines.append(f"Repo-map: using {map_tokens} tokens, {refresh} refresh")
|
||||
max_map_tokens = 2048
|
||||
max_map_tokens = self.main_model.get_repo_map_tokens() * 2
|
||||
if map_tokens > max_map_tokens:
|
||||
lines.append(
|
||||
f"Warning: map-tokens > {max_map_tokens} is not recommended as too much"
|
||||
f"Warning: map-tokens > {max_map_tokens} is not recommended. Too much"
|
||||
" irrelevant code can confuse LLMs."
|
||||
)
|
||||
else:
|
||||
@@ -244,9 +246,16 @@ class Coder:
|
||||
for fname in self.get_inchat_relative_files():
|
||||
lines.append(f"Added {fname} to the chat.")
|
||||
|
||||
for fname in self.abs_read_only_fnames:
|
||||
rel_fname = self.get_rel_fname(fname)
|
||||
lines.append(f"Added {rel_fname} to the chat (read-only).")
|
||||
|
||||
if self.done_messages:
|
||||
lines.append("Restored previous conversation history.")
|
||||
|
||||
if self.io.multiline_mode:
|
||||
lines.append("Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text")
|
||||
|
||||
return lines
|
||||
|
||||
def __init__(
|
||||
@@ -283,6 +292,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 +305,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
|
||||
@@ -332,7 +353,6 @@ class Coder:
|
||||
self.done_messages = []
|
||||
|
||||
self.io = io
|
||||
self.stream = stream
|
||||
|
||||
self.shell_commands = []
|
||||
|
||||
@@ -347,6 +367,8 @@ class Coder:
|
||||
|
||||
self.main_model = main_model
|
||||
|
||||
self.stream = stream and main_model.streaming
|
||||
|
||||
if cache_prompts and self.main_model.cache_control:
|
||||
self.add_cache_headers = True
|
||||
|
||||
@@ -503,7 +525,7 @@ class Coder:
|
||||
return False
|
||||
|
||||
# only show pretty output if fences are the normal triple-backtick
|
||||
if self.fence != self.fences[0]:
|
||||
if self.fence[0][0] != "`":
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -597,9 +619,19 @@ class Coder:
|
||||
def get_ident_filename_matches(self, idents):
|
||||
all_fnames = defaultdict(set)
|
||||
for fname in self.get_all_relative_files():
|
||||
base = Path(fname).with_suffix("").name.lower()
|
||||
if len(base) >= 5:
|
||||
all_fnames[base].add(fname)
|
||||
# Skip empty paths or just '.'
|
||||
if not fname or fname == ".":
|
||||
continue
|
||||
|
||||
try:
|
||||
# Handle dotfiles properly
|
||||
path = Path(fname)
|
||||
base = path.stem.lower() # Use stem instead of with_suffix("").name
|
||||
if len(base) >= 5:
|
||||
all_fnames[base].add(fname)
|
||||
except ValueError:
|
||||
# Skip paths that can't be processed
|
||||
continue
|
||||
|
||||
matches = set()
|
||||
for ident in idents:
|
||||
@@ -782,9 +814,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()
|
||||
@@ -793,6 +826,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]
|
||||
@@ -1104,7 +1141,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.
|
||||
@@ -1115,7 +1155,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"]
|
||||
@@ -1420,6 +1460,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:
|
||||
@@ -1448,7 +1490,7 @@ class Coder:
|
||||
words = set(word for word in content.split())
|
||||
|
||||
# drop sentence punctuation from the end
|
||||
words = set(word.rstrip(",.!;:") for word in words)
|
||||
words = set(word.rstrip(",.!;:?") for word in words)
|
||||
|
||||
# strip away all kinds of quotes
|
||||
quotes = "".join(['"', "'", "`"])
|
||||
@@ -1537,6 +1579,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
|
||||
@@ -1554,8 +1606,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)
|
||||
|
||||
@@ -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}
|
||||
@@ -181,6 +183,9 @@ If you want to put code in a new file, use a *SEARCH/REPLACE block* with:
|
||||
|
||||
To rename files which have been added to the chat, use shell commands at the end of your response.
|
||||
|
||||
If the user just says something like "ok" or "go ahead" or "do that" they probably want you to make SEARCH/REPLACE blocks for the code changes you just proposed.
|
||||
The user will say when they've applied your edits. If they haven't explicitly confirmed the edits have been applied, they probably want proper SEARCH/REPLACE blocks.
|
||||
|
||||
{lazy_prompt}
|
||||
ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
|
||||
{shell_cmd_reminder}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import git
|
||||
try:
|
||||
import git
|
||||
except ImportError:
|
||||
git = None
|
||||
|
||||
from diff_match_patch import diff_match_patch
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
@@ -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__(
|
||||
@@ -50,6 +52,8 @@ class Commands:
|
||||
io,
|
||||
coder,
|
||||
voice_language=None,
|
||||
voice_input_device=None,
|
||||
voice_format=None,
|
||||
verify_ssl=True,
|
||||
args=None,
|
||||
parser=None,
|
||||
@@ -67,6 +71,8 @@ class Commands:
|
||||
voice_language = None
|
||||
|
||||
self.voice_language = voice_language
|
||||
self.voice_format = voice_format
|
||||
self.voice_input_device = voice_input_device
|
||||
|
||||
self.help = None
|
||||
self.editor = editor
|
||||
@@ -101,6 +107,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 +601,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 +802,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):
|
||||
@@ -900,10 +918,14 @@ class Commands:
|
||||
if combined_output is None:
|
||||
return
|
||||
|
||||
# Calculate token count of output
|
||||
token_count = self.coder.main_model.token_count(combined_output)
|
||||
k_tokens = token_count / 1000
|
||||
|
||||
if add_on_nonzero_exit:
|
||||
add = exit_status != 0
|
||||
else:
|
||||
add = self.io.confirm_ask("Add command output to the chat?")
|
||||
add = self.io.confirm_ask(f"Add {k_tokens:.1f}k tokens of command output to the chat?")
|
||||
|
||||
if add:
|
||||
num_lines = len(combined_output.strip().splitlines())
|
||||
@@ -920,6 +942,9 @@ class Commands:
|
||||
dict(role="assistant", content="Ok."),
|
||||
]
|
||||
|
||||
if add and exit_status != 0:
|
||||
self.io.placeholder = "What's wrong? Fix"
|
||||
|
||||
def cmd_exit(self, args):
|
||||
"Exit the application"
|
||||
self.coder.event("exit", reason="/exit")
|
||||
@@ -992,7 +1017,7 @@ class Commands:
|
||||
return
|
||||
|
||||
self.coder.event("interactive help")
|
||||
from aider.coders import Coder
|
||||
from aider.coders.base_coder import Coder
|
||||
|
||||
if not self.help:
|
||||
res = install_help_extra(self.io)
|
||||
@@ -1036,23 +1061,23 @@ class Commands:
|
||||
)
|
||||
|
||||
def cmd_ask(self, args):
|
||||
"Ask questions about the code base without editing any files"
|
||||
"""Ask questions about the code base without editing any files. If no prompt provided, switches to ask mode.""" # noqa
|
||||
return self._generic_chat_command(args, "ask")
|
||||
|
||||
def cmd_code(self, args):
|
||||
"Ask for changes to your code"
|
||||
"""Ask for changes to your code. If no prompt provided, switches to code mode.""" # noqa
|
||||
return self._generic_chat_command(args, self.coder.main_model.edit_format)
|
||||
|
||||
def cmd_architect(self, args):
|
||||
"Enter architect mode to discuss high-level design and architecture"
|
||||
"""Enter architect mode to discuss high-level design and architecture. If no prompt provided, switches to architect mode.""" # noqa
|
||||
return self._generic_chat_command(args, "architect")
|
||||
|
||||
def _generic_chat_command(self, args, edit_format):
|
||||
if not args.strip():
|
||||
self.io.tool_error(f"Please provide a question or topic for the {edit_format} chat.")
|
||||
return
|
||||
# Switch to the corresponding chat mode if no args provided
|
||||
return self.cmd_chat_mode(edit_format)
|
||||
|
||||
from aider.coders import Coder
|
||||
from aider.coders.base_coder import Coder
|
||||
|
||||
coder = Coder.create(
|
||||
io=self.io,
|
||||
@@ -1100,7 +1125,7 @@ class Commands:
|
||||
return
|
||||
try:
|
||||
self.voice = voice.Voice(
|
||||
audio_format=self.args.voice_format, device_name=self.args.voice_input_device
|
||||
audio_format=self.voice_format or "wav", device_name=self.voice_input_device
|
||||
)
|
||||
except voice.SoundDeviceError:
|
||||
self.io.tool_error(
|
||||
@@ -1108,36 +1133,14 @@ class Commands:
|
||||
)
|
||||
return
|
||||
|
||||
history_iter = self.io.get_input_history()
|
||||
|
||||
history = []
|
||||
size = 0
|
||||
for line in history_iter:
|
||||
if line.startswith("/"):
|
||||
continue
|
||||
if line in history:
|
||||
continue
|
||||
if size + len(line) > 1024:
|
||||
break
|
||||
size += len(line)
|
||||
history.append(line)
|
||||
|
||||
history.reverse()
|
||||
history = "\n".join(history)
|
||||
|
||||
try:
|
||||
text = self.voice.record_and_transcribe(history, language=self.voice_language)
|
||||
text = self.voice.record_and_transcribe(None, language=self.voice_language)
|
||||
except litellm.OpenAIError as err:
|
||||
self.io.tool_error(f"Unable to use OpenAI whisper model: {err}")
|
||||
return
|
||||
|
||||
if text:
|
||||
self.io.add_to_input_history(text)
|
||||
self.io.print()
|
||||
self.io.user_input(text, log_only=False)
|
||||
self.io.print()
|
||||
|
||||
return text
|
||||
self.io.placeholder = text
|
||||
|
||||
def cmd_paste(self, args):
|
||||
"""Paste image/text from the clipboard into the chat.\
|
||||
@@ -1190,9 +1193,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)
|
||||
@@ -1309,7 +1317,12 @@ class Commands:
|
||||
continue
|
||||
|
||||
self.io.tool_output(f"\nExecuting: {cmd}")
|
||||
self.run(cmd)
|
||||
try:
|
||||
self.run(cmd)
|
||||
except SwitchCoder:
|
||||
self.io.tool_error(
|
||||
f"Command '{cmd}' is only supported in interactive mode, skipping."
|
||||
)
|
||||
|
||||
def completions_raw_save(self, document, complete_event):
|
||||
return self.completions_raw_read_only(document, complete_event)
|
||||
@@ -1341,6 +1354,10 @@ class Commands:
|
||||
except Exception as e:
|
||||
self.io.tool_error(f"Error saving commands to file: {e}")
|
||||
|
||||
def cmd_multiline_mode(self, args):
|
||||
"Toggle multiline mode (swaps behavior of Enter and Meta+Enter)"
|
||||
self.io.toggle_multiline_mode()
|
||||
|
||||
def cmd_copy(self, args):
|
||||
"Copy the last assistant message to the clipboard"
|
||||
all_messages = self.coder.done_messages + self.coder.cur_messages
|
||||
@@ -1389,6 +1406,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
72
aider/copypaste.py
Normal 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()
|
||||
@@ -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))
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# This needs to sync with MANIFEST.in
|
||||
|
||||
exclude_website_pats = [
|
||||
"**/.DS_Store",
|
||||
"examples/**",
|
||||
"_posts/**",
|
||||
"HISTORY.md",
|
||||
@@ -7,5 +10,4 @@ exclude_website_pats = [
|
||||
"docs/unified-diffs.md",
|
||||
"docs/leaderboards/index.md",
|
||||
"assets/**",
|
||||
"**/.DS_Store",
|
||||
]
|
||||
|
||||
@@ -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)]
|
||||
|
||||
158
aider/io.py
158
aider/io.py
@@ -1,5 +1,6 @@
|
||||
import base64
|
||||
import os
|
||||
import signal
|
||||
import time
|
||||
import webbrowser
|
||||
from collections import defaultdict
|
||||
@@ -11,9 +12,12 @@ from pathlib import Path
|
||||
from prompt_toolkit.completion import Completer, Completion, ThreadedCompleter
|
||||
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
|
||||
from prompt_toolkit.enums import EditingMode
|
||||
from prompt_toolkit.filters import Condition, is_searching
|
||||
from prompt_toolkit.history import FileHistory
|
||||
from prompt_toolkit.key_binding import KeyBindings
|
||||
from prompt_toolkit.keys import Keys
|
||||
from prompt_toolkit.lexers import PygmentsLexer
|
||||
from prompt_toolkit.output.vt100 import is_dumb_terminal
|
||||
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
|
||||
from prompt_toolkit.styles import Style
|
||||
from pygments.lexers import MarkdownLexer, guess_lexer_for_filename
|
||||
@@ -173,6 +177,7 @@ class AutoCompleter(Completer):
|
||||
class InputOutput:
|
||||
num_error_outputs = 0
|
||||
num_user_asks = 0
|
||||
clipboard_watcher = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -197,10 +202,15 @@ class InputOutput:
|
||||
llm_history_file=None,
|
||||
editingmode=EditingMode.EMACS,
|
||||
fancy_input=True,
|
||||
file_watcher=None,
|
||||
multiline_mode=False,
|
||||
root=".",
|
||||
):
|
||||
self.placeholder = None
|
||||
self.interrupted = False
|
||||
self.never_prompts = set()
|
||||
self.editingmode = editingmode
|
||||
self.multiline_mode = multiline_mode
|
||||
no_color = os.environ.get("NO_COLOR")
|
||||
if no_color is not None and no_color != "":
|
||||
pretty = False
|
||||
@@ -240,8 +250,14 @@ class InputOutput:
|
||||
self.append_chat_history(f"\n# aider chat started at {current_time}\n\n")
|
||||
|
||||
self.prompt_session = None
|
||||
self.is_dumb_terminal = is_dumb_terminal()
|
||||
|
||||
if self.is_dumb_terminal:
|
||||
self.pretty = False
|
||||
fancy_input = False
|
||||
|
||||
if fancy_input:
|
||||
# Initialize PromptSession
|
||||
# Initialize PromptSession only if we have a capable terminal
|
||||
session_kwargs = {
|
||||
"input": self.input,
|
||||
"output": self.output,
|
||||
@@ -260,6 +276,11 @@ class InputOutput:
|
||||
self.tool_error(f"Can't initialize prompt toolkit: {err}") # non-pretty
|
||||
else:
|
||||
self.console = Console(force_terminal=False, no_color=True) # non-pretty
|
||||
if self.is_dumb_terminal:
|
||||
self.tool_output("Detected dumb terminal, disabling fancy input and pretty output.")
|
||||
|
||||
self.file_watcher = file_watcher
|
||||
self.root = root
|
||||
|
||||
def _get_style(self):
|
||||
style_dict = {}
|
||||
@@ -314,7 +335,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 +343,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 +398,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 +425,8 @@ class InputOutput:
|
||||
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
|
||||
if edit_format:
|
||||
show += edit_format
|
||||
if self.multiline_mode:
|
||||
show += (" " if edit_format else "") + "multi"
|
||||
show += "> "
|
||||
|
||||
inp = ""
|
||||
@@ -411,8 +445,17 @@ 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"
|
||||
@@ -428,9 +471,25 @@ class InputOutput:
|
||||
"Navigate forward through history"
|
||||
event.current_buffer.history_forward()
|
||||
|
||||
@kb.add("escape", "c-m", eager=True)
|
||||
@kb.add("enter", eager=True, filter=~is_searching)
|
||||
def _(event):
|
||||
event.current_buffer.insert_text("\n")
|
||||
"Handle Enter key press"
|
||||
if self.multiline_mode:
|
||||
# In multiline mode, Enter adds a newline
|
||||
event.current_buffer.insert_text("\n")
|
||||
else:
|
||||
# In normal mode, Enter submits
|
||||
event.current_buffer.validate_and_handle()
|
||||
|
||||
@kb.add("escape", "enter", eager=True, filter=~is_searching) # This is Alt+Enter
|
||||
def _(event):
|
||||
"Handle Alt+Enter key press"
|
||||
if self.multiline_mode:
|
||||
# In multiline mode, Alt+Enter submits
|
||||
event.current_buffer.validate_and_handle()
|
||||
else:
|
||||
# In normal mode, Alt+Enter adds a newline
|
||||
event.current_buffer.insert_text("\n")
|
||||
|
||||
while True:
|
||||
if multiline_input:
|
||||
@@ -442,6 +501,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,
|
||||
@@ -450,12 +516,34 @@ class InputOutput:
|
||||
complete_style=CompleteStyle.MULTI_COLUMN,
|
||||
style=style,
|
||||
key_bindings=kb,
|
||||
complete_while_typing=True,
|
||||
)
|
||||
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")
|
||||
@@ -573,6 +661,9 @@ class InputOutput:
|
||||
group=None,
|
||||
allow_never=False,
|
||||
):
|
||||
# Temporarily disable multiline mode for yes/no prompts
|
||||
orig_multiline = self.multiline_mode
|
||||
self.multiline_mode = False
|
||||
self.num_user_asks += 1
|
||||
|
||||
question_id = (question, subject)
|
||||
@@ -630,6 +721,7 @@ class InputOutput:
|
||||
res = self.prompt_session.prompt(
|
||||
question,
|
||||
style=style,
|
||||
complete_while_typing=False,
|
||||
)
|
||||
else:
|
||||
res = input(question)
|
||||
@@ -670,9 +762,15 @@ class InputOutput:
|
||||
hist = f"{question.strip()} {res}"
|
||||
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
||||
|
||||
# Restore original multiline mode
|
||||
self.multiline_mode = orig_multiline
|
||||
|
||||
return is_yes
|
||||
|
||||
def prompt_ask(self, question, default="", subject=None):
|
||||
# Temporarily disable multiline mode for prompts
|
||||
orig_multiline = self.multiline_mode
|
||||
self.multiline_mode = False
|
||||
self.num_user_asks += 1
|
||||
|
||||
if subject:
|
||||
@@ -687,7 +785,12 @@ class InputOutput:
|
||||
res = "no"
|
||||
else:
|
||||
if self.prompt_session:
|
||||
res = self.prompt_session.prompt(question + " ", default=default, style=style)
|
||||
res = self.prompt_session.prompt(
|
||||
question + " ",
|
||||
default=default,
|
||||
style=style,
|
||||
complete_while_typing=True,
|
||||
)
|
||||
else:
|
||||
res = input(question + " ")
|
||||
|
||||
@@ -696,6 +799,9 @@ class InputOutput:
|
||||
if self.yes in (True, False):
|
||||
self.tool_output(hist)
|
||||
|
||||
# Restore original multiline mode
|
||||
self.multiline_mode = orig_multiline
|
||||
|
||||
return res
|
||||
|
||||
def _tool_message(self, message="", strip=True, color=None):
|
||||
@@ -707,9 +813,17 @@ class InputOutput:
|
||||
hist = message.strip() if strip else message
|
||||
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
||||
|
||||
message = Text(message)
|
||||
if not isinstance(message, Text):
|
||||
message = Text(message)
|
||||
style = dict(style=color) if self.pretty and color else dict()
|
||||
self.console.print(message, **style)
|
||||
try:
|
||||
self.console.print(message, **style)
|
||||
except UnicodeEncodeError:
|
||||
# Fallback to ASCII-safe output
|
||||
if isinstance(message, Text):
|
||||
message = message.plain
|
||||
message = str(message).encode("ascii", errors="replace").decode("ascii")
|
||||
self.console.print(message, **style)
|
||||
|
||||
def tool_error(self, message="", strip=True):
|
||||
self.num_error_outputs += 1
|
||||
@@ -765,6 +879,18 @@ class InputOutput:
|
||||
def print(self, message=""):
|
||||
print(message)
|
||||
|
||||
def toggle_multiline_mode(self):
|
||||
"""Toggle between normal and multiline input modes"""
|
||||
self.multiline_mode = not self.multiline_mode
|
||||
if self.multiline_mode:
|
||||
self.tool_output(
|
||||
"Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text"
|
||||
)
|
||||
else:
|
||||
self.tool_output(
|
||||
"Multiline mode: Disabled. Alt-Enter inserts newline, Enter submits text"
|
||||
)
|
||||
|
||||
def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True):
|
||||
if blockquote:
|
||||
if strip:
|
||||
@@ -806,7 +932,13 @@ class InputOutput:
|
||||
editable_files = [f for f in sorted(rel_fnames) if f not in rel_read_only_fnames]
|
||||
|
||||
if read_only_files:
|
||||
files_with_label = ["Readonly:"] + read_only_files
|
||||
# Use shorter of abs/rel paths for readonly files
|
||||
ro_paths = []
|
||||
for rel_path in read_only_files:
|
||||
abs_path = os.path.abspath(os.path.join(self.root, rel_path))
|
||||
ro_paths.append(abs_path if len(abs_path) < len(rel_path) else rel_path)
|
||||
|
||||
files_with_label = ["Readonly:"] + ro_paths
|
||||
read_only_output = StringIO()
|
||||
Console(file=read_only_output, force_terminal=False).print(Columns(files_with_label))
|
||||
read_only_lines = read_only_output.getvalue().splitlines()
|
||||
|
||||
@@ -11,6 +11,7 @@ from grep_ast import TreeContext, filename_to_lang
|
||||
from tree_sitter_languages import get_parser # noqa: E402
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
from aider.run_cmd import run_cmd_subprocess # noqa: F401
|
||||
|
||||
# tree_sitter is throwing a FutureWarning
|
||||
warnings.simplefilter("ignore", category=FutureWarning)
|
||||
@@ -44,26 +45,22 @@ class Linter:
|
||||
|
||||
def run_cmd(self, cmd, rel_fname, code):
|
||||
cmd += " " + rel_fname
|
||||
cmd = cmd.split()
|
||||
|
||||
returncode = 0
|
||||
stdout = ""
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
returncode, stdout = run_cmd_subprocess(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding=self.encoding,
|
||||
errors="replace",
|
||||
cwd=self.root,
|
||||
encoding=self.encoding,
|
||||
)
|
||||
except OSError as err:
|
||||
print(f"Unable to execute lint command: {err}")
|
||||
return
|
||||
stdout, _ = process.communicate()
|
||||
errors = stdout
|
||||
if process.returncode == 0:
|
||||
if returncode == 0:
|
||||
return # zero exit status
|
||||
|
||||
cmd = " ".join(cmd)
|
||||
res = f"## Running: {cmd}\n\n"
|
||||
res += errors
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
162
aider/main.py
162
aider/main.py
@@ -9,7 +9,11 @@ import webbrowser
|
||||
from dataclasses import fields
|
||||
from pathlib import Path
|
||||
|
||||
import git
|
||||
try:
|
||||
import git
|
||||
except ImportError:
|
||||
git = None
|
||||
|
||||
import importlib_resources
|
||||
from dotenv import load_dotenv
|
||||
from prompt_toolkit.enums import EditingMode
|
||||
@@ -20,6 +24,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 +33,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
|
||||
|
||||
@@ -91,6 +97,9 @@ def make_new_repo(git_root, io):
|
||||
|
||||
|
||||
def setup_git(git_root, io):
|
||||
if git is None:
|
||||
return
|
||||
|
||||
try:
|
||||
cwd = Path.cwd()
|
||||
except OSError:
|
||||
@@ -104,7 +113,9 @@ def setup_git(git_root, io):
|
||||
except ANY_GIT_ERROR:
|
||||
pass
|
||||
elif cwd == Path.home():
|
||||
io.tool_warning("You should probably run aider in a directory, not your home dir.")
|
||||
io.tool_warning(
|
||||
"You should probably run aider in your project's directory, not your home dir."
|
||||
)
|
||||
return
|
||||
elif cwd and io.confirm_ask(
|
||||
"No git repo found, create one to track aider's changes (recommended)?"
|
||||
@@ -164,7 +175,8 @@ def check_gitignore(git_root, io, ask=True):
|
||||
existing_lines = content.splitlines()
|
||||
for pat in patterns:
|
||||
if pat not in existing_lines:
|
||||
patterns_to_add.append(pat)
|
||||
if "*" in pat or (Path(git_root) / pat).exists():
|
||||
patterns_to_add.append(pat)
|
||||
except OSError as e:
|
||||
io.tool_error(f"Error when trying to read {gitignore_file}: {e}")
|
||||
return
|
||||
@@ -203,6 +215,22 @@ def check_streamlit_install(io):
|
||||
)
|
||||
|
||||
|
||||
def write_streamlit_credentials():
|
||||
from streamlit.file_util import get_streamlit_file_path
|
||||
|
||||
# See https://github.com/Aider-AI/aider/issues/772
|
||||
|
||||
credential_path = Path(get_streamlit_file_path()) / "credentials.toml"
|
||||
if not os.path.exists(credential_path):
|
||||
empty_creds = '[general]\nemail = ""\n'
|
||||
|
||||
os.makedirs(os.path.dirname(credential_path), exist_ok=True)
|
||||
with open(credential_path, "w") as f:
|
||||
f.write(empty_creds)
|
||||
else:
|
||||
print("Streamlit credentials already exist.")
|
||||
|
||||
|
||||
def launch_gui(args):
|
||||
from streamlit.web import cli
|
||||
|
||||
@@ -211,6 +239,9 @@ def launch_gui(args):
|
||||
print()
|
||||
print("CONTROL-C to exit...")
|
||||
|
||||
# Necessary so streamlit does not prompt the user for an email address.
|
||||
write_streamlit_credentials()
|
||||
|
||||
target = gui.__file__
|
||||
|
||||
st_args = ["run", target]
|
||||
@@ -348,18 +379,18 @@ def load_dotenv_files(git_root, dotenv_fname, encoding="utf-8"):
|
||||
|
||||
|
||||
def register_litellm_models(git_root, model_metadata_fname, io, verbose=False):
|
||||
model_metatdata_files = []
|
||||
model_metadata_files = []
|
||||
|
||||
# Add the resource file path
|
||||
resource_metadata = importlib_resources.files("aider.resources").joinpath("model-metadata.json")
|
||||
model_metatdata_files.append(str(resource_metadata))
|
||||
model_metadata_files.append(str(resource_metadata))
|
||||
|
||||
model_metatdata_files += generate_search_path_list(
|
||||
model_metadata_files += generate_search_path_list(
|
||||
".aider.model.metadata.json", git_root, model_metadata_fname
|
||||
)
|
||||
|
||||
try:
|
||||
model_metadata_files_loaded = models.register_litellm_models(model_metatdata_files)
|
||||
model_metadata_files_loaded = models.register_litellm_models(model_metadata_files)
|
||||
if len(model_metadata_files_loaded) > 0 and verbose:
|
||||
io.tool_output("Loaded model metadata from:")
|
||||
for model_metadata_file in model_metadata_files_loaded:
|
||||
@@ -383,6 +414,12 @@ def sanity_check_repo(repo, io):
|
||||
if not repo.git_repo_error:
|
||||
return True
|
||||
error_msg = str(repo.git_repo_error)
|
||||
except UnicodeDecodeError as exc:
|
||||
error_msg = (
|
||||
"Failed to read the Git repository. This issue is likely caused by a path encoded "
|
||||
f'in a format different from the expected encoding "{sys.getfilesystemencoding()}".\n'
|
||||
f"Internal error: {str(exc)}"
|
||||
)
|
||||
except ANY_GIT_ERROR as exc:
|
||||
error_msg = str(exc)
|
||||
bad_ver = "version in (1, 2)" in error_msg
|
||||
@@ -408,7 +445,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
if force_git_root:
|
||||
if git is None:
|
||||
git_root = None
|
||||
elif force_git_root:
|
||||
git_root = force_git_root
|
||||
else:
|
||||
git_root = get_git_root()
|
||||
@@ -455,6 +494,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
# Parse again to include any arguments that might have been defined in .env
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if git is None:
|
||||
args.git = False
|
||||
|
||||
if args.analytics_disable:
|
||||
analytics = Analytics(permanently_disable=True)
|
||||
print("Analytics have been permanently disabled.")
|
||||
@@ -513,6 +555,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
llm_history_file=args.llm_history_file,
|
||||
editingmode=editing_mode,
|
||||
fancy_input=args.fancy_input,
|
||||
multiline_mode=args.multiline,
|
||||
)
|
||||
|
||||
io = get_io(args.pretty)
|
||||
@@ -524,6 +567,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):
|
||||
@@ -566,7 +653,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:
|
||||
@@ -599,7 +686,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
# We can't know the git repo for sure until after parsing the args.
|
||||
# If we guessed wrong, reparse because that changes things like
|
||||
# the location of the config.yml and history files.
|
||||
if args.git and not force_git_root:
|
||||
if args.git and not force_git_root and git is not None:
|
||||
right_repo_root = guessed_wrong_repo(io, git_root, fnames, git_dname)
|
||||
if right_repo_root:
|
||||
analytics.event("exit", reason="Recursing with correct repo")
|
||||
@@ -644,20 +731,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)
|
||||
|
||||
@@ -686,6 +759,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))
|
||||
@@ -746,6 +823,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
commands = Commands(
|
||||
io,
|
||||
None,
|
||||
voice_language=args.voice_language,
|
||||
voice_input_device=args.voice_input_device,
|
||||
voice_format=args.voice_format,
|
||||
verify_ssl=args.verify_ssl,
|
||||
args=args,
|
||||
parser=parser,
|
||||
@@ -768,6 +848,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
)
|
||||
args.stream = False
|
||||
|
||||
if args.map_tokens is None:
|
||||
map_tokens = main_model.get_repo_map_tokens()
|
||||
else:
|
||||
map_tokens = args.map_tokens
|
||||
|
||||
try:
|
||||
coder = Coder.create(
|
||||
main_model=main_model,
|
||||
@@ -780,7 +865,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
auto_commits=args.auto_commits,
|
||||
dirty_commits=args.dirty_commits,
|
||||
dry_run=args.dry_run,
|
||||
map_tokens=args.map_tokens,
|
||||
map_tokens=map_tokens,
|
||||
verbose=args.verbose,
|
||||
stream=args.stream,
|
||||
use_git=args.git,
|
||||
@@ -799,6 +884,7 @@ 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))
|
||||
@@ -814,6 +900,26 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
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,
|
||||
root=str(Path.cwd()) if args.subtree_only else None,
|
||||
)
|
||||
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:
|
||||
@@ -833,9 +939,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
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:
|
||||
|
||||
@@ -10,10 +10,17 @@ from rich.text import Text
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
|
||||
_text = """
|
||||
_text_prefix = """
|
||||
# Header
|
||||
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
||||
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
|
||||
when an unknown printer took a galley of type and scrambled it to make a type
|
||||
specimen book. It has survived not only five centuries, but also the leap into
|
||||
electronic typesetting, remaining essentially unchanged. It was popularised in
|
||||
the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
|
||||
and more recently with desktop publishing software like Aldus PageMaker
|
||||
including versions of Lorem Ipsum.
|
||||
|
||||
|
||||
|
||||
@@ -27,10 +34,9 @@ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem
|
||||
|
||||
|
||||
```python
|
||||
import sys
|
||||
"""
|
||||
|
||||
def greeting():
|
||||
print("Hello world!")
|
||||
_text_suffix = """
|
||||
```
|
||||
|
||||
## Sub header too
|
||||
@@ -41,81 +47,146 @@ The end.
|
||||
|
||||
|
||||
class MarkdownStream:
|
||||
live = None
|
||||
when = 0
|
||||
min_delay = 0.050
|
||||
live_window = 6
|
||||
"""Streaming markdown renderer that progressively displays content with a live updating window.
|
||||
|
||||
Uses rich.console and rich.live to render markdown content with smooth scrolling
|
||||
and partial updates. Maintains a sliding window of visible content while streaming
|
||||
in new markdown text.
|
||||
"""
|
||||
|
||||
live = None # Rich Live display instance
|
||||
when = 0 # Timestamp of last update
|
||||
min_delay = 1.0 / 20 # Minimum time between updates (20fps)
|
||||
live_window = 6 # Number of lines to keep visible at bottom during streaming
|
||||
|
||||
def __init__(self, mdargs=None):
|
||||
self.printed = []
|
||||
"""Initialize the markdown stream.
|
||||
|
||||
Args:
|
||||
mdargs (dict, optional): Additional arguments to pass to rich Markdown renderer
|
||||
"""
|
||||
self.printed = [] # Stores lines that have already been printed
|
||||
|
||||
if mdargs:
|
||||
self.mdargs = mdargs
|
||||
else:
|
||||
self.mdargs = dict()
|
||||
|
||||
# Initialize rich Live display with empty text
|
||||
self.live = Live(Text(""), refresh_per_second=1.0 / self.min_delay)
|
||||
self.live.start()
|
||||
|
||||
def _render_markdown_to_lines(self, text):
|
||||
"""Render markdown text to a list of lines.
|
||||
|
||||
Args:
|
||||
text (str): Markdown text to render
|
||||
|
||||
Returns:
|
||||
list: List of rendered lines with line endings preserved
|
||||
"""
|
||||
# Render the markdown to a string buffer
|
||||
string_io = io.StringIO()
|
||||
console = Console(file=string_io, force_terminal=True)
|
||||
markdown = Markdown(text, **self.mdargs)
|
||||
console.print(markdown)
|
||||
output = string_io.getvalue()
|
||||
|
||||
# Split rendered output into lines
|
||||
return output.splitlines(keepends=True)
|
||||
|
||||
def __del__(self):
|
||||
"""Destructor to ensure Live display is properly cleaned up."""
|
||||
if self.live:
|
||||
try:
|
||||
self.live.stop()
|
||||
except Exception:
|
||||
pass
|
||||
pass # Ignore any errors during cleanup
|
||||
|
||||
def update(self, text, final=False):
|
||||
"""Update the displayed markdown content.
|
||||
|
||||
Args:
|
||||
text (str): The markdown text received so far
|
||||
final (bool): If True, this is the final update and we should clean up
|
||||
|
||||
Splits the output into "stable" older lines and the "last few" lines
|
||||
which aren't considered stable. They may shift around as new chunks
|
||||
are appended to the markdown text.
|
||||
|
||||
The stable lines emit to the console above the Live window.
|
||||
The unstable lines emit into the Live window so they can be repainted.
|
||||
|
||||
Markdown going to the console works better in terminal scrollback buffers.
|
||||
The live window doesn't play nice with terminal scrollback.
|
||||
"""
|
||||
now = time.time()
|
||||
# Throttle updates to maintain smooth rendering
|
||||
if not final and now - self.when < self.min_delay:
|
||||
return
|
||||
self.when = now
|
||||
|
||||
string_io = io.StringIO()
|
||||
console = Console(file=string_io, force_terminal=True)
|
||||
# Measure render time and adjust min_delay to maintain smooth rendering
|
||||
start = time.time()
|
||||
lines = self._render_markdown_to_lines(text)
|
||||
render_time = time.time() - start
|
||||
|
||||
markdown = Markdown(text, **self.mdargs)
|
||||
# Set min_delay to render time plus a small buffer
|
||||
self.min_delay = min(max(render_time * 10, 1.0 / 20), 2)
|
||||
|
||||
console.print(markdown)
|
||||
output = string_io.getvalue()
|
||||
|
||||
lines = output.splitlines(keepends=True)
|
||||
num_lines = len(lines)
|
||||
|
||||
# How many lines have "left" the live window and are now considered stable?
|
||||
# Or if final, consider all lines to be stable.
|
||||
if not final:
|
||||
num_lines -= self.live_window
|
||||
|
||||
# If we have stable content to display...
|
||||
if final or num_lines > 0:
|
||||
# How many stable lines do we need to newly show above the live window?
|
||||
num_printed = len(self.printed)
|
||||
|
||||
show = num_lines - num_printed
|
||||
|
||||
# Skip if no new lines to show above live window
|
||||
if show <= 0:
|
||||
return
|
||||
|
||||
# Get the new lines and display them
|
||||
show = lines[num_printed:num_lines]
|
||||
show = "".join(show)
|
||||
show = Text.from_ansi(show)
|
||||
self.live.console.print(show)
|
||||
self.live.console.print(show) # to the console above the live area
|
||||
|
||||
# Update our record of printed lines
|
||||
self.printed = lines[:num_lines]
|
||||
|
||||
# Handle final update cleanup
|
||||
if final:
|
||||
self.live.update(Text(""))
|
||||
self.live.stop()
|
||||
self.live = None
|
||||
else:
|
||||
rest = lines[num_lines:]
|
||||
rest = "".join(rest)
|
||||
# rest = '...\n' + rest
|
||||
rest = Text.from_ansi(rest)
|
||||
self.live.update(rest)
|
||||
return
|
||||
|
||||
# Update the live window with remaining lines
|
||||
rest = lines[num_lines:]
|
||||
rest = "".join(rest)
|
||||
rest = Text.from_ansi(rest)
|
||||
self.live.update(rest)
|
||||
|
||||
def find_minimal_suffix(self, text, match_lines=50):
|
||||
"""
|
||||
Splits text into chunks on blank lines "\n\n".
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_text = 5 * _text
|
||||
with open("aider/io.py", "r") as f:
|
||||
code = f.read()
|
||||
_text = _text_prefix + code + _text_suffix
|
||||
_text = _text * 10
|
||||
|
||||
pm = MarkdownStream()
|
||||
for i in range(6, len(_text)):
|
||||
for i in range(6, len(_text), 5):
|
||||
pm.update(_text[:i])
|
||||
time.sleep(0.01)
|
||||
|
||||
|
||||
@@ -69,13 +69,14 @@ MODEL_ALIASES = {
|
||||
"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",
|
||||
"deepseek": "deepseek/deepseek-chat",
|
||||
"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",
|
||||
@@ -643,6 +665,13 @@ MODEL_SETTINGS = [
|
||||
examples_as_sys_msg=True,
|
||||
reminder="sys",
|
||||
),
|
||||
ModelSettings(
|
||||
"openrouter/deepseek/deepseek-chat",
|
||||
"diff",
|
||||
use_repo_map=True,
|
||||
examples_as_sys_msg=True,
|
||||
reminder="sys",
|
||||
),
|
||||
ModelSettings(
|
||||
"openrouter/openai/gpt-4o",
|
||||
"diff",
|
||||
@@ -742,6 +771,39 @@ MODEL_SETTINGS = [
|
||||
use_temperature=False,
|
||||
streaming=False,
|
||||
),
|
||||
ModelSettings(
|
||||
"openrouter/openai/o1",
|
||||
"diff",
|
||||
weak_model_name="openrouter/openai/gpt-4o-mini",
|
||||
editor_model_name="openrouter/openai/gpt-4o",
|
||||
editor_edit_format="editor-diff",
|
||||
use_repo_map=True,
|
||||
streaming=False,
|
||||
use_temperature=False,
|
||||
# extra_params=dict(extra_body=dict(reasoning_effort="high")),
|
||||
),
|
||||
ModelSettings(
|
||||
"openai/o1",
|
||||
"diff",
|
||||
weak_model_name="openai/gpt-4o-mini",
|
||||
editor_model_name="openai/gpt-4o",
|
||||
editor_edit_format="editor-diff",
|
||||
use_repo_map=True,
|
||||
streaming=False,
|
||||
use_temperature=False,
|
||||
# extra_params=dict(extra_body=dict(reasoning_effort="high")),
|
||||
),
|
||||
ModelSettings(
|
||||
"o1",
|
||||
"diff",
|
||||
weak_model_name="gpt-4o-mini",
|
||||
editor_model_name="gpt-4o",
|
||||
editor_edit_format="editor-diff",
|
||||
use_repo_map=True,
|
||||
streaming=False,
|
||||
use_temperature=False,
|
||||
# extra_params=dict(extra_body=dict(reasoning_effort="high")),
|
||||
),
|
||||
ModelSettings(
|
||||
"openrouter/qwen/qwen-2.5-coder-32b-instruct",
|
||||
"diff",
|
||||
@@ -858,10 +920,9 @@ class Model(ModelSettings):
|
||||
self.keys_in_environment = res.get("keys_in_environment")
|
||||
|
||||
max_input_tokens = self.info.get("max_input_tokens") or 0
|
||||
if max_input_tokens < 32 * 1024:
|
||||
self.max_chat_history_tokens = 1024
|
||||
else:
|
||||
self.max_chat_history_tokens = 2 * 1024
|
||||
# Calculate max_chat_history_tokens as 1/16th of max_input_tokens,
|
||||
# with minimum 1k and maximum 8k
|
||||
self.max_chat_history_tokens = min(max(max_input_tokens / 16, 1024), 8192)
|
||||
|
||||
self.configure_model_settings(model)
|
||||
if weak_model is False:
|
||||
@@ -1116,6 +1177,15 @@ class Model(ModelSettings):
|
||||
|
||||
return res
|
||||
|
||||
def get_repo_map_tokens(self):
|
||||
map_tokens = 1024
|
||||
max_inp_tokens = self.info.get("max_input_tokens")
|
||||
if max_inp_tokens:
|
||||
map_tokens = max_inp_tokens / 8
|
||||
map_tokens = min(map_tokens, 4096)
|
||||
map_tokens = max(map_tokens, 1024)
|
||||
return map_tokens
|
||||
|
||||
|
||||
def register_models(model_settings_fnames):
|
||||
files_loaded = []
|
||||
@@ -1210,10 +1280,10 @@ def sanity_check_model(io, model):
|
||||
status = "Set" if value else "Not set"
|
||||
io.tool_output(f"- {key}: {status}")
|
||||
|
||||
if platform.system() == "Windows" or True:
|
||||
if platform.system() == "Windows":
|
||||
io.tool_output(
|
||||
"If you just set these environment variables using `setx` you may need to restart"
|
||||
" your terminal or command prompt for the changes to take effect."
|
||||
"Note: You may need to restart your terminal or command prompt for `setx` to take"
|
||||
" effect."
|
||||
)
|
||||
|
||||
elif not model.keys_in_environment:
|
||||
|
||||
@@ -2,7 +2,18 @@ import os
|
||||
import time
|
||||
from pathlib import Path, PurePosixPath
|
||||
|
||||
import git
|
||||
try:
|
||||
import git
|
||||
|
||||
ANY_GIT_ERROR = [
|
||||
git.exc.ODBError,
|
||||
git.exc.GitError,
|
||||
git.exc.InvalidGitRepositoryError,
|
||||
]
|
||||
except ImportError:
|
||||
git = None
|
||||
ANY_GIT_ERROR = []
|
||||
|
||||
import pathspec
|
||||
|
||||
from aider import prompts, utils
|
||||
@@ -10,15 +21,16 @@ from aider.sendchat import simple_send_with_retries
|
||||
|
||||
from .dump import dump # noqa: F401
|
||||
|
||||
ANY_GIT_ERROR = (
|
||||
git.exc.ODBError,
|
||||
git.exc.GitError,
|
||||
ANY_GIT_ERROR += [
|
||||
OSError,
|
||||
IndexError,
|
||||
BufferError,
|
||||
TypeError,
|
||||
ValueError,
|
||||
)
|
||||
AttributeError,
|
||||
AssertionError,
|
||||
]
|
||||
ANY_GIT_ERROR = tuple(ANY_GIT_ERROR)
|
||||
|
||||
|
||||
class GitRepo:
|
||||
@@ -192,9 +204,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
|
||||
|
||||
@@ -278,9 +288,17 @@ class GitRepo:
|
||||
files = self.tree_files[commit]
|
||||
else:
|
||||
try:
|
||||
for blob in commit.tree.traverse():
|
||||
if blob.type == "blob": # blob is a file
|
||||
files.add(blob.path)
|
||||
iterator = commit.tree.traverse()
|
||||
while True:
|
||||
try:
|
||||
blob = next(iterator)
|
||||
if blob.type == "blob": # blob is a file
|
||||
files.add(blob.path)
|
||||
except IndexError:
|
||||
self.io.tool_warning(f"GitRepo: read error skipping {blob.path}")
|
||||
continue
|
||||
except StopIteration:
|
||||
break
|
||||
except ANY_GIT_ERROR as err:
|
||||
self.git_repo_error = err
|
||||
self.io.tool_error(f"Unable to list files in git repo: {err}")
|
||||
@@ -352,8 +370,8 @@ class GitRepo:
|
||||
|
||||
def ignored_file_raw(self, fname):
|
||||
if self.subtree_only:
|
||||
fname_path = Path(self.normalize_path(fname))
|
||||
try:
|
||||
fname_path = Path(self.normalize_path(fname))
|
||||
cwd_path = Path.cwd().resolve().relative_to(Path(self.root).resolve())
|
||||
except ValueError:
|
||||
# Issue #1524
|
||||
|
||||
@@ -605,7 +605,7 @@ class RepoMap:
|
||||
|
||||
self.tree_cache = dict()
|
||||
|
||||
middle = min(max_map_tokens // 25, num_tags)
|
||||
middle = min(int(max_map_tokens // 25), num_tags)
|
||||
while lower_bound <= upper_bound:
|
||||
# dump(lower_bound, middle, upper_bound)
|
||||
|
||||
@@ -628,7 +628,7 @@ class RepoMap:
|
||||
else:
|
||||
upper_bound = middle - 1
|
||||
|
||||
middle = (lower_bound + upper_bound) // 2
|
||||
middle = int((lower_bound + upper_bound) // 2)
|
||||
|
||||
spin.end()
|
||||
return best_tree
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ def get_windows_parent_process_name():
|
||||
return None
|
||||
|
||||
|
||||
def run_cmd_subprocess(command, verbose=False, cwd=None):
|
||||
def run_cmd_subprocess(command, verbose=False, cwd=None, encoding=sys.stdout.encoding):
|
||||
if verbose:
|
||||
print("Using run_cmd_subprocess:", command)
|
||||
|
||||
@@ -65,7 +65,7 @@ def run_cmd_subprocess(command, verbose=False, cwd=None):
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
shell=True,
|
||||
encoding=sys.stdout.encoding,
|
||||
encoding=encoding,
|
||||
errors="replace",
|
||||
bufsize=0, # Set bufsize to 0 for unbuffered output
|
||||
universal_newlines=True,
|
||||
@@ -113,7 +113,7 @@ def run_cmd_pexpect(command, verbose=False, cwd=None):
|
||||
# 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", cwd=cwd)
|
||||
child = pexpect.spawn(shell, args=["-i", "-c", command], encoding="utf-8", cwd=cwd)
|
||||
else:
|
||||
# Fall back to spawning the command directly
|
||||
if verbose:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -2,15 +2,12 @@ import itertools
|
||||
import os
|
||||
import platform
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import git
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
|
||||
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp", ".pdf"}
|
||||
@@ -74,6 +71,8 @@ class GitTemporaryDirectory(ChdirTemporaryDirectory):
|
||||
|
||||
|
||||
def make_repo(path=None):
|
||||
import git
|
||||
|
||||
if not path:
|
||||
path = "."
|
||||
repo = git.Repo.init(path)
|
||||
@@ -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):
|
||||
@@ -301,12 +300,15 @@ class Spinner:
|
||||
|
||||
|
||||
def find_common_root(abs_fnames):
|
||||
if len(abs_fnames) == 1:
|
||||
return safe_abs_path(os.path.dirname(list(abs_fnames)[0]))
|
||||
elif abs_fnames:
|
||||
return safe_abs_path(os.path.commonpath(list(abs_fnames)))
|
||||
else:
|
||||
return safe_abs_path(os.getcwd())
|
||||
try:
|
||||
if len(abs_fnames) == 1:
|
||||
return safe_abs_path(os.path.dirname(list(abs_fnames)[0]))
|
||||
elif abs_fnames:
|
||||
return safe_abs_path(os.path.commonpath(list(abs_fnames)))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
return safe_abs_path(os.getcwd())
|
||||
|
||||
|
||||
def format_tokens(count):
|
||||
@@ -382,3 +384,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()
|
||||
|
||||
@@ -14,8 +14,11 @@ 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
|
||||
from pydub.exceptions import CouldntDecodeError, CouldntEncodeError # noqa
|
||||
|
||||
try:
|
||||
import soundfile as sf
|
||||
@@ -43,7 +46,6 @@ class Voice:
|
||||
|
||||
self.sd = sd
|
||||
|
||||
|
||||
devices = sd.query_devices()
|
||||
|
||||
if device_name:
|
||||
@@ -55,7 +57,10 @@ class Voice:
|
||||
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: {available_inputs}")
|
||||
raise ValueError(
|
||||
f"Device '{device_name}' not found. Available input devices:"
|
||||
f" {available_inputs}"
|
||||
)
|
||||
|
||||
print(f"Using input device: {device_name} (ID: {device_id})")
|
||||
|
||||
@@ -125,7 +130,9 @@ class Voice:
|
||||
self.start_time = time.time()
|
||||
|
||||
try:
|
||||
with self.sd.InputStream(samplerate=sample_rate, channels=1, callback=self.callback, device=self.device_id):
|
||||
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}")
|
||||
@@ -134,13 +141,28 @@ class Voice:
|
||||
while not self.q.empty():
|
||||
file.write(self.q.get())
|
||||
|
||||
if self.audio_format != "wav":
|
||||
filename = tempfile.mktemp(suffix=f".{self.audio_format}")
|
||||
audio = AudioSegment.from_wav(temp_wav)
|
||||
audio.export(filename, format=self.audio_format)
|
||||
os.remove(temp_wav)
|
||||
else:
|
||||
filename = temp_wav
|
||||
use_audio_format = self.audio_format
|
||||
|
||||
# Check file size and offer to convert to mp3 if too large
|
||||
file_size = os.path.getsize(temp_wav)
|
||||
if file_size > 24.9 * 1024 * 1024 and self.audio_format == "wav":
|
||||
print("\nWarning: {temp_wav} is too large, switching to mp3 format.")
|
||||
use_audio_format = "mp3"
|
||||
|
||||
filename = temp_wav
|
||||
if use_audio_format != "wav":
|
||||
try:
|
||||
new_filename = tempfile.mktemp(suffix=f".{use_audio_format}")
|
||||
audio = AudioSegment.from_wav(temp_wav)
|
||||
audio.export(new_filename, format=use_audio_format)
|
||||
os.remove(temp_wav)
|
||||
filename = new_filename
|
||||
except (CouldntDecodeError, CouldntEncodeError) as e:
|
||||
print(f"Error converting audio: {e}")
|
||||
except (OSError, FileNotFoundError) as e:
|
||||
print(f"File system error during conversion: {e}")
|
||||
except Exception as e:
|
||||
print(f"Unexpected error during audio conversion: {e}")
|
||||
|
||||
with open(filename, "rb") as fh:
|
||||
try:
|
||||
@@ -151,7 +173,7 @@ class Voice:
|
||||
print(f"Unable to transcribe {filename}: {err}")
|
||||
return
|
||||
|
||||
if self.audio_format != "wav":
|
||||
if filename != temp_wav:
|
||||
os.remove(filename)
|
||||
|
||||
text = transcript.text
|
||||
|
||||
281
aider/watch.py
Normal file
281
aider/watch.py
Normal file
@@ -0,0 +1,281 @@
|
||||
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, root=None):
|
||||
self.coder = coder
|
||||
self.io = coder.io
|
||||
self.root = Path(root) if root else 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
|
||||
added = False
|
||||
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)
|
||||
if not added:
|
||||
self.io.tool_output()
|
||||
added = True
|
||||
self.io.tool_output(f"Added {rel_fname} to the chat")
|
||||
|
||||
if not has_action:
|
||||
if added:
|
||||
self.io.tool_output(
|
||||
"End your comment with AI! to request changes or AI? to ask questions"
|
||||
)
|
||||
return ""
|
||||
|
||||
if self.analytics:
|
||||
self.analytics.event("ai-comments execute")
|
||||
self.io.tool_output("Processing your request...")
|
||||
|
||||
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)
|
||||
if not content:
|
||||
return None, None, None
|
||||
|
||||
for i, line in enumerate(content.splitlines(), 1):
|
||||
if match := self.ai_comment_pattern.search(line):
|
||||
comment = match.group(0).strip()
|
||||
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()
|
||||
12
aider/watch_prompts.py
Normal file
12
aider/watch_prompts.py
Normal file
@@ -0,0 +1,12 @@
|
||||
watch_code_prompt = """
|
||||
I've written your instructions in comments in the code and marked them with "ai"
|
||||
You can see the "AI" comments shown below (marked with █).
|
||||
Find them in the code files I've shared with you, and follow their instructions.
|
||||
|
||||
After completing those instructions, also be sure to remove all the "AI" comments from the code too.
|
||||
"""
|
||||
|
||||
watch_ask_prompt = """/ask
|
||||
Find the "AI" comments below (marked with █) in the code files I've shared with you.
|
||||
They contain my questions that I need you to answer and other instructions for you.
|
||||
"""
|
||||
@@ -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,110 @@ cog.out(text)
|
||||
]]]-->
|
||||
|
||||
|
||||
### main branch
|
||||
### Aider v0.71.1
|
||||
|
||||
- Fix permissions issue in Docker images.
|
||||
- Added read-only file announcements to chat.
|
||||
- Bugfix: ASCII fallback for unicode errors.
|
||||
- Bugfix: integer indices for list slicing in repomap calculations.
|
||||
- Aider wrote 83% of the code in this release.
|
||||
|
||||
### Aider v0.71.0
|
||||
|
||||
- Prompts to help DeepSeek work better when alternating between `/ask` and `/code`.
|
||||
- Streaming pretty LLM responses is smoother and faster for long replies.
|
||||
- Streaming automatically turns of for model that don't support it
|
||||
- Can now switch to/from `/model o1` and a streaming model
|
||||
- Pretty output remains enabled even when editing files with triple-backtick fences
|
||||
- Bare `/ask`, `/code` and `/architect` commands now switch the chat mode.
|
||||
- Increased default size of the repomap.
|
||||
- Increased max chat history tokens limit from 4k to 8k.
|
||||
- Turn off fancy input and watch files if terminal is dumb.
|
||||
- Added support for custom voice format and input device settings.
|
||||
- Disabled Streamlit email prompt, by apaz-cli.
|
||||
- Docker container runs as non-root user.
|
||||
- Fixed lint command handling of nested spaced strings, by Aaron Weisberg.
|
||||
- Added token count feedback when adding command output to chat.
|
||||
- Improved error handling for large audio files with automatic format conversion.
|
||||
- Improved handling of git repo index errors, by Krazer.
|
||||
- Improved unicode handling in console output with ASCII fallback.
|
||||
- Added AssertionError, AttributeError to git error handling.
|
||||
- Aider wrote 60% of the code in this release.
|
||||
|
||||
### Aider v0.70.0
|
||||
|
||||
- Full support for o1 models.
|
||||
- Watch files now honors `--subtree-only`, and only watches that subtree.
|
||||
- Improved prompting for watch files, to work more reliably with more models.
|
||||
- New install methods via uv, including one-liners.
|
||||
- Support for openrouter/deepseek/deepseek-chat model.
|
||||
- Better error handling when interactive commands are attempted via `/load` or `--load`.
|
||||
- Display read-only files with abs path if its shorter than rel path.
|
||||
- Ask 10% of users to opt-in to analytics.
|
||||
- Bugfix for auto-suggest.
|
||||
- Gracefully handle unicode errors in git path names.
|
||||
- Aider wrote 74% of the code in this release.
|
||||
|
||||
### Aider v0.69.1
|
||||
|
||||
- Fix for gemini model names in model metadata.
|
||||
- Show hints about AI! and AI? when user makes AI comments.
|
||||
- Support for running without git installed.
|
||||
- Improved environment variable setup messages on Windows.
|
||||
|
||||
### Aider v0.69.0
|
||||
|
||||
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
|
||||
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
|
||||
- Now watches *all* files, not just certain source files.
|
||||
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
|
||||
- Full support for Gemini Flash 2.0 Exp:
|
||||
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
|
||||
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
|
||||
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
|
||||
- Improved clipboard error handling with helpful requirements install info.
|
||||
- Ask 5% of users if they want to opt-in to analytics.
|
||||
- `/voice` now lets you edit the transcribed text before sending.
|
||||
- Disabled auto-complete in Y/N prompts.
|
||||
- Aider wrote 68% of the code in this release.
|
||||
|
||||
### Aider v0.68.0
|
||||
|
||||
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
|
||||
- New `--copy-paste` mode.
|
||||
- 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.
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
theme: just-the-docs
|
||||
url: "https://aider.chat"
|
||||
|
||||
# Analytics configuration
|
||||
analytics:
|
||||
enabled: false # Single switch to control analytics and cookie consent
|
||||
posthog_key: 'phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv'
|
||||
posthog_host: 'https://us.i.posthog.com'
|
||||
|
||||
plugins:
|
||||
- jekyll-redirect-from
|
||||
- jekyll-sitemap
|
||||
@@ -45,4 +51,4 @@ callouts:
|
||||
note:
|
||||
title: Note
|
||||
color: yellow
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -2020,3 +2020,213 @@
|
||||
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
|
||||
|
||||
- dirname: 2024-12-18-01-50-08--o1
|
||||
test_cases: 133
|
||||
model: o1
|
||||
edit_format: diff
|
||||
commit_hash: 074c636-dirty
|
||||
pass_rate_1: 65.4
|
||||
pass_rate_2: 84.2
|
||||
percent_cases_well_formed: 99.2
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 0
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
command: aider --model openrouter/openai/o1
|
||||
date: 2024-12-18
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 29.9
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-21-22-06-01--polyglot-o1-mini-whole
|
||||
test_cases: 225
|
||||
model: o1-mini-2024-09-12
|
||||
edit_format: whole
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 8.9
|
||||
pass_rate_2: 27.1
|
||||
pass_num_1: 20
|
||||
pass_num_2: 61
|
||||
percent_cases_well_formed: 95.6
|
||||
error_outputs: 15
|
||||
num_malformed_responses: 14
|
||||
num_with_malformed_responses: 10
|
||||
user_asks: 37
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model o1-mini
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.3
|
||||
total_cost: 17.6270
|
||||
259
aider/website/_data/o1_polyglot_leaderboard.yml
Normal file
259
aider/website/_data/o1_polyglot_leaderboard.yml
Normal file
@@ -0,0 +1,259 @@
|
||||
- dirname: 2024-12-21-18-41-18--polyglot-gpt-4o-mini
|
||||
test_cases: 225
|
||||
model: gpt-4o-mini-2024-07-18
|
||||
edit_format: whole
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 0.9
|
||||
pass_rate_2: 3.6
|
||||
pass_num_1: 2
|
||||
pass_num_2: 8
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 36
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-mini-2024-07-18
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 17.3
|
||||
total_cost: 0.3236
|
||||
|
||||
- dirname: 2024-12-21-18-44-28--polyglot-sonnet
|
||||
test_cases: 225
|
||||
model: claude-3-5-sonnet-20241022
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 18.7
|
||||
pass_rate_2: 45.3
|
||||
pass_num_1: 42
|
||||
pass_num_2: 102
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 14
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 12
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-sonnet-20241022
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 30.8
|
||||
total_cost: 13.4847
|
||||
|
||||
- dirname: 2024-12-21-18-52-34--polyglot-gpt-4o-diff
|
||||
test_cases: 225
|
||||
model: gpt-4o-2024-11-20
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 4.9
|
||||
pass_rate_2: 15.1
|
||||
pass_num_1: 11
|
||||
pass_num_2: 34
|
||||
percent_cases_well_formed: 96.0
|
||||
error_outputs: 12
|
||||
num_malformed_responses: 11
|
||||
num_with_malformed_responses: 9
|
||||
user_asks: 34
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 19
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-2024-11-20
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 22.2
|
||||
total_cost: 7.1835
|
||||
|
||||
- dirname: 2024-12-21-19-23-03--polyglot-o1-hard-diff
|
||||
test_cases: 224
|
||||
model: o1-2024-12-17 (high)
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 23.7
|
||||
pass_rate_2: 61.7
|
||||
pass_num_1: 53
|
||||
pass_num_2: 139
|
||||
percent_cases_well_formed: 91.5
|
||||
error_outputs: 25
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 19
|
||||
user_asks: 16
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model openrouter/openai/o1
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 133.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-21-20-56-21--polyglot-deepseek-diff
|
||||
test_cases: 225
|
||||
model: DeepSeek Chat V2.5
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 5.3
|
||||
pass_rate_2: 17.8
|
||||
pass_num_1: 12
|
||||
pass_num_2: 40
|
||||
percent_cases_well_formed: 92.9
|
||||
error_outputs: 42
|
||||
num_malformed_responses: 37
|
||||
num_with_malformed_responses: 16
|
||||
user_asks: 23
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 5
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-chat
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 184.0
|
||||
total_cost: 0.5101
|
||||
|
||||
- dirname: 2024-12-21-21-46-27--polyglot-haiku-diff
|
||||
test_cases: 225
|
||||
model: claude-3-5-haiku-20241022
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 7.1
|
||||
pass_rate_2: 28.0
|
||||
pass_num_1: 16
|
||||
pass_num_2: 63
|
||||
percent_cases_well_formed: 91.1
|
||||
error_outputs: 31
|
||||
num_malformed_responses: 30
|
||||
num_with_malformed_responses: 20
|
||||
user_asks: 13
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-haiku-20241022
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 31.8
|
||||
total_cost: 6.0583
|
||||
|
||||
- dirname: 2024-12-22-13-22-32--polyglot-qwen-diff
|
||||
test_cases: 225
|
||||
model: Qwen2.5-Coder-32B-Instruct
|
||||
edit_format: diff
|
||||
commit_hash: 6d7e8be-dirty
|
||||
pass_rate_1: 4.4
|
||||
pass_rate_2: 8.0
|
||||
pass_num_1: 10
|
||||
pass_num_2: 18
|
||||
percent_cases_well_formed: 71.6
|
||||
error_outputs: 158
|
||||
num_malformed_responses: 148
|
||||
num_with_malformed_responses: 64
|
||||
user_asks: 132
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: "aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct # via hyperbolic"
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 84.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-21-26-35--polyglot-o1mini-whole
|
||||
test_cases: 225
|
||||
model: o1-mini-2024-09-12
|
||||
edit_format: whole
|
||||
commit_hash: 37df899
|
||||
pass_rate_1: 5.8
|
||||
pass_rate_2: 32.9
|
||||
pass_num_1: 13
|
||||
pass_num_2: 74
|
||||
percent_cases_well_formed: 96.9
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 27
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model o1-mini
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.7
|
||||
total_cost: 18.5770
|
||||
|
||||
- dirname: 2024-12-22-18-43-25--gemini-exp-1206-polyglot-whole-2
|
||||
test_cases: 225
|
||||
model: gemini-exp-1206
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 19.6
|
||||
pass_rate_2: 38.2
|
||||
pass_num_1: 44
|
||||
pass_num_2: 86
|
||||
percent_cases_well_formed: 98.2
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 4
|
||||
user_asks: 32
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-exp-1206
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 45.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-20-08-13--gemini-2.0-flash-exp-polyglot-whole
|
||||
test_cases: 225
|
||||
model: gemini-2.0-flash-exp
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 11.6
|
||||
pass_rate_2: 22.2
|
||||
pass_num_1: 26
|
||||
pass_num_2: 50
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 9
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-2.0-flash-exp
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 12.2
|
||||
total_cost: 0.0000
|
||||
338
aider/website/_data/polyglot_leaderboard.yml
Normal file
338
aider/website/_data/polyglot_leaderboard.yml
Normal file
@@ -0,0 +1,338 @@
|
||||
- dirname: 2024-12-21-18-41-18--polyglot-gpt-4o-mini
|
||||
test_cases: 225
|
||||
model: gpt-4o-mini-2024-07-18
|
||||
edit_format: whole
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 0.9
|
||||
pass_rate_2: 3.6
|
||||
pass_num_1: 2
|
||||
pass_num_2: 8
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 36
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-mini-2024-07-18
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 17.3
|
||||
total_cost: 0.3236
|
||||
|
||||
- dirname: 2024-12-21-18-44-28--polyglot-sonnet
|
||||
test_cases: 225
|
||||
model: claude-3-5-sonnet-20241022
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 18.7
|
||||
pass_rate_2: 45.3
|
||||
pass_num_1: 42
|
||||
pass_num_2: 102
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 14
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 12
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-sonnet-20241022
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 30.8
|
||||
total_cost: 13.4847
|
||||
|
||||
- dirname: 2024-12-21-18-52-34--polyglot-gpt-4o-diff
|
||||
test_cases: 225
|
||||
model: gpt-4o-2024-11-20
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 4.9
|
||||
pass_rate_2: 15.1
|
||||
pass_num_1: 11
|
||||
pass_num_2: 34
|
||||
percent_cases_well_formed: 96.0
|
||||
error_outputs: 12
|
||||
num_malformed_responses: 11
|
||||
num_with_malformed_responses: 9
|
||||
user_asks: 34
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 19
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-2024-11-20
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 22.2
|
||||
total_cost: 7.1835
|
||||
|
||||
- dirname: 2024-12-21-19-23-03--polyglot-o1-hard-diff
|
||||
test_cases: 224
|
||||
model: o1-2024-12-17 (high)
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 23.7
|
||||
pass_rate_2: 61.7
|
||||
pass_num_1: 53
|
||||
pass_num_2: 139
|
||||
percent_cases_well_formed: 91.5
|
||||
error_outputs: 25
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 19
|
||||
user_asks: 16
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model openrouter/openai/o1
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 133.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-21-20-56-21--polyglot-deepseek-diff
|
||||
test_cases: 225
|
||||
model: DeepSeek Chat V2.5
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 5.3
|
||||
pass_rate_2: 17.8
|
||||
pass_num_1: 12
|
||||
pass_num_2: 40
|
||||
percent_cases_well_formed: 92.9
|
||||
error_outputs: 42
|
||||
num_malformed_responses: 37
|
||||
num_with_malformed_responses: 16
|
||||
user_asks: 23
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 5
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-chat
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 184.0
|
||||
total_cost: 0.5101
|
||||
|
||||
- dirname: 2024-12-21-21-46-27--polyglot-haiku-diff
|
||||
test_cases: 225
|
||||
model: claude-3-5-haiku-20241022
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 7.1
|
||||
pass_rate_2: 28.0
|
||||
pass_num_1: 16
|
||||
pass_num_2: 63
|
||||
percent_cases_well_formed: 91.1
|
||||
error_outputs: 31
|
||||
num_malformed_responses: 30
|
||||
num_with_malformed_responses: 20
|
||||
user_asks: 13
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-haiku-20241022
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 31.8
|
||||
total_cost: 6.0583
|
||||
|
||||
- dirname: 2024-12-22-13-22-32--polyglot-qwen-diff
|
||||
test_cases: 225
|
||||
model: Qwen2.5-Coder-32B-Instruct
|
||||
edit_format: diff
|
||||
commit_hash: 6d7e8be-dirty
|
||||
pass_rate_1: 4.4
|
||||
pass_rate_2: 8.0
|
||||
pass_num_1: 10
|
||||
pass_num_2: 18
|
||||
percent_cases_well_formed: 71.6
|
||||
error_outputs: 158
|
||||
num_malformed_responses: 148
|
||||
num_with_malformed_responses: 64
|
||||
user_asks: 132
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: "aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct # via hyperbolic"
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 84.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-21-26-35--polyglot-o1mini-whole
|
||||
test_cases: 225
|
||||
model: o1-mini-2024-09-12
|
||||
edit_format: whole
|
||||
commit_hash: 37df899
|
||||
pass_rate_1: 5.8
|
||||
pass_rate_2: 32.9
|
||||
pass_num_1: 13
|
||||
pass_num_2: 74
|
||||
percent_cases_well_formed: 96.9
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 27
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model o1-mini
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.7
|
||||
total_cost: 18.5770
|
||||
|
||||
- dirname: 2024-12-22-18-43-25--gemini-exp-1206-polyglot-whole-2
|
||||
test_cases: 225
|
||||
model: gemini-exp-1206
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 19.6
|
||||
pass_rate_2: 38.2
|
||||
pass_num_1: 44
|
||||
pass_num_2: 86
|
||||
percent_cases_well_formed: 98.2
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 4
|
||||
user_asks: 32
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-exp-1206
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 45.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-20-08-13--gemini-2.0-flash-exp-polyglot-whole
|
||||
test_cases: 225
|
||||
model: gemini-2.0-flash-exp
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 11.6
|
||||
pass_rate_2: 22.2
|
||||
pass_num_1: 26
|
||||
pass_num_2: 50
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 9
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-2.0-flash-exp
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 12.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-23-01-11-56--yi-test
|
||||
test_cases: 225
|
||||
model: yi-lightning
|
||||
edit_format: whole
|
||||
commit_hash: 2b1625e
|
||||
pass_rate_1: 5.8
|
||||
pass_rate_2: 12.9
|
||||
pass_num_1: 13
|
||||
pass_num_2: 29
|
||||
percent_cases_well_formed: 92.9
|
||||
error_outputs: 87
|
||||
num_malformed_responses: 72
|
||||
num_with_malformed_responses: 16
|
||||
user_asks: 107
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 6
|
||||
total_tests: 225
|
||||
command: aider --model openai/yi-lightning
|
||||
date: 2024-12-23
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 146.7
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-25-13-31-51--deepseekv3preview-diff2
|
||||
test_cases: 225
|
||||
model: DeepSeek Chat V3
|
||||
edit_format: diff
|
||||
commit_hash: 0a23c4a-dirty
|
||||
pass_rate_1: 22.7
|
||||
pass_rate_2: 48.4
|
||||
pass_num_1: 51
|
||||
pass_num_2: 109
|
||||
percent_cases_well_formed: 98.7
|
||||
error_outputs: 7
|
||||
num_malformed_responses: 7
|
||||
num_with_malformed_responses: 3
|
||||
user_asks: 19
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-chat
|
||||
date: 2024-12-25
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.8
|
||||
total_cost: 0.3369
|
||||
|
||||
- dirname: 2024-12-26-00-55-20--Qwen2.5-Coder-32B-Instruct
|
||||
test_cases: 225
|
||||
model: openai/Qwen2.5-Coder-32B-Instruct
|
||||
edit_format: whole
|
||||
commit_hash: b51768b0
|
||||
pass_rate_1: 4.9
|
||||
pass_rate_2: 16.4
|
||||
pass_num_1: 11
|
||||
pass_num_2: 37
|
||||
percent_cases_well_formed: 99.6
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 33
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 6
|
||||
total_tests: 225
|
||||
command: aider --model openai/Qwen2.5-Coder-32B-Instruct
|
||||
date: 2024-12-26
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 42.0
|
||||
total_cost: 0.0000
|
||||
|
||||
170
aider/website/_data/qwq.yml
Normal file
170
aider/website/_data/qwq.yml
Normal 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
|
||||
@@ -1,5 +1,18 @@
|
||||
<canvas id="blameChart" width="800" height="360" style="margin-top: 20px"></canvas>
|
||||
<canvas id="linesChart" width="800" height="360" style="margin-top: 20px"></canvas>
|
||||
<div class="chart-container">
|
||||
<canvas id="blameChart" style="margin-top: 20px"></canvas>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<canvas id="linesChart" style="margin-top: 20px"></canvas>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.chart-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
|
||||
@@ -24,10 +37,17 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
var linesData = {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: 'Aider\'s lines of new code',
|
||||
label: 'Aider',
|
||||
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.aider_total }} },{% endfor %}],
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.8)',
|
||||
borderColor: 'rgba(255, 99, 132, 1)',
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.8)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
},
|
||||
{
|
||||
label: 'Human',
|
||||
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.total_lines | minus: row.aider_total }} },{% endfor %}],
|
||||
backgroundColor: 'rgba(200, 200, 200, 0.8)',
|
||||
borderColor: 'rgba(200, 200, 200, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
@@ -36,6 +56,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
type: 'bar',
|
||||
data: blameData,
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
type: 'category',
|
||||
@@ -85,9 +106,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
type: 'bar',
|
||||
data: linesData,
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
type: 'category',
|
||||
stacked: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Version'
|
||||
@@ -98,6 +121,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
},
|
||||
y: {
|
||||
stacked: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Lines of new code'
|
||||
@@ -107,12 +131,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
display: true,
|
||||
position: 'chartArea',
|
||||
reverse: true
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
var label = 'New lines of code by aider';
|
||||
var label = context.dataset.label;
|
||||
var value = context.parsed.y || 0;
|
||||
return `${label}: ${value}`;
|
||||
}
|
||||
@@ -120,7 +146,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Lines of new code written by aider, by release',
|
||||
text: 'Lines of new code, by release',
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var ctx = document.getElementById('editChart').getContext('2d');
|
||||
const HIGHTLIGHT_MODEL = 'no no no no';
|
||||
var leaderboardData = {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'Percent completed correctly',
|
||||
data: [],
|
||||
backgroundColor: function(context) {
|
||||
const label = context.chart.data.labels[context.dataIndex] || '';
|
||||
return (label && label.includes(HIGHTLIGHT_MODEL)) ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)';
|
||||
},
|
||||
borderColor: function(context) {
|
||||
const label = context.chart.data.labels[context.dataIndex] || '';
|
||||
return (label && label.includes(HIGHTLIGHT_MODEL)) ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)';
|
||||
},
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
|
||||
var allData = [];
|
||||
{% for row in edit_sorted %}
|
||||
allData.push({
|
||||
model: '{{ row.model }}',
|
||||
pass_rate_2: {{ row.pass_rate_2 }},
|
||||
percent_cases_well_formed: {{ row.percent_cases_well_formed }}
|
||||
});
|
||||
{% endfor %}
|
||||
|
||||
function updateChart() {
|
||||
var selectedRows = document.querySelectorAll('tr.selected');
|
||||
var showAll = selectedRows.length === 0;
|
||||
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
|
||||
allData.forEach(function(row, index) {
|
||||
var rowElement = document.getElementById('edit-row-' + index);
|
||||
if (showAll) {
|
||||
rowElement.classList.remove('selected');
|
||||
}
|
||||
if (showAll || rowElement.classList.contains('selected')) {
|
||||
leaderboardData.labels.push(row.model);
|
||||
leaderboardData.datasets[0].data.push(row.pass_rate_2);
|
||||
}
|
||||
});
|
||||
|
||||
leaderboardChart.update();
|
||||
}
|
||||
|
||||
var tableBody = document.querySelector('table tbody');
|
||||
allData.forEach(function(row, index) {
|
||||
var tr = tableBody.children[index];
|
||||
tr.id = 'edit-row-' + index;
|
||||
tr.style.cursor = 'pointer';
|
||||
tr.onclick = function() {
|
||||
this.classList.toggle('selected');
|
||||
updateChart();
|
||||
};
|
||||
});
|
||||
|
||||
var leaderboardChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: leaderboardData,
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateChart();
|
||||
|
||||
// Add search functionality for edit table
|
||||
document.getElementById('editSearchInput').addEventListener('keyup', function() {
|
||||
var searchWords = this.value.toLowerCase().split(' ').filter(word => word.length > 0);
|
||||
var tableBody = document.querySelector('table:first-of-type tbody');
|
||||
var rows = tableBody.getElementsByTagName('tr');
|
||||
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var rowText = rows[i].textContent;
|
||||
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
|
||||
rows[i].style.display = '';
|
||||
leaderboardData.labels.push(allData[i].model);
|
||||
leaderboardData.datasets[0].data.push(allData[i].pass_rate_2);
|
||||
} else {
|
||||
rows[i].style.display = 'none';
|
||||
}
|
||||
}
|
||||
leaderboardChart.update();
|
||||
});
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
{: .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).
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
|
||||
You can get started quickly like this:
|
||||
If you already have python 3.8-3.13 installed, you can get started quickly like this:
|
||||
|
||||
```
|
||||
python -m pip install -U aider-chat
|
||||
|
||||
# Change directory into a git repo
|
||||
cd /to/your/git/repo
|
||||
|
||||
# Work with Claude 3.5 Sonnet on your repo
|
||||
export ANTHROPIC_API_KEY=your-key-goes-here
|
||||
aider
|
||||
|
||||
# Work with GPT-4o on your repo
|
||||
export OPENAI_API_KEY=your-key-goes-here
|
||||
aider
|
||||
```bash
|
||||
python -m pip install aider-install
|
||||
aider-install
|
||||
|
||||
# Change directory into your code base
|
||||
cd /to/your/project
|
||||
|
||||
# Work with Claude 3.5 Sonnet on your code
|
||||
aider --model sonnet --anthropic-api-key your-key-goes-here
|
||||
|
||||
# Work with GPT-4o on your code
|
||||
aider --model gpt-4o --openai-api-key your-key-goes-here
|
||||
```
|
||||
|
||||
@@ -18,3 +18,65 @@
|
||||
<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">
|
||||
|
||||
{% if site.analytics.enabled %}
|
||||
<!-- Cookie Consent -->
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js" data-cfasync="false"></script>
|
||||
<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('{{ site.analytics.posthog_key }}', {
|
||||
api_host: '{{ site.analytics.posthog_host }}',
|
||||
person_profiles: 'identified_only'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
4
aider/website/_includes/keys.md
Normal file
4
aider/website/_includes/keys.md
Normal file
@@ -0,0 +1,4 @@
|
||||
{: .tip :}
|
||||
See the
|
||||
[API key configuration docs](/docs/config/api-keys.html)
|
||||
for information on how to configure and store your API keys.
|
||||
@@ -0,0 +1,190 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var ctx = document.getElementById('editChart').getContext('2d');
|
||||
const blueDiagonalPattern = pattern.draw('diagonal', 'rgba(54, 162, 235, 0.2)');
|
||||
const redDiagonalPattern = pattern.draw('diagonal', 'rgba(255, 99, 132, 0.2)');
|
||||
let displayedData = [];
|
||||
|
||||
const HIGHLIGHT_MODEL = '{{ highlight_model | default: "no no no" }}';
|
||||
var leaderboardData = {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'Percent completed correctly',
|
||||
data: [],
|
||||
backgroundColor: function(context) {
|
||||
const row = allData[context.dataIndex];
|
||||
if (row && row.edit_format === 'whole') {
|
||||
return diagonalPattern;
|
||||
}
|
||||
const label = leaderboardData.labels[context.dataIndex] || '';
|
||||
return (label && label.includes(HIGHLIGHT_MODEL)) ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)';
|
||||
},
|
||||
borderColor: function(context) {
|
||||
const label = context.chart.data.labels[context.dataIndex] || '';
|
||||
return (label && label.includes(HIGHLIGHT_MODEL)) ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)';
|
||||
},
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
|
||||
var allData = [];
|
||||
{% for row in data_source %}
|
||||
allData.push({
|
||||
model: '{{ row.model }}',
|
||||
pass_rate: {{ row[pass_rate_field] }},
|
||||
percent_cases_well_formed: {{ row.percent_cases_well_formed }},
|
||||
edit_format: '{{ row.edit_format | default: "diff" }}'
|
||||
});
|
||||
{% endfor %}
|
||||
|
||||
function updateChart() {
|
||||
var selectedRows = document.querySelectorAll('tr.selected');
|
||||
var showAll = selectedRows.length === 0;
|
||||
|
||||
displayedData = [];
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
|
||||
allData.forEach(function(row, index) {
|
||||
var rowElement = document.getElementById('edit-row-' + index);
|
||||
if (showAll) {
|
||||
rowElement.classList.remove('selected');
|
||||
}
|
||||
if (showAll || rowElement.classList.contains('selected')) {
|
||||
displayedData.push(row);
|
||||
leaderboardData.labels.push(row.model);
|
||||
leaderboardData.datasets[0].data.push(row.pass_rate);
|
||||
}
|
||||
});
|
||||
|
||||
leaderboardChart.update();
|
||||
leaderboardChart.render();
|
||||
}
|
||||
|
||||
// Use displayedData in the backgroundColor callback instead of allData
|
||||
leaderboardData.datasets[0].backgroundColor = function(context) {
|
||||
const row = displayedData[context.dataIndex];
|
||||
const label = leaderboardData.labels[context.dataIndex] || '';
|
||||
if (label && label.includes(HIGHLIGHT_MODEL)) {
|
||||
if (row && row.edit_format === 'whole') return redDiagonalPattern;
|
||||
else return 'rgba(255, 99, 132, 0.2)';
|
||||
} else if (row && row.edit_format === 'whole') {
|
||||
return blueDiagonalPattern;
|
||||
} else {
|
||||
return 'rgba(54, 162, 235, 0.2)';
|
||||
}
|
||||
};
|
||||
|
||||
var tableBody = document.querySelector('table tbody');
|
||||
allData.forEach(function(row, index) {
|
||||
var tr = tableBody.children[index];
|
||||
if (!tr) {
|
||||
// If the row doesn't exist, create it
|
||||
tr = document.createElement('tr');
|
||||
tableBody.appendChild(tr);
|
||||
}
|
||||
tr.id = 'edit-row-' + index;
|
||||
tr.style.cursor = 'pointer';
|
||||
tr.onclick = function() {
|
||||
this.classList.toggle('selected');
|
||||
updateChart();
|
||||
};
|
||||
});
|
||||
|
||||
var leaderboardChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: leaderboardData,
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
labels: {
|
||||
generateLabels: function(chart) {
|
||||
return [
|
||||
{
|
||||
text: 'Diff-like format',
|
||||
fillStyle: 'rgba(54, 162, 235, 0.2)',
|
||||
strokeStyle: 'rgba(54, 162, 235, 1)',
|
||||
lineWidth: 1
|
||||
},
|
||||
{
|
||||
text: 'Whole format',
|
||||
fillStyle: blueDiagonalPattern,
|
||||
strokeStyle: 'rgba(54, 162, 235, 1)',
|
||||
lineWidth: 1
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Percent completed correctly'
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
callback: function(value, index) {
|
||||
const label = this.getLabelForValue(value);
|
||||
if (label.length <= "claude-3-5-sonnet".length) {
|
||||
return label;
|
||||
}
|
||||
|
||||
// Find all possible split positions
|
||||
const splitPositions = [];
|
||||
for (let i = 0; i < label.length; i++) {
|
||||
if (label[i] === '-' || label[i] === ' ') {
|
||||
splitPositions.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (splitPositions.length === 0) {
|
||||
return label;
|
||||
}
|
||||
|
||||
// Find split position closest to middle
|
||||
const middle = label.length / 2;
|
||||
const splitIndex = splitPositions.reduce((closest, current) => {
|
||||
return Math.abs(current - middle) < Math.abs(closest - middle) ? current : closest;
|
||||
});
|
||||
|
||||
return [
|
||||
label.slice(0, splitIndex),
|
||||
label.slice(splitIndex + 1)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateChart();
|
||||
|
||||
// Add search functionality for edit table
|
||||
document.getElementById('editSearchInput').addEventListener('keyup', function() {
|
||||
var searchWords = this.value.toLowerCase().split(' ').filter(word => word.length > 0);
|
||||
var tableBody = document.querySelector('table:first-of-type tbody');
|
||||
var rows = tableBody.getElementsByTagName('tr');
|
||||
|
||||
displayedData = [];
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var rowText = rows[i].textContent;
|
||||
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
|
||||
rows[i].style.display = '';
|
||||
displayedData.push(allData[i]);
|
||||
leaderboardData.labels.push(allData[i].model);
|
||||
leaderboardData.datasets[0].data.push(allData[i].pass_rate);
|
||||
} else {
|
||||
rows[i].style.display = 'none';
|
||||
}
|
||||
}
|
||||
leaderboardChart.update();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
120
aider/website/_includes/qwq-chart.js
Normal file
120
aider/website/_includes/qwq-chart.js
Normal 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);
|
||||
});
|
||||
});
|
||||
@@ -1,90 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var ctx = document.getElementById('refacChart').getContext('2d');
|
||||
var leaderboardData = {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'Percent completed correctly',
|
||||
data: [],
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
|
||||
var allData = [];
|
||||
{% for row in refac_sorted %}
|
||||
allData.push({
|
||||
model: '{{ row.model }}',
|
||||
pass_rate_1: {{ row.pass_rate_1 }},
|
||||
percent_cases_well_formed: {{ row.percent_cases_well_formed }}
|
||||
});
|
||||
{% endfor %}
|
||||
|
||||
function updateChart() {
|
||||
var selectedRows = document.querySelectorAll('tr.selected');
|
||||
var showAll = selectedRows.length === 0;
|
||||
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
|
||||
allData.forEach(function(row, index) {
|
||||
var rowElement = document.getElementById('refac-row-' + index);
|
||||
if (showAll) {
|
||||
rowElement.classList.remove('selected');
|
||||
}
|
||||
if (showAll || rowElement.classList.contains('selected')) {
|
||||
leaderboardData.labels.push(row.model);
|
||||
leaderboardData.datasets[0].data.push(row.pass_rate_1);
|
||||
}
|
||||
});
|
||||
|
||||
leaderboardChart.update();
|
||||
}
|
||||
|
||||
var tableBody = document.querySelectorAll('table tbody')[1];
|
||||
allData.forEach(function(row, index) {
|
||||
var tr = tableBody.children[index];
|
||||
tr.id = 'refac-row-' + index;
|
||||
tr.style.cursor = 'pointer';
|
||||
tr.onclick = function() {
|
||||
this.classList.toggle('selected');
|
||||
updateChart();
|
||||
};
|
||||
});
|
||||
|
||||
var leaderboardChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: leaderboardData,
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateChart();
|
||||
|
||||
// Add search functionality for refactoring table
|
||||
document.getElementById('refacSearchInput').addEventListener('keyup', function() {
|
||||
var searchWords = this.value.toLowerCase().split(' ').filter(word => word.length > 0);
|
||||
var tableBody = document.querySelectorAll('table tbody')[1];
|
||||
var rows = tableBody.getElementsByTagName('tr');
|
||||
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var rowText = rows[i].textContent;
|
||||
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
|
||||
rows[i].style.display = '';
|
||||
leaderboardData.labels.push(allData[i].model);
|
||||
leaderboardData.datasets[0].data.push(allData[i].pass_rate_1);
|
||||
} else {
|
||||
rows[i].style.display = 'none';
|
||||
}
|
||||
}
|
||||
leaderboardChart.update();
|
||||
});
|
||||
});
|
||||
@@ -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...
|
||||
```
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
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).
|
||||
@@ -1,7 +0,0 @@
|
||||
{: .tip }
|
||||
Using a Python
|
||||
[virtual environment](https://docs.python.org/3/library/venv.html){:target="_blank"}
|
||||
is recommended.
|
||||
Or, you could
|
||||
[use pipx to install aider](/docs/install/pipx.html)
|
||||
once for your whole system.
|
||||
@@ -1,2 +1 @@
|
||||
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
|
||||
[connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
Aider works best with Claude 3.5 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
|
||||
@@ -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%)
|
||||
|
||||
[](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)
|
||||
|
||||
140
aider/website/_posts/2024-12-03-qwq.md
Normal file
140
aider/website/_posts/2024-12-03-qwq.md
Normal 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.
|
||||
216
aider/website/_posts/2024-12-21-polyglot.md
Normal file
216
aider/website/_posts/2024-12-21-polyglot.md
Normal file
@@ -0,0 +1,216 @@
|
||||
---
|
||||
title: o1 tops aider's new polyglot leaderboard
|
||||
excerpt: o1 scores the top result on aider's new multi-language, more challenging coding benchmark.
|
||||
highlight_image: /assets/o1-polyglot.jpg
|
||||
draft: false
|
||||
nav_exclude: true
|
||||
---
|
||||
{% if page.date %}
|
||||
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
|
||||
{% endif %}
|
||||
|
||||
# o1 tops aider's new polyglot leaderboard
|
||||
{: .no_toc }
|
||||
|
||||
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
||||
|
||||
OpenAI's new o1 model with "high" reasoning effort
|
||||
gets the top score on the
|
||||
new
|
||||
[aider polyglot leaderboard](/docs/leaderboards/), significantly ahead of
|
||||
other top LLMs.
|
||||
The new polyglot benchmark uses many popular coding languages
|
||||
and was designed to be
|
||||
*much more challenging* than aider's original
|
||||
[code editing benchmark](/docs/leaderboards/edit.html).
|
||||
This more clearly distinguishes
|
||||
the performance of
|
||||
today's strongest coding models and
|
||||
leaves headroom for future LLMs.
|
||||
|
||||
{: .note :}
|
||||
See the main
|
||||
[aider leaderboard](https://aider.chat/docs/leaderboards/)
|
||||
for benchmark results from more models.
|
||||
This article only contains a snapshot
|
||||
of results at the time of publication.
|
||||
|
||||
## The polyglot benchmark
|
||||
|
||||
Like aider's original code editing benchmark,
|
||||
the new polyglot benchmark is based on Exercism
|
||||
coding exercises.
|
||||
|
||||
The new polyglot benchmark:
|
||||
|
||||
- Contains coding problems in C++, Go, Java, JavaScript, Python and Rust.
|
||||
The old benchmark was solely based on Python exercises.
|
||||
- Focuses on the *most difficult* 225 exercises out of the 697 that
|
||||
Exercism provides for those languages.
|
||||
The old benchmark simply included all 133 Python exercises,
|
||||
regardless of difficulty.
|
||||
|
||||
## Motivation and goals
|
||||
|
||||
Aider's original code editing benchmark was
|
||||
saturating as the top scores approached and then surpassed 80%.
|
||||
Sonnet's score of 84.2% was based on solving 112 of the 133
|
||||
exercises, leaving only 21 unsolved exercises.
|
||||
New champions were advancing the top score by
|
||||
solving just 1-2 more problems than the previous record.
|
||||
This made it hard to clearly
|
||||
measure the
|
||||
difference in code editing skill between these top models.
|
||||
|
||||
Part of the problem is that many of the original
|
||||
133 Python problems are very easy
|
||||
and provide
|
||||
little challenge to today's frontier LLMs.
|
||||
Models as old as GPT 3.5 Turbo were able to solve half of the
|
||||
133 problems.
|
||||
Such easy problems simply inflate the benchmark scores
|
||||
of modern LLMs without
|
||||
providing any data about which models are better or worse.
|
||||
|
||||
The main goal for a new benchmark
|
||||
was to re-calibrate the scale so that
|
||||
today's top coding LLMs
|
||||
would occupy a wide range of scores between about 5% and 50%.
|
||||
This should leave headroom for future LLMs and
|
||||
make it possible to
|
||||
more clearly compare the relative performance of top models.
|
||||
|
||||
## Designing the polyglot benchmark
|
||||
|
||||
The new benchmark:
|
||||
|
||||
- Tests LLMs with more coding languages, to increase diversity and source a larger pool of problems.
|
||||
- Includes just the most challenging coding problems and excludes easy problems that are solvable by most of today's top coding LLMs.
|
||||
- Includes more total coding problems, to enable more granularity of comparison.
|
||||
|
||||
The new benchmark is based on Exercism coding problems
|
||||
from 6 of the most popular programming languages:
|
||||
|
||||
- C++
|
||||
- Go
|
||||
- Java
|
||||
- JavaScript
|
||||
- Python
|
||||
- Rust
|
||||
|
||||
Exercism provides a total of 697 coding problems in those 6 languages.
|
||||
A set of 7 of today's top coding models each attempted all 697 of
|
||||
the Exercism problems:
|
||||
|
||||
- Sonnet
|
||||
- Haiku
|
||||
- o1 Mini
|
||||
- DeepSeek
|
||||
- GPT-4o
|
||||
- Qwen 32B Coder Instruct
|
||||
- GPT-4o Mini
|
||||
|
||||
Depending on the difficulty of the problems,
|
||||
a different number of solutions were found by the collection of
|
||||
7 models:
|
||||
|
||||
| Solutions<br>found | Number of<br>problems | Cumulative number<br>of problems |
|
||||
|--------|-----------|------------|
|
||||
| 0 | 66 | 66 |
|
||||
| 1 | 61 | 127 |
|
||||
| 2 | 50 | 177 |
|
||||
| 3 | 48 | 225 |
|
||||
| 4 | 53 | 278 |
|
||||
| 5 | 71 | 349 |
|
||||
| 6 | 90 | 439 |
|
||||
| 7 | 258 | 697 |
|
||||
|
||||
In the table above, you can see that 258 of the problems were solved
|
||||
by all 7 LLMs.
|
||||
These problems are far too easy, and wouldn't be good choices for the new benchmark.
|
||||
Instead, we need hard problems like the
|
||||
66 that none of the 7 models were able to solve.
|
||||
|
||||
The new benchmark uses
|
||||
the 225 problems that were solved by 3 or fewer models.
|
||||
This achieves a balance between hard and moderate problems,
|
||||
and provides a large but not excessive total pool of problems.
|
||||
It also represents a good diversity of coding languages:
|
||||
|
||||
| Language | Problems |
|
||||
|-------------|----------|
|
||||
| C++ | 26 |
|
||||
| Go | 39 |
|
||||
| Java | 47 |
|
||||
| JavaScript | 49 |
|
||||
| Python | 34 |
|
||||
| Rust | 30 |
|
||||
| **Total** | **225** |
|
||||
|
||||
## o1
|
||||
|
||||
OpenAI's new o1 model established a very strong
|
||||
top score of 62% on the new benchmark.
|
||||
This still leaves 86 problems of headroom for future models
|
||||
to solve.
|
||||
Given the incredible pace of recent advancements, it
|
||||
will be interesting to see
|
||||
how long it will take for this new benchmark to saturate.
|
||||
|
||||
## Benchmark problems
|
||||
|
||||
The 225 coding problems are available in the
|
||||
[aider polyglot benchmark repo](https://github.com/Aider-AI/polyglot-benchmark)
|
||||
on GitHub.
|
||||
|
||||
|
||||
|
||||
## Results
|
||||
|
||||
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
|
||||
<thead style="background-color: #f2f2f2;">
|
||||
<tr>
|
||||
<th style="padding: 8px; text-align: left;">Model</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
|
||||
<th style="padding: 8px; text-align: left;">Command</th>
|
||||
<th style="padding: 8px; text-align: center;">Edit format</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% assign edit_sorted = site.data.o1_polyglot_leaderboard | sort: 'pass_rate_2' | reverse %}
|
||||
{% for row in edit_sorted %}
|
||||
<tr style="border-bottom: 1px solid #ddd;">
|
||||
<td style="padding: 8px;">{{ row.model }}</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_2 }}%</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
|
||||
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
{% assign data_source = edit_sorted %}
|
||||
{% assign pass_rate_field = "pass_rate_2" %}
|
||||
{% assign highlight_model = "o1-2024" %}
|
||||
{% include leaderboard.js %}
|
||||
</script>
|
||||
<style>
|
||||
tr.selected {
|
||||
color: #0056b3;
|
||||
}
|
||||
table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
td, th {
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
td:nth-child(3), td:nth-child(4) {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
BIN
aider/website/assets/copypaste.jpg
Normal file
BIN
aider/website/assets/copypaste.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 314 KiB |
BIN
aider/website/assets/copypaste.mp4
Normal file
BIN
aider/website/assets/copypaste.mp4
Normal file
Binary file not shown.
BIN
aider/website/assets/o1-polyglot.jpg
Normal file
BIN
aider/website/assets/o1-polyglot.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 157 KiB |
BIN
aider/website/assets/qwq.jpg
Normal file
BIN
aider/website/assets/qwq.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -50,7 +44,7 @@
|
||||
## Use gpt-3.5-turbo model for the main chat
|
||||
#35turbo: false
|
||||
|
||||
## Use deepseek/deepseek-coder model for the main chat
|
||||
## Use deepseek/deepseek-chat model for the main chat
|
||||
#deepseek: false
|
||||
|
||||
## Use o1-mini model for the main chat
|
||||
@@ -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
|
||||
|
||||
@@ -121,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
|
||||
@@ -134,9 +150,9 @@
|
||||
#cache-keepalive-pings: false
|
||||
|
||||
###################
|
||||
# Repomap Settings:
|
||||
# Repomap settings:
|
||||
|
||||
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
|
||||
## Suggested number of tokens to use for repo map, use 0 to disable
|
||||
#map-tokens: xxx
|
||||
|
||||
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
|
||||
@@ -161,7 +177,7 @@
|
||||
#llm-history-file: xxx
|
||||
|
||||
##################
|
||||
# Output Settings:
|
||||
# Output settings:
|
||||
|
||||
## Use colors suitable for a dark terminal background (default: False)
|
||||
#dark-mode: false
|
||||
@@ -202,14 +218,14 @@
|
||||
## Set the background color for the current item in the completion menu (default: terminal's default text color)
|
||||
#completion-menu-current-bg-color: xxx
|
||||
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
|
||||
#code-theme: default
|
||||
|
||||
## Show diffs when committing changes (default: False)
|
||||
#show-diffs: false
|
||||
|
||||
###############
|
||||
# Git Settings:
|
||||
# Git settings:
|
||||
|
||||
## Enable/disable looking for a git repo (default: True)
|
||||
#git: true
|
||||
@@ -253,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:
|
||||
|
||||
@@ -291,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
|
||||
@@ -316,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
|
||||
|
||||
@@ -370,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
|
||||
@@ -379,20 +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
|
||||
|
||||
## Specify the input device name for voice recording
|
||||
#voice-input-device: xxx
|
||||
|
||||
@@ -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
|
||||
@@ -54,7 +48,7 @@
|
||||
## Use gpt-3.5-turbo model for the main chat
|
||||
#AIDER_35TURBO=
|
||||
|
||||
## Use deepseek/deepseek-coder model for the main chat
|
||||
## Use deepseek/deepseek-chat model for the main chat
|
||||
#AIDER_DEEPSEEK=
|
||||
|
||||
## Use o1-mini model for the main chat
|
||||
@@ -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
|
||||
|
||||
@@ -120,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
|
||||
@@ -133,9 +139,9 @@
|
||||
#AIDER_CACHE_KEEPALIVE_PINGS=false
|
||||
|
||||
###################
|
||||
# Repomap Settings:
|
||||
# Repomap settings:
|
||||
|
||||
## Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)
|
||||
## Suggested number of tokens to use for repo map, use 0 to disable
|
||||
#AIDER_MAP_TOKENS=
|
||||
|
||||
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
|
||||
@@ -160,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
|
||||
@@ -201,14 +207,14 @@
|
||||
## Set the background color for the current item in the completion menu (default: terminal's default text color)
|
||||
#AIDER_COMPLETION_MENU_CURRENT_BG_COLOR=
|
||||
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
|
||||
#AIDER_CODE_THEME=default
|
||||
|
||||
## Show diffs when committing changes (default: False)
|
||||
#AIDER_SHOW_DIFFS=false
|
||||
|
||||
###############
|
||||
# Git Settings:
|
||||
# Git settings:
|
||||
|
||||
## Enable/disable looking for a git repo (default: True)
|
||||
#AIDER_GIT=true
|
||||
@@ -252,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:
|
||||
|
||||
@@ -285,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
|
||||
@@ -315,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=
|
||||
@@ -342,29 +321,29 @@
|
||||
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
|
||||
#AIDER_MESSAGE_FILE=
|
||||
|
||||
## 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
|
||||
|
||||
## Enable/disable suggesting shell commands (default: True)
|
||||
#AIDER_SUGGEST_SHELL_COMMANDS=true
|
||||
## Enable automatic copy/paste of chat between aider and web UI (default: False)
|
||||
#AIDER_COPY_PASTE=false
|
||||
|
||||
## Enable/disable fancy input with history and completion (default: True)
|
||||
#AIDER_FANCY_INPUT=true
|
||||
## Apply the changes from the given file instead of running the chat (debug)
|
||||
#AIDER_APPLY=
|
||||
|
||||
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
#AIDER_DETECT_URLS=true
|
||||
## Apply clipboard contents as edits using the main model's editor format
|
||||
#AIDER_APPLY_CLIPBOARD_EDITS=false
|
||||
|
||||
## Specify which editor to use for the /editor command
|
||||
#AIDER_EDITOR=
|
||||
## 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:
|
||||
# Voice settings:
|
||||
|
||||
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
||||
#AIDER_VOICE_FORMAT=wav
|
||||
@@ -374,3 +353,48 @@
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
|
||||
## 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=
|
||||
|
||||
BIN
aider/website/assets/watch.jpg
Normal file
BIN
aider/website/assets/watch.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 204 KiB |
BIN
aider/website/assets/watch.mp4
Normal file
BIN
aider/website/assets/watch.mp4
Normal file
Binary file not shown.
@@ -40,5 +40,5 @@ Using an `.env` file:
|
||||
AIDER_DARK_MODE=true
|
||||
```
|
||||
|
||||
{% include env-keys-tip.md %}
|
||||
{% include keys.md %}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1093,6 +1163,22 @@ cog.out("```\n")
|
||||
use_system_prompt: true
|
||||
use_temperature: true
|
||||
weak_model_name: null
|
||||
- cache_control: false
|
||||
caches_by_default: false
|
||||
edit_format: diff
|
||||
editor_edit_format: null
|
||||
editor_model_name: null
|
||||
examples_as_sys_msg: true
|
||||
extra_params: null
|
||||
lazy: false
|
||||
name: openrouter/deepseek/deepseek-chat
|
||||
reminder: sys
|
||||
send_undo_reply: false
|
||||
streaming: true
|
||||
use_repo_map: true
|
||||
use_system_prompt: true
|
||||
use_temperature: true
|
||||
weak_model_name: null
|
||||
- cache_control: false
|
||||
caches_by_default: false
|
||||
edit_format: diff
|
||||
@@ -1237,6 +1323,54 @@ cog.out("```\n")
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
- cache_control: false
|
||||
caches_by_default: false
|
||||
edit_format: diff
|
||||
editor_edit_format: editor-diff
|
||||
editor_model_name: openrouter/openai/gpt-4o
|
||||
examples_as_sys_msg: false
|
||||
extra_params: null
|
||||
lazy: false
|
||||
name: openrouter/openai/o1
|
||||
reminder: user
|
||||
send_undo_reply: false
|
||||
streaming: false
|
||||
use_repo_map: true
|
||||
use_system_prompt: true
|
||||
use_temperature: false
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
- cache_control: false
|
||||
caches_by_default: false
|
||||
edit_format: diff
|
||||
editor_edit_format: editor-diff
|
||||
editor_model_name: openai/gpt-4o
|
||||
examples_as_sys_msg: false
|
||||
extra_params: null
|
||||
lazy: false
|
||||
name: openai/o1
|
||||
reminder: user
|
||||
send_undo_reply: false
|
||||
streaming: false
|
||||
use_repo_map: true
|
||||
use_system_prompt: true
|
||||
use_temperature: false
|
||||
weak_model_name: openai/gpt-4o-mini
|
||||
- cache_control: false
|
||||
caches_by_default: false
|
||||
edit_format: diff
|
||||
editor_edit_format: editor-diff
|
||||
editor_model_name: gpt-4o
|
||||
examples_as_sys_msg: false
|
||||
extra_params: null
|
||||
lazy: false
|
||||
name: o1
|
||||
reminder: user
|
||||
send_undo_reply: false
|
||||
streaming: false
|
||||
use_repo_map: true
|
||||
use_system_prompt: true
|
||||
use_temperature: false
|
||||
weak_model_name: gpt-4o-mini
|
||||
- cache_control: false
|
||||
caches_by_default: false
|
||||
edit_format: diff
|
||||
|
||||
@@ -15,11 +15,7 @@ load whichever is found first.
|
||||
- The root of your git repo.
|
||||
- Your home directory.
|
||||
|
||||
## Storing LLM keys
|
||||
|
||||
{% include special-keys.md %}
|
||||
|
||||
{% include env-keys-tip.md %}
|
||||
{% include keys.md %}
|
||||
|
||||
## A note on lists
|
||||
|
||||
@@ -70,14 +66,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 +84,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
|
||||
@@ -106,7 +96,7 @@ cog.outl("```")
|
||||
## Use gpt-3.5-turbo model for the main chat
|
||||
#35turbo: false
|
||||
|
||||
## Use deepseek/deepseek-coder model for the main chat
|
||||
## Use deepseek/deepseek-chat model for the main chat
|
||||
#deepseek: false
|
||||
|
||||
## Use o1-mini model for the main chat
|
||||
@@ -115,27 +105,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
|
||||
|
||||
@@ -177,11 +192,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
|
||||
@@ -190,9 +202,9 @@ 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)
|
||||
## Suggested number of tokens to use for repo map, use 0 to disable
|
||||
#map-tokens: xxx
|
||||
|
||||
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
|
||||
@@ -217,7 +229,7 @@ cog.outl("```")
|
||||
#llm-history-file: xxx
|
||||
|
||||
##################
|
||||
# Output Settings:
|
||||
# Output settings:
|
||||
|
||||
## Use colors suitable for a dark terminal background (default: False)
|
||||
#dark-mode: false
|
||||
@@ -258,14 +270,14 @@ cog.outl("```")
|
||||
## Set the background color for the current item in the completion menu (default: terminal's default text color)
|
||||
#completion-menu-current-bg-color: xxx
|
||||
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
|
||||
#code-theme: default
|
||||
|
||||
## Show diffs when committing changes (default: False)
|
||||
#show-diffs: false
|
||||
|
||||
###############
|
||||
# Git Settings:
|
||||
# Git settings:
|
||||
|
||||
## Enable/disable looking for a git repo (default: True)
|
||||
#git: true
|
||||
@@ -309,6 +321,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:
|
||||
|
||||
@@ -347,8 +362,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
|
||||
@@ -372,51 +450,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
|
||||
|
||||
@@ -426,8 +465,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
|
||||
@@ -435,22 +474,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
|
||||
|
||||
## Specify the input device name for voice recording
|
||||
#voice-input-device: xxx
|
||||
```
|
||||
<!--[[[end]]]-->
|
||||
|
||||
90
aider/website/docs/config/api-keys.md
Normal file
90
aider/website/docs/config/api-keys.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
parent: Configuration
|
||||
nav_order: 5
|
||||
description: Setting API keys for API providers.
|
||||
---
|
||||
|
||||
# API Keys
|
||||
|
||||
Aider lets you specify API keys in a few ways:
|
||||
|
||||
- On the command line
|
||||
- As environment variables
|
||||
- In a `.env` file
|
||||
- In your `.aider.conf.yml` config file
|
||||
|
||||
---
|
||||
|
||||
## OpenAI and Anthropic
|
||||
|
||||
Aider has special support for providing
|
||||
OpenAI and Anthropic API keys
|
||||
via dedicated switches and configuration options.
|
||||
Settings keys for other providers works a bit differently, see below.
|
||||
|
||||
#### Command line
|
||||
|
||||
You can set OpenAI and Anthropic API keys via
|
||||
[command line switches](/docs/config/options.html#api-keys-and-settings)
|
||||
`--openai-api-key` and `--anthropic-api-key`.
|
||||
|
||||
|
||||
#### Environment variables or .env file
|
||||
|
||||
You can also store them in environment variables or a
|
||||
[.env file](/docs/config/dotenv.html), which also works
|
||||
for every API provider:
|
||||
|
||||
```
|
||||
OPENAI_API_KEY=<key>
|
||||
ANTHROPIC_API_KEY=<key>
|
||||
```
|
||||
|
||||
#### Yaml config file
|
||||
You can also set those API keys via special entries in the
|
||||
[yaml config file](/docs/config/aider_conf.html), like this:
|
||||
|
||||
```yaml
|
||||
openai-api-key: <key>
|
||||
anthropic-api-key: <key>
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Other API providers
|
||||
|
||||
All other LLM providers can use one of these other methods to set their API keys.
|
||||
|
||||
#### Command line
|
||||
{: .no_toc }
|
||||
|
||||
Use `--api-key provider=<key>` which has the effect of setting the environment variable `PROVIDER_API_KEY=<key>`. So `--api-key gemini=xxx` would set `GEMINI_API_KEY=xxx`.
|
||||
|
||||
#### Environment variables or .env file
|
||||
{: .no_toc }
|
||||
|
||||
You can set API keys in environment variables.
|
||||
The [.env file](/docs/config/dotenv.html)
|
||||
is a great place to store your API keys and other provider API environment variables:
|
||||
|
||||
```bash
|
||||
GEMINI_API_KEY=foo
|
||||
OPENROUTER_API_KEY=bar
|
||||
DEEPSEEK_API_KEY=baz
|
||||
```
|
||||
|
||||
#### Yaml config file
|
||||
|
||||
|
||||
You can also set API keys in the
|
||||
[`.aider.conf.yml` file](/docs/config/aider_conf.html)
|
||||
via the `api-key` entry:
|
||||
|
||||
```
|
||||
api-key:
|
||||
- gemini=foo # Sets env var GEMINI_API_KEY=foo
|
||||
- openrouter=bar # Sets env var OPENROUTER_API_KEY=bar
|
||||
- deepseek=baz # Sets env var DEEPSEEK_API_KEY=baz
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
parent: Configuration
|
||||
nav_order: 900
|
||||
nav_order: 20
|
||||
description: Using a .env file to store LLM API keys for aider.
|
||||
---
|
||||
|
||||
@@ -20,9 +20,7 @@ Aider will look for a `.env` file in these locations:
|
||||
|
||||
If the files above exist, they will be loaded in that order. Files loaded last will take priority.
|
||||
|
||||
## Storing LLM keys
|
||||
|
||||
{% include special-keys.md %}
|
||||
{% include keys.md %}
|
||||
|
||||
## Sample .env file
|
||||
|
||||
@@ -60,14 +58,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 +76,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
|
||||
@@ -96,7 +88,7 @@ cog.outl("```")
|
||||
## Use gpt-3.5-turbo model for the main chat
|
||||
#AIDER_35TURBO=
|
||||
|
||||
## Use deepseek/deepseek-coder model for the main chat
|
||||
## Use deepseek/deepseek-chat model for the main chat
|
||||
#AIDER_DEEPSEEK=
|
||||
|
||||
## Use o1-mini model for the main chat
|
||||
@@ -105,27 +97,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
|
||||
|
||||
@@ -162,11 +169,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
|
||||
@@ -175,9 +179,9 @@ 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)
|
||||
## Suggested number of tokens to use for repo map, use 0 to disable
|
||||
#AIDER_MAP_TOKENS=
|
||||
|
||||
## Control how often the repo map is refreshed. Options: auto, always, files, manual (default: auto)
|
||||
@@ -202,7 +206,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
|
||||
@@ -243,14 +247,14 @@ cog.outl("```")
|
||||
## Set the background color for the current item in the completion menu (default: terminal's default text color)
|
||||
#AIDER_COMPLETION_MENU_CURRENT_BG_COLOR=
|
||||
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
|
||||
## Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
|
||||
#AIDER_CODE_THEME=default
|
||||
|
||||
## Show diffs when committing changes (default: False)
|
||||
#AIDER_SHOW_DIFFS=false
|
||||
|
||||
###############
|
||||
# Git Settings:
|
||||
# Git settings:
|
||||
|
||||
## Enable/disable looking for a git repo (default: True)
|
||||
#AIDER_GIT=true
|
||||
@@ -294,6 +298,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:
|
||||
|
||||
@@ -327,20 +334,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
|
||||
@@ -357,26 +352,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=
|
||||
@@ -384,29 +361,29 @@ cog.outl("```")
|
||||
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
|
||||
#AIDER_MESSAGE_FILE=
|
||||
|
||||
## 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
|
||||
|
||||
## Enable/disable suggesting shell commands (default: True)
|
||||
#AIDER_SUGGEST_SHELL_COMMANDS=true
|
||||
## Enable automatic copy/paste of chat between aider and web UI (default: False)
|
||||
#AIDER_COPY_PASTE=false
|
||||
|
||||
## Enable/disable fancy input with history and completion (default: True)
|
||||
#AIDER_FANCY_INPUT=true
|
||||
## Apply the changes from the given file instead of running the chat (debug)
|
||||
#AIDER_APPLY=
|
||||
|
||||
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
#AIDER_DETECT_URLS=true
|
||||
## Apply clipboard contents as edits using the main model's editor format
|
||||
#AIDER_APPLY_CLIPBOARD_EDITS=false
|
||||
|
||||
## Specify which editor to use for the /editor command
|
||||
#AIDER_EDITOR=
|
||||
## 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:
|
||||
# Voice settings:
|
||||
|
||||
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
||||
#AIDER_VOICE_FORMAT=wav
|
||||
@@ -416,5 +393,50 @@ cog.outl("```")
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
|
||||
## 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=
|
||||
```
|
||||
<!--[[[end]]]-->
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
parent: Configuration
|
||||
nav_order: 15
|
||||
nav_order: 100
|
||||
description: How to configure a custom editor for aider's /editor command
|
||||
---
|
||||
|
||||
|
||||
@@ -54,8 +54,9 @@ 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
|
||||
- `deepseek`: deepseek/deepseek-coder
|
||||
- `4o`: gpt-4o
|
||||
- `deepseek`: deepseek/deepseek-chat
|
||||
- `flash`: gemini/gemini-2.0-flash-exp
|
||||
- `haiku`: claude-3-5-haiku-20241022
|
||||
- `opus`: claude-3-opus-20240229
|
||||
- `sonnet`: claude-3-5-sonnet-20241022
|
||||
|
||||
@@ -13,10 +13,7 @@ or review them below.
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
## LLM keys
|
||||
{: .no_toc }
|
||||
|
||||
{% include special-keys.md %}
|
||||
{% include keys.md %}
|
||||
|
||||
## Usage summary
|
||||
|
||||
@@ -25,18 +22,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] [--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,24 +57,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]
|
||||
[--voice-input-device]
|
||||
|
||||
```
|
||||
|
||||
@@ -88,15 +89,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
|
||||
@@ -122,7 +115,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`
|
||||
@@ -143,7 +136,7 @@ Aliases:
|
||||
- `-3`
|
||||
|
||||
### `--deepseek`
|
||||
Use deepseek/deepseek-coder model for the main chat
|
||||
Use deepseek/deepseek-chat model for the main chat
|
||||
Environment variable: `AIDER_DEEPSEEK`
|
||||
|
||||
### `--o1-mini`
|
||||
@@ -154,7 +147,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
|
||||
@@ -163,26 +196,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
|
||||
@@ -244,12 +257,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)
|
||||
@@ -264,10 +272,10 @@ 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)
|
||||
Suggested number of tokens to use for repo map, use 0 to disable
|
||||
Environment variable: `AIDER_MAP_TOKENS`
|
||||
|
||||
### `--map-refresh VALUE`
|
||||
@@ -304,7 +312,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)
|
||||
@@ -373,7 +381,7 @@ Set the background color for the current item in the completion menu (default: t
|
||||
Environment variable: `AIDER_COMPLETION_MENU_CURRENT_BG_COLOR`
|
||||
|
||||
### `--code-theme VALUE`
|
||||
Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light)
|
||||
Set the markdown code theme (default: default, other options include monokai, solarized-dark, solarized-light, or a Pygments builtin style, see https://pygments.org/styles for available themes)
|
||||
Default: default
|
||||
Environment variable: `AIDER_CODE_THEME`
|
||||
|
||||
@@ -382,7 +390,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)
|
||||
@@ -480,6 +488,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`
|
||||
@@ -536,27 +552,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
|
||||
@@ -591,41 +587,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)
|
||||
@@ -642,6 +607,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`
|
||||
@@ -657,15 +711,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)
|
||||
@@ -683,6 +732,14 @@ Aliases:
|
||||
- `--fancy-input`
|
||||
- `--no-fancy-input`
|
||||
|
||||
### `--multiline`
|
||||
Enable/disable multi-line input mode with Meta-Enter to submit (default: False)
|
||||
Default: False
|
||||
Environment variable: `AIDER_MULTILINE`
|
||||
Aliases:
|
||||
- `--multiline`
|
||||
- `--no-multiline`
|
||||
|
||||
### `--detect-urls`
|
||||
Enable/disable detection and offering to add URLs to chat (default: True)
|
||||
Default: True
|
||||
@@ -694,20 +751,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`
|
||||
|
||||
### `--voice-input-device VOICE_INPUT_DEVICE`
|
||||
Specify the input device name for voice recording
|
||||
Environment variable: `AIDER_VOICE_INPUT_DEVICE`
|
||||
<!--[[[end]]]-->
|
||||
|
||||
@@ -209,6 +209,39 @@ all the raw information being sent to/from the LLM in the conversation.
|
||||
You can also refer to the
|
||||
[instructions for installing a development version of aider](https://aider.chat/docs/install/optional.html#install-the-development-version-of-aider).
|
||||
|
||||
## What LLMs do you use to build aider?
|
||||
|
||||
Aider writes a lot of its own code, usually about 70% of the new code in each
|
||||
release.
|
||||
People often ask which LLMs I use with aider, when writing aider.
|
||||
Below is a table showing the models I have used recently,
|
||||
extracted from the
|
||||
[public log](https://github.com/aider-ai/aider/blob/main/aider/website/assets/sample-analytics.jsonl)
|
||||
of my
|
||||
[aider analytics](https://aider.chat/docs/more/analytics.html).
|
||||
|
||||
<!--[[[cog
|
||||
import sys
|
||||
sys.path.append(".")
|
||||
import scripts.my_models as my_models
|
||||
stats = my_models.collect_model_stats()
|
||||
html = my_models.format_html_table(stats)
|
||||
cog.out(html)
|
||||
]]]-->
|
||||
<style>
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
|
||||
th { background-color: #f2f2f2; }
|
||||
tr:hover { background-color: #f5f5f5; }
|
||||
.right { text-align: right; }
|
||||
</style>
|
||||
<table>
|
||||
<tr><th>Model Name</th><th class='right'>Total Tokens</th><th class='right'>Percent</th></tr>
|
||||
<tr><td>deepseek/deepseek-chat</td><td class='right'>1,258,436</td><td class='right'>86.2%</td></tr>
|
||||
<tr><td>claude-3-5-sonnet-20241022</td><td class='right'>178,352</td><td class='right'>12.2%</td></tr>
|
||||
<tr><td>o1</td><td class='right'>22,748</td><td class='right'>1.6%</td></tr>
|
||||
</table>
|
||||
<!--[[[end]]]-->
|
||||
|
||||
## How are the "aider wrote xx% of code" stats computed?
|
||||
|
||||
@@ -220,6 +253,31 @@ by doing something like `git blame` on the repo,
|
||||
and counting up who wrote all the new lines of code in each release.
|
||||
Only lines in source code files are counted, not documentation or prompt files.
|
||||
|
||||
## Why does aider sometimes stop highlighting code in its replies?
|
||||
|
||||
Aider displays the markdown responses that are coming back from the LLM.
|
||||
Usually, the LLM will reply with code in a markdown "code block" with
|
||||
triple backtick fences, like this:
|
||||
|
||||
````
|
||||
Here's some code:
|
||||
|
||||
```
|
||||
print("hello")
|
||||
```
|
||||
````
|
||||
|
||||
But if you've added files to the chat that contain triple backticks,
|
||||
aider needs to tell the LLM to use a different set of fences.
|
||||
Otherwise, the LLM can't safely include your code's triple backticks
|
||||
inside the code blocks that it returns with edits.
|
||||
Aider will use fences like `<source>...</source>` in this case.
|
||||
|
||||
A side effect of this is that the code that aider outputs may no
|
||||
longer be properly highlighted.
|
||||
You will most often notice this if you add markdown files
|
||||
to you chats that contain code blocks.
|
||||
|
||||
## Why is the LLM speaking to me in an unexpected language?
|
||||
|
||||
Aider goes to some effort to prompt the model to use the language that is configured
|
||||
|
||||
@@ -5,41 +5,118 @@ nav_order: 20
|
||||
description: How to install and get started pair programming with aider.
|
||||
---
|
||||
|
||||
# Quick start
|
||||
# Installation
|
||||
{: .no_toc }
|
||||
|
||||
|
||||
## Get started quickly with aider-install
|
||||
|
||||
{% include get-started.md %}
|
||||
|
||||
Or see the
|
||||
[full installation instructions](/docs/install/install.html)
|
||||
for more details,
|
||||
or the
|
||||
[usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
|
||||
This will install aider in its own separate python environment.
|
||||
If needed,
|
||||
aider-install will also install a separate version of python 3.12 to use with aider.
|
||||
|
||||
Once aider is installed,
|
||||
there are also some [optional install steps](/docs/install/optional.html).
|
||||
|
||||
See the [usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
|
||||
|
||||
## One-liners
|
||||
|
||||
These one-liners will install aider, along with python 3.12 if needed.
|
||||
They are based on the
|
||||
[uv installers](https://docs.astral.sh/uv/getting-started/installation/).
|
||||
|
||||
#### Windows
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy ByPass -c "irm https://aider.chat/install.ps1 | iex"
|
||||
```
|
||||
|
||||
#### Mac & Linux
|
||||
|
||||
Use curl to download the script and execute it with sh:
|
||||
|
||||
```bash
|
||||
curl -LsSf https://aider.chat/install.sh | sh
|
||||
```
|
||||
|
||||
If your system doesn't have curl, you can use wget:
|
||||
|
||||
```bash
|
||||
wget -qO- https://aider.chat/install.sh | sh
|
||||
```
|
||||
|
||||
|
||||
## Install with uv
|
||||
|
||||
You can install aider with uv:
|
||||
|
||||
```bash
|
||||
python -m pip install uv # If you need to install uv
|
||||
uv tool install --force --python python3.12 aider-chat@latest
|
||||
```
|
||||
|
||||
This will install uv using your existing python version 3.8-3.13,
|
||||
and use it to install aider.
|
||||
If needed,
|
||||
uv will automatically install a separate python 3.12 to use with aider.
|
||||
|
||||
Also see the
|
||||
[docs on other methods for installing uv itself](https://docs.astral.sh/uv/getting-started/installation/).
|
||||
|
||||
## Install with pipx
|
||||
|
||||
You can install aider with pipx:
|
||||
|
||||
```bash
|
||||
python -m pip install pipx # If you need to install pipx
|
||||
pipx install aider-chat
|
||||
```
|
||||
|
||||
You can use pipx to install aider with python versions 3.9-3.12.
|
||||
|
||||
Also see the
|
||||
[docs on other methods for installing pipx itself](https://pipx.pypa.io/stable/installation/).
|
||||
|
||||
## Other install methods
|
||||
|
||||
You can install aider with the methods described below, but one of the above
|
||||
methods is usually safer.
|
||||
|
||||
#### Install with pip
|
||||
|
||||
If you install with pip, you should consider
|
||||
using a
|
||||
[virtual environment](https://docs.python.org/3/library/venv.html)
|
||||
to keep aider's dependencies separated.
|
||||
|
||||
|
||||
You can use pip to install aider with python versions 3.9-3.12.
|
||||
|
||||
```bash
|
||||
# Install aider
|
||||
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
|
||||
|
||||
# To work with GPT-4o:
|
||||
aider --4o --openai-api-key sk-xxx...
|
||||
|
||||
# To work with Claude 3.5 Sonnet:
|
||||
aider --sonnet --anthropic-api-key sk-xxx...
|
||||
```
|
||||
|
||||
{% include python-m-aider.md %}
|
||||
|
||||
<div class="video-container">
|
||||
<video controls poster="/assets/install.jpg">
|
||||
<source src="/assets/install.mp4" type="video/mp4">
|
||||
<a href="/assets/install.mp4">Installing aider</a>
|
||||
</video>
|
||||
</div>
|
||||
#### Installing with package managers
|
||||
|
||||
<style>
|
||||
.video-container {
|
||||
position: relative;
|
||||
padding-bottom: 76.2711864407%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.video-container video {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
It's best to install aider using one of methods
|
||||
recommended above.
|
||||
While aider is available in a number of system package managers,
|
||||
they often install aider with incorrect dependencies.
|
||||
|
||||
## Next steps...
|
||||
|
||||
There are some [optional install steps](/docs/install/optional.html) you could consider.
|
||||
See the [usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ nav_order: 900
|
||||
|
||||
You can use aider in GitHub Codespaces via the built-in Terminal pane.
|
||||
See below for an example,
|
||||
but you can see the
|
||||
but you can just follow the
|
||||
[main install instructions](/docs/install.html)
|
||||
for all the details.
|
||||
inside your codespace terminal.
|
||||
|
||||
|
||||
<div class="video-container">
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
parent: Installation
|
||||
nav_order: 10
|
||||
---
|
||||
|
||||
# Installing aider
|
||||
{: .no_toc }
|
||||
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
## Python version
|
||||
|
||||
Aider currently works with python 3.9-3.12.
|
||||
|
||||
## Install git
|
||||
|
||||
Make sure you have git installed.
|
||||
Here are
|
||||
[instructions for installing git in various environments](https://github.com/git-guides/install-git).
|
||||
|
||||
## Get your API key
|
||||
|
||||
To work with OpenAI's models like GPT-4o or GPT-3.5 you need a paid
|
||||
[OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key).
|
||||
Note that this is different than being a "ChatGPT Plus" subscriber.
|
||||
|
||||
To work with Anthropic's models like Claude 3.5 Sonnet you need a paid
|
||||
[Anthropic API key](https://docs.anthropic.com/claude/reference/getting-started-with-the-api).
|
||||
|
||||
|
||||
{% include venv-pipx.md %}
|
||||
|
||||
## Mac/Linux install
|
||||
|
||||
```
|
||||
# Install aider
|
||||
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
|
||||
|
||||
# To work with GPT-4o:
|
||||
$ aider --4o --openai-api-key sk-xxx...
|
||||
|
||||
# To work with Claude 3.5 Sonnet:
|
||||
$ aider --sonnet --anthropic-api-key sk-xxx...
|
||||
```
|
||||
|
||||
## Windows install
|
||||
|
||||
```
|
||||
# Install aider
|
||||
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
|
||||
|
||||
# To work with GPT-4o:
|
||||
$ aider --4o --openai-api-key sk-xxx...
|
||||
|
||||
# To work with Claude 3.5 Sonnet:
|
||||
$ aider --sonnet --anthropic-api-key sk-xxx...
|
||||
```
|
||||
|
||||
{% include python-m-aider.md %}
|
||||
|
||||
## Working with other LLMs
|
||||
|
||||
{% include works-best.md %}
|
||||
|
||||
## You are done!
|
||||
|
||||
There are some [optional install steps](/docs/install/optional.html) you could consider.
|
||||
See the [usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
|
||||
|
||||
@@ -11,10 +11,29 @@ The steps below are completely optional.
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
## Install git
|
||||
|
||||
## Store your api keys
|
||||
Aider works best if you have git installed.
|
||||
Here are
|
||||
[instructions for installing git in various environments](https://github.com/git-guides/install-git).
|
||||
|
||||
You can [store your api keys in a .env file](/docs/config/dotenv.html)
|
||||
## Get your API key
|
||||
|
||||
To work with OpenAI's models like GPT-4o or o1-preview you need a paid
|
||||
[OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key).
|
||||
Note that this is different than being a "ChatGPT Plus" subscriber.
|
||||
|
||||
To work with Anthropic's models like Claude 3.5 Sonnet you need a paid
|
||||
[Anthropic API key](https://docs.anthropic.com/claude/reference/getting-started-with-the-api).
|
||||
|
||||
|
||||
### Working with other LLMs
|
||||
|
||||
{% include works-best.md %}
|
||||
|
||||
### Store your api keys
|
||||
|
||||
You can [store your api keys in configuration or env files](/docs/config/api-keys.html)
|
||||
and they will be loaded automatically whenever you run aider.
|
||||
|
||||
## Enable Playwright
|
||||
@@ -55,13 +74,17 @@ Installing PortAudio is completely optional, but can usually be accomplished lik
|
||||
- For Linux, do `sudo apt-get install libportaudio2`
|
||||
- Some linux environments may also need `sudo apt install libasound2-plugins`
|
||||
|
||||
## Add aider to your editor
|
||||
## Add aider to your IDE/editor
|
||||
|
||||
Other projects have integrated aider into some IDE/editors.
|
||||
It's not clear if they are tracking the latest
|
||||
You can use
|
||||
[aider's `--watch-files` mode](https://aider.chat/docs/usage/watch.html)
|
||||
to integrate with any IDE or editor.
|
||||
|
||||
There are a number of 3rd party aider plugins for various IDE/editors.
|
||||
It's not clear how well they are tracking the latest
|
||||
versions of aider,
|
||||
so it may be best to just run the latest
|
||||
aider in a terminal alongside your editor.
|
||||
aider in a terminal alongside your editor and use `--watch-files`.
|
||||
|
||||
### NeoVim
|
||||
|
||||
@@ -71,29 +94,22 @@ aider in a terminal alongside your editor.
|
||||
|
||||
### VS Code
|
||||
|
||||
joshuavial also confirmed that aider works inside a VS Code terminal window.
|
||||
Aider detects if it is running inside VSCode and turns off pretty/color output,
|
||||
since the VSCode terminal doesn't seem to support it well.
|
||||
You can run aider inside a VS Code terminal window.
|
||||
There are a number of 3rd party
|
||||
[aider plugins for VSCode](https://marketplace.visualstudio.com/search?term=aider%20-kodu&target=VSCode&category=All%20categories&sortBy=Relevance).
|
||||
|
||||
### Other editors
|
||||
|
||||
If you are interested in creating an aider plugin for your favorite editor,
|
||||
please let me know by opening a
|
||||
please let us know by opening a
|
||||
[GitHub issue](https://github.com/Aider-AI/aider/issues).
|
||||
|
||||
|
||||
## Install the development version of aider
|
||||
|
||||
If you want the very latest development version of aider
|
||||
you can install directly from GitHub:
|
||||
you can install it like this:
|
||||
|
||||
```
|
||||
python -m pip install --upgrade git+https://github.com/Aider-AI/aider.git
|
||||
aider --install-main-branch
|
||||
```
|
||||
|
||||
If you've git cloned the aider repository already, you can install "live" from your local copy. This is mostly useful if you are developing aider and want your current modifications to take effect immediately.
|
||||
|
||||
```
|
||||
python -m pip install -e .
|
||||
```
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
parent: Installation
|
||||
nav_order: 100
|
||||
---
|
||||
|
||||
# Install with pipx
|
||||
|
||||
If you are using aider to work on a python project, sometimes your project will require
|
||||
specific versions of python packages which conflict with the versions that aider
|
||||
requires.
|
||||
If this happens, the `python -m pip install` command may return errors like these:
|
||||
|
||||
```
|
||||
aider-chat 0.23.0 requires somepackage==X.Y.Z, but you have somepackage U.W.V which is incompatible.
|
||||
```
|
||||
|
||||
You can avoid this problem by installing aider using `pipx`,
|
||||
which will install it globally on your system
|
||||
within its own python environment.
|
||||
This way you can use aider to work on any python project,
|
||||
even if that project has conflicting dependencies.
|
||||
|
||||
Install [pipx](https://pipx.pypa.io/stable/) then just do:
|
||||
|
||||
```
|
||||
pipx install aider-chat
|
||||
```
|
||||
|
||||
|
||||
## pipx on replit
|
||||
|
||||
{% include replit-pipx.md %}
|
||||
|
||||
8
aider/website/docs/install/replit.md
Normal file
8
aider/website/docs/install/replit.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
parent: Installation
|
||||
nav_order: 900
|
||||
---
|
||||
|
||||
### Replit
|
||||
|
||||
{% include replit-pipx.md %}
|
||||
10
aider/website/docs/leaderboards/by-release-date.md
Normal file
10
aider/website/docs/leaderboards/by-release-date.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Scores by release date
|
||||
parent: Aider LLM Leaderboards
|
||||
nav_order: 200
|
||||
---
|
||||
|
||||
## LLM code editing skill by model release date
|
||||
|
||||
[](https://aider.chat/assets/models-over-time.svg)
|
||||
|
||||
14
aider/website/docs/leaderboards/contrib.md
Normal file
14
aider/website/docs/leaderboards/contrib.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
parent: Aider LLM Leaderboards
|
||||
nav_order: 900
|
||||
---
|
||||
|
||||
# Contributing results
|
||||
|
||||
Contributions of benchmark results are welcome!
|
||||
See the
|
||||
[benchmark README](https://github.com/Aider-AI/aider/blob/main/benchmark/README.md)
|
||||
for information on running aider's code editing benchmarks.
|
||||
Submit results by opening a PR with edits to the
|
||||
[benchmark results data files](https://github.com/Aider-AI/aider/blob/main/aider/website/_data/).
|
||||
|
||||
134
aider/website/docs/leaderboards/edit.md
Normal file
134
aider/website/docs/leaderboards/edit.md
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
parent: Aider LLM Leaderboards
|
||||
highlight_image: /assets/leaderboard.jpg
|
||||
nav_order: 50
|
||||
description: Quantitative benchmark of basic LLM code editing skill.
|
||||
---
|
||||
|
||||
# Code editing leaderboard
|
||||
|
||||
|
||||
{: .note :}
|
||||
This old
|
||||
[aider code editing leaderboard](edit.html)
|
||||
has been replaced by the
|
||||
new, much more challenging
|
||||
[polyglot leaderboard](/docs/leaderboards/).
|
||||
|
||||
[Aider's code editing benchmark](/docs/benchmarks.html#the-benchmark) asks the LLM to edit python source files to complete 133 small coding exercises
|
||||
from Exercism.
|
||||
This measures the LLM's coding ability, and whether it can
|
||||
write new code that integrates into existing code.
|
||||
The model also has to successfully apply all its changes to the source file without human intervention.
|
||||
|
||||
<input type="text" id="editSearchInput" placeholder="Search..." style="width: 100%; max-width: 800px; margin: 10px auto; padding: 8px; display: block; border: 1px solid #ddd; border-radius: 4px;">
|
||||
|
||||
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
|
||||
<thead style="background-color: #f2f2f2;">
|
||||
<tr>
|
||||
<th style="padding: 8px; text-align: left;">Model</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
|
||||
<th style="padding: 8px; text-align: left;">Command</th>
|
||||
<th style="padding: 8px; text-align: center;">Edit format</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% assign edit_sorted = site.data.edit_leaderboard | sort: 'pass_rate_2' | reverse %}
|
||||
{% for row in edit_sorted %}
|
||||
<tr style="border-bottom: 1px solid #ddd;">
|
||||
<td style="padding: 8px;">{{ row.model }}</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_2 }}%</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
|
||||
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
||||
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
{% assign data_source = edit_sorted %}
|
||||
{% assign pass_rate_field = "pass_rate_2" %}
|
||||
{% include leaderboard.js %}
|
||||
</script>
|
||||
<style>
|
||||
tr.selected {
|
||||
color: #0056b3;
|
||||
}
|
||||
table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
td, th {
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
td:nth-child(3), td:nth-child(4) {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
## Notes on benchmarking results
|
||||
|
||||
The key benchmarking results are:
|
||||
|
||||
- **Percent completed correctly** - Measures what percentage of the coding tasks that the LLM completed successfully. To complete a task, the LLM must solve the programming assignment *and* edit the code to implement that solution.
|
||||
- **Percent using correct edit format** - Measures the percent of coding tasks where the LLM complied with the edit format specified in the system prompt. If the LLM makes edit mistakes, aider will give it feedback and ask for a fixed copy of the edit. The best models can reliably conform to the edit format, without making errors.
|
||||
|
||||
|
||||
## Notes on the edit format
|
||||
|
||||
Aider uses different "edit formats" to collect code edits from different LLMs.
|
||||
The "whole" format is the easiest for an LLM to use, but it uses a lot of tokens
|
||||
and may limit how large a file can be edited.
|
||||
Models which can use one of the diff formats are much more efficient,
|
||||
using far fewer tokens.
|
||||
Models that use a diff-like format are able to
|
||||
edit larger files with less cost and without hitting token limits.
|
||||
|
||||
Aider is configured to use the best edit format for the popular OpenAI and Anthropic models
|
||||
and the [other models recommended on the LLM page](/docs/llms.html).
|
||||
For lesser known models aider will default to using the "whole" editing format
|
||||
since it is the easiest format for an LLM to use.
|
||||
|
||||
## Contributing benchmark results
|
||||
|
||||
Contributions of benchmark results are welcome!
|
||||
See the
|
||||
[benchmark README](https://github.com/Aider-AI/aider/blob/main/benchmark/README.md)
|
||||
for information on running aider's code editing benchmarks.
|
||||
Submit results by opening a PR with edits to the
|
||||
[benchmark results data files](https://github.com/Aider-AI/aider/blob/main/aider/website/_data/).
|
||||
|
||||
|
||||
<p class="post-date">
|
||||
By Paul Gauthier,
|
||||
last updated
|
||||
<!--[[[cog
|
||||
import subprocess
|
||||
import datetime
|
||||
|
||||
files = [
|
||||
'aider/website/docs/leaderboards/index.md',
|
||||
'aider/website/_data/edit_leaderboard.yml',
|
||||
'aider/website/_data/refactor_leaderboard.yml'
|
||||
]
|
||||
|
||||
def get_last_modified_date(file):
|
||||
result = subprocess.run(['git', 'log', '-1', '--format=%ct', file], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
timestamp = int(result.stdout.strip())
|
||||
return datetime.datetime.fromtimestamp(timestamp)
|
||||
return datetime.datetime.min
|
||||
|
||||
mod_dates = [get_last_modified_date(file) for file in files]
|
||||
latest_mod_date = max(mod_dates)
|
||||
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
|
||||
]]]-->
|
||||
December 16, 2024.
|
||||
<!--[[[end]]]-->
|
||||
</p>
|
||||
@@ -2,32 +2,43 @@
|
||||
highlight_image: /assets/leaderboard.jpg
|
||||
nav_order: 950
|
||||
description: Quantitative benchmarks of LLM code editing skill.
|
||||
has_children: true
|
||||
---
|
||||
|
||||
|
||||
# Aider LLM Leaderboards
|
||||
{: .no_toc }
|
||||
|
||||
Aider works best with LLMs which are good at *editing* code, not just good at writing
|
||||
code.
|
||||
To evaluate an LLM's editing skill, aider uses a pair of benchmarks that
|
||||
To evaluate an LLM's editing skill, aider uses benchmarks that
|
||||
assess a model's ability to consistently follow the system prompt
|
||||
to successfully edit code.
|
||||
|
||||
The leaderboards below report the results from a number of popular LLMs.
|
||||
The leaderboards report the results from a number of popular LLMs.
|
||||
While [aider can connect to almost any LLM](/docs/llms.html),
|
||||
it works best with models that score well on the benchmarks.
|
||||
|
||||
See the following sections for benchmark
|
||||
results and additional information:
|
||||
- TOC
|
||||
{:toc}
|
||||
|
||||
## Code editing leaderboard
|
||||
{: .note :}
|
||||
The
|
||||
[original aider code editing leaderboard](edit.html)
|
||||
has been replaced by this
|
||||
new, much more challenging
|
||||
[polyglot leaderboard](https://aider.chat/2024/12/21/polyglot.html).
|
||||
|
||||
[Aider's code editing benchmark](/docs/benchmarks.html#the-benchmark) asks the LLM to edit python source files to complete 133 small coding exercises
|
||||
## Polyglot leaderboard
|
||||
|
||||
[Aider's polyglot benchmark](/docs/benchmarks.html#the-benchmark)
|
||||
asks the LLM to edit source files to complete 225 coding exercises
|
||||
from Exercism.
|
||||
This measures the LLM's coding ability, and whether it can
|
||||
It contains exercises in many popular programming languages:
|
||||
C++, Go, Java, JavaScript, Python and Rust.
|
||||
The 225 exercises were purposely selected to be the *hardest*
|
||||
that Exercism offered in those languages, to provide
|
||||
a strong coding challenge to LLMs.
|
||||
|
||||
This benchmark measures the LLM's coding ability in popular languages,
|
||||
and whether it can
|
||||
write new code that integrates into existing code.
|
||||
The model also has to successfully apply all its changes to the source file without human intervention.
|
||||
|
||||
@@ -44,7 +55,7 @@ The model also has to successfully apply all its changes to the source file with
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% assign edit_sorted = site.data.edit_leaderboard | sort: 'pass_rate_2' | reverse %}
|
||||
{% assign edit_sorted = site.data.polyglot_leaderboard | sort: 'pass_rate_2' | reverse %}
|
||||
{% for row in edit_sorted %}
|
||||
<tr style="border-bottom: 1px solid #ddd;">
|
||||
<td style="padding: 8px;">{{ row.model }}</td>
|
||||
@@ -57,10 +68,16 @@ The model also has to successfully apply all its changes to the source file with
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Aider polyglot benchmark results
|
||||
|
||||
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
||||
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
{% include edit-leaderboard.js %}
|
||||
{% assign data_source = edit_sorted %}
|
||||
{% assign pass_rate_field = "pass_rate_2" %}
|
||||
{% assign highlight_model = "xxxxxxxxxxx" %}
|
||||
{% include leaderboard.js %}
|
||||
</script>
|
||||
<style>
|
||||
tr.selected {
|
||||
@@ -78,83 +95,7 @@ The model also has to successfully apply all its changes to the source file with
|
||||
}
|
||||
</style>
|
||||
|
||||
## Code refactoring leaderboard
|
||||
|
||||
[Aider's refactoring benchmark](https://github.com/Aider-AI/refactor-benchmark) asks the LLM to refactor 89 large methods from large python classes. This is a more challenging benchmark, which tests the model's ability to output long chunks of code without skipping sections or making mistakes. It was developed to provoke and measure [GPT-4 Turbo's "lazy coding" habit](/2023/12/21/unified-diffs.html).
|
||||
|
||||
The refactoring benchmark requires a large context window to
|
||||
work with large source files.
|
||||
Therefore, results are available for fewer models.
|
||||
|
||||
<input type="text" id="refacSearchInput" placeholder="Search..." style="width: 100%; max-width: 800px; margin: 10px auto; padding: 8px; display: block; border: 1px solid #ddd; border-radius: 4px;">
|
||||
|
||||
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
|
||||
<thead style="background-color: #f2f2f2;">
|
||||
<tr>
|
||||
<th style="padding: 8px; text-align: left;">Model</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
|
||||
<th style="padding: 8px; text-align: left;">Command</th>
|
||||
<th style="padding: 8px; text-align: center;">Edit format</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% assign refac_sorted = site.data.refactor_leaderboard | sort: 'pass_rate_1' | reverse %}
|
||||
{% for row in refac_sorted %}
|
||||
<tr style="border-bottom: 1px solid #ddd;">
|
||||
<td style="padding: 8px;">{{ row.model }}</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_1 }}%</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
|
||||
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<canvas id="refacChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
{% include refactor-leaderboard.js %}
|
||||
</script>
|
||||
|
||||
|
||||
## LLM code editing skill by model release date
|
||||
|
||||
[](https://aider.chat/assets/models-over-time.svg)
|
||||
|
||||
|
||||
## Notes on benchmarking results
|
||||
|
||||
The key benchmarking results are:
|
||||
|
||||
- **Percent completed correctly** - Measures what percentage of the coding tasks that the LLM completed successfully. To complete a task, the LLM must solve the programming assignment *and* edit the code to implement that solution.
|
||||
- **Percent using correct edit format** - Measures the percent of coding tasks where the LLM complied with the edit format specified in the system prompt. If the LLM makes edit mistakes, aider will give it feedback and ask for a fixed copy of the edit. The best models can reliably conform to the edit format, without making errors.
|
||||
|
||||
|
||||
## Notes on the edit format
|
||||
|
||||
Aider uses different "edit formats" to collect code edits from different LLMs.
|
||||
The "whole" format is the easiest for an LLM to use, but it uses a lot of tokens
|
||||
and may limit how large a file can be edited.
|
||||
Models which can use one of the diff formats are much more efficient,
|
||||
using far fewer tokens.
|
||||
Models that use a diff-like format are able to
|
||||
edit larger files with less cost and without hitting token limits.
|
||||
|
||||
Aider is configured to use the best edit format for the popular OpenAI and Anthropic models
|
||||
and the [other models recommended on the LLM page](/docs/llms.html).
|
||||
For lesser known models aider will default to using the "whole" editing format
|
||||
since it is the easiest format for an LLM to use.
|
||||
|
||||
## Contributing benchmark results
|
||||
|
||||
Contributions of benchmark results are welcome!
|
||||
See the
|
||||
[benchmark README](https://github.com/Aider-AI/aider/blob/main/benchmark/README.md)
|
||||
for information on running aider's code editing benchmarks.
|
||||
Submit results by opening a PR with edits to the
|
||||
[benchmark results data files](https://github.com/Aider-AI/aider/blob/main/aider/website/_data/).
|
||||
|
||||
|
||||
<p class="post-date">
|
||||
@@ -181,6 +122,6 @@ mod_dates = [get_last_modified_date(file) for file in files]
|
||||
latest_mod_date = max(mod_dates)
|
||||
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
|
||||
]]]-->
|
||||
November 28, 2024.
|
||||
December 26, 2024.
|
||||
<!--[[[end]]]-->
|
||||
</p>
|
||||
|
||||
29
aider/website/docs/leaderboards/notes.md
Normal file
29
aider/website/docs/leaderboards/notes.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
parent: Aider LLM Leaderboards
|
||||
nav_order: 800
|
||||
---
|
||||
|
||||
# Benchmark notes
|
||||
|
||||
## Notes on benchmarking results
|
||||
|
||||
The key benchmarking results are:
|
||||
|
||||
- **Percent completed correctly** - Measures what percentage of the coding tasks that the LLM completed successfully. To complete a task, the LLM must solve the programming assignment *and* edit the code to implement that solution.
|
||||
- **Percent using correct edit format** - Measures the percent of coding tasks where the LLM complied with the edit format specified in the system prompt. If the LLM makes edit mistakes, aider will give it feedback and ask for a fixed copy of the edit. The best models can reliably conform to the edit format, without making errors.
|
||||
|
||||
|
||||
## Notes on the edit format
|
||||
|
||||
Aider uses different "edit formats" to collect code edits from different LLMs.
|
||||
The "whole" format is the easiest for an LLM to use, but it uses a lot of tokens
|
||||
and may limit how large a file can be edited.
|
||||
Models which can use one of the diff formats are much more efficient,
|
||||
using far fewer tokens.
|
||||
Models that use a diff-like format are able to
|
||||
edit larger files with less cost and without hitting token limits.
|
||||
|
||||
Aider is configured to use the best edit format for the popular OpenAI and Anthropic models
|
||||
and the [other models recommended on the LLM page](/docs/llms.html).
|
||||
For lesser known models aider will default to using the "whole" editing format
|
||||
since it is the easiest format for an LLM to use.
|
||||
52
aider/website/docs/leaderboards/refactor.md
Normal file
52
aider/website/docs/leaderboards/refactor.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
parent: Aider LLM Leaderboards
|
||||
highlight_image: /assets/leaderboard.jpg
|
||||
nav_order: 100
|
||||
description: Quantitative benchmark of LLM code refactoring skill.
|
||||
---
|
||||
|
||||
|
||||
## Refactoring leaderboard
|
||||
|
||||
[Aider's refactoring benchmark](https://github.com/Aider-AI/refactor-benchmark) asks the LLM to refactor 89 large methods from large python classes. This is a more challenging benchmark, which tests the model's ability to output long chunks of code without skipping sections or making mistakes. It was developed to provoke and measure [GPT-4 Turbo's "lazy coding" habit](/2023/12/21/unified-diffs.html).
|
||||
|
||||
The refactoring benchmark requires a large context window to
|
||||
work with large source files.
|
||||
Therefore, results are available for fewer models.
|
||||
|
||||
<input type="text" id="editSearchInput" placeholder="Search..." style="width: 100%; max-width: 800px; margin: 10px auto; padding: 8px; display: block; border: 1px solid #ddd; border-radius: 4px;">
|
||||
|
||||
<table style="width: 100%; max-width: 800px; margin: auto; border-collapse: collapse; box-shadow: 0 2px 4px rgba(0,0,0,0.1); font-size: 14px;">
|
||||
<thead style="background-color: #f2f2f2;">
|
||||
<tr>
|
||||
<th style="padding: 8px; text-align: left;">Model</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent completed correctly</th>
|
||||
<th style="padding: 8px; text-align: center;">Percent using correct edit format</th>
|
||||
<th style="padding: 8px; text-align: left;">Command</th>
|
||||
<th style="padding: 8px; text-align: center;">Edit format</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% assign refac_sorted = site.data.refactor_leaderboard | sort: 'pass_rate_1' | reverse %}
|
||||
{% for row in refac_sorted %}
|
||||
<tr style="border-bottom: 1px solid #ddd;">
|
||||
<td style="padding: 8px;">{{ row.model }}</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.pass_rate_1 }}%</td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.percent_cases_well_formed }}%</td>
|
||||
<td style="padding: 8px;"><code>{{ row.command }}</code></td>
|
||||
<td style="padding: 8px; text-align: center;">{{ row.edit_format }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
||||
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
{% assign data_source = refac_sorted %}
|
||||
{% assign pass_rate_field = "pass_rate_1" %}
|
||||
{% include leaderboard.js %}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ We make reasonable efforts to protect your information by using physical and ele
|
||||
|
||||
### Children’s 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>
|
||||
|
||||
@@ -39,12 +39,24 @@ 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
|
||||
```
|
||||
|
||||
You must install `boto3` dependency to aider's virtual environment installed via one-liner or uv by running
|
||||
|
||||
```bash
|
||||
uv tool run --from aider-chat pip install boto3
|
||||
```
|
||||
|
||||
|
||||
@@ -56,12 +68,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/
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -95,6 +95,8 @@ cog.out(''.join(lines))
|
||||
- TOGETHERAI_API_KEY
|
||||
- VOLCENGINE_API_KEY
|
||||
- VOYAGE_API_KEY
|
||||
- WATSONX_API_KEY
|
||||
- WX_API_KEY
|
||||
- XAI_API_KEY
|
||||
- XINFERENCE_API_KEY
|
||||
<!--[[[end]]]-->
|
||||
|
||||
@@ -20,7 +20,7 @@ copy of each source file that needs changes.
|
||||
While simple, it can be slow and costly because the LLM has to return
|
||||
the *entire file* even if just a few lines are edited.
|
||||
|
||||
The format expects the file path just before the fenced file content:
|
||||
The whole format expects the file path just before the fenced file content:
|
||||
|
||||
````
|
||||
show_greeting.py
|
||||
@@ -28,7 +28,7 @@ show_greeting.py
|
||||
import sys
|
||||
|
||||
def greeting(name):
|
||||
print(f"Hey {{name}}")
|
||||
print("Hey", name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
greeting(sys.argv[1])
|
||||
@@ -42,7 +42,7 @@ The "diff" edit format asks the LLM to specify file edits as a series of search/
|
||||
This is an efficient format, because the model only needs to return parts of the file
|
||||
which have changes.
|
||||
|
||||
They are formatted using a syntax similar to the git merge conflict resolution markings,
|
||||
Edits are formatted using a syntax similar to the git merge conflict resolution markings,
|
||||
with the file path right before a fenced block:
|
||||
|
||||
````
|
||||
@@ -62,7 +62,7 @@ from flask import Flask
|
||||
The "diff-fenced" edit format is based on the diff format, but
|
||||
the file path is placed inside the fence.
|
||||
It is primarily used with the Gemini family of models,
|
||||
which often fail to conform to fencing approach specified in the diff format.
|
||||
which often fail to conform to the fencing approach specified in the diff format.
|
||||
|
||||
````
|
||||
```
|
||||
@@ -84,7 +84,10 @@ This is an efficient format, because the model only needs to return parts of the
|
||||
which have changes.
|
||||
|
||||
It was mainly used to the GPT-4 Turbo family of models,
|
||||
to reduce their "lazy coding" tendencies with other edit formats.
|
||||
because it reduced their "lazy coding" tendencies.
|
||||
With other edit formats the GPT-4 Turbo models tended to elide
|
||||
large sections of code and replace them with "# ... original code here ..."
|
||||
style comments.
|
||||
|
||||
|
||||
````
|
||||
@@ -104,3 +107,10 @@ to reduce their "lazy coding" tendencies with other edit formats.
|
||||
These are streamlined versions of the diff and whole formats, intended to be used
|
||||
with `--editor-edit-format` when using
|
||||
[architect mode](/docs/usage/modes.html).
|
||||
The actual edit format is the same, but aider uses a simpler prompt that
|
||||
is more narrowly focused on just editing the file as opposed to
|
||||
solving the coding task.
|
||||
The architect model resolves the coding task and
|
||||
provides plain text instructions about which file changes need to be made.
|
||||
The editor interprets those instructions to produce the
|
||||
syntactically correct diff or whole edits.
|
||||
|
||||
@@ -65,14 +65,15 @@ cog.out(model_list)
|
||||
- claude-3-sonnet-20240229
|
||||
- codestral/codestral-2405
|
||||
- codestral/codestral-latest
|
||||
- deepseek-chat
|
||||
- deepseek-coder
|
||||
- deepseek/deepseek-chat
|
||||
- deepseek/deepseek-coder
|
||||
- eu.anthropic.claude-3-5-sonnet-20241022-v2:0
|
||||
- mistral/codestral-2405
|
||||
- mistral/codestral-latest
|
||||
- mistral/codestral-mamba-latest
|
||||
- mistral/mistral-large-2402
|
||||
- mistral/mistral-large-2407
|
||||
- mistral/mistral-large-2411
|
||||
- mistral/mistral-large-latest
|
||||
- mistral/mistral-medium
|
||||
- mistral/mistral-medium-2312
|
||||
@@ -87,6 +88,8 @@ cog.out(model_list)
|
||||
- mistral/open-mixtral-8x22b
|
||||
- mistral/open-mixtral-8x7b
|
||||
- mistral/pixtral-12b-2409
|
||||
- mistral/pixtral-large-2411
|
||||
- mistral/pixtral-large-latest
|
||||
- openrouter/anthropic/claude-3.5-sonnet
|
||||
- us.anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
- us.anthropic.claude-3-5-sonnet-20241022-v2:0
|
||||
|
||||
@@ -14,12 +14,11 @@ You may see an error message like this:
|
||||
|
||||
> aider: The term 'aider' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
|
||||
|
||||
Below is the most fail safe way to install and run aider in these situations:
|
||||
Below is the most fail safe way to run aider in these situations:
|
||||
|
||||
```
|
||||
python -m pip install -U aider-chat
|
||||
python -m aider
|
||||
```
|
||||
|
||||
|
||||
{% include venv-pipx.md %}
|
||||
You should also consider
|
||||
[installing aider using aider-install, uv or pipx](/docs/install.html).
|
||||
|
||||
@@ -5,7 +5,7 @@ nav_order: 28
|
||||
|
||||
# Dependency versions
|
||||
|
||||
Aider expects to be installed via `pip` or `pipx`, which will install
|
||||
Aider expects to be installed with the
|
||||
correct versions of all of its required dependencies.
|
||||
|
||||
If you've been linked to this doc from a GitHub issue,
|
||||
@@ -13,43 +13,38 @@ or if aider is reporting `ImportErrors`
|
||||
it is likely that your
|
||||
aider install is using incorrect dependencies.
|
||||
|
||||
## Install with pipx
|
||||
|
||||
## Avoid package conflicts
|
||||
|
||||
If you are using aider to work on a python project, sometimes your project will require
|
||||
specific versions of python packages which conflict with the versions that aider
|
||||
requires.
|
||||
If this happens, you may see errors like these when running pip installs:
|
||||
|
||||
```
|
||||
aider-chat 0.23.0 requires somepackage==X.Y.Z, but you have somepackage U.W.V which is incompatible.
|
||||
```
|
||||
|
||||
## Install with aider-install, uv or pipx
|
||||
|
||||
If you are having dependency problems you should consider
|
||||
[installing aider using pipx](/docs/install/pipx.html).
|
||||
[installing aider using aider-install, uv or pipx](/docs/install.html).
|
||||
This will ensure that aider is installed in its own python environment,
|
||||
with the correct set of dependencies.
|
||||
|
||||
Try re-installing cleanly:
|
||||
|
||||
```
|
||||
pipx uninstall aider-chat
|
||||
pipx install aider-chat
|
||||
```
|
||||
|
||||
## Package managers like Homebrew, AUR, ports
|
||||
|
||||
Package managers often install aider with the wrong dependencies, leading
|
||||
to import errors and other problems.
|
||||
|
||||
The recommended way to
|
||||
install aider is with
|
||||
[pip](/docs/install/install.html).
|
||||
Be sure to use the `--upgrade-strategy only-if-needed` switch so that the correct
|
||||
versions of dependencies will be installed.
|
||||
It is recommended to
|
||||
[install aider using aider-install, uv or pipx](/docs/install.html).
|
||||
|
||||
```
|
||||
python -m pip install -U --upgrade-strategy only-if-needed aider-chat
|
||||
```
|
||||
|
||||
A very safe way is to
|
||||
[install aider using pipx](/docs/install/pipx.html),
|
||||
which will ensure it is installed in a stand alone virtual environment.
|
||||
|
||||
## Dependency versions matter
|
||||
|
||||
Aider pins its dependencies and is tested to work with those specific versions.
|
||||
If you are installing aider with pip (rather than pipx),
|
||||
If you are installing aider directly with pip
|
||||
you should be careful about upgrading or downgrading the python packages that
|
||||
aider uses.
|
||||
|
||||
@@ -64,9 +59,4 @@ and sometimes introduces bugs or backwards incompatible changes.
|
||||
|
||||
## Replit
|
||||
|
||||
You can `pip install -U aider-chat` on replit.
|
||||
|
||||
Or you can install aider with
|
||||
pipx as follows:
|
||||
|
||||
{% include replit-pipx.md %}
|
||||
|
||||
@@ -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](https://aider.chat/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
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user