mirror of
https://github.com/Aider-AI/aider
synced 2026-04-26 01:25:17 +02:00
Compare commits
744 Commits
v0.65.2.de
...
v0.69.2.de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
c62dde4c9c | ||
|
|
3fef1babcb | ||
|
|
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 | ||
|
|
16af1751a6 | ||
|
|
b0e138952e | ||
|
|
1271c037ef | ||
|
|
36b59ba617 | ||
|
|
b671db7108 | ||
|
|
9304b80b69 | ||
|
|
03c2964364 | ||
|
|
49c78f2797 | ||
|
|
1a8d112055 | ||
|
|
7b193d693f | ||
|
|
e8fa5c36c2 | ||
|
|
c9a27ba6ac | ||
|
|
a6e162c37a | ||
|
|
9c55b7a317 | ||
|
|
4ef4e8cd72 | ||
|
|
e9942737c6 | ||
|
|
5c208dba41 | ||
|
|
ba032ce60e | ||
|
|
2fe0dda8af | ||
|
|
97daff4a10 | ||
|
|
caeceb58a5 | ||
|
|
3739d48e52 | ||
|
|
858fdb02ec | ||
|
|
b0cbb071e6 | ||
|
|
f222739b0d | ||
|
|
a280f5d5b2 | ||
|
|
cef333a01c | ||
|
|
24bd016a1a | ||
|
|
3c44f824cb | ||
|
|
3ee78ef557 | ||
|
|
d9b1bcbdcc | ||
|
|
283dd0b1f1 | ||
|
|
56345ddef9 | ||
|
|
4631008f8c | ||
|
|
e2ebde75be | ||
|
|
91613fcbf7 | ||
|
|
0b279143cc | ||
|
|
ade4847c61 | ||
|
|
a3e7203331 | ||
|
|
bbabd38a48 | ||
|
|
eb996c1e42 | ||
|
|
bf0ad4cda1 | ||
|
|
c32af6536a | ||
|
|
2437f9b051 | ||
|
|
0b781174bd | ||
|
|
f448d3e2db | ||
|
|
6b4222ec48 | ||
|
|
3f770cc5c0 | ||
|
|
14902f5b9a | ||
|
|
efdeb13bf5 | ||
|
|
62558291b6 | ||
|
|
edb0120bbf | ||
|
|
0dbaec553f | ||
|
|
295040c94c | ||
|
|
c1c4193b1d | ||
|
|
d17f0a9e1f | ||
|
|
871030dadb | ||
|
|
0ee9b74c0f | ||
|
|
82929f650c | ||
|
|
37b31c46bd | ||
|
|
c682bd858a | ||
|
|
2439891ee0 | ||
|
|
23825cafe7 | ||
|
|
a8f6f1fce2 | ||
|
|
e11faadf39 | ||
|
|
2c7251f4b9 | ||
|
|
fb9f18fc9c | ||
|
|
93cd3d0d8b | ||
|
|
ed2479ea82 | ||
|
|
accde0bfd0 | ||
|
|
7b34d9e4f4 | ||
|
|
6af71951af | ||
|
|
3eed45dc3e | ||
|
|
320b059bc7 | ||
|
|
a89ce06377 | ||
|
|
e4a1d6fe89 | ||
|
|
93c625bb81 | ||
|
|
87f84fb82d | ||
|
|
ce9e76a7dc | ||
|
|
4f3f1c5e23 | ||
|
|
22076d401f | ||
|
|
79ea82f147 | ||
|
|
3785415632 | ||
|
|
35eda73ad1 | ||
|
|
c8282fc8d3 | ||
|
|
5030881934 | ||
|
|
bc1e3a7059 | ||
|
|
ba17dceb4d | ||
|
|
4e689e20e9 | ||
|
|
2f78b6f7f3 | ||
|
|
920917a47e | ||
|
|
c1a7784781 | ||
|
|
62109f4ab1 | ||
|
|
c3a9c05455 | ||
|
|
333e4aa362 | ||
|
|
59ce26f28a | ||
|
|
2ff63aaebf | ||
|
|
8cf72a4409 | ||
|
|
496b92536f | ||
|
|
ac7900ecd7 | ||
|
|
310832f111 | ||
|
|
f69dd0ef8d | ||
|
|
4b51bb2334 | ||
|
|
0d4f9f00ee | ||
|
|
4a0100271f | ||
|
|
52a467806a | ||
|
|
0fedecff58 | ||
|
|
da4cb0aa62 | ||
|
|
3b8a771909 | ||
|
|
f9bcfa14e0 | ||
|
|
11c2eab967 | ||
|
|
094d2e12a4 | ||
|
|
af195a610c | ||
|
|
f7a05cf077 | ||
|
|
d54fbd6592 | ||
|
|
41b0868165 | ||
|
|
a1f5bfb746 | ||
|
|
3ab1018c66 | ||
|
|
62e96372fa | ||
|
|
945d10f554 | ||
|
|
f44e5ae5f9 | ||
|
|
a67b665846 | ||
|
|
8fb23b414c | ||
|
|
f5100626a8 | ||
|
|
9ab46fade7 | ||
|
|
2ce01b157b | ||
|
|
f714e42e11 | ||
|
|
447b7af573 | ||
|
|
ec2b635a1a | ||
|
|
7465b4bf91 | ||
|
|
4580fac6fa | ||
|
|
8c218e9edc | ||
|
|
44ceb8f1a0 | ||
|
|
642c1c50fb | ||
|
|
4de8c25a3f | ||
|
|
565f08a8e9 | ||
|
|
a85ae206c9 | ||
|
|
9e9b5e8d46 | ||
|
|
b623141a8f | ||
|
|
631cdc37c4 | ||
|
|
8d50bc0ef1 | ||
|
|
ae395fbb8f | ||
|
|
10877a99f1 | ||
|
|
0faff91c72 | ||
|
|
00f79fecd0 | ||
|
|
203128d935 | ||
|
|
4f6e52aed0 | ||
|
|
7bc7b2e3da | ||
|
|
27f0ca3b08 | ||
|
|
2337b2bb3e | ||
|
|
48ea13e130 | ||
|
|
5c73ab26c0 | ||
|
|
947e4ce71d | ||
|
|
200295e3ee | ||
|
|
ded5fe5ec0 | ||
|
|
7dffa943fa | ||
|
|
f702f67e27 | ||
|
|
a64956406d | ||
|
|
9c8bde2cff | ||
|
|
70a282ebf1 | ||
|
|
415652d38e | ||
|
|
1a745e4fa9 | ||
|
|
973e86df27 | ||
|
|
1f2917681f | ||
|
|
28d1feacf5 | ||
|
|
cf4ef8605d | ||
|
|
4be3728273 | ||
|
|
34b8c3f47c | ||
|
|
309893fd1e | ||
|
|
705eb06e8d | ||
|
|
5cfcf255e9 | ||
|
|
b8f36c8277 | ||
|
|
73c1dc697f | ||
|
|
a9c4647461 | ||
|
|
aaeaa24153 | ||
|
|
59a7494770 | ||
|
|
b2232cda7b | ||
|
|
3ba4aca268 | ||
|
|
f45533e20b | ||
|
|
2e7c5d6cfa | ||
|
|
476acc7715 | ||
|
|
ab3b50296c | ||
|
|
60c29b2839 | ||
|
|
7972f5f4bc | ||
|
|
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 |
2
.github/workflows/docker-build-test.yml
vendored
2
.github/workflows/docker-build-test.yml
vendored
@@ -24,6 +24,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|||||||
2
.github/workflows/docker-release.yml
vendored
2
.github/workflows/docker-release.yml
vendored
@@ -12,6 +12,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|||||||
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
|
||||||
6
.github/workflows/pages.yml
vendored
6
.github/workflows/pages.yml
vendored
@@ -36,7 +36,9 @@ jobs:
|
|||||||
working-directory: aider/website
|
working-directory: aider/website
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
- name: Setup Ruby
|
- name: Setup Ruby
|
||||||
uses: ruby/setup-ruby@v1
|
uses: ruby/setup-ruby@v1
|
||||||
with:
|
with:
|
||||||
@@ -82,4 +84,4 @@ jobs:
|
|||||||
|
|
||||||
- name: Run linkchecker
|
- name: Run linkchecker
|
||||||
run: |
|
run: |
|
||||||
linkchecker https://aider.chat
|
linkchecker --ignore-url='.+\.(mp4|mov|avi)' https://aider.chat
|
||||||
|
|||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -12,6 +12,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
|
|||||||
9
.github/workflows/ubuntu-tests.yml
vendored
9
.github/workflows/ubuntu-tests.yml
vendored
@@ -25,12 +25,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libportaudio2
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
@@ -38,5 +45,7 @@ jobs:
|
|||||||
pip install .
|
pip install .
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
env:
|
||||||
|
AIDER_ANALYTICS: false
|
||||||
run: |
|
run: |
|
||||||
pytest
|
pytest
|
||||||
|
|||||||
4
.github/workflows/windows-tests.yml
vendored
4
.github/workflows/windows-tests.yml
vendored
@@ -25,6 +25,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
@@ -38,6 +40,8 @@ jobs:
|
|||||||
pip install .
|
pip install .
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
env:
|
||||||
|
AIDER_ANALYTICS: false
|
||||||
run: |
|
run: |
|
||||||
pytest
|
pytest
|
||||||
|
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,5 +11,7 @@ _site
|
|||||||
.jekyll-cache/
|
.jekyll-cache/
|
||||||
.jekyll-metadata
|
.jekyll-metadata
|
||||||
aider/__version__.py
|
aider/__version__.py
|
||||||
|
aider/_version.py
|
||||||
.venv/
|
.venv/
|
||||||
|
.#*
|
||||||
.gitattributes
|
.gitattributes
|
||||||
|
|||||||
73
HISTORY.md
73
HISTORY.md
@@ -1,5 +1,78 @@
|
|||||||
# Release history
|
# Release history
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
- Added `--timeout` option to configure API call timeouts.
|
||||||
|
- Set cwd to repo root when running shell commands.
|
||||||
|
- Added Ctrl-Up/Down keyboard shortcuts for per-message history navigation.
|
||||||
|
- Improved error handling for failed .gitignore file operations.
|
||||||
|
- Improved error handling for input history file permissions.
|
||||||
|
- Improved error handling for analytics file access.
|
||||||
|
- Removed spurious warning about disabling pretty in VSCode.
|
||||||
|
- Removed broken support for Dart.
|
||||||
|
- Bugfix when scraping URLs found in chat messages.
|
||||||
|
- Better handling of __version__ import errors.
|
||||||
|
- Improved `/drop` command to support substring matching for non-glob patterns.
|
||||||
|
- Aider wrote 82% of the code in this release.
|
||||||
|
|
||||||
|
### Aider v0.65.1
|
||||||
|
|
||||||
|
- Bugfix to `--alias`.
|
||||||
|
|
||||||
### Aider v0.65.0
|
### Aider v0.65.0
|
||||||
|
|
||||||
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
||||||
|
|||||||
14
MANIFEST.in
Normal file
14
MANIFEST.in
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# 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/docs/leaderboards/index.md
|
||||||
|
recursive-exclude aider/website/assets *
|
||||||
|
recursive-exclude aider/website *.js
|
||||||
|
recursive-exclude aider/website *.html
|
||||||
|
recursive-exclude aider/website *.yml
|
||||||
19
README.md
19
README.md
@@ -43,28 +43,27 @@ VIDEO END -->
|
|||||||
cog.out(open("aider/website/_includes/get-started.md").read())
|
cog.out(open("aider/website/_includes/get-started.md").read())
|
||||||
]]]-->
|
]]]-->
|
||||||
|
|
||||||
You can get started quickly like this:
|
You can get started quickly like this, with python 3.8-3.13:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
python -m pip install -U aider-chat
|
python -m pip install aider-install
|
||||||
|
aider-install
|
||||||
|
|
||||||
# Change directory into a git repo
|
# Change directory into your code base
|
||||||
cd /to/your/git/repo
|
cd /to/your/git/repo
|
||||||
|
|
||||||
# Work with Claude 3.5 Sonnet on your repo
|
# Work with Claude 3.5 Sonnet on your repo
|
||||||
export ANTHROPIC_API_KEY=your-key-goes-here
|
aider --model sonnet --anthropic-api-key your-key-goes-here
|
||||||
aider
|
|
||||||
|
|
||||||
# Work with GPT-4o on your repo
|
# Work with GPT-4o on your repo
|
||||||
export OPENAI_API_KEY=your-key-goes-here
|
aider --model gpt-4o --openai-api-key your-key-goes-here
|
||||||
aider
|
|
||||||
```
|
```
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|
||||||
See the
|
See the
|
||||||
[installation instructions](https://aider.chat/docs/install.html)
|
[installation instructions](https://aider.chat/docs/install.html)
|
||||||
and other
|
and
|
||||||
[documentation](https://aider.chat/docs/usage.html)
|
[usage documentation](https://aider.chat/docs/usage.html)
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|||||||
@@ -1,6 +1,20 @@
|
|||||||
|
from packaging import version
|
||||||
|
|
||||||
|
__version__ = "0.69.2.dev"
|
||||||
|
safe_version = __version__
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from aider.__version__ import __version__
|
from aider._version import __version__
|
||||||
except Exception:
|
except Exception:
|
||||||
__version__ = "0.65.2.dev"
|
__version__ = safe_version + "+import"
|
||||||
|
|
||||||
|
if type(__version__) is not str:
|
||||||
|
__version__ = safe_version + "+type"
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
if version.parse(__version__) < version.parse(safe_version):
|
||||||
|
__version__ = safe_version + "+less"
|
||||||
|
except Exception:
|
||||||
|
__version__ = safe_version + "+parse"
|
||||||
|
|
||||||
__all__ = [__version__]
|
__all__ = [__version__]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import time
|
|||||||
import uuid
|
import uuid
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from mixpanel import Mixpanel, MixpanelException
|
from mixpanel import MixpanelException
|
||||||
from posthog import Posthog
|
from posthog import Posthog
|
||||||
|
|
||||||
from aider import __version__
|
from aider import __version__
|
||||||
@@ -50,8 +50,14 @@ class Analytics:
|
|||||||
self.disable(False)
|
self.disable(False)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.mp = Mixpanel(mixpanel_project_token)
|
# self.mp = Mixpanel(mixpanel_project_token)
|
||||||
self.ph = Posthog(project_api_key=posthog_project_api_key, host=posthog_host)
|
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):
|
def disable(self, permanently):
|
||||||
self.mp = None
|
self.mp = None
|
||||||
@@ -78,7 +84,7 @@ class Analytics:
|
|||||||
if not self.user_id:
|
if not self.user_id:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
PERCENT = 2.5
|
PERCENT = 5
|
||||||
return self.is_uuid_in_percentage(self.user_id, PERCENT)
|
return self.is_uuid_in_percentage(self.user_id, PERCENT)
|
||||||
|
|
||||||
def is_uuid_in_percentage(self, uuid_str, percent):
|
def is_uuid_in_percentage(self, uuid_str, percent):
|
||||||
@@ -105,9 +111,14 @@ class Analytics:
|
|||||||
return uuid_str[:6] <= threshold
|
return uuid_str[:6] <= threshold
|
||||||
|
|
||||||
def get_data_file_path(self):
|
def get_data_file_path(self):
|
||||||
data_file = Path.home() / ".aider" / "analytics.json"
|
try:
|
||||||
data_file.parent.mkdir(parents=True, exist_ok=True)
|
data_file = Path.home() / ".aider" / "analytics.json"
|
||||||
return data_file
|
data_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
return data_file
|
||||||
|
except OSError:
|
||||||
|
# If we can't create/access the directory, just disable analytics
|
||||||
|
self.disable(permanently=False)
|
||||||
|
return None
|
||||||
|
|
||||||
def get_or_create_uuid(self):
|
def get_or_create_uuid(self):
|
||||||
self.load_data()
|
self.load_data()
|
||||||
@@ -119,6 +130,9 @@ class Analytics:
|
|||||||
|
|
||||||
def load_data(self):
|
def load_data(self):
|
||||||
data_file = self.get_data_file_path()
|
data_file = self.get_data_file_path()
|
||||||
|
if not data_file:
|
||||||
|
return
|
||||||
|
|
||||||
if data_file.exists():
|
if data_file.exists():
|
||||||
try:
|
try:
|
||||||
data = json.loads(data_file.read_text())
|
data = json.loads(data_file.read_text())
|
||||||
@@ -130,14 +144,20 @@ class Analytics:
|
|||||||
|
|
||||||
def save_data(self):
|
def save_data(self):
|
||||||
data_file = self.get_data_file_path()
|
data_file = self.get_data_file_path()
|
||||||
|
if not data_file:
|
||||||
|
return
|
||||||
|
|
||||||
data = dict(
|
data = dict(
|
||||||
uuid=self.user_id,
|
uuid=self.user_id,
|
||||||
permanently_disable=self.permanently_disable,
|
permanently_disable=self.permanently_disable,
|
||||||
asked_opt_in=self.asked_opt_in,
|
asked_opt_in=self.asked_opt_in,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Allow exceptions; crash if we can't record permanently_disabled=True, etc
|
try:
|
||||||
data_file.write_text(json.dumps(data, indent=4))
|
data_file.write_text(json.dumps(data, indent=4))
|
||||||
|
except OSError:
|
||||||
|
# If we can't write the file, just disable analytics
|
||||||
|
self.disable(permanently=False)
|
||||||
|
|
||||||
def get_system_info(self):
|
def get_system_info(self):
|
||||||
return {
|
return {
|
||||||
@@ -145,6 +165,7 @@ class Analytics:
|
|||||||
"os_platform": platform.system(),
|
"os_platform": platform.system(),
|
||||||
"os_release": platform.release(),
|
"os_release": platform.release(),
|
||||||
"machine": platform.machine(),
|
"machine": platform.machine(),
|
||||||
|
"aider_version": __version__,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _redact_model_name(self, model):
|
def _redact_model_name(self, model):
|
||||||
@@ -158,6 +179,13 @@ class Analytics:
|
|||||||
return model.name.split("/")[0] + "/REDACTED"
|
return model.name.split("/")[0] + "/REDACTED"
|
||||||
return None
|
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):
|
def event(self, event_name, main_model=None, **kwargs):
|
||||||
if not self.mp and not self.ph and not self.logfile:
|
if not self.mp and not self.ph and not self.logfile:
|
||||||
return
|
return
|
||||||
@@ -170,7 +198,6 @@ class Analytics:
|
|||||||
properties["editor_model"] = self._redact_model_name(main_model.editor_model)
|
properties["editor_model"] = self._redact_model_name(main_model.editor_model)
|
||||||
|
|
||||||
properties.update(kwargs)
|
properties.update(kwargs)
|
||||||
properties.update(self.get_system_info()) # Add system info to all events
|
|
||||||
|
|
||||||
# Handle numeric values
|
# Handle numeric values
|
||||||
for key, value in properties.items():
|
for key, value in properties.items():
|
||||||
@@ -179,8 +206,6 @@ class Analytics:
|
|||||||
else:
|
else:
|
||||||
properties[key] = str(value)
|
properties[key] = str(value)
|
||||||
|
|
||||||
properties["aider_version"] = __version__
|
|
||||||
|
|
||||||
if self.mp:
|
if self.mp:
|
||||||
try:
|
try:
|
||||||
self.mp.track(self.user_id, event_name, dict(properties))
|
self.mp.track(self.user_id, event_name, dict(properties))
|
||||||
@@ -197,10 +222,9 @@ class Analytics:
|
|||||||
"user_id": self.user_id,
|
"user_id": self.user_id,
|
||||||
"time": int(time.time()),
|
"time": int(time.time()),
|
||||||
}
|
}
|
||||||
with open(self.logfile, "a") as f:
|
try:
|
||||||
json.dump(log_entry, f)
|
with open(self.logfile, "a") as f:
|
||||||
f.write("\n")
|
json.dump(log_entry, f)
|
||||||
|
f.write("\n")
|
||||||
def __del__(self):
|
except OSError:
|
||||||
if self.ph:
|
pass # Ignore OS errors when writing to logfile
|
||||||
self.ph.shutdown()
|
|
||||||
|
|||||||
341
aider/args.py
341
aider/args.py
@@ -28,22 +28,10 @@ def get_parser(default_config_files, git_root):
|
|||||||
config_file_parser_class=configargparse.YAMLConfigFileParser,
|
config_file_parser_class=configargparse.YAMLConfigFileParser,
|
||||||
auto_env_var_prefix="AIDER_",
|
auto_env_var_prefix="AIDER_",
|
||||||
)
|
)
|
||||||
group = parser.add_argument_group("Main")
|
group = parser.add_argument_group("Main model")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"files", metavar="FILE", nargs="*", help="files to edit with an LLM (optional)"
|
"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(
|
group.add_argument(
|
||||||
"--model",
|
"--model",
|
||||||
metavar="MODEL",
|
metavar="MODEL",
|
||||||
@@ -83,7 +71,7 @@ def get_parser(default_config_files, git_root):
|
|||||||
const=gpt_4_model,
|
const=gpt_4_model,
|
||||||
help=f"Use {gpt_4_model} model for the main chat",
|
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(
|
group.add_argument(
|
||||||
"--4o",
|
"--4o",
|
||||||
action="store_const",
|
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(
|
group.add_argument(
|
||||||
"--list-models",
|
"--list-models",
|
||||||
"--models",
|
"--models",
|
||||||
metavar="MODEL",
|
metavar="MODEL",
|
||||||
help="List known models which match the (partial) MODEL name",
|
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(
|
group.add_argument(
|
||||||
"--model-settings-file",
|
"--model-settings-file",
|
||||||
metavar="MODEL_SETTINGS_FILE",
|
metavar="MODEL_SETTINGS_FILE",
|
||||||
@@ -205,6 +209,12 @@ def get_parser(default_config_files, git_root):
|
|||||||
default=True,
|
default=True,
|
||||||
help="Verify the SSL cert when connecting to models (default: True)",
|
help="Verify the SSL cert when connecting to models (default: True)",
|
||||||
)
|
)
|
||||||
|
group.add_argument(
|
||||||
|
"--timeout",
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
help="Timeout in seconds for API calls (default: None)",
|
||||||
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--edit-format",
|
"--edit-format",
|
||||||
"--chat-mode",
|
"--chat-mode",
|
||||||
@@ -255,17 +265,9 @@ def get_parser(default_config_files, git_root):
|
|||||||
" If unspecified, defaults to the model's max_chat_history_tokens."
|
" 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(
|
group.add_argument(
|
||||||
"--cache-prompts",
|
"--cache-prompts",
|
||||||
action=argparse.BooleanOptionalAction,
|
action=argparse.BooleanOptionalAction,
|
||||||
@@ -280,7 +282,7 @@ def get_parser(default_config_files, git_root):
|
|||||||
)
|
)
|
||||||
|
|
||||||
##########
|
##########
|
||||||
group = parser.add_argument_group("Repomap Settings")
|
group = parser.add_argument_group("Repomap settings")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--map-tokens",
|
"--map-tokens",
|
||||||
type=int,
|
type=int,
|
||||||
@@ -337,7 +339,7 @@ def get_parser(default_config_files, git_root):
|
|||||||
)
|
)
|
||||||
|
|
||||||
##########
|
##########
|
||||||
group = parser.add_argument_group("Output Settings")
|
group = parser.add_argument_group("Output settings")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--dark-mode",
|
"--dark-mode",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -436,7 +438,7 @@ def get_parser(default_config_files, git_root):
|
|||||||
)
|
)
|
||||||
|
|
||||||
##########
|
##########
|
||||||
group = parser.add_argument_group("Git Settings")
|
group = parser.add_argument_group("Git settings")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--git",
|
"--git",
|
||||||
action=argparse.BooleanOptionalAction,
|
action=argparse.BooleanOptionalAction,
|
||||||
@@ -523,6 +525,12 @@ def get_parser(default_config_files, git_root):
|
|||||||
help="Skip the sanity check for the git repository (default: False)",
|
help="Skip the sanity check for the git repository (default: False)",
|
||||||
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 = parser.add_argument_group("Fixing and committing")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--lint",
|
"--lint",
|
||||||
@@ -559,7 +567,7 @@ def get_parser(default_config_files, git_root):
|
|||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--test",
|
"--test",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Run tests and fix problems found",
|
help="Run tests, fix problems found and then exit",
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -583,37 +591,8 @@ def get_parser(default_config_files, git_root):
|
|||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
group = parser.add_argument_group("Other Settings")
|
#########
|
||||||
group.add_argument(
|
group = parser.add_argument_group("Upgrading")
|
||||||
"--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.add_argument(
|
group.add_argument(
|
||||||
"--just-check-update",
|
"--just-check-update",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -646,47 +625,14 @@ def get_parser(default_config_files, git_root):
|
|||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--apply",
|
"--version",
|
||||||
metavar="FILE",
|
action="version",
|
||||||
help="Apply the changes from the given file instead of running the chat (debug)",
|
version=f"%(prog)s {__version__}",
|
||||||
)
|
help="Show the version number and exit",
|
||||||
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,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
##########
|
||||||
|
group = parser.add_argument_group("Modes")
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--message",
|
"--message",
|
||||||
"--msg",
|
"--msg",
|
||||||
@@ -705,6 +651,110 @@ def get_parser(default_config_files, git_root):
|
|||||||
" (disables chat mode)"
|
" (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(
|
group.add_argument(
|
||||||
"--load",
|
"--load",
|
||||||
metavar="LOAD_FILE",
|
metavar="LOAD_FILE",
|
||||||
@@ -725,12 +775,13 @@ def get_parser(default_config_files, git_root):
|
|||||||
" or home directory)"
|
" 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(
|
group.add_argument(
|
||||||
"--gui",
|
"--env-file",
|
||||||
"--browser",
|
metavar="ENV_FILE",
|
||||||
action=argparse.BooleanOptionalAction,
|
default=default_env_file(git_root),
|
||||||
help="Run aider in your browser (default: False)",
|
help="Specify the .env file to load (default: .env in git root)",
|
||||||
default=False,
|
|
||||||
)
|
)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--suggest-shell-commands",
|
"--suggest-shell-commands",
|
||||||
@@ -744,6 +795,12 @@ def get_parser(default_config_files, git_root):
|
|||||||
default=True,
|
default=True,
|
||||||
help="Enable/disable fancy input with history and completion (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(
|
group.add_argument(
|
||||||
"--detect-urls",
|
"--detect-urls",
|
||||||
action=argparse.BooleanOptionalAction,
|
action=argparse.BooleanOptionalAction,
|
||||||
@@ -755,22 +812,6 @@ def get_parser(default_config_files, git_root):
|
|||||||
help="Specify which editor to use for the /editor command",
|
help="Specify which editor to use for the /editor command",
|
||||||
)
|
)
|
||||||
|
|
||||||
##########
|
|
||||||
group = parser.add_argument_group("Voice Settings")
|
|
||||||
group.add_argument(
|
|
||||||
"--voice-format",
|
|
||||||
metavar="VOICE_FORMAT",
|
|
||||||
default="wav",
|
|
||||||
choices=["wav", "mp3", "webm"],
|
|
||||||
help="Audio format for voice recording (default: wav). webm and mp3 require ffmpeg",
|
|
||||||
)
|
|
||||||
group.add_argument(
|
|
||||||
"--voice-language",
|
|
||||||
metavar="VOICE_LANGUAGE",
|
|
||||||
default="en",
|
|
||||||
help="Specify the language for voice using ISO 639-1 code (default: auto)",
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ class Coder:
|
|||||||
detect_urls = True
|
detect_urls = True
|
||||||
ignore_mentions = None
|
ignore_mentions = None
|
||||||
chat_language = None
|
chat_language = None
|
||||||
|
file_watcher = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(
|
||||||
@@ -153,8 +154,9 @@ class Coder:
|
|||||||
aider_commit_hashes=from_coder.aider_commit_hashes,
|
aider_commit_hashes=from_coder.aider_commit_hashes,
|
||||||
commands=from_coder.commands.clone(),
|
commands=from_coder.commands.clone(),
|
||||||
total_cost=from_coder.total_cost,
|
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(update) # override to complete the switch
|
||||||
use_kwargs.update(kwargs) # override passed kwargs
|
use_kwargs.update(kwargs) # override passed kwargs
|
||||||
|
|
||||||
@@ -175,7 +177,6 @@ class Coder:
|
|||||||
|
|
||||||
def clone(self, **kwargs):
|
def clone(self, **kwargs):
|
||||||
new_coder = Coder.create(from_coder=self, **kwargs)
|
new_coder = Coder.create(from_coder=self, **kwargs)
|
||||||
new_coder.ignore_mentions = self.ignore_mentions
|
|
||||||
return new_coder
|
return new_coder
|
||||||
|
|
||||||
def get_announcements(self):
|
def get_announcements(self):
|
||||||
@@ -247,6 +248,9 @@ class Coder:
|
|||||||
if self.done_messages:
|
if self.done_messages:
|
||||||
lines.append("Restored previous conversation history.")
|
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
|
return lines
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -283,6 +287,9 @@ class Coder:
|
|||||||
suggest_shell_commands=True,
|
suggest_shell_commands=True,
|
||||||
chat_language=None,
|
chat_language=None,
|
||||||
detect_urls=True,
|
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
|
# Fill in a dummy Analytics if needed, but it is never .enable()'d
|
||||||
self.analytics = analytics if analytics is not None else Analytics()
|
self.analytics = analytics if analytics is not None else Analytics()
|
||||||
@@ -293,7 +300,16 @@ class Coder:
|
|||||||
self.aider_commit_hashes = set()
|
self.aider_commit_hashes = set()
|
||||||
self.rejected_urls = set()
|
self.rejected_urls = set()
|
||||||
self.abs_root_path_cache = {}
|
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.suggest_shell_commands = suggest_shell_commands
|
||||||
self.detect_urls = detect_urls
|
self.detect_urls = detect_urls
|
||||||
@@ -665,6 +681,8 @@ class Coder:
|
|||||||
|
|
||||||
def get_readonly_files_messages(self):
|
def get_readonly_files_messages(self):
|
||||||
readonly_messages = []
|
readonly_messages = []
|
||||||
|
|
||||||
|
# Handle non-image files
|
||||||
read_only_content = self.get_read_only_files_content()
|
read_only_content = self.get_read_only_files_content()
|
||||||
if read_only_content:
|
if read_only_content:
|
||||||
readonly_messages += [
|
readonly_messages += [
|
||||||
@@ -676,6 +694,15 @@ class Coder:
|
|||||||
content="Ok, I will use these files as references.",
|
content="Ok, I will use these files as references.",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Handle image files
|
||||||
|
images_message = self.get_images_message(self.abs_read_only_fnames)
|
||||||
|
if images_message is not None:
|
||||||
|
readonly_messages += [
|
||||||
|
images_message,
|
||||||
|
dict(role="assistant", content="Ok, I will use these images as references."),
|
||||||
|
]
|
||||||
|
|
||||||
return readonly_messages
|
return readonly_messages
|
||||||
|
|
||||||
def get_chat_files_messages(self):
|
def get_chat_files_messages(self):
|
||||||
@@ -697,7 +724,7 @@ class Coder:
|
|||||||
dict(role="assistant", content=files_reply),
|
dict(role="assistant", content=files_reply),
|
||||||
]
|
]
|
||||||
|
|
||||||
images_message = self.get_images_message()
|
images_message = self.get_images_message(self.abs_fnames)
|
||||||
if images_message is not None:
|
if images_message is not None:
|
||||||
chat_files_messages += [
|
chat_files_messages += [
|
||||||
images_message,
|
images_message,
|
||||||
@@ -706,23 +733,42 @@ class Coder:
|
|||||||
|
|
||||||
return chat_files_messages
|
return chat_files_messages
|
||||||
|
|
||||||
def get_images_message(self):
|
def get_images_message(self, fnames):
|
||||||
if not self.main_model.info.get("supports_vision"):
|
supports_images = self.main_model.info.get("supports_vision")
|
||||||
|
supports_pdfs = self.main_model.info.get("supports_pdf_input") or self.main_model.info.get(
|
||||||
|
"max_pdf_size_mb"
|
||||||
|
)
|
||||||
|
|
||||||
|
# https://github.com/BerriAI/litellm/pull/6928
|
||||||
|
supports_pdfs = supports_pdfs or "claude-3-5-sonnet-20241022" in self.main_model.name
|
||||||
|
|
||||||
|
if not (supports_images or supports_pdfs):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
image_messages = []
|
image_messages = []
|
||||||
for fname, content in self.get_abs_fnames_content():
|
for fname in fnames:
|
||||||
if is_image_file(fname):
|
if not is_image_file(fname):
|
||||||
with open(fname, "rb") as image_file:
|
continue
|
||||||
encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
|
|
||||||
mime_type, _ = mimetypes.guess_type(fname)
|
mime_type, _ = mimetypes.guess_type(fname)
|
||||||
if mime_type and mime_type.startswith("image/"):
|
if not mime_type:
|
||||||
image_url = f"data:{mime_type};base64,{encoded_string}"
|
continue
|
||||||
rel_fname = self.get_rel_fname(fname)
|
|
||||||
image_messages += [
|
with open(fname, "rb") as image_file:
|
||||||
{"type": "text", "text": f"Image file: {rel_fname}"},
|
encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
|
||||||
{"type": "image_url", "image_url": {"url": image_url, "detail": "high"}},
|
image_url = f"data:{mime_type};base64,{encoded_string}"
|
||||||
]
|
rel_fname = self.get_rel_fname(fname)
|
||||||
|
|
||||||
|
if mime_type.startswith("image/") and supports_images:
|
||||||
|
image_messages += [
|
||||||
|
{"type": "text", "text": f"Image file: {rel_fname}"},
|
||||||
|
{"type": "image_url", "image_url": {"url": image_url, "detail": "high"}},
|
||||||
|
]
|
||||||
|
elif mime_type == "application/pdf" and supports_pdfs:
|
||||||
|
image_messages += [
|
||||||
|
{"type": "text", "text": f"PDF file: {rel_fname}"},
|
||||||
|
{"type": "image_url", "image_url": image_url},
|
||||||
|
]
|
||||||
|
|
||||||
if not image_messages:
|
if not image_messages:
|
||||||
return None
|
return None
|
||||||
@@ -741,6 +787,7 @@ class Coder:
|
|||||||
self.lint_outcome = None
|
self.lint_outcome = None
|
||||||
self.test_outcome = None
|
self.test_outcome = None
|
||||||
self.shell_commands = []
|
self.shell_commands = []
|
||||||
|
self.message_cost = 0
|
||||||
|
|
||||||
if self.repo:
|
if self.repo:
|
||||||
self.commit_before_message.append(self.repo.get_head_commit_sha())
|
self.commit_before_message.append(self.repo.get_head_commit_sha())
|
||||||
@@ -751,9 +798,10 @@ class Coder:
|
|||||||
self.io.user_input(with_message)
|
self.io.user_input(with_message)
|
||||||
self.run_one(with_message, preproc)
|
self.run_one(with_message, preproc)
|
||||||
return self.partial_response_content
|
return self.partial_response_content
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
if not self.io.placeholder:
|
||||||
|
self.copy_context()
|
||||||
user_message = self.get_input()
|
user_message = self.get_input()
|
||||||
self.run_one(user_message, preproc)
|
self.run_one(user_message, preproc)
|
||||||
self.show_undo_hint()
|
self.show_undo_hint()
|
||||||
@@ -762,6 +810,10 @@ class Coder:
|
|||||||
except EOFError:
|
except EOFError:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def copy_context(self):
|
||||||
|
if self.auto_copy_context:
|
||||||
|
self.commands.cmd_copy_context()
|
||||||
|
|
||||||
def get_input(self):
|
def get_input(self):
|
||||||
inchat_files = self.get_inchat_relative_files()
|
inchat_files = self.get_inchat_relative_files()
|
||||||
read_only_files = [self.get_rel_fname(fname) for fname in self.abs_read_only_fnames]
|
read_only_files = [self.get_rel_fname(fname) for fname in self.abs_read_only_fnames]
|
||||||
@@ -784,7 +836,7 @@ class Coder:
|
|||||||
return self.commands.run(inp)
|
return self.commands.run(inp)
|
||||||
|
|
||||||
self.check_for_file_mentions(inp)
|
self.check_for_file_mentions(inp)
|
||||||
self.check_for_urls(inp)
|
inp = self.check_for_urls(inp)
|
||||||
|
|
||||||
return inp
|
return inp
|
||||||
|
|
||||||
@@ -830,11 +882,10 @@ class Coder:
|
|||||||
def check_for_urls(self, inp: str) -> List[str]:
|
def check_for_urls(self, inp: str) -> List[str]:
|
||||||
"""Check input for URLs and offer to add them to the chat."""
|
"""Check input for URLs and offer to add them to the chat."""
|
||||||
if not self.detect_urls:
|
if not self.detect_urls:
|
||||||
return []
|
return inp
|
||||||
|
|
||||||
url_pattern = re.compile(r"(https?://[^\s/$.?#].[^\s]*[^\s,.])")
|
url_pattern = re.compile(r"(https?://[^\s/$.?#].[^\s]*[^\s,.])")
|
||||||
urls = list(set(url_pattern.findall(inp))) # Use set to remove duplicates
|
urls = list(set(url_pattern.findall(inp))) # Use set to remove duplicates
|
||||||
added_urls = []
|
|
||||||
group = ConfirmGroup(urls)
|
group = ConfirmGroup(urls)
|
||||||
for url in urls:
|
for url in urls:
|
||||||
if url not in self.rejected_urls:
|
if url not in self.rejected_urls:
|
||||||
@@ -844,11 +895,10 @@ class Coder:
|
|||||||
):
|
):
|
||||||
inp += "\n\n"
|
inp += "\n\n"
|
||||||
inp += self.commands.cmd_web(url, return_content=True)
|
inp += self.commands.cmd_web(url, return_content=True)
|
||||||
added_urls.append(url)
|
|
||||||
else:
|
else:
|
||||||
self.rejected_urls.add(url)
|
self.rejected_urls.add(url)
|
||||||
|
|
||||||
return added_urls
|
return inp
|
||||||
|
|
||||||
def keyboard_interrupt(self):
|
def keyboard_interrupt(self):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
@@ -856,6 +906,7 @@ class Coder:
|
|||||||
thresh = 2 # seconds
|
thresh = 2 # seconds
|
||||||
if self.last_keyboard_interrupt and now - self.last_keyboard_interrupt < thresh:
|
if self.last_keyboard_interrupt and now - self.last_keyboard_interrupt < thresh:
|
||||||
self.io.tool_warning("\n\n^C KeyboardInterrupt")
|
self.io.tool_warning("\n\n^C KeyboardInterrupt")
|
||||||
|
self.event("exit", reason="Control-C")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
self.io.tool_warning("\n\n^C again to exit")
|
self.io.tool_warning("\n\n^C again to exit")
|
||||||
@@ -1074,7 +1125,10 @@ class Coder:
|
|||||||
# add the reminder anyway
|
# add the reminder anyway
|
||||||
total_tokens = 0
|
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
|
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.
|
# Add the reminder prompt if we still have room to include it.
|
||||||
@@ -1085,7 +1139,7 @@ class Coder:
|
|||||||
):
|
):
|
||||||
if self.main_model.reminder == "sys":
|
if self.main_model.reminder == "sys":
|
||||||
chunks.reminder = reminder_message
|
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
|
# stuff it into the user message
|
||||||
new_content = (
|
new_content = (
|
||||||
final["content"]
|
final["content"]
|
||||||
@@ -1157,6 +1211,8 @@ class Coder:
|
|||||||
return chunks
|
return chunks
|
||||||
|
|
||||||
def send_message(self, inp):
|
def send_message(self, inp):
|
||||||
|
self.event("message_send_starting")
|
||||||
|
|
||||||
self.cur_messages += [
|
self.cur_messages += [
|
||||||
dict(role="user", content=inp),
|
dict(role="user", content=inp),
|
||||||
]
|
]
|
||||||
@@ -1236,6 +1292,7 @@ class Coder:
|
|||||||
lines = traceback.format_exception(type(err), err, err.__traceback__)
|
lines = traceback.format_exception(type(err), err, err.__traceback__)
|
||||||
self.io.tool_warning("".join(lines))
|
self.io.tool_warning("".join(lines))
|
||||||
self.io.tool_error(str(err))
|
self.io.tool_error(str(err))
|
||||||
|
self.event("message_send_exception", exception=str(err))
|
||||||
return
|
return
|
||||||
finally:
|
finally:
|
||||||
if self.mdstream:
|
if self.mdstream:
|
||||||
@@ -1370,9 +1427,7 @@ class Coder:
|
|||||||
res.append("- Ask for smaller changes in each request.")
|
res.append("- Ask for smaller changes in each request.")
|
||||||
res.append("- Break your code into smaller source files.")
|
res.append("- Break your code into smaller source files.")
|
||||||
if "diff" not in self.main_model.edit_format:
|
if "diff" not in self.main_model.edit_format:
|
||||||
res.append(
|
res.append("- Use a stronger model that can return diffs.")
|
||||||
"- Use a stronger model like gpt-4o, sonnet or opus that can return diffs."
|
|
||||||
)
|
|
||||||
|
|
||||||
if input_tokens >= max_input_tokens or total_tokens >= max_input_tokens:
|
if input_tokens >= max_input_tokens or total_tokens >= max_input_tokens:
|
||||||
res.append("")
|
res.append("")
|
||||||
@@ -1389,6 +1444,8 @@ class Coder:
|
|||||||
def lint_edited(self, fnames):
|
def lint_edited(self, fnames):
|
||||||
res = ""
|
res = ""
|
||||||
for fname in fnames:
|
for fname in fnames:
|
||||||
|
if not fname:
|
||||||
|
continue
|
||||||
errors = self.linter.lint(self.abs_root_path(fname))
|
errors = self.linter.lint(self.abs_root_path(fname))
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
@@ -1417,7 +1474,7 @@ class Coder:
|
|||||||
words = set(word for word in content.split())
|
words = set(word for word in content.split())
|
||||||
|
|
||||||
# drop sentence punctuation from the end
|
# 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
|
# strip away all kinds of quotes
|
||||||
quotes = "".join(['"', "'", "`"])
|
quotes = "".join(['"', "'", "`"])
|
||||||
@@ -1506,6 +1563,16 @@ class Coder:
|
|||||||
yield from self.show_send_output_stream(completion)
|
yield from self.show_send_output_stream(completion)
|
||||||
else:
|
else:
|
||||||
self.show_send_output(completion)
|
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:
|
except KeyboardInterrupt as kbi:
|
||||||
self.keyboard_interrupt()
|
self.keyboard_interrupt()
|
||||||
raise kbi
|
raise kbi
|
||||||
@@ -1523,8 +1590,6 @@ class Coder:
|
|||||||
if args:
|
if args:
|
||||||
self.io.ai_output(json.dumps(args, indent=4))
|
self.io.ai_output(json.dumps(args, indent=4))
|
||||||
|
|
||||||
self.calculate_and_show_tokens_and_cost(messages, completion)
|
|
||||||
|
|
||||||
def show_send_output(self, completion):
|
def show_send_output(self, completion):
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print(completion)
|
print(completion)
|
||||||
@@ -2086,7 +2151,7 @@ class Coder:
|
|||||||
self.io.tool_output(f"Running {command}")
|
self.io.tool_output(f"Running {command}")
|
||||||
# Add the command to input history
|
# Add the command to input history
|
||||||
self.io.add_to_input_history(f"/run {command.strip()}")
|
self.io.add_to_input_history(f"/run {command.strip()}")
|
||||||
exit_status, output = run_cmd(command, error_print=self.io.tool_error)
|
exit_status, output = run_cmd(command, error_print=self.io.tool_error, cwd=self.root)
|
||||||
if output:
|
if output:
|
||||||
accumulated_output += f"Output from {command}\n{output}\n"
|
accumulated_output += f"Output from {command}\n{output}\n"
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
|
|||||||
|
|
||||||
Just suggest shell commands this way, not example code.
|
Just suggest shell commands this way, not example code.
|
||||||
Only suggest complete shell commands that are ready to execute, without placeholders.
|
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:
|
Use the appropriate shell based on the user's system info:
|
||||||
{platform}
|
{platform}
|
||||||
|
|||||||
@@ -3,5 +3,6 @@ from .editor_editblock_prompts import EditorEditBlockPrompts
|
|||||||
|
|
||||||
|
|
||||||
class EditorEditBlockCoder(EditBlockCoder):
|
class EditorEditBlockCoder(EditBlockCoder):
|
||||||
|
"A coder that uses search/replace blocks, focused purely on editing files."
|
||||||
edit_format = "editor-diff"
|
edit_format = "editor-diff"
|
||||||
gpt_prompts = EditorEditBlockPrompts()
|
gpt_prompts = EditorEditBlockPrompts()
|
||||||
|
|||||||
@@ -3,5 +3,6 @@ from .wholefile_coder import WholeFileCoder
|
|||||||
|
|
||||||
|
|
||||||
class EditorWholeFileCoder(WholeFileCoder):
|
class EditorWholeFileCoder(WholeFileCoder):
|
||||||
|
"A coder that operates on entire files, focused purely on editing files."
|
||||||
edit_format = "editor-whole"
|
edit_format = "editor-whole"
|
||||||
gpt_prompts = EditorWholeFilePrompts()
|
gpt_prompts = EditorWholeFilePrompts()
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import git
|
try:
|
||||||
|
import git
|
||||||
|
except ImportError:
|
||||||
|
git = None
|
||||||
|
|
||||||
from diff_match_patch import diff_match_patch
|
from diff_match_patch import diff_match_patch
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ class Commands:
|
|||||||
verify_ssl=self.verify_ssl,
|
verify_ssl=self.verify_ssl,
|
||||||
args=self.args,
|
args=self.args,
|
||||||
parser=self.parser,
|
parser=self.parser,
|
||||||
|
verbose=self.verbose,
|
||||||
|
editor=self.editor,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -101,6 +103,13 @@ class Commands:
|
|||||||
("help", "Get help about using aider (usage, config, troubleshoot)."),
|
("help", "Get help about using aider (usage, config, troubleshoot)."),
|
||||||
("ask", "Ask questions about your code without making any changes."),
|
("ask", "Ask questions about your code without making any changes."),
|
||||||
("code", "Ask for changes to your code (using the best edit format)."),
|
("code", "Ask for changes to your code (using the best edit format)."),
|
||||||
|
(
|
||||||
|
"architect",
|
||||||
|
(
|
||||||
|
"Work with an architect model to design code changes, and an editor to make"
|
||||||
|
" them."
|
||||||
|
),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -588,6 +597,10 @@ class Commands:
|
|||||||
|
|
||||||
self.io.tool_output(f"Diff since {commit_before_message[:7]}...")
|
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(
|
diff = self.coder.repo.diff_commits(
|
||||||
self.coder.pretty,
|
self.coder.pretty,
|
||||||
commit_before_message,
|
commit_before_message,
|
||||||
@@ -785,7 +798,8 @@ class Commands:
|
|||||||
self.io.tool_error(f"Unable to read {matched_file}")
|
self.io.tool_error(f"Unable to read {matched_file}")
|
||||||
else:
|
else:
|
||||||
self.coder.abs_fnames.add(abs_file_path)
|
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()
|
self.coder.check_added_files()
|
||||||
|
|
||||||
def completions_drop(self):
|
def completions_drop(self):
|
||||||
@@ -808,15 +822,33 @@ class Commands:
|
|||||||
# Expand tilde in the path
|
# Expand tilde in the path
|
||||||
expanded_word = os.path.expanduser(word)
|
expanded_word = os.path.expanduser(word)
|
||||||
|
|
||||||
# Handle read-only files separately, without glob_filtered_to_repo
|
# Handle read-only files with substring matching and samefile check
|
||||||
read_only_matched = [f for f in self.coder.abs_read_only_fnames if expanded_word in f]
|
read_only_matched = []
|
||||||
|
for f in self.coder.abs_read_only_fnames:
|
||||||
|
if expanded_word in f:
|
||||||
|
read_only_matched.append(f)
|
||||||
|
continue
|
||||||
|
|
||||||
if read_only_matched:
|
# Try samefile comparison for relative paths
|
||||||
for matched_file in read_only_matched:
|
try:
|
||||||
self.coder.abs_read_only_fnames.remove(matched_file)
|
abs_word = os.path.abspath(expanded_word)
|
||||||
self.io.tool_output(f"Removed read-only file {matched_file} from the chat")
|
if os.path.samefile(abs_word, f):
|
||||||
|
read_only_matched.append(f)
|
||||||
|
except (FileNotFoundError, OSError):
|
||||||
|
continue
|
||||||
|
|
||||||
matched_files = self.glob_filtered_to_repo(expanded_word)
|
for matched_file in read_only_matched:
|
||||||
|
self.coder.abs_read_only_fnames.remove(matched_file)
|
||||||
|
self.io.tool_output(f"Removed read-only file {matched_file} from the chat")
|
||||||
|
|
||||||
|
# For editable files, use glob if word contains glob chars, otherwise use substring
|
||||||
|
if any(c in expanded_word for c in "*?[]"):
|
||||||
|
matched_files = self.glob_filtered_to_repo(expanded_word)
|
||||||
|
else:
|
||||||
|
# Use substring matching like we do for read-only files
|
||||||
|
matched_files = [
|
||||||
|
self.coder.get_rel_fname(f) for f in self.coder.abs_fnames if expanded_word in f
|
||||||
|
]
|
||||||
|
|
||||||
if not matched_files:
|
if not matched_files:
|
||||||
matched_files.append(expanded_word)
|
matched_files.append(expanded_word)
|
||||||
@@ -876,7 +908,7 @@ class Commands:
|
|||||||
def cmd_run(self, args, add_on_nonzero_exit=False):
|
def cmd_run(self, args, add_on_nonzero_exit=False):
|
||||||
"Run a shell command and optionally add the output to the chat (alias: !)"
|
"Run a shell command and optionally add the output to the chat (alias: !)"
|
||||||
exit_status, combined_output = run_cmd(
|
exit_status, combined_output = run_cmd(
|
||||||
args, verbose=self.verbose, error_print=self.io.tool_error
|
args, verbose=self.verbose, error_print=self.io.tool_error, cwd=self.coder.root
|
||||||
)
|
)
|
||||||
|
|
||||||
if combined_output is None:
|
if combined_output is None:
|
||||||
@@ -902,13 +934,17 @@ class Commands:
|
|||||||
dict(role="assistant", content="Ok."),
|
dict(role="assistant", content="Ok."),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if add and exit_status != 0:
|
||||||
|
self.io.placeholder = "Fix that"
|
||||||
|
|
||||||
def cmd_exit(self, args):
|
def cmd_exit(self, args):
|
||||||
"Exit the application"
|
"Exit the application"
|
||||||
|
self.coder.event("exit", reason="/exit")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
def cmd_quit(self, args):
|
def cmd_quit(self, args):
|
||||||
"Exit the application"
|
"Exit the application"
|
||||||
sys.exit()
|
self.cmd_exit(args)
|
||||||
|
|
||||||
def cmd_ls(self, args):
|
def cmd_ls(self, args):
|
||||||
"List all known files and indicate which are included in the chat session"
|
"List all known files and indicate which are included in the chat session"
|
||||||
@@ -1080,43 +1116,23 @@ class Commands:
|
|||||||
self.io.tool_error("To use /voice you must provide an OpenAI API key.")
|
self.io.tool_error("To use /voice you must provide an OpenAI API key.")
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.voice = voice.Voice(audio_format=self.args.voice_format)
|
self.voice = voice.Voice(
|
||||||
|
audio_format=self.args.voice_format, device_name=self.args.voice_input_device
|
||||||
|
)
|
||||||
except voice.SoundDeviceError:
|
except voice.SoundDeviceError:
|
||||||
self.io.tool_error(
|
self.io.tool_error(
|
||||||
"Unable to import `sounddevice` and/or `soundfile`, is portaudio installed?"
|
"Unable to import `sounddevice` and/or `soundfile`, is portaudio installed?"
|
||||||
)
|
)
|
||||||
return
|
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:
|
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:
|
except litellm.OpenAIError as err:
|
||||||
self.io.tool_error(f"Unable to use OpenAI whisper model: {err}")
|
self.io.tool_error(f"Unable to use OpenAI whisper model: {err}")
|
||||||
return
|
return
|
||||||
|
|
||||||
if text:
|
if text:
|
||||||
self.io.add_to_input_history(text)
|
self.io.placeholder = text
|
||||||
self.io.print()
|
|
||||||
self.io.user_input(text, log_only=False)
|
|
||||||
self.io.print()
|
|
||||||
|
|
||||||
return text
|
|
||||||
|
|
||||||
def cmd_paste(self, args):
|
def cmd_paste(self, args):
|
||||||
"""Paste image/text from the clipboard into the chat.\
|
"""Paste image/text from the clipboard into the chat.\
|
||||||
@@ -1169,9 +1185,14 @@ class Commands:
|
|||||||
self.io.tool_error(f"Error processing clipboard content: {e}")
|
self.io.tool_error(f"Error processing clipboard content: {e}")
|
||||||
|
|
||||||
def cmd_read_only(self, args):
|
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():
|
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
|
return
|
||||||
|
|
||||||
filenames = parse_quoted_filenames(args)
|
filenames = parse_quoted_filenames(args)
|
||||||
@@ -1320,6 +1341,10 @@ class Commands:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.io.tool_error(f"Error saving commands to file: {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):
|
def cmd_copy(self, args):
|
||||||
"Copy the last assistant message to the clipboard"
|
"Copy the last assistant message to the clipboard"
|
||||||
all_messages = self.coder.done_messages + self.coder.cur_messages
|
all_messages = self.coder.done_messages + self.coder.cur_messages
|
||||||
@@ -1368,6 +1393,50 @@ class Commands:
|
|||||||
if user_input.strip():
|
if user_input.strip():
|
||||||
self.io.set_placeholder(user_input.rstrip())
|
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):
|
def expand_subdir(file_path):
|
||||||
if file_path.is_file():
|
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):
|
def get_ex_info(self, ex):
|
||||||
"""Return the ExInfo for a given exception instance"""
|
"""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))
|
return self.exceptions.get(ex.__class__, ExInfo(None, None, None))
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
# This needs to sync with MANIFEST.in
|
||||||
|
|
||||||
exclude_website_pats = [
|
exclude_website_pats = [
|
||||||
|
"**/.DS_Store",
|
||||||
"examples/**",
|
"examples/**",
|
||||||
"_posts/**",
|
"_posts/**",
|
||||||
"HISTORY.md",
|
"HISTORY.md",
|
||||||
@@ -7,5 +10,4 @@ exclude_website_pats = [
|
|||||||
"docs/unified-diffs.md",
|
"docs/unified-diffs.md",
|
||||||
"docs/leaderboards/index.md",
|
"docs/leaderboards/index.md",
|
||||||
"assets/**",
|
"assets/**",
|
||||||
"**/.DS_Store",
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -108,9 +108,7 @@ class ChatSummary:
|
|||||||
|
|
||||||
for model in self.models:
|
for model in self.models:
|
||||||
try:
|
try:
|
||||||
summary = simple_send_with_retries(
|
summary = simple_send_with_retries(model, summarize_messages)
|
||||||
model.name, summarize_messages, extra_params=model.extra_params
|
|
||||||
)
|
|
||||||
if summary is not None:
|
if summary is not None:
|
||||||
summary = prompts.summary_prefix + summary
|
summary = prompts.summary_prefix + summary
|
||||||
return [dict(role="user", content=summary)]
|
return [dict(role="user", content=summary)]
|
||||||
|
|||||||
138
aider/io.py
138
aider/io.py
@@ -1,5 +1,6 @@
|
|||||||
import base64
|
import base64
|
||||||
import os
|
import os
|
||||||
|
import signal
|
||||||
import time
|
import time
|
||||||
import webbrowser
|
import webbrowser
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
@@ -11,8 +12,10 @@ from pathlib import Path
|
|||||||
from prompt_toolkit.completion import Completer, Completion, ThreadedCompleter
|
from prompt_toolkit.completion import Completer, Completion, ThreadedCompleter
|
||||||
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
|
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
|
||||||
from prompt_toolkit.enums import EditingMode
|
from prompt_toolkit.enums import EditingMode
|
||||||
|
from prompt_toolkit.filters import Condition, is_searching
|
||||||
from prompt_toolkit.history import FileHistory
|
from prompt_toolkit.history import FileHistory
|
||||||
from prompt_toolkit.key_binding import KeyBindings
|
from prompt_toolkit.key_binding import KeyBindings
|
||||||
|
from prompt_toolkit.keys import Keys
|
||||||
from prompt_toolkit.lexers import PygmentsLexer
|
from prompt_toolkit.lexers import PygmentsLexer
|
||||||
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
|
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
|
||||||
from prompt_toolkit.styles import Style
|
from prompt_toolkit.styles import Style
|
||||||
@@ -173,6 +176,7 @@ class AutoCompleter(Completer):
|
|||||||
class InputOutput:
|
class InputOutput:
|
||||||
num_error_outputs = 0
|
num_error_outputs = 0
|
||||||
num_user_asks = 0
|
num_user_asks = 0
|
||||||
|
clipboard_watcher = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -197,10 +201,14 @@ class InputOutput:
|
|||||||
llm_history_file=None,
|
llm_history_file=None,
|
||||||
editingmode=EditingMode.EMACS,
|
editingmode=EditingMode.EMACS,
|
||||||
fancy_input=True,
|
fancy_input=True,
|
||||||
|
file_watcher=None,
|
||||||
|
multiline_mode=False,
|
||||||
):
|
):
|
||||||
self.placeholder = None
|
self.placeholder = None
|
||||||
|
self.interrupted = False
|
||||||
self.never_prompts = set()
|
self.never_prompts = set()
|
||||||
self.editingmode = editingmode
|
self.editingmode = editingmode
|
||||||
|
self.multiline_mode = multiline_mode
|
||||||
no_color = os.environ.get("NO_COLOR")
|
no_color = os.environ.get("NO_COLOR")
|
||||||
if no_color is not None and no_color != "":
|
if no_color is not None and no_color != "":
|
||||||
pretty = False
|
pretty = False
|
||||||
@@ -261,6 +269,8 @@ class InputOutput:
|
|||||||
else:
|
else:
|
||||||
self.console = Console(force_terminal=False, no_color=True) # non-pretty
|
self.console = Console(force_terminal=False, no_color=True) # non-pretty
|
||||||
|
|
||||||
|
self.file_watcher = file_watcher
|
||||||
|
|
||||||
def _get_style(self):
|
def _get_style(self):
|
||||||
style_dict = {}
|
style_dict = {}
|
||||||
if not self.pretty:
|
if not self.pretty:
|
||||||
@@ -314,7 +324,7 @@ class InputOutput:
|
|||||||
self.tool_error(f"{filename}: {e}")
|
self.tool_error(f"{filename}: {e}")
|
||||||
return
|
return
|
||||||
|
|
||||||
def read_text(self, filename):
|
def read_text(self, filename, silent=False):
|
||||||
if is_image_file(filename):
|
if is_image_file(filename):
|
||||||
return self.read_image(filename)
|
return self.read_image(filename)
|
||||||
|
|
||||||
@@ -322,17 +332,21 @@ class InputOutput:
|
|||||||
with open(str(filename), "r", encoding=self.encoding) as f:
|
with open(str(filename), "r", encoding=self.encoding) as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
except OSError as err:
|
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
|
return
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.tool_error(f"{filename}: file not found error")
|
if not silent:
|
||||||
|
self.tool_error(f"{filename}: file not found error")
|
||||||
return
|
return
|
||||||
except IsADirectoryError:
|
except IsADirectoryError:
|
||||||
self.tool_error(f"{filename}: is a directory")
|
if not silent:
|
||||||
|
self.tool_error(f"{filename}: is a directory")
|
||||||
return
|
return
|
||||||
except UnicodeError as e:
|
except UnicodeError as e:
|
||||||
self.tool_error(f"{filename}: {e}")
|
if not silent:
|
||||||
self.tool_error("Use --encoding to set the unicode encoding.")
|
self.tool_error(f"{filename}: {e}")
|
||||||
|
self.tool_error("Use --encoding to set the unicode encoding.")
|
||||||
return
|
return
|
||||||
|
|
||||||
def write_text(self, filename, content, max_retries=5, initial_delay=0.1):
|
def write_text(self, filename, content, max_retries=5, initial_delay=0.1):
|
||||||
@@ -373,6 +387,13 @@ class InputOutput:
|
|||||||
else:
|
else:
|
||||||
print()
|
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(
|
def get_input(
|
||||||
self,
|
self,
|
||||||
root,
|
root,
|
||||||
@@ -393,6 +414,8 @@ class InputOutput:
|
|||||||
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
|
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
|
||||||
if edit_format:
|
if edit_format:
|
||||||
show += edit_format
|
show += edit_format
|
||||||
|
if self.multiline_mode:
|
||||||
|
show += (" " if edit_format else "") + "multi"
|
||||||
show += "> "
|
show += "> "
|
||||||
|
|
||||||
inp = ""
|
inp = ""
|
||||||
@@ -411,16 +434,51 @@ class InputOutput:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def suspend_to_bg(event):
|
||||||
|
"""Suspend currently running application."""
|
||||||
|
event.app.suspend_to_background()
|
||||||
|
|
||||||
kb = KeyBindings()
|
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")
|
@kb.add("c-space")
|
||||||
def _(event):
|
def _(event):
|
||||||
"Ignore Ctrl when pressing space bar"
|
"Ignore Ctrl when pressing space bar"
|
||||||
event.current_buffer.insert_text(" ")
|
event.current_buffer.insert_text(" ")
|
||||||
|
|
||||||
@kb.add("escape", "c-m", eager=True)
|
@kb.add("c-up")
|
||||||
def _(event):
|
def _(event):
|
||||||
event.current_buffer.insert_text("\n")
|
"Navigate backward through history"
|
||||||
|
event.current_buffer.history_backward()
|
||||||
|
|
||||||
|
@kb.add("c-down")
|
||||||
|
def _(event):
|
||||||
|
"Navigate forward through history"
|
||||||
|
event.current_buffer.history_forward()
|
||||||
|
|
||||||
|
@kb.add("enter", eager=True, filter=~is_searching)
|
||||||
|
def _(event):
|
||||||
|
"Handle Enter key press"
|
||||||
|
if self.multiline_mode:
|
||||||
|
# In multiline mode, Enter adds a newline
|
||||||
|
event.current_buffer.insert_text("\n")
|
||||||
|
else:
|
||||||
|
# In normal mode, Enter submits
|
||||||
|
event.current_buffer.validate_and_handle()
|
||||||
|
|
||||||
|
@kb.add("escape", "enter", eager=True, filter=~is_searching) # This is Alt+Enter
|
||||||
|
def _(event):
|
||||||
|
"Handle Alt+Enter key press"
|
||||||
|
if self.multiline_mode:
|
||||||
|
# In multiline mode, Alt+Enter submits
|
||||||
|
event.current_buffer.validate_and_handle()
|
||||||
|
else:
|
||||||
|
# In normal mode, Alt+Enter adds a newline
|
||||||
|
event.current_buffer.insert_text("\n")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if multiline_input:
|
if multiline_input:
|
||||||
@@ -432,6 +490,13 @@ class InputOutput:
|
|||||||
default = self.placeholder or ""
|
default = self.placeholder or ""
|
||||||
self.placeholder = None
|
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(
|
line = self.prompt_session.prompt(
|
||||||
show,
|
show,
|
||||||
default=default,
|
default=default,
|
||||||
@@ -443,9 +508,30 @@ class InputOutput:
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
line = input(show)
|
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:
|
except UnicodeEncodeError as err:
|
||||||
self.tool_error(str(err))
|
self.tool_error(str(err))
|
||||||
return ""
|
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:
|
if line.strip("\r\n") and not multiline_input:
|
||||||
stripped = line.strip("\r\n")
|
stripped = line.strip("\r\n")
|
||||||
@@ -492,10 +578,13 @@ class InputOutput:
|
|||||||
def add_to_input_history(self, inp):
|
def add_to_input_history(self, inp):
|
||||||
if not self.input_history_file:
|
if not self.input_history_file:
|
||||||
return
|
return
|
||||||
FileHistory(self.input_history_file).append_string(inp)
|
try:
|
||||||
# Also add to the in-memory history if it exists
|
FileHistory(self.input_history_file).append_string(inp)
|
||||||
if self.prompt_session and self.prompt_session.history:
|
# Also add to the in-memory history if it exists
|
||||||
self.prompt_session.history.append_string(inp)
|
if self.prompt_session and self.prompt_session.history:
|
||||||
|
self.prompt_session.history.append_string(inp)
|
||||||
|
except OSError as err:
|
||||||
|
self.tool_warning(f"Unable to write to input history file: {err}")
|
||||||
|
|
||||||
def get_input_history(self):
|
def get_input_history(self):
|
||||||
if not self.input_history_file:
|
if not self.input_history_file:
|
||||||
@@ -560,6 +649,9 @@ class InputOutput:
|
|||||||
group=None,
|
group=None,
|
||||||
allow_never=False,
|
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
|
self.num_user_asks += 1
|
||||||
|
|
||||||
question_id = (question, subject)
|
question_id = (question, subject)
|
||||||
@@ -617,6 +709,7 @@ class InputOutput:
|
|||||||
res = self.prompt_session.prompt(
|
res = self.prompt_session.prompt(
|
||||||
question,
|
question,
|
||||||
style=style,
|
style=style,
|
||||||
|
complete_while_typing=False,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
res = input(question)
|
res = input(question)
|
||||||
@@ -657,9 +750,15 @@ class InputOutput:
|
|||||||
hist = f"{question.strip()} {res}"
|
hist = f"{question.strip()} {res}"
|
||||||
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
||||||
|
|
||||||
|
# Restore original multiline mode
|
||||||
|
self.multiline_mode = orig_multiline
|
||||||
|
|
||||||
return is_yes
|
return is_yes
|
||||||
|
|
||||||
def prompt_ask(self, question, default="", subject=None):
|
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
|
self.num_user_asks += 1
|
||||||
|
|
||||||
if subject:
|
if subject:
|
||||||
@@ -683,6 +782,9 @@ class InputOutput:
|
|||||||
if self.yes in (True, False):
|
if self.yes in (True, False):
|
||||||
self.tool_output(hist)
|
self.tool_output(hist)
|
||||||
|
|
||||||
|
# Restore original multiline mode
|
||||||
|
self.multiline_mode = orig_multiline
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _tool_message(self, message="", strip=True, color=None):
|
def _tool_message(self, message="", strip=True, color=None):
|
||||||
@@ -752,6 +854,18 @@ class InputOutput:
|
|||||||
def print(self, message=""):
|
def print(self, message=""):
|
||||||
print(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):
|
def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True):
|
||||||
if blockquote:
|
if blockquote:
|
||||||
if strip:
|
if strip:
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ class Linter:
|
|||||||
try:
|
try:
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
cmd,
|
cmd,
|
||||||
cwd=self.root,
|
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
encoding=self.encoding,
|
encoding=self.encoding,
|
||||||
errors="replace",
|
errors="replace",
|
||||||
|
cwd=self.root,
|
||||||
)
|
)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
print(f"Unable to execute lint command: {err}")
|
print(f"Unable to execute lint command: {err}")
|
||||||
@@ -152,12 +152,12 @@ class Linter:
|
|||||||
try:
|
try:
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
flake8_cmd,
|
flake8_cmd,
|
||||||
cwd=self.root,
|
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
check=False,
|
check=False,
|
||||||
encoding=self.encoding,
|
encoding=self.encoding,
|
||||||
errors="replace",
|
errors="replace",
|
||||||
|
cwd=self.root,
|
||||||
)
|
)
|
||||||
errors = result.stdout + result.stderr
|
errors = result.stdout + result.stderr
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ os.environ["LITELLM_MODE"] = "PRODUCTION"
|
|||||||
|
|
||||||
# `import litellm` takes 1.5 seconds, defer it!
|
# `import litellm` takes 1.5 seconds, defer it!
|
||||||
|
|
||||||
|
VERBOSE = False
|
||||||
|
|
||||||
|
|
||||||
class LazyLiteLLM:
|
class LazyLiteLLM:
|
||||||
_lazy_module = None
|
_lazy_module = None
|
||||||
@@ -27,6 +29,9 @@ class LazyLiteLLM:
|
|||||||
if self._lazy_module is not None:
|
if self._lazy_module is not None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if VERBOSE:
|
||||||
|
print("Loading litellm...")
|
||||||
|
|
||||||
self._lazy_module = importlib.import_module("litellm")
|
self._lazy_module = importlib.import_module("litellm")
|
||||||
|
|
||||||
self._lazy_module.suppress_debug_info = True
|
self._lazy_module.suppress_debug_info = True
|
||||||
|
|||||||
184
aider/main.py
184
aider/main.py
@@ -9,7 +9,11 @@ import webbrowser
|
|||||||
from dataclasses import fields
|
from dataclasses import fields
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import git
|
try:
|
||||||
|
import git
|
||||||
|
except ImportError:
|
||||||
|
git = None
|
||||||
|
|
||||||
import importlib_resources
|
import importlib_resources
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from prompt_toolkit.enums import EditingMode
|
from prompt_toolkit.enums import EditingMode
|
||||||
@@ -20,6 +24,7 @@ from aider.args import get_parser
|
|||||||
from aider.coders import Coder
|
from aider.coders import Coder
|
||||||
from aider.coders.base_coder import UnknownEditFormat
|
from aider.coders.base_coder import UnknownEditFormat
|
||||||
from aider.commands import Commands, SwitchCoder
|
from aider.commands import Commands, SwitchCoder
|
||||||
|
from aider.copypaste import ClipboardWatcher
|
||||||
from aider.format_settings import format_settings, scrub_sensitive_info
|
from aider.format_settings import format_settings, scrub_sensitive_info
|
||||||
from aider.history import ChatSummary
|
from aider.history import ChatSummary
|
||||||
from aider.io import InputOutput
|
from aider.io import InputOutput
|
||||||
@@ -28,6 +33,7 @@ from aider.models import ModelSettings
|
|||||||
from aider.repo import ANY_GIT_ERROR, GitRepo
|
from aider.repo import ANY_GIT_ERROR, GitRepo
|
||||||
from aider.report import report_uncaught_exceptions
|
from aider.report import report_uncaught_exceptions
|
||||||
from aider.versioncheck import check_version, install_from_main_branch, install_upgrade
|
from aider.versioncheck import check_version, install_from_main_branch, install_upgrade
|
||||||
|
from aider.watch import FileWatcher
|
||||||
|
|
||||||
from .dump import dump # noqa: F401
|
from .dump import dump # noqa: F401
|
||||||
|
|
||||||
@@ -91,6 +97,9 @@ def make_new_repo(git_root, io):
|
|||||||
|
|
||||||
|
|
||||||
def setup_git(git_root, io):
|
def setup_git(git_root, io):
|
||||||
|
if git is None:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cwd = Path.cwd()
|
cwd = Path.cwd()
|
||||||
except OSError:
|
except OSError:
|
||||||
@@ -157,13 +166,17 @@ def check_gitignore(git_root, io, ask=True):
|
|||||||
|
|
||||||
gitignore_file = Path(git_root) / ".gitignore"
|
gitignore_file = Path(git_root) / ".gitignore"
|
||||||
if gitignore_file.exists():
|
if gitignore_file.exists():
|
||||||
content = io.read_text(gitignore_file)
|
try:
|
||||||
if content is None:
|
content = io.read_text(gitignore_file)
|
||||||
|
if content is None:
|
||||||
|
return
|
||||||
|
existing_lines = content.splitlines()
|
||||||
|
for pat in patterns:
|
||||||
|
if pat not in existing_lines:
|
||||||
|
patterns_to_add.append(pat)
|
||||||
|
except OSError as e:
|
||||||
|
io.tool_error(f"Error when trying to read {gitignore_file}: {e}")
|
||||||
return
|
return
|
||||||
existing_lines = content.splitlines()
|
|
||||||
for pat in patterns:
|
|
||||||
if pat not in existing_lines:
|
|
||||||
patterns_to_add.append(pat)
|
|
||||||
else:
|
else:
|
||||||
content = ""
|
content = ""
|
||||||
patterns_to_add = patterns
|
patterns_to_add = patterns
|
||||||
@@ -177,9 +190,17 @@ def check_gitignore(git_root, io, ask=True):
|
|||||||
if content and not content.endswith("\n"):
|
if content and not content.endswith("\n"):
|
||||||
content += "\n"
|
content += "\n"
|
||||||
content += "\n".join(patterns_to_add) + "\n"
|
content += "\n".join(patterns_to_add) + "\n"
|
||||||
io.write_text(gitignore_file, content)
|
|
||||||
|
|
||||||
io.tool_output(f"Added {', '.join(patterns_to_add)} to .gitignore")
|
try:
|
||||||
|
io.write_text(gitignore_file, content)
|
||||||
|
io.tool_output(f"Added {', '.join(patterns_to_add)} to .gitignore")
|
||||||
|
except OSError as e:
|
||||||
|
io.tool_error(f"Error when trying to write to {gitignore_file}: {e}")
|
||||||
|
io.tool_output(
|
||||||
|
"Try running with appropriate permissions or manually add these patterns to .gitignore:"
|
||||||
|
)
|
||||||
|
for pattern in patterns_to_add:
|
||||||
|
io.tool_output(f" {pattern}")
|
||||||
|
|
||||||
|
|
||||||
def check_streamlit_install(io):
|
def check_streamlit_install(io):
|
||||||
@@ -396,7 +417,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
if argv is None:
|
if argv is None:
|
||||||
argv = sys.argv[1:]
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
if force_git_root:
|
if git is None:
|
||||||
|
git_root = None
|
||||||
|
elif force_git_root:
|
||||||
git_root = force_git_root
|
git_root = force_git_root
|
||||||
else:
|
else:
|
||||||
git_root = get_git_root()
|
git_root = get_git_root()
|
||||||
@@ -443,6 +466,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
|
# Parse again to include any arguments that might have been defined in .env
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
|
|
||||||
|
if git is None:
|
||||||
|
args.git = False
|
||||||
|
|
||||||
if args.analytics_disable:
|
if args.analytics_disable:
|
||||||
analytics = Analytics(permanently_disable=True)
|
analytics = Analytics(permanently_disable=True)
|
||||||
print("Analytics have been permanently disabled.")
|
print("Analytics have been permanently disabled.")
|
||||||
@@ -455,6 +481,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
litellm._lazy_module.client_session = httpx.Client(verify=False)
|
litellm._lazy_module.client_session = httpx.Client(verify=False)
|
||||||
litellm._lazy_module.aclient_session = httpx.AsyncClient(verify=False)
|
litellm._lazy_module.aclient_session = httpx.AsyncClient(verify=False)
|
||||||
|
|
||||||
|
if args.timeout:
|
||||||
|
litellm._load_litellm()
|
||||||
|
litellm._lazy_module.request_timeout = args.timeout
|
||||||
|
|
||||||
if args.dark_mode:
|
if args.dark_mode:
|
||||||
args.user_input_color = "#32FF32"
|
args.user_input_color = "#32FF32"
|
||||||
args.tool_error_color = "#FF3333"
|
args.tool_error_color = "#FF3333"
|
||||||
@@ -497,6 +527,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
llm_history_file=args.llm_history_file,
|
llm_history_file=args.llm_history_file,
|
||||||
editingmode=editing_mode,
|
editingmode=editing_mode,
|
||||||
fancy_input=args.fancy_input,
|
fancy_input=args.fancy_input,
|
||||||
|
multiline_mode=args.multiline,
|
||||||
)
|
)
|
||||||
|
|
||||||
io = get_io(args.pretty)
|
io = get_io(args.pretty)
|
||||||
@@ -508,6 +539,50 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
io = get_io(False)
|
io = get_io(False)
|
||||||
io.tool_warning("Terminal does not support pretty output (UnicodeDecodeError)")
|
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)
|
analytics = Analytics(logfile=args.analytics_log, permanently_disable=args.analytics_disable)
|
||||||
if args.analytics is not False:
|
if args.analytics is not False:
|
||||||
if analytics.need_to_ask(args.analytics):
|
if analytics.need_to_ask(args.analytics):
|
||||||
@@ -535,9 +610,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
|
|
||||||
if args.gui and not return_coder:
|
if args.gui and not return_coder:
|
||||||
if not check_streamlit_install(io):
|
if not check_streamlit_install(io):
|
||||||
|
analytics.event("exit", reason="Streamlit not installed")
|
||||||
return
|
return
|
||||||
analytics.event("gui session")
|
analytics.event("gui session")
|
||||||
launch_gui(argv)
|
launch_gui(argv)
|
||||||
|
analytics.event("exit", reason="GUI session ended")
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
@@ -548,7 +625,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]
|
fnames = [str(Path(fn).resolve()) for fn in all_files]
|
||||||
read_only_fnames = []
|
read_only_fnames = []
|
||||||
for fn in args.read or []:
|
for fn in args.read or []:
|
||||||
path = Path(fn).resolve()
|
path = Path(fn).expanduser().resolve()
|
||||||
if path.is_dir():
|
if path.is_dir():
|
||||||
read_only_fnames.extend(str(f) for f in path.rglob("*") if f.is_file())
|
read_only_fnames.extend(str(f) for f in path.rglob("*") if f.is_file())
|
||||||
else:
|
else:
|
||||||
@@ -564,6 +641,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
io.tool_output(
|
io.tool_output(
|
||||||
"Provide either a single directory of a git repo, or a list of one or more files."
|
"Provide either a single directory of a git repo, or a list of one or more files."
|
||||||
)
|
)
|
||||||
|
analytics.event("exit", reason="Invalid directory input")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
git_dname = None
|
git_dname = None
|
||||||
@@ -574,26 +652,31 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
fnames = []
|
fnames = []
|
||||||
else:
|
else:
|
||||||
io.tool_error(f"{all_files[0]} is a directory, but --no-git selected.")
|
io.tool_error(f"{all_files[0]} is a directory, but --no-git selected.")
|
||||||
|
analytics.event("exit", reason="Directory with --no-git")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# We can't know the git repo for sure until after parsing the args.
|
# We can't know the git repo for sure until after parsing the args.
|
||||||
# If we guessed wrong, reparse because that changes things like
|
# If we guessed wrong, reparse because that changes things like
|
||||||
# the location of the config.yml and history files.
|
# 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)
|
right_repo_root = guessed_wrong_repo(io, git_root, fnames, git_dname)
|
||||||
if right_repo_root:
|
if right_repo_root:
|
||||||
|
analytics.event("exit", reason="Recursing with correct repo")
|
||||||
return main(argv, input, output, right_repo_root, return_coder=return_coder)
|
return main(argv, input, output, right_repo_root, return_coder=return_coder)
|
||||||
|
|
||||||
if args.just_check_update:
|
if args.just_check_update:
|
||||||
update_available = check_version(io, just_check=True, verbose=args.verbose)
|
update_available = check_version(io, just_check=True, verbose=args.verbose)
|
||||||
|
analytics.event("exit", reason="Just checking update")
|
||||||
return 0 if not update_available else 1
|
return 0 if not update_available else 1
|
||||||
|
|
||||||
if args.install_main_branch:
|
if args.install_main_branch:
|
||||||
success = install_from_main_branch(io)
|
success = install_from_main_branch(io)
|
||||||
|
analytics.event("exit", reason="Installed main branch")
|
||||||
return 0 if success else 1
|
return 0 if success else 1
|
||||||
|
|
||||||
if args.upgrade:
|
if args.upgrade:
|
||||||
success = install_upgrade(io)
|
success = install_upgrade(io)
|
||||||
|
analytics.event("exit", reason="Upgrade completed")
|
||||||
return 0 if success else 1
|
return 0 if success else 1
|
||||||
|
|
||||||
if args.check_update:
|
if args.check_update:
|
||||||
@@ -601,6 +684,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
|
|
||||||
if args.list_models:
|
if args.list_models:
|
||||||
models.print_matching_models(io, args.list_models)
|
models.print_matching_models(io, args.list_models)
|
||||||
|
analytics.event("exit", reason="Listed models")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if args.git:
|
if args.git:
|
||||||
@@ -619,20 +703,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)
|
is_first_run = is_first_run_of_new_version(io, verbose=args.verbose)
|
||||||
check_and_load_imports(io, is_first_run, 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_models(git_root, args.model_settings_file, io, verbose=args.verbose)
|
||||||
register_litellm_models(git_root, args.model_metadata_file, io, verbose=args.verbose)
|
register_litellm_models(git_root, args.model_metadata_file, io, verbose=args.verbose)
|
||||||
|
|
||||||
@@ -644,6 +714,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
if len(parts) != 2:
|
if len(parts) != 2:
|
||||||
io.tool_error(f"Invalid alias format: {alias_def}")
|
io.tool_error(f"Invalid alias format: {alias_def}")
|
||||||
io.tool_output("Format should be: alias:model-name")
|
io.tool_output("Format should be: alias:model-name")
|
||||||
|
analytics.event("exit", reason="Invalid alias format error")
|
||||||
return 1
|
return 1
|
||||||
alias, model = parts
|
alias, model = parts
|
||||||
models.MODEL_ALIASES[alias.strip()] = model.strip()
|
models.MODEL_ALIASES[alias.strip()] = model.strip()
|
||||||
@@ -660,6 +731,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
editor_edit_format=args.editor_edit_format,
|
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:
|
if args.verbose:
|
||||||
io.tool_output("Model metadata:")
|
io.tool_output("Model metadata:")
|
||||||
io.tool_output(json.dumps(main_model.info, indent=4))
|
io.tool_output(json.dumps(main_model.info, indent=4))
|
||||||
@@ -672,6 +747,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
|
|
||||||
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
|
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
|
||||||
if lint_cmds is None:
|
if lint_cmds is None:
|
||||||
|
analytics.event("exit", reason="Invalid lint command format")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if args.show_model_warnings:
|
if args.show_model_warnings:
|
||||||
@@ -684,6 +760,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
io.offer_url(urls.model_warnings, "Open documentation url for more info?")
|
io.offer_url(urls.model_warnings, "Open documentation url for more info?")
|
||||||
io.tool_output()
|
io.tool_output()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
analytics.event("exit", reason="Keyboard interrupt during model warnings")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
repo = None
|
repo = None
|
||||||
@@ -707,8 +784,14 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
|
|
||||||
if not args.skip_sanity_check_repo:
|
if not args.skip_sanity_check_repo:
|
||||||
if not sanity_check_repo(repo, io):
|
if not sanity_check_repo(repo, io):
|
||||||
|
analytics.event("exit", reason="Repository sanity check failed")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
if repo:
|
||||||
|
analytics.event("repo", num_files=len(repo.get_tracked_files()))
|
||||||
|
else:
|
||||||
|
analytics.event("no-repo")
|
||||||
|
|
||||||
commands = Commands(
|
commands = Commands(
|
||||||
io,
|
io,
|
||||||
None,
|
None,
|
||||||
@@ -765,18 +848,38 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
suggest_shell_commands=args.suggest_shell_commands,
|
suggest_shell_commands=args.suggest_shell_commands,
|
||||||
chat_language=args.chat_language,
|
chat_language=args.chat_language,
|
||||||
detect_urls=args.detect_urls,
|
detect_urls=args.detect_urls,
|
||||||
|
auto_copy_context=args.copy_paste,
|
||||||
)
|
)
|
||||||
except UnknownEditFormat as err:
|
except UnknownEditFormat as err:
|
||||||
io.tool_error(str(err))
|
io.tool_error(str(err))
|
||||||
io.offer_url(urls.edit_formats, "Open documentation about edit formats?")
|
io.offer_url(urls.edit_formats, "Open documentation about edit formats?")
|
||||||
|
analytics.event("exit", reason="Unknown edit format")
|
||||||
return 1
|
return 1
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
io.tool_error(str(err))
|
io.tool_error(str(err))
|
||||||
|
analytics.event("exit", reason="ValueError during coder creation")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if return_coder:
|
if return_coder:
|
||||||
|
analytics.event("exit", reason="Returning coder object")
|
||||||
return coder
|
return coder
|
||||||
|
|
||||||
|
ignores = []
|
||||||
|
if git_root:
|
||||||
|
ignores.append(str(Path(git_root) / ".gitignore"))
|
||||||
|
if args.aiderignore:
|
||||||
|
ignores.append(args.aiderignore)
|
||||||
|
|
||||||
|
if args.watch_files:
|
||||||
|
file_watcher = FileWatcher(
|
||||||
|
coder, gitignores=ignores, verbose=args.verbose, analytics=analytics
|
||||||
|
)
|
||||||
|
coder.file_watcher = file_watcher
|
||||||
|
|
||||||
|
if args.copy_paste:
|
||||||
|
analytics.event("copy-paste mode")
|
||||||
|
ClipboardWatcher(coder.io, verbose=args.verbose)
|
||||||
|
|
||||||
coder.show_announcements()
|
coder.show_announcements()
|
||||||
|
|
||||||
if args.show_prompts:
|
if args.show_prompts:
|
||||||
@@ -785,6 +888,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
]
|
]
|
||||||
messages = coder.format_messages().all_messages()
|
messages = coder.format_messages().all_messages()
|
||||||
utils.show_messages(messages)
|
utils.show_messages(messages)
|
||||||
|
analytics.event("exit", reason="Showed prompts")
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.lint:
|
if args.lint:
|
||||||
@@ -793,10 +897,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
if args.test:
|
if args.test:
|
||||||
if not args.test_cmd:
|
if not args.test_cmd:
|
||||||
io.tool_error("No --test-cmd provided.")
|
io.tool_error("No --test-cmd provided.")
|
||||||
|
analytics.event("exit", reason="No test command provided")
|
||||||
return 1
|
return 1
|
||||||
test_errors = coder.commands.cmd_test(args.test_cmd)
|
coder.commands.cmd_test(args.test_cmd)
|
||||||
if test_errors:
|
if io.placeholder:
|
||||||
coder.run(test_errors)
|
coder.run(io.placeholder)
|
||||||
|
|
||||||
if args.commit:
|
if args.commit:
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
@@ -805,32 +910,30 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
coder.commands.cmd_commit()
|
coder.commands.cmd_commit()
|
||||||
|
|
||||||
if args.lint or args.test or args.commit:
|
if args.lint or args.test or args.commit:
|
||||||
|
analytics.event("exit", reason="Completed lint/test/commit")
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.show_repo_map:
|
if args.show_repo_map:
|
||||||
repo_map = coder.get_repo_map()
|
repo_map = coder.get_repo_map()
|
||||||
if repo_map:
|
if repo_map:
|
||||||
io.tool_output(repo_map)
|
io.tool_output(repo_map)
|
||||||
|
analytics.event("exit", reason="Showed repo map")
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.apply:
|
if args.apply:
|
||||||
content = io.read_text(args.apply)
|
content = io.read_text(args.apply)
|
||||||
if content is None:
|
if content is None:
|
||||||
|
analytics.event("exit", reason="Failed to read apply content")
|
||||||
return
|
return
|
||||||
coder.partial_response_content = content
|
coder.partial_response_content = content
|
||||||
coder.apply_updates()
|
coder.apply_updates()
|
||||||
|
analytics.event("exit", reason="Applied updates")
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.apply_clipboard_edits:
|
if args.apply_clipboard_edits:
|
||||||
args.edit_format = main_model.editor_edit_format
|
args.edit_format = main_model.editor_edit_format
|
||||||
args.message = "/paste"
|
args.message = "/paste"
|
||||||
|
|
||||||
if "VSCODE_GIT_IPC_HANDLE" in os.environ:
|
|
||||||
args.pretty = False
|
|
||||||
io.tool_output("VSCode terminal detected, pretty output has been disabled.")
|
|
||||||
|
|
||||||
io.tool_output('Use /help <question> for help, run "aider --help" to see cmd line args')
|
|
||||||
|
|
||||||
if args.show_release_notes is True:
|
if args.show_release_notes is True:
|
||||||
io.tool_output(f"Opening release notes: {urls.release_notes}")
|
io.tool_output(f"Opening release notes: {urls.release_notes}")
|
||||||
io.tool_output()
|
io.tool_output()
|
||||||
@@ -862,6 +965,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
coder.run(with_message=args.message)
|
coder.run(with_message=args.message)
|
||||||
except SwitchCoder:
|
except SwitchCoder:
|
||||||
pass
|
pass
|
||||||
|
analytics.event("exit", reason="Completed --message")
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.message_file:
|
if args.message_file:
|
||||||
@@ -871,13 +975,18 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
coder.run(with_message=message_from_file)
|
coder.run(with_message=message_from_file)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
io.tool_error(f"Message file not found: {args.message_file}")
|
io.tool_error(f"Message file not found: {args.message_file}")
|
||||||
|
analytics.event("exit", reason="Message file not found")
|
||||||
return 1
|
return 1
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
io.tool_error(f"Error reading message file: {e}")
|
io.tool_error(f"Error reading message file: {e}")
|
||||||
|
analytics.event("exit", reason="Message file IO error")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
analytics.event("exit", reason="Completed --message-file")
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.exit:
|
if args.exit:
|
||||||
|
analytics.event("exit", reason="Exit flag set")
|
||||||
return
|
return
|
||||||
|
|
||||||
analytics.event("cli session", main_model=main_model, edit_format=main_model.edit_format)
|
analytics.event("cli session", main_model=main_model, edit_format=main_model.edit_format)
|
||||||
@@ -885,6 +994,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
coder.run()
|
coder.run()
|
||||||
|
analytics.event("exit", reason="Completed main CLI coder.run")
|
||||||
return
|
return
|
||||||
except SwitchCoder as switch:
|
except SwitchCoder as switch:
|
||||||
kwargs = dict(io=io, from_coder=coder)
|
kwargs = dict(io=io, from_coder=coder)
|
||||||
@@ -903,6 +1013,10 @@ def is_first_run_of_new_version(io, verbose=False):
|
|||||||
installs_file = Path.home() / ".aider" / "installs.json"
|
installs_file = Path.home() / ".aider" / "installs.json"
|
||||||
key = (__version__, sys.executable)
|
key = (__version__, sys.executable)
|
||||||
|
|
||||||
|
# Never show notes for .dev versions
|
||||||
|
if ".dev" in __version__:
|
||||||
|
return False
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
io.tool_output(
|
io.tool_output(
|
||||||
f"Checking imports for version {__version__} and executable {sys.executable}"
|
f"Checking imports for version {__version__} and executable {sys.executable}"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from aider.dump import dump # noqa: F401
|
|||||||
from aider.llm import litellm
|
from aider.llm import litellm
|
||||||
|
|
||||||
DEFAULT_MODEL_NAME = "gpt-4o"
|
DEFAULT_MODEL_NAME = "gpt-4o"
|
||||||
ANTHROPIC_BETA_HEADER = "prompt-caching-2024-07-31"
|
ANTHROPIC_BETA_HEADER = "prompt-caching-2024-07-31,pdfs-2024-09-25"
|
||||||
|
|
||||||
OPENAI_MODELS = """
|
OPENAI_MODELS = """
|
||||||
gpt-4
|
gpt-4
|
||||||
@@ -69,13 +69,14 @@ MODEL_ALIASES = {
|
|||||||
"opus": "claude-3-opus-20240229",
|
"opus": "claude-3-opus-20240229",
|
||||||
# GPT models
|
# GPT models
|
||||||
"4": "gpt-4-0613",
|
"4": "gpt-4-0613",
|
||||||
"4o": "gpt-4o-2024-08-06",
|
"4o": "gpt-4o",
|
||||||
"4-turbo": "gpt-4-1106-preview",
|
"4-turbo": "gpt-4-1106-preview",
|
||||||
"35turbo": "gpt-3.5-turbo",
|
"35turbo": "gpt-3.5-turbo",
|
||||||
"35-turbo": "gpt-3.5-turbo",
|
"35-turbo": "gpt-3.5-turbo",
|
||||||
"3": "gpt-3.5-turbo",
|
"3": "gpt-3.5-turbo",
|
||||||
# Other models
|
# Other models
|
||||||
"deepseek": "deepseek/deepseek-coder",
|
"deepseek": "deepseek/deepseek-coder",
|
||||||
|
"flash": "gemini/gemini-2.0-flash-exp",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -583,6 +584,21 @@ MODEL_SETTINGS = [
|
|||||||
"diff-fenced",
|
"diff-fenced",
|
||||||
use_repo_map=True,
|
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(
|
ModelSettings(
|
||||||
"vertex_ai/gemini-pro-experimental",
|
"vertex_ai/gemini-pro-experimental",
|
||||||
"diff-fenced",
|
"diff-fenced",
|
||||||
@@ -594,6 +610,12 @@ MODEL_SETTINGS = [
|
|||||||
use_repo_map=False,
|
use_repo_map=False,
|
||||||
send_undo_reply=False,
|
send_undo_reply=False,
|
||||||
),
|
),
|
||||||
|
ModelSettings(
|
||||||
|
"gemini/gemini-2.0-flash-exp",
|
||||||
|
"diff",
|
||||||
|
use_repo_map=True,
|
||||||
|
send_undo_reply=False,
|
||||||
|
),
|
||||||
ModelSettings(
|
ModelSettings(
|
||||||
"deepseek/deepseek-chat",
|
"deepseek/deepseek-chat",
|
||||||
"diff",
|
"diff",
|
||||||
@@ -1210,10 +1232,10 @@ def sanity_check_model(io, model):
|
|||||||
status = "Set" if value else "Not set"
|
status = "Set" if value else "Not set"
|
||||||
io.tool_output(f"- {key}: {status}")
|
io.tool_output(f"- {key}: {status}")
|
||||||
|
|
||||||
if platform.system() == "Windows" or True:
|
if platform.system() == "Windows":
|
||||||
io.tool_output(
|
io.tool_output(
|
||||||
"If you just set these environment variables using `setx` you may need to restart"
|
"Note: You may need to restart your terminal or command prompt for `setx` to take"
|
||||||
" your terminal or command prompt for the changes to take effect."
|
" effect."
|
||||||
)
|
)
|
||||||
|
|
||||||
elif not model.keys_in_environment:
|
elif not model.keys_in_environment:
|
||||||
|
|||||||
@@ -2,7 +2,17 @@ import os
|
|||||||
import time
|
import time
|
||||||
from pathlib import Path, PurePosixPath
|
from pathlib import Path, PurePosixPath
|
||||||
|
|
||||||
import git
|
try:
|
||||||
|
import git
|
||||||
|
|
||||||
|
ANY_GIT_ERROR = [
|
||||||
|
git.exc.ODBError,
|
||||||
|
git.exc.GitError,
|
||||||
|
]
|
||||||
|
except ImportError:
|
||||||
|
git = None
|
||||||
|
ANY_GIT_ERROR = []
|
||||||
|
|
||||||
import pathspec
|
import pathspec
|
||||||
|
|
||||||
from aider import prompts, utils
|
from aider import prompts, utils
|
||||||
@@ -10,15 +20,14 @@ from aider.sendchat import simple_send_with_retries
|
|||||||
|
|
||||||
from .dump import dump # noqa: F401
|
from .dump import dump # noqa: F401
|
||||||
|
|
||||||
ANY_GIT_ERROR = (
|
ANY_GIT_ERROR += [
|
||||||
git.exc.ODBError,
|
|
||||||
git.exc.GitError,
|
|
||||||
OSError,
|
OSError,
|
||||||
IndexError,
|
IndexError,
|
||||||
BufferError,
|
BufferError,
|
||||||
TypeError,
|
TypeError,
|
||||||
ValueError,
|
ValueError,
|
||||||
)
|
]
|
||||||
|
ANY_GIT_ERROR = tuple(ANY_GIT_ERROR)
|
||||||
|
|
||||||
|
|
||||||
class GitRepo:
|
class GitRepo:
|
||||||
@@ -192,9 +201,7 @@ class GitRepo:
|
|||||||
max_tokens = model.info.get("max_input_tokens") or 0
|
max_tokens = model.info.get("max_input_tokens") or 0
|
||||||
if max_tokens and num_tokens > max_tokens:
|
if max_tokens and num_tokens > max_tokens:
|
||||||
continue
|
continue
|
||||||
commit_message = simple_send_with_retries(
|
commit_message = simple_send_with_retries(model, messages)
|
||||||
model.name, messages, extra_params=model.extra_params
|
|
||||||
)
|
|
||||||
if commit_message:
|
if commit_message:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"vertex_ai-language-models/gemini-2.0-flash-exp": {
|
||||||
|
"max_tokens": 8192,
|
||||||
|
"max_input_tokens": 1048576,
|
||||||
|
"max_output_tokens": 8192,
|
||||||
|
"max_images_per_prompt": 3000,
|
||||||
|
"max_videos_per_prompt": 10,
|
||||||
|
"max_video_length": 1,
|
||||||
|
"max_audio_length_hours": 8.4,
|
||||||
|
"max_audio_per_prompt": 1,
|
||||||
|
"max_pdf_size_mb": 30,
|
||||||
|
"litellm_provider": "vertex_ai-language-models",
|
||||||
|
"mode": "chat",
|
||||||
|
"supports_system_messages": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"source": "https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2"
|
||||||
|
},
|
||||||
|
"gemini/gemini-2.0-flash-exp": {
|
||||||
|
"max_tokens": 8192,
|
||||||
|
"max_input_tokens": 1048576,
|
||||||
|
"max_output_tokens": 8192,
|
||||||
|
"max_images_per_prompt": 3000,
|
||||||
|
"max_videos_per_prompt": 10,
|
||||||
|
"max_video_length": 1,
|
||||||
|
"max_audio_length_hours": 8.4,
|
||||||
|
"max_audio_per_prompt": 1,
|
||||||
|
"max_pdf_size_mb": 30,
|
||||||
|
"litellm_provider": "gemini",
|
||||||
|
"mode": "chat",
|
||||||
|
"supports_system_messages": true,
|
||||||
|
"supports_function_calling": true,
|
||||||
|
"supports_vision": true,
|
||||||
|
"supports_response_schema": true,
|
||||||
|
"source": "https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import pexpect
|
|||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
|
|
||||||
def run_cmd(command, verbose=False, error_print=None):
|
def run_cmd(command, verbose=False, error_print=None, cwd=None):
|
||||||
try:
|
try:
|
||||||
if sys.stdin.isatty() and hasattr(pexpect, "spawn") and platform.system() != "Windows":
|
if sys.stdin.isatty() and hasattr(pexpect, "spawn") and platform.system() != "Windows":
|
||||||
return run_cmd_pexpect(command, verbose)
|
return run_cmd_pexpect(command, verbose, cwd)
|
||||||
|
|
||||||
return run_cmd_subprocess(command, verbose)
|
return run_cmd_subprocess(command, verbose, cwd)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
error_message = f"Error occurred while running command '{command}': {str(e)}"
|
error_message = f"Error occurred while running command '{command}': {str(e)}"
|
||||||
if error_print is None:
|
if error_print is None:
|
||||||
@@ -39,7 +39,7 @@ def get_windows_parent_process_name():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def run_cmd_subprocess(command, verbose=False):
|
def run_cmd_subprocess(command, verbose=False, cwd=None):
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Using run_cmd_subprocess:", command)
|
print("Using run_cmd_subprocess:", command)
|
||||||
|
|
||||||
@@ -69,6 +69,7 @@ def run_cmd_subprocess(command, verbose=False):
|
|||||||
errors="replace",
|
errors="replace",
|
||||||
bufsize=0, # Set bufsize to 0 for unbuffered output
|
bufsize=0, # Set bufsize to 0 for unbuffered output
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
|
cwd=cwd,
|
||||||
)
|
)
|
||||||
|
|
||||||
output = []
|
output = []
|
||||||
@@ -85,7 +86,7 @@ def run_cmd_subprocess(command, verbose=False):
|
|||||||
return 1, str(e)
|
return 1, str(e)
|
||||||
|
|
||||||
|
|
||||||
def run_cmd_pexpect(command, verbose=False):
|
def run_cmd_pexpect(command, verbose=False, cwd=None):
|
||||||
"""
|
"""
|
||||||
Run a shell command interactively using pexpect, capturing all output.
|
Run a shell command interactively using pexpect, capturing all output.
|
||||||
|
|
||||||
@@ -112,12 +113,12 @@ def run_cmd_pexpect(command, verbose=False):
|
|||||||
# Use the shell from SHELL environment variable
|
# Use the shell from SHELL environment variable
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Running pexpect.spawn with shell:", shell)
|
print("Running pexpect.spawn with shell:", shell)
|
||||||
child = pexpect.spawn(shell, args=["-c", command], encoding="utf-8")
|
child = pexpect.spawn(shell, args=["-i", "-c", command], encoding="utf-8", cwd=cwd)
|
||||||
else:
|
else:
|
||||||
# Fall back to spawning the command directly
|
# Fall back to spawning the command directly
|
||||||
if verbose:
|
if verbose:
|
||||||
print("Running pexpect.spawn without shell.")
|
print("Running pexpect.spawn without shell.")
|
||||||
child = pexpect.spawn(command, encoding="utf-8")
|
child = pexpect.spawn(command, encoding="utf-8", cwd=cwd)
|
||||||
|
|
||||||
# Transfer control to the user, capturing output
|
# Transfer control to the user, capturing output
|
||||||
child.interact(output_filter=output_callback)
|
child.interact(output_filter=output_callback)
|
||||||
|
|||||||
@@ -56,18 +56,19 @@ def send_completion(
|
|||||||
return hash_object, res
|
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()
|
litellm_ex = LiteLLMExceptions()
|
||||||
|
|
||||||
retry_delay = 0.125
|
retry_delay = 0.125
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
kwargs = {
|
kwargs = {
|
||||||
"model_name": model_name,
|
"model_name": model.name,
|
||||||
"messages": messages,
|
"messages": messages,
|
||||||
"functions": None,
|
"functions": None,
|
||||||
"stream": False,
|
"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)
|
_hash, response = send_completion(**kwargs)
|
||||||
|
|||||||
@@ -2,18 +2,15 @@ import itertools
|
|||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import shlex
|
import shlex
|
||||||
import shutil
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import git
|
|
||||||
|
|
||||||
from aider.dump import dump # noqa: F401
|
from aider.dump import dump # noqa: F401
|
||||||
|
|
||||||
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp"}
|
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp", ".pdf"}
|
||||||
|
|
||||||
|
|
||||||
class IgnorantTemporaryDirectory:
|
class IgnorantTemporaryDirectory:
|
||||||
@@ -74,6 +71,8 @@ class GitTemporaryDirectory(ChdirTemporaryDirectory):
|
|||||||
|
|
||||||
|
|
||||||
def make_repo(path=None):
|
def make_repo(path=None):
|
||||||
|
import git
|
||||||
|
|
||||||
if not path:
|
if not path:
|
||||||
path = "."
|
path = "."
|
||||||
repo = git.Repo.init(path)
|
repo = git.Repo.init(path)
|
||||||
@@ -194,25 +193,9 @@ def split_chat_history_markdown(text, include_tool=False):
|
|||||||
return messages
|
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):
|
def get_pip_install(args):
|
||||||
cmd = [
|
cmd = [
|
||||||
get_best_invocation_for_this_python(),
|
sys.executable,
|
||||||
"-m",
|
"-m",
|
||||||
"pip",
|
"pip",
|
||||||
"install",
|
"install",
|
||||||
@@ -268,7 +251,8 @@ def run_install(cmd):
|
|||||||
|
|
||||||
|
|
||||||
class Spinner:
|
class Spinner:
|
||||||
spinner_chars = itertools.cycle(["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
|
unicode_spinner = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
||||||
|
ascii_spinner = ["|", "/", "-", "\\"]
|
||||||
|
|
||||||
def __init__(self, text):
|
def __init__(self, text):
|
||||||
self.text = text
|
self.text = text
|
||||||
@@ -276,6 +260,20 @@ class Spinner:
|
|||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.visible = False
|
self.visible = False
|
||||||
self.is_tty = sys.stdout.isatty()
|
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):
|
def step(self):
|
||||||
if not self.is_tty:
|
if not self.is_tty:
|
||||||
@@ -293,6 +291,7 @@ class Spinner:
|
|||||||
if not self.visible:
|
if not self.visible:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.test_charset()
|
||||||
print(f"\r{self.text} {next(self.spinner_chars)}\r{self.text} ", end="", flush=True)
|
print(f"\r{self.text} {next(self.spinner_chars)}\r{self.text} ", end="", flush=True)
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
@@ -382,3 +381,15 @@ def printable_shell_command(cmd_list):
|
|||||||
return subprocess.list2cmdline(cmd_list)
|
return subprocess.list2cmdline(cmd_list)
|
||||||
else:
|
else:
|
||||||
return shlex.join(cmd_list)
|
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,6 +14,8 @@ from .dump import dump # noqa: F401
|
|||||||
warnings.filterwarnings(
|
warnings.filterwarnings(
|
||||||
"ignore", message="Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work"
|
"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 import AudioSegment # noqa
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ class Voice:
|
|||||||
|
|
||||||
threshold = 0.15
|
threshold = 0.15
|
||||||
|
|
||||||
def __init__(self, audio_format="wav"):
|
def __init__(self, audio_format="wav", device_name=None):
|
||||||
if sf is None:
|
if sf is None:
|
||||||
raise SoundDeviceError
|
raise SoundDeviceError
|
||||||
try:
|
try:
|
||||||
@@ -42,6 +44,29 @@ class Voice:
|
|||||||
import sounddevice as sd
|
import sounddevice as sd
|
||||||
|
|
||||||
self.sd = sd
|
self.sd = sd
|
||||||
|
|
||||||
|
devices = sd.query_devices()
|
||||||
|
|
||||||
|
if device_name:
|
||||||
|
# Find the device with matching name
|
||||||
|
device_id = None
|
||||||
|
for i, device in enumerate(devices):
|
||||||
|
if device_name in device["name"]:
|
||||||
|
device_id = i
|
||||||
|
break
|
||||||
|
if device_id is None:
|
||||||
|
available_inputs = [d["name"] for d in devices if d["max_input_channels"] > 0]
|
||||||
|
raise ValueError(
|
||||||
|
f"Device '{device_name}' not found. Available input devices:"
|
||||||
|
f" {available_inputs}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Using input device: {device_name} (ID: {device_id})")
|
||||||
|
|
||||||
|
self.device_id = device_id
|
||||||
|
else:
|
||||||
|
self.device_id = None
|
||||||
|
|
||||||
except (OSError, ModuleNotFoundError):
|
except (OSError, ModuleNotFoundError):
|
||||||
raise SoundDeviceError
|
raise SoundDeviceError
|
||||||
if audio_format not in ["wav", "mp3", "webm"]:
|
if audio_format not in ["wav", "mp3", "webm"]:
|
||||||
@@ -93,7 +118,7 @@ class Voice:
|
|||||||
temp_wav = tempfile.mktemp(suffix=".wav")
|
temp_wav = tempfile.mktemp(suffix=".wav")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sample_rate = int(self.sd.query_devices(None, "input")["default_samplerate"])
|
sample_rate = int(self.sd.query_devices(self.device_id, "input")["default_samplerate"])
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
sample_rate = 16000 # fallback to 16kHz if unable to query device
|
sample_rate = 16000 # fallback to 16kHz if unable to query device
|
||||||
except self.sd.PortAudioError:
|
except self.sd.PortAudioError:
|
||||||
@@ -104,7 +129,9 @@ class Voice:
|
|||||||
self.start_time = time.time()
|
self.start_time = time.time()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with self.sd.InputStream(samplerate=sample_rate, channels=1, callback=self.callback):
|
with self.sd.InputStream(
|
||||||
|
samplerate=sample_rate, channels=1, callback=self.callback, device=self.device_id
|
||||||
|
):
|
||||||
prompt(self.get_prompt, refresh_interval=0.1)
|
prompt(self.get_prompt, refresh_interval=0.1)
|
||||||
except self.sd.PortAudioError as err:
|
except self.sd.PortAudioError as err:
|
||||||
raise SoundDeviceError(f"Error accessing audio input device: {err}")
|
raise SoundDeviceError(f"Error accessing audio input device: {err}")
|
||||||
|
|||||||
278
aider/watch.py
Normal file
278
aider/watch.py
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
import re
|
||||||
|
import threading
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from grep_ast import TreeContext
|
||||||
|
from pathspec import PathSpec
|
||||||
|
from pathspec.patterns import GitWildMatchPattern
|
||||||
|
from watchfiles import watch
|
||||||
|
|
||||||
|
from aider.dump import dump # noqa
|
||||||
|
from aider.watch_prompts import watch_ask_prompt, watch_code_prompt
|
||||||
|
|
||||||
|
|
||||||
|
def load_gitignores(gitignore_paths: list[Path]) -> Optional[PathSpec]:
|
||||||
|
"""Load and parse multiple .gitignore files into a single PathSpec"""
|
||||||
|
if not gitignore_paths:
|
||||||
|
return None
|
||||||
|
|
||||||
|
patterns = [
|
||||||
|
".aider*",
|
||||||
|
".git",
|
||||||
|
# Common editor backup/temp files
|
||||||
|
"*~", # Emacs/vim backup
|
||||||
|
"*.bak", # Generic backup
|
||||||
|
"*.swp", # Vim swap
|
||||||
|
"*.swo", # Vim swap
|
||||||
|
"\\#*\\#", # Emacs auto-save
|
||||||
|
".#*", # Emacs lock files
|
||||||
|
"*.tmp", # Generic temp files
|
||||||
|
"*.temp", # Generic temp files
|
||||||
|
"*.orig", # Merge conflict originals
|
||||||
|
"*.pyc", # Python bytecode
|
||||||
|
"__pycache__/", # Python cache dir
|
||||||
|
".DS_Store", # macOS metadata
|
||||||
|
"Thumbs.db", # Windows thumbnail cache
|
||||||
|
# IDE files
|
||||||
|
".idea/", # JetBrains IDEs
|
||||||
|
".vscode/", # VS Code
|
||||||
|
"*.sublime-*", # Sublime Text
|
||||||
|
".project", # Eclipse
|
||||||
|
".settings/", # Eclipse
|
||||||
|
"*.code-workspace", # VS Code workspace
|
||||||
|
# Environment files
|
||||||
|
".env", # Environment variables
|
||||||
|
".venv/", # Python virtual environments
|
||||||
|
"node_modules/", # Node.js dependencies
|
||||||
|
"vendor/", # Various dependencies
|
||||||
|
# Logs and caches
|
||||||
|
"*.log", # Log files
|
||||||
|
".cache/", # Cache directories
|
||||||
|
".pytest_cache/", # Python test cache
|
||||||
|
"coverage/", # Code coverage reports
|
||||||
|
] # Always ignore
|
||||||
|
for path in gitignore_paths:
|
||||||
|
if path.exists():
|
||||||
|
with open(path) as f:
|
||||||
|
patterns.extend(f.readlines())
|
||||||
|
|
||||||
|
return PathSpec.from_lines(GitWildMatchPattern, patterns) if patterns else None
|
||||||
|
|
||||||
|
|
||||||
|
class FileWatcher:
|
||||||
|
"""Watches source files for changes and AI comments"""
|
||||||
|
|
||||||
|
# Compiled regex pattern for AI comments
|
||||||
|
ai_comment_pattern = re.compile(r"(?:#|//|--) *(ai\b.*|ai\b.*|.*\bai[?!]?) *$", re.IGNORECASE)
|
||||||
|
|
||||||
|
def __init__(self, coder, gitignores=None, verbose=False, analytics=None):
|
||||||
|
self.coder = coder
|
||||||
|
self.io = coder.io
|
||||||
|
self.root = Path(coder.root)
|
||||||
|
self.verbose = verbose
|
||||||
|
self.analytics = analytics
|
||||||
|
self.stop_event = None
|
||||||
|
self.watcher_thread = None
|
||||||
|
self.changed_files = set()
|
||||||
|
self.gitignores = gitignores
|
||||||
|
|
||||||
|
self.gitignore_spec = load_gitignores(
|
||||||
|
[Path(g) for g in self.gitignores] if self.gitignores else []
|
||||||
|
)
|
||||||
|
|
||||||
|
coder.io.file_watcher = self
|
||||||
|
|
||||||
|
def filter_func(self, change_type, path):
|
||||||
|
"""Filter function for the file watcher"""
|
||||||
|
path_obj = Path(path)
|
||||||
|
path_abs = path_obj.absolute()
|
||||||
|
|
||||||
|
if not path_abs.is_relative_to(self.root.absolute()):
|
||||||
|
return False
|
||||||
|
|
||||||
|
rel_path = path_abs.relative_to(self.root)
|
||||||
|
if self.verbose:
|
||||||
|
dump(rel_path)
|
||||||
|
|
||||||
|
if self.gitignore_spec and self.gitignore_spec.match_file(str(rel_path)):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
dump("ok", rel_path)
|
||||||
|
|
||||||
|
# Check if file contains AI markers
|
||||||
|
try:
|
||||||
|
comments, _, _ = self.get_ai_comments(str(path_abs))
|
||||||
|
return bool(comments)
|
||||||
|
except Exception:
|
||||||
|
return
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""Start watching for file changes"""
|
||||||
|
self.stop_event = threading.Event()
|
||||||
|
self.changed_files = set()
|
||||||
|
|
||||||
|
def watch_files():
|
||||||
|
try:
|
||||||
|
for changes in watch(
|
||||||
|
str(self.root), watch_filter=self.filter_func, stop_event=self.stop_event
|
||||||
|
):
|
||||||
|
if not changes:
|
||||||
|
continue
|
||||||
|
changed_files = {str(Path(change[1])) for change in changes}
|
||||||
|
self.changed_files.update(changed_files)
|
||||||
|
self.io.interrupt_input()
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
if self.verbose:
|
||||||
|
dump(f"File watcher error: {e}")
|
||||||
|
raise e
|
||||||
|
|
||||||
|
self.watcher_thread = threading.Thread(target=watch_files, daemon=True)
|
||||||
|
self.watcher_thread.start()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Stop watching for file changes"""
|
||||||
|
if self.stop_event:
|
||||||
|
self.stop_event.set()
|
||||||
|
if self.watcher_thread:
|
||||||
|
self.watcher_thread.join()
|
||||||
|
self.watcher_thread = None
|
||||||
|
self.stop_event = None
|
||||||
|
|
||||||
|
def process_changes(self):
|
||||||
|
"""Get any detected file changes"""
|
||||||
|
|
||||||
|
has_action = None
|
||||||
|
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)
|
||||||
|
for i, line in enumerate(content.splitlines(), 1):
|
||||||
|
if match := self.ai_comment_pattern.search(line):
|
||||||
|
comment = match.group(0).strip()
|
||||||
|
if comment:
|
||||||
|
line_nums.append(i)
|
||||||
|
comments.append(comment)
|
||||||
|
comment = comment.lower()
|
||||||
|
comment = comment.lstrip("/#-")
|
||||||
|
comment = comment.strip()
|
||||||
|
if comment.startswith("ai!") or comment.endswith("ai!"):
|
||||||
|
has_action = "!"
|
||||||
|
elif comment.startswith("ai?") or comment.endswith("ai?"):
|
||||||
|
has_action = "?"
|
||||||
|
if not line_nums:
|
||||||
|
return None, None, None
|
||||||
|
return line_nums, comments, has_action
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Example usage of the file watcher"""
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Watch source files for changes")
|
||||||
|
parser.add_argument("directory", help="Directory to watch")
|
||||||
|
parser.add_argument(
|
||||||
|
"--gitignore",
|
||||||
|
action="append",
|
||||||
|
help="Path to .gitignore file (can be specified multiple times)",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
directory = args.directory
|
||||||
|
print(f"Watching source files in {directory}...")
|
||||||
|
|
||||||
|
# Example ignore function that ignores files with "test" in the name
|
||||||
|
def ignore_test_files(path):
|
||||||
|
return "test" in path.name.lower()
|
||||||
|
|
||||||
|
watcher = FileWatcher(directory, gitignores=args.gitignore)
|
||||||
|
try:
|
||||||
|
watcher.start()
|
||||||
|
while True:
|
||||||
|
if changes := watcher.get_changes():
|
||||||
|
for file in sorted(changes.keys()):
|
||||||
|
print(file)
|
||||||
|
watcher.changed_files = None
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nStopped watching files")
|
||||||
|
watcher.stop()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
11
aider/watch_prompts.py
Normal file
11
aider/watch_prompts.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
watch_code_prompt = """
|
||||||
|
Find the "AI" comments below (marked with █) in the code files I've shared with you.
|
||||||
|
They contain your instructions.
|
||||||
|
Make the requested changes.
|
||||||
|
Be sure to remove all these "AI" comments from the code!
|
||||||
|
"""
|
||||||
|
|
||||||
|
watch_ask_prompt = """/ask
|
||||||
|
Find the "AI" comments below (marked with █) in the code files I've shared with you.
|
||||||
|
They contain your questions you need to answer and other instructions.
|
||||||
|
"""
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Release history
|
title: Release history
|
||||||
parent: More info
|
nav_order: 925
|
||||||
nav_order: 900
|
|
||||||
highlight_image: /assets/blame.jpg
|
highlight_image: /assets/blame.jpg
|
||||||
description: Release notes and stats on aider writing its own code.
|
description: Release notes and stats on aider writing its own code.
|
||||||
---
|
---
|
||||||
@@ -24,6 +23,79 @@ cog.out(text)
|
|||||||
]]]-->
|
]]]-->
|
||||||
|
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
- Added `--timeout` option to configure API call timeouts.
|
||||||
|
- Set cwd to repo root when running shell commands.
|
||||||
|
- Added Ctrl-Up/Down keyboard shortcuts for per-message history navigation.
|
||||||
|
- Improved error handling for failed .gitignore file operations.
|
||||||
|
- Improved error handling for input history file permissions.
|
||||||
|
- Improved error handling for analytics file access.
|
||||||
|
- Removed spurious warning about disabling pretty in VSCode.
|
||||||
|
- Removed broken support for Dart.
|
||||||
|
- Bugfix when scraping URLs found in chat messages.
|
||||||
|
- Better handling of __version__ import errors.
|
||||||
|
- Improved `/drop` command to support substring matching for non-glob patterns.
|
||||||
|
- Aider wrote 82% of the code in this release.
|
||||||
|
|
||||||
|
### Aider v0.65.1
|
||||||
|
|
||||||
|
- Bugfix to `--alias`.
|
||||||
|
|
||||||
### Aider v0.65.0
|
### Aider v0.65.0
|
||||||
|
|
||||||
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
||||||
|
|||||||
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
|
- dirname: 2024-07-19-08-57-13--openrouter-deepseek-chat-v2-0628
|
||||||
test_cases: 133
|
test_cases: 133
|
||||||
model: DeepSeek Chat V2 0628 (deprecated)
|
model: DeepSeek Chat V2 0628
|
||||||
edit_format: diff
|
edit_format: diff
|
||||||
commit_hash: 96ff06e-dirty
|
commit_hash: 96ff06e-dirty
|
||||||
pass_rate_1: 60.9
|
pass_rate_1: 60.9
|
||||||
@@ -716,7 +716,7 @@
|
|||||||
|
|
||||||
- dirname: 2024-07-24-07-10-58--deepseek-coder2-0724-diff-direct
|
- dirname: 2024-07-24-07-10-58--deepseek-coder2-0724-diff-direct
|
||||||
test_cases: 133
|
test_cases: 133
|
||||||
model: DeepSeek Coder V2 0724 (deprecated)
|
model: DeepSeek Coder V2 0724
|
||||||
edit_format: diff
|
edit_format: diff
|
||||||
commit_hash: 89965bf
|
commit_hash: 89965bf
|
||||||
pass_rate_1: 57.9
|
pass_rate_1: 57.9
|
||||||
@@ -1232,7 +1232,7 @@
|
|||||||
|
|
||||||
- dirname: 2024-09-24-16-33-23--gemini-1.5-flash-002-whole
|
- dirname: 2024-09-24-16-33-23--gemini-1.5-flash-002-whole
|
||||||
test_cases: 133
|
test_cases: 133
|
||||||
model: gemini-1.5-flash-002
|
model: gemini-1.5-flash-002 (0924)
|
||||||
edit_format: whole
|
edit_format: whole
|
||||||
commit_hash: 3edcd71
|
commit_hash: 3edcd71
|
||||||
pass_rate_1: 37.6
|
pass_rate_1: 37.6
|
||||||
@@ -1945,4 +1945,239 @@
|
|||||||
command: aider --model gemini/gemini-exp-1114
|
command: aider --model gemini/gemini-exp-1114
|
||||||
date: 2024-11-15
|
date: 2024-11-15
|
||||||
versions: 0.63.2.dev
|
versions: 0.63.2.dev
|
||||||
seconds_per_case: 38.6
|
seconds_per_case: 38.6
|
||||||
|
- dirname: 2024-11-27-07-41-51--qwen2.5-coder-14b-whole-1
|
||||||
|
test_cases: 133
|
||||||
|
model: ollama/qwen2.5-coder:14b
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: 200295e
|
||||||
|
pass_rate_1: 53.4
|
||||||
|
pass_rate_2: 61.7
|
||||||
|
percent_cases_well_formed: 98.5
|
||||||
|
error_outputs: 4
|
||||||
|
num_malformed_responses: 4
|
||||||
|
num_with_malformed_responses: 2
|
||||||
|
user_asks: 48
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 2
|
||||||
|
indentation_errors: 2
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 2
|
||||||
|
command: aider --model ollama/qwen2.5-coder:14b
|
||||||
|
date: 2024-11-27
|
||||||
|
versions: 0.65.2.dev
|
||||||
|
seconds_per_case: 58.0
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-11-28-07-42-56--qwen2.5-coder-32b-whole-4
|
||||||
|
test_cases: 133
|
||||||
|
model: ollama/qwen2.5-coder:32b
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: 200295e
|
||||||
|
pass_rate_1: 58.6
|
||||||
|
pass_rate_2: 72.9
|
||||||
|
percent_cases_well_formed: 100.0
|
||||||
|
num_malformed_responses: 0
|
||||||
|
num_with_malformed_responses: 0
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 0
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
command: aider --model ollama/qwen2.5-coder:32b
|
||||||
|
date: 2024-11-28
|
||||||
|
versions: 0.65.2.dev
|
||||||
|
seconds_per_case: 147.5
|
||||||
|
total_cost: 0.0000
|
||||||
|
- dirname: 2024-11-28-13-14-00--tulu3-whole-2
|
||||||
|
test_cases: 133
|
||||||
|
model: ollama/tulu3
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: 200295e
|
||||||
|
pass_rate_1: 21.8
|
||||||
|
pass_rate_2: 26.3
|
||||||
|
percent_cases_well_formed: 100.0
|
||||||
|
error_outputs: 0
|
||||||
|
num_malformed_responses: 0
|
||||||
|
num_with_malformed_responses: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
command: aider --model ollama/tulu3
|
||||||
|
date: 2024-11-28
|
||||||
|
versions: 0.65.2.dev
|
||||||
|
seconds_per_case: 35.8
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-11-28-14-41-46--granite3-dense-8b-whole-1
|
||||||
|
test_cases: 133
|
||||||
|
model: ollama/granite3-dense:8b
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: 200295e
|
||||||
|
pass_rate_1: 17.3
|
||||||
|
pass_rate_2: 20.3
|
||||||
|
percent_cases_well_formed: 78.9
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
command: aider --model ollama/granite3-dense:8b
|
||||||
|
date: 2024-11-28
|
||||||
|
versions: 0.65.2.dev
|
||||||
|
seconds_per_case: 38.1
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-12-04-13-53-03--nova-whole
|
||||||
|
test_cases: 133
|
||||||
|
model: Nova Pro
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: 699e283
|
||||||
|
pass_rate_1: 44.4
|
||||||
|
pass_rate_2: 54.1
|
||||||
|
percent_cases_well_formed: 100.0
|
||||||
|
error_outputs: 0
|
||||||
|
num_malformed_responses: 0
|
||||||
|
num_with_malformed_responses: 0
|
||||||
|
user_asks: 7
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 0
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 4
|
||||||
|
command: aider --model bedrock/us.amazon.nova-pro-v1:0
|
||||||
|
date: 2024-12-04
|
||||||
|
versions: 0.66.1.dev
|
||||||
|
seconds_per_case: 8.7
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-12-06-18-27-47--llama33-diff
|
||||||
|
test_cases: 133
|
||||||
|
model: llama-3.3-70b-instruct
|
||||||
|
edit_format: diff
|
||||||
|
commit_hash: 53e0d67
|
||||||
|
pass_rate_1: 42.1
|
||||||
|
pass_rate_2: 59.4
|
||||||
|
percent_cases_well_formed: 88.7
|
||||||
|
error_outputs: 33
|
||||||
|
num_malformed_responses: 33
|
||||||
|
num_with_malformed_responses: 15
|
||||||
|
user_asks: 3
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 0
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 3
|
||||||
|
command: aider --model openrouter/meta-llama/llama-3.3-70b-instruct
|
||||||
|
date: 2024-12-06
|
||||||
|
versions: 0.67.1.dev
|
||||||
|
seconds_per_case: 20.2
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-12-06-21-35-50--gemini-exp-1206-diff
|
||||||
|
test_cases: 133
|
||||||
|
model: gemini-exp-1206 (diff)
|
||||||
|
edit_format: diff
|
||||||
|
commit_hash: f2d2ab5
|
||||||
|
pass_rate_1: 55.6
|
||||||
|
pass_rate_2: 69.2
|
||||||
|
percent_cases_well_formed: 84.2
|
||||||
|
error_outputs: 68
|
||||||
|
num_malformed_responses: 68
|
||||||
|
num_with_malformed_responses: 21
|
||||||
|
user_asks: 5
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 2
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 0
|
||||||
|
command: aider --model gemini/gemini-exp-1206
|
||||||
|
date: 2024-12-06
|
||||||
|
versions: 0.67.1.dev
|
||||||
|
seconds_per_case: 32.1
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-12-08-21-39-06--gemini-exp-1206-whole
|
||||||
|
test_cases: 133
|
||||||
|
model: gemini-exp-1206 (whole)
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: f2d2ab5
|
||||||
|
pass_rate_1: 60.9
|
||||||
|
pass_rate_2: 80.5
|
||||||
|
percent_cases_well_formed: 100.0
|
||||||
|
error_outputs: 0
|
||||||
|
num_malformed_responses: 0
|
||||||
|
num_with_malformed_responses: 0
|
||||||
|
user_asks: 1
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 0
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 3
|
||||||
|
command: aider --model gemini/gemini-exp-1206
|
||||||
|
date: 2024-12-08
|
||||||
|
versions: 0.67.1.dev
|
||||||
|
seconds_per_case: 64.2
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-12-10-14-45-21--deepseek-1210-diff
|
||||||
|
test_cases: 133
|
||||||
|
model: DeepSeek-V2.5-1210
|
||||||
|
edit_format: diff
|
||||||
|
commit_hash: 16332b2
|
||||||
|
pass_rate_1: 58.6
|
||||||
|
pass_rate_2: 72.2
|
||||||
|
percent_cases_well_formed: 99.2
|
||||||
|
error_outputs: 1
|
||||||
|
num_malformed_responses: 1
|
||||||
|
num_with_malformed_responses: 1
|
||||||
|
user_asks: 2
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 0
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 2
|
||||||
|
command: aider --model deepseek/deepseek-chat
|
||||||
|
date: 2024-12-10
|
||||||
|
versions: 0.67.1.dev
|
||||||
|
seconds_per_case: 32.7
|
||||||
|
total_cost: 0.1106
|
||||||
|
|
||||||
|
- dirname: 2024-12-11-00-37-08--yi-test
|
||||||
|
test_cases: 133
|
||||||
|
model: yi-lightning
|
||||||
|
edit_format: whole
|
||||||
|
commit_hash: e909a3d-dirty
|
||||||
|
pass_rate_1: 49.6
|
||||||
|
pass_rate_2: 65.4
|
||||||
|
percent_cases_well_formed: 97.0
|
||||||
|
error_outputs: 304
|
||||||
|
num_malformed_responses: 5
|
||||||
|
num_with_malformed_responses: 4
|
||||||
|
user_asks: 34
|
||||||
|
lazy_comments: 2
|
||||||
|
syntax_errors: 0
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 2
|
||||||
|
command: aider --model openai/yi-lightning
|
||||||
|
date: 2024-12-11
|
||||||
|
versions: 0.67.1.dev
|
||||||
|
seconds_per_case: 57.8
|
||||||
|
total_cost: 0.0000
|
||||||
|
|
||||||
|
- dirname: 2024-12-11-21-07-00--gemini-2-flash-diff
|
||||||
|
test_cases: 133
|
||||||
|
model: gemini-2.0-flash-exp
|
||||||
|
edit_format: diff
|
||||||
|
commit_hash: fcb2bac-dirty, 02e7e31-dirty
|
||||||
|
pass_rate_1: 56.4
|
||||||
|
pass_rate_2: 69.9
|
||||||
|
percent_cases_well_formed: 97.0
|
||||||
|
error_outputs: 10
|
||||||
|
num_malformed_responses: 6
|
||||||
|
num_with_malformed_responses: 4
|
||||||
|
user_asks: 8
|
||||||
|
lazy_comments: 0
|
||||||
|
syntax_errors: 1
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 2
|
||||||
|
test_timeouts: 1
|
||||||
|
command: aider --model gemini/gemini-2.0-flash-exp
|
||||||
|
date: 2024-12-11
|
||||||
|
versions: 0.68.1.dev
|
||||||
|
seconds_per_case: 7.3
|
||||||
|
total_cost: 0.0000
|
||||||
@@ -296,4 +296,27 @@
|
|||||||
date: 2024-11-24
|
date: 2024-11-24
|
||||||
versions: 0.64.2.dev
|
versions: 0.64.2.dev
|
||||||
seconds_per_case: 28.5
|
seconds_per_case: 28.5
|
||||||
total_cost: 0.1390
|
total_cost: 0.1390
|
||||||
|
|
||||||
|
- dirname: 2024-11-26-03-15-06--ollama-qwen2.5-coder:32b-instruct-fp16-2kctx
|
||||||
|
test_cases: 132
|
||||||
|
model: "Ollama: fp16, 2k ctx"
|
||||||
|
edit_format: diff
|
||||||
|
commit_hash: 68be6c5-dirty, 554d274, 2ff3a23, 2ff3a23-dirty, 61759f9, dd48b74, 3ebd47d-dirty
|
||||||
|
pass_rate_1: 43.2
|
||||||
|
pass_rate_2: 51.9
|
||||||
|
percent_cases_well_formed: 46.2
|
||||||
|
error_outputs: 171
|
||||||
|
num_malformed_responses: 165
|
||||||
|
num_with_malformed_responses: 71
|
||||||
|
user_asks: 97
|
||||||
|
lazy_comments: 2
|
||||||
|
syntax_errors: 4
|
||||||
|
indentation_errors: 0
|
||||||
|
exhausted_context_windows: 0
|
||||||
|
test_timeouts: 0
|
||||||
|
command: "aider --model ollama/qwen2.5-coder:32b-instruct-fp16 # num_ctx: 2048"
|
||||||
|
date: 2024-11-26
|
||||||
|
versions: 0.64.2.dev,0.65.1.dev
|
||||||
|
seconds_per_case: 188.6
|
||||||
|
total_cost: 0.0000
|
||||||
170
aider/website/_data/qwq.yml
Normal file
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,13 +1,21 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
var ctx = document.getElementById('editChart').getContext('2d');
|
var ctx = document.getElementById('editChart').getContext('2d');
|
||||||
const HIGHTLIGHT_MODEL = 'no no no no';
|
const blueDiagonalPattern = pattern.draw('diagonal', 'rgba(54, 162, 235, 0.2)');
|
||||||
|
const redDiagonalPattern = pattern.draw('diagonal', 'rgba(255, 99, 132, 0.2)');
|
||||||
|
let displayedData = [];
|
||||||
|
|
||||||
|
const HIGHTLIGHT_MODEL = 'no no no';
|
||||||
var leaderboardData = {
|
var leaderboardData = {
|
||||||
labels: [],
|
labels: [],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Percent completed correctly',
|
label: 'Percent completed correctly',
|
||||||
data: [],
|
data: [],
|
||||||
backgroundColor: function(context) {
|
backgroundColor: function(context) {
|
||||||
const label = context.chart.data.labels[context.dataIndex] || '';
|
const row = allData[context.dataIndex];
|
||||||
|
if (row && row.edit_format === 'whole') {
|
||||||
|
return diagonalPattern;
|
||||||
|
}
|
||||||
|
const label = leaderboardData.labels[context.dataIndex] || '';
|
||||||
return (label && label.includes(HIGHTLIGHT_MODEL)) ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)';
|
return (label && label.includes(HIGHTLIGHT_MODEL)) ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)';
|
||||||
},
|
},
|
||||||
borderColor: function(context) {
|
borderColor: function(context) {
|
||||||
@@ -23,7 +31,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
allData.push({
|
allData.push({
|
||||||
model: '{{ row.model }}',
|
model: '{{ row.model }}',
|
||||||
pass_rate_2: {{ row.pass_rate_2 }},
|
pass_rate_2: {{ row.pass_rate_2 }},
|
||||||
percent_cases_well_formed: {{ row.percent_cases_well_formed }}
|
percent_cases_well_formed: {{ row.percent_cases_well_formed }},
|
||||||
|
edit_format: '{{ row.edit_format }}'
|
||||||
});
|
});
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
@@ -31,6 +40,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
var selectedRows = document.querySelectorAll('tr.selected');
|
var selectedRows = document.querySelectorAll('tr.selected');
|
||||||
var showAll = selectedRows.length === 0;
|
var showAll = selectedRows.length === 0;
|
||||||
|
|
||||||
|
displayedData = [];
|
||||||
leaderboardData.labels = [];
|
leaderboardData.labels = [];
|
||||||
leaderboardData.datasets[0].data = [];
|
leaderboardData.datasets[0].data = [];
|
||||||
|
|
||||||
@@ -40,14 +50,30 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
rowElement.classList.remove('selected');
|
rowElement.classList.remove('selected');
|
||||||
}
|
}
|
||||||
if (showAll || rowElement.classList.contains('selected')) {
|
if (showAll || rowElement.classList.contains('selected')) {
|
||||||
|
displayedData.push(row);
|
||||||
leaderboardData.labels.push(row.model);
|
leaderboardData.labels.push(row.model);
|
||||||
leaderboardData.datasets[0].data.push(row.pass_rate_2);
|
leaderboardData.datasets[0].data.push(row.pass_rate_2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
leaderboardChart.update();
|
leaderboardChart.update();
|
||||||
|
leaderboardChart.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use displayedData in the backgroundColor callback instead of allData
|
||||||
|
leaderboardData.datasets[0].backgroundColor = function(context) {
|
||||||
|
const row = displayedData[context.dataIndex];
|
||||||
|
const label = leaderboardData.labels[context.dataIndex] || '';
|
||||||
|
if (label && label.includes(HIGHTLIGHT_MODEL)) {
|
||||||
|
if (row && row.edit_format === 'whole') return redDiagonalPattern;
|
||||||
|
else return 'rgba(255, 99, 132, 0.2)';
|
||||||
|
} else if (row && row.edit_format === 'whole') {
|
||||||
|
return blueDiagonalPattern;
|
||||||
|
} else {
|
||||||
|
return 'rgba(54, 162, 235, 0.2)';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var tableBody = document.querySelector('table tbody');
|
var tableBody = document.querySelector('table tbody');
|
||||||
allData.forEach(function(row, index) {
|
allData.forEach(function(row, index) {
|
||||||
var tr = tableBody.children[index];
|
var tr = tableBody.children[index];
|
||||||
@@ -63,9 +89,69 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: leaderboardData,
|
data: leaderboardData,
|
||||||
options: {
|
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: {
|
scales: {
|
||||||
y: {
|
y: {
|
||||||
beginAtZero: true
|
beginAtZero: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Percent completed correctly'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
ticks: {
|
||||||
|
callback: function(value, index) {
|
||||||
|
const label = this.getLabelForValue(value);
|
||||||
|
if (label.length <= "claude-3-5-sonnet".length) {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all possible split positions
|
||||||
|
const splitPositions = [];
|
||||||
|
for (let i = 0; i < label.length; i++) {
|
||||||
|
if (label[i] === '-' || label[i] === ' ') {
|
||||||
|
splitPositions.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splitPositions.length === 0) {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find split position closest to middle
|
||||||
|
const middle = label.length / 2;
|
||||||
|
const splitIndex = splitPositions.reduce((closest, current) => {
|
||||||
|
return Math.abs(current - middle) < Math.abs(closest - middle) ? current : closest;
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
label.slice(0, splitIndex),
|
||||||
|
label.slice(splitIndex + 1)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,6 +165,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
var tableBody = document.querySelector('table:first-of-type tbody');
|
var tableBody = document.querySelector('table:first-of-type tbody');
|
||||||
var rows = tableBody.getElementsByTagName('tr');
|
var rows = tableBody.getElementsByTagName('tr');
|
||||||
|
|
||||||
|
displayedData = [];
|
||||||
leaderboardData.labels = [];
|
leaderboardData.labels = [];
|
||||||
leaderboardData.datasets[0].data = [];
|
leaderboardData.datasets[0].data = [];
|
||||||
|
|
||||||
@@ -86,6 +173,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
var rowText = rows[i].textContent;
|
var rowText = rows[i].textContent;
|
||||||
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
|
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
|
||||||
rows[i].style.display = '';
|
rows[i].style.display = '';
|
||||||
|
displayedData.push(allData[i]);
|
||||||
leaderboardData.labels.push(allData[i].model);
|
leaderboardData.labels.push(allData[i].model);
|
||||||
leaderboardData.datasets[0].data.push(allData[i].pass_rate_2);
|
leaderboardData.datasets[0].data.push(allData[i].pass_rate_2);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -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:
|
You can get started quickly like this, with python 3.8-3.13:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
python -m pip install -U aider-chat
|
python -m pip install aider-install
|
||||||
|
aider-install
|
||||||
|
|
||||||
# Change directory into a git repo
|
# Change directory into your code base
|
||||||
cd /to/your/git/repo
|
cd /to/your/git/repo
|
||||||
|
|
||||||
# Work with Claude 3.5 Sonnet on your repo
|
# Work with Claude 3.5 Sonnet on your repo
|
||||||
export ANTHROPIC_API_KEY=your-key-goes-here
|
aider --model sonnet --anthropic-api-key your-key-goes-here
|
||||||
aider
|
|
||||||
|
|
||||||
# Work with GPT-4o on your repo
|
# Work with GPT-4o on your repo
|
||||||
export OPENAI_API_KEY=your-key-goes-here
|
aider --model gpt-4o --openai-api-key your-key-goes-here
|
||||||
aider
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -18,3 +18,63 @@
|
|||||||
<link rel="mask-icon" href="{{ '/assets/icons/safari-pinned-tab.svg' | relative_url }}" color="#5bbad5">
|
<link rel="mask-icon" href="{{ '/assets/icons/safari-pinned-tab.svg' | relative_url }}" color="#5bbad5">
|
||||||
<meta name="msapplication-TileColor" content="#da532c">
|
<meta name="msapplication-TileColor" content="#da532c">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
|
||||||
|
<!-- Cookie Consent -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css" />
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js" data-cfasync="false"></script>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('load', function(){
|
||||||
|
window.cookieconsent.initialise({
|
||||||
|
palette: {
|
||||||
|
popup: {
|
||||||
|
background: "#333333",
|
||||||
|
text: "#ffffff"
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
background: "#ffffff",
|
||||||
|
text: "#333333"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type: "opt-in",
|
||||||
|
position: "bottom-left",
|
||||||
|
showLink: false,
|
||||||
|
dismissOnScroll: true,
|
||||||
|
cookie: {
|
||||||
|
name: 'cookieconsent_status',
|
||||||
|
path: '/',
|
||||||
|
domain: 'aider.chat',
|
||||||
|
expiryDays: 365
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
message: "This website uses analytics cookies to help us understand how you use the site.",
|
||||||
|
dismiss: "Decline",
|
||||||
|
allow: "Accept",
|
||||||
|
link: "Learn more",
|
||||||
|
href: "https://aider.chat/docs/legal/privacy.html"
|
||||||
|
},
|
||||||
|
onInitialise: function(status) {
|
||||||
|
var type = this.options.type;
|
||||||
|
var didConsent = this.hasConsented();
|
||||||
|
if (didConsent) {
|
||||||
|
initPostHog();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onStatusChange: function(status, chosenBefore) {
|
||||||
|
var type = this.options.type;
|
||||||
|
var didConsent = this.hasConsented();
|
||||||
|
if (didConsent) {
|
||||||
|
initPostHog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// PostHog initialization function
|
||||||
|
function initPostHog() {
|
||||||
|
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
||||||
|
posthog.init('phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv', {
|
||||||
|
api_host:'https://us.i.posthog.com',
|
||||||
|
person_profiles: 'identified_only'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
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.
|
||||||
@@ -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 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 `/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 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:
|
Example with a tag:
|
||||||
```
|
```
|
||||||
{python
|
{python
|
||||||
@@ -13,3 +16,7 @@ def hello():
|
|||||||
print("Hello}") # Note: contains a brace
|
print("Hello}") # Note: contains a brace
|
||||||
python}
|
python}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
{: .note }
|
||||||
|
People often ask for SHIFT-ENTER to be a soft-newline.
|
||||||
|
Unfortunately there is no portable way to detect that keystroke in terminals.
|
||||||
|
|||||||
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,6 +1,6 @@
|
|||||||
To use aider with pipx on replit, you can run these commands in the replit shell:
|
To use aider with pipx on replit, you can run these commands in the replit shell:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
pip install pipx
|
pip install pipx
|
||||||
pipx run aider-chat ...normal aider args...
|
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,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Aider has written 7% of its own code
|
title: Aider has written 7% of its own code (outdated, now 70%)
|
||||||
excerpt: Aider has written 7% of its own code, via 600+ commits that inserted 4.8K and deleted 1.5K lines of code.
|
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
|
highlight_image: /assets/self-assembly.jpg
|
||||||
nav_exclude: true
|
nav_exclude: true
|
||||||
---
|
---
|
||||||
@@ -8,13 +8,16 @@ nav_exclude: true
|
|||||||
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
|
<p class="post-date">{{ page.date | date: "%B %d, %Y" }}</p>
|
||||||
{% endif %}
|
{% 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)
|
[](https://aider.chat/assets/self-assembly.jpg)
|
||||||
|
|
||||||
{: .note }
|
{: .note }
|
||||||
This article is quite out dated. For current statistics, see
|
This article is quite old and outdated.
|
||||||
[aider's release history](/HISTORY.html).
|
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
|
The
|
||||||
[aider git repo](https://github.com/Aider-AI/aider)
|
[aider git repo](https://github.com/Aider-AI/aider)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ nav_exclude: true
|
|||||||
# Details matter with open source models
|
# Details matter with open source models
|
||||||
{: .no_toc }
|
{: .no_toc }
|
||||||
|
|
||||||
|
<canvas id="quantChart" width="800" height="600" style="margin: 20px 0"></canvas>
|
||||||
|
|
||||||
Open source models like Qwen 2.5 32B Instruct are performing very well on
|
Open source models like Qwen 2.5 32B Instruct are performing very well on
|
||||||
aider's code editing benchmark, rivaling closed source frontier models.
|
aider's code editing benchmark, rivaling closed source frontier models.
|
||||||
|
|
||||||
@@ -21,35 +23,55 @@ Open source models are often available at a variety of quantizations,
|
|||||||
and can be served with different token limits.
|
and can be served with different token limits.
|
||||||
These details matter when working with code.
|
These details matter when working with code.
|
||||||
|
|
||||||
The graph and table below compares different versions of the Qwen 2.5 Coder 32B Instruct model,
|
The graph above and table below compares different versions of the Qwen 2.5 Coder 32B Instruct model,
|
||||||
served both locally and from a variety of cloud providers.
|
served both locally and from a variety of cloud providers.
|
||||||
|
|
||||||
- The [HuggingFace BF16 weights](https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct) served via [glhf.chat](https://glhf.chat).
|
- The [HuggingFace BF16 weights](https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct) served via [glhf.chat](https://glhf.chat).
|
||||||
- [4bit and 8bit quants for mlx](https://t.co/cwX3DYX35D).
|
- [4bit and 8bit quants for mlx](https://t.co/cwX3DYX35D).
|
||||||
- The results from [OpenRouter's mix of providers](https://openrouter.ai/qwen/qwen-2.5-coder-32b-instruct/providers) which serve the model with different levels of quantization.
|
- The results from [OpenRouter's mix of providers](https://openrouter.ai/qwen/qwen-2.5-coder-32b-instruct/providers) which serve the model with different levels of quantization.
|
||||||
- Results from individual providers served via OpenRouter and directly to their own APIs.
|
- Results from OpenRouter's providers, both served via OpenRouter and directly to their own APIs.
|
||||||
- Ollama locally serving different quantizations from the [Ollama model library](https://ollama.com/library/qwen2.5-coder:32b-instruct-q4_K_M).
|
- Ollama locally serving different quantizations from the [Ollama model library](https://ollama.com/library/qwen2.5-coder:32b-instruct-q4_K_M) with 8k+
|
||||||
|
context windows.
|
||||||
|
- An Ollama fp16 quantization served with Ollama's default 2k context window.
|
||||||
|
|
||||||
The best versions of the model rival GPT-4o, while the worst performer
|
### Pitfalls and details
|
||||||
is more like the older GPT-4 Turbo.
|
|
||||||
Suboptimal choices in quantization and token limits can
|
|
||||||
easily produce far worse results.
|
|
||||||
|
|
||||||
This benchmarking effort highlighted a number of pitfalls and details which
|
This benchmarking effort highlighted a number of pitfalls and details specific to open source
|
||||||
can have a significant impact on the model's ability to correctly edit code:
|
models which
|
||||||
|
can have a significant impact on their ability to correctly edit code:
|
||||||
|
|
||||||
- Quantization -- Open source models are often available at dozens of different quantizations.
|
- **Quantization** -- Open source models are often available at dozens of different quantizations.
|
||||||
- Context window -- Cloud providers can decide how large a context window to accept,
|
Most seem to only modestly decrease code editing skill, but stronger quantizations
|
||||||
and they often choose differently. Ollama defaults to a tiny 2k context window,
|
do have a real impact.
|
||||||
and silently discards data that exceeds it.
|
- **Context window** -- Cloud providers can decide how large a context window to accept,
|
||||||
- Output token limits -- Open source models are often served with wildly
|
and they often choose differently. Ollama's local API server
|
||||||
|
defaults to a tiny 2k context window,
|
||||||
|
and silently discards data that exceeds it. Such a small window has
|
||||||
|
catastrophic effects on performance, without throwing obvious hard errors.
|
||||||
|
- **Output token limits** -- Open source models are often served with wildly
|
||||||
differing output token limits. This has a direct impact on how much code the
|
differing output token limits. This has a direct impact on how much code the
|
||||||
model can write or edit in a response.
|
model can write or edit in a response.
|
||||||
- Buggy cloud providers -- Between Qwen and DeepSeep, there were
|
- **Buggy cloud providers** -- While benchmarking Qwen 2.5 Coder 32B Instruct
|
||||||
multiple cloud providers with broken or buggy API endpoints that seemed
|
and DeepSeek V2.5, I discovered
|
||||||
to be returning result different from expected based on the advertised
|
multiple cloud providers with broken or buggy API endpoints.
|
||||||
|
They seemed
|
||||||
|
to be returning results different from expected based on the advertised
|
||||||
quantization and context sizes.
|
quantization and context sizes.
|
||||||
|
The harm caused to the code editing benchmark varied from serious
|
||||||
|
to catastrophic.
|
||||||
|
One provider scored 0.5% on the benchmark with DeepSeek V2.5, a highly capable model.
|
||||||
|
|
||||||
|
Closed source, proprietary models don't typically have these issues.
|
||||||
|
They are owned and operated by the organization that created them,
|
||||||
|
and typically served with specific, predictable context window and output token limits.
|
||||||
|
Their quantization level is usually unknown, but fixed and unchanging for all users.
|
||||||
|
|
||||||
|
### Conclusions
|
||||||
|
|
||||||
|
The best versions of the Qwen model rival GPT-4o, while the worst performing
|
||||||
|
quantization is more like the older GPT-4 Turbo when served competently.
|
||||||
|
Even an otherwise excellent fp16 quantization falls to GPT-3.5 Turbo levels of performance
|
||||||
|
if run with Ollama's default 2k context window.
|
||||||
|
|
||||||
### Sections
|
### Sections
|
||||||
{: .no_toc }
|
{: .no_toc }
|
||||||
@@ -59,7 +81,9 @@ quantization and context sizes.
|
|||||||
|
|
||||||
## Benchmark results
|
## Benchmark results
|
||||||
|
|
||||||
<canvas id="quantChart" width="800" height="600" style="margin: 20px 0"></canvas>
|
{: .note :}
|
||||||
|
These are results from single benchmark runs, so expect normal variance of +/- 1-2%.
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script>
|
<script>
|
||||||
{% include quant-chart.js %}
|
{% include quant-chart.js %}
|
||||||
@@ -134,9 +158,10 @@ a request that exceeds the context window.
|
|||||||
Instead, it just silently truncates the request by discarding the "oldest" messages
|
Instead, it just silently truncates the request by discarding the "oldest" messages
|
||||||
in the chat to make it fit within the context window.
|
in the chat to make it fit within the context window.
|
||||||
|
|
||||||
All of the Ollama results above were collected with at least an 8k context window, which
|
Except for the single 2k context result,
|
||||||
is large enough to attempt all the coding problems in the benchmark.
|
all of the Ollama results above were collected with at least an 8k context window.
|
||||||
Aider sets Ollama's context window to 8k by default.
|
An 8k window is large enough to attempt all the coding problems in the benchmark.
|
||||||
|
Aider sets Ollama's context window to 8k by default, starting in aider v0.65.0.
|
||||||
|
|
||||||
You can change the Ollama server's context window with a
|
You can change the Ollama server's context window with a
|
||||||
[`.aider.model.settings.yml` file](https://aider.chat/docs/config/adv-model-settings.html#model-settings)
|
[`.aider.model.settings.yml` file](https://aider.chat/docs/config/adv-model-settings.html#model-settings)
|
||||||
|
|||||||
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.
|
||||||
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/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
|
## show this help message and exit
|
||||||
#help: xxx
|
#help: xxx
|
||||||
|
|
||||||
#######
|
#############
|
||||||
# Main:
|
# Main model:
|
||||||
|
|
||||||
## Specify the OpenAI API key
|
|
||||||
#openai-api-key: xxx
|
|
||||||
|
|
||||||
## Specify the Anthropic API key
|
|
||||||
#anthropic-api-key: xxx
|
|
||||||
|
|
||||||
## Specify the model to use for the main chat
|
## Specify the model to use for the main chat
|
||||||
#model: xxx
|
#model: xxx
|
||||||
@@ -38,7 +32,7 @@
|
|||||||
## Use gpt-4-0613 model for the main chat
|
## Use gpt-4-0613 model for the main chat
|
||||||
#4: false
|
#4: false
|
||||||
|
|
||||||
## Use gpt-4o-2024-08-06 model for the main chat
|
## Use gpt-4o model for the main chat
|
||||||
#4o: false
|
#4o: false
|
||||||
|
|
||||||
## Use gpt-4o-mini model for the main chat
|
## Use gpt-4o-mini model for the main chat
|
||||||
@@ -59,27 +53,52 @@
|
|||||||
## Use o1-preview model for the main chat
|
## Use o1-preview model for the main chat
|
||||||
#o1-preview: false
|
#o1-preview: false
|
||||||
|
|
||||||
#################
|
########################
|
||||||
# Model Settings:
|
# API Keys and settings:
|
||||||
|
|
||||||
## List known models which match the (partial) MODEL name
|
## Specify the OpenAI API key
|
||||||
#list-models: xxx
|
#openai-api-key: xxx
|
||||||
|
|
||||||
|
## Specify the Anthropic API key
|
||||||
|
#anthropic-api-key: xxx
|
||||||
|
|
||||||
## Specify the api base url
|
## Specify the api base url
|
||||||
#openai-api-base: xxx
|
#openai-api-base: xxx
|
||||||
|
|
||||||
## Specify the api_type
|
## (deprecated, use --set-env OPENAI_API_TYPE=<value>)
|
||||||
#openai-api-type: xxx
|
#openai-api-type: xxx
|
||||||
|
|
||||||
## Specify the api_version
|
## (deprecated, use --set-env OPENAI_API_VERSION=<value>)
|
||||||
#openai-api-version: xxx
|
#openai-api-version: xxx
|
||||||
|
|
||||||
## Specify the deployment_id
|
## (deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)
|
||||||
#openai-api-deployment-id: xxx
|
#openai-api-deployment-id: xxx
|
||||||
|
|
||||||
## Specify the OpenAI organization ID
|
## (deprecated, use --set-env OPENAI_ORGANIZATION=<value>)
|
||||||
#openai-organization-id: xxx
|
#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
|
## Specify a file with aider model settings for unknown models
|
||||||
#model-settings-file: .aider.model.settings.yml
|
#model-settings-file: .aider.model.settings.yml
|
||||||
|
|
||||||
@@ -97,6 +116,9 @@
|
|||||||
## Verify the SSL cert when connecting to models (default: True)
|
## Verify the SSL cert when connecting to models (default: True)
|
||||||
#verify-ssl: true
|
#verify-ssl: true
|
||||||
|
|
||||||
|
## Timeout in seconds for API calls (default: None)
|
||||||
|
#timeout: xxx
|
||||||
|
|
||||||
## Specify what edit format the LLM should use (default depends on model)
|
## Specify what edit format the LLM should use (default depends on model)
|
||||||
#edit-format: xxx
|
#edit-format: xxx
|
||||||
|
|
||||||
@@ -118,11 +140,8 @@
|
|||||||
## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens.
|
## 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
|
#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)
|
## Enable caching of prompts (default: False)
|
||||||
#cache-prompts: false
|
#cache-prompts: false
|
||||||
@@ -131,7 +150,7 @@
|
|||||||
#cache-keepalive-pings: false
|
#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 (default: 1024)
|
||||||
#map-tokens: xxx
|
#map-tokens: xxx
|
||||||
@@ -158,7 +177,7 @@
|
|||||||
#llm-history-file: xxx
|
#llm-history-file: xxx
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Output Settings:
|
# Output settings:
|
||||||
|
|
||||||
## Use colors suitable for a dark terminal background (default: False)
|
## Use colors suitable for a dark terminal background (default: False)
|
||||||
#dark-mode: false
|
#dark-mode: false
|
||||||
@@ -206,7 +225,7 @@
|
|||||||
#show-diffs: false
|
#show-diffs: false
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Git Settings:
|
# Git settings:
|
||||||
|
|
||||||
## Enable/disable looking for a git repo (default: True)
|
## Enable/disable looking for a git repo (default: True)
|
||||||
#git: true
|
#git: true
|
||||||
@@ -250,6 +269,9 @@
|
|||||||
## Skip the sanity check for the git repository (default: False)
|
## Skip the sanity check for the git repository (default: False)
|
||||||
#skip-sanity-check-repo: false
|
#skip-sanity-check-repo: false
|
||||||
|
|
||||||
|
## Enable/disable watching files for ai coding comments (default: False)
|
||||||
|
#watch-files: false
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Fixing and committing:
|
# Fixing and committing:
|
||||||
|
|
||||||
@@ -273,7 +295,7 @@
|
|||||||
## Enable/disable automatic testing after changes (default: False)
|
## Enable/disable automatic testing after changes (default: False)
|
||||||
#auto-test: false
|
#auto-test: false
|
||||||
|
|
||||||
## Run tests and fix problems found
|
## Run tests, fix problems found and then exit
|
||||||
#test: false
|
#test: false
|
||||||
|
|
||||||
############
|
############
|
||||||
@@ -288,8 +310,71 @@
|
|||||||
## Permanently disable analytics
|
## Permanently disable analytics
|
||||||
#analytics-disable: false
|
#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)
|
## specify a file to edit (can be used multiple times)
|
||||||
#file: xxx
|
#file: xxx
|
||||||
@@ -313,51 +398,12 @@
|
|||||||
## Specify the language to use in the chat (default: None, uses system settings)
|
## Specify the language to use in the chat (default: None, uses system settings)
|
||||||
#chat-language: xxx
|
#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
|
## Always say yes to every confirmation
|
||||||
#yes-always: false
|
#yes-always: false
|
||||||
|
|
||||||
## Enable verbose output
|
## Enable verbose output
|
||||||
#verbose: false
|
#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 and execute /commands from a file on launch
|
||||||
#load: xxx
|
#load: xxx
|
||||||
|
|
||||||
@@ -367,8 +413,8 @@
|
|||||||
## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory)
|
## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory)
|
||||||
#config: xxx
|
#config: xxx
|
||||||
|
|
||||||
## Run aider in your browser (default: False)
|
## Specify the .env file to load (default: .env in git root)
|
||||||
#gui: false
|
#env-file: .env
|
||||||
|
|
||||||
## Enable/disable suggesting shell commands (default: True)
|
## Enable/disable suggesting shell commands (default: True)
|
||||||
#suggest-shell-commands: true
|
#suggest-shell-commands: true
|
||||||
@@ -376,17 +422,11 @@
|
|||||||
## Enable/disable fancy input with history and completion (default: True)
|
## Enable/disable fancy input with history and completion (default: True)
|
||||||
#fancy-input: 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)
|
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||||
#detect-urls: true
|
#detect-urls: true
|
||||||
|
|
||||||
## Specify which editor to use for the /editor command
|
## Specify which editor to use for the /editor command
|
||||||
#editor: xxx
|
#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
|
|
||||||
|
|||||||
@@ -18,14 +18,8 @@
|
|||||||
|
|
||||||
##...
|
##...
|
||||||
|
|
||||||
#######
|
#############
|
||||||
# Main:
|
# Main model:
|
||||||
|
|
||||||
## Specify the OpenAI API key
|
|
||||||
#OPENAI_API_KEY=
|
|
||||||
|
|
||||||
## Specify the Anthropic API key
|
|
||||||
#ANTHROPIC_API_KEY=
|
|
||||||
|
|
||||||
## Specify the model to use for the main chat
|
## Specify the model to use for the main chat
|
||||||
#AIDER_MODEL=
|
#AIDER_MODEL=
|
||||||
@@ -42,7 +36,7 @@
|
|||||||
## Use gpt-4-0613 model for the main chat
|
## Use gpt-4-0613 model for the main chat
|
||||||
#AIDER_4=
|
#AIDER_4=
|
||||||
|
|
||||||
## Use gpt-4o-2024-08-06 model for the main chat
|
## Use gpt-4o model for the main chat
|
||||||
#AIDER_4O=
|
#AIDER_4O=
|
||||||
|
|
||||||
## Use gpt-4o-mini model for the main chat
|
## Use gpt-4o-mini model for the main chat
|
||||||
@@ -63,27 +57,42 @@
|
|||||||
## Use o1-preview model for the main chat
|
## Use o1-preview model for the main chat
|
||||||
#AIDER_O1_PREVIEW=
|
#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
|
## List known models which match the (partial) MODEL name
|
||||||
#AIDER_LIST_MODELS=
|
#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
|
## Specify a file with aider model settings for unknown models
|
||||||
#AIDER_MODEL_SETTINGS_FILE=.aider.model.settings.yml
|
#AIDER_MODEL_SETTINGS_FILE=.aider.model.settings.yml
|
||||||
|
|
||||||
@@ -96,6 +105,9 @@
|
|||||||
## Verify the SSL cert when connecting to models (default: True)
|
## Verify the SSL cert when connecting to models (default: True)
|
||||||
#AIDER_VERIFY_SSL=true
|
#AIDER_VERIFY_SSL=true
|
||||||
|
|
||||||
|
## Timeout in seconds for API calls (default: None)
|
||||||
|
#AIDER_TIMEOUT=
|
||||||
|
|
||||||
## Specify what edit format the LLM should use (default depends on model)
|
## Specify what edit format the LLM should use (default depends on model)
|
||||||
#AIDER_EDIT_FORMAT=
|
#AIDER_EDIT_FORMAT=
|
||||||
|
|
||||||
@@ -117,11 +129,8 @@
|
|||||||
## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens.
|
## 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=
|
#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)
|
## Enable caching of prompts (default: False)
|
||||||
#AIDER_CACHE_PROMPTS=false
|
#AIDER_CACHE_PROMPTS=false
|
||||||
@@ -130,7 +139,7 @@
|
|||||||
#AIDER_CACHE_KEEPALIVE_PINGS=false
|
#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 (default: 1024)
|
||||||
#AIDER_MAP_TOKENS=
|
#AIDER_MAP_TOKENS=
|
||||||
@@ -157,7 +166,7 @@
|
|||||||
#AIDER_LLM_HISTORY_FILE=
|
#AIDER_LLM_HISTORY_FILE=
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Output Settings:
|
# Output settings:
|
||||||
|
|
||||||
## Use colors suitable for a dark terminal background (default: False)
|
## Use colors suitable for a dark terminal background (default: False)
|
||||||
#AIDER_DARK_MODE=false
|
#AIDER_DARK_MODE=false
|
||||||
@@ -205,7 +214,7 @@
|
|||||||
#AIDER_SHOW_DIFFS=false
|
#AIDER_SHOW_DIFFS=false
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Git Settings:
|
# Git settings:
|
||||||
|
|
||||||
## Enable/disable looking for a git repo (default: True)
|
## Enable/disable looking for a git repo (default: True)
|
||||||
#AIDER_GIT=true
|
#AIDER_GIT=true
|
||||||
@@ -249,6 +258,9 @@
|
|||||||
## Skip the sanity check for the git repository (default: False)
|
## Skip the sanity check for the git repository (default: False)
|
||||||
#AIDER_SKIP_SANITY_CHECK_REPO=false
|
#AIDER_SKIP_SANITY_CHECK_REPO=false
|
||||||
|
|
||||||
|
## Enable/disable watching files for ai coding comments (default: False)
|
||||||
|
#AIDER_WATCH_FILES=false
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Fixing and committing:
|
# Fixing and committing:
|
||||||
|
|
||||||
@@ -267,7 +279,7 @@
|
|||||||
## Enable/disable automatic testing after changes (default: False)
|
## Enable/disable automatic testing after changes (default: False)
|
||||||
#AIDER_AUTO_TEST=false
|
#AIDER_AUTO_TEST=false
|
||||||
|
|
||||||
## Run tests and fix problems found
|
## Run tests, fix problems found and then exit
|
||||||
#AIDER_TEST=false
|
#AIDER_TEST=false
|
||||||
|
|
||||||
############
|
############
|
||||||
@@ -282,20 +294,8 @@
|
|||||||
## Permanently disable analytics
|
## Permanently disable analytics
|
||||||
#AIDER_ANALYTICS_DISABLE=false
|
#AIDER_ANALYTICS_DISABLE=false
|
||||||
|
|
||||||
#################
|
############
|
||||||
# Other Settings:
|
# Upgrading:
|
||||||
|
|
||||||
## 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=
|
|
||||||
|
|
||||||
## Check for updates and return status in the exit code
|
## Check for updates and return status in the exit code
|
||||||
#AIDER_JUST_CHECK_UPDATE=false
|
#AIDER_JUST_CHECK_UPDATE=false
|
||||||
@@ -312,26 +312,8 @@
|
|||||||
## Upgrade aider to the latest version from PyPI
|
## Upgrade aider to the latest version from PyPI
|
||||||
#AIDER_UPGRADE=false
|
#AIDER_UPGRADE=false
|
||||||
|
|
||||||
## Apply the changes from the given file instead of running the chat (debug)
|
########
|
||||||
#AIDER_APPLY=
|
# Modes:
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|
||||||
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
|
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
|
||||||
#AIDER_MESSAGE=
|
#AIDER_MESSAGE=
|
||||||
@@ -339,14 +321,68 @@
|
|||||||
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
|
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
|
||||||
#AIDER_MESSAGE_FILE=
|
#AIDER_MESSAGE_FILE=
|
||||||
|
|
||||||
|
## Run aider in your browser (default: False)
|
||||||
|
#AIDER_GUI=false
|
||||||
|
|
||||||
|
## Enable automatic copy/paste of chat between aider and web UI (default: False)
|
||||||
|
#AIDER_COPY_PASTE=false
|
||||||
|
|
||||||
|
## Apply the changes from the given file instead of running the chat (debug)
|
||||||
|
#AIDER_APPLY=
|
||||||
|
|
||||||
|
## Apply clipboard contents as edits using the main model's editor format
|
||||||
|
#AIDER_APPLY_CLIPBOARD_EDITS=false
|
||||||
|
|
||||||
|
## Do all startup activities then exit before accepting user input (debug)
|
||||||
|
#AIDER_EXIT=false
|
||||||
|
|
||||||
|
## Print the repo map and exit (debug)
|
||||||
|
#AIDER_SHOW_REPO_MAP=false
|
||||||
|
|
||||||
|
## Print the system prompts and exit (debug)
|
||||||
|
#AIDER_SHOW_PROMPTS=false
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Voice settings:
|
||||||
|
|
||||||
|
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
||||||
|
#AIDER_VOICE_FORMAT=wav
|
||||||
|
|
||||||
|
## Specify the language for voice using ISO 639-1 code (default: auto)
|
||||||
|
#AIDER_VOICE_LANGUAGE=en
|
||||||
|
|
||||||
|
## Specify the input device name for voice recording
|
||||||
|
#AIDER_VOICE_INPUT_DEVICE=
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Other settings:
|
||||||
|
|
||||||
|
## specify a file to edit (can be used multiple times)
|
||||||
|
#AIDER_FILE=
|
||||||
|
|
||||||
|
## specify a read-only file (can be used multiple times)
|
||||||
|
#AIDER_READ=
|
||||||
|
|
||||||
|
## Use VI editing mode in the terminal (default: False)
|
||||||
|
#AIDER_VIM=false
|
||||||
|
|
||||||
|
## Specify the language to use in the chat (default: None, uses system settings)
|
||||||
|
#AIDER_CHAT_LANGUAGE=
|
||||||
|
|
||||||
|
## Always say yes to every confirmation
|
||||||
|
#AIDER_YES_ALWAYS=
|
||||||
|
|
||||||
|
## Enable verbose output
|
||||||
|
#AIDER_VERBOSE=false
|
||||||
|
|
||||||
## Load and execute /commands from a file on launch
|
## Load and execute /commands from a file on launch
|
||||||
#AIDER_LOAD=
|
#AIDER_LOAD=
|
||||||
|
|
||||||
## Specify the encoding for input and output (default: utf-8)
|
## Specify the encoding for input and output (default: utf-8)
|
||||||
#AIDER_ENCODING=utf-8
|
#AIDER_ENCODING=utf-8
|
||||||
|
|
||||||
## Run aider in your browser (default: False)
|
## Specify the .env file to load (default: .env in git root)
|
||||||
#AIDER_GUI=false
|
#AIDER_ENV_FILE=.env
|
||||||
|
|
||||||
## Enable/disable suggesting shell commands (default: True)
|
## Enable/disable suggesting shell commands (default: True)
|
||||||
#AIDER_SUGGEST_SHELL_COMMANDS=true
|
#AIDER_SUGGEST_SHELL_COMMANDS=true
|
||||||
@@ -354,17 +390,11 @@
|
|||||||
## Enable/disable fancy input with history and completion (default: True)
|
## Enable/disable fancy input with history and completion (default: True)
|
||||||
#AIDER_FANCY_INPUT=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)
|
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||||
#AIDER_DETECT_URLS=true
|
#AIDER_DETECT_URLS=true
|
||||||
|
|
||||||
## Specify which editor to use for the /editor command
|
## Specify which editor to use for the /editor command
|
||||||
#AIDER_EDITOR=
|
#AIDER_EDITOR=
|
||||||
|
|
||||||
#################
|
|
||||||
# Voice Settings:
|
|
||||||
|
|
||||||
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
|
||||||
#AIDER_VOICE_FORMAT=wav
|
|
||||||
|
|
||||||
## Specify the language for voice using ISO 639-1 code (default: auto)
|
|
||||||
#AIDER_VOICE_LANGUAGE=en
|
|
||||||
|
|||||||
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
|
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 }
|
{: .tip }
|
||||||
Use a fully qualified model name with a `provider/` at the front
|
Use a fully qualified model name with a `provider/` at the front
|
||||||
in the `.aider.model.metadata.json` file.
|
in the `.aider.model.metadata.json` file.
|
||||||
For example, use `deepseek/deepseek-chat`, not just `deepseek-chat`.
|
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
|
## Model settings
|
||||||
|
|
||||||
@@ -504,7 +510,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
max_tokens: 8192
|
max_tokens: 8192
|
||||||
lazy: false
|
lazy: false
|
||||||
name: claude-3-5-sonnet-20240620
|
name: claude-3-5-sonnet-20240620
|
||||||
@@ -523,7 +529,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
max_tokens: 8192
|
max_tokens: 8192
|
||||||
lazy: false
|
lazy: false
|
||||||
name: anthropic/claude-3-5-sonnet-20240620
|
name: anthropic/claude-3-5-sonnet-20240620
|
||||||
@@ -542,7 +548,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
max_tokens: 8192
|
max_tokens: 8192
|
||||||
lazy: false
|
lazy: false
|
||||||
name: anthropic/claude-3-5-sonnet-20241022
|
name: anthropic/claude-3-5-sonnet-20241022
|
||||||
@@ -561,7 +567,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
max_tokens: 8192
|
max_tokens: 8192
|
||||||
lazy: false
|
lazy: false
|
||||||
name: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
|
name: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
|
||||||
@@ -580,7 +586,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
max_tokens: 8192
|
max_tokens: 8192
|
||||||
lazy: false
|
lazy: false
|
||||||
name: anthropic/claude-3-5-sonnet-latest
|
name: anthropic/claude-3-5-sonnet-latest
|
||||||
@@ -599,7 +605,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
max_tokens: 8192
|
max_tokens: 8192
|
||||||
lazy: false
|
lazy: false
|
||||||
name: claude-3-5-sonnet-20241022
|
name: claude-3-5-sonnet-20241022
|
||||||
@@ -618,7 +624,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
lazy: false
|
lazy: false
|
||||||
name: anthropic/claude-3-haiku-20240307
|
name: anthropic/claude-3-haiku-20240307
|
||||||
reminder: user
|
reminder: user
|
||||||
@@ -636,7 +642,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: false
|
examples_as_sys_msg: false
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
lazy: false
|
lazy: false
|
||||||
name: anthropic/claude-3-5-haiku-20241022
|
name: anthropic/claude-3-5-haiku-20241022
|
||||||
reminder: user
|
reminder: user
|
||||||
@@ -654,7 +660,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: false
|
examples_as_sys_msg: false
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
lazy: false
|
lazy: false
|
||||||
name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0
|
name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0
|
||||||
reminder: user
|
reminder: user
|
||||||
@@ -672,7 +678,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
lazy: false
|
lazy: false
|
||||||
name: claude-3-5-haiku-20241022
|
name: claude-3-5-haiku-20241022
|
||||||
reminder: user
|
reminder: user
|
||||||
@@ -707,7 +713,7 @@ cog.out("```\n")
|
|||||||
examples_as_sys_msg: true
|
examples_as_sys_msg: true
|
||||||
extra_params:
|
extra_params:
|
||||||
extra_headers:
|
extra_headers:
|
||||||
anthropic-beta: prompt-caching-2024-07-31
|
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||||
lazy: false
|
lazy: false
|
||||||
name: claude-3-haiku-20240307
|
name: claude-3-haiku-20240307
|
||||||
reminder: user
|
reminder: user
|
||||||
@@ -977,6 +983,54 @@ cog.out("```\n")
|
|||||||
use_system_prompt: true
|
use_system_prompt: true
|
||||||
use_temperature: true
|
use_temperature: true
|
||||||
weak_model_name: null
|
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
|
- cache_control: false
|
||||||
caches_by_default: false
|
caches_by_default: false
|
||||||
edit_format: diff-fenced
|
edit_format: diff-fenced
|
||||||
@@ -1009,6 +1063,22 @@ cog.out("```\n")
|
|||||||
use_system_prompt: true
|
use_system_prompt: true
|
||||||
use_temperature: true
|
use_temperature: true
|
||||||
weak_model_name: null
|
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
|
- cache_control: false
|
||||||
caches_by_default: false
|
caches_by_default: false
|
||||||
edit_format: diff
|
edit_format: diff
|
||||||
|
|||||||
@@ -15,11 +15,7 @@ load whichever is found first.
|
|||||||
- The root of your git repo.
|
- The root of your git repo.
|
||||||
- Your home directory.
|
- Your home directory.
|
||||||
|
|
||||||
## Storing LLM keys
|
{% include keys.md %}
|
||||||
|
|
||||||
{% include special-keys.md %}
|
|
||||||
|
|
||||||
{% include env-keys-tip.md %}
|
|
||||||
|
|
||||||
## A note on lists
|
## A note on lists
|
||||||
|
|
||||||
@@ -70,14 +66,8 @@ cog.outl("```")
|
|||||||
## show this help message and exit
|
## show this help message and exit
|
||||||
#help: xxx
|
#help: xxx
|
||||||
|
|
||||||
#######
|
#############
|
||||||
# Main:
|
# Main model:
|
||||||
|
|
||||||
## Specify the OpenAI API key
|
|
||||||
#openai-api-key: xxx
|
|
||||||
|
|
||||||
## Specify the Anthropic API key
|
|
||||||
#anthropic-api-key: xxx
|
|
||||||
|
|
||||||
## Specify the model to use for the main chat
|
## Specify the model to use for the main chat
|
||||||
#model: xxx
|
#model: xxx
|
||||||
@@ -94,7 +84,7 @@ cog.outl("```")
|
|||||||
## Use gpt-4-0613 model for the main chat
|
## Use gpt-4-0613 model for the main chat
|
||||||
#4: false
|
#4: false
|
||||||
|
|
||||||
## Use gpt-4o-2024-08-06 model for the main chat
|
## Use gpt-4o model for the main chat
|
||||||
#4o: false
|
#4o: false
|
||||||
|
|
||||||
## Use gpt-4o-mini model for the main chat
|
## Use gpt-4o-mini model for the main chat
|
||||||
@@ -115,27 +105,52 @@ cog.outl("```")
|
|||||||
## Use o1-preview model for the main chat
|
## Use o1-preview model for the main chat
|
||||||
#o1-preview: false
|
#o1-preview: false
|
||||||
|
|
||||||
#################
|
########################
|
||||||
# Model Settings:
|
# API Keys and settings:
|
||||||
|
|
||||||
## List known models which match the (partial) MODEL name
|
## Specify the OpenAI API key
|
||||||
#list-models: xxx
|
#openai-api-key: xxx
|
||||||
|
|
||||||
|
## Specify the Anthropic API key
|
||||||
|
#anthropic-api-key: xxx
|
||||||
|
|
||||||
## Specify the api base url
|
## Specify the api base url
|
||||||
#openai-api-base: xxx
|
#openai-api-base: xxx
|
||||||
|
|
||||||
## Specify the api_type
|
## (deprecated, use --set-env OPENAI_API_TYPE=<value>)
|
||||||
#openai-api-type: xxx
|
#openai-api-type: xxx
|
||||||
|
|
||||||
## Specify the api_version
|
## (deprecated, use --set-env OPENAI_API_VERSION=<value>)
|
||||||
#openai-api-version: xxx
|
#openai-api-version: xxx
|
||||||
|
|
||||||
## Specify the deployment_id
|
## (deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)
|
||||||
#openai-api-deployment-id: xxx
|
#openai-api-deployment-id: xxx
|
||||||
|
|
||||||
## Specify the OpenAI organization ID
|
## (deprecated, use --set-env OPENAI_ORGANIZATION=<value>)
|
||||||
#openai-organization-id: xxx
|
#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
|
## Specify a file with aider model settings for unknown models
|
||||||
#model-settings-file: .aider.model.settings.yml
|
#model-settings-file: .aider.model.settings.yml
|
||||||
|
|
||||||
@@ -153,6 +168,9 @@ cog.outl("```")
|
|||||||
## Verify the SSL cert when connecting to models (default: True)
|
## Verify the SSL cert when connecting to models (default: True)
|
||||||
#verify-ssl: true
|
#verify-ssl: true
|
||||||
|
|
||||||
|
## Timeout in seconds for API calls (default: None)
|
||||||
|
#timeout: xxx
|
||||||
|
|
||||||
## Specify what edit format the LLM should use (default depends on model)
|
## Specify what edit format the LLM should use (default depends on model)
|
||||||
#edit-format: xxx
|
#edit-format: xxx
|
||||||
|
|
||||||
@@ -174,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.
|
## 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
|
#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)
|
## Enable caching of prompts (default: False)
|
||||||
#cache-prompts: false
|
#cache-prompts: false
|
||||||
@@ -187,7 +202,7 @@ cog.outl("```")
|
|||||||
#cache-keepalive-pings: false
|
#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 (default: 1024)
|
||||||
#map-tokens: xxx
|
#map-tokens: xxx
|
||||||
@@ -214,7 +229,7 @@ cog.outl("```")
|
|||||||
#llm-history-file: xxx
|
#llm-history-file: xxx
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Output Settings:
|
# Output settings:
|
||||||
|
|
||||||
## Use colors suitable for a dark terminal background (default: False)
|
## Use colors suitable for a dark terminal background (default: False)
|
||||||
#dark-mode: false
|
#dark-mode: false
|
||||||
@@ -262,7 +277,7 @@ cog.outl("```")
|
|||||||
#show-diffs: false
|
#show-diffs: false
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Git Settings:
|
# Git settings:
|
||||||
|
|
||||||
## Enable/disable looking for a git repo (default: True)
|
## Enable/disable looking for a git repo (default: True)
|
||||||
#git: true
|
#git: true
|
||||||
@@ -306,6 +321,9 @@ cog.outl("```")
|
|||||||
## Skip the sanity check for the git repository (default: False)
|
## Skip the sanity check for the git repository (default: False)
|
||||||
#skip-sanity-check-repo: false
|
#skip-sanity-check-repo: false
|
||||||
|
|
||||||
|
## Enable/disable watching files for ai coding comments (default: False)
|
||||||
|
#watch-files: false
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Fixing and committing:
|
# Fixing and committing:
|
||||||
|
|
||||||
@@ -329,7 +347,7 @@ cog.outl("```")
|
|||||||
## Enable/disable automatic testing after changes (default: False)
|
## Enable/disable automatic testing after changes (default: False)
|
||||||
#auto-test: false
|
#auto-test: false
|
||||||
|
|
||||||
## Run tests and fix problems found
|
## Run tests, fix problems found and then exit
|
||||||
#test: false
|
#test: false
|
||||||
|
|
||||||
############
|
############
|
||||||
@@ -344,8 +362,71 @@ cog.outl("```")
|
|||||||
## Permanently disable analytics
|
## Permanently disable analytics
|
||||||
#analytics-disable: false
|
#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)
|
## specify a file to edit (can be used multiple times)
|
||||||
#file: xxx
|
#file: xxx
|
||||||
@@ -369,51 +450,12 @@ cog.outl("```")
|
|||||||
## Specify the language to use in the chat (default: None, uses system settings)
|
## Specify the language to use in the chat (default: None, uses system settings)
|
||||||
#chat-language: xxx
|
#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
|
## Always say yes to every confirmation
|
||||||
#yes-always: false
|
#yes-always: false
|
||||||
|
|
||||||
## Enable verbose output
|
## Enable verbose output
|
||||||
#verbose: false
|
#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 and execute /commands from a file on launch
|
||||||
#load: xxx
|
#load: xxx
|
||||||
|
|
||||||
@@ -423,8 +465,8 @@ cog.outl("```")
|
|||||||
## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory)
|
## Specify the config file (default: search for .aider.conf.yml in git root, cwd or home directory)
|
||||||
#config: xxx
|
#config: xxx
|
||||||
|
|
||||||
## Run aider in your browser (default: False)
|
## Specify the .env file to load (default: .env in git root)
|
||||||
#gui: false
|
#env-file: .env
|
||||||
|
|
||||||
## Enable/disable suggesting shell commands (default: True)
|
## Enable/disable suggesting shell commands (default: True)
|
||||||
#suggest-shell-commands: true
|
#suggest-shell-commands: true
|
||||||
@@ -432,19 +474,13 @@ cog.outl("```")
|
|||||||
## Enable/disable fancy input with history and completion (default: True)
|
## Enable/disable fancy input with history and completion (default: True)
|
||||||
#fancy-input: 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)
|
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||||
#detect-urls: true
|
#detect-urls: true
|
||||||
|
|
||||||
## Specify which editor to use for the /editor command
|
## Specify which editor to use for the /editor command
|
||||||
#editor: xxx
|
#editor: xxx
|
||||||
|
|
||||||
#################
|
|
||||||
# Voice Settings:
|
|
||||||
|
|
||||||
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
|
||||||
#voice-format: wav
|
|
||||||
|
|
||||||
## Specify the language for voice using ISO 639-1 code (default: auto)
|
|
||||||
#voice-language: en
|
|
||||||
```
|
```
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|||||||
68
aider/website/docs/config/api-keys.md
Normal file
68
aider/website/docs/config/api-keys.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
---
|
||||||
|
parent: Configuration
|
||||||
|
nav_order: 5
|
||||||
|
description: Setting API keys for API providers.
|
||||||
|
---
|
||||||
|
|
||||||
|
# API Keys
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
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>
|
||||||
|
```
|
||||||
|
|
||||||
|
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>
|
||||||
|
```
|
||||||
|
|
||||||
|
All other LLM providers can use one of these other methods to set their API keys.
|
||||||
|
|
||||||
|
### API keys on the command line
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
Use `--api-key provider=<key>` which has the effect of setting the environment variable `PROVIDER_API_KEY=<key>`. So `--api-key gemini=xxx` would set `GEMINI_API_KEY=xxx`.
|
||||||
|
|
||||||
|
### API keys in .aider.conf.yml
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
### API keys in a .env file
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
The [.env file](/docs/config/dotenv.html)
|
||||||
|
is a great place to set API keys and other provider API environment variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GEMINI_API_KEY=foo
|
||||||
|
OPENROUTER_API_KEY=bar
|
||||||
|
DEEPSEEK_API_KEY=baz
|
||||||
|
```
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
parent: Configuration
|
parent: Configuration
|
||||||
nav_order: 900
|
nav_order: 20
|
||||||
description: Using a .env file to store LLM API keys for aider.
|
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.
|
If the files above exist, they will be loaded in that order. Files loaded last will take priority.
|
||||||
|
|
||||||
## Storing LLM keys
|
{% include keys.md %}
|
||||||
|
|
||||||
{% include special-keys.md %}
|
|
||||||
|
|
||||||
## Sample .env file
|
## Sample .env file
|
||||||
|
|
||||||
@@ -60,14 +58,8 @@ cog.outl("```")
|
|||||||
|
|
||||||
##...
|
##...
|
||||||
|
|
||||||
#######
|
#############
|
||||||
# Main:
|
# Main model:
|
||||||
|
|
||||||
## Specify the OpenAI API key
|
|
||||||
#OPENAI_API_KEY=
|
|
||||||
|
|
||||||
## Specify the Anthropic API key
|
|
||||||
#ANTHROPIC_API_KEY=
|
|
||||||
|
|
||||||
## Specify the model to use for the main chat
|
## Specify the model to use for the main chat
|
||||||
#AIDER_MODEL=
|
#AIDER_MODEL=
|
||||||
@@ -84,7 +76,7 @@ cog.outl("```")
|
|||||||
## Use gpt-4-0613 model for the main chat
|
## Use gpt-4-0613 model for the main chat
|
||||||
#AIDER_4=
|
#AIDER_4=
|
||||||
|
|
||||||
## Use gpt-4o-2024-08-06 model for the main chat
|
## Use gpt-4o model for the main chat
|
||||||
#AIDER_4O=
|
#AIDER_4O=
|
||||||
|
|
||||||
## Use gpt-4o-mini model for the main chat
|
## Use gpt-4o-mini model for the main chat
|
||||||
@@ -105,27 +97,42 @@ cog.outl("```")
|
|||||||
## Use o1-preview model for the main chat
|
## Use o1-preview model for the main chat
|
||||||
#AIDER_O1_PREVIEW=
|
#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
|
## List known models which match the (partial) MODEL name
|
||||||
#AIDER_LIST_MODELS=
|
#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
|
## Specify a file with aider model settings for unknown models
|
||||||
#AIDER_MODEL_SETTINGS_FILE=.aider.model.settings.yml
|
#AIDER_MODEL_SETTINGS_FILE=.aider.model.settings.yml
|
||||||
|
|
||||||
@@ -138,6 +145,9 @@ cog.outl("```")
|
|||||||
## Verify the SSL cert when connecting to models (default: True)
|
## Verify the SSL cert when connecting to models (default: True)
|
||||||
#AIDER_VERIFY_SSL=true
|
#AIDER_VERIFY_SSL=true
|
||||||
|
|
||||||
|
## Timeout in seconds for API calls (default: None)
|
||||||
|
#AIDER_TIMEOUT=
|
||||||
|
|
||||||
## Specify what edit format the LLM should use (default depends on model)
|
## Specify what edit format the LLM should use (default depends on model)
|
||||||
#AIDER_EDIT_FORMAT=
|
#AIDER_EDIT_FORMAT=
|
||||||
|
|
||||||
@@ -159,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.
|
## 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=
|
#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)
|
## Enable caching of prompts (default: False)
|
||||||
#AIDER_CACHE_PROMPTS=false
|
#AIDER_CACHE_PROMPTS=false
|
||||||
@@ -172,7 +179,7 @@ cog.outl("```")
|
|||||||
#AIDER_CACHE_KEEPALIVE_PINGS=false
|
#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 (default: 1024)
|
||||||
#AIDER_MAP_TOKENS=
|
#AIDER_MAP_TOKENS=
|
||||||
@@ -199,7 +206,7 @@ cog.outl("```")
|
|||||||
#AIDER_LLM_HISTORY_FILE=
|
#AIDER_LLM_HISTORY_FILE=
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Output Settings:
|
# Output settings:
|
||||||
|
|
||||||
## Use colors suitable for a dark terminal background (default: False)
|
## Use colors suitable for a dark terminal background (default: False)
|
||||||
#AIDER_DARK_MODE=false
|
#AIDER_DARK_MODE=false
|
||||||
@@ -247,7 +254,7 @@ cog.outl("```")
|
|||||||
#AIDER_SHOW_DIFFS=false
|
#AIDER_SHOW_DIFFS=false
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Git Settings:
|
# Git settings:
|
||||||
|
|
||||||
## Enable/disable looking for a git repo (default: True)
|
## Enable/disable looking for a git repo (default: True)
|
||||||
#AIDER_GIT=true
|
#AIDER_GIT=true
|
||||||
@@ -291,6 +298,9 @@ cog.outl("```")
|
|||||||
## Skip the sanity check for the git repository (default: False)
|
## Skip the sanity check for the git repository (default: False)
|
||||||
#AIDER_SKIP_SANITY_CHECK_REPO=false
|
#AIDER_SKIP_SANITY_CHECK_REPO=false
|
||||||
|
|
||||||
|
## Enable/disable watching files for ai coding comments (default: False)
|
||||||
|
#AIDER_WATCH_FILES=false
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Fixing and committing:
|
# Fixing and committing:
|
||||||
|
|
||||||
@@ -309,7 +319,7 @@ cog.outl("```")
|
|||||||
## Enable/disable automatic testing after changes (default: False)
|
## Enable/disable automatic testing after changes (default: False)
|
||||||
#AIDER_AUTO_TEST=false
|
#AIDER_AUTO_TEST=false
|
||||||
|
|
||||||
## Run tests and fix problems found
|
## Run tests, fix problems found and then exit
|
||||||
#AIDER_TEST=false
|
#AIDER_TEST=false
|
||||||
|
|
||||||
############
|
############
|
||||||
@@ -324,20 +334,8 @@ cog.outl("```")
|
|||||||
## Permanently disable analytics
|
## Permanently disable analytics
|
||||||
#AIDER_ANALYTICS_DISABLE=false
|
#AIDER_ANALYTICS_DISABLE=false
|
||||||
|
|
||||||
#################
|
############
|
||||||
# Other Settings:
|
# Upgrading:
|
||||||
|
|
||||||
## 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=
|
|
||||||
|
|
||||||
## Check for updates and return status in the exit code
|
## Check for updates and return status in the exit code
|
||||||
#AIDER_JUST_CHECK_UPDATE=false
|
#AIDER_JUST_CHECK_UPDATE=false
|
||||||
@@ -354,26 +352,8 @@ cog.outl("```")
|
|||||||
## Upgrade aider to the latest version from PyPI
|
## Upgrade aider to the latest version from PyPI
|
||||||
#AIDER_UPGRADE=false
|
#AIDER_UPGRADE=false
|
||||||
|
|
||||||
## Apply the changes from the given file instead of running the chat (debug)
|
########
|
||||||
#AIDER_APPLY=
|
# Modes:
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|
||||||
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
|
## Specify a single message to send the LLM, process reply then exit (disables chat mode)
|
||||||
#AIDER_MESSAGE=
|
#AIDER_MESSAGE=
|
||||||
@@ -381,14 +361,68 @@ cog.outl("```")
|
|||||||
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
|
## Specify a file containing the message to send the LLM, process reply, then exit (disables chat mode)
|
||||||
#AIDER_MESSAGE_FILE=
|
#AIDER_MESSAGE_FILE=
|
||||||
|
|
||||||
|
## Run aider in your browser (default: False)
|
||||||
|
#AIDER_GUI=false
|
||||||
|
|
||||||
|
## Enable automatic copy/paste of chat between aider and web UI (default: False)
|
||||||
|
#AIDER_COPY_PASTE=false
|
||||||
|
|
||||||
|
## Apply the changes from the given file instead of running the chat (debug)
|
||||||
|
#AIDER_APPLY=
|
||||||
|
|
||||||
|
## Apply clipboard contents as edits using the main model's editor format
|
||||||
|
#AIDER_APPLY_CLIPBOARD_EDITS=false
|
||||||
|
|
||||||
|
## Do all startup activities then exit before accepting user input (debug)
|
||||||
|
#AIDER_EXIT=false
|
||||||
|
|
||||||
|
## Print the repo map and exit (debug)
|
||||||
|
#AIDER_SHOW_REPO_MAP=false
|
||||||
|
|
||||||
|
## Print the system prompts and exit (debug)
|
||||||
|
#AIDER_SHOW_PROMPTS=false
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Voice settings:
|
||||||
|
|
||||||
|
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
||||||
|
#AIDER_VOICE_FORMAT=wav
|
||||||
|
|
||||||
|
## Specify the language for voice using ISO 639-1 code (default: auto)
|
||||||
|
#AIDER_VOICE_LANGUAGE=en
|
||||||
|
|
||||||
|
## Specify the input device name for voice recording
|
||||||
|
#AIDER_VOICE_INPUT_DEVICE=
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Other settings:
|
||||||
|
|
||||||
|
## specify a file to edit (can be used multiple times)
|
||||||
|
#AIDER_FILE=
|
||||||
|
|
||||||
|
## specify a read-only file (can be used multiple times)
|
||||||
|
#AIDER_READ=
|
||||||
|
|
||||||
|
## Use VI editing mode in the terminal (default: False)
|
||||||
|
#AIDER_VIM=false
|
||||||
|
|
||||||
|
## Specify the language to use in the chat (default: None, uses system settings)
|
||||||
|
#AIDER_CHAT_LANGUAGE=
|
||||||
|
|
||||||
|
## Always say yes to every confirmation
|
||||||
|
#AIDER_YES_ALWAYS=
|
||||||
|
|
||||||
|
## Enable verbose output
|
||||||
|
#AIDER_VERBOSE=false
|
||||||
|
|
||||||
## Load and execute /commands from a file on launch
|
## Load and execute /commands from a file on launch
|
||||||
#AIDER_LOAD=
|
#AIDER_LOAD=
|
||||||
|
|
||||||
## Specify the encoding for input and output (default: utf-8)
|
## Specify the encoding for input and output (default: utf-8)
|
||||||
#AIDER_ENCODING=utf-8
|
#AIDER_ENCODING=utf-8
|
||||||
|
|
||||||
## Run aider in your browser (default: False)
|
## Specify the .env file to load (default: .env in git root)
|
||||||
#AIDER_GUI=false
|
#AIDER_ENV_FILE=.env
|
||||||
|
|
||||||
## Enable/disable suggesting shell commands (default: True)
|
## Enable/disable suggesting shell commands (default: True)
|
||||||
#AIDER_SUGGEST_SHELL_COMMANDS=true
|
#AIDER_SUGGEST_SHELL_COMMANDS=true
|
||||||
@@ -396,21 +430,13 @@ cog.outl("```")
|
|||||||
## Enable/disable fancy input with history and completion (default: True)
|
## Enable/disable fancy input with history and completion (default: True)
|
||||||
#AIDER_FANCY_INPUT=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)
|
## Enable/disable detection and offering to add URLs to chat (default: True)
|
||||||
#AIDER_DETECT_URLS=true
|
#AIDER_DETECT_URLS=true
|
||||||
|
|
||||||
## Specify which editor to use for the /editor command
|
## Specify which editor to use for the /editor command
|
||||||
#AIDER_EDITOR=
|
#AIDER_EDITOR=
|
||||||
|
|
||||||
#################
|
|
||||||
# Voice Settings:
|
|
||||||
|
|
||||||
## Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
|
||||||
#AIDER_VOICE_FORMAT=wav
|
|
||||||
|
|
||||||
## Specify the language for voice using ISO 639-1 code (default: auto)
|
|
||||||
#AIDER_VOICE_LANGUAGE=en
|
|
||||||
```
|
```
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
parent: Configuration
|
parent: Configuration
|
||||||
nav_order: 15
|
nav_order: 100
|
||||||
description: How to configure a custom editor for aider's /editor command
|
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
|
- `35turbo`: gpt-3.5-turbo
|
||||||
- `4`: gpt-4-0613
|
- `4`: gpt-4-0613
|
||||||
- `4-turbo`: gpt-4-1106-preview
|
- `4-turbo`: gpt-4-1106-preview
|
||||||
- `4o`: gpt-4o-2024-08-06
|
- `4o`: gpt-4o
|
||||||
- `deepseek`: deepseek/deepseek-coder
|
- `deepseek`: deepseek/deepseek-coder
|
||||||
|
- `flash`: gemini/gemini-2.0-flash-exp
|
||||||
- `haiku`: claude-3-5-haiku-20241022
|
- `haiku`: claude-3-5-haiku-20241022
|
||||||
- `opus`: claude-3-opus-20240229
|
- `opus`: claude-3-opus-20240229
|
||||||
- `sonnet`: claude-3-5-sonnet-20241022
|
- `sonnet`: claude-3-5-sonnet-20241022
|
||||||
|
|||||||
@@ -13,10 +13,7 @@ or review them below.
|
|||||||
- TOC
|
- TOC
|
||||||
{:toc}
|
{:toc}
|
||||||
|
|
||||||
## LLM keys
|
{% include keys.md %}
|
||||||
{: .no_toc }
|
|
||||||
|
|
||||||
{% include special-keys.md %}
|
|
||||||
|
|
||||||
## Usage summary
|
## Usage summary
|
||||||
|
|
||||||
@@ -25,18 +22,19 @@ from aider.args import get_md_help
|
|||||||
cog.out(get_md_help())
|
cog.out(get_md_help())
|
||||||
]]]-->
|
]]]-->
|
||||||
```
|
```
|
||||||
usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
|
usage: aider [-h] [--model] [--opus] [--sonnet] [--haiku] [--4]
|
||||||
[--opus] [--sonnet] [--haiku] [--4] [--4o] [--mini]
|
[--4o] [--mini] [--4-turbo] [--35turbo] [--deepseek]
|
||||||
[--4-turbo] [--35turbo] [--deepseek] [--o1-mini]
|
[--o1-mini] [--o1-preview] [--openai-api-key]
|
||||||
[--o1-preview] [--list-models] [--openai-api-base]
|
[--anthropic-api-key] [--openai-api-base]
|
||||||
[--openai-api-type] [--openai-api-version]
|
[--openai-api-type] [--openai-api-version]
|
||||||
[--openai-api-deployment-id] [--openai-organization-id]
|
[--openai-api-deployment-id] [--openai-organization-id]
|
||||||
|
[--set-env] [--api-key] [--list-models]
|
||||||
[--model-settings-file] [--model-metadata-file]
|
[--model-settings-file] [--model-metadata-file]
|
||||||
[--alias] [--verify-ssl | --no-verify-ssl]
|
[--alias] [--verify-ssl | --no-verify-ssl] [--timeout]
|
||||||
[--edit-format] [--architect] [--weak-model]
|
[--edit-format] [--architect] [--weak-model]
|
||||||
[--editor-model] [--editor-edit-format]
|
[--editor-model] [--editor-edit-format]
|
||||||
[--show-model-warnings | --no-show-model-warnings]
|
[--show-model-warnings | --no-show-model-warnings]
|
||||||
[--max-chat-history-tokens] [--env-file]
|
[--max-chat-history-tokens]
|
||||||
[--cache-prompts | --no-cache-prompts]
|
[--cache-prompts | --no-cache-prompts]
|
||||||
[--cache-keepalive-pings] [--map-tokens]
|
[--cache-keepalive-pings] [--map-tokens]
|
||||||
[--map-refresh] [--map-multiplier-no-files]
|
[--map-refresh] [--map-multiplier-no-files]
|
||||||
@@ -59,23 +57,27 @@ usage: aider [-h] [--openai-api-key] [--anthropic-api-key] [--model]
|
|||||||
[--attribute-commit-message-author | --no-attribute-commit-message-author]
|
[--attribute-commit-message-author | --no-attribute-commit-message-author]
|
||||||
[--attribute-commit-message-committer | --no-attribute-commit-message-committer]
|
[--attribute-commit-message-committer | --no-attribute-commit-message-committer]
|
||||||
[--commit] [--commit-prompt] [--dry-run | --no-dry-run]
|
[--commit] [--commit-prompt] [--dry-run | --no-dry-run]
|
||||||
[--skip-sanity-check-repo] [--lint] [--lint-cmd]
|
[--skip-sanity-check-repo]
|
||||||
[--auto-lint | --no-auto-lint] [--test-cmd]
|
[--watch-files | --no-watch-files] [--lint]
|
||||||
[--auto-test | --no-auto-test] [--test]
|
[--lint-cmd] [--auto-lint | --no-auto-lint]
|
||||||
|
[--test-cmd] [--auto-test | --no-auto-test] [--test]
|
||||||
[--analytics | --no-analytics] [--analytics-log]
|
[--analytics | --no-analytics] [--analytics-log]
|
||||||
[--analytics-disable] [--file] [--read] [--vim]
|
[--analytics-disable] [--just-check-update]
|
||||||
[--chat-language] [--version] [--just-check-update]
|
|
||||||
[--check-update | --no-check-update]
|
[--check-update | --no-check-update]
|
||||||
[--show-release-notes | --no-show-release-notes]
|
[--show-release-notes | --no-show-release-notes]
|
||||||
[--install-main-branch] [--upgrade] [--apply]
|
[--install-main-branch] [--upgrade] [--version]
|
||||||
[--apply-clipboard-edits] [--yes-always] [-v]
|
[--message] [--message-file]
|
||||||
[--show-repo-map] [--show-prompts] [--exit] [--message]
|
|
||||||
[--message-file] [--load] [--encoding] [-c]
|
|
||||||
[--gui | --no-gui | --browser | --no-browser]
|
[--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]
|
[--suggest-shell-commands | --no-suggest-shell-commands]
|
||||||
[--fancy-input | --no-fancy-input]
|
[--fancy-input | --no-fancy-input]
|
||||||
|
[--multiline | --no-multiline]
|
||||||
[--detect-urls | --no-detect-urls] [--editor]
|
[--detect-urls | --no-detect-urls] [--editor]
|
||||||
[--voice-format] [--voice-language]
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -87,15 +89,7 @@ Aliases:
|
|||||||
- `-h`
|
- `-h`
|
||||||
- `--help`
|
- `--help`
|
||||||
|
|
||||||
## Main:
|
## Main model:
|
||||||
|
|
||||||
### `--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`
|
|
||||||
|
|
||||||
### `--model MODEL`
|
### `--model MODEL`
|
||||||
Specify the model to use for the main chat
|
Specify the model to use for the main chat
|
||||||
@@ -121,7 +115,7 @@ Aliases:
|
|||||||
- `-4`
|
- `-4`
|
||||||
|
|
||||||
### `--4o`
|
### `--4o`
|
||||||
Use gpt-4o-2024-08-06 model for the main chat
|
Use gpt-4o model for the main chat
|
||||||
Environment variable: `AIDER_4O`
|
Environment variable: `AIDER_4O`
|
||||||
|
|
||||||
### `--mini`
|
### `--mini`
|
||||||
@@ -153,7 +147,47 @@ Environment variable: `AIDER_O1_MINI`
|
|||||||
Use o1-preview model for the main chat
|
Use o1-preview model for the main chat
|
||||||
Environment variable: `AIDER_O1_PREVIEW`
|
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-models MODEL`
|
||||||
List known models which match the (partial) MODEL name
|
List known models which match the (partial) MODEL name
|
||||||
@@ -162,26 +196,6 @@ Aliases:
|
|||||||
- `--list-models MODEL`
|
- `--list-models MODEL`
|
||||||
- `--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`
|
### `--model-settings-file MODEL_SETTINGS_FILE`
|
||||||
Specify a file with aider model settings for unknown models
|
Specify a file with aider model settings for unknown models
|
||||||
Default: .aider.model.settings.yml
|
Default: .aider.model.settings.yml
|
||||||
@@ -204,6 +218,10 @@ Aliases:
|
|||||||
- `--verify-ssl`
|
- `--verify-ssl`
|
||||||
- `--no-verify-ssl`
|
- `--no-verify-ssl`
|
||||||
|
|
||||||
|
### `--timeout VALUE`
|
||||||
|
Timeout in seconds for API calls (default: None)
|
||||||
|
Environment variable: `AIDER_TIMEOUT`
|
||||||
|
|
||||||
### `--edit-format EDIT_FORMAT`
|
### `--edit-format EDIT_FORMAT`
|
||||||
Specify what edit format the LLM should use (default depends on model)
|
Specify what edit format the LLM should use (default depends on model)
|
||||||
Environment variable: `AIDER_EDIT_FORMAT`
|
Environment variable: `AIDER_EDIT_FORMAT`
|
||||||
@@ -239,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.
|
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`
|
Environment variable: `AIDER_MAX_CHAT_HISTORY_TOKENS`
|
||||||
|
|
||||||
### `--env-file ENV_FILE`
|
## Cache settings:
|
||||||
Specify the .env file to load (default: .env in git root)
|
|
||||||
Default: .env
|
|
||||||
Environment variable: `AIDER_ENV_FILE`
|
|
||||||
|
|
||||||
## Cache Settings:
|
|
||||||
|
|
||||||
### `--cache-prompts`
|
### `--cache-prompts`
|
||||||
Enable caching of prompts (default: False)
|
Enable caching of prompts (default: False)
|
||||||
@@ -259,7 +272,7 @@ Number of times to ping at 5min intervals to keep prompt cache warm (default: 0)
|
|||||||
Default: 0
|
Default: 0
|
||||||
Environment variable: `AIDER_CACHE_KEEPALIVE_PINGS`
|
Environment variable: `AIDER_CACHE_KEEPALIVE_PINGS`
|
||||||
|
|
||||||
## Repomap Settings:
|
## Repomap settings:
|
||||||
|
|
||||||
### `--map-tokens VALUE`
|
### `--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 (default: 1024)
|
||||||
@@ -299,7 +312,7 @@ Aliases:
|
|||||||
Log the conversation with the LLM to this file (for example, .aider.llm.history)
|
Log the conversation with the LLM to this file (for example, .aider.llm.history)
|
||||||
Environment variable: `AIDER_LLM_HISTORY_FILE`
|
Environment variable: `AIDER_LLM_HISTORY_FILE`
|
||||||
|
|
||||||
## Output Settings:
|
## Output settings:
|
||||||
|
|
||||||
### `--dark-mode`
|
### `--dark-mode`
|
||||||
Use colors suitable for a dark terminal background (default: False)
|
Use colors suitable for a dark terminal background (default: False)
|
||||||
@@ -377,7 +390,7 @@ Show diffs when committing changes (default: False)
|
|||||||
Default: False
|
Default: False
|
||||||
Environment variable: `AIDER_SHOW_DIFFS`
|
Environment variable: `AIDER_SHOW_DIFFS`
|
||||||
|
|
||||||
## Git Settings:
|
## Git settings:
|
||||||
|
|
||||||
### `--git`
|
### `--git`
|
||||||
Enable/disable looking for a git repo (default: True)
|
Enable/disable looking for a git repo (default: True)
|
||||||
@@ -475,6 +488,14 @@ Skip the sanity check for the git repository (default: False)
|
|||||||
Default: False
|
Default: False
|
||||||
Environment variable: `AIDER_SKIP_SANITY_CHECK_REPO`
|
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:
|
## Fixing and committing:
|
||||||
|
|
||||||
### `--lint`
|
### `--lint`
|
||||||
@@ -509,7 +530,7 @@ Aliases:
|
|||||||
- `--no-auto-test`
|
- `--no-auto-test`
|
||||||
|
|
||||||
### `--test`
|
### `--test`
|
||||||
Run tests and fix problems found
|
Run tests, fix problems found and then exit
|
||||||
Default: False
|
Default: False
|
||||||
Environment variable: `AIDER_TEST`
|
Environment variable: `AIDER_TEST`
|
||||||
|
|
||||||
@@ -531,27 +552,7 @@ Permanently disable analytics
|
|||||||
Default: False
|
Default: False
|
||||||
Environment variable: `AIDER_ANALYTICS_DISABLE`
|
Environment variable: `AIDER_ANALYTICS_DISABLE`
|
||||||
|
|
||||||
## Other Settings:
|
## Upgrading:
|
||||||
|
|
||||||
### `--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
|
|
||||||
|
|
||||||
### `--just-check-update`
|
### `--just-check-update`
|
||||||
Check for updates and return status in the exit code
|
Check for updates and return status in the exit code
|
||||||
@@ -586,41 +587,10 @@ Aliases:
|
|||||||
- `--upgrade`
|
- `--upgrade`
|
||||||
- `--update`
|
- `--update`
|
||||||
|
|
||||||
### `--apply FILE`
|
### `--version`
|
||||||
Apply the changes from the given file instead of running the chat (debug)
|
Show the version number and exit
|
||||||
Environment variable: `AIDER_APPLY`
|
|
||||||
|
|
||||||
### `--apply-clipboard-edits`
|
## Modes:
|
||||||
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`
|
|
||||||
|
|
||||||
### `--message COMMAND`
|
### `--message COMMAND`
|
||||||
Specify a single message to send the LLM, process reply then exit (disables chat mode)
|
Specify a single message to send the LLM, process reply then exit (disables chat mode)
|
||||||
@@ -637,6 +607,95 @@ Aliases:
|
|||||||
- `--message-file MESSAGE_FILE`
|
- `--message-file MESSAGE_FILE`
|
||||||
- `-f 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 LOAD_FILE`
|
||||||
Load and execute /commands from a file on launch
|
Load and execute /commands from a file on launch
|
||||||
Environment variable: `AIDER_LOAD`
|
Environment variable: `AIDER_LOAD`
|
||||||
@@ -652,15 +711,10 @@ Aliases:
|
|||||||
- `-c CONFIG_FILE`
|
- `-c CONFIG_FILE`
|
||||||
- `--config CONFIG_FILE`
|
- `--config CONFIG_FILE`
|
||||||
|
|
||||||
### `--gui`
|
### `--env-file ENV_FILE`
|
||||||
Run aider in your browser (default: False)
|
Specify the .env file to load (default: .env in git root)
|
||||||
Default: False
|
Default: .env
|
||||||
Environment variable: `AIDER_GUI`
|
Environment variable: `AIDER_ENV_FILE`
|
||||||
Aliases:
|
|
||||||
- `--gui`
|
|
||||||
- `--no-gui`
|
|
||||||
- `--browser`
|
|
||||||
- `--no-browser`
|
|
||||||
|
|
||||||
### `--suggest-shell-commands`
|
### `--suggest-shell-commands`
|
||||||
Enable/disable suggesting shell commands (default: True)
|
Enable/disable suggesting shell commands (default: True)
|
||||||
@@ -678,6 +732,14 @@ Aliases:
|
|||||||
- `--fancy-input`
|
- `--fancy-input`
|
||||||
- `--no-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`
|
### `--detect-urls`
|
||||||
Enable/disable detection and offering to add URLs to chat (default: True)
|
Enable/disable detection and offering to add URLs to chat (default: True)
|
||||||
Default: True
|
Default: True
|
||||||
@@ -689,16 +751,4 @@ Aliases:
|
|||||||
### `--editor VALUE`
|
### `--editor VALUE`
|
||||||
Specify which editor to use for the /editor command
|
Specify which editor to use for the /editor command
|
||||||
Environment variable: `AIDER_EDITOR`
|
Environment variable: `AIDER_EDITOR`
|
||||||
|
|
||||||
## Voice Settings:
|
|
||||||
|
|
||||||
### `--voice-format VOICE_FORMAT`
|
|
||||||
Audio format for voice recording (default: wav). webm and mp3 require ffmpeg
|
|
||||||
Default: wav
|
|
||||||
Environment variable: `AIDER_VOICE_FORMAT`
|
|
||||||
|
|
||||||
### `--voice-language VOICE_LANGUAGE`
|
|
||||||
Specify the language for voice using ISO 639-1 code (default: auto)
|
|
||||||
Default: en
|
|
||||||
Environment variable: `AIDER_VOICE_LANGUAGE`
|
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|||||||
@@ -169,7 +169,10 @@ python -m aider
|
|||||||
|
|
||||||
## Can I change the system prompts that aider uses?
|
## Can I change the system prompts that aider uses?
|
||||||
|
|
||||||
Aider is set up to support different system prompts and edit formats
|
The most convenient way to add custom instructions is to use a
|
||||||
|
[conventions file](https://aider.chat/docs/usage/conventions.html).
|
||||||
|
|
||||||
|
But, aider is set up to support different actual system prompts and edit formats
|
||||||
in a modular way. If you look in the `aider/coders` subdirectory, you'll
|
in a modular way. If you look in the `aider/coders` subdirectory, you'll
|
||||||
see there's a base coder with base prompts, and then there are
|
see there's a base coder with base prompts, and then there are
|
||||||
a number of
|
a number of
|
||||||
@@ -206,6 +209,47 @@ all the raw information being sent to/from the LLM in the conversation.
|
|||||||
You can also refer to the
|
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).
|
[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>claude-3-5-sonnet-20241022</td><td class='right'>1,630,102</td><td class='right'>88.9%</td></tr>
|
||||||
|
<tr><td>o1-preview</td><td class='right'>83,782</td><td class='right'>4.6%</td></tr>
|
||||||
|
<tr><td>gemini/REDACTED</td><td class='right'>82,572</td><td class='right'>4.5%</td></tr>
|
||||||
|
<tr><td>deepseek/deepseek-coder</td><td class='right'>24,628</td><td class='right'>1.3%</td></tr>
|
||||||
|
<tr><td>gpt-4o</td><td class='right'>9,243</td><td class='right'>0.5%</td></tr>
|
||||||
|
<tr><td>gpt-4o-mini</td><td class='right'>3,420</td><td class='right'>0.2%</td></tr>
|
||||||
|
<tr><td>mistral/REDACTED</td><td class='right'>620</td><td class='right'>0.0%</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{: .note :}
|
||||||
|
Some models show as REDACTED, because they are new or unpopular models.
|
||||||
|
Aider's analytics only records the names of "well known" LLMs.
|
||||||
|
<!--[[[end]]]-->
|
||||||
|
|
||||||
## How are the "aider wrote xx% of code" stats computed?
|
## How are the "aider wrote xx% of code" stats computed?
|
||||||
|
|
||||||
@@ -217,6 +261,18 @@ by doing something like `git blame` on the repo,
|
|||||||
and counting up who wrote all the new lines of code in each release.
|
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.
|
Only lines in source code files are counted, not documentation or prompt files.
|
||||||
|
|
||||||
|
## Why is the LLM speaking to me in an unexpected language?
|
||||||
|
|
||||||
|
Aider goes to some effort to prompt the model to use the language that is configured
|
||||||
|
for your system.
|
||||||
|
But LLMs aren't fully reliable, and they sometimes decide to speak in
|
||||||
|
an unexpected language.
|
||||||
|
Claude is especially fond of speaking French.
|
||||||
|
|
||||||
|
You can explicitly set the language that aider tells the model to use with
|
||||||
|
`--chat-language <language>`.
|
||||||
|
But the LLM may not comply.
|
||||||
|
|
||||||
## Can I share my aider chat transcript?
|
## Can I share my aider chat transcript?
|
||||||
|
|
||||||
Yes, you can now share aider chat logs in a pretty way.
|
Yes, you can now share aider chat logs in a pretty way.
|
||||||
|
|||||||
@@ -5,41 +5,84 @@ nav_order: 20
|
|||||||
description: How to install and get started pair programming with aider.
|
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 %}
|
{% include get-started.md %}
|
||||||
|
|
||||||
Or see the
|
If needed,
|
||||||
[full installation instructions](/docs/install/install.html)
|
aider-install will automatically install a separate version of python3.12 to use with aider.
|
||||||
for more details,
|
|
||||||
or the
|
There are some [optional install steps](/docs/install/optional.html) you could consider.
|
||||||
[usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
|
See the [usage instructions](https://aider.chat/docs/usage.html) to start coding with aider.
|
||||||
|
|
||||||
|
## Install with uv
|
||||||
|
|
||||||
|
A recommended way to install aider is with uv:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m pip install uv # If you need to install uv
|
||||||
|
uv tool install --python python3.12 aider-chat
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use uv to install aider with your existing python versions 3.8-3.13.
|
||||||
|
If needed,
|
||||||
|
uv will automatically install a separate version of python3.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
|
||||||
|
|
||||||
|
A recommended way to install aider is 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/).
|
||||||
|
|
||||||
|
|
||||||
|
## Install with pip
|
||||||
|
|
||||||
|
You can directly install aider with pip, but one of the above
|
||||||
|
methods is usually safer.
|
||||||
|
If you do 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 %}
|
{% include python-m-aider.md %}
|
||||||
|
|
||||||
<div class="video-container">
|
## Installing with package managers
|
||||||
<video controls poster="/assets/install.jpg">
|
|
||||||
<source src="/assets/install.mp4" type="video/mp4">
|
|
||||||
<a href="/assets/install.mp4">Installing aider</a>
|
|
||||||
</video>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
It's best to install aider using aider-install, uv or pipx as described above.
|
||||||
.video-container {
|
While aider is available in a number of system package managers,
|
||||||
position: relative;
|
they often install aider with incorrect dependencies.
|
||||||
padding-bottom: 76.2711864407%;
|
|
||||||
height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-container video {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
## 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.
|
You can use aider in GitHub Codespaces via the built-in Terminal pane.
|
||||||
See below for an example,
|
See below for an example,
|
||||||
but you can see the
|
but you can just follow the
|
||||||
[main install instructions](/docs/install.html)
|
[main install instructions](/docs/install.html)
|
||||||
for all the details.
|
inside your codespace terminal.
|
||||||
|
|
||||||
|
|
||||||
<div class="video-container">
|
<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
|
||||||
{: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.
|
and they will be loaded automatically whenever you run aider.
|
||||||
|
|
||||||
## Enable Playwright
|
## Enable Playwright
|
||||||
@@ -53,14 +72,19 @@ Installing PortAudio is completely optional, but can usually be accomplished lik
|
|||||||
- For Windows, there is no need to install PortAudio.
|
- For Windows, there is no need to install PortAudio.
|
||||||
- For Mac, do `brew install portaudio`
|
- For Mac, do `brew install portaudio`
|
||||||
- For Linux, do `sudo apt-get install libportaudio2`
|
- 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.
|
You can use
|
||||||
|
[aider's `--watch-files` mode](https://aider.chat/docs/usage/watch.html)
|
||||||
|
to integrate with any IDE or editor.
|
||||||
|
|
||||||
|
Other projects have made plugins for various IDE/editors.
|
||||||
It's not clear if they are tracking the latest
|
It's not clear if they are tracking the latest
|
||||||
versions of aider,
|
versions of aider,
|
||||||
so it may be best to just run the latest
|
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
|
### NeoVim
|
||||||
|
|
||||||
@@ -70,9 +94,9 @@ aider in a terminal alongside your editor.
|
|||||||
|
|
||||||
### VS Code
|
### VS Code
|
||||||
|
|
||||||
joshuavial also confirmed that aider works inside a VS Code terminal window.
|
You can run aider inside a VS Code terminal window.
|
||||||
Aider detects if it is running inside VSCode and turns off pretty/color output,
|
There are a number of 3rd party
|
||||||
since the VSCode terminal doesn't seem to support it well.
|
[aider plugins for VSCode](https://marketplace.visualstudio.com/search?term=aider%20-kodu&target=VSCode&category=All%20categories&sortBy=Relevance).
|
||||||
|
|
||||||
### Other editors
|
### Other editors
|
||||||
|
|
||||||
@@ -84,15 +108,8 @@ please let me know by opening a
|
|||||||
## Install the development version of aider
|
## Install the development version of aider
|
||||||
|
|
||||||
If you want the very latest 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 %}
|
||||||
@@ -62,7 +62,6 @@ cog.out(get_supported_languages_md())
|
|||||||
| cpp | .cc | ✓ | ✓ |
|
| cpp | .cc | ✓ | ✓ |
|
||||||
| cpp | .cpp | ✓ | ✓ |
|
| cpp | .cpp | ✓ | ✓ |
|
||||||
| css | .css | | ✓ |
|
| css | .css | | ✓ |
|
||||||
| dart | .dart | ✓ | ✓ |
|
|
||||||
| dockerfile | .dockerfile | | ✓ |
|
| dockerfile | .dockerfile | | ✓ |
|
||||||
| dot | .dot | | ✓ |
|
| dot | .dot | | ✓ |
|
||||||
| elisp | .el | ✓ | ✓ |
|
| elisp | .el | ✓ | ✓ |
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ The model also has to successfully apply all its changes to the source file with
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<canvas id="editChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
<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 src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script>
|
<script>
|
||||||
{% include edit-leaderboard.js %}
|
{% include edit-leaderboard.js %}
|
||||||
@@ -113,6 +114,7 @@ Therefore, results are available for fewer models.
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<canvas id="refacChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
<canvas id="refacChart" width="800" height="450" style="margin-top: 20px"></canvas>
|
||||||
|
<script src="https://unpkg.com/patternomaly/dist/patternomaly.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script>
|
<script>
|
||||||
{% include refactor-leaderboard.js %}
|
{% include refactor-leaderboard.js %}
|
||||||
@@ -181,6 +183,6 @@ mod_dates = [get_last_modified_date(file) for file in files]
|
|||||||
latest_mod_date = max(mod_dates)
|
latest_mod_date = max(mod_dates)
|
||||||
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
|
cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}")
|
||||||
]]]-->
|
]]]-->
|
||||||
November 24, 2024.
|
December 11, 2024.
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ We make reasonable efforts to protect your information by using physical and ele
|
|||||||
|
|
||||||
### Children’s Privacy
|
### 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
|
### International Visitors
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ if result.returncode == 0:
|
|||||||
date = datetime.datetime.fromtimestamp(timestamp)
|
date = datetime.datetime.fromtimestamp(timestamp)
|
||||||
cog.out(f"{date.strftime('%B %d, %Y.')}")
|
cog.out(f"{date.strftime('%B %d, %Y.')}")
|
||||||
]]]-->
|
]]]-->
|
||||||
October 31, 2024.
|
December 06, 2024.
|
||||||
<!--[[[end]]]-->
|
<!--[[[end]]]-->
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -39,12 +39,18 @@ export AWS_PROFILE=your-profile
|
|||||||
You can add these to your
|
You can add these to your
|
||||||
[.env file](/docs/config/dotenv.html).
|
[.env file](/docs/config/dotenv.html).
|
||||||
|
|
||||||
## Bedrock with `pipx` installation
|
## Install boto3
|
||||||
|
|
||||||
The AWS Bedrock provider requires the `boto3` package in order to function correctly. To use aider installed via `pipx` with AWS Bedrock, you must add the `boto3` dependency to aider's virtual environment by running
|
The AWS Bedrock provider requires the `boto3` package in order to function correctly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install boto3
|
||||||
```
|
```
|
||||||
pipx inject aider boto3
|
|
||||||
|
To use aider installed via `pipx` with AWS Bedrock, you must add the `boto3` dependency to aider's virtual environment by running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pipx inject aider-chat boto3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -56,12 +62,18 @@ Once your AWS credentials are set up, you can run Aider with the `--model` comma
|
|||||||
aider --model bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
|
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
|
## Available Models
|
||||||
|
|
||||||
To see some models available via Bedrock, run:
|
To see some models available via Bedrock, run:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
aider --list-models bedrock/
|
aider --list-models bedrock/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,17 @@ nav_order: 300
|
|||||||
|
|
||||||
# Gemini
|
# 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).
|
You'll need a [Gemini API key](https://aistudio.google.com/app/u/2/apikey).
|
||||||
|
|
||||||
```
|
```
|
||||||
python -m pip install -U aider-chat
|
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
|
export GEMINI_API_KEY=<key> # Mac/Linux
|
||||||
setx GEMINI_API_KEY <key> # Windows, restart shell after setx
|
setx GEMINI_API_KEY <key> # Windows, restart shell after setx
|
||||||
|
|
||||||
|
|||||||
@@ -96,5 +96,5 @@ coder = Coder.create(model=model, fnames=fnames, io=io)
|
|||||||
```
|
```
|
||||||
|
|
||||||
{: .note }
|
{: .note }
|
||||||
The scripting API is not officially supported or documented and may
|
The python scripting API is not officially supported or documented,
|
||||||
change without warning.
|
and could change in future releases without providing backwards compatibility.
|
||||||
|
|||||||
@@ -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.
|
> 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
|
python -m aider
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You should also consider
|
||||||
{% include venv-pipx.md %}
|
[installing aider using aider-install, uv or pipx](/docs/install.html).
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ nav_order: 28
|
|||||||
|
|
||||||
# Dependency versions
|
# 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.
|
correct versions of all of its required dependencies.
|
||||||
|
|
||||||
If you've been linked to this doc from a GitHub issue,
|
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
|
it is likely that your
|
||||||
aider install is using incorrect dependencies.
|
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
|
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,
|
This will ensure that aider is installed in its own python environment,
|
||||||
with the correct set of dependencies.
|
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 like Homebrew, AUR, ports
|
||||||
|
|
||||||
Package managers often install aider with the wrong dependencies, leading
|
Package managers often install aider with the wrong dependencies, leading
|
||||||
to import errors and other problems.
|
to import errors and other problems.
|
||||||
|
|
||||||
The recommended way to
|
It is recommended to
|
||||||
install aider is with
|
[install aider using aider-install, uv or pipx](/docs/install.html).
|
||||||
[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.
|
|
||||||
|
|
||||||
```
|
|
||||||
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
|
## Dependency versions matter
|
||||||
|
|
||||||
Aider pins its dependencies and is tested to work with those specific versions.
|
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
|
you should be careful about upgrading or downgrading the python packages that
|
||||||
aider uses.
|
aider uses.
|
||||||
|
|
||||||
@@ -64,9 +59,4 @@ and sometimes introduces bugs or backwards incompatible changes.
|
|||||||
|
|
||||||
## Replit
|
## Replit
|
||||||
|
|
||||||
You can `pip install -U aider-chat` on replit.
|
|
||||||
|
|
||||||
Or you can install aider with
|
|
||||||
pipx as follows:
|
|
||||||
|
|
||||||
{% include replit-pipx.md %}
|
{% 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
|
- Each model has limit on how many **output tokens** it can
|
||||||
produce.
|
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.
|
it has exceeded a token limit.
|
||||||
The error will include suggested actions to try and
|
The error will include suggested actions to try and
|
||||||
avoid hitting token limits.
|
avoid hitting token limits.
|
||||||
Here's an example error:
|
|
||||||
|
Here's an example error:
|
||||||
|
|
||||||
```
|
```
|
||||||
Model gpt-3.5-turbo has hit a token limit!
|
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 }
|
{: .note }
|
||||||
Aider never *enforces* token limits, it only *reports* token limit errors
|
Aider never *enforces* token limits, it only *reports* token limit errors
|
||||||
from the API provider.
|
from the API provider.
|
||||||
You probably don't need to
|
The token counts that aider reports are *estimates*.
|
||||||
[configure aider with the proper token limits](http://0.0.0.0:4000/docs/config/adv-model-settings.html#context-window-size-and-token-costs)
|
|
||||||
for unusual models.
|
|
||||||
|
|
||||||
## Input tokens & context window size
|
## Input tokens & context window size
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ cog.out(get_help_md())
|
|||||||
| **/code** | Ask for changes to your code |
|
| **/code** | Ask for changes to your code |
|
||||||
| **/commit** | Commit edits to the repo made outside the chat (commit message optional) |
|
| **/commit** | Commit edits to the repo made outside the chat (commit message optional) |
|
||||||
| **/copy** | Copy the last assistant message to the clipboard |
|
| **/copy** | Copy the last assistant message to the clipboard |
|
||||||
|
| **/copy-context** | Copy the current chat context as markdown, suitable to paste into a web UI |
|
||||||
| **/diff** | Display the diff of changes since the last message |
|
| **/diff** | Display the diff of changes since the last message |
|
||||||
| **/drop** | Remove files from the chat session to free up context space |
|
| **/drop** | Remove files from the chat session to free up context space |
|
||||||
| **/editor** | Open an editor to write a prompt |
|
| **/editor** | Open an editor to write a prompt |
|
||||||
@@ -42,9 +43,10 @@ cog.out(get_help_md())
|
|||||||
| **/map-refresh** | Force a refresh of the repository map |
|
| **/map-refresh** | Force a refresh of the repository map |
|
||||||
| **/model** | Switch to a new LLM |
|
| **/model** | Switch to a new LLM |
|
||||||
| **/models** | Search the list of available models |
|
| **/models** | Search the list of available models |
|
||||||
|
| **/multiline-mode** | Toggle multiline mode (swaps behavior of Enter and Meta+Enter) |
|
||||||
| **/paste** | Paste image/text from the clipboard into the chat. Optionally provide a name for the image. |
|
| **/paste** | Paste image/text from the clipboard into the chat. Optionally provide a name for the image. |
|
||||||
| **/quit** | Exit the application |
|
| **/quit** | Exit the application |
|
||||||
| **/read-only** | Add files to the chat that are for reference, not to be edited |
|
| **/read-only** | Add files to the chat that are for reference only, or turn added files to read-only |
|
||||||
| **/report** | Report a problem by opening a GitHub Issue |
|
| **/report** | Report a problem by opening a GitHub Issue |
|
||||||
| **/reset** | Drop all files and clear the chat history |
|
| **/reset** | Drop all files and clear the chat history |
|
||||||
| **/run** | Run a shell command and optionally add the output to the chat (alias: !) |
|
| **/run** | Run a shell command and optionally add the output to the chat (alias: !) |
|
||||||
@@ -77,8 +79,10 @@ The interactive prompt is built with [prompt-toolkit](https://github.com/prompt-
|
|||||||
|
|
||||||
### Emacs
|
### Emacs
|
||||||
|
|
||||||
- `Up Arrow` : Scroll back through previously sent messages.
|
- `Up Arrow` : Move up one line in the current message.
|
||||||
- `Down Arrow` : Scroll forward through previously sent messages.
|
- `Down Arrow` : Move down one line in the current message.
|
||||||
|
- `Ctrl-Up` : Scroll back through previously sent messages.
|
||||||
|
- `Ctrl-Down` : Scroll forward through previously sent messages.
|
||||||
- `Ctrl-A` : Move cursor to the start of the line.
|
- `Ctrl-A` : Move cursor to the start of the line.
|
||||||
- `Ctrl-B` : Move cursor back one character.
|
- `Ctrl-B` : Move cursor back one character.
|
||||||
- `Ctrl-D` : Delete the character under the cursor.
|
- `Ctrl-D` : Delete the character under the cursor.
|
||||||
@@ -95,8 +99,10 @@ The interactive prompt is built with [prompt-toolkit](https://github.com/prompt-
|
|||||||
|
|
||||||
To use vi/vim keybindings, run aider with the `--vim` switch.
|
To use vi/vim keybindings, run aider with the `--vim` switch.
|
||||||
|
|
||||||
- `Up Arrow` : Scroll back through previously sent messages.
|
- `Up Arrow` : Move up one line in the current message.
|
||||||
- `Down Arrow` : Scroll forward through previously sent messages.
|
- `Down Arrow` : Move down one line in the current message.
|
||||||
|
- `Ctrl-Up` : Scroll back through previously sent messages.
|
||||||
|
- `Ctrl-Down` : Scroll forward through previously sent messages.
|
||||||
- `Esc` : Switch to command mode.
|
- `Esc` : Switch to command mode.
|
||||||
- `i` : Switch to insert mode.
|
- `i` : Switch to insert mode.
|
||||||
- `a` : Move cursor one character to the right and switch to insert mode.
|
- `a` : Move cursor one character to the right and switch to insert mode.
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ or `aider --read CONVENTIONS.md`.
|
|||||||
This way it is marked as read-only, and cached if prompt caching
|
This way it is marked as read-only, and cached if prompt caching
|
||||||
is enabled.
|
is enabled.
|
||||||
|
|
||||||
|
## Community contributed conventions
|
||||||
|
|
||||||
|
You can check the [aider conventions repository](https://github.com/Aider-AI/conventions)
|
||||||
|
to find or contribute conventions files.
|
||||||
|
|
||||||
## Always load conventions
|
## Always load conventions
|
||||||
|
|
||||||
You can also configure aider to always load your conventions file
|
You can also configure aider to always load your conventions file
|
||||||
|
|||||||
121
aider/website/docs/usage/copypaste.md
Normal file
121
aider/website/docs/usage/copypaste.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
---
|
||||||
|
title: Copy/paste with web chat
|
||||||
|
#highlight_image: /assets/browser.jpg
|
||||||
|
parent: Usage
|
||||||
|
nav_order: 850
|
||||||
|
description: Aider works with LLM web chat UIs
|
||||||
|
---
|
||||||
|
|
||||||
|
# Copy/paste with web chat
|
||||||
|
|
||||||
|
<div class="video-container">
|
||||||
|
<video controls loop poster="/assets/copypaste.jpg">
|
||||||
|
<source src="/assets/copypaste.mp4" type="video/mp4">
|
||||||
|
<a href="/assets/copypaste.mp4">Aider browser UI demo video</a>
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.video-container {
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 66.34%; /* 2160 / 3256 = 0.6634 */
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container video {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
## Working with an LLM web chat
|
||||||
|
|
||||||
|
[Aider can connect to most LLMs via API](https://aider.chat/docs/llms.html) and works best that way.
|
||||||
|
But there are times when you may want to work with an LLM via its web chat interface:
|
||||||
|
|
||||||
|
- Workplace policies may limit your LLM usage to a proprietary web chat system.
|
||||||
|
- The web chat LLM may have access to unique context or may have been specially fine tuned for your task.
|
||||||
|
- It may be cost prohibitive to use some models via API.
|
||||||
|
- There may not be an API available.
|
||||||
|
|
||||||
|
Aider has features for working with an LLM via its web chat interface.
|
||||||
|
This allows you to use the web chat LLM as the "big brain code architect"
|
||||||
|
while running aider with a smaller, cheaper LLM to actually make changes
|
||||||
|
to your local files.
|
||||||
|
|
||||||
|
For this "file editor" part of the process
|
||||||
|
you can run aider with many open source, free or very inexpensive LLMs.
|
||||||
|
For example, the demo video above shows aider using DeepSeek to apply the changes
|
||||||
|
that o1-preview is suggesting in the web chat.
|
||||||
|
|
||||||
|
### Copy aider's code context to your clipboard, paste into the web UI
|
||||||
|
|
||||||
|
The `/copy-context <instructions>` command can be used in chat to copy aider's code context to your clipboard.
|
||||||
|
It will include:
|
||||||
|
|
||||||
|
- All the files which have been added to the chat via `/add`.
|
||||||
|
- Any read only files which have been added via `/read`.
|
||||||
|
- Aider's [repository map](https://aider.chat/docs/repomap.html) that brings in code context related to the above files from elsewhere in your git repo.
|
||||||
|
- Some instructions to the LLM that ask it to output change instructions concisely.
|
||||||
|
- If you include `<instructions>`, they will be copied too.
|
||||||
|
|
||||||
|
You can paste the context into your browser, and start interacting with the LLM web chat to
|
||||||
|
ask for code changes.
|
||||||
|
|
||||||
|
### Paste the LLM's reply back into aider to edit your files
|
||||||
|
|
||||||
|
Once the LLM has replied, you can use the "copy response" button in the web UI to copy
|
||||||
|
the LLM's response.
|
||||||
|
Back in aider, you can run `/paste` and aider will edit your files
|
||||||
|
to implement the changes suggested by the LLM.
|
||||||
|
|
||||||
|
You can use a cheap, efficient model like GPT-4o Mini, DeepSeek or Qwen to do these edits.
|
||||||
|
This works best if you run aider with `--edit-format editor-diff` or `--edit-format editor-whole`.
|
||||||
|
|
||||||
|
### Copy/paste mode
|
||||||
|
|
||||||
|
Aider has a `--copy-paste` mode that streamlines this entire process:
|
||||||
|
|
||||||
|
- Whenever you `/add` or `/read` files, aider will automatically copy the entire, updated
|
||||||
|
code context to your clipboard.
|
||||||
|
You'll see "Copied code context to clipboard" whenever this happens.
|
||||||
|
- When you copy the LLM reply to your clipboard outside aider, aider will automatically notice
|
||||||
|
and load it into the aider chat.
|
||||||
|
Just press ENTER to send the message
|
||||||
|
and aider will apply the LLMs changes to your local files.
|
||||||
|
- Aider will automatically select the best edit format for this copy/paste functionality.
|
||||||
|
Depending on the LLM you have aider use, it will be either `editor-whole` or `editor-diff`.
|
||||||
|
|
||||||
|
## Terms of service
|
||||||
|
|
||||||
|
Be sure to review the Terms Of Service of any LLM web chat service you use with
|
||||||
|
these features.
|
||||||
|
These features are not intended to be used in violation of any service's Terms Of Service (TOS).
|
||||||
|
|
||||||
|
Aider's web chat features have been designed to be compliant with the
|
||||||
|
terms of service of most LLM web chats.
|
||||||
|
|
||||||
|
There are 4 copy/paste steps involved when coding with an LLM web chat:
|
||||||
|
|
||||||
|
1. Copy code and context from aider.
|
||||||
|
2. Paste the code and context into the LLM web chat.
|
||||||
|
3. Copy the reply from the LLM web chat.
|
||||||
|
4. Paste the LLM reply into aider.
|
||||||
|
|
||||||
|
Most LLM web chat TOS prohibit automating steps (2) and (3) where code
|
||||||
|
is copied from and pasted into the web chat.
|
||||||
|
Aider's `--copy-paste` mode leaves those as 100% manual steps for the user to complete.
|
||||||
|
It simply streamlines steps (1) and (4) that are interactions with aider,
|
||||||
|
and which should not be under the scope of an LLM web chat TOS.
|
||||||
|
|
||||||
|
If you are concerned that
|
||||||
|
the automatic interactions with aider in steps (1) and (4) may be problematic with respect to
|
||||||
|
your LLM web chat provider's TOS, you can forego `--copy-paste` mode.
|
||||||
|
Instead, manually use the `/copy-context` and `/paste` commands if that
|
||||||
|
will keep you in compliance.
|
||||||
|
|
||||||
|
Again, do not use these features in violation of any service's Terms Of Service.
|
||||||
295
aider/website/docs/usage/watch.md
Normal file
295
aider/website/docs/usage/watch.md
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
---
|
||||||
|
title: Aider in your IDE
|
||||||
|
#highlight_image: /assets/browser.jpg
|
||||||
|
parent: Usage
|
||||||
|
nav_order: 750
|
||||||
|
description: Aider can run in your browser, not just on the command line.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Aider in your IDE
|
||||||
|
|
||||||
|
<div class="video-container">
|
||||||
|
<video controls loop poster="/assets/watch.jpg">
|
||||||
|
<source src="/assets/watch.mp4" type="video/mp4">
|
||||||
|
<a href="/assets/watch.mp4">Aider browser UI demo video</a>
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.video-container {
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 102.7%; /1.027 */
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container video {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
## AI comments
|
||||||
|
|
||||||
|
If you run aider with `--watch-files`, it will watch all files in your repo
|
||||||
|
and look for any AI coding instructions you add using your favorite IDE or text editor.
|
||||||
|
|
||||||
|
Specifically, aider looks for one-liner comments (# ... or // ...) that either start or end with `AI`, `AI!` or `AI?` like these:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Make a snake game. AI!
|
||||||
|
# What is the purpose of this method AI?
|
||||||
|
```
|
||||||
|
|
||||||
|
Or in `//` comment languages...
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Write a protein folding prediction engine. AI!
|
||||||
|
```
|
||||||
|
|
||||||
|
Aider will take note of all the comments that start or end with `AI`.
|
||||||
|
Comments that include `AI!` with an exclamation point or `AI?` with a question
|
||||||
|
mark are special.
|
||||||
|
They triggers aider to take action to collect *all* the AI comments and use them
|
||||||
|
as your instructions.
|
||||||
|
|
||||||
|
- `AI!` triggers aider to make changes to your code.
|
||||||
|
- `AI?` triggers aider to answer your question.
|
||||||
|
|
||||||
|
See the demo video above that shows aider working with AI comments in VSCode.
|
||||||
|
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
For example, if you included this AI comment in your code:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function factorial(n) // Implement this. AI!
|
||||||
|
```
|
||||||
|
|
||||||
|
Then aider would update the file and implement the function:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function factorial(n) {
|
||||||
|
if (n === 0 || n === 1) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return n * factorial(n - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Comment styles
|
||||||
|
|
||||||
|
Aider only watches for these types of **one-liner** comments:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Python and bash style
|
||||||
|
// Javascript style
|
||||||
|
-- SQL style
|
||||||
|
```
|
||||||
|
|
||||||
|
Aider will look for those comment types in all files.
|
||||||
|
You can use them into any code file you're editing, even if they aren't the
|
||||||
|
correct comment syntax for that language.
|
||||||
|
|
||||||
|
## Multiple uses
|
||||||
|
|
||||||
|
This capability is quite flexible and powerful, and can be used in many ways.
|
||||||
|
|
||||||
|
### In-context instructions
|
||||||
|
|
||||||
|
You can add an AI comment in the function you want changed,
|
||||||
|
explaining the change request in-context right where you want the changes.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
app.get('/sqrt/:n', (req, res) => {
|
||||||
|
const n = parseFloat(req.params.n);
|
||||||
|
|
||||||
|
// Add error handling for NaN and less than zero. AI!
|
||||||
|
|
||||||
|
const result = math.sqrt(n);
|
||||||
|
res.json({ result: result });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple comments
|
||||||
|
|
||||||
|
You can add multiple `AI` comments without the `!`,
|
||||||
|
before triggering aider with a final `AI!`.
|
||||||
|
Also keep in mind that you can spread the AI comments across
|
||||||
|
multiple files, if you want to coordinate changes in multiple places.
|
||||||
|
Just use `AI!` last, to trigger aider.
|
||||||
|
|
||||||
|
```python
|
||||||
|
@app.route('/factorial/<int:n>')
|
||||||
|
def factorial(n):
|
||||||
|
if n < 0:
|
||||||
|
return jsonify(error="Factorial is not defined for negative numbers"), 400
|
||||||
|
|
||||||
|
# AI: Refactor this code...
|
||||||
|
|
||||||
|
result = 1
|
||||||
|
for i in range(1, n + 1):
|
||||||
|
result *= i
|
||||||
|
|
||||||
|
# ... into to a compute_factorial() function. AI!
|
||||||
|
|
||||||
|
return jsonify(result=result)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Long form instructions
|
||||||
|
|
||||||
|
You can add a block of comments, with longer instructions.
|
||||||
|
Just be sure to start or end one of the lines with `AI` or `AI!` to draw
|
||||||
|
aider's attention to the block.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Make these changes: AI!
|
||||||
|
# - Add a proper main() function
|
||||||
|
# - Use Click to process cmd line args
|
||||||
|
# - Accept --host and --port args
|
||||||
|
# - Print a welcome message that includes the listening url
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(debug=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add a file to the aider chat
|
||||||
|
|
||||||
|
Rather than using `/add` to add a file inside the aider chat, you can
|
||||||
|
simply put an `#AI` comment in it and save the file.
|
||||||
|
You can undo/remove the comment immediately if you like, the file
|
||||||
|
will still be added to the aider chat.
|
||||||
|
|
||||||
|
## Also use aider chat in the terminal
|
||||||
|
|
||||||
|
It can be really helpful to get a change started with AI comments.
|
||||||
|
But sometimes you want to build on or refine those changes.
|
||||||
|
You can of course continue to do that with AI comments,
|
||||||
|
but it can sometimes be effective to switch over to the aider terminal chat.
|
||||||
|
The chat has the history of the AI comments you just made,
|
||||||
|
so you can continue on naturally from there.
|
||||||
|
|
||||||
|
You can also use the normal aider chat in your terminal to work with
|
||||||
|
many of aider's more advanced features:
|
||||||
|
|
||||||
|
- Use `/undo` to revert changes you don't like. Although you may also be able to use your IDE's undo function to step back in the file history.
|
||||||
|
- Use [chat modes](https://aider.chat/docs/usage/modes.html) to ask questions or get help.
|
||||||
|
- Manage the chat context with `/tokens`, `/clear`, `/drop`, `/reset`.
|
||||||
|
Adding an AI comment will add the file to the chat.
|
||||||
|
Periodically, you may want remove extra context that is no longer needed.
|
||||||
|
- [Fix lint and test errors](https://aider.chat/docs/usage/lint-test.html).
|
||||||
|
- Run shell commands.
|
||||||
|
- Etc.
|
||||||
|
|
||||||
|
|
||||||
|
## You can be lazy
|
||||||
|
|
||||||
|
The examples above all show AI
|
||||||
|
comments with full sentences, proper capitalization, punctuation, etc.
|
||||||
|
This was done to help explain how AI comments work, but is not needed in practice.
|
||||||
|
|
||||||
|
Most LLMs are perfectly capable of dealing with ambiguity and
|
||||||
|
inferring implied intent.
|
||||||
|
This often allows you to be quite lazy with your AI comments.
|
||||||
|
In particular, you can start and end comments with lowercase `ai` and `ai!`,
|
||||||
|
but you can also be much more terse with the request itself.
|
||||||
|
Below are simpler versions of some of the examples given above.
|
||||||
|
|
||||||
|
When the context clearly implies the needed action, `ai!` might be all you
|
||||||
|
need. For example, to implement a factorial function
|
||||||
|
in a program full of other math functions either of these
|
||||||
|
approaches would probably work:
|
||||||
|
|
||||||
|
```js
|
||||||
|
function factorial(n) // ai!
|
||||||
|
```
|
||||||
|
|
||||||
|
Or...
|
||||||
|
|
||||||
|
```js
|
||||||
|
// add factorial() ai!
|
||||||
|
```
|
||||||
|
|
||||||
|
Rather than a long, explicit comment like "Add error handling for NaN and less than zero,"
|
||||||
|
you can let aider infer more about the request.
|
||||||
|
This simpler comment may be sufficient:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
app.get('/sqrt/:n', (req, res) => {
|
||||||
|
const n = parseFloat(req.params.n);
|
||||||
|
|
||||||
|
// add error handling ai!
|
||||||
|
|
||||||
|
const result = math.sqrt(n);
|
||||||
|
res.json({ result: result });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Similarly, this refactor probably could have been requested with fewer words, like this:
|
||||||
|
|
||||||
|
```python
|
||||||
|
@app.route('/factorial/<int:n>')
|
||||||
|
def factorial(n):
|
||||||
|
if n < 0:
|
||||||
|
return jsonify(error="Factorial is not defined for negative numbers"), 400
|
||||||
|
|
||||||
|
# ai refactor...
|
||||||
|
|
||||||
|
result = 1
|
||||||
|
for i in range(1, n + 1):
|
||||||
|
result *= i
|
||||||
|
|
||||||
|
# ... to compute_factorial() ai!
|
||||||
|
|
||||||
|
return jsonify(result=result)
|
||||||
|
```
|
||||||
|
|
||||||
|
As you use aider with your chosen LLM, you can develop a sense for how
|
||||||
|
explicit you need to make your AI comments.
|
||||||
|
|
||||||
|
## Behind the scenes
|
||||||
|
|
||||||
|
Aider sends your AI comments to the LLM with the
|
||||||
|
[repo map](https://aider.chat/docs/repomap.html)
|
||||||
|
and all the other code context you've added to the chat.
|
||||||
|
|
||||||
|
It also pulls out and highlights the AI comments with specific context, showing the LLM
|
||||||
|
exactly how they fit into the code base.
|
||||||
|
|
||||||
|
```
|
||||||
|
The "AI" comments below marked with █ can be found in the code files I've shared with you.
|
||||||
|
They contain your instructions.
|
||||||
|
Make the requested changes.
|
||||||
|
Be sure to remove all these "AI" comments from the code!
|
||||||
|
|
||||||
|
todo_app.py:
|
||||||
|
⋮...
|
||||||
|
│class TodoList:
|
||||||
|
⋮...
|
||||||
|
│ def __init__(self):
|
||||||
|
│ """Initialize an empty todo list"""
|
||||||
|
⋮...
|
||||||
|
│
|
||||||
|
│ def list_tasks(self):
|
||||||
|
│ """Display all tasks"""
|
||||||
|
█ # Implement this. AI!
|
||||||
|
│
|
||||||
|
│def main():
|
||||||
|
│ todo = TodoList()
|
||||||
|
│
|
||||||
|
⋮...
|
||||||
|
```
|
||||||
|
|
||||||
|
--------
|
||||||
|
|
||||||
|
#### Credits
|
||||||
|
|
||||||
|
*This feature was inspired by
|
||||||
|
the way [Override](https://github.com/oi-overide) watches for file changes
|
||||||
|
to find prompts embedded within `//> a specific set of delimiters <//`.*
|
||||||
|
|
||||||
@@ -70,28 +70,27 @@ Aider works best with GPT-4o & Claude 3.5 Sonnet and can
|
|||||||
cog.out(open("aider/website/_includes/get-started.md").read())
|
cog.out(open("aider/website/_includes/get-started.md").read())
|
||||||
-->
|
-->
|
||||||
|
|
||||||
You can get started quickly like this:
|
You can get started quickly like this, with python 3.8-3.13:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
python -m pip install -U aider-chat
|
python -m pip install aider-install
|
||||||
|
aider-install
|
||||||
|
|
||||||
# Change directory into a git repo
|
# Change directory into your code base
|
||||||
cd /to/your/git/repo
|
cd /to/your/git/repo
|
||||||
|
|
||||||
# Work with Claude 3.5 Sonnet on your repo
|
# Work with Claude 3.5 Sonnet on your repo
|
||||||
export ANTHROPIC_API_KEY=your-key-goes-here
|
aider --model sonnet --anthropic-api-key your-key-goes-here
|
||||||
aider
|
|
||||||
|
|
||||||
# Work with GPT-4o on your repo
|
# Work with GPT-4o on your repo
|
||||||
export OPENAI_API_KEY=your-key-goes-here
|
aider --model gpt-4o --openai-api-key your-key-goes-here
|
||||||
aider
|
|
||||||
```
|
```
|
||||||
<!-- NOOP -->
|
<!-- NOOP -->
|
||||||
|
|
||||||
See the
|
See the
|
||||||
[installation instructions](https://aider.chat/docs/install.html)
|
[installation instructions](https://aider.chat/docs/install.html)
|
||||||
and other
|
and
|
||||||
[documentation](https://aider.chat/docs/usage.html)
|
[usage documentation](https://aider.chat/docs/usage.html)
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ from dotenv import load_dotenv
|
|||||||
from plots import plot_refactoring
|
from plots import plot_refactoring
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from aider import models
|
from aider import models, sendchat
|
||||||
from aider.coders import Coder
|
from aider.coders import Coder, base_coder
|
||||||
from aider.dump import dump # noqa: F401
|
from aider.dump import dump # noqa: F401
|
||||||
from aider.io import InputOutput
|
from aider.io import InputOutput
|
||||||
|
|
||||||
@@ -47,10 +47,44 @@ def find_latest_benchmark_dir():
|
|||||||
print("Error: No benchmark directories found under tmp.benchmarks.")
|
print("Error: No benchmark directories found under tmp.benchmarks.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
latest_dir = max(
|
# Get current time and 24 hours ago
|
||||||
benchmark_dirs,
|
now = datetime.datetime.now()
|
||||||
key=lambda d: next((f.stat().st_mtime for f in d.rglob("*.md") if f.is_file()), 0),
|
day_ago = now - datetime.timedelta(days=1)
|
||||||
)
|
|
||||||
|
# Filter directories by name pattern YYYY-MM-DD-HH-MM-SS--
|
||||||
|
recent_dirs = []
|
||||||
|
for d in benchmark_dirs:
|
||||||
|
try:
|
||||||
|
# Extract datetime from directory name
|
||||||
|
date_str = d.name[:19] # Takes YYYY-MM-DD-HH-MM-SS
|
||||||
|
dir_date = datetime.datetime.strptime(date_str, "%Y-%m-%d-%H-%M-%S")
|
||||||
|
if dir_date >= day_ago:
|
||||||
|
recent_dirs.append(d)
|
||||||
|
except ValueError:
|
||||||
|
# Skip directories that don't match the expected format
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not recent_dirs:
|
||||||
|
print("Error: No benchmark directories found from the last 24 hours.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Find directory with most recently modified .md file
|
||||||
|
latest_dir = None
|
||||||
|
latest_time = 0
|
||||||
|
|
||||||
|
for d in recent_dirs:
|
||||||
|
# Look for .md files in subdirectories
|
||||||
|
for md_file in d.glob("*/.*.md"):
|
||||||
|
if md_file.is_file():
|
||||||
|
mtime = md_file.stat().st_mtime
|
||||||
|
if mtime > latest_time:
|
||||||
|
latest_time = mtime
|
||||||
|
latest_dir = d
|
||||||
|
|
||||||
|
if not latest_dir:
|
||||||
|
print("Error: No .md files found in recent benchmark directories.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
print(f"Using the most recently updated benchmark directory: {latest_dir.name}")
|
print(f"Using the most recently updated benchmark directory: {latest_dir.name}")
|
||||||
return latest_dir
|
return latest_dir
|
||||||
|
|
||||||
@@ -124,6 +158,9 @@ def main(
|
|||||||
dirnames: Optional[List[str]] = typer.Argument(None, help="Directory names"),
|
dirnames: Optional[List[str]] = typer.Argument(None, help="Directory names"),
|
||||||
graphs: bool = typer.Option(False, "--graphs", help="Generate graphs"),
|
graphs: bool = typer.Option(False, "--graphs", help="Generate graphs"),
|
||||||
model: str = typer.Option("gpt-3.5-turbo", "--model", "-m", help="Model name"),
|
model: str = typer.Option("gpt-3.5-turbo", "--model", "-m", help="Model name"),
|
||||||
|
sleep: float = typer.Option(
|
||||||
|
0, "--sleep", help="Sleep seconds between tests when single threaded"
|
||||||
|
),
|
||||||
edit_format: str = typer.Option(None, "--edit-format", "-e", help="Edit format"),
|
edit_format: str = typer.Option(None, "--edit-format", "-e", help="Edit format"),
|
||||||
editor_model: str = typer.Option(None, "--editor-model", help="Editor model name"),
|
editor_model: str = typer.Option(None, "--editor-model", help="Editor model name"),
|
||||||
editor_edit_format: str = typer.Option(None, "--editor-edit-format", help="Editor edit format"),
|
editor_edit_format: str = typer.Option(None, "--editor-edit-format", help="Editor edit format"),
|
||||||
@@ -233,6 +270,11 @@ def main(
|
|||||||
if num_tests > 0:
|
if num_tests > 0:
|
||||||
test_dnames = test_dnames[:num_tests]
|
test_dnames = test_dnames[:num_tests]
|
||||||
|
|
||||||
|
# Don't give up when benchmarking
|
||||||
|
LONG_TIMEOUT = 24 * 60 * 60
|
||||||
|
sendchat.RETRY_TIMEOUT = LONG_TIMEOUT
|
||||||
|
base_coder.RETRY_TIMEOUT = LONG_TIMEOUT
|
||||||
|
|
||||||
if threads == 1:
|
if threads == 1:
|
||||||
all_results = []
|
all_results = []
|
||||||
for testname in test_dnames:
|
for testname in test_dnames:
|
||||||
@@ -251,10 +293,13 @@ def main(
|
|||||||
editor_model,
|
editor_model,
|
||||||
editor_edit_format,
|
editor_edit_format,
|
||||||
num_ctx,
|
num_ctx,
|
||||||
|
sleep,
|
||||||
)
|
)
|
||||||
|
|
||||||
all_results.append(results)
|
all_results.append(results)
|
||||||
summarize_results(dirname)
|
summarize_results(dirname)
|
||||||
|
if sleep:
|
||||||
|
time.sleep(sleep)
|
||||||
else:
|
else:
|
||||||
run_test_threaded = lox.thread(threads)(run_test)
|
run_test_threaded = lox.thread(threads)(run_test)
|
||||||
for testname in test_dnames:
|
for testname in test_dnames:
|
||||||
@@ -531,6 +576,7 @@ def run_test_real(
|
|||||||
editor_model,
|
editor_model,
|
||||||
editor_edit_format,
|
editor_edit_format,
|
||||||
num_ctx=None,
|
num_ctx=None,
|
||||||
|
sleep=0,
|
||||||
):
|
):
|
||||||
if not os.path.isdir(testdir):
|
if not os.path.isdir(testdir):
|
||||||
print("Not a dir:", testdir)
|
print("Not a dir:", testdir)
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
# [[[cog
|
|
||||||
# from aider.help_pats import exclude_website_pats
|
|
||||||
# ]]]
|
|
||||||
# [[[end]]]
|
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "aider-chat"
|
name = "aider-chat"
|
||||||
@@ -38,36 +34,18 @@ help = { file = "requirements/requirements-help.txt" }
|
|||||||
browser = { file = "requirements/requirements-browser.txt" }
|
browser = { file = "requirements/requirements-browser.txt" }
|
||||||
playwright = { file = "requirements/requirements-playwright.txt" }
|
playwright = { file = "requirements/requirements-playwright.txt" }
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
include-package-data = true
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
include = ["aider*", "aider.website"]
|
include = ["aider"]
|
||||||
|
|
||||||
[tool.setuptools.package-data]
|
|
||||||
"aider" = ["queries/*.scm"]
|
|
||||||
"aider.website" = ["**/*.md"]
|
|
||||||
|
|
||||||
[tool.setuptools.exclude-package-data]
|
|
||||||
"aider.website" = [
|
|
||||||
# [[[cog
|
|
||||||
# cog.out("\n".join(f' "{pat}",' for pat in exclude_website_pats))
|
|
||||||
# ]]]
|
|
||||||
"examples/**",
|
|
||||||
"_posts/**",
|
|
||||||
"HISTORY.md",
|
|
||||||
"docs/benchmarks*md",
|
|
||||||
"docs/ctags.md",
|
|
||||||
"docs/unified-diffs.md",
|
|
||||||
"docs/leaderboards/index.md",
|
|
||||||
"assets/**",
|
|
||||||
"**/.DS_Store",
|
|
||||||
# [[[end]]]
|
|
||||||
]
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=68", "setuptools_scm[toml]>=8"]
|
requires = ["setuptools>=68", "setuptools_scm[toml]>=8"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[tool.setuptools_scm]
|
[tool.setuptools_scm]
|
||||||
write_to = "aider/__version__.py"
|
write_to = "aider/_version.py"
|
||||||
|
|
||||||
[tool.codespell]
|
[tool.codespell]
|
||||||
skip = "*.svg,Gemfile.lock"
|
skip = "*.svg,Gemfile.lock"
|
||||||
|
|||||||
@@ -6,5 +6,7 @@ testpaths =
|
|||||||
tests/help
|
tests/help
|
||||||
tests/browser
|
tests/browser
|
||||||
tests/scrape
|
tests/scrape
|
||||||
|
|
||||||
|
env =
|
||||||
|
AIDER_ANALYTICS=false
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,21 @@
|
|||||||
# This file is autogenerated by pip-compile with Python 3.12
|
# This file is autogenerated by pip-compile with Python 3.12
|
||||||
# by the following command:
|
# by the following command:
|
||||||
#
|
#
|
||||||
# pip-compile --output-file=requirements.txt requirements/requirements.in
|
# pip-compile --allow-unsafe --output-file=requirements.txt requirements/requirements.in
|
||||||
#
|
#
|
||||||
aiohappyeyeballs==2.4.3
|
aiohappyeyeballs==2.4.4
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
aiohttp==3.11.7
|
aiohttp==3.11.10
|
||||||
# via litellm
|
# via litellm
|
||||||
aiosignal==1.3.1
|
aiosignal==1.3.1
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
annotated-types==0.7.0
|
annotated-types==0.7.0
|
||||||
# via pydantic
|
# via pydantic
|
||||||
anyio==4.6.2.post1
|
anyio==4.7.0
|
||||||
# via
|
# via
|
||||||
# httpx
|
# httpx
|
||||||
# openai
|
# openai
|
||||||
|
# watchfiles
|
||||||
attrs==24.2.0
|
attrs==24.2.0
|
||||||
# via
|
# via
|
||||||
# aiohttp
|
# aiohttp
|
||||||
@@ -62,15 +63,17 @@ gitdb==4.0.11
|
|||||||
# via gitpython
|
# via gitpython
|
||||||
gitpython==3.1.43
|
gitpython==3.1.43
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
grep-ast==0.4.0
|
grep-ast==0.4.1
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
h11==0.14.0
|
h11==0.14.0
|
||||||
# via httpcore
|
# via httpcore
|
||||||
httpcore==1.0.7
|
httpcore==1.0.7
|
||||||
# via httpx
|
# via httpx
|
||||||
httpx==0.27.2
|
httpx==0.27.2
|
||||||
# via openai
|
# via
|
||||||
huggingface-hub==0.26.2
|
# litellm
|
||||||
|
# openai
|
||||||
|
huggingface-hub==0.26.5
|
||||||
# via tokenizers
|
# via tokenizers
|
||||||
idna==3.10
|
idna==3.10
|
||||||
# via
|
# via
|
||||||
@@ -86,9 +89,9 @@ importlib-resources==6.4.5
|
|||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
jinja2==3.1.4
|
jinja2==3.1.4
|
||||||
# via litellm
|
# via litellm
|
||||||
jiter==0.7.1
|
jiter==0.8.0
|
||||||
# via openai
|
# via openai
|
||||||
json5==0.9.28
|
json5==0.10.0
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
jsonschema==4.23.0
|
jsonschema==4.23.0
|
||||||
# via
|
# via
|
||||||
@@ -96,7 +99,7 @@ jsonschema==4.23.0
|
|||||||
# litellm
|
# litellm
|
||||||
jsonschema-specifications==2024.10.1
|
jsonschema-specifications==2024.10.1
|
||||||
# via jsonschema
|
# via jsonschema
|
||||||
litellm==1.52.16
|
litellm==1.53.9
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
markdown-it-py==3.0.0
|
markdown-it-py==3.0.0
|
||||||
# via rich
|
# via rich
|
||||||
@@ -120,7 +123,7 @@ numpy==1.26.4
|
|||||||
# via
|
# via
|
||||||
# -r requirements/requirements.in
|
# -r requirements/requirements.in
|
||||||
# scipy
|
# scipy
|
||||||
openai==1.55.1
|
openai==1.57.0
|
||||||
# via litellm
|
# via litellm
|
||||||
packaging==24.2
|
packaging==24.2
|
||||||
# via
|
# via
|
||||||
@@ -134,11 +137,11 @@ pexpect==4.9.0
|
|||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
pillow==10.4.0
|
pillow==10.4.0
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
posthog==3.7.3
|
posthog==3.7.4
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
prompt-toolkit==3.0.48
|
prompt-toolkit==3.0.48
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
propcache==0.2.0
|
propcache==0.2.1
|
||||||
# via
|
# via
|
||||||
# aiohttp
|
# aiohttp
|
||||||
# yarl
|
# yarl
|
||||||
@@ -150,7 +153,7 @@ pycodestyle==2.12.1
|
|||||||
# via flake8
|
# via flake8
|
||||||
pycparser==2.22
|
pycparser==2.22
|
||||||
# via cffi
|
# via cffi
|
||||||
pydantic==2.10.2
|
pydantic==2.10.3
|
||||||
# via
|
# via
|
||||||
# litellm
|
# litellm
|
||||||
# openai
|
# openai
|
||||||
@@ -189,13 +192,13 @@ requests==2.32.3
|
|||||||
# tiktoken
|
# tiktoken
|
||||||
rich==13.9.4
|
rich==13.9.4
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
rpds-py==0.21.0
|
rpds-py==0.22.3
|
||||||
# via
|
# via
|
||||||
# jsonschema
|
# jsonschema
|
||||||
# referencing
|
# referencing
|
||||||
scipy==1.13.1
|
scipy==1.13.1
|
||||||
# via -r requirements/requirements.in
|
# via -r requirements/requirements.in
|
||||||
six==1.16.0
|
six==1.17.0
|
||||||
# via
|
# via
|
||||||
# mixpanel
|
# mixpanel
|
||||||
# posthog
|
# posthog
|
||||||
@@ -231,6 +234,7 @@ tree-sitter-languages==1.10.2
|
|||||||
# via grep-ast
|
# via grep-ast
|
||||||
typing-extensions==4.12.2
|
typing-extensions==4.12.2
|
||||||
# via
|
# via
|
||||||
|
# anyio
|
||||||
# huggingface-hub
|
# huggingface-hub
|
||||||
# openai
|
# openai
|
||||||
# pydantic
|
# pydantic
|
||||||
@@ -239,9 +243,15 @@ urllib3==2.2.3
|
|||||||
# via
|
# via
|
||||||
# mixpanel
|
# mixpanel
|
||||||
# requests
|
# requests
|
||||||
|
watchfiles==1.0.0
|
||||||
|
# via -r requirements/requirements.in
|
||||||
wcwidth==0.2.13
|
wcwidth==0.2.13
|
||||||
# via prompt-toolkit
|
# via prompt-toolkit
|
||||||
yarl==1.18.0
|
yarl==1.18.3
|
||||||
# via aiohttp
|
# via aiohttp
|
||||||
zipp==3.21.0
|
zipp==3.21.0
|
||||||
# via importlib-metadata
|
# via importlib-metadata
|
||||||
|
|
||||||
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
|
pip==24.3.1
|
||||||
|
# via -r requirements/requirements.in
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# This file is autogenerated by pip-compile with Python 3.12
|
# This file is autogenerated by pip-compile with Python 3.12
|
||||||
# by the following command:
|
# by the following command:
|
||||||
#
|
#
|
||||||
# pip-compile --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --constraint=requirements/requirements-help.txt --output-file=requirements/requirements-browser.txt requirements/requirements-browser.in
|
# pip-compile --allow-unsafe --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --constraint=requirements/requirements-help.txt --output-file=requirements/requirements-browser.txt requirements/requirements-browser.in
|
||||||
#
|
#
|
||||||
altair==5.5.0
|
altair==5.5.0
|
||||||
# via streamlit
|
# via streamlit
|
||||||
@@ -92,7 +92,7 @@ mdurl==0.1.2
|
|||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# -c requirements/requirements-dev.txt
|
# -c requirements/requirements-dev.txt
|
||||||
# markdown-it-py
|
# markdown-it-py
|
||||||
narwhals==1.14.2
|
narwhals==1.16.0
|
||||||
# via altair
|
# via altair
|
||||||
numpy==1.26.4
|
numpy==1.26.4
|
||||||
# via
|
# via
|
||||||
@@ -122,7 +122,7 @@ pillow==10.4.0
|
|||||||
# -c requirements/requirements-dev.txt
|
# -c requirements/requirements-dev.txt
|
||||||
# -c requirements/requirements-help.txt
|
# -c requirements/requirements-help.txt
|
||||||
# streamlit
|
# streamlit
|
||||||
protobuf==5.28.3
|
protobuf==5.29.1
|
||||||
# via streamlit
|
# via streamlit
|
||||||
pyarrow==18.1.0
|
pyarrow==18.1.0
|
||||||
# via streamlit
|
# via streamlit
|
||||||
@@ -163,13 +163,13 @@ rich==13.9.4
|
|||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# -c requirements/requirements-dev.txt
|
# -c requirements/requirements-dev.txt
|
||||||
# streamlit
|
# streamlit
|
||||||
rpds-py==0.21.0
|
rpds-py==0.22.3
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# jsonschema
|
# jsonschema
|
||||||
# referencing
|
# referencing
|
||||||
six==1.16.0
|
six==1.17.0
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
# pip-compile --output-file=requirements-dev.txt requirements-dev.in --upgrade
|
# pip-compile --output-file=requirements-dev.txt requirements-dev.in --upgrade
|
||||||
#
|
#
|
||||||
pytest
|
pytest
|
||||||
|
pytest-env
|
||||||
pip-tools
|
pip-tools
|
||||||
lox
|
lox
|
||||||
matplotlib
|
matplotlib
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# This file is autogenerated by pip-compile with Python 3.12
|
# This file is autogenerated by pip-compile with Python 3.12
|
||||||
# by the following command:
|
# by the following command:
|
||||||
#
|
#
|
||||||
# pip-compile --constraint=requirements.txt --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in
|
# pip-compile --allow-unsafe --constraint=requirements.txt --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in
|
||||||
#
|
#
|
||||||
alabaster==1.0.0
|
alabaster==1.0.0
|
||||||
# via sphinx
|
# via sphinx
|
||||||
@@ -51,7 +51,7 @@ filelock==3.16.1
|
|||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# virtualenv
|
# virtualenv
|
||||||
fonttools==4.55.0
|
fonttools==4.55.2
|
||||||
# via matplotlib
|
# via matplotlib
|
||||||
identify==2.6.3
|
identify==2.6.3
|
||||||
# via pre-commit
|
# via pre-commit
|
||||||
@@ -85,7 +85,7 @@ markupsafe==3.0.2
|
|||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# jinja2
|
# jinja2
|
||||||
matplotlib==3.9.2
|
matplotlib==3.9.3
|
||||||
# via -r requirements/requirements-dev.in
|
# via -r requirements/requirements-dev.in
|
||||||
mdurl==0.1.2
|
mdurl==0.1.2
|
||||||
# via
|
# via
|
||||||
@@ -144,7 +144,11 @@ pyproject-hooks==1.2.0
|
|||||||
# via
|
# via
|
||||||
# build
|
# build
|
||||||
# pip-tools
|
# pip-tools
|
||||||
pytest==8.3.3
|
pytest==8.3.4
|
||||||
|
# via
|
||||||
|
# -r requirements/requirements-dev.in
|
||||||
|
# pytest-env
|
||||||
|
pytest-env==1.1.5
|
||||||
# via -r requirements/requirements-dev.in
|
# via -r requirements/requirements-dev.in
|
||||||
python-dateutil==2.9.0.post0
|
python-dateutil==2.9.0.post0
|
||||||
# via
|
# via
|
||||||
@@ -173,7 +177,7 @@ semver==3.0.2
|
|||||||
# via -r requirements/requirements-dev.in
|
# via -r requirements/requirements-dev.in
|
||||||
shellingham==1.5.4
|
shellingham==1.5.4
|
||||||
# via typer
|
# via typer
|
||||||
six==1.16.0
|
six==1.17.0
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
@@ -200,7 +204,7 @@ sphinxcontrib-qthelp==2.0.0
|
|||||||
# via sphinx
|
# via sphinx
|
||||||
sphinxcontrib-serializinghtml==2.0.0
|
sphinxcontrib-serializinghtml==2.0.0
|
||||||
# via sphinx
|
# via sphinx
|
||||||
typer==0.13.1
|
typer==0.15.1
|
||||||
# via -r requirements/requirements-dev.in
|
# via -r requirements/requirements-dev.in
|
||||||
typing-extensions==4.12.2
|
typing-extensions==4.12.2
|
||||||
# via
|
# via
|
||||||
@@ -220,5 +224,10 @@ wheel==0.45.1
|
|||||||
# via pip-tools
|
# via pip-tools
|
||||||
|
|
||||||
# The following packages are considered to be unsafe in a requirements file:
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
# pip
|
pip==24.3.1
|
||||||
# setuptools
|
# via
|
||||||
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
|
# -c requirements.txt
|
||||||
|
# pip-tools
|
||||||
|
setuptools==75.6.0
|
||||||
|
# via pip-tools
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
# This file is autogenerated by pip-compile with Python 3.12
|
# This file is autogenerated by pip-compile with Python 3.12
|
||||||
# by the following command:
|
# by the following command:
|
||||||
#
|
#
|
||||||
# pip-compile --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --output-file=requirements/requirements-help.txt requirements/requirements-help.in
|
# pip-compile --allow-unsafe --constraint=requirements.txt --constraint=requirements/requirements-dev.txt --output-file=requirements/requirements-help.txt requirements/requirements-help.in
|
||||||
#
|
#
|
||||||
aiohappyeyeballs==2.4.3
|
aiohappyeyeballs==2.4.4
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# aiohttp
|
# aiohttp
|
||||||
aiohttp==3.11.7
|
aiohttp==3.11.10
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
@@ -25,7 +25,7 @@ annotated-types==0.7.0
|
|||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# pydantic
|
# pydantic
|
||||||
anyio==4.6.2.post1
|
anyio==4.7.0
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
@@ -103,7 +103,7 @@ httpx==0.27.2
|
|||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# llama-index-core
|
# llama-index-core
|
||||||
huggingface-hub[inference]==0.26.2
|
huggingface-hub[inference]==0.26.5
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
@@ -188,13 +188,13 @@ pillow==10.4.0
|
|||||||
# -c requirements/requirements-dev.txt
|
# -c requirements/requirements-dev.txt
|
||||||
# llama-index-core
|
# llama-index-core
|
||||||
# sentence-transformers
|
# sentence-transformers
|
||||||
propcache==0.2.0
|
propcache==0.2.1
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# aiohttp
|
# aiohttp
|
||||||
# yarl
|
# yarl
|
||||||
pydantic==2.10.2
|
pydantic==2.10.3
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
@@ -284,6 +284,7 @@ typing-extensions==4.12.2
|
|||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
# -c requirements/requirements-dev.txt
|
# -c requirements/requirements-dev.txt
|
||||||
|
# anyio
|
||||||
# huggingface-hub
|
# huggingface-hub
|
||||||
# llama-index-core
|
# llama-index-core
|
||||||
# pydantic
|
# pydantic
|
||||||
@@ -305,7 +306,7 @@ wrapt==1.17.0
|
|||||||
# via
|
# via
|
||||||
# deprecated
|
# deprecated
|
||||||
# llama-index-core
|
# llama-index-core
|
||||||
yarl==1.18.0
|
yarl==1.18.3
|
||||||
# via
|
# via
|
||||||
# -c /Users/gauthier/Projects/aider/requirements.txt
|
# -c /Users/gauthier/Projects/aider/requirements.txt
|
||||||
# -c requirements.txt
|
# -c requirements.txt
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user