mirror of
https://github.com/Aider-AI/aider
synced 2026-04-26 01:25:17 +02:00
Compare commits
2664 Commits
v0.62.2.de
...
v0.76.2.de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cb6ec9ddb | ||
|
|
c21619608e | ||
|
|
76a8789bc1 | ||
|
|
bbf538e06c | ||
|
|
d94ab3395b | ||
|
|
6d8457a61f | ||
|
|
303f8e1bc9 | ||
|
|
e638116a2f | ||
|
|
5bac9133e6 | ||
|
|
6fde4041ba | ||
|
|
d0c8b38ffc | ||
|
|
be7888ab18 | ||
|
|
11b71fa28c | ||
|
|
c838f9bfd5 | ||
|
|
8d073ce221 | ||
|
|
0be5d39453 | ||
|
|
74ecdf2d3f | ||
|
|
20eacfab0f | ||
|
|
0396e15a3b | ||
|
|
3432a936ea | ||
|
|
87cd2b5dfe | ||
|
|
313b91edbe | ||
|
|
a1f104cb4d | ||
|
|
eadb8d5d0a | ||
|
|
41ae947885 | ||
|
|
84f610c0e9 | ||
|
|
0df959cf68 | ||
|
|
a15d10ea1e | ||
|
|
a37d6e86df | ||
|
|
a405063385 | ||
|
|
f5a5b85e9d | ||
|
|
ba7d941e5b | ||
|
|
804a2d1af9 | ||
|
|
c1bc6e161e | ||
|
|
af1b728b90 | ||
|
|
14e37a82ab | ||
|
|
f8a7854efa | ||
|
|
072ce87051 | ||
|
|
cac9b4460e | ||
|
|
67bf90a149 | ||
|
|
af8558b19e | ||
|
|
1903542f11 | ||
|
|
3ed16fb796 | ||
|
|
6f99392eda | ||
|
|
680dbfbf77 | ||
|
|
51a72b497b | ||
|
|
d6e57dd194 | ||
|
|
e92ab55da6 | ||
|
|
c78b3e0204 | ||
|
|
ac1c05389a | ||
|
|
95583fe2cd | ||
|
|
ddedda9233 | ||
|
|
d30b9d1513 | ||
|
|
4c35f88ea0 | ||
|
|
e6623ae0a8 | ||
|
|
4755578822 | ||
|
|
319d543ac2 | ||
|
|
9e668cda7f | ||
|
|
5447483da2 | ||
|
|
8e22a8d107 | ||
|
|
18d27ab4e4 | ||
|
|
fe60832492 | ||
|
|
6bf683409f | ||
|
|
634bfb1eae | ||
|
|
c9d597d2b1 | ||
|
|
92c616f717 | ||
|
|
b1e8d29ae0 | ||
|
|
e0cef55fcd | ||
|
|
9aacf5c7db | ||
|
|
4858749a20 | ||
|
|
b53c0b982a | ||
|
|
2aac9ff9c5 | ||
|
|
bdaa70ada5 | ||
|
|
ca6abdfc61 | ||
|
|
e18593fe88 | ||
|
|
08401aff26 | ||
|
|
cddc67ad69 | ||
|
|
586af2a435 | ||
|
|
97091fab60 | ||
|
|
5f2cf75be8 | ||
|
|
37c7b81c95 | ||
|
|
779a266713 | ||
|
|
ebaedc6f05 | ||
|
|
08a392787a | ||
|
|
883bf74bad | ||
|
|
80de3335b7 | ||
|
|
794072bdf8 | ||
|
|
e28fdb9cb1 | ||
|
|
7873d1c6b3 | ||
|
|
f8c069132e | ||
|
|
c53833072f | ||
|
|
16d7cf7a52 | ||
|
|
3b9c2b9729 | ||
|
|
b230fea66f | ||
|
|
f9b6501af1 | ||
|
|
0cd8e3701d | ||
|
|
8545672839 | ||
|
|
4a6c4b95f1 | ||
|
|
c893bc21ab | ||
|
|
c8c5cbf8cc | ||
|
|
54ef8a1e19 | ||
|
|
82df218bcb | ||
|
|
f613ad6c05 | ||
|
|
4e732d0379 | ||
|
|
ad8b5c9d29 | ||
|
|
1ab4bf14dc | ||
|
|
068a0b4576 | ||
|
|
5f694f228f | ||
|
|
2ffe49130d | ||
|
|
f7d18ef976 | ||
|
|
8233eb6007 | ||
|
|
de4693cdf3 | ||
|
|
8fb235c3f5 | ||
|
|
6feb00dcd9 | ||
|
|
4fc1847a70 | ||
|
|
e7f16f07f7 | ||
|
|
d9551b3106 | ||
|
|
854428795b | ||
|
|
5c3b4bd987 | ||
|
|
9d686d3e52 | ||
|
|
b62e00b935 | ||
|
|
634745c818 | ||
|
|
490c6d9a28 | ||
|
|
e6dd9978cb | ||
|
|
240a5613a5 | ||
|
|
fb96cbcaaf | ||
|
|
b58f879db7 | ||
|
|
1585c6095e | ||
|
|
30a630412d | ||
|
|
e5ca79cd51 | ||
|
|
148353aca4 | ||
|
|
7a098ce740 | ||
|
|
f3b9831a0c | ||
|
|
01454674c8 | ||
|
|
5093b18ecc | ||
|
|
c16cfd0668 | ||
|
|
1674cd5db9 | ||
|
|
f111ab48fb | ||
|
|
65309854ac | ||
|
|
cf0aff8c40 | ||
|
|
16b768485a | ||
|
|
c2e7b533d3 | ||
|
|
539859f1ab | ||
|
|
d1d40a9a76 | ||
|
|
52162a5604 | ||
|
|
84e84207a5 | ||
|
|
a4e1745eca | ||
|
|
5931979b74 | ||
|
|
a412a65315 | ||
|
|
25da0674bb | ||
|
|
c823bf4fbb | ||
|
|
cfd0e67a6b | ||
|
|
94f3af57f1 | ||
|
|
0050a3fe6c | ||
|
|
0e65ddee37 | ||
|
|
101f7de889 | ||
|
|
a21c1ff92d | ||
|
|
f9bb2e498e | ||
|
|
f6bb803be5 | ||
|
|
204a88c171 | ||
|
|
012afc0708 | ||
|
|
cf089abb64 | ||
|
|
40e463cdc1 | ||
|
|
6a1284a5ca | ||
|
|
60522ee474 | ||
|
|
0045641db7 | ||
|
|
97b5b1b669 | ||
|
|
448de8519a | ||
|
|
95e1fe0446 | ||
|
|
47254be254 | ||
|
|
3da15bfd19 | ||
|
|
c79db2581b | ||
|
|
93b86a8800 | ||
|
|
56ba7ef411 | ||
|
|
e2117fd8a9 | ||
|
|
e817c76e38 | ||
|
|
65e059a7d2 | ||
|
|
f661025acc | ||
|
|
2fe1b1e16e | ||
|
|
665ffe3984 | ||
|
|
c3401047e0 | ||
|
|
996177ceaf | ||
|
|
09e998523f | ||
|
|
38e8d27416 | ||
|
|
813de04596 | ||
|
|
3c0eae4180 | ||
|
|
99424a9f53 | ||
|
|
51d118fdb5 | ||
|
|
a26509a1fd | ||
|
|
0db70379e8 | ||
|
|
c612b5d17b | ||
|
|
1b469cce49 | ||
|
|
c62cbd2d77 | ||
|
|
da1bc19052 | ||
|
|
8e2246ec5c | ||
|
|
5cf6945bcb | ||
|
|
7132ae47d7 | ||
|
|
96bde4ad03 | ||
|
|
85b9bdd8f4 | ||
|
|
e5a85108d7 | ||
|
|
aaa3a8ebda | ||
|
|
9ceb766a67 | ||
|
|
f894240fbb | ||
|
|
4bac8e2ebe | ||
|
|
d3ad1fd384 | ||
|
|
ed0e4189e4 | ||
|
|
5f147242be | ||
|
|
c7b4c22b94 | ||
|
|
667bacf81e | ||
|
|
e896b0ea96 | ||
|
|
3b0a5a8b41 | ||
|
|
81d39e9bde | ||
|
|
59eabf03a6 | ||
|
|
4fc4987c43 | ||
|
|
dbf5bb149a | ||
|
|
38acbf6970 | ||
|
|
ad4bd91751 | ||
|
|
1a6f290979 | ||
|
|
c6e02a620a | ||
|
|
90efaa41c2 | ||
|
|
51a73ad8b5 | ||
|
|
93f2387d1b | ||
|
|
207a631a65 | ||
|
|
74e60e98b7 | ||
|
|
6ca6bf7457 | ||
|
|
ea49cdeb17 | ||
|
|
bcc8b1917a | ||
|
|
67b12d4416 | ||
|
|
dc02daecee | ||
|
|
6212b38ea6 | ||
|
|
ce7e5726e7 | ||
|
|
1156b3f22e | ||
|
|
66097f3507 | ||
|
|
146f02d314 | ||
|
|
77e5882ce7 | ||
|
|
d44850a4f3 | ||
|
|
e6e692dc43 | ||
|
|
dc65770ae3 | ||
|
|
8c15802277 | ||
|
|
3d666d9929 | ||
|
|
c0c960ec2e | ||
|
|
2bb4db127c | ||
|
|
dd1a5d4f58 | ||
|
|
961fdf7029 | ||
|
|
ff3d2b006f | ||
|
|
d7efbad3df | ||
|
|
d70995bb1a | ||
|
|
1b58e95dce | ||
|
|
780f70d5c6 | ||
|
|
a01e1f96fa | ||
|
|
3adb443ca5 | ||
|
|
dc9ff3a004 | ||
|
|
f879f4f432 | ||
|
|
183f831a7e | ||
|
|
3c361be621 | ||
|
|
5764d44faf | ||
|
|
ce86677faa | ||
|
|
17d93b39d5 | ||
|
|
1357b85a3d | ||
|
|
c67cb5c604 | ||
|
|
6ffb0df6cb | ||
|
|
032b40c78d | ||
|
|
742aea115b | ||
|
|
0f16cd46f9 | ||
|
|
eea64cf272 | ||
|
|
3d5c5f8054 | ||
|
|
748099a324 | ||
|
|
9c1d050d8b | ||
|
|
4ef834e295 | ||
|
|
50bead172b | ||
|
|
ee4508af03 | ||
|
|
6638959d66 | ||
|
|
f266a9d25d | ||
|
|
6cb8e1a518 | ||
|
|
85375359ed | ||
|
|
17c9ba2c68 | ||
|
|
34334ad8b8 | ||
|
|
4527714094 | ||
|
|
b43d74dbb7 | ||
|
|
0c4140ff02 | ||
|
|
b074c02fa2 | ||
|
|
7636c97f9f | ||
|
|
4211ab28b0 | ||
|
|
cecfbc7e20 | ||
|
|
31a6aff932 | ||
|
|
c4a67c4356 | ||
|
|
9f5765134b | ||
|
|
0c5b51d2ac | ||
|
|
31c4198cee | ||
|
|
a94c4b4ce4 | ||
|
|
088dd99ec1 | ||
|
|
4f9b907b4d | ||
|
|
e7dc3e6062 | ||
|
|
53055e78eb | ||
|
|
9a9c34aa18 | ||
|
|
2f1384840c | ||
|
|
b462e55799 | ||
|
|
263ec60ba6 | ||
|
|
8d44a57200 | ||
|
|
976722c129 | ||
|
|
4a9447d344 | ||
|
|
ac2ed9aa87 | ||
|
|
51cf241dae | ||
|
|
f239b8e26d | ||
|
|
ab9f4161ea | ||
|
|
1d10e649b7 | ||
|
|
a95b40aac6 | ||
|
|
1b5777821f | ||
|
|
587d469193 | ||
|
|
6c3e30f3ea | ||
|
|
91dbcae9e2 | ||
|
|
fb5db4f6b7 | ||
|
|
a1e029a825 | ||
|
|
54dbf9b6f2 | ||
|
|
b6344951fe | ||
|
|
ea972118b5 | ||
|
|
2fccd4799d | ||
|
|
a3937e4d0d | ||
|
|
acb022d5d5 | ||
|
|
b6e46d6101 | ||
|
|
347f75f804 | ||
|
|
4005ced505 | ||
|
|
c748c35b37 | ||
|
|
a73836ca43 | ||
|
|
b357fab326 | ||
|
|
16a3000451 | ||
|
|
c4fac2d179 | ||
|
|
60d11a6eba | ||
|
|
93edbda984 | ||
|
|
75bd94d757 | ||
|
|
a5cf0b6ef5 | ||
|
|
506280d645 | ||
|
|
2f79b4fde7 | ||
|
|
846f98628d | ||
|
|
eed9be5a9e | ||
|
|
27c77afafc | ||
|
|
c156b2f817 | ||
|
|
96fcc5df6b | ||
|
|
3c775fd5de | ||
|
|
75e9ee6528 | ||
|
|
ea0ee96398 | ||
|
|
3fd4a2841a | ||
|
|
6ecf44c87a | ||
|
|
031e8cea6e | ||
|
|
757fbb0124 | ||
|
|
d65e3f73df | ||
|
|
5b13105d58 | ||
|
|
c8745afb37 | ||
|
|
85189c0bde | ||
|
|
a8635bade2 | ||
|
|
4560572ff2 | ||
|
|
c7fa57fd14 | ||
|
|
54965fdf2e | ||
|
|
30361aa685 | ||
|
|
8be93b72c4 | ||
|
|
c7e9d645e5 | ||
|
|
fe6a3c89f3 | ||
|
|
686a32cbc0 | ||
|
|
55d7397ff5 | ||
|
|
3714d554df | ||
|
|
0415de853b | ||
|
|
0ba1e8f904 | ||
|
|
58bfcb0953 | ||
|
|
fa281d89d2 | ||
|
|
908b10dae0 | ||
|
|
ea03f9def0 | ||
|
|
3510799fca | ||
|
|
1f4a63d6db | ||
|
|
dd94a444d2 | ||
|
|
50fafc9ff6 | ||
|
|
47fc6a689d | ||
|
|
86175a1827 | ||
|
|
6d6e25df4e | ||
|
|
5402ed112c | ||
|
|
235b83d02e | ||
|
|
6ffbec969a | ||
|
|
185ea71646 | ||
|
|
69fcc3acd7 | ||
|
|
da94cf4aab | ||
|
|
8799cf95b4 | ||
|
|
108ce18d51 | ||
|
|
f67ea5d010 | ||
|
|
dd857aeccf | ||
|
|
44b1acd385 | ||
|
|
b2f6018e05 | ||
|
|
bca6507f11 | ||
|
|
30332c2ba5 | ||
|
|
17919d7503 | ||
|
|
42237ced80 | ||
|
|
737021ccdf | ||
|
|
22ed9d8d7c | ||
|
|
49dcd11813 | ||
|
|
7c30086d78 | ||
|
|
e2dbfdc537 | ||
|
|
674eb109c2 | ||
|
|
927b5bc8cc | ||
|
|
f7dd0fc582 | ||
|
|
35f30bde04 | ||
|
|
a682b50fd4 | ||
|
|
3b5024749f | ||
|
|
2a56d892d7 | ||
|
|
e3d5eaf388 | ||
|
|
5d1f50117b | ||
|
|
f6a2ec15d7 | ||
|
|
64a8d56725 | ||
|
|
71caea32e7 | ||
|
|
17993ef9ff | ||
|
|
b0aa4ef4c8 | ||
|
|
5c4aaa27d9 | ||
|
|
53586d95d0 | ||
|
|
3877ab1f00 | ||
|
|
2425322e8d | ||
|
|
3f80a113d1 | ||
|
|
9ad20849d3 | ||
|
|
c8c58280d8 | ||
|
|
d40505cd16 | ||
|
|
25c5f84090 | ||
|
|
a58293f04b | ||
|
|
1408fb41b8 | ||
|
|
cb7cb8e527 | ||
|
|
d750dbc703 | ||
|
|
91b417138a | ||
|
|
db5eabd927 | ||
|
|
cbcc0fde04 | ||
|
|
cca3b98a09 | ||
|
|
e63b8ff35d | ||
|
|
b6a37bf0e2 | ||
|
|
249ca4fd75 | ||
|
|
d382869b98 | ||
|
|
41a3c27aba | ||
|
|
af48c46c30 | ||
|
|
52bc51a197 | ||
|
|
57ca9cc840 | ||
|
|
56d6a47ad3 | ||
|
|
b806360a49 | ||
|
|
739a88ed00 | ||
|
|
38d4341e59 | ||
|
|
6118d91922 | ||
|
|
71ac7efafe | ||
|
|
cf0710225c | ||
|
|
21e96df85a | ||
|
|
79f32c2ebd | ||
|
|
492a1f69b3 | ||
|
|
32b962e186 | ||
|
|
37beb8e6b2 | ||
|
|
1ee9f3815d | ||
|
|
65a5e8721c | ||
|
|
036c7a2117 | ||
|
|
229e8e1ad1 | ||
|
|
390bb1bdc5 | ||
|
|
83b401b241 | ||
|
|
cfb2c1f62a | ||
|
|
4ad7df746e | ||
|
|
a218b1d3d0 | ||
|
|
6f61aff735 | ||
|
|
4893f78286 | ||
|
|
97296f3169 | ||
|
|
ebcf4364f5 | ||
|
|
6d0078d39b | ||
|
|
9b80b693c1 | ||
|
|
2e1e26fdb9 | ||
|
|
ddeb43783c | ||
|
|
b61e527baa | ||
|
|
53ce96b48f | ||
|
|
36ea166c20 | ||
|
|
f9fd4c71f1 | ||
|
|
44171417e3 | ||
|
|
b554a46a4c | ||
|
|
19a2c37678 | ||
|
|
23d74040ed | ||
|
|
685e63b9da | ||
|
|
39855f4d2b | ||
|
|
ae6fc41ca9 | ||
|
|
1bb41bec2a | ||
|
|
041d679a54 | ||
|
|
46058c275c | ||
|
|
b9e15a1340 | ||
|
|
f9eb4ffee2 | ||
|
|
419952f33b | ||
|
|
af8bdcd9e0 | ||
|
|
54122af9d7 | ||
|
|
5e4852bd32 | ||
|
|
3714f9fdbd | ||
|
|
a9dd6e0f3d | ||
|
|
3c9f4ee555 | ||
|
|
7ff0b4c6b9 | ||
|
|
648662469b | ||
|
|
c37ddd7872 | ||
|
|
17f35cde19 | ||
|
|
b5d17b99df | ||
|
|
5c9746e209 | ||
|
|
51938affc2 | ||
|
|
856006a68d | ||
|
|
a2622263ce | ||
|
|
7db1613b1a | ||
|
|
3add686e9b | ||
|
|
a9f0983f0f | ||
|
|
3b16d6c291 | ||
|
|
85399bd6e2 | ||
|
|
aef2b95d41 | ||
|
|
11a233da84 | ||
|
|
016aa87e34 | ||
|
|
9094af565f | ||
|
|
d7de908c66 | ||
|
|
a3985ac94c | ||
|
|
b48f26020a | ||
|
|
630d3679b5 | ||
|
|
78c89eb29b | ||
|
|
7fe4996bbe | ||
|
|
370deda5a7 | ||
|
|
d0d8ff8313 | ||
|
|
550b9ebf4d | ||
|
|
2265456bda | ||
|
|
b0f1cde33f | ||
|
|
cdd150be42 | ||
|
|
0d24d75d8f | ||
|
|
5c866c67b5 | ||
|
|
b49fea87ab | ||
|
|
1c262d22ce | ||
|
|
0dde77009e | ||
|
|
3e71c35fdd | ||
|
|
10f1fc5e92 | ||
|
|
8fbad757bf | ||
|
|
5755aa3eb8 | ||
|
|
f76d14f613 | ||
|
|
0c3470bab2 | ||
|
|
315ad06ecc | ||
|
|
c1627612cf | ||
|
|
b5cfceeed6 | ||
|
|
7fe7dd743c | ||
|
|
3e36f27987 | ||
|
|
b9f4f3f71c | ||
|
|
ff1230c3ae | ||
|
|
e71ec574e1 | ||
|
|
c2e716ec4a | ||
|
|
5ad8bb1830 | ||
|
|
751e78baa9 | ||
|
|
be620bd437 | ||
|
|
44365651a6 | ||
|
|
7b557c0586 | ||
|
|
495a27c0a7 | ||
|
|
e07fddb20b | ||
|
|
56eb1d106f | ||
|
|
c8b6d61ae2 | ||
|
|
47e91e943c | ||
|
|
4f8c52f09e | ||
|
|
f20b32b01b | ||
|
|
37cbb5ed01 | ||
|
|
289e13cb46 | ||
|
|
fb03c4c311 | ||
|
|
a65aecaf74 | ||
|
|
da9ba0a26a | ||
|
|
8440e881c0 | ||
|
|
85fa8a4761 | ||
|
|
5c8c78ca69 | ||
|
|
e9097c3b29 | ||
|
|
d53ee24741 | ||
|
|
6517cb15ef | ||
|
|
7b78f92feb | ||
|
|
0af6dc3838 | ||
|
|
e313a2ea45 | ||
|
|
f21ef30482 | ||
|
|
606fce65ab | ||
|
|
b4084484ff | ||
|
|
80062908d9 | ||
|
|
af8f7e95b0 | ||
|
|
9553478384 | ||
|
|
535b3ce286 | ||
|
|
cfe9c86edd | ||
|
|
ee66044425 | ||
|
|
30d56e1af0 | ||
|
|
354630770b | ||
|
|
74da63e3ca | ||
|
|
faa438bc51 | ||
|
|
6de6fb1932 | ||
|
|
6a8acefa30 | ||
|
|
ddec8325e7 | ||
|
|
b1852526f5 | ||
|
|
20aaf58ee9 | ||
|
|
b3db597c4b | ||
|
|
d302f228f9 | ||
|
|
74d5e2b0c1 | ||
|
|
dd42d24d8a | ||
|
|
5692fb32cd | ||
|
|
dbf80d564b | ||
|
|
72b82a8d19 | ||
|
|
c3beaedaa6 | ||
|
|
db694b20df | ||
|
|
34227ce738 | ||
|
|
24b1360eb8 | ||
|
|
60aff26d94 | ||
|
|
144bdf7dc7 | ||
|
|
8db4bb298e | ||
|
|
028477f34d | ||
|
|
6725c9e3cd | ||
|
|
a14dee5b8d | ||
|
|
2f8a1fc58f | ||
|
|
f250c4310e | ||
|
|
ad46e8a5e0 | ||
|
|
1e7031e5f4 | ||
|
|
8c736e979d | ||
|
|
335742a023 | ||
|
|
384ff3484c | ||
|
|
e17c29c258 | ||
|
|
e7d979ca74 | ||
|
|
bc2f38c790 | ||
|
|
88ee089d86 | ||
|
|
d9adaa5020 | ||
|
|
4a963adbcb | ||
|
|
56ac57b4cf | ||
|
|
cdbe2393c4 | ||
|
|
2f4490d059 | ||
|
|
447660504c | ||
|
|
5e44d18d54 | ||
|
|
7a9edae227 | ||
|
|
81b7bd35f4 | ||
|
|
4b946a23ca | ||
|
|
5ab92b1833 | ||
|
|
1a6a16e061 | ||
|
|
061b602334 | ||
|
|
f7deb02560 | ||
|
|
9dfe85eca3 | ||
|
|
cd5823d9f6 | ||
|
|
1af0a6cc8f | ||
|
|
9ed8ebab78 | ||
|
|
7f82a33bf5 | ||
|
|
41a7e5c915 | ||
|
|
8d22c0ba90 | ||
|
|
4636ae7237 | ||
|
|
ee9d0c4a99 | ||
|
|
476a0ad6ad | ||
|
|
14612fc116 | ||
|
|
5c87787351 | ||
|
|
3fa796382e | ||
|
|
f4f4761517 | ||
|
|
c78de41ccf | ||
|
|
b0d58d10bd | ||
|
|
f778741ee3 | ||
|
|
2fb517b293 | ||
|
|
aecc32fbfb | ||
|
|
64c8c0590c | ||
|
|
24dc436122 | ||
|
|
1e1fef52c4 | ||
|
|
c8b9e2ff37 | ||
|
|
34a6902986 | ||
|
|
0c47b0eb53 | ||
|
|
5d4ef7d009 | ||
|
|
31d23bc9a7 | ||
|
|
b4b54d1796 | ||
|
|
5023dfeb24 | ||
|
|
dad3092d8d | ||
|
|
ab77c032de | ||
|
|
778e54ef32 | ||
|
|
699db63615 | ||
|
|
01d0e13884 | ||
|
|
d743c196be | ||
|
|
c60ec18f34 | ||
|
|
1be1274d40 | ||
|
|
a65b49ea30 | ||
|
|
762d14c5a1 | ||
|
|
bd44c52cbb | ||
|
|
4cbdd27862 | ||
|
|
62cf42efb4 | ||
|
|
47dc30ea79 | ||
|
|
55abdff58c | ||
|
|
27cde532be | ||
|
|
9c2bd58488 | ||
|
|
a3c898fc4f | ||
|
|
da380119ef | ||
|
|
db631e3d57 | ||
|
|
fb63f9cc92 | ||
|
|
31e738a5a3 | ||
|
|
f3b1b351e8 | ||
|
|
149ecb380b | ||
|
|
67a43ff549 | ||
|
|
69f29d6fac | ||
|
|
51c12ef745 | ||
|
|
d0e89ec72a | ||
|
|
74c8b381e6 | ||
|
|
ddbd4236ab | ||
|
|
c0cbb5c75d | ||
|
|
717d00e64a | ||
|
|
19e9e52c4f | ||
|
|
1df2465222 | ||
|
|
70883d7fdc | ||
|
|
f3f5f0f896 | ||
|
|
a7828809e9 | ||
|
|
b80a2b0bc2 | ||
|
|
88d897eb14 | ||
|
|
2e9f562329 | ||
|
|
7aa6a30169 | ||
|
|
298f713e9b | ||
|
|
aa339d0851 | ||
|
|
ebb8596f03 | ||
|
|
fb57d3beef | ||
|
|
8488175ee8 | ||
|
|
e68191dcd9 | ||
|
|
0019a1f7dc | ||
|
|
5095a9e1c3 | ||
|
|
ddbaa8b32b | ||
|
|
9f7275eced | ||
|
|
3d8e6823f7 | ||
|
|
1368348cd9 | ||
|
|
b31cf90596 | ||
|
|
66025a06d5 | ||
|
|
65c8504141 | ||
|
|
cd16e001f6 | ||
|
|
77d2bc58fd | ||
|
|
bfc57459e1 | ||
|
|
3422718415 | ||
|
|
0b5e0a1113 | ||
|
|
b6b44e0f2d | ||
|
|
b642543600 | ||
|
|
095a05a8e1 | ||
|
|
4783204f31 | ||
|
|
82d819a6c7 | ||
|
|
10e7875680 | ||
|
|
2aad566857 | ||
|
|
a3e0a3ff1a | ||
|
|
8fe9ad80bb | ||
|
|
531262387d | ||
|
|
a73cd87b50 | ||
|
|
4601940f8d | ||
|
|
6e5b2c7368 | ||
|
|
8a3cc6041d | ||
|
|
25687c2db1 | ||
|
|
871229d0c5 | ||
|
|
74d179e479 | ||
|
|
910d384ed8 | ||
|
|
da89d6ab9c | ||
|
|
8d2159761f | ||
|
|
d434f8641d | ||
|
|
f49733d1d2 | ||
|
|
a3726d72f5 | ||
|
|
fe89ae13af | ||
|
|
6b90cd1277 | ||
|
|
ce64ec5397 | ||
|
|
bf6ca2dc78 | ||
|
|
204c68d475 | ||
|
|
5a7e59d833 | ||
|
|
0336a982ff | ||
|
|
aa18b63c16 | ||
|
|
3f890551e7 | ||
|
|
823127c87e | ||
|
|
cf2c9c6dc7 | ||
|
|
9b63b90ec4 | ||
|
|
a0ba140895 | ||
|
|
588f2502ec | ||
|
|
ae7d4592e1 | ||
|
|
24c7d145ea | ||
|
|
f1e7d68415 | ||
|
|
91f1528149 | ||
|
|
4f19f89d4c | ||
|
|
60b8bccd37 | ||
|
|
674dcba53c | ||
|
|
3dec9e531f | ||
|
|
980197cb05 | ||
|
|
5d30c71ccf | ||
|
|
1dcc5ca9f3 | ||
|
|
1eb24981c6 | ||
|
|
cb6b8ea5ac | ||
|
|
546a662a30 | ||
|
|
ef84c4dfad | ||
|
|
8ca81d0991 | ||
|
|
02e8158918 | ||
|
|
37cbe6c488 | ||
|
|
58d763f971 | ||
|
|
3d2700d29d | ||
|
|
e14ea94b0d | ||
|
|
17fde3df0c | ||
|
|
162204f28f | ||
|
|
491fb14eaa | ||
|
|
f4d7fe8850 | ||
|
|
4af583e5d5 | ||
|
|
282887368a | ||
|
|
94e372d8f2 | ||
|
|
3cb67939e4 | ||
|
|
f3197d2618 | ||
|
|
3785f7621c | ||
|
|
2b59badde7 | ||
|
|
54162b43c8 | ||
|
|
1933cdc28c | ||
|
|
f2512d1ff1 | ||
|
|
d54b13e80a | ||
|
|
8ed5e81bdb | ||
|
|
f0fc83372b | ||
|
|
081504edab | ||
|
|
b939123e84 | ||
|
|
f008d9dd19 | ||
|
|
d2386af523 | ||
|
|
41b9024e28 | ||
|
|
50c17bd5e4 | ||
|
|
1882c43389 | ||
|
|
d7027887cc | ||
|
|
7d8c9df252 | ||
|
|
e1e465dc51 | ||
|
|
b276d48ecf | ||
|
|
0c13734f7a | ||
|
|
de788266eb | ||
|
|
eb879a743e | ||
|
|
231bceeabb | ||
|
|
387b7602cf | ||
|
|
d8c14c04e3 | ||
|
|
33f981d8f1 | ||
|
|
6188b89ff0 | ||
|
|
2d424e078e | ||
|
|
ee5d72301a | ||
|
|
ddb02adbb4 | ||
|
|
b6b05f79a1 | ||
|
|
4a438e4799 | ||
|
|
31dc69da42 | ||
|
|
35dfd13ddd | ||
|
|
b4535bd29b | ||
|
|
5a30ec1806 | ||
|
|
d7bb80468b | ||
|
|
92f6d31f33 | ||
|
|
421bc93765 | ||
|
|
9d6a692054 | ||
|
|
278c7bfc53 | ||
|
|
ad23c0e03e | ||
|
|
ca8274dbe8 | ||
|
|
1234fbf5f4 | ||
|
|
e64ed4c27f | ||
|
|
a4b7236289 | ||
|
|
16c4374f7a | ||
|
|
05a77c7406 | ||
|
|
fceead7cbe | ||
|
|
3d81bdd281 | ||
|
|
56ab8de968 | ||
|
|
30b150dbfc | ||
|
|
40ee3b1b45 | ||
|
|
c79217dd75 | ||
|
|
075d4d4210 | ||
|
|
216b679e4b | ||
|
|
c5fe81f4e6 | ||
|
|
0c464d0220 | ||
|
|
02f28d12e3 | ||
|
|
13d24278f2 | ||
|
|
42ef4352f4 | ||
|
|
843720a671 | ||
|
|
0884dd88d6 | ||
|
|
4262fa8637 | ||
|
|
29a2db6552 | ||
|
|
06fa0c17a4 | ||
|
|
cfdca6a894 | ||
|
|
2873f6c193 | ||
|
|
8b963ed63c | ||
|
|
adb951426a | ||
|
|
9ced96a1c9 | ||
|
|
7e155dc87b | ||
|
|
c5e2d80fc0 | ||
|
|
b0fa646de9 | ||
|
|
83f08cffee | ||
|
|
03652a0030 | ||
|
|
1c3e0ba656 | ||
|
|
48f80b947b | ||
|
|
d7873de4e8 | ||
|
|
32d025bcf2 | ||
|
|
61ab5d1652 | ||
|
|
f5fd6833e2 | ||
|
|
163e6f56df | ||
|
|
5650697475 | ||
|
|
2968087d37 | ||
|
|
e7ec80f58a | ||
|
|
f0ba699463 | ||
|
|
06d5b14b86 | ||
|
|
dff544cd5d | ||
|
|
73bc0f6258 | ||
|
|
7e5e180000 | ||
|
|
fc431df2b4 | ||
|
|
bb61be630a | ||
|
|
cdc9ec2854 | ||
|
|
21d3703b69 | ||
|
|
c395be252e | ||
|
|
293c350fb7 | ||
|
|
a777f336e1 | ||
|
|
5b6c186125 | ||
|
|
6451d59deb | ||
|
|
c912b66a8f | ||
|
|
d62c43bc95 | ||
|
|
3b7b9b6ed1 | ||
|
|
9822a6ed5d | ||
|
|
a06f4dfad6 | ||
|
|
b92df87400 | ||
|
|
d7921c0111 | ||
|
|
af09c3e62a | ||
|
|
0ed42f657d | ||
|
|
ed7fbabd1c | ||
|
|
bd03563fcb | ||
|
|
05ffc7f8d6 | ||
|
|
ebc475d278 | ||
|
|
2813437515 | ||
|
|
ea2e885505 | ||
|
|
a7fadc3a45 | ||
|
|
8040a20f71 | ||
|
|
0e87854819 | ||
|
|
3bc6c641de | ||
|
|
4abb6e17ba | ||
|
|
1986f08cf9 | ||
|
|
620ae5cf1d | ||
|
|
590ee5a248 | ||
|
|
a08326ab60 | ||
|
|
63cf99361d | ||
|
|
1e54ca82b8 | ||
|
|
2ec576e110 | ||
|
|
4251e976b3 | ||
|
|
d831e2f3a4 | ||
|
|
21f20417d6 | ||
|
|
e1c914d9bb | ||
|
|
4b03b0a93a | ||
|
|
bbcde55a9e | ||
|
|
0cba898280 | ||
|
|
b9edec069a | ||
|
|
939cb7958a | ||
|
|
ebb38c6518 | ||
|
|
fa80d2f3cc | ||
|
|
869f37cd89 | ||
|
|
c22202585d | ||
|
|
f28c912d5a | ||
|
|
a0e56c5282 | ||
|
|
de7da1e806 | ||
|
|
add2f6f669 | ||
|
|
b06e765e68 | ||
|
|
c3952cb985 | ||
|
|
d5469a64d2 | ||
|
|
ac26fc6d5f | ||
|
|
122088712d | ||
|
|
9fb09ce14d | ||
|
|
392fb21946 | ||
|
|
e94b05851f | ||
|
|
571a5962b7 | ||
|
|
8b6863dc40 | ||
|
|
01af629399 | ||
|
|
4ece6d2a9b | ||
|
|
18d1d7af33 | ||
|
|
5ada250a66 | ||
|
|
308c7ab670 | ||
|
|
89d35e020a | ||
|
|
6729570799 | ||
|
|
f72f5f6438 | ||
|
|
a02e11e0bc | ||
|
|
9ff15e1506 | ||
|
|
fdddfc6b1f | ||
|
|
78ebb6295d | ||
|
|
73c89e8c00 | ||
|
|
fcc499e401 | ||
|
|
6e8efe22aa | ||
|
|
f9c5cb73a2 | ||
|
|
c939521f5f | ||
|
|
2640e05307 | ||
|
|
c1a371e3d3 | ||
|
|
5a4871155a | ||
|
|
d8e6dbf788 | ||
|
|
7ea69ae4b4 | ||
|
|
d238ead451 | ||
|
|
e6b449f24d | ||
|
|
41018d05a8 | ||
|
|
d48008e13d | ||
|
|
a9cf438100 | ||
|
|
6c7a0d21d2 | ||
|
|
d887db4c18 | ||
|
|
e6be69ec6d | ||
|
|
c1ba7db8a1 | ||
|
|
dc5b5896a9 | ||
|
|
38678fafc1 | ||
|
|
7611211d1c | ||
|
|
0d9c2cd902 | ||
|
|
1a84c109fc | ||
|
|
cbedf3f8cc | ||
|
|
50436e3106 | ||
|
|
62498ec867 | ||
|
|
91b94bb16c | ||
|
|
c2bbdc503c | ||
|
|
babae0fa6e | ||
|
|
f047882ac1 | ||
|
|
b818d6a921 | ||
|
|
ba631c8451 | ||
|
|
2c963b389c | ||
|
|
8437fbc314 | ||
|
|
76404004a4 | ||
|
|
1b64514c2c | ||
|
|
6efea7d365 | ||
|
|
e1a3b77d67 | ||
|
|
cfc7ad5627 | ||
|
|
b3cbf14ad6 | ||
|
|
51cfbe6b00 | ||
|
|
155f397d0b | ||
|
|
4b53b8b6a1 | ||
|
|
dbea4a1787 | ||
|
|
5b6da85e68 | ||
|
|
61671e9d3f | ||
|
|
f94e05e04e | ||
|
|
b5cad9a8cc | ||
|
|
3a97d8cc82 | ||
|
|
3c099465da | ||
|
|
fcdb2591b6 | ||
|
|
b67a16e9af | ||
|
|
1d672616be | ||
|
|
ed9d70903d | ||
|
|
8a9bab8a46 | ||
|
|
fdc6a08eb4 | ||
|
|
154309912d | ||
|
|
a84fea86b8 | ||
|
|
609998bc18 | ||
|
|
891868b061 | ||
|
|
3fc5cf8b9f | ||
|
|
6048ed5bc1 | ||
|
|
a1a007134c | ||
|
|
d82f9fa432 | ||
|
|
c0074301a3 | ||
|
|
9c2c05ad44 | ||
|
|
fad230c02e | ||
|
|
ad3c95f273 | ||
|
|
684fdb6095 | ||
|
|
8e64f171b8 | ||
|
|
d616c3fed7 | ||
|
|
e07e6cd2a3 | ||
|
|
f1bd5cdb52 | ||
|
|
be82b6bed9 | ||
|
|
37ad4758a1 | ||
|
|
e4a238a05c | ||
|
|
e5ca922ce8 | ||
|
|
6a1f4431d0 | ||
|
|
d67eda24d2 | ||
|
|
bba0cc8dc5 | ||
|
|
884b52b710 | ||
|
|
01ef2351b3 | ||
|
|
de1d566e9e | ||
|
|
19114a61ae | ||
|
|
36e5599ead | ||
|
|
f5a82e575c | ||
|
|
1851de323d | ||
|
|
f9408640a3 | ||
|
|
73837730fa | ||
|
|
9b46991721 | ||
|
|
606cd0368f | ||
|
|
d9ef23ad99 | ||
|
|
48b8f54c12 | ||
|
|
cec9f90c1c | ||
|
|
44d36f140a | ||
|
|
f88adcfa85 | ||
|
|
c5919f0c15 | ||
|
|
ac160cac12 | ||
|
|
867aaa5864 | ||
|
|
0b26505a20 | ||
|
|
98ad513621 | ||
|
|
591edbb003 | ||
|
|
a17b1c2ab7 | ||
|
|
648f14d95b | ||
|
|
2e4c2422b1 | ||
|
|
463fdb1ed9 | ||
|
|
d6b612a4a3 | ||
|
|
d24376608e | ||
|
|
ff41f9bd9a | ||
|
|
6d3dd5c484 | ||
|
|
f0bc8983b8 | ||
|
|
729354b038 | ||
|
|
c0be857f37 | ||
|
|
98b0e88ace | ||
|
|
3d501df21f | ||
|
|
1b4abb747d | ||
|
|
b1d418f7fb | ||
|
|
a702b4752b | ||
|
|
684ba7c0cb | ||
|
|
1bcc27d2be | ||
|
|
50d3b305d4 | ||
|
|
a341c98ec6 | ||
|
|
fa5c8a00e4 | ||
|
|
42f6c20ada | ||
|
|
787738094d | ||
|
|
a44ebfe99f | ||
|
|
c5959664e4 | ||
|
|
9b581268de | ||
|
|
acf654c984 | ||
|
|
94f83eb9e3 | ||
|
|
07c675ed06 | ||
|
|
f292e01980 | ||
|
|
61f9123147 | ||
|
|
60708a7fd7 | ||
|
|
761fb93aba | ||
|
|
20bc718bdc | ||
|
|
07337d2f41 | ||
|
|
3d2de00f49 | ||
|
|
a7242ca846 | ||
|
|
d3298ac5f2 | ||
|
|
e486243c06 | ||
|
|
8eaefb57d3 | ||
|
|
c21f7afdcb | ||
|
|
d734dee589 | ||
|
|
f035c4c01a | ||
|
|
8fcdcecf36 | ||
|
|
3f9ee1ac2e | ||
|
|
188e1f788d | ||
|
|
98a0f1cf5b | ||
|
|
1467a673b9 | ||
|
|
889eb86d89 | ||
|
|
125da0e2db | ||
|
|
14b274c707 | ||
|
|
dedbc20ac6 | ||
|
|
36cf2348d0 | ||
|
|
a19f8996b8 | ||
|
|
7293263773 | ||
|
|
ed5b07374d | ||
|
|
07b96bef95 | ||
|
|
5c3cca157d | ||
|
|
f1f66a9b9d | ||
|
|
f4007210c1 | ||
|
|
77962dbd4c | ||
|
|
419cbae55f | ||
|
|
5233789c40 | ||
|
|
70731719f7 | ||
|
|
cf4aa68f98 | ||
|
|
6bfd89074c | ||
|
|
acc4893a7f | ||
|
|
ab61ae2b36 | ||
|
|
514b9c1c7d | ||
|
|
44f2cf2b24 | ||
|
|
9befec5cd1 | ||
|
|
7efdfe5639 | ||
|
|
be6811b29a | ||
|
|
f160b8df04 | ||
|
|
158471b218 | ||
|
|
a383cece53 | ||
|
|
0901e6ab77 | ||
|
|
e1485971d8 | ||
|
|
91c9b1bfe7 | ||
|
|
befe6be86c | ||
|
|
79428cf4ed | ||
|
|
7bde5fe893 | ||
|
|
2f7e024387 | ||
|
|
9235cfa739 | ||
|
|
f1e623ec5a | ||
|
|
7c86dc9ac6 | ||
|
|
ec2da0a399 | ||
|
|
dd9b2a872c | ||
|
|
9767759033 | ||
|
|
7537d79311 | ||
|
|
b68f34eb9e | ||
|
|
0a23c4abd6 | ||
|
|
b51768b08e | ||
|
|
4561f0c79e | ||
|
|
5c92491bc0 | ||
|
|
083605e2d7 | ||
|
|
d28e2f0f56 | ||
|
|
87a964355b | ||
|
|
fbc3f0cef5 | ||
|
|
2b1625e3a8 | ||
|
|
6230df749e | ||
|
|
e62003c0ce | ||
|
|
d0f092f7ae | ||
|
|
9e2e07e8a7 | ||
|
|
4154d47c07 | ||
|
|
62e0cba7bd | ||
|
|
39d5c785d5 | ||
|
|
e5cb81c11f | ||
|
|
3abb8d38ec | ||
|
|
7f0860d5d0 | ||
|
|
8c74c8ab6f | ||
|
|
37df899ada | ||
|
|
f55181e447 | ||
|
|
b1bc2f8c5c | ||
|
|
350df7ca55 | ||
|
|
8768a8aca6 | ||
|
|
0f8bb016f4 | ||
|
|
eb30791ff4 | ||
|
|
7b37bf0f48 | ||
|
|
fff67a5917 | ||
|
|
3dbe91577c | ||
|
|
0e05b64ebc | ||
|
|
c895e99306 | ||
|
|
6d7e8beaaa | ||
|
|
8b62d8a6c5 | ||
|
|
ec44850646 | ||
|
|
2ea5a98ee0 | ||
|
|
80928b90a5 | ||
|
|
b28174aba1 | ||
|
|
da170bab3a | ||
|
|
49a2f998dd | ||
|
|
4efdc8b4f7 | ||
|
|
a75507980a | ||
|
|
8d0decc17a | ||
|
|
e334cbb5d4 | ||
|
|
e3ac8ab19d | ||
|
|
bddf6e9017 | ||
|
|
bcdc0217b3 | ||
|
|
521841b447 | ||
|
|
c53cd336f9 | ||
|
|
a8226989c8 | ||
|
|
114b156d74 | ||
|
|
def2d4bac9 | ||
|
|
250e2ab6aa | ||
|
|
6185ddf76a | ||
|
|
dddf192e5a | ||
|
|
2d32f77ed0 | ||
|
|
7eb7533d42 | ||
|
|
bb711fe255 | ||
|
|
14a8759b82 | ||
|
|
5a0d4eff71 | ||
|
|
805d6bbc8c | ||
|
|
a0004ab892 | ||
|
|
46a444dc21 | ||
|
|
aefb5c37fe | ||
|
|
2216978726 | ||
|
|
3a2d8edb53 | ||
|
|
e0d57b7713 | ||
|
|
3a9912c01e | ||
|
|
6cadee31bf | ||
|
|
678845dfda | ||
|
|
7f7e218504 | ||
|
|
256a9951f5 | ||
|
|
370b45bb35 | ||
|
|
616c4a9a53 | ||
|
|
821f7d6694 | ||
|
|
bc89be6187 | ||
|
|
86b6a4cefd | ||
|
|
1f9a53a454 | ||
|
|
f22d112da2 | ||
|
|
c36c06ab99 | ||
|
|
a915c60999 | ||
|
|
6ddb8a7d88 | ||
|
|
50bb2cb1e6 | ||
|
|
e1571dda9b | ||
|
|
7410c6216c | ||
|
|
8f84df44ab | ||
|
|
82f21b6734 | ||
|
|
892fd5a6ef | ||
|
|
3069db0cfd | ||
|
|
b71c9d539e | ||
|
|
78e643970d | ||
|
|
34da3dd3d7 | ||
|
|
817cb0d363 | ||
|
|
01088e214c | ||
|
|
3e4500f9fd | ||
|
|
d4b62608a9 | ||
|
|
e6bfc1c2fc | ||
|
|
051cabed69 | ||
|
|
04916a6e97 | ||
|
|
f3be2fa66b | ||
|
|
c36087cc0c | ||
|
|
e35909ac7d | ||
|
|
e5a693ab94 | ||
|
|
9e9cfb4600 | ||
|
|
5dddaac006 | ||
|
|
14af6f1fba | ||
|
|
e88064fdc9 | ||
|
|
6badf5ea1d | ||
|
|
20f5f3da24 | ||
|
|
8c1b147705 | ||
|
|
366155b828 | ||
|
|
2c7d1897eb | ||
|
|
26ccb23402 | ||
|
|
d9e2471fcd | ||
|
|
8302b351dd | ||
|
|
b8647c0481 | ||
|
|
a168403d68 | ||
|
|
42d8650058 | ||
|
|
7ad0d46c11 | ||
|
|
58812f7f1f | ||
|
|
65133b2aef | ||
|
|
291d8cd335 | ||
|
|
7a27e2b94b | ||
|
|
57a8eab1c3 | ||
|
|
236a7f68e9 | ||
|
|
81d424f475 | ||
|
|
687ba8c9a2 | ||
|
|
6d74a564e6 | ||
|
|
0a3e0665ab | ||
|
|
a19f1fbc67 | ||
|
|
2aa4615c78 | ||
|
|
7dd1346878 | ||
|
|
31f8c7d9cb | ||
|
|
914ce0b94d | ||
|
|
664f09111e | ||
|
|
6141f414fd | ||
|
|
8911f0f217 | ||
|
|
5af108ccee | ||
|
|
94e4169445 | ||
|
|
479b5b7064 | ||
|
|
674e935cf5 | ||
|
|
6b4982d75b | ||
|
|
4167743a34 | ||
|
|
ba289f6db4 | ||
|
|
422fd11f4d | ||
|
|
614d9c9b0d | ||
|
|
f91be86662 | ||
|
|
72f05544e8 | ||
|
|
81f55820be | ||
|
|
b9c14e1d65 | ||
|
|
5c55453a0e | ||
|
|
12491c4983 | ||
|
|
77d379c021 | ||
|
|
1a12a59e91 | ||
|
|
0b970dd9c7 | ||
|
|
93ac2bd53e | ||
|
|
f9646ac47a | ||
|
|
e8ed3b9e23 | ||
|
|
6238a07c8f | ||
|
|
1fb33f0c47 | ||
|
|
a842f41627 | ||
|
|
c4c135e678 | ||
|
|
f36f2fdea2 | ||
|
|
e3f0a67584 | ||
|
|
f6f05fa0c6 | ||
|
|
54ca7ceac8 | ||
|
|
cf5b38d4f5 | ||
|
|
b23669400f | ||
|
|
aaacd00ecf | ||
|
|
03aa22ba84 | ||
|
|
1493b8703f | ||
|
|
59308c20c6 | ||
|
|
cac5d8e716 | ||
|
|
7f16757bbe | ||
|
|
674e3846e2 | ||
|
|
3a0be0cca9 | ||
|
|
00d7c3a05a | ||
|
|
91f5fca5e9 | ||
|
|
1d7cb0c119 | ||
|
|
24599aa64f | ||
|
|
54c1553892 | ||
|
|
0ae53ce1a1 | ||
|
|
c69ffe02f8 | ||
|
|
7bfc2e0e74 | ||
|
|
9cc674c283 | ||
|
|
66e597a05c | ||
|
|
074c636e53 | ||
|
|
4ec44936f6 | ||
|
|
eb9c41f2a0 | ||
|
|
04afb99c54 | ||
|
|
2124e7b221 | ||
|
|
2416a8bf96 | ||
|
|
408a40f78b | ||
|
|
195ae5ce4b | ||
|
|
9bebb1e9a9 | ||
|
|
e7bec5be1d | ||
|
|
c708e8ba8e | ||
|
|
60f26cc067 | ||
|
|
64fa058bc7 | ||
|
|
9a770eeae9 | ||
|
|
ffc2c5a26e | ||
|
|
b6c5bd552e | ||
|
|
05147a3199 | ||
|
|
7f0d08ad77 | ||
|
|
64f95af833 | ||
|
|
7cd2662355 | ||
|
|
154d485c9e | ||
|
|
5f6821c7e2 | ||
|
|
59cf823d56 | ||
|
|
70312c58be | ||
|
|
4942366271 | ||
|
|
f237d0f212 | ||
|
|
9b424e0fe7 | ||
|
|
81b75d178b | ||
|
|
410e732eb3 | ||
|
|
2ca93cd93d | ||
|
|
50c806286e | ||
|
|
59de835b42 | ||
|
|
ecbac76cba | ||
|
|
9b16f2139d | ||
|
|
ef14df5ba2 | ||
|
|
b4be9875b2 | ||
|
|
8d0c962f42 | ||
|
|
5e0cb8d658 | ||
|
|
1869ab94fe | ||
|
|
2627c5baaf | ||
|
|
e4e16b8f77 | ||
|
|
85218d74d4 | ||
|
|
47d5b66986 | ||
|
|
ecfb133de2 | ||
|
|
23c95d24f1 | ||
|
|
b37d89bd08 | ||
|
|
5c848d59b2 | ||
|
|
b1c04dece9 | ||
|
|
b87c7987bb | ||
|
|
0bef52ae7d | ||
|
|
9ae04cf1ec | ||
|
|
0f7c4a8d4f | ||
|
|
07353207c0 | ||
|
|
d89be83414 | ||
|
|
01382527f5 | ||
|
|
dece2193fc | ||
|
|
d298f864fa | ||
|
|
ff37d8c691 | ||
|
|
f7f305a564 | ||
|
|
86f38e11cd | ||
|
|
0b60c48253 | ||
|
|
024b9840f0 | ||
|
|
2f4f59d82f | ||
|
|
830d5ee763 | ||
|
|
5bc63f7a33 | ||
|
|
b54f970e12 | ||
|
|
0cc8c54152 | ||
|
|
241e1e27d0 | ||
|
|
0145e86202 | ||
|
|
4d50e1e373 | ||
|
|
4b6ae34800 | ||
|
|
2feb85e831 | ||
|
|
a67ac81265 | ||
|
|
dab536c9e8 | ||
|
|
64cf298521 | ||
|
|
10b5aaa6a5 | ||
|
|
8c79e5ccfb | ||
|
|
2ef536a342 | ||
|
|
85b1303460 | ||
|
|
60aca3a241 | ||
|
|
db98381a86 | ||
|
|
f62ef34715 | ||
|
|
f95a6c1a5a | ||
|
|
65555b5dd0 | ||
|
|
9f6331a35e | ||
|
|
8c10cb6230 | ||
|
|
c8894bcead | ||
|
|
edc602c33a | ||
|
|
abfb2ca810 | ||
|
|
9967efe45a | ||
|
|
e77d80bda5 | ||
|
|
a691d1750a | ||
|
|
834e2f9304 | ||
|
|
66e5e9c1ce | ||
|
|
2d5f613984 | ||
|
|
868e7a278f | ||
|
|
f953d17889 | ||
|
|
3473969aae | ||
|
|
ec11ae7c40 | ||
|
|
8217ee1bbb | ||
|
|
1ad3ee0aec | ||
|
|
b3e9a2fede | ||
|
|
2f5d6bf909 | ||
|
|
cd79f479e9 | ||
|
|
12c0f675ce | ||
|
|
29471b8019 | ||
|
|
cad661f0c8 | ||
|
|
261d770482 | ||
|
|
a75c9c74fd | ||
|
|
8b5bdf9a16 | ||
|
|
e35eba2d51 | ||
|
|
df8c88cef4 | ||
|
|
844e12769c | ||
|
|
b982626ac4 | ||
|
|
517b2b42a6 | ||
|
|
6778c33628 | ||
|
|
bc0b11e1ef | ||
|
|
6b0d4b9c93 | ||
|
|
7d4e4f029e | ||
|
|
1fbdb629ff | ||
|
|
a437237947 | ||
|
|
910637c549 | ||
|
|
e8974a3e69 | ||
|
|
6c98310f7f | ||
|
|
72aed0d26d | ||
|
|
e10ef8b9e0 | ||
|
|
39fa8ba831 | ||
|
|
8ee8279044 | ||
|
|
c3f85c3bb2 | ||
|
|
ad59c4cbf3 | ||
|
|
26bc981981 | ||
|
|
514c34b242 | ||
|
|
6f266c0090 | ||
|
|
baa7352ca6 | ||
|
|
fdb1c8d99a | ||
|
|
79f5dba094 | ||
|
|
2134965f16 | ||
|
|
77b7a59a27 | ||
|
|
365e7126d0 | ||
|
|
d3daf9d159 | ||
|
|
8d59a519a6 | ||
|
|
239262f360 | ||
|
|
9eb938fd6f | ||
|
|
3fcbf1a43f | ||
|
|
2b7ee271df | ||
|
|
11512c6281 | ||
|
|
b16ba547ab | ||
|
|
e5b8899b4c | ||
|
|
fee3e9e63b | ||
|
|
57a24d30b5 | ||
|
|
5a83610fb1 | ||
|
|
96086f12c6 | ||
|
|
a6ee3ce07f | ||
|
|
5f36ddd425 | ||
|
|
bec67074e0 | ||
|
|
895c92cdae | ||
|
|
7406a5bc26 | ||
|
|
ef97714404 | ||
|
|
6d6daee511 | ||
|
|
32cd1c2a65 | ||
|
|
abad920a8a | ||
|
|
e1ab49e100 | ||
|
|
df300e89a2 | ||
|
|
9a278bed21 | ||
|
|
4a7fc084ce | ||
|
|
2649e736fb | ||
|
|
42ac891e28 | ||
|
|
4dc3b9072e | ||
|
|
ae3235b099 | ||
|
|
7cc5e0d577 | ||
|
|
f6b956dc8e | ||
|
|
fcb2bacd1e | ||
|
|
a9401e921e | ||
|
|
02e7e315b2 | ||
|
|
def72a64e0 | ||
|
|
46e7672197 | ||
|
|
2f8a5ce935 | ||
|
|
730e5bd831 | ||
|
|
b7984a05af | ||
|
|
5d4af67186 | ||
|
|
370e08cf4d | ||
|
|
aaf7e3f943 | ||
|
|
fbde0936e7 | ||
|
|
af48f7bab4 | ||
|
|
61def89878 | ||
|
|
88e86cee77 | ||
|
|
acc1625406 | ||
|
|
502f448053 | ||
|
|
55b081884c | ||
|
|
fd67171908 | ||
|
|
16a53aa641 | ||
|
|
4aec676950 | ||
|
|
d8fff0e90a | ||
|
|
57ad6cc3ea | ||
|
|
2b46a8b9c9 | ||
|
|
4d1a2e8c53 | ||
|
|
58b1409bd2 | ||
|
|
a2525dbf56 | ||
|
|
36eb2a31b5 | ||
|
|
0483bfc9cb | ||
|
|
3f63a64254 | ||
|
|
16332b285f | ||
|
|
f7371f6faf | ||
|
|
92d29805f1 | ||
|
|
4a37d07acb | ||
|
|
bb4c61e9cc | ||
|
|
f4e5515c82 | ||
|
|
141a2df19c | ||
|
|
e2385b4922 | ||
|
|
9974fb50f7 | ||
|
|
c5d51d62c4 | ||
|
|
4fcbf28f91 | ||
|
|
f678b664ff | ||
|
|
4206920a7d | ||
|
|
ad2e5ead54 | ||
|
|
eb72719117 | ||
|
|
20b46afbf2 | ||
|
|
1925e4a7f4 | ||
|
|
1a12322354 | ||
|
|
73f3f4ec7e | ||
|
|
a8c42f453a | ||
|
|
79dd0c5ba6 | ||
|
|
89bc3b6b16 | ||
|
|
a997dd6c49 | ||
|
|
6aa80d2a4c | ||
|
|
f009e8fb14 | ||
|
|
a8dde17155 | ||
|
|
cbcbff341b | ||
|
|
e50992bb93 | ||
|
|
fa6c3068c0 | ||
|
|
dd9bdca572 | ||
|
|
3f7dffe47d | ||
|
|
c7fde14458 | ||
|
|
57f4186cad | ||
|
|
fa5a6021b1 | ||
|
|
42ae279b91 | ||
|
|
a74cdbfc28 | ||
|
|
a56fa567dd | ||
|
|
c9c2d5ab6f | ||
|
|
ccf460c1f7 | ||
|
|
2325f542b8 | ||
|
|
63fdf3f3f6 | ||
|
|
efa83bdf34 | ||
|
|
5705bda818 | ||
|
|
20042334ff | ||
|
|
7ae9569816 | ||
|
|
cacba526b3 | ||
|
|
50f203cc8a | ||
|
|
3efcd154f3 | ||
|
|
bdb08d7c78 | ||
|
|
f3874dd40a | ||
|
|
935c39e341 | ||
|
|
7ddcc30e8d | ||
|
|
13ff038e58 | ||
|
|
1d4918dfbf | ||
|
|
ba14ab96da | ||
|
|
054e0820b7 | ||
|
|
af3d8dd6a7 | ||
|
|
e10d06cb47 | ||
|
|
87a1469c1e | ||
|
|
2492f1635c | ||
|
|
b3305e6e19 | ||
|
|
491d3e6606 | ||
|
|
e41bf67f73 | ||
|
|
66b99c4fa0 | ||
|
|
f2f2645fe6 | ||
|
|
4c77d0509a | ||
|
|
33d77f4355 | ||
|
|
ecf8617246 | ||
|
|
bec216d72a | ||
|
|
374e8c3307 | ||
|
|
b5eff8a9dd | ||
|
|
d53002a494 | ||
|
|
04662f0875 | ||
|
|
aec92c7c17 | ||
|
|
f7a7976923 | ||
|
|
1b50d4507f | ||
|
|
045cf887df | ||
|
|
277d7c0e04 | ||
|
|
0e2c703e77 | ||
|
|
62b3f38f00 | ||
|
|
422658293d | ||
|
|
74cfd05642 | ||
|
|
80586f1de3 | ||
|
|
a933177ac0 | ||
|
|
ade2db696b | ||
|
|
cf266037ff | ||
|
|
5f14277fbf | ||
|
|
b677349ec9 | ||
|
|
7f72d2a703 | ||
|
|
779983cb85 | ||
|
|
f2d2ab51b1 | ||
|
|
0a54f8c4a7 | ||
|
|
881527ddd0 | ||
|
|
cca4f894a8 | ||
|
|
20dae33be5 | ||
|
|
fd301c519d | ||
|
|
a96d87814b | ||
|
|
2a3eefc5be | ||
|
|
c5dc10e3cd | ||
|
|
c251a93609 | ||
|
|
2df509effd | ||
|
|
53e0d670b3 | ||
|
|
ccd19d2c96 | ||
|
|
b69f084db9 | ||
|
|
9639395937 | ||
|
|
117b7afd81 | ||
|
|
009c4dc8db | ||
|
|
0fdf3fc851 | ||
|
|
ffc2d91cef | ||
|
|
99975c8ff7 | ||
|
|
d44fd6b46d | ||
|
|
bd0a1426d7 | ||
|
|
353d144039 | ||
|
|
6efdf8a7f4 | ||
|
|
623770e24b | ||
|
|
402940a215 | ||
|
|
7fea85cdcd | ||
|
|
93b3b7a184 | ||
|
|
8f2a84629a | ||
|
|
7a1c1982f0 | ||
|
|
75d8982b23 | ||
|
|
87dbb56d7e | ||
|
|
aa217a3a43 | ||
|
|
22fc961dc0 | ||
|
|
8f57186945 | ||
|
|
f8277c55a8 | ||
|
|
6163713e34 | ||
|
|
d2d5887936 | ||
|
|
2a1065efc1 | ||
|
|
6f36a97c4a | ||
|
|
eeed79009a | ||
|
|
9930057171 | ||
|
|
e14c84f2fb | ||
|
|
a664c3dd47 | ||
|
|
73205b1f8c | ||
|
|
3016d7b8f3 | ||
|
|
beb3ddaa1f | ||
|
|
8db48fb4f1 | ||
|
|
6eb3641c1d | ||
|
|
8cfd64a7be | ||
|
|
e8d9ef269b | ||
|
|
80f83da9b8 | ||
|
|
6b8e235f88 | ||
|
|
a1d558a960 | ||
|
|
071ec80e2a | ||
|
|
995541db2e | ||
|
|
9121026856 | ||
|
|
341419788e | ||
|
|
f8f69fadc4 | ||
|
|
4830d82a73 | ||
|
|
f3a228c79a | ||
|
|
4bf96aaca0 | ||
|
|
a8a026d509 | ||
|
|
e1fd506269 | ||
|
|
63e86b5673 | ||
|
|
238299c759 | ||
|
|
4e9272e31c | ||
|
|
8f92c32693 | ||
|
|
699e283890 | ||
|
|
c51afc952c | ||
|
|
8fc030ba83 | ||
|
|
b754757c94 | ||
|
|
16bb40406a | ||
|
|
290ae04988 | ||
|
|
5c6f0e4d32 | ||
|
|
14143243b1 | ||
|
|
0e2c0c78f2 | ||
|
|
2a8e1f41d0 | ||
|
|
4e1d18e206 | ||
|
|
ff5a947a16 | ||
|
|
26ddb1e479 | ||
|
|
b2ddfd21c1 | ||
|
|
efe9268bcb | ||
|
|
974e618541 | ||
|
|
d09d281a8d | ||
|
|
43f3f54063 | ||
|
|
2b303e162c | ||
|
|
3947a755b1 | ||
|
|
0b764f4cb8 | ||
|
|
a0101c14a6 | ||
|
|
a4dcde2fc2 | ||
|
|
f6f5955753 | ||
|
|
d87f9fbd79 | ||
|
|
4c2bc47bf3 | ||
|
|
0d983d504b | ||
|
|
f26ccfa3e9 | ||
|
|
1ec6ba35e0 | ||
|
|
0378ea40e7 | ||
|
|
656250dd33 | ||
|
|
b914fa6da8 | ||
|
|
db77ec43a7 | ||
|
|
1a9d4bfb1c | ||
|
|
7180cb049c | ||
|
|
7e2769d8df | ||
|
|
23faeeb5d0 | ||
|
|
1e689a69a8 | ||
|
|
19004c0bad | ||
|
|
82059bb454 | ||
|
|
3fc846471e | ||
|
|
5379d45184 | ||
|
|
65b8bf6834 | ||
|
|
107dfcac65 | ||
|
|
2a29d077ee | ||
|
|
3d7f1f39ce | ||
|
|
51c02da206 | ||
|
|
16250e1b7c | ||
|
|
3e02c5e4a8 | ||
|
|
40da942bfe | ||
|
|
44909912cd | ||
|
|
631ee98738 | ||
|
|
0b68eea44a | ||
|
|
47743e7f90 | ||
|
|
b2da3545f9 | ||
|
|
fb005dd01b | ||
|
|
5b2bd90071 | ||
|
|
25e258e26a | ||
|
|
75d24974ec | ||
|
|
981bd950da | ||
|
|
0ca1886695 | ||
|
|
bf2f9e0f7e | ||
|
|
d74f1c22ff | ||
|
|
882e09f253 | ||
|
|
ce05c0e13d | ||
|
|
45c92f0868 | ||
|
|
e952f90b4c | ||
|
|
97bf5e8d69 | ||
|
|
ee7bb71a05 | ||
|
|
791cbab6f6 | ||
|
|
e001b7fb46 | ||
|
|
d8a75bef48 | ||
|
|
cfc4b79a05 | ||
|
|
fb3e5c9aab | ||
|
|
6796d8f124 | ||
|
|
154cb463e5 | ||
|
|
e9ce04ffe9 | ||
|
|
7a3fd11b6b | ||
|
|
e885f848a6 | ||
|
|
8343f074a2 | ||
|
|
cbadfd59db | ||
|
|
5d5fed62f2 | ||
|
|
c3d6484f6c | ||
|
|
315abec49c | ||
|
|
221b382e69 | ||
|
|
5fdbfef028 | ||
|
|
2cc671df75 | ||
|
|
ddbe2853ea | ||
|
|
2ab1b4b1c2 | ||
|
|
c5adc92f8b | ||
|
|
96b6056411 | ||
|
|
1108566e99 | ||
|
|
a54a5ee80d | ||
|
|
d57bc3ff01 | ||
|
|
f02dca2dd8 | ||
|
|
ad186701d3 | ||
|
|
a04b9ea053 | ||
|
|
41e6fb961b | ||
|
|
b2b43d2bd3 | ||
|
|
90339f9741 | ||
|
|
260806053b | ||
|
|
93c9bdcec7 | ||
|
|
935832028a | ||
|
|
c08f09b06b | ||
|
|
16410cf263 | ||
|
|
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 | ||
|
|
ee837889db | ||
|
|
a5f4cba72f | ||
|
|
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 | ||
|
|
83a6865eb3 | ||
|
|
29a9b650ed | ||
|
|
dd48b740f9 | ||
|
|
401ce7a63d | ||
|
|
8218d085f7 | ||
|
|
abb3c936f7 | ||
|
|
0cb5aca81e | ||
|
|
554d274fff | ||
|
|
13318219db | ||
|
|
474944fe74 | ||
|
|
d1a49cd9ce | ||
|
|
139d89d817 | ||
|
|
61759f984c | ||
|
|
a73e77a819 | ||
|
|
b5f1659382 | ||
|
|
beb6722f57 | ||
|
|
a052b89152 | ||
|
|
95b391350f | ||
|
|
5773eac03f | ||
|
|
da4ace2875 | ||
|
|
e507c5b502 | ||
|
|
722c2c2668 | ||
|
|
8e7bfef9f1 | ||
|
|
1811f0d0d5 | ||
|
|
6b9d534fe2 | ||
|
|
dc4562a845 | ||
|
|
c15af63bc9 | ||
|
|
5b68c2c7d9 | ||
|
|
b70e0bd1f6 | ||
|
|
743f0f5540 | ||
|
|
e647a5b733 | ||
|
|
df1d259e42 | ||
|
|
e3efab7fbf | ||
|
|
cd79f7f4b0 | ||
|
|
5d175745bf | ||
|
|
e648bac74b | ||
|
|
e5c0ebd0a0 | ||
|
|
608a43402c | ||
|
|
75bc2dd564 | ||
|
|
bbd81c3cf7 | ||
|
|
301eb7c74d | ||
|
|
a756039f27 | ||
|
|
b4d1b71ee7 | ||
|
|
8d85a4754d | ||
|
|
a1b48049a9 | ||
|
|
6789844c1f | ||
|
|
c602a839ca | ||
|
|
01c7793e90 | ||
|
|
47b013b034 | ||
|
|
dc2047804a | ||
|
|
885e5cbd7c | ||
|
|
635a5196e8 | ||
|
|
cbd339190b | ||
|
|
266093189d | ||
|
|
62b02d4370 | ||
|
|
8546a1dc86 | ||
|
|
ae98bf237f | ||
|
|
0398deb005 | ||
|
|
3a1492977b | ||
|
|
ef40a456e8 | ||
|
|
583b78c0c1 | ||
|
|
c0988de581 | ||
|
|
34a190e29b | ||
|
|
0940598708 | ||
|
|
7e6cbb3efa | ||
|
|
7dc4e00c75 | ||
|
|
8a598eacaf | ||
|
|
8592fad9cd | ||
|
|
fa72a89d35 | ||
|
|
5e99c51d93 | ||
|
|
905976e765 | ||
|
|
3ebd47d3db | ||
|
|
bf4c7c475a | ||
|
|
bf38371971 | ||
|
|
18460f4f91 | ||
|
|
f94e3e6aba | ||
|
|
1647da2942 | ||
|
|
86e2cdb1fb | ||
|
|
764702a377 | ||
|
|
837a97ffdf | ||
|
|
217e9b96d8 | ||
|
|
524274fcf4 | ||
|
|
6d5f576b92 | ||
|
|
445f9fa7df | ||
|
|
2ff3a23606 | ||
|
|
c5ce57ea7f | ||
|
|
351b8e50f0 | ||
|
|
68be6c5742 | ||
|
|
7a34a2dfa9 | ||
|
|
49ce9e1209 | ||
|
|
c84e192324 | ||
|
|
d696673f07 | ||
|
|
2957d463c9 | ||
|
|
af48e50898 | ||
|
|
f4b964a4b8 | ||
|
|
a79ce7a151 | ||
|
|
21bb83c55a | ||
|
|
7122ceb16c | ||
|
|
f9bcfe341c | ||
|
|
13c5bfdd88 | ||
|
|
bf79c2cb99 | ||
|
|
325cdfcf57 | ||
|
|
7d14d4ade9 | ||
|
|
1b7d12194e | ||
|
|
91f238aded | ||
|
|
78ff489995 | ||
|
|
ff791439e2 | ||
|
|
3f8b2d6b99 | ||
|
|
4dcbce58ed | ||
|
|
0427deb897 | ||
|
|
f3eb3409e3 | ||
|
|
86619052ca | ||
|
|
0c59d3234e | ||
|
|
939d7ea3fb | ||
|
|
dc8761763d | ||
|
|
4894914db1 | ||
|
|
aee94a0584 | ||
|
|
c550422168 | ||
|
|
cebd9cabb3 | ||
|
|
3f16652d56 | ||
|
|
2ebf48ca71 | ||
|
|
c2f184f5bb | ||
|
|
e56651e5c0 | ||
|
|
1d09e96127 | ||
|
|
73de0ea8be | ||
|
|
757eac0579 | ||
|
|
bb78e2f57f | ||
|
|
92579243c5 | ||
|
|
8d0ba40d67 | ||
|
|
ff8c1aace9 | ||
|
|
cf74dc9b48 | ||
|
|
e63df83091 | ||
|
|
14522dbbcd | ||
|
|
91daea9e01 | ||
|
|
12b789fc4e | ||
|
|
baa13351a6 | ||
|
|
8f83204f0f | ||
|
|
80f5b60e1d | ||
|
|
54525f6696 | ||
|
|
3dc50216b5 | ||
|
|
324430a696 | ||
|
|
65d7957610 | ||
|
|
6ac4993cf2 | ||
|
|
100744a952 | ||
|
|
3a331e55dc | ||
|
|
a57f81ba5f | ||
|
|
ca0b55fbbf | ||
|
|
38a3cf98dd | ||
|
|
1234ad92e5 | ||
|
|
488edc24ce | ||
|
|
307c23631a | ||
|
|
83d2241883 | ||
|
|
f9126416e8 | ||
|
|
4e9ae16cb3 | ||
|
|
ef8bfdffa7 | ||
|
|
bfb090331f | ||
|
|
5506d0f25b | ||
|
|
6ebd2d0883 | ||
|
|
a16dcaba4e | ||
|
|
f06452c6c5 | ||
|
|
6a0a97cb41 | ||
|
|
711102b438 | ||
|
|
6d53eb0aaa | ||
|
|
0ccf04a2c5 | ||
|
|
070ce35b44 | ||
|
|
a8296e5de5 | ||
|
|
d17f25e975 | ||
|
|
23095ada85 | ||
|
|
f9ef161991 | ||
|
|
28004bae2f | ||
|
|
17aef7be7d | ||
|
|
ebba8f5110 | ||
|
|
dbd7f51f5c | ||
|
|
fbadfcfa7c | ||
|
|
2c12234604 | ||
|
|
13cb6a315c | ||
|
|
48e7376002 | ||
|
|
60d82eddee | ||
|
|
30ee89c7e9 | ||
|
|
25bcea6aec | ||
|
|
488c88da91 | ||
|
|
8fdcd92260 | ||
|
|
781a40df52 | ||
|
|
2412c81d92 | ||
|
|
a7fc0f9d2e | ||
|
|
9eab021a50 | ||
|
|
c189a52e5e | ||
|
|
6d6d763dd3 | ||
|
|
3cfbaa0ed6 | ||
|
|
e1b4571fdf | ||
|
|
08027ea9c4 | ||
|
|
d0528a00c1 | ||
|
|
7ae6a2ba9a | ||
|
|
ad0e5c4770 | ||
|
|
51b181d5fb | ||
|
|
2785b0a857 | ||
|
|
45a113ff9e | ||
|
|
cee59c2ca3 | ||
|
|
5cb9b242e2 | ||
|
|
1ed48de928 | ||
|
|
c4e4bc71ed | ||
|
|
ed0763706b | ||
|
|
1c79d517fc | ||
|
|
1a7a2f3088 | ||
|
|
4199789786 | ||
|
|
c9b0941d1f | ||
|
|
3d544136d2 | ||
|
|
8448eff1eb | ||
|
|
a3dde4599a | ||
|
|
3d7440c673 | ||
|
|
8f41006eba | ||
|
|
7d1379fe9f | ||
|
|
ced4f9f0d9 | ||
|
|
7fba332f58 | ||
|
|
8eda09533d | ||
|
|
6c42ee4edf | ||
|
|
3053595bfe | ||
|
|
6cf78d1a3f | ||
|
|
6c0ee9d917 | ||
|
|
50051dbfd5 | ||
|
|
30a8c5e12e | ||
|
|
4498549783 | ||
|
|
2ce3fedbfc | ||
|
|
8e10be665c | ||
|
|
80636cb8aa | ||
|
|
1b893da07d | ||
|
|
2f8aa3471b | ||
|
|
92a6957f0b | ||
|
|
d7248b11e5 | ||
|
|
6f4ed00105 | ||
|
|
347b299bbc | ||
|
|
614d297f22 | ||
|
|
59d0fe00c3 | ||
|
|
d6ebdff28f | ||
|
|
0ec16d0eab | ||
|
|
3906894fde | ||
|
|
a43772b21d | ||
|
|
cd81c2619b | ||
|
|
5abadc31a3 | ||
|
|
87654b698b | ||
|
|
2a1d2ef294 | ||
|
|
2a387707ef | ||
|
|
ce68062290 | ||
|
|
1b9073b085 | ||
|
|
e94961a14f | ||
|
|
d4e77b3be4 | ||
|
|
b96b36d5ea | ||
|
|
72d559a92c | ||
|
|
9a7bdcb6db | ||
|
|
2e4cf48e7e | ||
|
|
b78f8abeb4 | ||
|
|
7aa4e44317 | ||
|
|
2619b92131 | ||
|
|
28be59582f | ||
|
|
f96cc03587 | ||
|
|
cbd35b0e87 | ||
|
|
443acbe4b5 | ||
|
|
1f0d26e8c7 | ||
|
|
8302e9d0dd | ||
|
|
c797af020a | ||
|
|
1c85afa320 | ||
|
|
eb5317f8e5 | ||
|
|
8b860615b8 | ||
|
|
c15ac341e2 | ||
|
|
c2c7ee1047 | ||
|
|
72c46ccec6 | ||
|
|
dd3bfaee01 | ||
|
|
03206ad90e | ||
|
|
2e00307190 | ||
|
|
b3e29ab20e | ||
|
|
5504ac535b | ||
|
|
4b3dd7f4ea | ||
|
|
8edf9540d5 | ||
|
|
1c62ecd1b5 | ||
|
|
7cf3d9f3ce | ||
|
|
9b5a703307 | ||
|
|
370993cbed | ||
|
|
ddc538cdfa | ||
|
|
062dc43c87 | ||
|
|
7d9b986c04 | ||
|
|
bd2b9a12ed | ||
|
|
2b55707738 | ||
|
|
093540507e | ||
|
|
8f1dcfda07 | ||
|
|
16b319174b | ||
|
|
35115f5707 | ||
|
|
e9e51db9c7 | ||
|
|
ec39f018e2 | ||
|
|
59f4a3bcc7 | ||
|
|
1a8949eea3 | ||
|
|
fa85bdceed | ||
|
|
6b703244ec | ||
|
|
1a1cb0d3f1 | ||
|
|
95c9863d0a | ||
|
|
82187f6a71 | ||
|
|
75f52a1324 | ||
|
|
6e076a40a9 | ||
|
|
ded60036cb | ||
|
|
539a6cde63 | ||
|
|
3a28e74d89 | ||
|
|
c93f3faed9 | ||
|
|
1aaa3d9279 | ||
|
|
a06a9ed7d8 | ||
|
|
18a88596a6 | ||
|
|
2ac077603b | ||
|
|
3bb8b163b8 | ||
|
|
aac45097ca | ||
|
|
788956e86d | ||
|
|
e917424f5d | ||
|
|
1f6a5d04d9 | ||
|
|
dba844c7f9 | ||
|
|
09c11ef8ad | ||
|
|
ff21669bb5 | ||
|
|
a059ca2537 | ||
|
|
f4531b9434 | ||
|
|
05b350ac4b | ||
|
|
cfba315a85 | ||
|
|
12188b6684 | ||
|
|
725b2fc16f | ||
|
|
90a28e31e8 | ||
|
|
c057b00e08 | ||
|
|
b0c0104ba3 | ||
|
|
855b184e91 | ||
|
|
bc88242dc0 | ||
|
|
6357cd623f | ||
|
|
d3e7d20e30 | ||
|
|
7b568c2df3 | ||
|
|
2bff0522e8 | ||
|
|
77e180171c | ||
|
|
1e8fc97ba4 | ||
|
|
a799851832 | ||
|
|
2c81105bfc | ||
|
|
bf99ac56a0 | ||
|
|
8bfb47948a | ||
|
|
b8c41198a3 | ||
|
|
fe138ac05b | ||
|
|
bed62fdcb5 | ||
|
|
f068df0297 | ||
|
|
6a05e34d20 | ||
|
|
8b69b9c6a4 | ||
|
|
10192296fe | ||
|
|
7b98db2f7d | ||
|
|
81696c2e7a | ||
|
|
16a4f823bd | ||
|
|
39bbfc56a4 | ||
|
|
308c49b2d8 | ||
|
|
53e46a9251 | ||
|
|
6075b3dc33 | ||
|
|
860a828973 | ||
|
|
033eaa36c6 | ||
|
|
b3566f5449 | ||
|
|
f1306d3301 | ||
|
|
cc18441435 | ||
|
|
7e787d93e6 | ||
|
|
b08f444e74 | ||
|
|
09c1acdbe2 | ||
|
|
7a4a956eff | ||
|
|
aabbf5a72f | ||
|
|
5ed44bb174 | ||
|
|
92cf2cbd47 | ||
|
|
34aff6c786 | ||
|
|
11f10e586a | ||
|
|
a31feae2bd | ||
|
|
3517d58f01 | ||
|
|
9d13fadd41 | ||
|
|
c1febce528 | ||
|
|
e0aadbd961 | ||
|
|
7b9a76c5ea | ||
|
|
6133fa8384 | ||
|
|
67cc215ed3 | ||
|
|
ea4ad2ea4d | ||
|
|
847454a4f7 | ||
|
|
8cba1fdd71 | ||
|
|
e56112739c | ||
|
|
76988b746f | ||
|
|
32eb365a0b | ||
|
|
2c5feddad5 | ||
|
|
210500ff3e | ||
|
|
7c8f10e832 | ||
|
|
644da2f9e4 | ||
|
|
2a80d9c555 | ||
|
|
76f8791f3c | ||
|
|
c51a013109 | ||
|
|
88c2f95ea5 | ||
|
|
062fa7de78 | ||
|
|
d6c1a41e8d | ||
|
|
20ab5f9326 | ||
|
|
ab5a8b24a5 | ||
|
|
21a28623ca | ||
|
|
06a5fec612 | ||
|
|
46ecb8a663 | ||
|
|
3c9c6eef6e | ||
|
|
72734de376 | ||
|
|
a20ea09a6e | ||
|
|
4bd7bce232 | ||
|
|
8adf42216d | ||
|
|
5f40aaabb5 | ||
|
|
5295abbb83 | ||
|
|
201abe1524 | ||
|
|
6d26051d11 | ||
|
|
4613bf78d5 | ||
|
|
1f8fdc6f5c | ||
|
|
abf804cf10 | ||
|
|
d7a195706f | ||
|
|
569370109a | ||
|
|
eae3f04c83 | ||
|
|
ee0987f331 | ||
|
|
bdafa842bd | ||
|
|
76c7c2562c | ||
|
|
f7de2234f2 | ||
|
|
c725c45726 | ||
|
|
383bef456d | ||
|
|
7f48f3d01d | ||
|
|
0bf17a48f7 | ||
|
|
c127f8f2f0 | ||
|
|
d4d5d15e18 | ||
|
|
b254afa498 | ||
|
|
0ce5a94c15 | ||
|
|
38a5405c65 | ||
|
|
ecef784686 | ||
|
|
e82b2c12b4 | ||
|
|
3c26ced8db | ||
|
|
2681a41abb | ||
|
|
805deb1002 | ||
|
|
6b792de802 | ||
|
|
26f8e34dcb | ||
|
|
e0c1b2458c | ||
|
|
66f94d2141 | ||
|
|
503a9a0038 | ||
|
|
d8a5bc3ae9 | ||
|
|
94c3957d92 | ||
|
|
266350b8ce | ||
|
|
fedaede3b0 | ||
|
|
721d852cc7 | ||
|
|
ffbf205aba | ||
|
|
e1a1e43c3a | ||
|
|
c538817b61 | ||
|
|
71d85d2771 | ||
|
|
69f4d5fca7 | ||
|
|
bb31fc5301 | ||
|
|
87ce51e314 | ||
|
|
33555ca2ea | ||
|
|
6fc3776c0c | ||
|
|
8a05f05bd4 | ||
|
|
0dff51920e | ||
|
|
262f217d04 | ||
|
|
8b9154bab0 | ||
|
|
533613d92b | ||
|
|
20d87e1136 | ||
|
|
1450c4194e | ||
|
|
bc82baa968 | ||
|
|
218623be28 | ||
|
|
ea1a4ecdc6 | ||
|
|
6acbff3c11 | ||
|
|
153021efcf | ||
|
|
fef1b59b42 | ||
|
|
733b11b7d4 | ||
|
|
400514ff10 | ||
|
|
bbfac316fc | ||
|
|
7d0b67f70e | ||
|
|
d0f1b38848 | ||
|
|
4d4b5bc366 | ||
|
|
1f39c7ef0d | ||
|
|
2e97fcc47f | ||
|
|
550c8322c4 | ||
|
|
2467e23033 | ||
|
|
0e53198c59 | ||
|
|
94ff9dc0a4 | ||
|
|
44063590e2 | ||
|
|
557f25bf80 | ||
|
|
190531543f | ||
|
|
acfb7c3a89 | ||
|
|
94a6d3bc7e | ||
|
|
5751bcd382 | ||
|
|
21b88c0e65 | ||
|
|
f66b916d4b | ||
|
|
bd9c43a48d | ||
|
|
352b91f342 | ||
|
|
be6e3254ea | ||
|
|
dd1ee209ab | ||
|
|
c0b1101a52 | ||
|
|
52c49fc8fd | ||
|
|
77cb64958e | ||
|
|
b3d13e44b2 | ||
|
|
9dd7b795ca | ||
|
|
7a8399571a | ||
|
|
d0e85d9c2c | ||
|
|
14d02bc843 | ||
|
|
b79c09cf58 | ||
|
|
c9dfe5daff | ||
|
|
092e7f6b3c | ||
|
|
203634314c | ||
|
|
c472e6e160 | ||
|
|
86d9275375 | ||
|
|
9db6780af6 | ||
|
|
e10205ff69 | ||
|
|
9f539436b8 | ||
|
|
acd75e1083 | ||
|
|
f30225db90 | ||
|
|
007305962a | ||
|
|
8065e38797 | ||
|
|
34dc684867 | ||
|
|
7edc9603d0 | ||
|
|
479d476878 | ||
|
|
92bbec1852 | ||
|
|
d406636878 | ||
|
|
6362199363 | ||
|
|
22dbcb7590 | ||
|
|
cefea38ee5 | ||
|
|
d44cd01493 | ||
|
|
e578655653 | ||
|
|
434dc27557 | ||
|
|
d4a88d08e4 | ||
|
|
79af39bd2c | ||
|
|
20d5a9fd4b | ||
|
|
80e57ca074 | ||
|
|
8a3c95d8dd | ||
|
|
4941a360cb | ||
|
|
9e7219c4d6 | ||
|
|
4d96728709 | ||
|
|
816fd5e65c | ||
|
|
8d4175536f | ||
|
|
bba9ca3d5a | ||
|
|
8bc9ebf2aa | ||
|
|
dad335b8b6 | ||
|
|
62e93d4002 | ||
|
|
728f4a0f81 | ||
|
|
0cafd6ee4b | ||
|
|
2962e51dac | ||
|
|
cf5733b237 | ||
|
|
c96e3326bc | ||
|
|
1cd373c0a5 | ||
|
|
ae970cf2da | ||
|
|
d43a01f182 | ||
|
|
42aac55b82 | ||
|
|
a66f31dc87 | ||
|
|
64c48f2151 | ||
|
|
9eead8a904 | ||
|
|
7761bccffe | ||
|
|
a848933875 | ||
|
|
e475f3d752 | ||
|
|
4d24dbc661 | ||
|
|
0368c3fae9 | ||
|
|
2cf93ccb54 | ||
|
|
3d72cafea4 | ||
|
|
af0466ea83 | ||
|
|
c84f2996ec | ||
|
|
add9b83d3b | ||
|
|
5411fb6fd4 | ||
|
|
49fc1b40e5 | ||
|
|
daef2eecdd | ||
|
|
1520422cc3 | ||
|
|
7fc7ea6aba | ||
|
|
8801fda972 | ||
|
|
a8a3e2401b | ||
|
|
a7f59a2e2b | ||
|
|
d8e9da35d6 | ||
|
|
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 |
24
.github/workflows/close-stale.yml
vendored
24
.github/workflows/close-stale.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
stale-issue-message: 'This issue has been labelled stale because it has been open for 2 weeks with no activity. Remove stale label or add a comment to keep this issue open. Otherwise, it will be closed in 7 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 3 weeks with no activity. Feel free to add a comment here and we can re-open it. Or feel free to file a new issue any time.'
|
||||
days-before-stale: 14
|
||||
days-before-close: 7
|
||||
stale-issue-label: 'stale'
|
||||
stale-pr-label: 'stale'
|
||||
only-labels: 'question'
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
55
.github/workflows/docker-build-test.yml
vendored
55
.github/workflows/docker-build-test.yml
vendored
@@ -4,34 +4,46 @@ on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'aider/website/**'
|
||||
- README.md
|
||||
- HISTORY.md
|
||||
- 'README.md'
|
||||
- 'HISTORY.md'
|
||||
- '.github/workflows/*'
|
||||
- '!.github/workflows/docker-build-test.yml'
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'aider/website/**'
|
||||
- README.md
|
||||
- 'README.md'
|
||||
- 'HISTORY.md'
|
||||
- '.github/workflows/*'
|
||||
- '!.github/workflows/docker-build-test.yml'
|
||||
branches:
|
||||
- main
|
||||
|
||||
# copy most of these steps from release.yml, but push: false and no tags:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
docker_build_and_push:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build Docker standard image
|
||||
- name: Login to DockerHub
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Build Docker images (PR)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
@@ -40,7 +52,19 @@ jobs:
|
||||
push: false
|
||||
target: aider
|
||||
|
||||
- name: Build Docker full image
|
||||
- name: Build Docker images (Push)
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/aider:dev
|
||||
target: aider
|
||||
|
||||
- name: Build Docker full image (PR)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
@@ -48,3 +72,14 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: false
|
||||
target: aider-full
|
||||
|
||||
- name: Build Docker full image (Push)
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/aider-full:dev
|
||||
target: aider-full
|
||||
|
||||
2
.github/workflows/docker-release.yml
vendored
2
.github/workflows/docker-release.yml
vendored
@@ -12,6 +12,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
29
.github/workflows/issues.yml
vendored
Normal file
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
|
||||
14
.github/workflows/pages.yml
vendored
14
.github/workflows/pages.yml
vendored
@@ -12,6 +12,7 @@ on:
|
||||
- "main"
|
||||
paths:
|
||||
- "aider/website/**"
|
||||
- ".github/workflows/pages.yml"
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
@@ -36,7 +37,9 @@ jobs:
|
||||
working-directory: aider/website
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
@@ -53,10 +56,9 @@ jobs:
|
||||
env:
|
||||
JEKYLL_ENV: production
|
||||
- name: Upload artifact
|
||||
# Automatically uploads an artifact from the './_site' directory by default
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: "aider/website/_site/"
|
||||
path: "aider/website/_site"
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
@@ -68,7 +70,7 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
@@ -82,4 +84,4 @@ jobs:
|
||||
|
||||
- name: Run linkchecker
|
||||
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:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
|
||||
20
.github/workflows/ubuntu-tests.yml
vendored
20
.github/workflows/ubuntu-tests.yml
vendored
@@ -4,14 +4,19 @@ on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'aider/website/**'
|
||||
- README.md
|
||||
- HISTORY.md
|
||||
- 'README.md'
|
||||
- 'HISTORY.md'
|
||||
- '.github/workflows/*'
|
||||
- '!.github/workflows/ubuntu-tests.yml'
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'aider/website/**'
|
||||
- README.md
|
||||
- 'README.md'
|
||||
- 'HISTORY.md'
|
||||
- '.github/workflows/*'
|
||||
- '!.github/workflows/ubuntu-tests.yml'
|
||||
branches:
|
||||
- main
|
||||
|
||||
@@ -25,12 +30,19 @@ jobs:
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libportaudio2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
@@ -38,5 +50,7 @@ jobs:
|
||||
pip install .
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
AIDER_ANALYTICS: false
|
||||
run: |
|
||||
pytest
|
||||
|
||||
15
.github/workflows/windows-tests.yml
vendored
15
.github/workflows/windows-tests.yml
vendored
@@ -4,14 +4,19 @@ on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'aider/website/**'
|
||||
- README.md
|
||||
- HISTORY.md
|
||||
- 'README.md'
|
||||
- 'HISTORY.md'
|
||||
- '.github/workflows/*'
|
||||
- '!.github/workflows/windows-tests.yml'
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'aider/website/**'
|
||||
- README.md
|
||||
- 'README.md'
|
||||
- 'HISTORY.md'
|
||||
- '.github/workflows/*'
|
||||
- '!.github/workflows/windows-tests.yml'
|
||||
branches:
|
||||
- main
|
||||
|
||||
@@ -25,6 +30,8 @@ jobs:
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
@@ -38,6 +45,8 @@ jobs:
|
||||
pip install .
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
AIDER_ANALYTICS: false
|
||||
run: |
|
||||
pytest
|
||||
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -11,4 +11,8 @@ _site
|
||||
.jekyll-cache/
|
||||
.jekyll-metadata
|
||||
aider/__version__.py
|
||||
.venv/
|
||||
aider/_version.py
|
||||
.venv/
|
||||
.#*
|
||||
.gitattributes
|
||||
tmp.benchmarks/
|
||||
@@ -56,13 +56,6 @@ It is recommended to create a virtual environment outside of the repository to k
|
||||
python -m venv /path/to/venv
|
||||
```
|
||||
|
||||
#### Using `virtualenv` (for older Python versions)
|
||||
|
||||
```
|
||||
pip install virtualenv
|
||||
virtualenv /path/to/venv
|
||||
```
|
||||
|
||||
### Activate the Virtual Environment
|
||||
|
||||
#### On Windows
|
||||
@@ -187,8 +180,8 @@ pytest
|
||||
You can also run specific test files or test cases by providing the file path or test name:
|
||||
|
||||
```
|
||||
pytest aider/tests/test_coder.py
|
||||
pytest aider/tests/test_coder.py::TestCoder::test_specific_case
|
||||
pytest tests/basic/test_coder.py
|
||||
pytest tests/basic/test_coder.py::TestCoder::test_specific_case
|
||||
```
|
||||
|
||||
#### Continuous Integration
|
||||
|
||||
305
HISTORY.md
305
HISTORY.md
@@ -1,6 +1,309 @@
|
||||
|
||||
# Release history
|
||||
|
||||
### Aider v0.76.1
|
||||
|
||||
- Added ignore_permission_denied option to file watcher to prevent errors when accessing restricted files, by Yutaka Matsubara.
|
||||
- Aider wrote 0% of the code in this release.
|
||||
|
||||
### Aider v0.76.0
|
||||
|
||||
- Improved support for thinking/reasoningmodels:
|
||||
- Added `--thinking-tokens` CLI option to control token budget for models that support thinking.
|
||||
- Display thinking/reasoning content from LLMs which return it.
|
||||
- Enhanced handling of reasoning tags to better clean up model responses.
|
||||
- Added deprecation warning for `remove_reasoning` setting, now replaced by `reasoning_tag`.
|
||||
- Aider will notify you when it's completed the last request and needs your input:
|
||||
- Added [notifications when LLM responses are ready](https://aider.chat/docs/usage/notifications.html) with `--notifications` flag.
|
||||
- Specify desktop notification command with `--notifications-command`.
|
||||
- Added support for QWQ 32B.
|
||||
- Switch to `tree-sitter-language-pack` for tree sitter support.
|
||||
- Improved error handling for EOF (Ctrl+D) in user input prompts.
|
||||
- Added helper function to ensure hex color values have a # prefix.
|
||||
- Fixed handling of Git errors when reading staged files.
|
||||
- Improved SSL verification control for model information requests.
|
||||
- Improved empty LLM response handling with clearer warning messages.
|
||||
- Fixed Git identity retrieval to respect global configuration, by Akira Komamura.
|
||||
- Offer to install dependencies for Bedrock and Vertex AI models.
|
||||
- Deprecated model shortcut args (like --4o, --opus) in favor of the --model flag.
|
||||
- Aider wrote 85% of the code in this release.
|
||||
|
||||
### Aider v0.75.3
|
||||
|
||||
- Support for V3 free on OpenRouter: `--model openrouter/deepseek/deepseek-chat:free`.
|
||||
|
||||
### Aider v0.75.2
|
||||
|
||||
- Added support for Claude 3.7 Sonnet models on OpenRouter, Bedrock and Vertex AI.
|
||||
- Updated default model to Claude 3.7 Sonnet on OpenRouter.
|
||||
- Added support for GPT-4.5-preview model.
|
||||
- Added support for Claude 3.7 Sonnet:beta on OpenRouter.
|
||||
- Fixed weak_model_name patterns to match main model name patterns for some models.
|
||||
|
||||
### Aider v0.75.1
|
||||
|
||||
- Added support for `openrouter/anthropic/claude-3.7-sonnet`
|
||||
|
||||
### Aider v0.75.0
|
||||
|
||||
- Basic support for Claude 3.7 Sonnet
|
||||
- Use `--model sonnet` to use the new 3.7
|
||||
- Thinking support coming soon.
|
||||
- Bugfix to `/editor` command.
|
||||
- Aider wrote 46% of the code in this release.
|
||||
|
||||
### Aider v0.74.3
|
||||
|
||||
- Downgrade streamlit dependency to avoid threading bug.
|
||||
- Added support for tree-sitter language pack.
|
||||
- Added openrouter/o3-mini-high model configuration.
|
||||
- Added build.gradle.kts to special files for Kotlin project support, by Lucas Shadler.
|
||||
|
||||
### Aider v0.74.2
|
||||
|
||||
- Prevent more than one cache warming thread from becoming active.
|
||||
- Fixed continuation prompt ". " for multiline input.
|
||||
- Added HCL (Terraform) syntax support, by Warren Krewenki.
|
||||
|
||||
### Aider v0.74.1
|
||||
|
||||
- Have o1 & o3-mini generate markdown by sending the magic "Formatting re-enabled." string.
|
||||
- Bugfix for multi-line inputs, which should not include the ". " continuation prompt.
|
||||
|
||||
### Aider v0.74.0
|
||||
|
||||
- Dynamically changes the Ollama context window to hold the current chat.
|
||||
- Better support for o3-mini, DeepSeek V3 & R1, o1-mini, o1 especially via third-party API providers.
|
||||
- Remove `<think>` tags from R1 responses for commit messages (and other weak model uses).
|
||||
- Can now specify `use_temperature: <float>` in model settings, not just true/false.
|
||||
- The full docker container now includes `boto3` for Bedrock.
|
||||
- Docker containers now set `HOME=/app` which is the normal project mount-point, to persist `~/.aider`.
|
||||
- Bugfix to prevent creating incorrect filenames like `python`, `php`, etc.
|
||||
- Bugfix for `--timeout`
|
||||
- Bugfix so that `/model` now correctly reports that the weak model is not changed.
|
||||
- Bugfix so that multi-line mode persists through ^C at confirmation prompts.
|
||||
- Watch files now fully ignores top-level directories named in ignore files, to reduce the chance of hitting OS watch limits. Helpful to ignore giant subtrees like `node_modules`.
|
||||
- Fast startup with more providers and when model metadata provided in local files.
|
||||
- Improved .gitignore handling:
|
||||
- Honor ignores already in effect regardless of how they've been configured.
|
||||
- Check for .env only when the file exists.
|
||||
- Yes/No prompts now accept All/Skip as alias for Y/N even when not processing a group of confirmations.
|
||||
- Aider wrote 77% of the code in this release.
|
||||
|
||||
### Aider v0.73.0
|
||||
|
||||
- Full support for o3-mini: `aider --model o3-mini`
|
||||
- New `--reasoning-effort` argument: low, medium, high.
|
||||
- Improved handling of context window size limits, with better messaging and Ollama-specific guidance.
|
||||
- Added support for removing model-specific reasoning tags from responses with `remove_reasoning: tagname` model setting.
|
||||
- Auto-create parent directories when creating new files, by xqyz.
|
||||
- Support for R1 free on OpenRouter: `--model openrouter/deepseek/deepseek-r1:free`
|
||||
- Aider wrote 69% of the code in this release.
|
||||
|
||||
### Aider v0.72.3
|
||||
|
||||
- Enforce user/assistant turn order to avoid R1 errors, by miradnanali.
|
||||
- Case-insensitive model name matching while preserving original case.
|
||||
|
||||
### Aider v0.72.2
|
||||
- Harden against user/assistant turn order problems which cause R1 errors.
|
||||
|
||||
### Aider v0.72.1
|
||||
- Fix model metadata for `openrouter/deepseek/deepseek-r1`
|
||||
|
||||
### Aider v0.72.0
|
||||
- Support for DeepSeek R1.
|
||||
- Use shortcut: `--model r1`
|
||||
- Also via OpenRouter: `--model openrouter/deepseek/deepseek-r1`
|
||||
- Added Kotlin syntax support to repo map, by Paul Walker.
|
||||
- Added `--line-endings` for file writing, by Titusz Pan.
|
||||
- Added examples_as_sys_msg=True for GPT-4o models, improves benchmark scores.
|
||||
- Bumped all dependencies, to pick up litellm support for o1 system messages.
|
||||
- Bugfix for turn taking when reflecting lint/test errors.
|
||||
- Aider wrote 52% of the code in this release.
|
||||
|
||||
### Aider v0.71.1
|
||||
|
||||
- Fix permissions issue in Docker images.
|
||||
- Added read-only file announcements.
|
||||
- Bugfix: ASCII fallback for unicode errors.
|
||||
- Bugfix: integer indices for list slicing in repomap calculations.
|
||||
|
||||
### Aider v0.71.0
|
||||
|
||||
- Prompts to help DeepSeek work better when alternating between `/ask` and `/code`.
|
||||
- Streaming pretty LLM responses is smoother and faster for long replies.
|
||||
- Streaming automatically turns of for model that don't support it
|
||||
- Can now switch to/from `/model o1` and a streaming model
|
||||
- Pretty output remains enabled even when editing files with triple-backtick fences
|
||||
- Bare `/ask`, `/code` and `/architect` commands now switch the chat mode.
|
||||
- Increased default size of the repomap.
|
||||
- Increased max chat history tokens limit from 4k to 8k.
|
||||
- Turn off fancy input and watch files if terminal is dumb.
|
||||
- Added support for custom voice format and input device settings.
|
||||
- Disabled Streamlit email prompt, by apaz-cli.
|
||||
- Docker container runs as non-root user.
|
||||
- Fixed lint command handling of nested spaced strings, by Aaron Weisberg.
|
||||
- Added token count feedback when adding command output to chat.
|
||||
- Improved error handling for large audio files with automatic format conversion.
|
||||
- Improved handling of git repo index errors, by Krazer.
|
||||
- Improved unicode handling in console output with ASCII fallback.
|
||||
- Added AssertionError, AttributeError to git error handling.
|
||||
- Aider wrote 60% of the code in this release.
|
||||
|
||||
### Aider v0.70.0
|
||||
|
||||
- Full support for o1 models.
|
||||
- Watch files now honors `--subtree-only`, and only watches that subtree.
|
||||
- Improved prompting for watch files, to work more reliably with more models.
|
||||
- New install methods via uv, including one-liners.
|
||||
- Support for openrouter/deepseek/deepseek-chat model.
|
||||
- Better error handling when interactive commands are attempted via `/load` or `--load`.
|
||||
- Display read-only files with abs path if its shorter than rel path.
|
||||
- Ask 10% of users to opt-in to analytics.
|
||||
- Bugfix for auto-suggest.
|
||||
- Gracefully handle unicode errors in git path names.
|
||||
- Aider wrote 74% of the code in this release.
|
||||
|
||||
### Aider v0.69.1
|
||||
|
||||
- Fix for gemini model names in model metadata.
|
||||
- Show hints about AI! and AI? when user makes AI comments.
|
||||
- Support for running without git installed.
|
||||
- Improved environment variable setup messages on Windows.
|
||||
|
||||
### Aider v0.69.0
|
||||
|
||||
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
|
||||
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
|
||||
- Now watches *all* files, not just certain source files.
|
||||
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
|
||||
- Full support for Gemini Flash 2.0 Exp:
|
||||
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
|
||||
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
|
||||
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
|
||||
- Improved clipboard error handling with helpful requirements install info.
|
||||
- Ask 5% of users if they want to opt-in to analytics.
|
||||
- `/voice` now lets you edit the transcribed text before sending.
|
||||
- Disabled auto-complete in Y/N prompts.
|
||||
- Aider wrote 68% of the code in this release.
|
||||
|
||||
### Aider v0.68.0
|
||||
|
||||
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
|
||||
- New `--copy-paste` mode.
|
||||
- New `/copy-context` command.
|
||||
- [Set API keys and other environment variables for all providers from command line or yaml conf file](https://aider.chat/docs/config/aider_conf.html#storing-llm-keys).
|
||||
- New `--api-key provider=key` setting.
|
||||
- New `--set-env VAR=value` setting.
|
||||
- Added bash and zsh support to `--watch-files`.
|
||||
- Better error messages when missing dependencies for Gemini and Bedrock models.
|
||||
- Control-D now properly exits the program.
|
||||
- Don't count token costs when API provider returns a hard error.
|
||||
- Bugfix so watch files works with files that don't have tree-sitter support.
|
||||
- Bugfix so o1 models can be used as weak model.
|
||||
- Updated shell command prompt.
|
||||
- Added docstrings for all Coders.
|
||||
- Reorganized command line arguments with improved help messages and grouping.
|
||||
- Use the exact `sys.python` for self-upgrades.
|
||||
- Added experimental Gemini models.
|
||||
- Aider wrote 71% of the code in this release.
|
||||
|
||||
### Aider v0.67.0
|
||||
|
||||
- [Use aider in your IDE or editor](https://aider.chat/docs/usage/watch.html).
|
||||
- Run `aider --watch-files` and it will watch for instructions you add to your source files.
|
||||
- One-liner `# ...` or `// ...` comments that start or end with "AI" are instructions to aider.
|
||||
- When aider sees "AI!" it reads and follows all the instructions in AI comments.
|
||||
- Support for new Amazon Bedrock Nova models.
|
||||
- When `/run` or `/test` have non-zero exit codes, pre-fill "Fix that" into the next message prompt.
|
||||
- `/diff` now invokes `git diff` to use your preferred diff tool.
|
||||
- Added Ctrl-Z support for process suspension.
|
||||
- Spinner now falls back to ASCII art if fancy symbols throw unicode errors.
|
||||
- `--read` now expands `~` home dirs.
|
||||
- Enabled exception capture in analytics.
|
||||
- [Aider wrote 61% of the code in this release.](https://aider.chat/HISTORY.html)
|
||||
|
||||
### Aider v0.66.0
|
||||
|
||||
- PDF support for Sonnet and Gemini models.
|
||||
- Added `--voice-input-device` to select audio input device for voice recording, by @preynal.
|
||||
- Added `--timeout` option to configure API call timeouts.
|
||||
- Set cwd to repo root when running shell commands.
|
||||
- Added Ctrl-Up/Down keyboard shortcuts for per-message history navigation.
|
||||
- Improved error handling for failed .gitignore file operations.
|
||||
- Improved error handling for input history file permissions.
|
||||
- Improved error handling for analytics file access.
|
||||
- Removed spurious warning about disabling pretty in VSCode.
|
||||
- Removed broken support for Dart.
|
||||
- Bugfix when scraping URLs found in chat messages.
|
||||
- Better handling of __version__ import errors.
|
||||
- Improved `/drop` command to support substring matching for non-glob patterns.
|
||||
- Aider wrote 82% of the code in this release.
|
||||
|
||||
### Aider v0.65.1
|
||||
|
||||
- Bugfix to `--alias`.
|
||||
|
||||
### Aider v0.65.0
|
||||
|
||||
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
||||
- Added `--[no-]detect-urls` flag to disable detecting and offering to scrape URLs found in the chat.
|
||||
- Ollama models now default to an 8k context window.
|
||||
- Added [RepoMap support for Dart language](https://aider.chat/docs/languages.html) by @malkoG.
|
||||
- Ask 2.5% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
|
||||
- Skip suggesting files that share names with files already in chat.
|
||||
- `/editor` returns and prefill the file content into the prompt, so you can use `/editor` to compose messages that start with `/commands`, etc.
|
||||
- Enhanced error handling for analytics.
|
||||
- Improved handling of UnknownEditFormat exceptions with helpful documentation links.
|
||||
- Bumped dependencies to pick up grep-ast 0.4.0 for Dart language support.
|
||||
- Aider wrote 81% of the code in this release.
|
||||
|
||||
### Aider v0.64.1
|
||||
|
||||
- Disable streaming for o1 on OpenRouter.
|
||||
|
||||
### Aider v0.64.0
|
||||
|
||||
- Added [`/editor` command](https://aider.chat/docs/usage/commands.html) to open system editor for writing prompts, by @thehunmonkgroup.
|
||||
- Full support for `gpt-4o-2024-11-20`.
|
||||
- Stream o1 models by default.
|
||||
- `/run` and suggested shell commands are less mysterious and now confirm that they "Added XX lines of output to the chat."
|
||||
- Ask 1% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
|
||||
- Added support for [optional multiline input tags](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) with matching closing tags.
|
||||
- Improved [model settings configuration](https://aider.chat/docs/config/adv-model-settings.html#global-extra-params) with support for global `extra_params` for `litellm.completion()`.
|
||||
- Architect mode now asks to add files suggested by the LLM.
|
||||
- Fixed bug in fuzzy model name matching.
|
||||
- Added Timeout exception to handle API provider timeouts.
|
||||
- Added `--show-release-notes` to control release notes display on first run of new version.
|
||||
- Save empty dict to cache file on model metadata download failure, to delay retry.
|
||||
- Improved error handling and code formatting.
|
||||
- Aider wrote 74% of the code in this release.
|
||||
|
||||
### Aider v0.63.2
|
||||
|
||||
- Fixed bug in fuzzy model name matching when litellm provider info is missing.
|
||||
- Modified model metadata file loading to allow override of resource file.
|
||||
- Allow recursive loading of dirs using `--read`.
|
||||
- Updated dependency versions to pick up litellm fix for ollama models.
|
||||
- Added exponential backoff retry when writing files to handle editor file locks.
|
||||
- Updated Qwen 2.5 Coder 32B model configuration.
|
||||
|
||||
### Aider v0.63.1
|
||||
|
||||
- Fixed bug in git ignored file handling.
|
||||
- Improved error handling for git operations.
|
||||
|
||||
### Aider v0.63.0
|
||||
|
||||
- Support for Qwen 2.5 Coder 32B.
|
||||
- `/web` command just adds the page to the chat, without triggering an LLM response.
|
||||
- Improved prompting for the user's preferred chat language.
|
||||
- Improved handling of LiteLLM exceptions.
|
||||
- Bugfix for double-counting tokens when reporting cache stats.
|
||||
- Bugfix for the LLM creating new files.
|
||||
- Other small bug fixes.
|
||||
- Aider wrote 55% of the code in this release.
|
||||
|
||||
### Aider v0.62.0
|
||||
|
||||
- Full support for Claude 3.5 Haiku
|
||||
|
||||
20
MANIFEST.in
Normal file
20
MANIFEST.in
Normal file
@@ -0,0 +1,20 @@
|
||||
# This needs to sync with aider/help_pats.py
|
||||
|
||||
global-exclude .DS_Store
|
||||
|
||||
recursive-exclude aider/website/examples *
|
||||
recursive-exclude aider/website/_posts *
|
||||
|
||||
exclude aider/website/HISTORY.md
|
||||
exclude aider/website/docs/benchmarks*.md
|
||||
exclude aider/website/docs/ctags.md
|
||||
exclude aider/website/docs/unified-diffs.md
|
||||
|
||||
exclude aider/website/install.ps1
|
||||
exclude aider/website/install.sh
|
||||
|
||||
recursive-exclude aider/website/docs/leaderboards *
|
||||
recursive-exclude aider/website/assets *
|
||||
recursive-exclude aider/website *.js
|
||||
recursive-exclude aider/website *.html
|
||||
recursive-exclude aider/website *.yml
|
||||
46
README.md
46
README.md
@@ -5,9 +5,8 @@
|
||||
|
||||
Aider lets you pair program with LLMs,
|
||||
to edit code in your local git repository.
|
||||
Start a new project or work with an existing git repo.
|
||||
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
|
||||
[connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
Start a new project or work with an existing code base.
|
||||
Aider works best with Claude 3.7 Sonnet, DeepSeek R1 & Chat V3, OpenAI o1, o3-mini & GPT-4o. Aider can [connect to almost any LLM, including local models](https://aider.chat/docs/llms.html).
|
||||
|
||||
<!-- SCREENCAST START -->
|
||||
<p align="center">
|
||||
@@ -43,28 +42,36 @@ VIDEO END -->
|
||||
cog.out(open("aider/website/_includes/get-started.md").read())
|
||||
]]]-->
|
||||
|
||||
You can get started quickly like this:
|
||||
If you already have python 3.8-3.13 installed, you can get started quickly like this:
|
||||
|
||||
```
|
||||
python -m pip install -U aider-chat
|
||||
```bash
|
||||
python -m pip install aider-install
|
||||
aider-install
|
||||
|
||||
# Change directory into a git repo
|
||||
cd /to/your/git/repo
|
||||
# Change directory into your code base
|
||||
cd /to/your/project
|
||||
|
||||
# Work with Claude 3.5 Sonnet on your repo
|
||||
export ANTHROPIC_API_KEY=your-key-goes-here
|
||||
aider
|
||||
# Work with DeepSeek via DeepSeek's API
|
||||
aider --model deepseek --api-key deepseek=your-key-goes-here
|
||||
|
||||
# Work with GPT-4o on your repo
|
||||
export OPENAI_API_KEY=your-key-goes-here
|
||||
aider
|
||||
# Work with Claude 3.7 Sonnet via Anthropic's API
|
||||
aider --model sonnet --api-key anthropic=your-key-goes-here
|
||||
|
||||
# Work with GPT-4o via OpenAI's API
|
||||
aider --model gpt-4o --api-key openai=your-key-goes-here
|
||||
|
||||
# Work with Sonnet via OpenRouter's API
|
||||
aider --model openrouter/anthropic/claude-3.7-sonnet --api-key openrouter=your-key-goes-here
|
||||
|
||||
# Work with DeepSeek via OpenRouter's API
|
||||
aider --model openrouter/deepseek/deepseek-chat --api-key openrouter=your-key-goes-here
|
||||
```
|
||||
<!--[[[end]]]-->
|
||||
|
||||
See the
|
||||
[installation instructions](https://aider.chat/docs/install.html)
|
||||
and other
|
||||
[documentation](https://aider.chat/docs/usage.html)
|
||||
and
|
||||
[usage documentation](https://aider.chat/docs/usage.html)
|
||||
for more details.
|
||||
|
||||
## Features
|
||||
@@ -73,21 +80,22 @@ for more details.
|
||||
- Ask for changes:
|
||||
- Add new features or test cases.
|
||||
- Describe a bug.
|
||||
- Paste in an error message or or GitHub issue URL.
|
||||
- Paste in an error message or GitHub issue URL.
|
||||
- Refactor code.
|
||||
- Update docs.
|
||||
- Aider will edit your files to complete your request.
|
||||
- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message.
|
||||
- [Use aider inside your favorite editor or IDE](https://aider.chat/docs/usage/watch.html).
|
||||
- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more...
|
||||
- Aider works best with GPT-4o & Claude 3.5 Sonnet and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
- Aider can edit multiple files at once for complex requests.
|
||||
- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases.
|
||||
- Edit files in your editor while chatting with aider,
|
||||
- Edit files in your editor or IDE while chatting with aider,
|
||||
and it will always use the latest version.
|
||||
Pair program with AI.
|
||||
- [Add images to the chat](https://aider.chat/docs/usage/images-urls.html) (GPT-4o, Claude 3.5 Sonnet, etc).
|
||||
- [Add URLs to the chat](https://aider.chat/docs/usage/images-urls.html) and aider will read their content.
|
||||
- [Code with your voice](https://aider.chat/docs/usage/voice.html).
|
||||
- Aider works best with Claude 3.7 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html).
|
||||
|
||||
|
||||
## Top tier performance
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
from packaging import version
|
||||
|
||||
__version__ = "0.76.2.dev"
|
||||
safe_version = __version__
|
||||
|
||||
try:
|
||||
from aider.__version__ import __version__
|
||||
from aider._version import __version__
|
||||
except Exception:
|
||||
__version__ = "0.62.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__]
|
||||
|
||||
@@ -5,13 +5,53 @@ import time
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
from mixpanel import Mixpanel
|
||||
from mixpanel import MixpanelException
|
||||
from posthog import Posthog
|
||||
|
||||
from aider import __version__
|
||||
from aider.dump import dump # noqa: F401
|
||||
from aider.models import model_info_manager
|
||||
|
||||
PERCENT = 10
|
||||
|
||||
|
||||
def compute_hex_threshold(percent):
|
||||
"""Convert percentage to 6-digit hex threshold.
|
||||
|
||||
Args:
|
||||
percent: Percentage threshold (0-100)
|
||||
|
||||
Returns:
|
||||
str: 6-digit hex threshold
|
||||
"""
|
||||
return format(int(0xFFFFFF * percent / 100), "06x")
|
||||
|
||||
|
||||
def is_uuid_in_percentage(uuid_str, percent):
|
||||
"""Check if a UUID string falls within the first X percent of the UUID space.
|
||||
|
||||
Args:
|
||||
uuid_str: UUID string to test
|
||||
percent: Percentage threshold (0-100)
|
||||
|
||||
Returns:
|
||||
bool: True if UUID falls within the first X percent
|
||||
"""
|
||||
if not (0 <= percent <= 100):
|
||||
raise ValueError("Percentage must be between 0 and 100")
|
||||
|
||||
if not uuid_str:
|
||||
return False
|
||||
|
||||
# Convert percentage to hex threshold (1% = "04...", 10% = "1a...", etc)
|
||||
# Using first 6 hex digits
|
||||
if percent == 0:
|
||||
return False
|
||||
|
||||
threshold = compute_hex_threshold(percent)
|
||||
return uuid_str[:6] <= threshold
|
||||
|
||||
|
||||
mixpanel_project_token = "6da9a43058a5d1b9f3353153921fb04d"
|
||||
posthog_project_api_key = "phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv"
|
||||
posthog_host = "https://us.i.posthog.com"
|
||||
@@ -50,8 +90,14 @@ class Analytics:
|
||||
self.disable(False)
|
||||
return
|
||||
|
||||
self.mp = Mixpanel(mixpanel_project_token)
|
||||
self.ph = Posthog(project_api_key=posthog_project_api_key, host=posthog_host)
|
||||
# self.mp = Mixpanel(mixpanel_project_token)
|
||||
self.ph = Posthog(
|
||||
project_api_key=posthog_project_api_key,
|
||||
host=posthog_host,
|
||||
on_error=self.posthog_error,
|
||||
enable_exception_autocapture=True,
|
||||
super_properties=self.get_system_info(), # Add system info to all events
|
||||
)
|
||||
|
||||
def disable(self, permanently):
|
||||
self.mp = None
|
||||
@@ -62,13 +108,33 @@ class Analytics:
|
||||
self.permanently_disable = True
|
||||
self.save_data()
|
||||
|
||||
def need_to_ask(self):
|
||||
return not self.asked_opt_in and not self.permanently_disable
|
||||
def need_to_ask(self, args_analytics):
|
||||
if args_analytics is False:
|
||||
return False
|
||||
|
||||
could_ask = not self.asked_opt_in and not self.permanently_disable
|
||||
if not could_ask:
|
||||
return False
|
||||
|
||||
if args_analytics is True:
|
||||
return True
|
||||
|
||||
assert args_analytics is None, args_analytics
|
||||
|
||||
if not self.user_id:
|
||||
return False
|
||||
|
||||
return is_uuid_in_percentage(self.user_id, PERCENT)
|
||||
|
||||
def get_data_file_path(self):
|
||||
data_file = Path.home() / ".aider" / "analytics.json"
|
||||
data_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
return data_file
|
||||
try:
|
||||
data_file = Path.home() / ".aider" / "analytics.json"
|
||||
data_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
return data_file
|
||||
except OSError:
|
||||
# If we can't create/access the directory, just disable analytics
|
||||
self.disable(permanently=False)
|
||||
return None
|
||||
|
||||
def get_or_create_uuid(self):
|
||||
self.load_data()
|
||||
@@ -80,6 +146,9 @@ class Analytics:
|
||||
|
||||
def load_data(self):
|
||||
data_file = self.get_data_file_path()
|
||||
if not data_file:
|
||||
return
|
||||
|
||||
if data_file.exists():
|
||||
try:
|
||||
data = json.loads(data_file.read_text())
|
||||
@@ -91,14 +160,20 @@ class Analytics:
|
||||
|
||||
def save_data(self):
|
||||
data_file = self.get_data_file_path()
|
||||
if not data_file:
|
||||
return
|
||||
|
||||
data = dict(
|
||||
uuid=self.user_id,
|
||||
permanently_disable=self.permanently_disable,
|
||||
asked_opt_in=self.asked_opt_in,
|
||||
)
|
||||
|
||||
# Allow exceptions; crash if we can't record permanently_disabled=True, etc
|
||||
data_file.write_text(json.dumps(data, indent=4))
|
||||
try:
|
||||
data_file.write_text(json.dumps(data, indent=4))
|
||||
except OSError:
|
||||
# If we can't write the file, just disable analytics
|
||||
self.disable(permanently=False)
|
||||
|
||||
def get_system_info(self):
|
||||
return {
|
||||
@@ -106,6 +181,7 @@ class Analytics:
|
||||
"os_platform": platform.system(),
|
||||
"os_release": platform.release(),
|
||||
"machine": platform.machine(),
|
||||
"aider_version": __version__,
|
||||
}
|
||||
|
||||
def _redact_model_name(self, model):
|
||||
@@ -119,8 +195,15 @@ class Analytics:
|
||||
return model.name.split("/")[0] + "/REDACTED"
|
||||
return None
|
||||
|
||||
def posthog_error(self):
|
||||
"""disable posthog if we get an error"""
|
||||
print("X" * 100)
|
||||
# https://github.com/PostHog/posthog-python/blob/9e1bb8c58afaa229da24c4fb576c08bb88a75752/posthog/consumer.py#L86
|
||||
# https://github.com/Aider-AI/aider/issues/2532
|
||||
self.ph = None
|
||||
|
||||
def event(self, event_name, main_model=None, **kwargs):
|
||||
if not (self.mp or self.ph) and not self.logfile:
|
||||
if not self.mp and not self.ph and not self.logfile:
|
||||
return
|
||||
|
||||
properties = {}
|
||||
@@ -131,7 +214,6 @@ class Analytics:
|
||||
properties["editor_model"] = self._redact_model_name(main_model.editor_model)
|
||||
|
||||
properties.update(kwargs)
|
||||
properties.update(self.get_system_info()) # Add system info to all events
|
||||
|
||||
# Handle numeric values
|
||||
for key, value in properties.items():
|
||||
@@ -140,10 +222,11 @@ class Analytics:
|
||||
else:
|
||||
properties[key] = str(value)
|
||||
|
||||
properties["aider_version"] = __version__
|
||||
|
||||
if self.mp:
|
||||
self.mp.track(self.user_id, event_name, dict(properties))
|
||||
try:
|
||||
self.mp.track(self.user_id, event_name, dict(properties))
|
||||
except MixpanelException:
|
||||
self.mp = None # Disable mixpanel on connection errors
|
||||
|
||||
if self.ph:
|
||||
self.ph.capture(self.user_id, event_name, dict(properties))
|
||||
@@ -155,10 +238,13 @@ class Analytics:
|
||||
"user_id": self.user_id,
|
||||
"time": int(time.time()),
|
||||
}
|
||||
with open(self.logfile, "a") as f:
|
||||
json.dump(log_entry, f)
|
||||
f.write("\n")
|
||||
try:
|
||||
with open(self.logfile, "a") as f:
|
||||
json.dump(log_entry, f)
|
||||
f.write("\n")
|
||||
except OSError:
|
||||
pass # Ignore OS errors when writing to logfile
|
||||
|
||||
def __del__(self):
|
||||
if self.ph:
|
||||
self.ph.shutdown()
|
||||
|
||||
if __name__ == "__main__":
|
||||
dump(compute_hex_threshold(PERCENT))
|
||||
|
||||
514
aider/args.py
514
aider/args.py
@@ -12,6 +12,7 @@ from aider.args_formatter import (
|
||||
MarkdownHelpFormatter,
|
||||
YamlHelpFormatter,
|
||||
)
|
||||
from aider.deprecated import add_deprecated_model_args
|
||||
|
||||
from .dump import dump # noqa: F401
|
||||
|
||||
@@ -28,159 +29,71 @@ def get_parser(default_config_files, git_root):
|
||||
config_file_parser_class=configargparse.YAMLConfigFileParser,
|
||||
auto_env_var_prefix="AIDER_",
|
||||
)
|
||||
group = parser.add_argument_group("Main")
|
||||
group = parser.add_argument_group("Main model")
|
||||
group.add_argument(
|
||||
"files", metavar="FILE", nargs="*", help="files to edit with an LLM (optional)"
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-key",
|
||||
metavar="OPENAI_API_KEY",
|
||||
env_var="OPENAI_API_KEY",
|
||||
help="Specify the OpenAI API key",
|
||||
)
|
||||
group.add_argument(
|
||||
"--anthropic-api-key",
|
||||
metavar="ANTHROPIC_API_KEY",
|
||||
env_var="ANTHROPIC_API_KEY",
|
||||
help="Specify the Anthropic API key",
|
||||
)
|
||||
group.add_argument(
|
||||
"--model",
|
||||
metavar="MODEL",
|
||||
default=None,
|
||||
help="Specify the model to use for the main chat",
|
||||
)
|
||||
opus_model = "claude-3-opus-20240229"
|
||||
group.add_argument(
|
||||
"--opus",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=opus_model,
|
||||
help=f"Use {opus_model} model for the main chat",
|
||||
)
|
||||
sonnet_model = "claude-3-5-sonnet-20241022"
|
||||
group.add_argument(
|
||||
"--sonnet",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=sonnet_model,
|
||||
help=f"Use {sonnet_model} model for the main chat",
|
||||
)
|
||||
haiku_model = "claude-3-5-haiku-20241022"
|
||||
group.add_argument(
|
||||
"--haiku",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=haiku_model,
|
||||
help=f"Use {haiku_model} model for the main chat",
|
||||
)
|
||||
gpt_4_model = "gpt-4-0613"
|
||||
group.add_argument(
|
||||
"--4",
|
||||
"-4",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=gpt_4_model,
|
||||
help=f"Use {gpt_4_model} model for the main chat",
|
||||
)
|
||||
gpt_4o_model = "gpt-4o-2024-08-06"
|
||||
group.add_argument(
|
||||
"--4o",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=gpt_4o_model,
|
||||
help=f"Use {gpt_4o_model} model for the main chat",
|
||||
)
|
||||
gpt_4o_mini_model = "gpt-4o-mini"
|
||||
group.add_argument(
|
||||
"--mini",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=gpt_4o_mini_model,
|
||||
help=f"Use {gpt_4o_mini_model} model for the main chat",
|
||||
)
|
||||
gpt_4_turbo_model = "gpt-4-1106-preview"
|
||||
group.add_argument(
|
||||
"--4-turbo",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=gpt_4_turbo_model,
|
||||
help=f"Use {gpt_4_turbo_model} model for the main chat",
|
||||
)
|
||||
gpt_3_model_name = "gpt-3.5-turbo"
|
||||
group.add_argument(
|
||||
"--35turbo",
|
||||
"--35-turbo",
|
||||
"--3",
|
||||
"-3",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=gpt_3_model_name,
|
||||
help=f"Use {gpt_3_model_name} model for the main chat",
|
||||
)
|
||||
deepseek_model = "deepseek/deepseek-coder"
|
||||
group.add_argument(
|
||||
"--deepseek",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=deepseek_model,
|
||||
help=f"Use {deepseek_model} model for the main chat",
|
||||
)
|
||||
o1_mini_model = "o1-mini"
|
||||
group.add_argument(
|
||||
"--o1-mini",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=o1_mini_model,
|
||||
help=f"Use {o1_mini_model} model for the main chat",
|
||||
)
|
||||
o1_preview_model = "o1-preview"
|
||||
group.add_argument(
|
||||
"--o1-preview",
|
||||
action="store_const",
|
||||
dest="model",
|
||||
const=o1_preview_model,
|
||||
help=f"Use {o1_preview_model} model for the main chat",
|
||||
)
|
||||
|
||||
##########
|
||||
group = parser.add_argument_group("Model Settings")
|
||||
group = parser.add_argument_group("API Keys and settings")
|
||||
group.add_argument(
|
||||
"--openai-api-key",
|
||||
help="Specify the OpenAI API key",
|
||||
)
|
||||
group.add_argument(
|
||||
"--anthropic-api-key",
|
||||
help="Specify the Anthropic API key",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-base",
|
||||
help="Specify the api base url",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-type",
|
||||
help="(deprecated, use --set-env OPENAI_API_TYPE=<value>)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-version",
|
||||
help="(deprecated, use --set-env OPENAI_API_VERSION=<value>)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-deployment-id",
|
||||
help="(deprecated, use --set-env OPENAI_API_DEPLOYMENT_ID=<value>)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-organization-id",
|
||||
help="(deprecated, use --set-env OPENAI_ORGANIZATION=<value>)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--set-env",
|
||||
action="append",
|
||||
metavar="ENV_VAR_NAME=value",
|
||||
help="Set an environment variable (to control API settings, can be used multiple times)",
|
||||
default=[],
|
||||
)
|
||||
group.add_argument(
|
||||
"--api-key",
|
||||
action="append",
|
||||
metavar="PROVIDER=KEY",
|
||||
help=(
|
||||
"Set an API key for a provider (eg: --api-key provider=<key> sets"
|
||||
" PROVIDER_API_KEY=<key>)"
|
||||
),
|
||||
default=[],
|
||||
)
|
||||
group = parser.add_argument_group("Model settings")
|
||||
group.add_argument(
|
||||
"--list-models",
|
||||
"--models",
|
||||
metavar="MODEL",
|
||||
help="List known models which match the (partial) MODEL name",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-base",
|
||||
metavar="OPENAI_API_BASE",
|
||||
env_var="OPENAI_API_BASE",
|
||||
help="Specify the api base url",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-type",
|
||||
metavar="OPENAI_API_TYPE",
|
||||
env_var="OPENAI_API_TYPE",
|
||||
help="Specify the api_type",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-version",
|
||||
metavar="OPENAI_API_VERSION",
|
||||
env_var="OPENAI_API_VERSION",
|
||||
help="Specify the api_version",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-deployment-id",
|
||||
metavar="OPENAI_API_DEPLOYMENT_ID",
|
||||
env_var="OPENAI_API_DEPLOYMENT_ID",
|
||||
help="Specify the deployment_id",
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-organization-id",
|
||||
metavar="OPENAI_ORGANIZATION_ID",
|
||||
env_var="OPENAI_ORGANIZATION_ID",
|
||||
help="Specify the OpenAI organization ID",
|
||||
)
|
||||
group.add_argument(
|
||||
"--model-settings-file",
|
||||
metavar="MODEL_SETTINGS_FILE",
|
||||
@@ -193,12 +106,34 @@ def get_parser(default_config_files, git_root):
|
||||
default=".aider.model.metadata.json",
|
||||
help="Specify a file with context window and costs for unknown models",
|
||||
)
|
||||
group.add_argument(
|
||||
"--alias",
|
||||
action="append",
|
||||
metavar="ALIAS:MODEL",
|
||||
help="Add a model alias (can be used multiple times)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--reasoning-effort",
|
||||
type=str,
|
||||
help="Set the reasoning_effort API parameter (default: not set)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--thinking-tokens",
|
||||
type=int,
|
||||
help="Set the thinking token budget for models that support it (default: not set)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--verify-ssl",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=True,
|
||||
help="Verify the SSL cert when connecting to models (default: True)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--timeout",
|
||||
type=float,
|
||||
default=None,
|
||||
help="Timeout in seconds for API calls (default: None)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--edit-format",
|
||||
"--chat-mode",
|
||||
@@ -249,17 +184,9 @@ def get_parser(default_config_files, git_root):
|
||||
" If unspecified, defaults to the model's max_chat_history_tokens."
|
||||
),
|
||||
)
|
||||
# This is a duplicate of the argument in the preparser and is a no-op by this time of
|
||||
# argument parsing, but it's here so that the help is displayed as expected.
|
||||
group.add_argument(
|
||||
"--env-file",
|
||||
metavar="ENV_FILE",
|
||||
default=default_env_file(git_root),
|
||||
help="Specify the .env file to load (default: .env in git root)",
|
||||
)
|
||||
|
||||
##########
|
||||
group = parser.add_argument_group("Cache Settings")
|
||||
group = parser.add_argument_group("Cache settings")
|
||||
group.add_argument(
|
||||
"--cache-prompts",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
@@ -274,12 +201,12 @@ def get_parser(default_config_files, git_root):
|
||||
)
|
||||
|
||||
##########
|
||||
group = parser.add_argument_group("Repomap Settings")
|
||||
group = parser.add_argument_group("Repomap settings")
|
||||
group.add_argument(
|
||||
"--map-tokens",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Suggested number of tokens to use for repo map, use 0 to disable (default: 1024)",
|
||||
help="Suggested number of tokens to use for repo map, use 0 to disable",
|
||||
)
|
||||
group.add_argument(
|
||||
"--map-refresh",
|
||||
@@ -331,7 +258,7 @@ def get_parser(default_config_files, git_root):
|
||||
)
|
||||
|
||||
##########
|
||||
group = parser.add_argument_group("Output Settings")
|
||||
group = parser.add_argument_group("Output settings")
|
||||
group.add_argument(
|
||||
"--dark-mode",
|
||||
action="store_true",
|
||||
@@ -419,7 +346,8 @@ def get_parser(default_config_files, git_root):
|
||||
default="default",
|
||||
help=(
|
||||
"Set the markdown code theme (default: default, other options include monokai,"
|
||||
" solarized-dark, solarized-light)"
|
||||
" solarized-dark, solarized-light, or a Pygments builtin style,"
|
||||
" see https://pygments.org/styles for available themes)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
@@ -430,7 +358,7 @@ def get_parser(default_config_files, git_root):
|
||||
)
|
||||
|
||||
##########
|
||||
group = parser.add_argument_group("Git Settings")
|
||||
group = parser.add_argument_group("Git settings")
|
||||
group.add_argument(
|
||||
"--git",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
@@ -517,6 +445,12 @@ def get_parser(default_config_files, git_root):
|
||||
help="Skip the sanity check for the git repository (default: False)",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--watch-files",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=False,
|
||||
help="Enable/disable watching files for ai coding comments (default: False)",
|
||||
)
|
||||
group = parser.add_argument_group("Fixing and committing")
|
||||
group.add_argument(
|
||||
"--lint",
|
||||
@@ -553,7 +487,7 @@ def get_parser(default_config_files, git_root):
|
||||
group.add_argument(
|
||||
"--test",
|
||||
action="store_true",
|
||||
help="Run tests and fix problems found",
|
||||
help="Run tests, fix problems found and then exit",
|
||||
default=False,
|
||||
)
|
||||
|
||||
@@ -562,8 +496,8 @@ def get_parser(default_config_files, git_root):
|
||||
group.add_argument(
|
||||
"--analytics",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=False,
|
||||
help="Enable/disable analytics for one session (default: False)",
|
||||
default=None,
|
||||
help="Enable/disable analytics for current session (default: random)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--analytics-log",
|
||||
@@ -577,7 +511,133 @@ def get_parser(default_config_files, git_root):
|
||||
default=False,
|
||||
)
|
||||
|
||||
group = parser.add_argument_group("Other Settings")
|
||||
#########
|
||||
group = parser.add_argument_group("Upgrading")
|
||||
group.add_argument(
|
||||
"--just-check-update",
|
||||
action="store_true",
|
||||
help="Check for updates and return status in the exit code",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--check-update",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Check for new aider versions on launch",
|
||||
default=True,
|
||||
)
|
||||
group.add_argument(
|
||||
"--show-release-notes",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Show release notes on first run of new version (default: None, ask user)",
|
||||
default=None,
|
||||
)
|
||||
group.add_argument(
|
||||
"--install-main-branch",
|
||||
action="store_true",
|
||||
help="Install the latest version from the main branch",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--upgrade",
|
||||
"--update",
|
||||
action="store_true",
|
||||
help="Upgrade aider to the latest version from PyPI",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--version",
|
||||
action="version",
|
||||
version=f"%(prog)s {__version__}",
|
||||
help="Show the version number and exit",
|
||||
)
|
||||
|
||||
##########
|
||||
group = parser.add_argument_group("Modes")
|
||||
group.add_argument(
|
||||
"--message",
|
||||
"--msg",
|
||||
"-m",
|
||||
metavar="COMMAND",
|
||||
help=(
|
||||
"Specify a single message to send the LLM, process reply then exit (disables chat mode)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
"--message-file",
|
||||
"-f",
|
||||
metavar="MESSAGE_FILE",
|
||||
help=(
|
||||
"Specify a file containing the message to send the LLM, process reply, then exit"
|
||||
" (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",
|
||||
@@ -602,48 +662,6 @@ def get_parser(default_config_files, git_root):
|
||||
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(
|
||||
"--just-check-update",
|
||||
action="store_true",
|
||||
help="Check for updates and return status in the exit code",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--check-update",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Check for new aider versions on launch",
|
||||
default=True,
|
||||
)
|
||||
group.add_argument(
|
||||
"--install-main-branch",
|
||||
action="store_true",
|
||||
help="Install the latest version from the main branch",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--upgrade",
|
||||
"--update",
|
||||
action="store_true",
|
||||
help="Upgrade aider to the latest version from PyPI",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--apply",
|
||||
metavar="FILE",
|
||||
help="Apply the changes from the given file instead of running the chat (debug)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--apply-clipboard-edits",
|
||||
action="store_true",
|
||||
help="Apply clipboard contents as edits using the main model's editor format",
|
||||
default=False,
|
||||
)
|
||||
group.add_argument(
|
||||
"--yes-always",
|
||||
action="store_true",
|
||||
@@ -657,42 +675,6 @@ def get_parser(default_config_files, git_root):
|
||||
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.add_argument(
|
||||
"--message",
|
||||
"--msg",
|
||||
"-m",
|
||||
metavar="COMMAND",
|
||||
help=(
|
||||
"Specify a single message to send the LLM, process reply then exit (disables chat mode)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
"--message-file",
|
||||
"-f",
|
||||
metavar="MESSAGE_FILE",
|
||||
help=(
|
||||
"Specify a file containing the message to send the LLM, process reply, then exit"
|
||||
" (disables chat mode)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
"--load",
|
||||
metavar="LOAD_FILE",
|
||||
@@ -703,6 +685,12 @@ def get_parser(default_config_files, git_root):
|
||||
default="utf-8",
|
||||
help="Specify the encoding for input and output (default: utf-8)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--line-endings",
|
||||
choices=["platform", "lf", "crlf"],
|
||||
default="platform",
|
||||
help="Line endings to use when writing files (default: platform)",
|
||||
)
|
||||
group.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
@@ -713,12 +701,13 @@ def get_parser(default_config_files, git_root):
|
||||
" or home directory)"
|
||||
),
|
||||
)
|
||||
# This is a duplicate of the argument in the preparser and is a no-op by this time of
|
||||
# argument parsing, but it's here so that the help is displayed as expected.
|
||||
group.add_argument(
|
||||
"--gui",
|
||||
"--browser",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Run aider in your browser (default: False)",
|
||||
default=False,
|
||||
"--env-file",
|
||||
metavar="ENV_FILE",
|
||||
default=default_env_file(git_root),
|
||||
help="Specify the .env file to load (default: .env in git root)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--suggest-shell-commands",
|
||||
@@ -732,22 +721,45 @@ def get_parser(default_config_files, git_root):
|
||||
default=True,
|
||||
help="Enable/disable fancy input with history and completion (default: True)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--multiline",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=False,
|
||||
help="Enable/disable multi-line input mode with Meta-Enter to submit (default: False)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--notifications",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=False,
|
||||
help=(
|
||||
"Enable/disable terminal bell notifications when LLM responses are ready (default:"
|
||||
" False)"
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
"--notifications-command",
|
||||
metavar="COMMAND",
|
||||
default=None,
|
||||
help=(
|
||||
"Specify a command to run for notifications instead of the terminal bell. If not"
|
||||
" specified, a default command for your OS may be used."
|
||||
),
|
||||
)
|
||||
group.add_argument(
|
||||
"--detect-urls",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
default=True,
|
||||
help="Enable/disable detection and offering to add URLs to chat (default: True)",
|
||||
)
|
||||
group.add_argument(
|
||||
"--editor",
|
||||
help="Specify which editor to use for the /editor command",
|
||||
)
|
||||
|
||||
##########
|
||||
group = parser.add_argument_group("Voice Settings")
|
||||
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 = parser.add_argument_group("Deprecated model settings")
|
||||
# Add deprecated model shortcut arguments
|
||||
add_deprecated_model_args(parser, group)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
@@ -148,11 +148,14 @@ class YamlHelpFormatter(argparse.HelpFormatter):
|
||||
parts.append(f"#{switch}: xxx")
|
||||
parts.append("## Specify multiple values like this:")
|
||||
parts.append(f"#{switch}:")
|
||||
parts.append(f"# - xxx")
|
||||
parts.append(f"# - yyy")
|
||||
parts.append(f"# - zzz")
|
||||
parts.append("# - xxx")
|
||||
parts.append("# - yyy")
|
||||
parts.append("# - zzz")
|
||||
else:
|
||||
parts.append(f"#{switch}: xxx\n")
|
||||
if switch.endswith("color"):
|
||||
parts.append(f'#{switch}: "xxx"\n')
|
||||
else:
|
||||
parts.append(f"#{switch}: xxx\n")
|
||||
|
||||
###
|
||||
# parts.append(str(action))
|
||||
|
||||
@@ -10,6 +10,9 @@ class ArchitectCoder(AskCoder):
|
||||
def reply_completed(self):
|
||||
content = self.partial_response_content
|
||||
|
||||
if not content or not content.strip():
|
||||
return
|
||||
|
||||
if not self.io.confirm_ask("Edit the files?"):
|
||||
return
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Just show the changes needed.
|
||||
|
||||
DO NOT show the entire updated function/file/etc!
|
||||
|
||||
Always reply in the same language as the change request.
|
||||
Always reply to the user in {language}.
|
||||
"""
|
||||
|
||||
example_messages = []
|
||||
|
||||
@@ -6,7 +6,9 @@ from .base_prompts import CoderPrompts
|
||||
class AskPrompts(CoderPrompts):
|
||||
main_system = """Act as an expert code analyst.
|
||||
Answer questions about the supplied code.
|
||||
Always reply to the user in the same language they are using.
|
||||
Always reply to the user in {language}.
|
||||
|
||||
Describe code changes however you like. Don't use SEARCH/REPLACE blocks!
|
||||
"""
|
||||
|
||||
example_messages = []
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -401,6 +401,9 @@ missing_filename_err = (
|
||||
" {fence[0]}"
|
||||
)
|
||||
|
||||
# Always be willing to treat triple-backticks as a fence when searching for filenames
|
||||
triple_backticks = "`" * 3
|
||||
|
||||
|
||||
def strip_filename(filename, fence):
|
||||
filename = filename.strip()
|
||||
@@ -409,7 +412,7 @@ def strip_filename(filename, fence):
|
||||
return
|
||||
|
||||
start_fence = fence[0]
|
||||
if filename.startswith(start_fence):
|
||||
if filename.startswith(start_fence) or filename.startswith(triple_backticks):
|
||||
return
|
||||
|
||||
filename = filename.rstrip(":")
|
||||
@@ -546,7 +549,7 @@ def find_filename(lines, fence, valid_fnames):
|
||||
filenames.append(filename)
|
||||
|
||||
# Only continue as long as we keep seeing fences
|
||||
if not line.startswith(fence[0]):
|
||||
if not line.startswith(fence[0]) and not line.startswith(triple_backticks):
|
||||
break
|
||||
|
||||
if not filenames:
|
||||
|
||||
@@ -11,7 +11,7 @@ Respect and use existing conventions, libraries, etc that are already present in
|
||||
Take requests for changes to the supplied code.
|
||||
If the request is ambiguous, ask questions.
|
||||
|
||||
Always reply to the user in the same language they are using.
|
||||
Always reply to the user in {language}.
|
||||
|
||||
Once you understand the request you MUST:
|
||||
|
||||
@@ -35,7 +35,9 @@ ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
|
||||
|
||||
Just suggest shell commands this way, not example code.
|
||||
Only suggest complete shell commands that are ready to execute, without placeholders.
|
||||
Only suggest at most a few shell commands at a time, not more than 1-3.
|
||||
Only suggest at most a few shell commands at a time, not more than 1-3, one per line.
|
||||
Do not suggest multi-line shell commands.
|
||||
All shell commands will run from the root directory of the user's project.
|
||||
|
||||
Use the appropriate shell based on the user's system info:
|
||||
{platform}
|
||||
@@ -155,7 +157,7 @@ Every *SEARCH/REPLACE block* must use this format:
|
||||
8. The closing fence: {fence[1]}
|
||||
|
||||
Use the *FULL* file path, as shown to you by the user.
|
||||
|
||||
{quad_backtick_reminder}
|
||||
Every *SEARCH* section must *EXACTLY MATCH* the existing file content, character for character, including all comments, docstrings, etc.
|
||||
If the file contains code or other data wrapped/escaped in json/xml/quotes or other containers, you need to propose edits to the literal contents of the file, including the container markup.
|
||||
|
||||
@@ -181,6 +183,9 @@ If you want to put code in a new file, use a *SEARCH/REPLACE block* with:
|
||||
|
||||
To rename files which have been added to the chat, use shell commands at the end of your response.
|
||||
|
||||
If the user just says something like "ok" or "go ahead" or "do that" they probably want you to make SEARCH/REPLACE blocks for the code changes you just proposed.
|
||||
The user will say when they've applied your edits. If they haven't explicitly confirmed the edits have been applied, they probably want proper SEARCH/REPLACE blocks.
|
||||
|
||||
{lazy_prompt}
|
||||
ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
|
||||
{shell_cmd_reminder}
|
||||
|
||||
@@ -3,5 +3,6 @@ from .editor_editblock_prompts import EditorEditBlockPrompts
|
||||
|
||||
|
||||
class EditorEditBlockCoder(EditBlockCoder):
|
||||
"A coder that uses search/replace blocks, focused purely on editing files."
|
||||
edit_format = "editor-diff"
|
||||
gpt_prompts = EditorEditBlockPrompts()
|
||||
|
||||
@@ -3,5 +3,6 @@ from .wholefile_coder import WholeFileCoder
|
||||
|
||||
|
||||
class EditorWholeFileCoder(WholeFileCoder):
|
||||
"A coder that operates on entire files, focused purely on editing files."
|
||||
edit_format = "editor-whole"
|
||||
gpt_prompts = EditorWholeFilePrompts()
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import git
|
||||
try:
|
||||
import git
|
||||
except ImportError:
|
||||
git = None
|
||||
|
||||
from diff_match_patch import diff_match_patch
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class SingleWholeFileFunctionCoder(Coder):
|
||||
self.gpt_prompts = SingleWholeFileFunctionPrompts()
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def update_cur_messages(self, edited):
|
||||
def add_assistant_reply_to_cur_messages(self, edited):
|
||||
if edited:
|
||||
self.cur_messages += [
|
||||
dict(role="assistant", content=self.gpt_prompts.redacted_edit_message)
|
||||
|
||||
@@ -12,7 +12,7 @@ Respect and use existing conventions, libraries, etc that are already present in
|
||||
Take requests for changes to the supplied code.
|
||||
If the request is ambiguous, ask questions.
|
||||
|
||||
Always reply to the user in the same language they are using.
|
||||
Always reply to the user in {language}.
|
||||
|
||||
For each file that needs to be changed, write out the changes similar to a unified diff like `diff -U0` would produce.
|
||||
"""
|
||||
|
||||
@@ -17,10 +17,10 @@ class WholeFileCoder(Coder):
|
||||
try:
|
||||
return self.get_edits(mode="diff")
|
||||
except ValueError:
|
||||
return self.get_multi_response_content()
|
||||
return self.get_multi_response_content_in_progress()
|
||||
|
||||
def get_edits(self, mode="update"):
|
||||
content = self.get_multi_response_content()
|
||||
content = self.get_multi_response_content_in_progress()
|
||||
|
||||
chat_files = self.get_inchat_relative_files()
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class WholeFileFunctionCoder(Coder):
|
||||
self.gpt_prompts = WholeFileFunctionPrompts()
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def update_cur_messages(self, edited):
|
||||
def add_assistant_reply_to_cur_messages(self, edited):
|
||||
if edited:
|
||||
self.cur_messages += [
|
||||
dict(role="assistant", content=self.gpt_prompts.redacted_edit_message)
|
||||
|
||||
@@ -8,7 +8,7 @@ class WholeFilePrompts(CoderPrompts):
|
||||
Take requests for changes to the supplied code.
|
||||
If the request is ambiguous, ask questions.
|
||||
|
||||
Always reply to the user in the same language they are using.
|
||||
Always reply to the user in {language}.
|
||||
|
||||
{lazy_prompt}
|
||||
Once you understand the request you MUST:
|
||||
|
||||
@@ -14,6 +14,7 @@ from prompt_toolkit.completion import Completion, PathCompleter
|
||||
from prompt_toolkit.document import Document
|
||||
|
||||
from aider import models, prompts, voice
|
||||
from aider.editor import pipe_editor
|
||||
from aider.format_settings import format_settings
|
||||
from aider.help import Help, install_help_extra
|
||||
from aider.llm import litellm
|
||||
@@ -42,10 +43,22 @@ class Commands:
|
||||
verify_ssl=self.verify_ssl,
|
||||
args=self.args,
|
||||
parser=self.parser,
|
||||
verbose=self.verbose,
|
||||
editor=self.editor,
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self, io, coder, voice_language=None, verify_ssl=True, args=None, parser=None, verbose=False
|
||||
self,
|
||||
io,
|
||||
coder,
|
||||
voice_language=None,
|
||||
voice_input_device=None,
|
||||
voice_format=None,
|
||||
verify_ssl=True,
|
||||
args=None,
|
||||
parser=None,
|
||||
verbose=False,
|
||||
editor=None,
|
||||
):
|
||||
self.io = io
|
||||
self.coder = coder
|
||||
@@ -58,14 +71,17 @@ class Commands:
|
||||
voice_language = None
|
||||
|
||||
self.voice_language = voice_language
|
||||
self.voice_format = voice_format
|
||||
self.voice_input_device = voice_input_device
|
||||
|
||||
self.help = None
|
||||
self.editor = editor
|
||||
|
||||
def cmd_model(self, args):
|
||||
"Switch to a new LLM"
|
||||
|
||||
model_name = args.strip()
|
||||
model = models.Model(model_name)
|
||||
model = models.Model(model_name, weak_model=self.coder.main_model.weak_model.name)
|
||||
models.sanity_check_models(self.io, model)
|
||||
raise SwitchCoder(main_model=model)
|
||||
|
||||
@@ -91,6 +107,13 @@ class Commands:
|
||||
("help", "Get help about using aider (usage, config, troubleshoot)."),
|
||||
("ask", "Ask questions about your code without making any changes."),
|
||||
("code", "Ask for changes to your code (using the best edit format)."),
|
||||
(
|
||||
"architect",
|
||||
(
|
||||
"Work with an architect model to design code changes, and an editor to make"
|
||||
" them."
|
||||
),
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
@@ -139,7 +162,7 @@ class Commands:
|
||||
else:
|
||||
self.io.tool_output("Please provide a partial model name to search for.")
|
||||
|
||||
def cmd_web(self, args):
|
||||
def cmd_web(self, args, return_content=False):
|
||||
"Scrape a webpage, convert to markdown and send in a message"
|
||||
|
||||
url = args.strip()
|
||||
@@ -158,11 +181,16 @@ class Commands:
|
||||
)
|
||||
|
||||
content = self.scraper.scrape(url) or ""
|
||||
content = f"{url}:\n\n" + content
|
||||
content = f"Here is the content of {url}:\n\n" + content
|
||||
if return_content:
|
||||
return content
|
||||
|
||||
self.io.tool_output("... done.")
|
||||
self.io.tool_output("... added to chat.")
|
||||
|
||||
return content
|
||||
self.coder.cur_messages += [
|
||||
dict(role="user", content=content),
|
||||
dict(role="assistant", content="Ok."),
|
||||
]
|
||||
|
||||
def is_command(self, inp):
|
||||
return inp[0] in "/!"
|
||||
@@ -376,6 +404,7 @@ class Commands:
|
||||
|
||||
fence = "`" * 3
|
||||
|
||||
file_res = []
|
||||
# files
|
||||
for fname in self.coder.abs_fnames:
|
||||
relative_fname = self.coder.get_rel_fname(fname)
|
||||
@@ -386,7 +415,7 @@ class Commands:
|
||||
# approximate
|
||||
content = f"{relative_fname}\n{fence}\n" + content + "{fence}\n"
|
||||
tokens = self.coder.main_model.token_count(content)
|
||||
res.append((tokens, f"{relative_fname}", "/drop to remove"))
|
||||
file_res.append((tokens, f"{relative_fname}", "/drop to remove"))
|
||||
|
||||
# read-only files
|
||||
for fname in self.coder.abs_read_only_fnames:
|
||||
@@ -396,7 +425,10 @@ class Commands:
|
||||
# approximate
|
||||
content = f"{relative_fname}\n{fence}\n" + content + "{fence}\n"
|
||||
tokens = self.coder.main_model.token_count(content)
|
||||
res.append((tokens, f"{relative_fname} (read-only)", "/drop to remove"))
|
||||
file_res.append((tokens, f"{relative_fname} (read-only)", "/drop to remove"))
|
||||
|
||||
file_res.sort()
|
||||
res.extend(file_res)
|
||||
|
||||
self.io.tool_output(
|
||||
f"Approximate context window usage for {self.coder.main_model.name}, in tokens:"
|
||||
@@ -573,6 +605,10 @@ class Commands:
|
||||
|
||||
self.io.tool_output(f"Diff since {commit_before_message[:7]}...")
|
||||
|
||||
if self.coder.pretty:
|
||||
run_cmd(f"git diff {commit_before_message}")
|
||||
return
|
||||
|
||||
diff = self.coder.repo.diff_commits(
|
||||
self.coder.pretty,
|
||||
commit_before_message,
|
||||
@@ -724,6 +760,7 @@ class Commands:
|
||||
|
||||
if self.io.confirm_ask(f"No files matched '{word}'. Do you want to create {fname}?"):
|
||||
try:
|
||||
fname.parent.mkdir(parents=True, exist_ok=True)
|
||||
fname.touch()
|
||||
all_matched_files.add(str(fname))
|
||||
except OSError as e:
|
||||
@@ -738,6 +775,10 @@ class Commands:
|
||||
)
|
||||
continue
|
||||
|
||||
if self.coder.repo and self.coder.repo.git_ignored_file(matched_file):
|
||||
self.io.tool_error(f"Can't add {matched_file} which is in gitignore")
|
||||
continue
|
||||
|
||||
if abs_file_path in self.coder.abs_fnames:
|
||||
self.io.tool_error(f"{matched_file} is already in the chat as an editable file")
|
||||
continue
|
||||
@@ -766,7 +807,8 @@ class Commands:
|
||||
self.io.tool_error(f"Unable to read {matched_file}")
|
||||
else:
|
||||
self.coder.abs_fnames.add(abs_file_path)
|
||||
self.io.tool_output(f"Added {matched_file} to the chat")
|
||||
fname = self.coder.get_rel_fname(abs_file_path)
|
||||
self.io.tool_output(f"Added {fname} to the chat")
|
||||
self.coder.check_added_files()
|
||||
|
||||
def completions_drop(self):
|
||||
@@ -789,15 +831,33 @@ class Commands:
|
||||
# Expand tilde in the path
|
||||
expanded_word = os.path.expanduser(word)
|
||||
|
||||
# Handle read-only files separately, without glob_filtered_to_repo
|
||||
read_only_matched = [f for f in self.coder.abs_read_only_fnames if expanded_word in f]
|
||||
# Handle read-only files with substring matching and samefile check
|
||||
read_only_matched = []
|
||||
for f in self.coder.abs_read_only_fnames:
|
||||
if expanded_word in f:
|
||||
read_only_matched.append(f)
|
||||
continue
|
||||
|
||||
if read_only_matched:
|
||||
for matched_file in read_only_matched:
|
||||
self.coder.abs_read_only_fnames.remove(matched_file)
|
||||
self.io.tool_output(f"Removed read-only file {matched_file} from the chat")
|
||||
# Try samefile comparison for relative paths
|
||||
try:
|
||||
abs_word = os.path.abspath(expanded_word)
|
||||
if os.path.samefile(abs_word, f):
|
||||
read_only_matched.append(f)
|
||||
except (FileNotFoundError, OSError):
|
||||
continue
|
||||
|
||||
matched_files = self.glob_filtered_to_repo(expanded_word)
|
||||
for matched_file in read_only_matched:
|
||||
self.coder.abs_read_only_fnames.remove(matched_file)
|
||||
self.io.tool_output(f"Removed read-only file {matched_file} from the chat")
|
||||
|
||||
# For editable files, use glob if word contains glob chars, otherwise use substring
|
||||
if any(c in expanded_word for c in "*?[]"):
|
||||
matched_files = self.glob_filtered_to_repo(expanded_word)
|
||||
else:
|
||||
# Use substring matching like we do for read-only files
|
||||
matched_files = [
|
||||
self.coder.get_rel_fname(f) for f in self.coder.abs_fnames if expanded_word in f
|
||||
]
|
||||
|
||||
if not matched_files:
|
||||
matched_files.append(expanded_word)
|
||||
@@ -857,54 +917,47 @@ class Commands:
|
||||
def cmd_run(self, args, add_on_nonzero_exit=False):
|
||||
"Run a shell command and optionally add the output to the chat (alias: !)"
|
||||
exit_status, combined_output = run_cmd(
|
||||
args, verbose=self.verbose, error_print=self.io.tool_error
|
||||
args, verbose=self.verbose, error_print=self.io.tool_error, cwd=self.coder.root
|
||||
)
|
||||
instructions = None
|
||||
|
||||
if combined_output is None:
|
||||
return
|
||||
|
||||
# Calculate token count of output
|
||||
token_count = self.coder.main_model.token_count(combined_output)
|
||||
k_tokens = token_count / 1000
|
||||
|
||||
if add_on_nonzero_exit:
|
||||
add = exit_status != 0
|
||||
else:
|
||||
self.io.tool_output()
|
||||
response = self.io.prompt_ask(
|
||||
"Add the output to the chat?\n(Y)es/(n)o/message with instructions:",
|
||||
).strip()
|
||||
self.io.tool_output()
|
||||
|
||||
if response.lower() in ["yes", "y"]:
|
||||
add = True
|
||||
elif response.lower() in ["no", "n"]:
|
||||
add = False
|
||||
else:
|
||||
add = True
|
||||
instructions = response
|
||||
if response.strip():
|
||||
self.io.user_input(response, log_only=True)
|
||||
self.io.add_to_input_history(response)
|
||||
add = self.io.confirm_ask(f"Add {k_tokens:.1f}k tokens of command output to the chat?")
|
||||
|
||||
if add:
|
||||
for line in combined_output.splitlines():
|
||||
self.io.tool_output(line, log_only=True)
|
||||
num_lines = len(combined_output.strip().splitlines())
|
||||
line_plural = "line" if num_lines == 1 else "lines"
|
||||
self.io.tool_output(f"Added {num_lines} {line_plural} of output to the chat.")
|
||||
|
||||
msg = prompts.run_output.format(
|
||||
command=args,
|
||||
output=combined_output,
|
||||
)
|
||||
|
||||
if instructions:
|
||||
msg = instructions + "\n\n" + msg
|
||||
self.coder.cur_messages += [
|
||||
dict(role="user", content=msg),
|
||||
dict(role="assistant", content="Ok."),
|
||||
]
|
||||
|
||||
return msg
|
||||
if add and exit_status != 0:
|
||||
self.io.placeholder = "What's wrong? Fix"
|
||||
|
||||
def cmd_exit(self, args):
|
||||
"Exit the application"
|
||||
self.coder.event("exit", reason="/exit")
|
||||
sys.exit()
|
||||
|
||||
def cmd_quit(self, args):
|
||||
"Exit the application"
|
||||
sys.exit()
|
||||
self.cmd_exit(args)
|
||||
|
||||
def cmd_ls(self, args):
|
||||
"List all known files and indicate which are included in the chat session"
|
||||
@@ -969,7 +1022,7 @@ class Commands:
|
||||
return
|
||||
|
||||
self.coder.event("interactive help")
|
||||
from aider.coders import Coder
|
||||
from aider.coders.base_coder import Coder
|
||||
|
||||
if not self.help:
|
||||
res = install_help_extra(self.io)
|
||||
@@ -1013,23 +1066,23 @@ class Commands:
|
||||
)
|
||||
|
||||
def cmd_ask(self, args):
|
||||
"Ask questions about the code base without editing any files"
|
||||
"""Ask questions about the code base without editing any files. If no prompt provided, switches to ask mode.""" # noqa
|
||||
return self._generic_chat_command(args, "ask")
|
||||
|
||||
def cmd_code(self, args):
|
||||
"Ask for changes to your code"
|
||||
"""Ask for changes to your code. If no prompt provided, switches to code mode.""" # noqa
|
||||
return self._generic_chat_command(args, self.coder.main_model.edit_format)
|
||||
|
||||
def cmd_architect(self, args):
|
||||
"Enter architect mode to discuss high-level design and architecture"
|
||||
"""Enter architect/editor mode using 2 different models. If no prompt provided, switches to architect/editor mode.""" # noqa
|
||||
return self._generic_chat_command(args, "architect")
|
||||
|
||||
def _generic_chat_command(self, args, edit_format):
|
||||
if not args.strip():
|
||||
self.io.tool_error(f"Please provide a question or topic for the {edit_format} chat.")
|
||||
return
|
||||
# Switch to the corresponding chat mode if no args provided
|
||||
return self.cmd_chat_mode(edit_format)
|
||||
|
||||
from aider.coders import Coder
|
||||
from aider.coders.base_coder import Coder
|
||||
|
||||
coder = Coder.create(
|
||||
io=self.io,
|
||||
@@ -1076,43 +1129,23 @@ class Commands:
|
||||
self.io.tool_error("To use /voice you must provide an OpenAI API key.")
|
||||
return
|
||||
try:
|
||||
self.voice = voice.Voice(audio_format=self.args.voice_format)
|
||||
self.voice = voice.Voice(
|
||||
audio_format=self.voice_format or "wav", device_name=self.voice_input_device
|
||||
)
|
||||
except voice.SoundDeviceError:
|
||||
self.io.tool_error(
|
||||
"Unable to import `sounddevice` and/or `soundfile`, is portaudio installed?"
|
||||
)
|
||||
return
|
||||
|
||||
history_iter = self.io.get_input_history()
|
||||
|
||||
history = []
|
||||
size = 0
|
||||
for line in history_iter:
|
||||
if line.startswith("/"):
|
||||
continue
|
||||
if line in history:
|
||||
continue
|
||||
if size + len(line) > 1024:
|
||||
break
|
||||
size += len(line)
|
||||
history.append(line)
|
||||
|
||||
history.reverse()
|
||||
history = "\n".join(history)
|
||||
|
||||
try:
|
||||
text = self.voice.record_and_transcribe(history, language=self.voice_language)
|
||||
text = self.voice.record_and_transcribe(None, language=self.voice_language)
|
||||
except litellm.OpenAIError as err:
|
||||
self.io.tool_error(f"Unable to use OpenAI whisper model: {err}")
|
||||
return
|
||||
|
||||
if text:
|
||||
self.io.add_to_input_history(text)
|
||||
self.io.print()
|
||||
self.io.user_input(text, log_only=False)
|
||||
self.io.print()
|
||||
|
||||
return text
|
||||
self.io.placeholder = text
|
||||
|
||||
def cmd_paste(self, args):
|
||||
"""Paste image/text from the clipboard into the chat.\
|
||||
@@ -1165,9 +1198,14 @@ class Commands:
|
||||
self.io.tool_error(f"Error processing clipboard content: {e}")
|
||||
|
||||
def cmd_read_only(self, args):
|
||||
"Add files to the chat that are for reference, not to be edited"
|
||||
"Add files to the chat that are for reference only, or turn added files to read-only"
|
||||
if not args.strip():
|
||||
self.io.tool_error("Please provide filenames or directories to read.")
|
||||
# Convert all files in chat to read-only
|
||||
for fname in list(self.coder.abs_fnames):
|
||||
self.coder.abs_fnames.remove(fname)
|
||||
self.coder.abs_read_only_fnames.add(fname)
|
||||
rel_fname = self.coder.get_rel_fname(fname)
|
||||
self.io.tool_output(f"Converted {rel_fname} to read-only")
|
||||
return
|
||||
|
||||
filenames = parse_quoted_filenames(args)
|
||||
@@ -1284,7 +1322,12 @@ class Commands:
|
||||
continue
|
||||
|
||||
self.io.tool_output(f"\nExecuting: {cmd}")
|
||||
self.run(cmd)
|
||||
try:
|
||||
self.run(cmd)
|
||||
except SwitchCoder:
|
||||
self.io.tool_error(
|
||||
f"Command '{cmd}' is only supported in interactive mode, skipping."
|
||||
)
|
||||
|
||||
def completions_raw_save(self, document, complete_event):
|
||||
return self.completions_raw_read_only(document, complete_event)
|
||||
@@ -1316,6 +1359,10 @@ class Commands:
|
||||
except Exception as e:
|
||||
self.io.tool_error(f"Error saving commands to file: {e}")
|
||||
|
||||
def cmd_multiline_mode(self, args):
|
||||
"Toggle multiline mode (swaps behavior of Enter and Meta+Enter)"
|
||||
self.io.toggle_multiline_mode()
|
||||
|
||||
def cmd_copy(self, args):
|
||||
"Copy the last assistant message to the clipboard"
|
||||
all_messages = self.coder.done_messages + self.coder.cur_messages
|
||||
@@ -1357,6 +1404,57 @@ class Commands:
|
||||
|
||||
report_github_issue(issue_text, title=title, confirm=False)
|
||||
|
||||
def cmd_editor(self, initial_content=""):
|
||||
"Open an editor to write a prompt"
|
||||
|
||||
user_input = pipe_editor(initial_content, suffix="md", editor=self.editor)
|
||||
if user_input.strip():
|
||||
self.io.set_placeholder(user_input.rstrip())
|
||||
|
||||
def cmd_copy_context(self, args=None):
|
||||
"""Copy the current chat context as markdown, suitable to paste into a web UI"""
|
||||
|
||||
chunks = self.coder.format_chat_chunks()
|
||||
|
||||
markdown = ""
|
||||
|
||||
# Only include specified chunks in order
|
||||
for messages in [chunks.repo, chunks.readonly_files, chunks.chat_files]:
|
||||
for msg in messages:
|
||||
# Only include user messages
|
||||
if msg["role"] != "user":
|
||||
continue
|
||||
|
||||
content = msg["content"]
|
||||
|
||||
# Handle image/multipart content
|
||||
if isinstance(content, list):
|
||||
for part in content:
|
||||
if part.get("type") == "text":
|
||||
markdown += part["text"] + "\n\n"
|
||||
else:
|
||||
markdown += content + "\n\n"
|
||||
|
||||
args = args or ""
|
||||
markdown += f"""
|
||||
Just tell me how to edit the files to make the changes.
|
||||
Don't give me back entire files.
|
||||
Just show me the edits I need to make.
|
||||
|
||||
{args}
|
||||
"""
|
||||
|
||||
try:
|
||||
pyperclip.copy(markdown)
|
||||
self.io.tool_output("Copied code context to clipboard.")
|
||||
except pyperclip.PyperclipException as e:
|
||||
self.io.tool_error(f"Failed to copy to clipboard: {str(e)}")
|
||||
self.io.tool_output(
|
||||
"You may need to install xclip or xsel on Linux, or pbcopy on macOS."
|
||||
)
|
||||
except Exception as e:
|
||||
self.io.tool_error(f"An unexpected error occurred while copying to clipboard: {str(e)}")
|
||||
|
||||
|
||||
def expand_subdir(file_path):
|
||||
if file_path.is_file():
|
||||
|
||||
72
aider/copypaste.py
Normal file
72
aider/copypaste.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import threading
|
||||
import time
|
||||
|
||||
import pyperclip
|
||||
|
||||
|
||||
class ClipboardWatcher:
|
||||
"""Watches clipboard for changes and updates IO placeholder"""
|
||||
|
||||
def __init__(self, io, verbose=False):
|
||||
self.io = io
|
||||
self.verbose = verbose
|
||||
self.stop_event = None
|
||||
self.watcher_thread = None
|
||||
self.last_clipboard = None
|
||||
self.io.clipboard_watcher = self
|
||||
|
||||
def start(self):
|
||||
"""Start watching clipboard for changes"""
|
||||
self.stop_event = threading.Event()
|
||||
self.last_clipboard = pyperclip.paste()
|
||||
|
||||
def watch_clipboard():
|
||||
while not self.stop_event.is_set():
|
||||
try:
|
||||
current = pyperclip.paste()
|
||||
if current != self.last_clipboard:
|
||||
self.last_clipboard = current
|
||||
self.io.interrupt_input()
|
||||
self.io.placeholder = current
|
||||
if len(current.splitlines()) > 1:
|
||||
self.io.placeholder = "\n" + self.io.placeholder + "\n"
|
||||
|
||||
time.sleep(0.5)
|
||||
except Exception as e:
|
||||
if self.verbose:
|
||||
from aider.dump import dump
|
||||
|
||||
dump(f"Clipboard watcher error: {e}")
|
||||
continue
|
||||
|
||||
self.watcher_thread = threading.Thread(target=watch_clipboard, daemon=True)
|
||||
self.watcher_thread.start()
|
||||
|
||||
def stop(self):
|
||||
"""Stop watching clipboard for changes"""
|
||||
if self.stop_event:
|
||||
self.stop_event.set()
|
||||
if self.watcher_thread:
|
||||
self.watcher_thread.join()
|
||||
self.watcher_thread = None
|
||||
self.stop_event = None
|
||||
|
||||
|
||||
def main():
|
||||
"""Example usage of the clipboard watcher"""
|
||||
from aider.io import InputOutput
|
||||
|
||||
io = InputOutput()
|
||||
watcher = ClipboardWatcher(io, verbose=True)
|
||||
|
||||
try:
|
||||
watcher.start()
|
||||
while True:
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
print("\nStopped watching clipboard")
|
||||
watcher.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
125
aider/deprecated.py
Normal file
125
aider/deprecated.py
Normal file
@@ -0,0 +1,125 @@
|
||||
def add_deprecated_model_args(parser, group):
|
||||
"""Add deprecated model shortcut arguments to the argparse parser."""
|
||||
opus_model = "claude-3-opus-20240229"
|
||||
group.add_argument(
|
||||
"--opus",
|
||||
action="store_true",
|
||||
help=f"Use {opus_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
sonnet_model = "anthropic/claude-3-7-sonnet-20250219"
|
||||
group.add_argument(
|
||||
"--sonnet",
|
||||
action="store_true",
|
||||
help=f"Use {sonnet_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
haiku_model = "claude-3-5-haiku-20241022"
|
||||
group.add_argument(
|
||||
"--haiku",
|
||||
action="store_true",
|
||||
help=f"Use {haiku_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
gpt_4_model = "gpt-4-0613"
|
||||
group.add_argument(
|
||||
"--4",
|
||||
"-4",
|
||||
action="store_true",
|
||||
help=f"Use {gpt_4_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
gpt_4o_model = "gpt-4o"
|
||||
group.add_argument(
|
||||
"--4o",
|
||||
action="store_true",
|
||||
help=f"Use {gpt_4o_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
gpt_4o_mini_model = "gpt-4o-mini"
|
||||
group.add_argument(
|
||||
"--mini",
|
||||
action="store_true",
|
||||
help=f"Use {gpt_4o_mini_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
gpt_4_turbo_model = "gpt-4-1106-preview"
|
||||
group.add_argument(
|
||||
"--4-turbo",
|
||||
action="store_true",
|
||||
help=f"Use {gpt_4_turbo_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
gpt_3_model_name = "gpt-3.5-turbo"
|
||||
group.add_argument(
|
||||
"--35turbo",
|
||||
"--35-turbo",
|
||||
"--3",
|
||||
"-3",
|
||||
action="store_true",
|
||||
help=f"Use {gpt_3_model_name} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
deepseek_model = "deepseek/deepseek-chat"
|
||||
group.add_argument(
|
||||
"--deepseek",
|
||||
action="store_true",
|
||||
help=f"Use {deepseek_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
o1_mini_model = "o1-mini"
|
||||
group.add_argument(
|
||||
"--o1-mini",
|
||||
action="store_true",
|
||||
help=f"Use {o1_mini_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
o1_preview_model = "o1-preview"
|
||||
group.add_argument(
|
||||
"--o1-preview",
|
||||
action="store_true",
|
||||
help=f"Use {o1_preview_model} model for the main chat (deprecated, use --model)",
|
||||
default=False,
|
||||
)
|
||||
|
||||
|
||||
def handle_deprecated_model_args(args, io):
|
||||
"""Handle deprecated model shortcut arguments and provide appropriate warnings."""
|
||||
# Define model mapping
|
||||
model_map = {
|
||||
"opus": "claude-3-opus-20240229",
|
||||
"sonnet": "anthropic/claude-3-7-sonnet-20250219",
|
||||
"haiku": "claude-3-5-haiku-20241022",
|
||||
"4": "gpt-4-0613",
|
||||
"4o": "gpt-4o",
|
||||
"mini": "gpt-4o-mini",
|
||||
"4_turbo": "gpt-4-1106-preview",
|
||||
"35turbo": "gpt-3.5-turbo",
|
||||
"deepseek": "deepseek/deepseek-chat",
|
||||
"o1_mini": "o1-mini",
|
||||
"o1_preview": "o1-preview",
|
||||
}
|
||||
|
||||
# Check if any deprecated args are used
|
||||
for arg_name, model_name in model_map.items():
|
||||
arg_name_clean = arg_name.replace("-", "_")
|
||||
if hasattr(args, arg_name_clean) and getattr(args, arg_name_clean):
|
||||
# Find preferred name to display in warning
|
||||
from aider.models import MODEL_ALIASES
|
||||
|
||||
display_name = model_name
|
||||
# Check if there's a shorter alias for this model
|
||||
for alias, full_name in MODEL_ALIASES.items():
|
||||
if full_name == model_name:
|
||||
display_name = alias
|
||||
break
|
||||
|
||||
# Show the warning
|
||||
io.tool_warning(
|
||||
f"The --{arg_name.replace('_', '-')} flag is deprecated and will be removed in a"
|
||||
f" future version. Please use --model {display_name} instead."
|
||||
)
|
||||
|
||||
# Set the model
|
||||
args.model = model_name
|
||||
break
|
||||
@@ -50,7 +50,6 @@ def diff_partial_update(lines_orig, lines_updated, final=False, fname=None):
|
||||
# dump(lines_orig)
|
||||
# dump(lines_updated)
|
||||
|
||||
assert_newlines(lines_orig)
|
||||
assert_newlines(lines_orig)
|
||||
|
||||
num_orig_lines = len(lines_orig)
|
||||
|
||||
147
aider/editor.py
Normal file
147
aider/editor.py
Normal file
@@ -0,0 +1,147 @@
|
||||
"""
|
||||
Editor module for handling system text editor interactions.
|
||||
|
||||
This module provides functionality to:
|
||||
- Discover and launch the system's configured text editor
|
||||
- Create and manage temporary files for editing
|
||||
- Handle editor preferences from environment variables
|
||||
- Support cross-platform editor operations
|
||||
"""
|
||||
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
from aider.dump import dump # noqa
|
||||
|
||||
DEFAULT_EDITOR_NIX = "vi"
|
||||
DEFAULT_EDITOR_OS_X = "vim"
|
||||
DEFAULT_EDITOR_WINDOWS = "notepad"
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
def print_status_message(success, message, style=None):
|
||||
"""
|
||||
Print a status message with appropriate styling.
|
||||
|
||||
:param success: Whether the operation was successful
|
||||
:param message: The message to display
|
||||
:param style: Optional style override. If None, uses green for success and red for failure
|
||||
"""
|
||||
if style is None:
|
||||
style = "bold green" if success else "bold red"
|
||||
console.print(message, style=style)
|
||||
print("")
|
||||
|
||||
|
||||
def write_temp_file(
|
||||
input_data="",
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
):
|
||||
"""
|
||||
Create a temporary file with the given input data.
|
||||
|
||||
:param input_data: Content to write to the temporary file
|
||||
:param suffix: Optional file extension (without the dot)
|
||||
:param prefix: Optional prefix for the temporary filename
|
||||
:param dir: Optional directory to create the file in
|
||||
:return: Path to the created temporary file
|
||||
:raises: OSError if file creation or writing fails
|
||||
"""
|
||||
kwargs = {"prefix": prefix, "dir": dir}
|
||||
if suffix:
|
||||
kwargs["suffix"] = f".{suffix}"
|
||||
fd, filepath = tempfile.mkstemp(**kwargs)
|
||||
try:
|
||||
with os.fdopen(fd, "w") as f:
|
||||
f.write(input_data)
|
||||
except Exception:
|
||||
os.close(fd)
|
||||
raise
|
||||
return filepath
|
||||
|
||||
|
||||
def get_environment_editor(default=None):
|
||||
"""
|
||||
Fetches the preferred editor from the environment variables.
|
||||
|
||||
This function checks the following environment variables in order to
|
||||
determine the user's preferred editor:
|
||||
|
||||
- VISUAL
|
||||
- EDITOR
|
||||
|
||||
:param default: The default editor to return if no environment variable is set.
|
||||
:type default: str or None
|
||||
:return: The preferred editor as specified by environment variables or the default value.
|
||||
:rtype: str or None
|
||||
"""
|
||||
editor = os.environ.get("VISUAL", os.environ.get("EDITOR", default))
|
||||
return editor
|
||||
|
||||
|
||||
def discover_editor(editor_override=None):
|
||||
"""
|
||||
Discovers and returns the appropriate editor command.
|
||||
|
||||
Handles cases where the editor command includes arguments, including quoted arguments
|
||||
with spaces (e.g. 'vim -c "set noswapfile"').
|
||||
|
||||
:return: The editor command as a string
|
||||
:rtype: str
|
||||
"""
|
||||
system = platform.system()
|
||||
if system == "Windows":
|
||||
default_editor = DEFAULT_EDITOR_WINDOWS
|
||||
elif system == "Darwin":
|
||||
default_editor = DEFAULT_EDITOR_OS_X
|
||||
else:
|
||||
default_editor = DEFAULT_EDITOR_NIX
|
||||
|
||||
if editor_override:
|
||||
editor = editor_override
|
||||
else:
|
||||
editor = get_environment_editor(default_editor)
|
||||
|
||||
return editor
|
||||
|
||||
|
||||
def pipe_editor(input_data="", suffix=None, editor=None):
|
||||
"""
|
||||
Opens the system editor with optional input data and returns the edited content.
|
||||
|
||||
This function creates a temporary file with the provided input data, opens it in
|
||||
the system editor, waits for the user to make changes and close the editor, then
|
||||
reads and returns the modified content. The temporary file is deleted afterwards.
|
||||
|
||||
:param input_data: Initial content to populate the editor with
|
||||
:type input_data: str
|
||||
:param suffix: Optional file extension for the temporary file (e.g. '.txt', '.md')
|
||||
:type suffix: str or None
|
||||
:return: The edited content after the editor is closed
|
||||
:rtype: str
|
||||
"""
|
||||
filepath = write_temp_file(input_data, suffix)
|
||||
command_str = discover_editor(editor)
|
||||
command_str += " " + filepath
|
||||
|
||||
subprocess.call(command_str, shell=True)
|
||||
with open(filepath, "r") as f:
|
||||
output_data = f.read()
|
||||
try:
|
||||
os.remove(filepath)
|
||||
except PermissionError:
|
||||
print_status_message(
|
||||
False,
|
||||
(
|
||||
f"WARNING: Unable to delete temporary file {filepath!r}. You may need to delete it"
|
||||
" manually."
|
||||
),
|
||||
)
|
||||
return output_data
|
||||
86
aider/exceptions.py
Normal file
86
aider/exceptions.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExInfo:
|
||||
name: str
|
||||
retry: bool
|
||||
description: str
|
||||
|
||||
|
||||
EXCEPTIONS = [
|
||||
ExInfo("APIConnectionError", True, None),
|
||||
ExInfo("APIError", True, None),
|
||||
ExInfo("APIResponseValidationError", True, None),
|
||||
ExInfo(
|
||||
"AuthenticationError",
|
||||
False,
|
||||
"The API provider is not able to authenticate you. Check your API key.",
|
||||
),
|
||||
ExInfo("AzureOpenAIError", True, None),
|
||||
ExInfo("BadRequestError", False, None),
|
||||
ExInfo("BudgetExceededError", True, None),
|
||||
ExInfo(
|
||||
"ContentPolicyViolationError",
|
||||
True,
|
||||
"The API provider has refused the request due to a safety policy about the content.",
|
||||
),
|
||||
ExInfo("ContextWindowExceededError", False, None), # special case handled in base_coder
|
||||
ExInfo("InternalServerError", True, "The API provider's servers are down or overloaded."),
|
||||
ExInfo("InvalidRequestError", True, None),
|
||||
ExInfo("JSONSchemaValidationError", True, None),
|
||||
ExInfo("NotFoundError", False, None),
|
||||
ExInfo("OpenAIError", True, None),
|
||||
ExInfo(
|
||||
"RateLimitError",
|
||||
True,
|
||||
"The API provider has rate limited you. Try again later or check your quotas.",
|
||||
),
|
||||
ExInfo("RouterRateLimitError", True, None),
|
||||
ExInfo("ServiceUnavailableError", True, "The API provider's servers are down or overloaded."),
|
||||
ExInfo("UnprocessableEntityError", True, None),
|
||||
ExInfo("UnsupportedParamsError", True, None),
|
||||
ExInfo(
|
||||
"Timeout",
|
||||
True,
|
||||
"The API provider timed out without returning a response. They may be down or overloaded.",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
class LiteLLMExceptions:
|
||||
exceptions = dict()
|
||||
exception_info = {exi.name: exi for exi in EXCEPTIONS}
|
||||
|
||||
def __init__(self):
|
||||
self._load()
|
||||
|
||||
def _load(self, strict=False):
|
||||
import litellm
|
||||
|
||||
for var in dir(litellm):
|
||||
if var.endswith("Error"):
|
||||
if var not in self.exception_info:
|
||||
raise ValueError(f"{var} is in litellm but not in aider's exceptions list")
|
||||
|
||||
for var in self.exception_info:
|
||||
ex = getattr(litellm, var)
|
||||
self.exceptions[ex] = self.exception_info[var]
|
||||
|
||||
def exceptions_tuple(self):
|
||||
return tuple(self.exceptions)
|
||||
|
||||
def get_ex_info(self, ex):
|
||||
"""Return the ExInfo for a given exception instance"""
|
||||
import litellm
|
||||
|
||||
if ex.__class__ is litellm.APIConnectionError:
|
||||
if "google.auth" in str(ex):
|
||||
return ExInfo(
|
||||
"APIConnectionError", False, "You need to: pip install google-generativeai"
|
||||
)
|
||||
if "boto3" in str(ex):
|
||||
return ExInfo("APIConnectionError", False, "You need to: pip install boto3")
|
||||
return self.exceptions.get(ex.__class__, ExInfo(None, None, None))
|
||||
@@ -1,4 +1,7 @@
|
||||
# This needs to sync with MANIFEST.in
|
||||
|
||||
exclude_website_pats = [
|
||||
"**/.DS_Store",
|
||||
"examples/**",
|
||||
"_posts/**",
|
||||
"HISTORY.md",
|
||||
|
||||
@@ -2,7 +2,6 @@ import argparse
|
||||
|
||||
from aider import models, prompts
|
||||
from aider.dump import dump # noqa: F401
|
||||
from aider.sendchat import simple_send_with_retries
|
||||
|
||||
|
||||
class ChatSummary:
|
||||
@@ -26,6 +25,12 @@ class ChatSummary:
|
||||
return sized
|
||||
|
||||
def summarize(self, messages, depth=0):
|
||||
messages = self.summarize_real(messages)
|
||||
if messages and messages[-1]["role"] != "assistant":
|
||||
messages.append(dict(role="assistant", content="Ok."))
|
||||
return messages
|
||||
|
||||
def summarize_real(self, messages, depth=0):
|
||||
if not self.models:
|
||||
raise ValueError("No models available for summarization")
|
||||
|
||||
@@ -88,7 +93,7 @@ class ChatSummary:
|
||||
if summary_tokens + tail_tokens < self.max_tokens:
|
||||
return result
|
||||
|
||||
return self.summarize(result, depth + 1)
|
||||
return self.summarize_real(result, depth + 1)
|
||||
|
||||
def summarize_all(self, messages):
|
||||
content = ""
|
||||
@@ -108,9 +113,7 @@ class ChatSummary:
|
||||
|
||||
for model in self.models:
|
||||
try:
|
||||
summary = simple_send_with_retries(
|
||||
model.name, summarize_messages, extra_params=model.extra_params
|
||||
)
|
||||
summary = model.simple_send_with_retries(summarize_messages)
|
||||
if summary is not None:
|
||||
summary = prompts.summary_prefix + summary
|
||||
return [dict(role="user", content=summary)]
|
||||
|
||||
493
aider/io.py
493
aider/io.py
@@ -1,5 +1,11 @@
|
||||
import base64
|
||||
import functools
|
||||
import os
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import time
|
||||
import webbrowser
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
@@ -9,9 +15,12 @@ from pathlib import Path
|
||||
from prompt_toolkit.completion import Completer, Completion, ThreadedCompleter
|
||||
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
|
||||
from prompt_toolkit.enums import EditingMode
|
||||
from prompt_toolkit.filters import Condition, is_searching
|
||||
from prompt_toolkit.history import FileHistory
|
||||
from prompt_toolkit.key_binding import KeyBindings
|
||||
from prompt_toolkit.keys import Keys
|
||||
from prompt_toolkit.lexers import PygmentsLexer
|
||||
from prompt_toolkit.output.vt100 import is_dumb_terminal
|
||||
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
|
||||
from prompt_toolkit.styles import Style
|
||||
from pygments.lexers import MarkdownLexer, guess_lexer_for_filename
|
||||
@@ -27,6 +36,37 @@ from aider.mdstream import MarkdownStream
|
||||
from .dump import dump # noqa: F401
|
||||
from .utils import is_image_file
|
||||
|
||||
# Constants
|
||||
NOTIFICATION_MESSAGE = "Aider is waiting for your input"
|
||||
|
||||
|
||||
def ensure_hash_prefix(color):
|
||||
"""Ensure hex color values have a # prefix."""
|
||||
if not color:
|
||||
return color
|
||||
if isinstance(color, str) and color.strip() and not color.startswith("#"):
|
||||
# Check if it's a valid hex color (3 or 6 hex digits)
|
||||
if all(c in "0123456789ABCDEFabcdef" for c in color) and len(color) in (3, 6):
|
||||
return f"#{color}"
|
||||
return color
|
||||
|
||||
|
||||
def restore_multiline(func):
|
||||
"""Decorator to restore multiline mode after function execution"""
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
orig_multiline = self.multiline_mode
|
||||
self.multiline_mode = False
|
||||
try:
|
||||
return func(self, *args, **kwargs)
|
||||
except Exception:
|
||||
raise
|
||||
finally:
|
||||
self.multiline_mode = orig_multiline
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@dataclass
|
||||
class ConfirmGroup:
|
||||
@@ -171,6 +211,9 @@ class AutoCompleter(Completer):
|
||||
class InputOutput:
|
||||
num_error_outputs = 0
|
||||
num_user_asks = 0
|
||||
clipboard_watcher = None
|
||||
bell_on_next_input = False
|
||||
notifications_command = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -191,26 +234,48 @@ class InputOutput:
|
||||
completion_menu_current_bg_color=None,
|
||||
code_theme="default",
|
||||
encoding="utf-8",
|
||||
line_endings="platform",
|
||||
dry_run=False,
|
||||
llm_history_file=None,
|
||||
editingmode=EditingMode.EMACS,
|
||||
fancy_input=True,
|
||||
file_watcher=None,
|
||||
multiline_mode=False,
|
||||
root=".",
|
||||
notifications=False,
|
||||
notifications_command=None,
|
||||
):
|
||||
self.placeholder = None
|
||||
self.interrupted = False
|
||||
self.never_prompts = set()
|
||||
self.editingmode = editingmode
|
||||
self.multiline_mode = multiline_mode
|
||||
self.bell_on_next_input = False
|
||||
self.notifications = notifications
|
||||
if notifications and notifications_command is None:
|
||||
self.notifications_command = self.get_default_notification_command()
|
||||
else:
|
||||
self.notifications_command = notifications_command
|
||||
|
||||
no_color = os.environ.get("NO_COLOR")
|
||||
if no_color is not None and no_color != "":
|
||||
pretty = False
|
||||
|
||||
self.user_input_color = user_input_color if pretty else None
|
||||
self.tool_output_color = tool_output_color if pretty else None
|
||||
self.tool_error_color = tool_error_color if pretty else None
|
||||
self.tool_warning_color = tool_warning_color if pretty else None
|
||||
self.assistant_output_color = assistant_output_color
|
||||
self.completion_menu_color = completion_menu_color if pretty else None
|
||||
self.completion_menu_bg_color = completion_menu_bg_color if pretty else None
|
||||
self.completion_menu_current_color = completion_menu_current_color if pretty else None
|
||||
self.completion_menu_current_bg_color = completion_menu_current_bg_color if pretty else None
|
||||
self.user_input_color = ensure_hash_prefix(user_input_color) if pretty else None
|
||||
self.tool_output_color = ensure_hash_prefix(tool_output_color) if pretty else None
|
||||
self.tool_error_color = ensure_hash_prefix(tool_error_color) if pretty else None
|
||||
self.tool_warning_color = ensure_hash_prefix(tool_warning_color) if pretty else None
|
||||
self.assistant_output_color = ensure_hash_prefix(assistant_output_color)
|
||||
self.completion_menu_color = ensure_hash_prefix(completion_menu_color) if pretty else None
|
||||
self.completion_menu_bg_color = (
|
||||
ensure_hash_prefix(completion_menu_bg_color) if pretty else None
|
||||
)
|
||||
self.completion_menu_current_color = (
|
||||
ensure_hash_prefix(completion_menu_current_color) if pretty else None
|
||||
)
|
||||
self.completion_menu_current_bg_color = (
|
||||
ensure_hash_prefix(completion_menu_current_bg_color) if pretty else None
|
||||
)
|
||||
|
||||
self.code_theme = code_theme
|
||||
|
||||
@@ -231,14 +296,29 @@ class InputOutput:
|
||||
self.chat_history_file = None
|
||||
|
||||
self.encoding = encoding
|
||||
valid_line_endings = {"platform", "lf", "crlf"}
|
||||
if line_endings not in valid_line_endings:
|
||||
raise ValueError(
|
||||
f"Invalid line_endings value: {line_endings}. "
|
||||
f"Must be one of: {', '.join(valid_line_endings)}"
|
||||
)
|
||||
self.newline = (
|
||||
None if line_endings == "platform" else "\n" if line_endings == "lf" else "\r\n"
|
||||
)
|
||||
self.dry_run = dry_run
|
||||
|
||||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.append_chat_history(f"\n# aider chat started at {current_time}\n\n")
|
||||
|
||||
self.prompt_session = None
|
||||
self.is_dumb_terminal = is_dumb_terminal()
|
||||
|
||||
if self.is_dumb_terminal:
|
||||
self.pretty = False
|
||||
fancy_input = False
|
||||
|
||||
if fancy_input:
|
||||
# Initialize PromptSession
|
||||
# Initialize PromptSession only if we have a capable terminal
|
||||
session_kwargs = {
|
||||
"input": self.input,
|
||||
"output": self.output,
|
||||
@@ -257,6 +337,11 @@ class InputOutput:
|
||||
self.tool_error(f"Can't initialize prompt toolkit: {err}") # non-pretty
|
||||
else:
|
||||
self.console = Console(force_terminal=False, no_color=True) # non-pretty
|
||||
if self.is_dumb_terminal:
|
||||
self.tool_output("Detected dumb terminal, disabling fancy input and pretty output.")
|
||||
|
||||
self.file_watcher = file_watcher
|
||||
self.root = root
|
||||
|
||||
def _get_style(self):
|
||||
style_dict = {}
|
||||
@@ -311,35 +396,61 @@ class InputOutput:
|
||||
self.tool_error(f"{filename}: {e}")
|
||||
return
|
||||
|
||||
def read_text(self, filename):
|
||||
def read_text(self, filename, silent=False):
|
||||
if is_image_file(filename):
|
||||
return self.read_image(filename)
|
||||
|
||||
try:
|
||||
with open(str(filename), "r", encoding=self.encoding) as f:
|
||||
return f.read()
|
||||
except OSError as err:
|
||||
self.tool_error(f"{filename}: unable to read: {err}")
|
||||
return
|
||||
except FileNotFoundError:
|
||||
self.tool_error(f"{filename}: file not found error")
|
||||
if not silent:
|
||||
self.tool_error(f"{filename}: file not found error")
|
||||
return
|
||||
except IsADirectoryError:
|
||||
self.tool_error(f"{filename}: is a directory")
|
||||
if not silent:
|
||||
self.tool_error(f"{filename}: is a directory")
|
||||
return
|
||||
except OSError as err:
|
||||
if not silent:
|
||||
self.tool_error(f"{filename}: unable to read: {err}")
|
||||
return
|
||||
except UnicodeError as e:
|
||||
self.tool_error(f"{filename}: {e}")
|
||||
self.tool_error("Use --encoding to set the unicode encoding.")
|
||||
if not silent:
|
||||
self.tool_error(f"{filename}: {e}")
|
||||
self.tool_error("Use --encoding to set the unicode encoding.")
|
||||
return
|
||||
|
||||
def write_text(self, filename, content):
|
||||
def write_text(self, filename, content, max_retries=5, initial_delay=0.1):
|
||||
"""
|
||||
Writes content to a file, retrying with progressive backoff if the file is locked.
|
||||
|
||||
:param filename: Path to the file to write.
|
||||
:param content: Content to write to the file.
|
||||
:param max_retries: Maximum number of retries if a file lock is encountered.
|
||||
:param initial_delay: Initial delay (in seconds) before the first retry.
|
||||
"""
|
||||
if self.dry_run:
|
||||
return
|
||||
try:
|
||||
with open(str(filename), "w", encoding=self.encoding) as f:
|
||||
f.write(content)
|
||||
except OSError as err:
|
||||
self.tool_error(f"Unable to write file {filename}: {err}")
|
||||
|
||||
delay = initial_delay
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
with open(str(filename), "w", encoding=self.encoding, newline=self.newline) as f:
|
||||
f.write(content)
|
||||
return # Successfully wrote the file
|
||||
except PermissionError as err:
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(delay)
|
||||
delay *= 2 # Exponential backoff
|
||||
else:
|
||||
self.tool_error(
|
||||
f"Unable to write file {filename} after {max_retries} attempts: {err}"
|
||||
)
|
||||
raise
|
||||
except OSError as err:
|
||||
self.tool_error(f"Unable to write file {filename}: {err}")
|
||||
raise
|
||||
|
||||
def rule(self):
|
||||
if self.pretty:
|
||||
@@ -348,6 +459,13 @@ class InputOutput:
|
||||
else:
|
||||
print()
|
||||
|
||||
def interrupt_input(self):
|
||||
if self.prompt_session and self.prompt_session.app:
|
||||
# Store any partial input before interrupting
|
||||
self.placeholder = self.prompt_session.app.current_buffer.text
|
||||
self.interrupted = True
|
||||
self.prompt_session.app.exit()
|
||||
|
||||
def get_input(
|
||||
self,
|
||||
root,
|
||||
@@ -359,6 +477,9 @@ class InputOutput:
|
||||
):
|
||||
self.rule()
|
||||
|
||||
# Ring the bell if needed
|
||||
self.ring_bell()
|
||||
|
||||
rel_fnames = list(rel_fnames)
|
||||
show = ""
|
||||
if rel_fnames:
|
||||
@@ -368,6 +489,8 @@ class InputOutput:
|
||||
show = self.format_files_for_input(rel_fnames, rel_read_only_fnames)
|
||||
if edit_format:
|
||||
show += edit_format
|
||||
if self.multiline_mode:
|
||||
show += (" " if edit_format else "") + "multi"
|
||||
show += "> "
|
||||
|
||||
inp = ""
|
||||
@@ -386,16 +509,51 @@ class InputOutput:
|
||||
)
|
||||
)
|
||||
|
||||
def suspend_to_bg(event):
|
||||
"""Suspend currently running application."""
|
||||
event.app.suspend_to_background()
|
||||
|
||||
kb = KeyBindings()
|
||||
|
||||
@kb.add(Keys.ControlZ, filter=Condition(lambda: hasattr(signal, "SIGTSTP")))
|
||||
def _(event):
|
||||
"Suspend to background with ctrl-z"
|
||||
suspend_to_bg(event)
|
||||
|
||||
@kb.add("c-space")
|
||||
def _(event):
|
||||
"Ignore Ctrl when pressing space bar"
|
||||
event.current_buffer.insert_text(" ")
|
||||
|
||||
@kb.add("escape", "c-m", eager=True)
|
||||
@kb.add("c-up")
|
||||
def _(event):
|
||||
event.current_buffer.insert_text("\n")
|
||||
"Navigate backward through history"
|
||||
event.current_buffer.history_backward()
|
||||
|
||||
@kb.add("c-down")
|
||||
def _(event):
|
||||
"Navigate forward through history"
|
||||
event.current_buffer.history_forward()
|
||||
|
||||
@kb.add("enter", eager=True, filter=~is_searching)
|
||||
def _(event):
|
||||
"Handle Enter key press"
|
||||
if self.multiline_mode:
|
||||
# In multiline mode, Enter adds a newline
|
||||
event.current_buffer.insert_text("\n")
|
||||
else:
|
||||
# In normal mode, Enter submits
|
||||
event.current_buffer.validate_and_handle()
|
||||
|
||||
@kb.add("escape", "enter", eager=True, filter=~is_searching) # This is Alt+Enter
|
||||
def _(event):
|
||||
"Handle Alt+Enter key press"
|
||||
if self.multiline_mode:
|
||||
# In multiline mode, Alt+Enter submits
|
||||
event.current_buffer.validate_and_handle()
|
||||
else:
|
||||
# In normal mode, Alt+Enter adds a newline
|
||||
event.current_buffer.insert_text("\n")
|
||||
|
||||
while True:
|
||||
if multiline_input:
|
||||
@@ -403,27 +561,90 @@ class InputOutput:
|
||||
|
||||
try:
|
||||
if self.prompt_session:
|
||||
# Use placeholder if set, then clear it
|
||||
default = self.placeholder or ""
|
||||
self.placeholder = None
|
||||
|
||||
self.interrupted = False
|
||||
if not multiline_input:
|
||||
if self.file_watcher:
|
||||
self.file_watcher.start()
|
||||
if self.clipboard_watcher:
|
||||
self.clipboard_watcher.start()
|
||||
|
||||
def get_continuation(width, line_number, is_soft_wrap):
|
||||
return ". "
|
||||
|
||||
line = self.prompt_session.prompt(
|
||||
show,
|
||||
default=default,
|
||||
completer=completer_instance,
|
||||
reserve_space_for_menu=4,
|
||||
complete_style=CompleteStyle.MULTI_COLUMN,
|
||||
style=style,
|
||||
key_bindings=kb,
|
||||
complete_while_typing=True,
|
||||
prompt_continuation=get_continuation,
|
||||
)
|
||||
else:
|
||||
line = input(show)
|
||||
|
||||
# Check if we were interrupted by a file change
|
||||
if self.interrupted:
|
||||
line = line or ""
|
||||
if self.file_watcher:
|
||||
cmd = self.file_watcher.process_changes()
|
||||
return cmd
|
||||
|
||||
except EOFError:
|
||||
raise
|
||||
except Exception as err:
|
||||
import traceback
|
||||
|
||||
self.tool_error(str(err))
|
||||
self.tool_error(traceback.format_exc())
|
||||
return ""
|
||||
except UnicodeEncodeError as err:
|
||||
self.tool_error(str(err))
|
||||
return ""
|
||||
finally:
|
||||
if self.file_watcher:
|
||||
self.file_watcher.stop()
|
||||
if self.clipboard_watcher:
|
||||
self.clipboard_watcher.stop()
|
||||
|
||||
if line and line[0] == "{" and not multiline_input:
|
||||
multiline_input = True
|
||||
inp += line[1:] + "\n"
|
||||
if line.strip("\r\n") and not multiline_input:
|
||||
stripped = line.strip("\r\n")
|
||||
if stripped == "{":
|
||||
multiline_input = True
|
||||
multiline_tag = None
|
||||
inp += ""
|
||||
elif stripped[0] == "{":
|
||||
# Extract tag if it exists (only alphanumeric chars)
|
||||
tag = "".join(c for c in stripped[1:] if c.isalnum())
|
||||
if stripped == "{" + tag:
|
||||
multiline_input = True
|
||||
multiline_tag = tag
|
||||
inp += ""
|
||||
else:
|
||||
inp = line
|
||||
break
|
||||
else:
|
||||
inp = line
|
||||
break
|
||||
continue
|
||||
elif line and line[-1] == "}" and multiline_input:
|
||||
inp += line[:-1] + "\n"
|
||||
break
|
||||
elif multiline_input and line.strip():
|
||||
if multiline_tag:
|
||||
# Check if line is exactly "tag}"
|
||||
if line.strip("\r\n") == f"{multiline_tag}}}":
|
||||
break
|
||||
else:
|
||||
inp += line + "\n"
|
||||
# Check if line is exactly "}"
|
||||
elif line.strip("\r\n") == "}":
|
||||
break
|
||||
else:
|
||||
inp += line + "\n"
|
||||
elif multiline_input:
|
||||
inp += line + "\n"
|
||||
else:
|
||||
@@ -437,10 +658,13 @@ class InputOutput:
|
||||
def add_to_input_history(self, inp):
|
||||
if not self.input_history_file:
|
||||
return
|
||||
FileHistory(self.input_history_file).append_string(inp)
|
||||
# Also add to the in-memory history if it exists
|
||||
if hasattr(self, "session") and hasattr(self.session, "history"):
|
||||
self.session.history.append_string(inp)
|
||||
try:
|
||||
FileHistory(self.input_history_file).append_string(inp)
|
||||
# Also add to the in-memory history if it exists
|
||||
if self.prompt_session and self.prompt_session.history:
|
||||
self.prompt_session.history.append_string(inp)
|
||||
except OSError as err:
|
||||
self.tool_warning(f"Unable to write to input history file: {err}")
|
||||
|
||||
def get_input_history(self):
|
||||
if not self.input_history_file:
|
||||
@@ -457,14 +681,17 @@ class InputOutput:
|
||||
log_file.write(f"{role.upper()} {timestamp}\n")
|
||||
log_file.write(content + "\n")
|
||||
|
||||
def display_user_input(self, inp):
|
||||
if self.pretty and self.user_input_color:
|
||||
style = dict(style=self.user_input_color)
|
||||
else:
|
||||
style = dict()
|
||||
|
||||
self.console.print(Text(inp), **style)
|
||||
|
||||
def user_input(self, inp, log_only=True):
|
||||
if not log_only:
|
||||
if self.pretty and self.user_input_color:
|
||||
style = dict(style=self.user_input_color)
|
||||
else:
|
||||
style = dict()
|
||||
|
||||
self.console.print(Text(inp), **style)
|
||||
self.display_user_input(inp)
|
||||
|
||||
prefix = "####"
|
||||
if inp:
|
||||
@@ -484,6 +711,16 @@ class InputOutput:
|
||||
hist = "\n" + content.strip() + "\n\n"
|
||||
self.append_chat_history(hist)
|
||||
|
||||
def offer_url(self, url, prompt="Open URL for more info?", allow_never=True):
|
||||
"""Offer to open a URL in the browser, returns True if opened."""
|
||||
if url in self.never_prompts:
|
||||
return False
|
||||
if self.confirm_ask(prompt, subject=url, allow_never=allow_never):
|
||||
webbrowser.open(url)
|
||||
return True
|
||||
return False
|
||||
|
||||
@restore_multiline
|
||||
def confirm_ask(
|
||||
self,
|
||||
question,
|
||||
@@ -495,6 +732,9 @@ class InputOutput:
|
||||
):
|
||||
self.num_user_asks += 1
|
||||
|
||||
# Ring the bell if needed
|
||||
self.ring_bell()
|
||||
|
||||
question_id = (question, subject)
|
||||
|
||||
if question_id in self.never_prompts:
|
||||
@@ -505,19 +745,22 @@ class InputOutput:
|
||||
if group:
|
||||
allow_never = True
|
||||
|
||||
valid_responses = ["yes", "no"]
|
||||
valid_responses = ["yes", "no", "skip", "all"]
|
||||
options = " (Y)es/(N)o"
|
||||
if group:
|
||||
if not explicit_yes_required:
|
||||
options += "/(A)ll"
|
||||
valid_responses.append("all")
|
||||
options += "/(S)kip all"
|
||||
valid_responses.append("skip")
|
||||
if allow_never:
|
||||
options += "/(D)on't ask again"
|
||||
valid_responses.append("don't")
|
||||
|
||||
question += options + " [Yes]: "
|
||||
if default.lower().startswith("y"):
|
||||
question += options + " [Yes]: "
|
||||
elif default.lower().startswith("n"):
|
||||
question += options + " [No]: "
|
||||
else:
|
||||
question += options + f" [{default}]: "
|
||||
|
||||
if subject:
|
||||
self.tool_output()
|
||||
@@ -546,16 +789,22 @@ class InputOutput:
|
||||
self.user_input(f"{question}{res}", log_only=False)
|
||||
else:
|
||||
while True:
|
||||
if self.prompt_session:
|
||||
res = self.prompt_session.prompt(
|
||||
question,
|
||||
style=style,
|
||||
)
|
||||
else:
|
||||
res = input(question)
|
||||
try:
|
||||
if self.prompt_session:
|
||||
res = self.prompt_session.prompt(
|
||||
question,
|
||||
style=style,
|
||||
complete_while_typing=False,
|
||||
)
|
||||
else:
|
||||
res = input(question)
|
||||
except EOFError:
|
||||
# Treat EOF (Ctrl+D) as if the user pressed Enter
|
||||
res = default
|
||||
break
|
||||
|
||||
if not res:
|
||||
res = "y" # Default to Yes if no input
|
||||
res = default
|
||||
break
|
||||
res = res.lower()
|
||||
good = any(valid_response.startswith(res) for valid_response in valid_responses)
|
||||
@@ -592,9 +841,13 @@ class InputOutput:
|
||||
|
||||
return is_yes
|
||||
|
||||
@restore_multiline
|
||||
def prompt_ask(self, question, default="", subject=None):
|
||||
self.num_user_asks += 1
|
||||
|
||||
# Ring the bell if needed
|
||||
self.ring_bell()
|
||||
|
||||
if subject:
|
||||
self.tool_output()
|
||||
self.tool_output(subject, bold=True)
|
||||
@@ -606,10 +859,19 @@ class InputOutput:
|
||||
elif self.yes is False:
|
||||
res = "no"
|
||||
else:
|
||||
if self.prompt_session:
|
||||
res = self.prompt_session.prompt(question + " ", default=default, style=style)
|
||||
else:
|
||||
res = input(question + " ")
|
||||
try:
|
||||
if self.prompt_session:
|
||||
res = self.prompt_session.prompt(
|
||||
question + " ",
|
||||
default=default,
|
||||
style=style,
|
||||
complete_while_typing=True,
|
||||
)
|
||||
else:
|
||||
res = input(question + " ")
|
||||
except EOFError:
|
||||
# Treat EOF (Ctrl+D) as if the user pressed Enter
|
||||
res = default
|
||||
|
||||
hist = f"{question.strip()} {res.strip()}"
|
||||
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
||||
@@ -627,9 +889,17 @@ class InputOutput:
|
||||
hist = message.strip() if strip else message
|
||||
self.append_chat_history(hist, linebreak=True, blockquote=True)
|
||||
|
||||
message = Text(message)
|
||||
if not isinstance(message, Text):
|
||||
message = Text(message)
|
||||
style = dict(style=color) if self.pretty and color else dict()
|
||||
self.console.print(message, **style)
|
||||
try:
|
||||
self.console.print(message, **style)
|
||||
except UnicodeEncodeError:
|
||||
# Fallback to ASCII-safe output
|
||||
if isinstance(message, Text):
|
||||
message = message.plain
|
||||
message = str(message).encode("ascii", errors="replace").decode("ascii")
|
||||
self.console.print(message, **style)
|
||||
|
||||
def tool_error(self, message="", strip=True):
|
||||
self.num_error_outputs += 1
|
||||
@@ -663,6 +933,10 @@ class InputOutput:
|
||||
return mdStream
|
||||
|
||||
def assistant_output(self, message, pretty=None):
|
||||
if not message:
|
||||
self.tool_warning("Empty response received from LLM. Check your provider account?")
|
||||
return
|
||||
|
||||
show_resp = message
|
||||
|
||||
# Coder will force pretty off if fence is not triple-backticks
|
||||
@@ -674,13 +948,84 @@ class InputOutput:
|
||||
message, style=self.assistant_output_color, code_theme=self.code_theme
|
||||
)
|
||||
else:
|
||||
show_resp = Text(message or "<no response>")
|
||||
show_resp = Text(message or "(empty response)")
|
||||
|
||||
self.console.print(show_resp)
|
||||
|
||||
def set_placeholder(self, placeholder):
|
||||
"""Set a one-time placeholder text for the next input prompt."""
|
||||
self.placeholder = placeholder
|
||||
|
||||
def print(self, message=""):
|
||||
print(message)
|
||||
|
||||
def llm_started(self):
|
||||
"""Mark that the LLM has started processing, so we should ring the bell on next input"""
|
||||
self.bell_on_next_input = True
|
||||
|
||||
def get_default_notification_command(self):
|
||||
"""Return a default notification command based on the operating system."""
|
||||
import platform
|
||||
|
||||
system = platform.system()
|
||||
|
||||
if system == "Darwin": # macOS
|
||||
# Check for terminal-notifier first
|
||||
if shutil.which("terminal-notifier"):
|
||||
return f"terminal-notifier -title 'Aider' -message '{NOTIFICATION_MESSAGE}'"
|
||||
# Fall back to osascript
|
||||
return (
|
||||
f'osascript -e \'display notification "{NOTIFICATION_MESSAGE}" with title "Aider"\''
|
||||
)
|
||||
elif system == "Linux":
|
||||
# Check for common Linux notification tools
|
||||
for cmd in ["notify-send", "zenity"]:
|
||||
if shutil.which(cmd):
|
||||
if cmd == "notify-send":
|
||||
return f"notify-send 'Aider' '{NOTIFICATION_MESSAGE}'"
|
||||
elif cmd == "zenity":
|
||||
return f"zenity --notification --text='{NOTIFICATION_MESSAGE}'"
|
||||
return None # No known notification tool found
|
||||
elif system == "Windows":
|
||||
# PowerShell notification
|
||||
return (
|
||||
"powershell -command"
|
||||
" \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');"
|
||||
f" [System.Windows.Forms.MessageBox]::Show('{NOTIFICATION_MESSAGE}',"
|
||||
" 'Aider')\""
|
||||
)
|
||||
|
||||
return None # Unknown system
|
||||
|
||||
def ring_bell(self):
|
||||
"""Ring the terminal bell if needed and clear the flag"""
|
||||
if self.bell_on_next_input and self.notifications:
|
||||
if self.notifications_command:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
self.notifications_command, shell=True, capture_output=True
|
||||
)
|
||||
if result.returncode != 0 and result.stderr:
|
||||
error_msg = result.stderr.decode("utf-8", errors="replace")
|
||||
self.tool_warning(f"Failed to run notifications command: {error_msg}")
|
||||
except Exception as e:
|
||||
self.tool_warning(f"Failed to run notifications command: {e}")
|
||||
else:
|
||||
print("\a", end="", flush=True) # Ring the bell
|
||||
self.bell_on_next_input = False # Clear the flag
|
||||
|
||||
def toggle_multiline_mode(self):
|
||||
"""Toggle between normal and multiline input modes"""
|
||||
self.multiline_mode = not self.multiline_mode
|
||||
if self.multiline_mode:
|
||||
self.tool_output(
|
||||
"Multiline mode: Enabled. Enter inserts newline, Alt-Enter submits text"
|
||||
)
|
||||
else:
|
||||
self.tool_output(
|
||||
"Multiline mode: Disabled. Alt-Enter inserts newline, Enter submits text"
|
||||
)
|
||||
|
||||
def append_chat_history(self, text, linebreak=False, blockquote=False, strip=True):
|
||||
if blockquote:
|
||||
if strip:
|
||||
@@ -722,13 +1067,29 @@ class InputOutput:
|
||||
editable_files = [f for f in sorted(rel_fnames) if f not in rel_read_only_fnames]
|
||||
|
||||
if read_only_files:
|
||||
console.print("Read only files:", style="bold")
|
||||
console.print(Columns(read_only_files))
|
||||
# Use shorter of abs/rel paths for readonly files
|
||||
ro_paths = []
|
||||
for rel_path in read_only_files:
|
||||
abs_path = os.path.abspath(os.path.join(self.root, rel_path))
|
||||
ro_paths.append(abs_path if len(abs_path) < len(rel_path) else rel_path)
|
||||
|
||||
files_with_label = ["Readonly:"] + ro_paths
|
||||
read_only_output = StringIO()
|
||||
Console(file=read_only_output, force_terminal=False).print(Columns(files_with_label))
|
||||
read_only_lines = read_only_output.getvalue().splitlines()
|
||||
console.print(Columns(files_with_label))
|
||||
|
||||
if editable_files:
|
||||
files_with_label = editable_files
|
||||
if read_only_files:
|
||||
console.print()
|
||||
console.print("Editable files:", style="bold")
|
||||
console.print(Columns(editable_files))
|
||||
files_with_label = ["Editable:"] + editable_files
|
||||
editable_output = StringIO()
|
||||
Console(file=editable_output, force_terminal=False).print(Columns(files_with_label))
|
||||
editable_lines = editable_output.getvalue().splitlines()
|
||||
|
||||
if len(read_only_lines) > 1 or len(editable_lines) > 1:
|
||||
console.print()
|
||||
console.print(Columns(files_with_label))
|
||||
|
||||
return output.getvalue()
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from grep_ast import TreeContext, filename_to_lang
|
||||
from tree_sitter_languages import get_parser # noqa: E402
|
||||
from grep_ast.tsl import get_parser # noqa: E402
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
from aider.run_cmd import run_cmd_subprocess # noqa: F401
|
||||
|
||||
# tree_sitter is throwing a FutureWarning
|
||||
warnings.simplefilter("ignore", category=FutureWarning)
|
||||
@@ -44,26 +45,22 @@ class Linter:
|
||||
|
||||
def run_cmd(self, cmd, rel_fname, code):
|
||||
cmd += " " + rel_fname
|
||||
cmd = cmd.split()
|
||||
|
||||
returncode = 0
|
||||
stdout = ""
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
returncode, stdout = run_cmd_subprocess(
|
||||
cmd,
|
||||
cwd=self.root,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding=self.encoding,
|
||||
errors="replace",
|
||||
)
|
||||
except OSError as err:
|
||||
print(f"Unable to execute lint command: {err}")
|
||||
return
|
||||
stdout, _ = process.communicate()
|
||||
errors = stdout
|
||||
if process.returncode == 0:
|
||||
if returncode == 0:
|
||||
return # zero exit status
|
||||
|
||||
cmd = " ".join(cmd)
|
||||
res = f"## Running: {cmd}\n\n"
|
||||
res += errors
|
||||
|
||||
@@ -152,12 +149,12 @@ class Linter:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
flake8_cmd,
|
||||
cwd=self.root,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
encoding=self.encoding,
|
||||
errors="replace",
|
||||
cwd=self.root,
|
||||
)
|
||||
errors = result.stdout + result.stderr
|
||||
except Exception as e:
|
||||
|
||||
@@ -2,6 +2,8 @@ import importlib
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
|
||||
warnings.filterwarnings("ignore", category=UserWarning, module="pydantic")
|
||||
|
||||
AIDER_SITE_URL = "https://aider.chat"
|
||||
@@ -13,6 +15,8 @@ os.environ["LITELLM_MODE"] = "PRODUCTION"
|
||||
|
||||
# `import litellm` takes 1.5 seconds, defer it!
|
||||
|
||||
VERBOSE = False
|
||||
|
||||
|
||||
class LazyLiteLLM:
|
||||
_lazy_module = None
|
||||
@@ -27,6 +31,9 @@ class LazyLiteLLM:
|
||||
if self._lazy_module is not None:
|
||||
return
|
||||
|
||||
if VERBOSE:
|
||||
print("Loading litellm...")
|
||||
|
||||
self._lazy_module = importlib.import_module("litellm")
|
||||
|
||||
self._lazy_module.suppress_debug_info = True
|
||||
|
||||
463
aider/main.py
463
aider/main.py
@@ -1,4 +1,3 @@
|
||||
import configparser
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
@@ -6,9 +5,14 @@ import sys
|
||||
import threading
|
||||
import traceback
|
||||
import webbrowser
|
||||
from dataclasses import fields
|
||||
from pathlib import Path
|
||||
|
||||
import git
|
||||
try:
|
||||
import git
|
||||
except ImportError:
|
||||
git = None
|
||||
|
||||
import importlib_resources
|
||||
from dotenv import load_dotenv
|
||||
from prompt_toolkit.enums import EditingMode
|
||||
@@ -17,14 +21,19 @@ from aider import __version__, models, urls, utils
|
||||
from aider.analytics import Analytics
|
||||
from aider.args import get_parser
|
||||
from aider.coders import Coder
|
||||
from aider.coders.base_coder import UnknownEditFormat
|
||||
from aider.commands import Commands, SwitchCoder
|
||||
from aider.copypaste import ClipboardWatcher
|
||||
from aider.deprecated import handle_deprecated_model_args
|
||||
from aider.format_settings import format_settings, scrub_sensitive_info
|
||||
from aider.history import ChatSummary
|
||||
from aider.io import InputOutput
|
||||
from aider.llm import litellm # noqa: F401; properly init litellm on launch
|
||||
from aider.models import ModelSettings
|
||||
from aider.repo import ANY_GIT_ERROR, GitRepo
|
||||
from aider.report import report_uncaught_exceptions
|
||||
from aider.versioncheck import check_version, install_from_main_branch, install_upgrade
|
||||
from aider.watch import FileWatcher
|
||||
|
||||
from .dump import dump # noqa: F401
|
||||
|
||||
@@ -88,31 +97,37 @@ def make_new_repo(git_root, io):
|
||||
|
||||
|
||||
def setup_git(git_root, io):
|
||||
if git is None:
|
||||
return
|
||||
|
||||
try:
|
||||
cwd = Path.cwd()
|
||||
except OSError:
|
||||
cwd = None
|
||||
|
||||
repo = None
|
||||
|
||||
if git_root:
|
||||
repo = git.Repo(git_root)
|
||||
elif Path.cwd() == Path.home():
|
||||
io.tool_warning("You should probably run aider in a directory, not your home dir.")
|
||||
try:
|
||||
repo = git.Repo(git_root)
|
||||
except ANY_GIT_ERROR:
|
||||
pass
|
||||
elif cwd == Path.home():
|
||||
io.tool_warning(
|
||||
"You should probably run aider in your project's directory, not your home dir."
|
||||
)
|
||||
return
|
||||
elif io.confirm_ask("No git repo found, create one to track aider's changes (recommended)?"):
|
||||
git_root = str(Path.cwd().resolve())
|
||||
elif cwd and io.confirm_ask(
|
||||
"No git repo found, create one to track aider's changes (recommended)?"
|
||||
):
|
||||
git_root = str(cwd.resolve())
|
||||
repo = make_new_repo(git_root, io)
|
||||
|
||||
if not repo:
|
||||
return
|
||||
|
||||
user_name = None
|
||||
user_email = None
|
||||
with repo.config_reader() as config:
|
||||
try:
|
||||
user_name = config.get_value("user", "name", None)
|
||||
except (configparser.NoSectionError, configparser.NoOptionError):
|
||||
pass
|
||||
try:
|
||||
user_email = config.get_value("user", "email", None)
|
||||
except (configparser.NoSectionError, configparser.NoOptionError):
|
||||
pass
|
||||
user_name = repo.git.config("--default", "", "--get", "user.name") or None
|
||||
user_email = repo.git.config("--default", "", "--get", "user.email") or None
|
||||
|
||||
if user_name and user_email:
|
||||
return repo.working_tree_dir
|
||||
@@ -134,39 +149,51 @@ def check_gitignore(git_root, io, ask=True):
|
||||
|
||||
try:
|
||||
repo = git.Repo(git_root)
|
||||
if repo.ignored(".aider") and repo.ignored(".env"):
|
||||
patterns_to_add = []
|
||||
|
||||
if not repo.ignored(".aider"):
|
||||
patterns_to_add.append(".aider*")
|
||||
|
||||
env_path = Path(git_root) / ".env"
|
||||
if env_path.exists() and not repo.ignored(".env"):
|
||||
patterns_to_add.append(".env")
|
||||
|
||||
if not patterns_to_add:
|
||||
return
|
||||
|
||||
gitignore_file = Path(git_root) / ".gitignore"
|
||||
if gitignore_file.exists():
|
||||
try:
|
||||
content = io.read_text(gitignore_file)
|
||||
if content is None:
|
||||
return
|
||||
if not content.endswith("\n"):
|
||||
content += "\n"
|
||||
except OSError as e:
|
||||
io.tool_error(f"Error when trying to read {gitignore_file}: {e}")
|
||||
return
|
||||
else:
|
||||
content = ""
|
||||
except ANY_GIT_ERROR:
|
||||
pass
|
||||
return
|
||||
|
||||
patterns = [".aider*", ".env"]
|
||||
patterns_to_add = []
|
||||
|
||||
gitignore_file = Path(git_root) / ".gitignore"
|
||||
if gitignore_file.exists():
|
||||
content = io.read_text(gitignore_file)
|
||||
if content is None:
|
||||
if ask:
|
||||
io.tool_output("You can skip this check with --no-gitignore")
|
||||
if not io.confirm_ask(f"Add {', '.join(patterns_to_add)} to .gitignore (recommended)?"):
|
||||
return
|
||||
existing_lines = content.splitlines()
|
||||
for pat in patterns:
|
||||
if pat not in existing_lines:
|
||||
patterns_to_add.append(pat)
|
||||
else:
|
||||
content = ""
|
||||
patterns_to_add = patterns
|
||||
|
||||
if not patterns_to_add:
|
||||
return
|
||||
|
||||
if ask and not io.confirm_ask(f"Add {', '.join(patterns_to_add)} to .gitignore (recommended)?"):
|
||||
return
|
||||
|
||||
if content and not content.endswith("\n"):
|
||||
content += "\n"
|
||||
content += "\n".join(patterns_to_add) + "\n"
|
||||
io.write_text(gitignore_file, content)
|
||||
|
||||
io.tool_output(f"Added {', '.join(patterns_to_add)} to .gitignore")
|
||||
try:
|
||||
io.write_text(gitignore_file, content)
|
||||
io.tool_output(f"Added {', '.join(patterns_to_add)} to .gitignore")
|
||||
except OSError as e:
|
||||
io.tool_error(f"Error when trying to write to {gitignore_file}: {e}")
|
||||
io.tool_output(
|
||||
"Try running with appropriate permissions or manually add these patterns to .gitignore:"
|
||||
)
|
||||
for pattern in patterns_to_add:
|
||||
io.tool_output(f" {pattern}")
|
||||
|
||||
|
||||
def check_streamlit_install(io):
|
||||
@@ -178,6 +205,22 @@ def check_streamlit_install(io):
|
||||
)
|
||||
|
||||
|
||||
def write_streamlit_credentials():
|
||||
from streamlit.file_util import get_streamlit_file_path
|
||||
|
||||
# See https://github.com/Aider-AI/aider/issues/772
|
||||
|
||||
credential_path = Path(get_streamlit_file_path()) / "credentials.toml"
|
||||
if not os.path.exists(credential_path):
|
||||
empty_creds = '[general]\nemail = ""\n'
|
||||
|
||||
os.makedirs(os.path.dirname(credential_path), exist_ok=True)
|
||||
with open(credential_path, "w") as f:
|
||||
f.write(empty_creds)
|
||||
else:
|
||||
print("Streamlit credentials already exist.")
|
||||
|
||||
|
||||
def launch_gui(args):
|
||||
from streamlit.web import cli
|
||||
|
||||
@@ -186,6 +229,9 @@ def launch_gui(args):
|
||||
print()
|
||||
print("CONTROL-C to exit...")
|
||||
|
||||
# Necessary so streamlit does not prompt the user for an email address.
|
||||
write_streamlit_credentials()
|
||||
|
||||
target = gui.__file__
|
||||
|
||||
st_args = ["run", target]
|
||||
@@ -323,16 +369,18 @@ def load_dotenv_files(git_root, dotenv_fname, encoding="utf-8"):
|
||||
|
||||
|
||||
def register_litellm_models(git_root, model_metadata_fname, io, verbose=False):
|
||||
model_metatdata_files = generate_search_path_list(
|
||||
".aider.model.metadata.json", git_root, model_metadata_fname
|
||||
)
|
||||
model_metadata_files = []
|
||||
|
||||
# Add the resource file path
|
||||
resource_metadata = importlib_resources.files("aider.resources").joinpath("model-metadata.json")
|
||||
model_metatdata_files.append(str(resource_metadata))
|
||||
model_metadata_files.append(str(resource_metadata))
|
||||
|
||||
model_metadata_files += generate_search_path_list(
|
||||
".aider.model.metadata.json", git_root, model_metadata_fname
|
||||
)
|
||||
|
||||
try:
|
||||
model_metadata_files_loaded = models.register_litellm_models(model_metatdata_files)
|
||||
model_metadata_files_loaded = models.register_litellm_models(model_metadata_files)
|
||||
if len(model_metadata_files_loaded) > 0 and verbose:
|
||||
io.tool_output("Loaded model metadata from:")
|
||||
for model_metadata_file in model_metadata_files_loaded:
|
||||
@@ -356,6 +404,12 @@ def sanity_check_repo(repo, io):
|
||||
if not repo.git_repo_error:
|
||||
return True
|
||||
error_msg = str(repo.git_repo_error)
|
||||
except UnicodeDecodeError as exc:
|
||||
error_msg = (
|
||||
"Failed to read the Git repository. This issue is likely caused by a path encoded "
|
||||
f'in a format different from the expected encoding "{sys.getfilesystemencoding()}".\n'
|
||||
f"Internal error: {str(exc)}"
|
||||
)
|
||||
except ANY_GIT_ERROR as exc:
|
||||
error_msg = str(exc)
|
||||
bad_ver = "version in (1, 2)" in error_msg
|
||||
@@ -367,8 +421,7 @@ def sanity_check_repo(repo, io):
|
||||
io.tool_error("Aider only works with git repos with version number 1 or 2.")
|
||||
io.tool_output("You may be able to convert your repo: git update-index --index-version=2")
|
||||
io.tool_output("Or run aider --no-git to proceed without using git.")
|
||||
if io.confirm_ask("Open documentation url for more info?", subject=urls.git_index_version):
|
||||
webbrowser.open(urls.git_index_version)
|
||||
io.offer_url(urls.git_index_version, "Open documentation url for more info?")
|
||||
return False
|
||||
|
||||
io.tool_error("Unable to read git repository, it may be corrupt?")
|
||||
@@ -382,7 +435,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
if force_git_root:
|
||||
if git is None:
|
||||
git_root = None
|
||||
elif force_git_root:
|
||||
git_root = force_git_root
|
||||
else:
|
||||
git_root = get_git_root()
|
||||
@@ -429,6 +484,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
# Parse again to include any arguments that might have been defined in .env
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if git is None:
|
||||
args.git = False
|
||||
|
||||
if args.analytics_disable:
|
||||
analytics = Analytics(permanently_disable=True)
|
||||
print("Analytics have been permanently disabled.")
|
||||
@@ -440,6 +498,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
litellm._load_litellm()
|
||||
litellm._lazy_module.client_session = httpx.Client(verify=False)
|
||||
litellm._lazy_module.aclient_session = httpx.AsyncClient(verify=False)
|
||||
# Set verify_ssl on the model_info_manager
|
||||
models.model_info_manager.set_verify_ssl(False)
|
||||
|
||||
if args.timeout:
|
||||
models.request_timeout = args.timeout
|
||||
|
||||
if args.dark_mode:
|
||||
args.user_input_color = "#32FF32"
|
||||
@@ -480,9 +543,13 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
code_theme=args.code_theme,
|
||||
dry_run=args.dry_run,
|
||||
encoding=args.encoding,
|
||||
line_endings=args.line_endings,
|
||||
llm_history_file=args.llm_history_file,
|
||||
editingmode=editing_mode,
|
||||
fancy_input=args.fancy_input,
|
||||
multiline_mode=args.multiline,
|
||||
notifications=args.notifications,
|
||||
notifications_command=args.notifications_command,
|
||||
)
|
||||
|
||||
io = get_io(args.pretty)
|
||||
@@ -494,9 +561,56 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
io = get_io(False)
|
||||
io.tool_warning("Terminal does not support pretty output (UnicodeDecodeError)")
|
||||
|
||||
# Process any environment variables set via --set-env
|
||||
if args.set_env:
|
||||
for env_setting in args.set_env:
|
||||
try:
|
||||
name, value = env_setting.split("=", 1)
|
||||
os.environ[name.strip()] = value.strip()
|
||||
except ValueError:
|
||||
io.tool_error(f"Invalid --set-env format: {env_setting}")
|
||||
io.tool_output("Format should be: ENV_VAR_NAME=value")
|
||||
return 1
|
||||
|
||||
# Process any API keys set via --api-key
|
||||
if args.api_key:
|
||||
for api_setting in args.api_key:
|
||||
try:
|
||||
provider, key = api_setting.split("=", 1)
|
||||
env_var = f"{provider.strip().upper()}_API_KEY"
|
||||
os.environ[env_var] = key.strip()
|
||||
except ValueError:
|
||||
io.tool_error(f"Invalid --api-key format: {api_setting}")
|
||||
io.tool_output("Format should be: provider=key")
|
||||
return 1
|
||||
|
||||
if args.anthropic_api_key:
|
||||
os.environ["ANTHROPIC_API_KEY"] = args.anthropic_api_key
|
||||
|
||||
if args.openai_api_key:
|
||||
os.environ["OPENAI_API_KEY"] = args.openai_api_key
|
||||
|
||||
# Handle deprecated model shortcut args
|
||||
handle_deprecated_model_args(args, io)
|
||||
if args.openai_api_base:
|
||||
os.environ["OPENAI_API_BASE"] = args.openai_api_base
|
||||
if args.openai_api_version:
|
||||
io.tool_warning(
|
||||
"--openai-api-version is deprecated, use --set-env OPENAI_API_VERSION=<value>"
|
||||
)
|
||||
os.environ["OPENAI_API_VERSION"] = args.openai_api_version
|
||||
if args.openai_api_type:
|
||||
io.tool_warning("--openai-api-type is deprecated, use --set-env OPENAI_API_TYPE=<value>")
|
||||
os.environ["OPENAI_API_TYPE"] = args.openai_api_type
|
||||
if args.openai_organization_id:
|
||||
io.tool_warning(
|
||||
"--openai-organization-id is deprecated, use --set-env OPENAI_ORGANIZATION=<value>"
|
||||
)
|
||||
os.environ["OPENAI_ORGANIZATION"] = args.openai_organization_id
|
||||
|
||||
analytics = Analytics(logfile=args.analytics_log, permanently_disable=args.analytics_disable)
|
||||
if args.analytics:
|
||||
if analytics.need_to_ask():
|
||||
if args.analytics is not False:
|
||||
if analytics.need_to_ask(args.analytics):
|
||||
io.tool_output(
|
||||
"Aider respects your privacy and never collects your code, chat messages, keys or"
|
||||
" personal info."
|
||||
@@ -521,9 +635,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
|
||||
if args.gui and not return_coder:
|
||||
if not check_streamlit_install(io):
|
||||
analytics.event("exit", reason="Streamlit not installed")
|
||||
return
|
||||
analytics.event("gui session")
|
||||
launch_gui(argv)
|
||||
analytics.event("exit", reason="GUI session ended")
|
||||
return
|
||||
|
||||
if args.verbose:
|
||||
@@ -532,7 +648,14 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
|
||||
all_files = args.files + (args.file or [])
|
||||
fnames = [str(Path(fn).resolve()) for fn in all_files]
|
||||
read_only_fnames = [str(Path(fn).resolve()) for fn in (args.read or [])]
|
||||
read_only_fnames = []
|
||||
for fn in args.read or []:
|
||||
path = Path(fn).expanduser().resolve()
|
||||
if path.is_dir():
|
||||
read_only_fnames.extend(str(f) for f in path.rglob("*") if f.is_file())
|
||||
else:
|
||||
read_only_fnames.append(str(path))
|
||||
|
||||
if len(all_files) > 1:
|
||||
good = True
|
||||
for fname in all_files:
|
||||
@@ -543,6 +666,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
io.tool_output(
|
||||
"Provide either a single directory of a git repo, or a list of one or more files."
|
||||
)
|
||||
analytics.event("exit", reason="Invalid directory input")
|
||||
return 1
|
||||
|
||||
git_dname = None
|
||||
@@ -553,26 +677,31 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
fnames = []
|
||||
else:
|
||||
io.tool_error(f"{all_files[0]} is a directory, but --no-git selected.")
|
||||
analytics.event("exit", reason="Directory with --no-git")
|
||||
return 1
|
||||
|
||||
# We can't know the git repo for sure until after parsing the args.
|
||||
# If we guessed wrong, reparse because that changes things like
|
||||
# the location of the config.yml and history files.
|
||||
if args.git and not force_git_root:
|
||||
if args.git and not force_git_root and git is not None:
|
||||
right_repo_root = guessed_wrong_repo(io, git_root, fnames, git_dname)
|
||||
if right_repo_root:
|
||||
analytics.event("exit", reason="Recursing with correct repo")
|
||||
return main(argv, input, output, right_repo_root, return_coder=return_coder)
|
||||
|
||||
if args.just_check_update:
|
||||
update_available = check_version(io, just_check=True, verbose=args.verbose)
|
||||
analytics.event("exit", reason="Just checking update")
|
||||
return 0 if not update_available else 1
|
||||
|
||||
if args.install_main_branch:
|
||||
success = install_from_main_branch(io)
|
||||
analytics.event("exit", reason="Installed main branch")
|
||||
return 0 if success else 1
|
||||
|
||||
if args.upgrade:
|
||||
success = install_upgrade(io)
|
||||
analytics.event("exit", reason="Upgrade completed")
|
||||
return 0 if success else 1
|
||||
|
||||
if args.check_update:
|
||||
@@ -580,6 +709,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
|
||||
if args.list_models:
|
||||
models.print_matching_models(io, args.list_models)
|
||||
analytics.event("exit", reason="Listed models")
|
||||
return 0
|
||||
|
||||
if args.git:
|
||||
@@ -595,29 +725,46 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
cmd_line = scrub_sensitive_info(args, cmd_line)
|
||||
io.tool_output(cmd_line, log_only=True)
|
||||
|
||||
check_and_load_imports(io, verbose=args.verbose)
|
||||
|
||||
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
|
||||
is_first_run = is_first_run_of_new_version(io, verbose=args.verbose)
|
||||
check_and_load_imports(io, is_first_run, 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)
|
||||
|
||||
# Process any command line aliases
|
||||
if args.alias:
|
||||
for alias_def in args.alias:
|
||||
# Split on first colon only
|
||||
parts = alias_def.split(":", 1)
|
||||
if len(parts) != 2:
|
||||
io.tool_error(f"Invalid alias format: {alias_def}")
|
||||
io.tool_output("Format should be: alias:model-name")
|
||||
analytics.event("exit", reason="Invalid alias format error")
|
||||
return 1
|
||||
alias, model = parts
|
||||
models.MODEL_ALIASES[alias.strip()] = model.strip()
|
||||
|
||||
if not args.model:
|
||||
args.model = "gpt-4o-2024-08-06"
|
||||
if os.environ.get("ANTHROPIC_API_KEY"):
|
||||
args.model = "claude-3-5-sonnet-20241022"
|
||||
# Select model based on available API keys
|
||||
model_key_pairs = [
|
||||
("ANTHROPIC_API_KEY", "sonnet"),
|
||||
("DEEPSEEK_API_KEY", "deepseek"),
|
||||
("OPENROUTER_API_KEY", "openrouter/anthropic/claude-3.7-sonnet"),
|
||||
("OPENAI_API_KEY", "gpt-4o"),
|
||||
("GEMINI_API_KEY", "flash"),
|
||||
]
|
||||
|
||||
for env_key, model_name in model_key_pairs:
|
||||
if os.environ.get(env_key):
|
||||
args.model = model_name
|
||||
io.tool_warning(
|
||||
f"Found {env_key} so using {model_name} since no --model was specified."
|
||||
)
|
||||
break
|
||||
if not args.model:
|
||||
io.tool_error("You need to specify a --model and an --api-key to use.")
|
||||
io.offer_url(urls.models_and_keys, "Open documentation url for more info?")
|
||||
return 1
|
||||
|
||||
main_model = models.Model(
|
||||
args.model,
|
||||
@@ -626,12 +773,37 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
editor_edit_format=args.editor_edit_format,
|
||||
)
|
||||
|
||||
# Check if deprecated remove_reasoning is set
|
||||
if main_model.remove_reasoning is not None:
|
||||
io.tool_warning(
|
||||
"Model setting 'remove_reasoning' is deprecated, please use 'reasoning_tag' instead."
|
||||
)
|
||||
|
||||
# Set reasoning effort if specified
|
||||
if args.reasoning_effort is not None:
|
||||
main_model.set_reasoning_effort(args.reasoning_effort)
|
||||
|
||||
# Set thinking tokens if specified
|
||||
if args.thinking_tokens is not None:
|
||||
main_model.set_thinking_tokens(args.thinking_tokens)
|
||||
|
||||
if args.copy_paste and args.edit_format is None:
|
||||
if main_model.edit_format in ("diff", "whole"):
|
||||
main_model.edit_format = "editor-" + main_model.edit_format
|
||||
|
||||
if args.verbose:
|
||||
io.tool_output("Model info:")
|
||||
io.tool_output("Model metadata:")
|
||||
io.tool_output(json.dumps(main_model.info, indent=4))
|
||||
|
||||
io.tool_output("Model settings:")
|
||||
for attr in sorted(fields(ModelSettings), key=lambda x: x.name):
|
||||
val = getattr(main_model, attr.name)
|
||||
val = json.dumps(val, indent=4)
|
||||
io.tool_output(f"{attr.name}: {val}")
|
||||
|
||||
lint_cmds = parse_lint_cmds(args.lint_cmd, io)
|
||||
if lint_cmds is None:
|
||||
analytics.event("exit", reason="Invalid lint command format")
|
||||
return 1
|
||||
|
||||
if args.show_model_warnings:
|
||||
@@ -641,12 +813,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
io.tool_output("You can skip this check with --no-show-model-warnings")
|
||||
|
||||
try:
|
||||
if io.confirm_ask(
|
||||
"Open documentation url for more info?", subject=urls.model_warnings
|
||||
):
|
||||
webbrowser.open(urls.model_warnings)
|
||||
io.offer_url(urls.model_warnings, "Open documentation url for more info?")
|
||||
io.tool_output()
|
||||
except KeyboardInterrupt:
|
||||
analytics.event("exit", reason="Keyboard interrupt during model warnings")
|
||||
return 1
|
||||
|
||||
repo = None
|
||||
@@ -670,10 +840,25 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
|
||||
if not args.skip_sanity_check_repo:
|
||||
if not sanity_check_repo(repo, io):
|
||||
analytics.event("exit", reason="Repository sanity check failed")
|
||||
return 1
|
||||
|
||||
if repo:
|
||||
analytics.event("repo", num_files=len(repo.get_tracked_files()))
|
||||
else:
|
||||
analytics.event("no-repo")
|
||||
|
||||
commands = Commands(
|
||||
io, None, verify_ssl=args.verify_ssl, args=args, parser=parser, verbose=args.verbose
|
||||
io,
|
||||
None,
|
||||
voice_language=args.voice_language,
|
||||
voice_input_device=args.voice_input_device,
|
||||
voice_format=args.voice_format,
|
||||
verify_ssl=args.verify_ssl,
|
||||
args=args,
|
||||
parser=parser,
|
||||
verbose=args.verbose,
|
||||
editor=args.editor,
|
||||
)
|
||||
|
||||
summarizer = ChatSummary(
|
||||
@@ -691,6 +876,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
)
|
||||
args.stream = False
|
||||
|
||||
if args.map_tokens is None:
|
||||
map_tokens = main_model.get_repo_map_tokens()
|
||||
else:
|
||||
map_tokens = args.map_tokens
|
||||
|
||||
try:
|
||||
coder = Coder.create(
|
||||
main_model=main_model,
|
||||
@@ -703,7 +893,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
auto_commits=args.auto_commits,
|
||||
dirty_commits=args.dirty_commits,
|
||||
dry_run=args.dry_run,
|
||||
map_tokens=args.map_tokens,
|
||||
map_tokens=map_tokens,
|
||||
verbose=args.verbose,
|
||||
stream=args.stream,
|
||||
use_git=args.git,
|
||||
@@ -721,14 +911,43 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
num_cache_warming_pings=args.cache_keepalive_pings,
|
||||
suggest_shell_commands=args.suggest_shell_commands,
|
||||
chat_language=args.chat_language,
|
||||
detect_urls=args.detect_urls,
|
||||
auto_copy_context=args.copy_paste,
|
||||
)
|
||||
except UnknownEditFormat as err:
|
||||
io.tool_error(str(err))
|
||||
io.offer_url(urls.edit_formats, "Open documentation about edit formats?")
|
||||
analytics.event("exit", reason="Unknown edit format")
|
||||
return 1
|
||||
except ValueError as err:
|
||||
io.tool_error(str(err))
|
||||
analytics.event("exit", reason="ValueError during coder creation")
|
||||
return 1
|
||||
|
||||
if return_coder:
|
||||
analytics.event("exit", reason="Returning coder object")
|
||||
return coder
|
||||
|
||||
ignores = []
|
||||
if git_root:
|
||||
ignores.append(str(Path(git_root) / ".gitignore"))
|
||||
if args.aiderignore:
|
||||
ignores.append(args.aiderignore)
|
||||
|
||||
if args.watch_files:
|
||||
file_watcher = FileWatcher(
|
||||
coder,
|
||||
gitignores=ignores,
|
||||
verbose=args.verbose,
|
||||
analytics=analytics,
|
||||
root=str(Path.cwd()) if args.subtree_only else None,
|
||||
)
|
||||
coder.file_watcher = file_watcher
|
||||
|
||||
if args.copy_paste:
|
||||
analytics.event("copy-paste mode")
|
||||
ClipboardWatcher(coder.io, verbose=args.verbose)
|
||||
|
||||
coder.show_announcements()
|
||||
|
||||
if args.show_prompts:
|
||||
@@ -737,6 +956,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
]
|
||||
messages = coder.format_messages().all_messages()
|
||||
utils.show_messages(messages)
|
||||
analytics.event("exit", reason="Showed prompts")
|
||||
return
|
||||
|
||||
if args.lint:
|
||||
@@ -745,10 +965,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
if args.test:
|
||||
if not args.test_cmd:
|
||||
io.tool_error("No --test-cmd provided.")
|
||||
analytics.event("exit", reason="No test command provided")
|
||||
return 1
|
||||
test_errors = coder.commands.cmd_test(args.test_cmd)
|
||||
if test_errors:
|
||||
coder.run(test_errors)
|
||||
coder.commands.cmd_test(args.test_cmd)
|
||||
if io.placeholder:
|
||||
coder.run(io.placeholder)
|
||||
|
||||
if args.commit:
|
||||
if args.dry_run:
|
||||
@@ -757,31 +978,44 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
coder.commands.cmd_commit()
|
||||
|
||||
if args.lint or args.test or args.commit:
|
||||
analytics.event("exit", reason="Completed lint/test/commit")
|
||||
return
|
||||
|
||||
if args.show_repo_map:
|
||||
repo_map = coder.get_repo_map()
|
||||
if repo_map:
|
||||
io.tool_output(repo_map)
|
||||
analytics.event("exit", reason="Showed repo map")
|
||||
return
|
||||
|
||||
if args.apply:
|
||||
content = io.read_text(args.apply)
|
||||
if content is None:
|
||||
analytics.event("exit", reason="Failed to read apply content")
|
||||
return
|
||||
coder.partial_response_content = content
|
||||
# For testing #2879
|
||||
# from aider.coders.base_coder import all_fences
|
||||
# coder.fence = all_fences[1]
|
||||
coder.apply_updates()
|
||||
analytics.event("exit", reason="Applied updates")
|
||||
return
|
||||
|
||||
if args.apply_clipboard_edits:
|
||||
args.edit_format = main_model.editor_edit_format
|
||||
args.message = "/paste"
|
||||
|
||||
if "VSCODE_GIT_IPC_HANDLE" in os.environ:
|
||||
args.pretty = False
|
||||
io.tool_output("VSCode terminal detected, pretty output has been disabled.")
|
||||
|
||||
io.tool_output('Use /help <question> for help, run "aider --help" to see cmd line args')
|
||||
if args.show_release_notes is True:
|
||||
io.tool_output(f"Opening release notes: {urls.release_notes}")
|
||||
io.tool_output()
|
||||
webbrowser.open(urls.release_notes)
|
||||
elif args.show_release_notes is None and is_first_run:
|
||||
io.tool_output()
|
||||
io.offer_url(
|
||||
urls.release_notes,
|
||||
"Would you like to see what's new in this version?",
|
||||
allow_never=False,
|
||||
)
|
||||
|
||||
if git_root and Path.cwd().resolve() != Path(git_root).resolve():
|
||||
io.tool_warning(
|
||||
@@ -802,6 +1036,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
coder.run(with_message=args.message)
|
||||
except SwitchCoder:
|
||||
pass
|
||||
analytics.event("exit", reason="Completed --message")
|
||||
return
|
||||
|
||||
if args.message_file:
|
||||
@@ -811,22 +1046,31 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
coder.run(with_message=message_from_file)
|
||||
except FileNotFoundError:
|
||||
io.tool_error(f"Message file not found: {args.message_file}")
|
||||
analytics.event("exit", reason="Message file not found")
|
||||
return 1
|
||||
except IOError as e:
|
||||
io.tool_error(f"Error reading message file: {e}")
|
||||
analytics.event("exit", reason="Message file IO error")
|
||||
return 1
|
||||
|
||||
analytics.event("exit", reason="Completed --message-file")
|
||||
return
|
||||
|
||||
if args.exit:
|
||||
analytics.event("exit", reason="Exit flag set")
|
||||
return
|
||||
|
||||
analytics.event("cli session", main_model=main_model, edit_format=main_model.edit_format)
|
||||
|
||||
while True:
|
||||
try:
|
||||
coder.ok_to_warm_cache = bool(args.cache_keepalive_pings)
|
||||
coder.run()
|
||||
analytics.event("exit", reason="Completed main CLI coder.run")
|
||||
return
|
||||
except SwitchCoder as switch:
|
||||
coder.ok_to_warm_cache = False
|
||||
|
||||
kwargs = dict(io=io, from_coder=coder)
|
||||
kwargs.update(switch.kwargs)
|
||||
if "show_announcements" in kwargs:
|
||||
@@ -838,10 +1082,15 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
||||
coder.show_announcements()
|
||||
|
||||
|
||||
def check_and_load_imports(io, verbose=False):
|
||||
def is_first_run_of_new_version(io, verbose=False):
|
||||
"""Check if this is the first run of a new version/executable combination"""
|
||||
installs_file = Path.home() / ".aider" / "installs.json"
|
||||
key = (__version__, sys.executable)
|
||||
|
||||
# Never show notes for .dev versions
|
||||
if ".dev" in __version__:
|
||||
return False
|
||||
|
||||
if verbose:
|
||||
io.tool_output(
|
||||
f"Checking imports for version {__version__} and executable {sys.executable}"
|
||||
@@ -859,7 +1108,26 @@ def check_and_load_imports(io, verbose=False):
|
||||
if verbose:
|
||||
io.tool_output("Installs file does not exist, creating new dictionary")
|
||||
|
||||
if str(key) not in installs:
|
||||
is_first_run = str(key) not in installs
|
||||
|
||||
if is_first_run:
|
||||
installs[str(key)] = True
|
||||
installs_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(installs_file, "w") as f:
|
||||
json.dump(installs, f, indent=4)
|
||||
|
||||
return is_first_run
|
||||
|
||||
except Exception as e:
|
||||
io.tool_warning(f"Error checking version: {e}")
|
||||
if verbose:
|
||||
io.tool_output(f"Full exception details: {traceback.format_exc()}")
|
||||
return True # Safer to assume it's a first run if we hit an error
|
||||
|
||||
|
||||
def check_and_load_imports(io, is_first_run, verbose=False):
|
||||
try:
|
||||
if is_first_run:
|
||||
if verbose:
|
||||
io.tool_output(
|
||||
"First run for this version and executable, loading imports synchronously"
|
||||
@@ -869,17 +1137,9 @@ def check_and_load_imports(io, verbose=False):
|
||||
except Exception as err:
|
||||
io.tool_error(str(err))
|
||||
io.tool_output("Error loading required imports. Did you install aider properly?")
|
||||
if io.confirm_ask(
|
||||
"Open documentation url for more info?", subject=urls.install_properly
|
||||
):
|
||||
webbrowser.open(urls.install_properly)
|
||||
|
||||
io.offer_url(urls.install_properly, "Open documentation url for more info?")
|
||||
sys.exit(1)
|
||||
|
||||
installs[str(key)] = True
|
||||
installs_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(installs_file, "w") as f:
|
||||
json.dump(installs, f, indent=4)
|
||||
if verbose:
|
||||
io.tool_output("Imports loaded and installs file updated")
|
||||
else:
|
||||
@@ -888,8 +1148,9 @@ def check_and_load_imports(io, verbose=False):
|
||||
thread = threading.Thread(target=load_slow_imports)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
except Exception as e:
|
||||
io.tool_warning(f"Error in checking imports: {e}")
|
||||
io.tool_warning(f"Error in loading imports: {e}")
|
||||
if verbose:
|
||||
io.tool_output(f"Full exception details: {traceback.format_exc()}")
|
||||
|
||||
|
||||
@@ -10,10 +10,17 @@ from rich.text import Text
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
|
||||
_text = """
|
||||
_text_prefix = """
|
||||
# Header
|
||||
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
||||
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
|
||||
when an unknown printer took a galley of type and scrambled it to make a type
|
||||
specimen book. It has survived not only five centuries, but also the leap into
|
||||
electronic typesetting, remaining essentially unchanged. It was popularised in
|
||||
the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
|
||||
and more recently with desktop publishing software like Aldus PageMaker
|
||||
including versions of Lorem Ipsum.
|
||||
|
||||
|
||||
|
||||
@@ -27,10 +34,9 @@ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem
|
||||
|
||||
|
||||
```python
|
||||
import sys
|
||||
"""
|
||||
|
||||
def greeting():
|
||||
print("Hello world!")
|
||||
_text_suffix = """
|
||||
```
|
||||
|
||||
## Sub header too
|
||||
@@ -41,81 +47,146 @@ The end.
|
||||
|
||||
|
||||
class MarkdownStream:
|
||||
live = None
|
||||
when = 0
|
||||
min_delay = 0.050
|
||||
live_window = 6
|
||||
"""Streaming markdown renderer that progressively displays content with a live updating window.
|
||||
|
||||
Uses rich.console and rich.live to render markdown content with smooth scrolling
|
||||
and partial updates. Maintains a sliding window of visible content while streaming
|
||||
in new markdown text.
|
||||
"""
|
||||
|
||||
live = None # Rich Live display instance
|
||||
when = 0 # Timestamp of last update
|
||||
min_delay = 1.0 / 20 # Minimum time between updates (20fps)
|
||||
live_window = 6 # Number of lines to keep visible at bottom during streaming
|
||||
|
||||
def __init__(self, mdargs=None):
|
||||
self.printed = []
|
||||
"""Initialize the markdown stream.
|
||||
|
||||
Args:
|
||||
mdargs (dict, optional): Additional arguments to pass to rich Markdown renderer
|
||||
"""
|
||||
self.printed = [] # Stores lines that have already been printed
|
||||
|
||||
if mdargs:
|
||||
self.mdargs = mdargs
|
||||
else:
|
||||
self.mdargs = dict()
|
||||
|
||||
# Initialize rich Live display with empty text
|
||||
self.live = Live(Text(""), refresh_per_second=1.0 / self.min_delay)
|
||||
self.live.start()
|
||||
|
||||
def _render_markdown_to_lines(self, text):
|
||||
"""Render markdown text to a list of lines.
|
||||
|
||||
Args:
|
||||
text (str): Markdown text to render
|
||||
|
||||
Returns:
|
||||
list: List of rendered lines with line endings preserved
|
||||
"""
|
||||
# Render the markdown to a string buffer
|
||||
string_io = io.StringIO()
|
||||
console = Console(file=string_io, force_terminal=True)
|
||||
markdown = Markdown(text, **self.mdargs)
|
||||
console.print(markdown)
|
||||
output = string_io.getvalue()
|
||||
|
||||
# Split rendered output into lines
|
||||
return output.splitlines(keepends=True)
|
||||
|
||||
def __del__(self):
|
||||
"""Destructor to ensure Live display is properly cleaned up."""
|
||||
if self.live:
|
||||
try:
|
||||
self.live.stop()
|
||||
except Exception:
|
||||
pass
|
||||
pass # Ignore any errors during cleanup
|
||||
|
||||
def update(self, text, final=False):
|
||||
"""Update the displayed markdown content.
|
||||
|
||||
Args:
|
||||
text (str): The markdown text received so far
|
||||
final (bool): If True, this is the final update and we should clean up
|
||||
|
||||
Splits the output into "stable" older lines and the "last few" lines
|
||||
which aren't considered stable. They may shift around as new chunks
|
||||
are appended to the markdown text.
|
||||
|
||||
The stable lines emit to the console above the Live window.
|
||||
The unstable lines emit into the Live window so they can be repainted.
|
||||
|
||||
Markdown going to the console works better in terminal scrollback buffers.
|
||||
The live window doesn't play nice with terminal scrollback.
|
||||
"""
|
||||
now = time.time()
|
||||
# Throttle updates to maintain smooth rendering
|
||||
if not final and now - self.when < self.min_delay:
|
||||
return
|
||||
self.when = now
|
||||
|
||||
string_io = io.StringIO()
|
||||
console = Console(file=string_io, force_terminal=True)
|
||||
# Measure render time and adjust min_delay to maintain smooth rendering
|
||||
start = time.time()
|
||||
lines = self._render_markdown_to_lines(text)
|
||||
render_time = time.time() - start
|
||||
|
||||
markdown = Markdown(text, **self.mdargs)
|
||||
# Set min_delay to render time plus a small buffer
|
||||
self.min_delay = min(max(render_time * 10, 1.0 / 20), 2)
|
||||
|
||||
console.print(markdown)
|
||||
output = string_io.getvalue()
|
||||
|
||||
lines = output.splitlines(keepends=True)
|
||||
num_lines = len(lines)
|
||||
|
||||
# How many lines have "left" the live window and are now considered stable?
|
||||
# Or if final, consider all lines to be stable.
|
||||
if not final:
|
||||
num_lines -= self.live_window
|
||||
|
||||
# If we have stable content to display...
|
||||
if final or num_lines > 0:
|
||||
# How many stable lines do we need to newly show above the live window?
|
||||
num_printed = len(self.printed)
|
||||
|
||||
show = num_lines - num_printed
|
||||
|
||||
# Skip if no new lines to show above live window
|
||||
if show <= 0:
|
||||
return
|
||||
|
||||
# Get the new lines and display them
|
||||
show = lines[num_printed:num_lines]
|
||||
show = "".join(show)
|
||||
show = Text.from_ansi(show)
|
||||
self.live.console.print(show)
|
||||
self.live.console.print(show) # to the console above the live area
|
||||
|
||||
# Update our record of printed lines
|
||||
self.printed = lines[:num_lines]
|
||||
|
||||
# Handle final update cleanup
|
||||
if final:
|
||||
self.live.update(Text(""))
|
||||
self.live.stop()
|
||||
self.live = None
|
||||
else:
|
||||
rest = lines[num_lines:]
|
||||
rest = "".join(rest)
|
||||
# rest = '...\n' + rest
|
||||
rest = Text.from_ansi(rest)
|
||||
self.live.update(rest)
|
||||
return
|
||||
|
||||
# Update the live window with remaining lines
|
||||
rest = lines[num_lines:]
|
||||
rest = "".join(rest)
|
||||
rest = Text.from_ansi(rest)
|
||||
self.live.update(rest)
|
||||
|
||||
def find_minimal_suffix(self, text, match_lines=50):
|
||||
"""
|
||||
Splits text into chunks on blank lines "\n\n".
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_text = 5 * _text
|
||||
with open("aider/io.py", "r") as f:
|
||||
code = f.read()
|
||||
_text = _text_prefix + code + _text_suffix
|
||||
_text = _text * 10
|
||||
|
||||
pm = MarkdownStream()
|
||||
for i in range(6, len(_text)):
|
||||
for i in range(6, len(_text), 5):
|
||||
pm.update(_text[:i])
|
||||
time.sleep(0.01)
|
||||
|
||||
|
||||
1062
aider/models.py
1062
aider/models.py
File diff suppressed because it is too large
Load Diff
26
aider/queries/tree-sitter-language-pack/csharp-tags.scm
Normal file
26
aider/queries/tree-sitter-language-pack/csharp-tags.scm
Normal file
@@ -0,0 +1,26 @@
|
||||
; Based on https://github.com/tree-sitter/tree-sitter-c-sharp/blob/master/queries/tags.scm
|
||||
; MIT License.
|
||||
|
||||
(class_declaration name: (identifier) @name.definition.class) @definition.class
|
||||
|
||||
(class_declaration (base_list (_) @name.reference.class)) @reference.class
|
||||
|
||||
(interface_declaration name: (identifier) @name.definition.interface) @definition.interface
|
||||
|
||||
(interface_declaration (base_list (_) @name.reference.interface)) @reference.interface
|
||||
|
||||
(method_declaration name: (identifier) @name.definition.method) @definition.method
|
||||
|
||||
(object_creation_expression type: (identifier) @name.reference.class) @reference.class
|
||||
|
||||
(type_parameter_constraints_clause (identifier) @name.reference.class) @reference.class
|
||||
|
||||
(type_parameter_constraint (type type: (identifier) @name.reference.class)) @reference.class
|
||||
|
||||
(variable_declaration type: (identifier) @name.reference.class) @reference.class
|
||||
|
||||
(invocation_expression function: (member_access_expression name: (identifier) @name.reference.send)) @reference.send
|
||||
|
||||
(namespace_declaration name: (identifier) @name.definition.module) @definition.module
|
||||
|
||||
(namespace_declaration name: (identifier) @name.definition.module) @module
|
||||
88
aider/queries/tree-sitter-language-pack/javascript-tags.scm
Normal file
88
aider/queries/tree-sitter-language-pack/javascript-tags.scm
Normal file
@@ -0,0 +1,88 @@
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
(method_definition
|
||||
name: (property_identifier) @name.definition.method) @definition.method
|
||||
(#not-eq? @name.definition.method "constructor")
|
||||
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||
(#select-adjacent! @doc @definition.method)
|
||||
)
|
||||
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
[
|
||||
(class
|
||||
name: (_) @name.definition.class)
|
||||
(class_declaration
|
||||
name: (_) @name.definition.class)
|
||||
] @definition.class
|
||||
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||
(#select-adjacent! @doc @definition.class)
|
||||
)
|
||||
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
[
|
||||
(function_expression
|
||||
name: (identifier) @name.definition.function)
|
||||
(function_declaration
|
||||
name: (identifier) @name.definition.function)
|
||||
(generator_function
|
||||
name: (identifier) @name.definition.function)
|
||||
(generator_function_declaration
|
||||
name: (identifier) @name.definition.function)
|
||||
] @definition.function
|
||||
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||
(#select-adjacent! @doc @definition.function)
|
||||
)
|
||||
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
(lexical_declaration
|
||||
(variable_declarator
|
||||
name: (identifier) @name.definition.function
|
||||
value: [(arrow_function) (function_expression)]) @definition.function)
|
||||
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||
(#select-adjacent! @doc @definition.function)
|
||||
)
|
||||
|
||||
(
|
||||
(comment)* @doc
|
||||
.
|
||||
(variable_declaration
|
||||
(variable_declarator
|
||||
name: (identifier) @name.definition.function
|
||||
value: [(arrow_function) (function_expression)]) @definition.function)
|
||||
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||
(#select-adjacent! @doc @definition.function)
|
||||
)
|
||||
|
||||
(assignment_expression
|
||||
left: [
|
||||
(identifier) @name.definition.function
|
||||
(member_expression
|
||||
property: (property_identifier) @name.definition.function)
|
||||
]
|
||||
right: [(arrow_function) (function_expression)]
|
||||
) @definition.function
|
||||
|
||||
(pair
|
||||
key: (property_identifier) @name.definition.function
|
||||
value: [(arrow_function) (function_expression)]) @definition.function
|
||||
|
||||
(
|
||||
(call_expression
|
||||
function: (identifier) @name.reference.call) @reference.call
|
||||
(#not-match? @name.reference.call "^(require)$")
|
||||
)
|
||||
|
||||
(call_expression
|
||||
function: (member_expression
|
||||
property: (property_identifier) @name.reference.call)
|
||||
arguments: (_) @reference.call)
|
||||
|
||||
(new_expression
|
||||
constructor: (_) @name.reference.class) @reference.class
|
||||
91
aider/queries/tree-sitter-languages/dart-tags.scm
Normal file
91
aider/queries/tree-sitter-languages/dart-tags.scm
Normal file
@@ -0,0 +1,91 @@
|
||||
(class_definition
|
||||
name: (identifier) @name.definition.class) @definition.class
|
||||
|
||||
(method_signature
|
||||
(function_signature)) @definition.method
|
||||
|
||||
(type_alias
|
||||
(type_identifier) @name.definition.type) @definition.type
|
||||
|
||||
(method_signature
|
||||
(getter_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(setter_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(function_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(factory_constructor_signature
|
||||
(identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(constructor_signature
|
||||
name: (identifier) @name.definition.method)) @definition.method
|
||||
|
||||
(method_signature
|
||||
(operator_signature)) @definition.method
|
||||
|
||||
(method_signature) @definition.method
|
||||
|
||||
(mixin_declaration
|
||||
(mixin)
|
||||
(identifier) @name.definition.mixin) @definition.mixin
|
||||
|
||||
(extension_declaration
|
||||
name: (identifier) @name.definition.extension) @definition.extension
|
||||
|
||||
(enum_declaration
|
||||
name: (identifier) @name.definition.enum) @definition.enum
|
||||
|
||||
(function_signature
|
||||
name: (identifier) @name.definition.function) @definition.function
|
||||
|
||||
(new_expression
|
||||
(type_identifier) @name.reference.class) @reference.class
|
||||
|
||||
(initialized_variable_definition
|
||||
name: (identifier)
|
||||
value: (identifier) @name.reference.class
|
||||
value: (selector
|
||||
"!"?
|
||||
(argument_part
|
||||
(arguments
|
||||
(argument)*))?)?) @reference.class
|
||||
|
||||
(assignment_expression
|
||||
left: (assignable_expression
|
||||
(identifier)
|
||||
(unconditional_assignable_selector
|
||||
"."
|
||||
(identifier) @name.reference.call))) @reference.call
|
||||
|
||||
(assignment_expression
|
||||
left: (assignable_expression
|
||||
(identifier)
|
||||
(conditional_assignable_selector
|
||||
"?."
|
||||
(identifier) @name.reference.call))) @reference.call
|
||||
|
||||
((identifier) @name
|
||||
(selector
|
||||
"!"?
|
||||
(conditional_assignable_selector
|
||||
"?." (identifier) @name.reference.call)?
|
||||
(unconditional_assignable_selector
|
||||
"."? (identifier) @name.reference.call)?
|
||||
(argument_part
|
||||
(arguments
|
||||
(argument)*))?)*
|
||||
(cascade_section
|
||||
(cascade_selector
|
||||
(identifier)) @name.reference.call
|
||||
(argument_part
|
||||
(arguments
|
||||
(argument)*))?)?) @reference.call
|
||||
|
||||
|
||||
77
aider/queries/tree-sitter-languages/hcl-tags.scm
Normal file
77
aider/queries/tree-sitter-languages/hcl-tags.scm
Normal file
@@ -0,0 +1,77 @@
|
||||
;; Based on https://github.com/tree-sitter-grammars/tree-sitter-hcl/blob/main/make_grammar.js
|
||||
;; Which has Apache 2.0 License
|
||||
;; tags.scm for Terraform (tree-sitter-hcl)
|
||||
|
||||
; === Definitions: Terraform Blocks ===
|
||||
(block
|
||||
(identifier) @block_type
|
||||
(string_lit (template_literal) @resource_type)
|
||||
(string_lit (template_literal) @name.definition.resource)
|
||||
(body) @definition.resource
|
||||
) (#eq? @block_type "resource")
|
||||
|
||||
(block
|
||||
(identifier) @block_type
|
||||
(string_lit (template_literal) @name.definition.module)
|
||||
(body) @definition.module
|
||||
) (#eq? @block_type "module")
|
||||
|
||||
(block
|
||||
(identifier) @block_type
|
||||
(string_lit (template_literal) @name.definition.variable)
|
||||
(body) @definition.variable
|
||||
) (#eq? @block_type "variable")
|
||||
|
||||
(block
|
||||
(identifier) @block_type
|
||||
(string_lit (template_literal) @name.definition.output)
|
||||
(body) @definition.output
|
||||
) (#eq? @block_type "output")
|
||||
|
||||
(block
|
||||
(identifier) @block_type
|
||||
(string_lit (template_literal) @name.definition.provider)
|
||||
(body) @definition.provider
|
||||
) (#eq? @block_type "provider")
|
||||
|
||||
(block
|
||||
(identifier) @block_type
|
||||
(body
|
||||
(attribute
|
||||
(identifier) @name.definition.local
|
||||
(expression) @definition.local
|
||||
)+
|
||||
)
|
||||
) (#eq? @block_type "locals")
|
||||
|
||||
; === References: Variables, Locals, Modules, Data, Resources ===
|
||||
((variable_expr) @ref_type
|
||||
(get_attr (identifier) @name.reference.variable)
|
||||
) @reference.variable
|
||||
(#eq? @ref_type "var")
|
||||
|
||||
((variable_expr) @ref_type
|
||||
(get_attr (identifier) @name.reference.local)
|
||||
) @reference.local
|
||||
(#eq? @ref_type "local")
|
||||
|
||||
((variable_expr) @ref_type
|
||||
(get_attr (identifier) @name.reference.module)
|
||||
) @reference.module
|
||||
(#eq? @ref_type "module")
|
||||
|
||||
((variable_expr) @ref_type
|
||||
(get_attr (identifier) @data_source_type)
|
||||
(get_attr (identifier) @name.reference.data)
|
||||
) @reference.data
|
||||
(#eq? @ref_type "data")
|
||||
|
||||
((variable_expr) @resource_type
|
||||
(get_attr (identifier) @name.reference.resource)
|
||||
) @reference.resource
|
||||
(#not-eq? @resource_type "var")
|
||||
(#not-eq? @resource_type "local")
|
||||
(#not-eq? @resource_type "module")
|
||||
(#not-eq? @resource_type "data")
|
||||
(#not-eq? @resource_type "provider")
|
||||
(#not-eq? @resource_type "output")
|
||||
27
aider/queries/tree-sitter-languages/kotlin-tags.scm
Normal file
27
aider/queries/tree-sitter-languages/kotlin-tags.scm
Normal file
@@ -0,0 +1,27 @@
|
||||
; Definitions
|
||||
|
||||
(class_declaration
|
||||
(type_identifier) @name.definition.class) @definition.class
|
||||
|
||||
(function_declaration
|
||||
(simple_identifier) @name.definition.function) @definition.function
|
||||
|
||||
(object_declaration
|
||||
(type_identifier) @name.definition.object) @definition.object
|
||||
|
||||
; References
|
||||
|
||||
(call_expression
|
||||
[
|
||||
(simple_identifier) @name.reference.call
|
||||
(navigation_expression
|
||||
(navigation_suffix
|
||||
(simple_identifier) @name.reference.call))
|
||||
]) @reference.call
|
||||
|
||||
(delegation_specifier
|
||||
[
|
||||
(user_type) @name.reference.type
|
||||
(constructor_invocation
|
||||
(user_type) @name.reference.type)
|
||||
]) @reference.type
|
||||
82
aider/reasoning_tags.py
Normal file
82
aider/reasoning_tags.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
|
||||
from aider.dump import dump # noqa
|
||||
|
||||
# Standard tag identifier
|
||||
REASONING_TAG = "thinking-content-" + "7bbeb8e1441453ad999a0bbba8a46d4b"
|
||||
# Output formatting
|
||||
REASONING_START = "--------------\n► **THINKING**"
|
||||
REASONING_END = "------------\n► **ANSWER**"
|
||||
|
||||
|
||||
def remove_reasoning_content(res, reasoning_tag):
|
||||
"""
|
||||
Remove reasoning content from text based on tags.
|
||||
|
||||
Args:
|
||||
res (str): The text to process
|
||||
reasoning_tag (str): The tag name to remove
|
||||
|
||||
Returns:
|
||||
str: Text with reasoning content removed
|
||||
"""
|
||||
if not reasoning_tag:
|
||||
return res
|
||||
|
||||
# Try to match the complete tag pattern first
|
||||
pattern = f"<{reasoning_tag}>.*?</{reasoning_tag}>"
|
||||
res = re.sub(pattern, "", res, flags=re.DOTALL).strip()
|
||||
|
||||
# If closing tag exists but opening tag might be missing, remove everything before closing
|
||||
# tag
|
||||
closing_tag = f"</{reasoning_tag}>"
|
||||
if closing_tag in res:
|
||||
# Split on the closing tag and keep everything after it
|
||||
parts = res.split(closing_tag, 1)
|
||||
res = parts[1].strip() if len(parts) > 1 else res
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def replace_reasoning_tags(text, tag_name):
|
||||
"""
|
||||
Replace opening and closing reasoning tags with standard formatting.
|
||||
Ensures exactly one blank line before START and END markers.
|
||||
|
||||
Args:
|
||||
text (str): The text containing the tags
|
||||
tag_name (str): The name of the tag to replace
|
||||
|
||||
Returns:
|
||||
str: Text with reasoning tags replaced with standard format
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
|
||||
# Replace opening tag with proper spacing
|
||||
text = re.sub(f"\\s*<{tag_name}>\\s*", f"\n{REASONING_START}\n\n", text)
|
||||
|
||||
# Replace closing tag with proper spacing
|
||||
text = re.sub(f"\\s*</{tag_name}>\\s*", f"\n\n{REASONING_END}\n\n", text)
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def format_reasoning_content(reasoning_content, tag_name):
|
||||
"""
|
||||
Format reasoning content with appropriate tags.
|
||||
|
||||
Args:
|
||||
reasoning_content (str): The content to format
|
||||
tag_name (str): The tag name to use
|
||||
|
||||
Returns:
|
||||
str: Formatted reasoning content with tags
|
||||
"""
|
||||
if not reasoning_content:
|
||||
return ""
|
||||
|
||||
formatted = f"<{tag_name}>\n\n{reasoning_content}\n\n</{tag_name}>"
|
||||
return formatted
|
||||
@@ -2,23 +2,35 @@ import os
|
||||
import time
|
||||
from pathlib import Path, PurePosixPath
|
||||
|
||||
import git
|
||||
try:
|
||||
import git
|
||||
|
||||
ANY_GIT_ERROR = [
|
||||
git.exc.ODBError,
|
||||
git.exc.GitError,
|
||||
git.exc.InvalidGitRepositoryError,
|
||||
]
|
||||
except ImportError:
|
||||
git = None
|
||||
ANY_GIT_ERROR = []
|
||||
|
||||
import pathspec
|
||||
|
||||
from aider import prompts, utils
|
||||
from aider.sendchat import simple_send_with_retries
|
||||
|
||||
from .dump import dump # noqa: F401
|
||||
|
||||
ANY_GIT_ERROR = (
|
||||
git.exc.ODBError,
|
||||
git.exc.GitError,
|
||||
ANY_GIT_ERROR += [
|
||||
OSError,
|
||||
IndexError,
|
||||
BufferError,
|
||||
TypeError,
|
||||
ValueError,
|
||||
)
|
||||
AttributeError,
|
||||
AssertionError,
|
||||
TimeoutError,
|
||||
]
|
||||
ANY_GIT_ERROR = tuple(ANY_GIT_ERROR)
|
||||
|
||||
|
||||
class GitRepo:
|
||||
@@ -133,7 +145,7 @@ class GitRepo:
|
||||
else:
|
||||
cmd += ["-a"]
|
||||
|
||||
original_user_name = self.repo.config_reader().get_value("user", "name")
|
||||
original_user_name = self.repo.git.config("--get", "user.name")
|
||||
original_committer_name_env = os.environ.get("GIT_COMMITTER_NAME")
|
||||
committer_name = f"{original_user_name} (aider)"
|
||||
|
||||
@@ -141,7 +153,7 @@ class GitRepo:
|
||||
os.environ["GIT_COMMITTER_NAME"] = committer_name
|
||||
|
||||
if aider_edits and self.attribute_author:
|
||||
original_auther_name_env = os.environ.get("GIT_AUTHOR_NAME")
|
||||
original_author_name_env = os.environ.get("GIT_AUTHOR_NAME")
|
||||
os.environ["GIT_AUTHOR_NAME"] = committer_name
|
||||
|
||||
try:
|
||||
@@ -161,15 +173,15 @@ class GitRepo:
|
||||
del os.environ["GIT_COMMITTER_NAME"]
|
||||
|
||||
if aider_edits and self.attribute_author:
|
||||
if original_auther_name_env is not None:
|
||||
os.environ["GIT_AUTHOR_NAME"] = original_auther_name_env
|
||||
if original_author_name_env is not None:
|
||||
os.environ["GIT_AUTHOR_NAME"] = original_author_name_env
|
||||
else:
|
||||
del os.environ["GIT_AUTHOR_NAME"]
|
||||
|
||||
def get_rel_repo_dir(self):
|
||||
try:
|
||||
return os.path.relpath(self.repo.git_dir, os.getcwd())
|
||||
except ValueError:
|
||||
except (ValueError, OSError):
|
||||
return self.repo.git_dir
|
||||
|
||||
def get_commit_message(self, diffs, context):
|
||||
@@ -192,9 +204,7 @@ class GitRepo:
|
||||
max_tokens = model.info.get("max_input_tokens") or 0
|
||||
if max_tokens and num_tokens > max_tokens:
|
||||
continue
|
||||
commit_message = simple_send_with_retries(
|
||||
model.name, messages, extra_params=model.extra_params
|
||||
)
|
||||
commit_message = model.simple_send_with_retries(messages)
|
||||
if commit_message:
|
||||
break
|
||||
|
||||
@@ -278,9 +288,17 @@ class GitRepo:
|
||||
files = self.tree_files[commit]
|
||||
else:
|
||||
try:
|
||||
for blob in commit.tree.traverse():
|
||||
if blob.type == "blob": # blob is a file
|
||||
files.add(blob.path)
|
||||
iterator = commit.tree.traverse()
|
||||
while True:
|
||||
try:
|
||||
blob = next(iterator)
|
||||
if blob.type == "blob": # blob is a file
|
||||
files.add(blob.path)
|
||||
except IndexError:
|
||||
self.io.tool_warning(f"GitRepo: read error skipping {blob.path}")
|
||||
continue
|
||||
except StopIteration:
|
||||
break
|
||||
except ANY_GIT_ERROR as err:
|
||||
self.git_repo_error = err
|
||||
self.io.tool_error(f"Unable to list files in git repo: {err}")
|
||||
@@ -291,8 +309,11 @@ class GitRepo:
|
||||
|
||||
# Add staged files
|
||||
index = self.repo.index
|
||||
staged_files = [path for path, _ in index.entries.keys()]
|
||||
files.update(self.normalize_path(path) for path in staged_files)
|
||||
try:
|
||||
staged_files = [path for path, _ in index.entries.keys()]
|
||||
files.update(self.normalize_path(path) for path in staged_files)
|
||||
except ANY_GIT_ERROR as err:
|
||||
self.io.tool_error(f"Unable to read staged files: {err}")
|
||||
|
||||
res = [fname for fname in files if not self.ignored_file(fname)]
|
||||
|
||||
@@ -331,6 +352,15 @@ class GitRepo:
|
||||
lines,
|
||||
)
|
||||
|
||||
def git_ignored_file(self, path):
|
||||
if not self.repo:
|
||||
return
|
||||
try:
|
||||
if self.repo.ignored(path):
|
||||
return True
|
||||
except ANY_GIT_ERROR:
|
||||
return False
|
||||
|
||||
def ignored_file(self, fname):
|
||||
self.refresh_aider_ignore()
|
||||
|
||||
@@ -343,8 +373,8 @@ class GitRepo:
|
||||
|
||||
def ignored_file_raw(self, fname):
|
||||
if self.subtree_only:
|
||||
fname_path = Path(self.normalize_path(fname))
|
||||
try:
|
||||
fname_path = Path(self.normalize_path(fname))
|
||||
cwd_path = Path.cwd().resolve().relative_to(Path(self.root).resolve())
|
||||
except ValueError:
|
||||
# Issue #1524
|
||||
|
||||
@@ -23,16 +23,20 @@ from aider.utils import Spinner
|
||||
|
||||
# tree_sitter is throwing a FutureWarning
|
||||
warnings.simplefilter("ignore", category=FutureWarning)
|
||||
from tree_sitter_languages import get_language, get_parser # noqa: E402
|
||||
from grep_ast.tsl import USING_TSL_PACK, get_language, get_parser # noqa: E402
|
||||
|
||||
Tag = namedtuple("Tag", "rel_fname fname line name kind".split())
|
||||
|
||||
|
||||
SQLITE_ERRORS = (sqlite3.OperationalError, sqlite3.DatabaseError)
|
||||
SQLITE_ERRORS = (sqlite3.OperationalError, sqlite3.DatabaseError, OSError)
|
||||
|
||||
|
||||
CACHE_VERSION = 3
|
||||
if USING_TSL_PACK:
|
||||
CACHE_VERSION = 4
|
||||
|
||||
|
||||
class RepoMap:
|
||||
CACHE_VERSION = 3
|
||||
TAGS_CACHE_DIR = f".aider.tags.cache.v{CACHE_VERSION}"
|
||||
|
||||
warned_files = set()
|
||||
@@ -197,7 +201,7 @@ class RepoMap:
|
||||
self.TAGS_CACHE = new_cache
|
||||
return
|
||||
|
||||
except (SQLITE_ERRORS, OSError) as e:
|
||||
except SQLITE_ERRORS as e:
|
||||
# If anything goes wrong, warn and fall back to dict
|
||||
self.io.tool_warning(
|
||||
f"Unable to use tags cache at {path}, falling back to memory cache"
|
||||
@@ -282,10 +286,15 @@ class RepoMap:
|
||||
query = language.query(query_scm)
|
||||
captures = query.captures(tree.root_node)
|
||||
|
||||
captures = list(captures)
|
||||
|
||||
saw = set()
|
||||
for node, tag in captures:
|
||||
if USING_TSL_PACK:
|
||||
all_nodes = []
|
||||
for tag, nodes in captures.items():
|
||||
all_nodes += [(node, tag) for node in nodes]
|
||||
else:
|
||||
all_nodes = list(captures)
|
||||
|
||||
for node, tag in all_nodes:
|
||||
if tag.startswith("name.definition."):
|
||||
kind = "def"
|
||||
elif tag.startswith("name.reference."):
|
||||
@@ -422,6 +431,15 @@ class RepoMap:
|
||||
|
||||
G = nx.MultiDiGraph()
|
||||
|
||||
# Add a small self-edge for every definition that has no references
|
||||
# Helps with tree-sitter 0.23.2 with ruby, where "def greet(name)"
|
||||
# isn't counted as a def AND a ref. tree-sitter 0.24.0 does.
|
||||
for ident in defines.keys():
|
||||
if ident in references:
|
||||
continue
|
||||
for definer in defines[ident]:
|
||||
G.add_edge(definer, definer, weight=0.1, ident=ident)
|
||||
|
||||
for ident in idents:
|
||||
if progress:
|
||||
progress()
|
||||
@@ -605,7 +623,7 @@ class RepoMap:
|
||||
|
||||
self.tree_cache = dict()
|
||||
|
||||
middle = min(max_map_tokens // 25, num_tags)
|
||||
middle = min(int(max_map_tokens // 25), num_tags)
|
||||
while lower_bound <= upper_bound:
|
||||
# dump(lower_bound, middle, upper_bound)
|
||||
|
||||
@@ -628,7 +646,7 @@ class RepoMap:
|
||||
else:
|
||||
upper_bound = middle - 1
|
||||
|
||||
middle = (lower_bound + upper_bound) // 2
|
||||
middle = int((lower_bound + upper_bound) // 2)
|
||||
|
||||
spin.end()
|
||||
return best_tree
|
||||
@@ -732,8 +750,27 @@ def get_random_color():
|
||||
|
||||
def get_scm_fname(lang):
|
||||
# Load the tags queries
|
||||
if USING_TSL_PACK:
|
||||
subdir = "tree-sitter-language-pack"
|
||||
try:
|
||||
path = resources.files(__package__).joinpath(
|
||||
"queries",
|
||||
subdir,
|
||||
f"{lang}-tags.scm",
|
||||
)
|
||||
if path.exists():
|
||||
return path
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Fall back to tree-sitter-languages
|
||||
subdir = "tree-sitter-languages"
|
||||
try:
|
||||
return resources.files(__package__).joinpath("queries", f"tree-sitter-{lang}-tags.scm")
|
||||
return resources.files(__package__).joinpath(
|
||||
"queries",
|
||||
subdir,
|
||||
f"{lang}-tags.scm",
|
||||
)
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
|
||||
@@ -1,75 +1,244 @@
|
||||
{
|
||||
"claude-3-5-haiku-20241022": {
|
||||
"max_tokens": 4096,
|
||||
"deepseek-reasoner": {
|
||||
"max_tokens": 8192,
|
||||
"max_input_tokens": 64000,
|
||||
"max_output_tokens": 8192,
|
||||
"input_cost_per_token": 0.00000055,
|
||||
"input_cost_per_token_cache_hit": 0.00000014,
|
||||
"cache_read_input_token_cost": 0.00000014,
|
||||
"cache_creation_input_token_cost": 0.0,
|
||||
"output_cost_per_token": 0.00000219,
|
||||
"litellm_provider": "deepseek",
|
||||
"mode": "chat",
|
||||
//"supports_function_calling": true,
|
||||
"supports_assistant_prefill": true,
|
||||
//"supports_tool_choice": true,
|
||||
"supports_prompt_caching": true
|
||||
},
|
||||
"openrouter/deepseek/deepseek-r1": {
|
||||
"max_tokens": 8192,
|
||||
"max_input_tokens": 64000,
|
||||
"max_output_tokens": 8192,
|
||||
"input_cost_per_token": 0.00000055,
|
||||
"input_cost_per_token_cache_hit": 0.00000014,
|
||||
"cache_read_input_token_cost": 0.00000014,
|
||||
"cache_creation_input_token_cost": 0.0,
|
||||
"output_cost_per_token": 0.00000219,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
//"supports_function_calling": true,
|
||||
"supports_assistant_prefill": true,
|
||||
//"supports_tool_choice": true,
|
||||
"supports_prompt_caching": true
|
||||
},
|
||||
"openrouter/deepseek/deepseek-r1:free": {
|
||||
"max_tokens": 8192,
|
||||
"max_input_tokens": 64000,
|
||||
"max_output_tokens": 8192,
|
||||
"input_cost_per_token": 0.0,
|
||||
"input_cost_per_token_cache_hit": 0.0,
|
||||
"cache_read_input_token_cost": 0.00,
|
||||
"cache_creation_input_token_cost": 0.0,
|
||||
"output_cost_per_token": 0.0,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
//"supports_function_calling": true,
|
||||
"supports_assistant_prefill": true,
|
||||
//"supports_tool_choice": true,
|
||||
"supports_prompt_caching": true
|
||||
},
|
||||
"openrouter/deepseek/deepseek-chat:free": {
|
||||
"max_tokens": 8192,
|
||||
"max_input_tokens": 64000,
|
||||
"max_output_tokens": 8192,
|
||||
"input_cost_per_token": 0.0,
|
||||
"input_cost_per_token_cache_hit": 0.0,
|
||||
"cache_read_input_token_cost": 0.00,
|
||||
"cache_creation_input_token_cost": 0.0,
|
||||
"output_cost_per_token": 0.0,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
//"supports_function_calling": true,
|
||||
"supports_assistant_prefill": true,
|
||||
//"supports_tool_choice": true,
|
||||
"supports_prompt_caching": true
|
||||
},
|
||||
"fireworks_ai/accounts/fireworks/models/deepseek-r1": {
|
||||
"max_tokens": 160000,
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 20480,
|
||||
"litellm_provider": "fireworks_ai",
|
||||
"input_cost_per_token": 0.000008,
|
||||
"output_cost_per_token": 0.000008,
|
||||
"mode": "chat",
|
||||
},
|
||||
"fireworks_ai/accounts/fireworks/models/deepseek-v3": {
|
||||
"max_tokens": 128000,
|
||||
"max_input_tokens": 100000,
|
||||
"max_output_tokens": 8192,
|
||||
"litellm_provider": "fireworks_ai",
|
||||
"input_cost_per_token": 0.0000009,
|
||||
"output_cost_per_token": 0.0000009,
|
||||
"mode": "chat",
|
||||
},
|
||||
"o3-mini": {
|
||||
"max_tokens": 100000,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000001,
|
||||
"output_cost_per_token": 0.000005,
|
||||
"max_output_tokens": 100000,
|
||||
"input_cost_per_token": 0.0000011,
|
||||
"output_cost_per_token": 0.0000044,
|
||||
"cache_read_input_token_cost": 0.00000055,
|
||||
"litellm_provider": "openai",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_vision": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_response_schema": true
|
||||
},
|
||||
"openrouter/openai/o3-mini": {
|
||||
"max_tokens": 100000,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 100000,
|
||||
"input_cost_per_token": 0.0000011,
|
||||
"output_cost_per_token": 0.0000044,
|
||||
"cache_read_input_token_cost": 0.00000055,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_vision": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_response_schema": true
|
||||
},
|
||||
"openrouter/openai/o3-mini-high": {
|
||||
"max_tokens": 100000,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 100000,
|
||||
"input_cost_per_token": 0.0000011,
|
||||
"output_cost_per_token": 0.0000044,
|
||||
"cache_read_input_token_cost": 0.00000055,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_vision": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_response_schema": true
|
||||
},
|
||||
"openrouter/openai/gpt-4o-mini": {
|
||||
"max_tokens": 16384,
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 16384,
|
||||
"input_cost_per_token": 0.00000015,
|
||||
"output_cost_per_token": 0.00000060,
|
||||
"input_cost_per_token_batches": 0.000000075,
|
||||
"output_cost_per_token_batches": 0.00000030,
|
||||
"cache_read_input_token_cost": 0.000000075,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_vision": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_system_messages": true
|
||||
},
|
||||
"claude-3-7-sonnet-20250219": {
|
||||
"max_tokens": 8192,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 8192,
|
||||
"input_cost_per_token": 0.000003,
|
||||
"output_cost_per_token": 0.000015,
|
||||
"cache_creation_input_token_cost": 0.00000375,
|
||||
"cache_read_input_token_cost": 0.0000003,
|
||||
"litellm_provider": "anthropic",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"tool_use_system_prompt_tokens": 264,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 159,
|
||||
"supports_assistant_prefill": true,
|
||||
"supports_prompt_caching": true
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"deprecation_date": "2025-10-01",
|
||||
"supports_tool_choice": true
|
||||
},
|
||||
"vertex_ai/claude-3-5-haiku@20241022": {
|
||||
"max_tokens": 4096,
|
||||
"anthropic/claude-3-7-sonnet-20250219": {
|
||||
"max_tokens": 8192,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000001,
|
||||
"output_cost_per_token": 0.000005,
|
||||
"litellm_provider": "vertex_ai-anthropic_models",
|
||||
"max_output_tokens": 8192,
|
||||
"input_cost_per_token": 0.000003,
|
||||
"output_cost_per_token": 0.000015,
|
||||
"cache_creation_input_token_cost": 0.00000375,
|
||||
"cache_read_input_token_cost": 0.0000003,
|
||||
"litellm_provider": "anthropic",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"supports_assistant_prefill": true
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 159,
|
||||
"supports_assistant_prefill": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"deprecation_date": "2025-10-01",
|
||||
"supports_tool_choice": true
|
||||
},
|
||||
"openrouter/anthropic/claude-3-5-haiku": {
|
||||
"max_tokens": 200000,
|
||||
"input_cost_per_token": 0.000001,
|
||||
"output_cost_per_token": 0.000005,
|
||||
"openrouter/anthropic/claude-3.7-sonnet": {
|
||||
"max_tokens": 8192,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 8192,
|
||||
"input_cost_per_token": 0.000003,
|
||||
"output_cost_per_token": 0.000015,
|
||||
"cache_creation_input_token_cost": 0.00000375,
|
||||
"cache_read_input_token_cost": 0.0000003,
|
||||
"litellm_provider": "openrouter",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"supports_vision": true,
|
||||
"tool_use_system_prompt_tokens": 159,
|
||||
"supports_assistant_prefill": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"deprecation_date": "2025-10-01",
|
||||
"supports_tool_choice": true
|
||||
},
|
||||
"openrouter/anthropic/claude-3-5-haiku-20241022": {
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000001,
|
||||
"output_cost_per_token": 0.000005,
|
||||
"litellm_provider": "openrouter",
|
||||
"gpt-4.5-preview": {
|
||||
"max_tokens": 16384,
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 16384,
|
||||
"input_cost_per_token": 0.000075,
|
||||
"output_cost_per_token": 0.00015,
|
||||
"cache_read_input_token_cost": 0.0000375,
|
||||
"litellm_provider": "openai",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"tool_use_system_prompt_tokens": 264
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_vision": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true
|
||||
},
|
||||
"anthropic.claude-3-5-haiku-20241022-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000001,
|
||||
"output_cost_per_token": 0.000005,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
},
|
||||
"us.anthropic.claude-3-5-haiku-20241022-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000001,
|
||||
"output_cost_per_token": 0.000005,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
},
|
||||
"eu.anthropic.claude-3-5-haiku-20241022-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 200000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000001,
|
||||
"output_cost_per_token": 0.000005,
|
||||
"litellm_provider": "bedrock",
|
||||
"openai/gpt-4.5-preview": {
|
||||
"max_tokens": 16384,
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 16384,
|
||||
"input_cost_per_token": 0.000075,
|
||||
"output_cost_per_token": 0.00015,
|
||||
"cache_read_input_token_cost": 0.0000375,
|
||||
"litellm_provider": "openai",
|
||||
"mode": "chat",
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_vision": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true
|
||||
},
|
||||
}
|
||||
|
||||
885
aider/resources/model-settings.yml
Normal file
885
aider/resources/model-settings.yml
Normal file
@@ -0,0 +1,885 @@
|
||||
- name: gpt-3.5-turbo
|
||||
weak_model_name: gpt-4o-mini
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-3.5-turbo-0125
|
||||
weak_model_name: gpt-4o-mini
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-3.5-turbo-1106
|
||||
weak_model_name: gpt-4o-mini
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-3.5-turbo-0613
|
||||
weak_model_name: gpt-4o-mini
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-3.5-turbo-16k-0613
|
||||
weak_model_name: gpt-4o-mini
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-4-turbo-2024-04-09
|
||||
edit_format: udiff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-4-turbo
|
||||
edit_format: udiff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
|
||||
- name: openai/gpt-4o
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openai/gpt-4o-2024-08-06
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: gpt-4o-2024-08-06
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: gpt-4o-2024-11-20
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: openai/gpt-4o-2024-11-20
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: gpt-4o
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: gpt-4o-mini
|
||||
weak_model_name: gpt-4o-mini
|
||||
lazy: true
|
||||
reminder: sys
|
||||
|
||||
- name: openai/gpt-4o-mini
|
||||
weak_model_name: openai/gpt-4o-mini
|
||||
lazy: true
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-4-0125-preview
|
||||
edit_format: udiff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: gpt-4-1106-preview
|
||||
edit_format: udiff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-4-vision-preview
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-4-0314
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: gpt-4-0613
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
|
||||
- name: gpt-4-32k-0613
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
|
||||
- name: claude-3-opus-20240229
|
||||
edit_format: diff
|
||||
weak_model_name: claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
|
||||
- name: openrouter/anthropic/claude-3-opus
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/anthropic/claude-3-5-haiku
|
||||
use_repo_map: true
|
||||
|
||||
- name: claude-3-sonnet-20240229
|
||||
weak_model_name: claude-3-5-haiku-20241022
|
||||
|
||||
- name: claude-3-5-sonnet-20240620
|
||||
edit_format: diff
|
||||
weak_model_name: claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: claude-3-5-sonnet-20240620
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: anthropic/claude-3-5-sonnet-20240620
|
||||
edit_format: diff
|
||||
weak_model_name: anthropic/claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: anthropic/claude-3-5-sonnet-20240620
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: anthropic/claude-3-5-sonnet-20241022
|
||||
edit_format: diff
|
||||
weak_model_name: anthropic/claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: anthropic/claude-3-5-sonnet-20241022
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: anthropic/claude-3-7-sonnet-20250219
|
||||
edit_format: diff
|
||||
weak_model_name: anthropic/claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: anthropic/claude-3-7-sonnet-20250219
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: anthropic/claude-3-7-sonnet-latest
|
||||
edit_format: diff
|
||||
weak_model_name: anthropic/claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: anthropic/claude-3-7-sonnet-latest
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: claude-3-7-sonnet-20250219
|
||||
edit_format: diff
|
||||
weak_model_name: claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: claude-3-7-sonnet-20250219
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: claude-3-7-sonnet-latest
|
||||
edit_format: diff
|
||||
weak_model_name: claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: claude-3-7-sonnet-latest
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: bedrock/anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
edit_format: diff
|
||||
weak_model_name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: bedrock/anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
edit_format: diff
|
||||
weak_model_name: bedrock/us.anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: bedrock_converse/anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
edit_format: diff
|
||||
weak_model_name: bedrock_converse/anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: bedrock_converse/anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: bedrock_converse/us.anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
edit_format: diff
|
||||
weak_model_name: bedrock_converse/us.anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: bedrock_converse/us.anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: vertex_ai/claude-3-7-sonnet@20250219
|
||||
edit_format: diff
|
||||
weak_model_name: vertex_ai/claude-3-5-haiku@20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 64000
|
||||
editor_model_name: vertex_ai/claude-3-7-sonnet@20250219
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: vertex_ai-anthropic_models/vertex_ai/claude-3-7-sonnet@20250219
|
||||
edit_format: diff
|
||||
weak_model_name: vertex_ai/claude-3-5-haiku@20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 64000
|
||||
editor_model_name: vertex_ai-anthropic_models/vertex_ai/claude-3-7-sonnet@20250219
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/anthropic/claude-3.7-sonnet
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/anthropic/claude-3-5-haiku
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: openrouter/anthropic/claude-3.7-sonnet
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/anthropic/claude-3.7-sonnet:beta
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/anthropic/claude-3-5-haiku
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25,output-128k-2025-02-19
|
||||
max_tokens: 64000
|
||||
cache_control: true
|
||||
editor_model_name: openrouter/anthropic/claude-3.7-sonnet
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
|
||||
edit_format: diff
|
||||
weak_model_name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: anthropic/claude-3-5-sonnet-latest
|
||||
edit_format: diff
|
||||
weak_model_name: anthropic/claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: anthropic/claude-3-5-sonnet-20241022
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: claude-3-5-sonnet-20241022
|
||||
edit_format: diff
|
||||
weak_model_name: claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: claude-3-5-sonnet-20241022
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: anthropic/claude-3-haiku-20240307
|
||||
weak_model_name: anthropic/claude-3-haiku-20240307
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
cache_control: true
|
||||
|
||||
- name: anthropic/claude-3-5-haiku-20241022
|
||||
edit_format: diff
|
||||
weak_model_name: anthropic/claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
cache_control: true
|
||||
|
||||
- name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
edit_format: diff
|
||||
weak_model_name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0
|
||||
use_repo_map: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
cache_control: true
|
||||
|
||||
- name: claude-3-5-haiku-20241022
|
||||
edit_format: diff
|
||||
weak_model_name: claude-3-5-haiku-20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
cache_control: true
|
||||
|
||||
- name: vertex_ai/claude-3-5-haiku@20241022
|
||||
edit_format: diff
|
||||
weak_model_name: vertex_ai/claude-3-5-haiku@20241022
|
||||
use_repo_map: true
|
||||
extra_params:
|
||||
max_tokens: 4096
|
||||
|
||||
- name: claude-3-haiku-20240307
|
||||
weak_model_name: claude-3-haiku-20240307
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
extra_headers:
|
||||
anthropic-beta: prompt-caching-2024-07-31,pdfs-2024-09-25
|
||||
cache_control: true
|
||||
|
||||
- name: openrouter/anthropic/claude-3.5-sonnet
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/anthropic/claude-3-5-haiku
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: openrouter/anthropic/claude-3.5-sonnet
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/anthropic/claude-3.5-sonnet:beta
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/anthropic/claude-3-5-haiku:beta
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
cache_control: true
|
||||
editor_model_name: openrouter/anthropic/claude-3.5-sonnet:beta
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: vertex_ai/claude-3-5-sonnet@20240620
|
||||
edit_format: diff
|
||||
weak_model_name: vertex_ai/claude-3-5-haiku@20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
editor_model_name: vertex_ai/claude-3-5-sonnet@20240620
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: vertex_ai/claude-3-5-sonnet-v2@20241022
|
||||
edit_format: diff
|
||||
weak_model_name: vertex_ai/claude-3-5-haiku@20241022
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
editor_model_name: vertex_ai/claude-3-5-sonnet-v2@20241022
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: vertex_ai/claude-3-opus@20240229
|
||||
edit_format: diff
|
||||
weak_model_name: vertex_ai/claude-3-5-haiku@20241022
|
||||
use_repo_map: true
|
||||
|
||||
- name: vertex_ai/claude-3-sonnet@20240229
|
||||
weak_model_name: vertex_ai/claude-3-5-haiku@20241022
|
||||
|
||||
- name: command-r-plus
|
||||
weak_model_name: command-r-plus
|
||||
use_repo_map: true
|
||||
|
||||
- name: command-r-08-2024
|
||||
weak_model_name: command-r-08-2024
|
||||
use_repo_map: true
|
||||
|
||||
- name: command-r-plus-08-2024
|
||||
weak_model_name: command-r-plus-08-2024
|
||||
use_repo_map: true
|
||||
|
||||
- name: groq/llama3-70b-8192
|
||||
edit_format: diff
|
||||
weak_model_name: groq/llama3-8b-8192
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: openrouter/meta-llama/llama-3-70b-instruct
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/meta-llama/llama-3-70b-instruct
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: gemini/gemini-1.5-pro-002
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-1.5-flash-002
|
||||
|
||||
- name: gemini/gemini-1.5-pro
|
||||
edit_format: diff-fenced
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-1.5-pro-latest
|
||||
edit_format: diff-fenced
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-1.5-pro-exp-0827
|
||||
edit_format: diff-fenced
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-exp-1206
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-exp-1114
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-exp-1121
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
|
||||
- name: vertex_ai/gemini-pro-experimental
|
||||
edit_format: diff-fenced
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-1.5-flash-exp-0827
|
||||
|
||||
- name: gemini/gemini-2.0-flash-exp
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
|
||||
- name: gemini/gemini-2.0-flash
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
|
||||
- name: openrouter/deepseek/deepseek-r1
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/deepseek/deepseek-chat
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
include_reasoning: true
|
||||
caches_by_default: true
|
||||
editor_model_name: openrouter/deepseek/deepseek-chat
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/deepseek/deepseek-r1:free
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/deepseek/deepseek-r1:free
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
caches_by_default: true
|
||||
use_temperature: false
|
||||
editor_model_name: openrouter/deepseek/deepseek-r1:free
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: deepseek/deepseek-reasoner
|
||||
edit_format: diff
|
||||
weak_model_name: deepseek/deepseek-chat
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
caches_by_default: true
|
||||
use_temperature: false
|
||||
editor_model_name: deepseek/deepseek-chat
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: deepseek/deepseek-chat
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
caches_by_default: true
|
||||
|
||||
- name: openrouter/deepseek/deepseek-chat:free
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/deepseek/deepseek-chat:free
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
caches_by_default: true
|
||||
use_temperature: false
|
||||
editor_model_name: openrouter/deepseek/deepseek-chat:free
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: deepseek/deepseek-coder
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
caches_by_default: true
|
||||
|
||||
- name: deepseek-chat
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
|
||||
- name: deepseek-coder
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
caches_by_default: true
|
||||
|
||||
- name: openrouter/deepseek/deepseek-coder
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: openrouter/deepseek/deepseek-chat
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
|
||||
- name: openrouter/openai/gpt-4o
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openai/o1-mini
|
||||
weak_model_name: openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
editor_model_name: openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: azure/o1-mini
|
||||
weak_model_name: azure/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
editor_model_name: azure/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: o1-mini
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
editor_model_name: gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openai/o1-preview
|
||||
edit_format: diff
|
||||
weak_model_name: openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
editor_model_name: openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: azure/o1-preview
|
||||
edit_format: diff
|
||||
weak_model_name: azure/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
editor_model_name: azure/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: azure/o1
|
||||
edit_format: diff
|
||||
weak_model_name: azure/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
streaming: false
|
||||
editor_model_name: azure/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: o1-preview
|
||||
edit_format: architect
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
editor_model_name: gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/openai/o1-mini
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
streaming: false
|
||||
editor_model_name: openrouter/openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/openai/o1-preview
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_system_prompt: false
|
||||
use_temperature: false
|
||||
streaming: false
|
||||
editor_model_name: openrouter/openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/openai/o1
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
streaming: false
|
||||
editor_model_name: openrouter/openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: openai/o1
|
||||
edit_format: diff
|
||||
weak_model_name: openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
streaming: false
|
||||
editor_model_name: openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: o1
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
streaming: false
|
||||
editor_model_name: gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
use_repo_map: true
|
||||
editor_model_name: openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openrouter/deepseek/deepseek-r1-distill-llama-70b
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/deepseek/deepseek-chat
|
||||
use_repo_map: true
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 8192
|
||||
caches_by_default: true
|
||||
use_temperature: false
|
||||
editor_model_name: openrouter/deepseek/deepseek-chat
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: fireworks_ai/accounts/fireworks/models/deepseek-r1
|
||||
edit_format: diff
|
||||
weak_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
streaming: true
|
||||
editor_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3
|
||||
editor_edit_format: editor-diff
|
||||
reasoning_tag: think
|
||||
extra_params:
|
||||
max_tokens: 160000
|
||||
|
||||
- name: fireworks_ai/accounts/fireworks/models/deepseek-v3
|
||||
edit_format: diff
|
||||
use_repo_map: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
extra_params:
|
||||
max_tokens: 128000
|
||||
|
||||
- name: openai/o3-mini
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
editor_model_name: gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: o3-mini
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
editor_model_name: gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: openrouter/openai/o3-mini
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
editor_model_name: openrouter/openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: openrouter/openai/o3-mini-high
|
||||
edit_format: diff
|
||||
weak_model_name: openrouter/openai/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
editor_model_name: openrouter/openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: azure/o3-mini
|
||||
edit_format: diff
|
||||
weak_model_name: azure/gpt-4o-mini
|
||||
use_repo_map: true
|
||||
use_temperature: false
|
||||
editor_model_name: azure/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
system_prompt_prefix: "Formatting re-enabled. "
|
||||
|
||||
- name: gpt-4.5-preview
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
editor_model_name: gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: openai/gpt-4.5-preview
|
||||
edit_format: diff
|
||||
weak_model_name: gpt-4o-mini
|
||||
use_repo_map: true
|
||||
lazy: true
|
||||
reminder: sys
|
||||
examples_as_sys_msg: true
|
||||
editor_model_name: openai/gpt-4o
|
||||
editor_edit_format: editor-diff
|
||||
|
||||
- name: fireworks_ai/accounts/fireworks/models/qwq-32b
|
||||
reasoning_tag: think
|
||||
edit_format: diff
|
||||
weak_model_name: fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct
|
||||
use_repo_map: true
|
||||
editor_model_name: fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct
|
||||
editor_edit_format: editor-diff
|
||||
reminder: user
|
||||
examples_as_sys_msg: true
|
||||
use_temperature: 0.6
|
||||
extra_params:
|
||||
max_tokens: 32000
|
||||
top_p: 0.95
|
||||
|
||||
- name: groq/qwen-qwq-32b
|
||||
reasoning_tag: think
|
||||
edit_format: diff
|
||||
weak_model_name: groq/qwen-2.5-coder-32b
|
||||
use_repo_map: true
|
||||
editor_model_name: groq/qwen-2.5-coder-32b
|
||||
editor_edit_format: editor-diff
|
||||
use_temperature: 0.6
|
||||
extra_params:
|
||||
max_tokens: 128000
|
||||
top_p: 0.95
|
||||
|
||||
@@ -8,12 +8,12 @@ import pexpect
|
||||
import psutil
|
||||
|
||||
|
||||
def run_cmd(command, verbose=False, error_print=None):
|
||||
def run_cmd(command, verbose=False, error_print=None, cwd=None):
|
||||
try:
|
||||
if sys.stdin.isatty() and hasattr(pexpect, "spawn") and platform.system() != "Windows":
|
||||
return run_cmd_pexpect(command, verbose)
|
||||
return run_cmd_pexpect(command, verbose, cwd)
|
||||
|
||||
return run_cmd_subprocess(command, verbose)
|
||||
return run_cmd_subprocess(command, verbose, cwd)
|
||||
except OSError as e:
|
||||
error_message = f"Error occurred while running command '{command}': {str(e)}"
|
||||
if error_print is None:
|
||||
@@ -39,7 +39,7 @@ def get_windows_parent_process_name():
|
||||
return None
|
||||
|
||||
|
||||
def run_cmd_subprocess(command, verbose=False):
|
||||
def run_cmd_subprocess(command, verbose=False, cwd=None, encoding=sys.stdout.encoding):
|
||||
if verbose:
|
||||
print("Using run_cmd_subprocess:", command)
|
||||
|
||||
@@ -65,10 +65,11 @@ def run_cmd_subprocess(command, verbose=False):
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
shell=True,
|
||||
encoding=sys.stdout.encoding,
|
||||
encoding=encoding,
|
||||
errors="replace",
|
||||
bufsize=0, # Set bufsize to 0 for unbuffered output
|
||||
universal_newlines=True,
|
||||
cwd=cwd,
|
||||
)
|
||||
|
||||
output = []
|
||||
@@ -85,7 +86,7 @@ def run_cmd_subprocess(command, verbose=False):
|
||||
return 1, str(e)
|
||||
|
||||
|
||||
def run_cmd_pexpect(command, verbose=False):
|
||||
def run_cmd_pexpect(command, verbose=False, cwd=None):
|
||||
"""
|
||||
Run a shell command interactively using pexpect, capturing all output.
|
||||
|
||||
@@ -112,12 +113,12 @@ def run_cmd_pexpect(command, verbose=False):
|
||||
# Use the shell from SHELL environment variable
|
||||
if verbose:
|
||||
print("Running pexpect.spawn with shell:", shell)
|
||||
child = pexpect.spawn(shell, args=["-c", command], encoding="utf-8")
|
||||
child = pexpect.spawn(shell, args=["-i", "-c", command], encoding="utf-8", cwd=cwd)
|
||||
else:
|
||||
# Fall back to spawning the command directly
|
||||
if verbose:
|
||||
print("Running pexpect.spawn without shell.")
|
||||
child = pexpect.spawn(command, encoding="utf-8")
|
||||
child = pexpect.spawn(command, encoding="utf-8", cwd=cwd)
|
||||
|
||||
# Transfer control to the user, capturing output
|
||||
child.interact(output_filter=output_callback)
|
||||
|
||||
@@ -1,129 +1,61 @@
|
||||
import hashlib
|
||||
import json
|
||||
import time
|
||||
|
||||
import backoff
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
from aider.llm import litellm
|
||||
|
||||
# from diskcache import Cache
|
||||
from aider.utils import format_messages
|
||||
|
||||
|
||||
CACHE_PATH = "~/.aider.send.cache.v1"
|
||||
CACHE = None
|
||||
# CACHE = Cache(CACHE_PATH)
|
||||
def sanity_check_messages(messages):
|
||||
"""Check if messages alternate between user and assistant roles.
|
||||
System messages can be interspersed anywhere.
|
||||
Also verifies the last non-system message is from the user.
|
||||
Returns True if valid, False otherwise."""
|
||||
last_role = None
|
||||
last_non_system_role = None
|
||||
|
||||
RETRY_TIMEOUT = 60
|
||||
|
||||
|
||||
def retry_exceptions():
|
||||
import httpx
|
||||
import openai
|
||||
|
||||
return (
|
||||
# httpx
|
||||
httpx.ConnectError,
|
||||
httpx.RemoteProtocolError,
|
||||
httpx.ReadTimeout,
|
||||
#
|
||||
# litellm exceptions inherit from openai exceptions
|
||||
# https://docs.litellm.ai/docs/exception_mapping
|
||||
#
|
||||
# openai.BadRequestError,
|
||||
# litellm.ContextWindowExceededError,
|
||||
# litellm.ContentPolicyViolationError,
|
||||
#
|
||||
# openai.AuthenticationError,
|
||||
# openai.PermissionDeniedError,
|
||||
# openai.NotFoundError,
|
||||
#
|
||||
openai.APITimeoutError,
|
||||
openai.UnprocessableEntityError,
|
||||
openai.RateLimitError,
|
||||
openai.APIConnectionError,
|
||||
# openai.APIError,
|
||||
# openai.APIStatusError,
|
||||
openai.InternalServerError,
|
||||
)
|
||||
|
||||
|
||||
def lazy_litellm_retry_decorator(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
decorated_func = backoff.on_exception(
|
||||
backoff.expo,
|
||||
retry_exceptions(),
|
||||
max_time=RETRY_TIMEOUT,
|
||||
on_backoff=lambda details: print(
|
||||
f"{details.get('exception', 'Exception')}\nRetry in {details['wait']:.1f} seconds."
|
||||
),
|
||||
)(func)
|
||||
return decorated_func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def send_completion(
|
||||
model_name,
|
||||
messages,
|
||||
functions,
|
||||
stream,
|
||||
temperature=0,
|
||||
extra_params=None,
|
||||
):
|
||||
kwargs = dict(
|
||||
model=model_name,
|
||||
messages=messages,
|
||||
stream=stream,
|
||||
)
|
||||
if temperature is not None:
|
||||
kwargs["temperature"] = temperature
|
||||
|
||||
if functions is not None:
|
||||
function = functions[0]
|
||||
kwargs["tools"] = [dict(type="function", function=function)]
|
||||
kwargs["tool_choice"] = {"type": "function", "function": {"name": function["name"]}}
|
||||
|
||||
if extra_params is not None:
|
||||
kwargs.update(extra_params)
|
||||
|
||||
key = json.dumps(kwargs, sort_keys=True).encode()
|
||||
|
||||
# Generate SHA1 hash of kwargs and append it to chat_completion_call_hashes
|
||||
hash_object = hashlib.sha1(key)
|
||||
|
||||
if not stream and CACHE is not None and key in CACHE:
|
||||
return hash_object, CACHE[key]
|
||||
|
||||
res = litellm.completion(**kwargs)
|
||||
|
||||
if not stream and CACHE is not None:
|
||||
CACHE[key] = res
|
||||
|
||||
return hash_object, res
|
||||
|
||||
|
||||
def simple_send_with_retries(model_name, messages, extra_params=None):
|
||||
retry_delay = 0.125
|
||||
while True:
|
||||
try:
|
||||
kwargs = {
|
||||
"model_name": model_name,
|
||||
"messages": messages,
|
||||
"functions": None,
|
||||
"stream": False,
|
||||
"extra_params": extra_params,
|
||||
}
|
||||
|
||||
_hash, response = send_completion(**kwargs)
|
||||
return response.choices[0].message.content
|
||||
except retry_exceptions() as err:
|
||||
print(str(err))
|
||||
retry_delay *= 2
|
||||
if retry_delay > RETRY_TIMEOUT:
|
||||
break
|
||||
print(f"Retrying in {retry_delay:.1f} seconds...")
|
||||
time.sleep(retry_delay)
|
||||
for msg in messages:
|
||||
role = msg.get("role")
|
||||
if role == "system":
|
||||
continue
|
||||
except AttributeError:
|
||||
return
|
||||
|
||||
if last_role and role == last_role:
|
||||
turns = format_messages(messages)
|
||||
raise ValueError("Messages don't properly alternate user/assistant:\n\n" + turns)
|
||||
|
||||
last_role = role
|
||||
last_non_system_role = role
|
||||
|
||||
# Ensure last non-system message is from user
|
||||
return last_non_system_role == "user"
|
||||
|
||||
|
||||
def ensure_alternating_roles(messages):
|
||||
"""Ensure messages alternate between 'assistant' and 'user' roles.
|
||||
|
||||
Inserts empty messages of the opposite role when consecutive messages
|
||||
of the same role are found.
|
||||
|
||||
Args:
|
||||
messages: List of message dictionaries with 'role' and 'content' keys.
|
||||
|
||||
Returns:
|
||||
List of messages with alternating roles.
|
||||
"""
|
||||
if not messages:
|
||||
return messages
|
||||
|
||||
fixed_messages = []
|
||||
prev_role = None
|
||||
|
||||
for msg in messages:
|
||||
current_role = msg.get("role") # Get 'role', None if missing
|
||||
|
||||
# If current role same as previous, insert empty message
|
||||
# of the opposite role
|
||||
if current_role == prev_role:
|
||||
if current_role == "user":
|
||||
fixed_messages.append({"role": "assistant", "content": ""})
|
||||
else:
|
||||
fixed_messages.append({"role": "user", "content": ""})
|
||||
|
||||
fixed_messages.append(msg)
|
||||
prev_role = current_role
|
||||
|
||||
return fixed_messages
|
||||
|
||||
@@ -41,6 +41,7 @@ ROOT_IMPORTANT_FILES = [
|
||||
"composer.lock",
|
||||
"pom.xml",
|
||||
"build.gradle",
|
||||
"build.gradle.kts",
|
||||
"build.sbt",
|
||||
"go.mod",
|
||||
"go.sum",
|
||||
|
||||
@@ -12,3 +12,6 @@ github_issues = "https://github.com/Aider-AI/aider/issues/new"
|
||||
git_index_version = "https://github.com/Aider-AI/aider/issues/211"
|
||||
install_properly = "https://aider.chat/docs/troubleshooting/imports.html"
|
||||
analytics = "https://aider.chat/docs/more/analytics.html"
|
||||
release_notes = "https://aider.chat/HISTORY.html#release-notes"
|
||||
edit_formats = "https://aider.chat/docs/more/edit-formats.html"
|
||||
models_and_keys = "https://aider.chat/docs/troubleshooting/models-and-keys.html"
|
||||
|
||||
@@ -2,18 +2,15 @@ import itertools
|
||||
import os
|
||||
import platform
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import git
|
||||
|
||||
from aider.dump import dump # noqa: F401
|
||||
|
||||
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp"}
|
||||
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".webp", ".pdf"}
|
||||
|
||||
|
||||
class IgnorantTemporaryDirectory:
|
||||
@@ -74,6 +71,8 @@ class GitTemporaryDirectory(ChdirTemporaryDirectory):
|
||||
|
||||
|
||||
def make_repo(path=None):
|
||||
import git
|
||||
|
||||
if not path:
|
||||
path = "."
|
||||
repo = git.Repo.init(path)
|
||||
@@ -113,7 +112,7 @@ def format_messages(messages, title=None):
|
||||
output.append(f"{title.upper()} {'*' * 50}")
|
||||
|
||||
for msg in messages:
|
||||
output.append("")
|
||||
output.append("-------")
|
||||
role = msg["role"].upper()
|
||||
content = msg.get("content")
|
||||
if isinstance(content, list): # Handle list content (e.g., image messages)
|
||||
@@ -194,25 +193,9 @@ def split_chat_history_markdown(text, include_tool=False):
|
||||
return messages
|
||||
|
||||
|
||||
# Copied from pip, MIT license
|
||||
# https://github.com/pypa/pip/blob/b989e6ef04810bbd4033a3683020bd4ddcbdb627/src/pip/_internal/utils/entrypoints.py#L73
|
||||
def get_best_invocation_for_this_python() -> str:
|
||||
"""Try to figure out the best way to invoke the current Python."""
|
||||
exe = sys.executable
|
||||
exe_name = os.path.basename(exe)
|
||||
|
||||
# Try to use the basename, if it's the first executable.
|
||||
found_executable = shutil.which(exe_name)
|
||||
if found_executable and os.path.samefile(found_executable, exe):
|
||||
return exe_name
|
||||
|
||||
# Use the full executable name, because we couldn't find something simpler.
|
||||
return exe
|
||||
|
||||
|
||||
def get_pip_install(args):
|
||||
cmd = [
|
||||
get_best_invocation_for_this_python(),
|
||||
sys.executable,
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
@@ -268,7 +251,8 @@ def run_install(cmd):
|
||||
|
||||
|
||||
class Spinner:
|
||||
spinner_chars = itertools.cycle(["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
|
||||
unicode_spinner = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
||||
ascii_spinner = ["|", "/", "-", "\\"]
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
@@ -276,6 +260,20 @@ class Spinner:
|
||||
self.last_update = 0
|
||||
self.visible = False
|
||||
self.is_tty = sys.stdout.isatty()
|
||||
self.tested = False
|
||||
|
||||
def test_charset(self):
|
||||
if self.tested:
|
||||
return
|
||||
self.tested = True
|
||||
# Try unicode first, fall back to ascii if needed
|
||||
try:
|
||||
# Test if we can print unicode characters
|
||||
print(self.unicode_spinner[0], end="", flush=True)
|
||||
print("\r", end="", flush=True)
|
||||
self.spinner_chars = itertools.cycle(self.unicode_spinner)
|
||||
except UnicodeEncodeError:
|
||||
self.spinner_chars = itertools.cycle(self.ascii_spinner)
|
||||
|
||||
def step(self):
|
||||
if not self.is_tty:
|
||||
@@ -293,6 +291,7 @@ class Spinner:
|
||||
if not self.visible:
|
||||
return
|
||||
|
||||
self.test_charset()
|
||||
print(f"\r{self.text} {next(self.spinner_chars)}\r{self.text} ", end="", flush=True)
|
||||
|
||||
def end(self):
|
||||
@@ -301,12 +300,15 @@ class Spinner:
|
||||
|
||||
|
||||
def find_common_root(abs_fnames):
|
||||
if len(abs_fnames) == 1:
|
||||
return safe_abs_path(os.path.dirname(list(abs_fnames)[0]))
|
||||
elif abs_fnames:
|
||||
return safe_abs_path(os.path.commonpath(list(abs_fnames)))
|
||||
else:
|
||||
return safe_abs_path(os.getcwd())
|
||||
try:
|
||||
if len(abs_fnames) == 1:
|
||||
return safe_abs_path(os.path.dirname(list(abs_fnames)[0]))
|
||||
elif abs_fnames:
|
||||
return safe_abs_path(os.path.commonpath(list(abs_fnames)))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
return safe_abs_path(os.getcwd())
|
||||
|
||||
|
||||
def format_tokens(count):
|
||||
@@ -382,3 +384,15 @@ def printable_shell_command(cmd_list):
|
||||
return subprocess.list2cmdline(cmd_list)
|
||||
else:
|
||||
return shlex.join(cmd_list)
|
||||
|
||||
|
||||
def main():
|
||||
spinner = Spinner("Running spinner...")
|
||||
for _ in range(40): # 40 steps * 0.25 seconds = 10 seconds
|
||||
time.sleep(0.25)
|
||||
spinner.step()
|
||||
spinner.end()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -14,8 +14,11 @@ from .dump import dump # noqa: F401
|
||||
warnings.filterwarnings(
|
||||
"ignore", message="Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work"
|
||||
)
|
||||
warnings.filterwarnings("ignore", category=SyntaxWarning)
|
||||
|
||||
|
||||
from pydub import AudioSegment # noqa
|
||||
from pydub.exceptions import CouldntDecodeError, CouldntEncodeError # noqa
|
||||
|
||||
try:
|
||||
import soundfile as sf
|
||||
@@ -34,7 +37,7 @@ class Voice:
|
||||
|
||||
threshold = 0.15
|
||||
|
||||
def __init__(self, audio_format="wav"):
|
||||
def __init__(self, audio_format="wav", device_name=None):
|
||||
if sf is None:
|
||||
raise SoundDeviceError
|
||||
try:
|
||||
@@ -42,6 +45,29 @@ class Voice:
|
||||
import sounddevice as sd
|
||||
|
||||
self.sd = sd
|
||||
|
||||
devices = sd.query_devices()
|
||||
|
||||
if device_name:
|
||||
# Find the device with matching name
|
||||
device_id = None
|
||||
for i, device in enumerate(devices):
|
||||
if device_name in device["name"]:
|
||||
device_id = i
|
||||
break
|
||||
if device_id is None:
|
||||
available_inputs = [d["name"] for d in devices if d["max_input_channels"] > 0]
|
||||
raise ValueError(
|
||||
f"Device '{device_name}' not found. Available input devices:"
|
||||
f" {available_inputs}"
|
||||
)
|
||||
|
||||
print(f"Using input device: {device_name} (ID: {device_id})")
|
||||
|
||||
self.device_id = device_id
|
||||
else:
|
||||
self.device_id = None
|
||||
|
||||
except (OSError, ModuleNotFoundError):
|
||||
raise SoundDeviceError
|
||||
if audio_format not in ["wav", "mp3", "webm"]:
|
||||
@@ -93,7 +119,7 @@ class Voice:
|
||||
temp_wav = tempfile.mktemp(suffix=".wav")
|
||||
|
||||
try:
|
||||
sample_rate = int(self.sd.query_devices(None, "input")["default_samplerate"])
|
||||
sample_rate = int(self.sd.query_devices(self.device_id, "input")["default_samplerate"])
|
||||
except (TypeError, ValueError):
|
||||
sample_rate = 16000 # fallback to 16kHz if unable to query device
|
||||
except self.sd.PortAudioError:
|
||||
@@ -104,7 +130,9 @@ class Voice:
|
||||
self.start_time = time.time()
|
||||
|
||||
try:
|
||||
with self.sd.InputStream(samplerate=sample_rate, channels=1, callback=self.callback):
|
||||
with self.sd.InputStream(
|
||||
samplerate=sample_rate, channels=1, callback=self.callback, device=self.device_id
|
||||
):
|
||||
prompt(self.get_prompt, refresh_interval=0.1)
|
||||
except self.sd.PortAudioError as err:
|
||||
raise SoundDeviceError(f"Error accessing audio input device: {err}")
|
||||
@@ -113,13 +141,28 @@ class Voice:
|
||||
while not self.q.empty():
|
||||
file.write(self.q.get())
|
||||
|
||||
if self.audio_format != "wav":
|
||||
filename = tempfile.mktemp(suffix=f".{self.audio_format}")
|
||||
audio = AudioSegment.from_wav(temp_wav)
|
||||
audio.export(filename, format=self.audio_format)
|
||||
os.remove(temp_wav)
|
||||
else:
|
||||
filename = temp_wav
|
||||
use_audio_format = self.audio_format
|
||||
|
||||
# Check file size and offer to convert to mp3 if too large
|
||||
file_size = os.path.getsize(temp_wav)
|
||||
if file_size > 24.9 * 1024 * 1024 and self.audio_format == "wav":
|
||||
print("\nWarning: {temp_wav} is too large, switching to mp3 format.")
|
||||
use_audio_format = "mp3"
|
||||
|
||||
filename = temp_wav
|
||||
if use_audio_format != "wav":
|
||||
try:
|
||||
new_filename = tempfile.mktemp(suffix=f".{use_audio_format}")
|
||||
audio = AudioSegment.from_wav(temp_wav)
|
||||
audio.export(new_filename, format=use_audio_format)
|
||||
os.remove(temp_wav)
|
||||
filename = new_filename
|
||||
except (CouldntDecodeError, CouldntEncodeError) as e:
|
||||
print(f"Error converting audio: {e}")
|
||||
except (OSError, FileNotFoundError) as e:
|
||||
print(f"File system error during conversion: {e}")
|
||||
except Exception as e:
|
||||
print(f"Unexpected error during audio conversion: {e}")
|
||||
|
||||
with open(filename, "rb") as fh:
|
||||
try:
|
||||
@@ -130,7 +173,7 @@ class Voice:
|
||||
print(f"Unable to transcribe {filename}: {err}")
|
||||
return
|
||||
|
||||
if self.audio_format != "wav":
|
||||
if filename != temp_wav:
|
||||
os.remove(filename)
|
||||
|
||||
text = transcript.text
|
||||
|
||||
310
aider/watch.py
Normal file
310
aider/watch.py
Normal file
@@ -0,0 +1,310 @@
|
||||
import re
|
||||
import threading
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from grep_ast import TreeContext
|
||||
from pathspec import PathSpec
|
||||
from pathspec.patterns import GitWildMatchPattern
|
||||
from watchfiles import watch
|
||||
|
||||
from aider.dump import dump # noqa
|
||||
from aider.watch_prompts import watch_ask_prompt, watch_code_prompt
|
||||
|
||||
|
||||
def load_gitignores(gitignore_paths: list[Path]) -> Optional[PathSpec]:
|
||||
"""Load and parse multiple .gitignore files into a single PathSpec"""
|
||||
if not gitignore_paths:
|
||||
return None
|
||||
|
||||
patterns = [
|
||||
".aider*",
|
||||
".git",
|
||||
# Common editor backup/temp files
|
||||
"*~", # Emacs/vim backup
|
||||
"*.bak", # Generic backup
|
||||
"*.swp", # Vim swap
|
||||
"*.swo", # Vim swap
|
||||
"\\#*\\#", # Emacs auto-save
|
||||
".#*", # Emacs lock files
|
||||
"*.tmp", # Generic temp files
|
||||
"*.temp", # Generic temp files
|
||||
"*.orig", # Merge conflict originals
|
||||
"*.pyc", # Python bytecode
|
||||
"__pycache__/", # Python cache dir
|
||||
".DS_Store", # macOS metadata
|
||||
"Thumbs.db", # Windows thumbnail cache
|
||||
# IDE files
|
||||
".idea/", # JetBrains IDEs
|
||||
".vscode/", # VS Code
|
||||
"*.sublime-*", # Sublime Text
|
||||
".project", # Eclipse
|
||||
".settings/", # Eclipse
|
||||
"*.code-workspace", # VS Code workspace
|
||||
# Environment files
|
||||
".env", # Environment variables
|
||||
".venv/", # Python virtual environments
|
||||
"node_modules/", # Node.js dependencies
|
||||
"vendor/", # Various dependencies
|
||||
# Logs and caches
|
||||
"*.log", # Log files
|
||||
".cache/", # Cache directories
|
||||
".pytest_cache/", # Python test cache
|
||||
"coverage/", # Code coverage reports
|
||||
] # Always ignore
|
||||
for path in gitignore_paths:
|
||||
if path.exists():
|
||||
with open(path) as f:
|
||||
patterns.extend(f.readlines())
|
||||
|
||||
return PathSpec.from_lines(GitWildMatchPattern, patterns) if patterns else None
|
||||
|
||||
|
||||
class FileWatcher:
|
||||
"""Watches source files for changes and AI comments"""
|
||||
|
||||
# Compiled regex pattern for AI comments
|
||||
ai_comment_pattern = re.compile(r"(?:#|//|--) *(ai\b.*|ai\b.*|.*\bai[?!]?) *$", re.IGNORECASE)
|
||||
|
||||
def __init__(self, coder, gitignores=None, verbose=False, analytics=None, root=None):
|
||||
self.coder = coder
|
||||
self.io = coder.io
|
||||
self.root = Path(root) if root else Path(coder.root)
|
||||
self.verbose = verbose
|
||||
self.analytics = analytics
|
||||
self.stop_event = None
|
||||
self.watcher_thread = None
|
||||
self.changed_files = set()
|
||||
self.gitignores = gitignores
|
||||
|
||||
self.gitignore_spec = load_gitignores(
|
||||
[Path(g) for g in self.gitignores] if self.gitignores else []
|
||||
)
|
||||
|
||||
coder.io.file_watcher = self
|
||||
|
||||
def filter_func(self, change_type, path):
|
||||
"""Filter function for the file watcher"""
|
||||
path_obj = Path(path)
|
||||
path_abs = path_obj.absolute()
|
||||
|
||||
if not path_abs.is_relative_to(self.root.absolute()):
|
||||
return False
|
||||
|
||||
rel_path = path_abs.relative_to(self.root)
|
||||
if self.verbose:
|
||||
dump(rel_path)
|
||||
|
||||
if self.gitignore_spec and self.gitignore_spec.match_file(
|
||||
rel_path.as_posix() + ("/" if path_abs.is_dir() else "")
|
||||
):
|
||||
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 get_roots_to_watch(self):
|
||||
"""Determine which root paths to watch based on gitignore rules"""
|
||||
if self.gitignore_spec:
|
||||
roots = [
|
||||
str(path)
|
||||
for path in self.root.iterdir()
|
||||
if not self.gitignore_spec.match_file(
|
||||
path.relative_to(self.root).as_posix() + ("/" if path.is_dir() else "")
|
||||
)
|
||||
]
|
||||
# Fallback to watching root if all top-level items are filtered out
|
||||
return roots if roots else [str(self.root)]
|
||||
return [str(self.root)]
|
||||
|
||||
def handle_changes(self, changes):
|
||||
"""Process the detected changes and update state"""
|
||||
if not changes:
|
||||
return False
|
||||
|
||||
changed_files = {str(Path(change[1])) for change in changes}
|
||||
self.changed_files.update(changed_files)
|
||||
self.io.interrupt_input()
|
||||
return True
|
||||
|
||||
def watch_files(self):
|
||||
"""Watch for file changes and process them"""
|
||||
try:
|
||||
roots_to_watch = self.get_roots_to_watch()
|
||||
|
||||
for changes in watch(
|
||||
*roots_to_watch,
|
||||
watch_filter=self.filter_func,
|
||||
stop_event=self.stop_event,
|
||||
ignore_permission_denied=True,
|
||||
):
|
||||
if self.handle_changes(changes):
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
if self.verbose:
|
||||
dump(f"File watcher error: {e}")
|
||||
raise e
|
||||
|
||||
def start(self):
|
||||
"""Start watching for file changes"""
|
||||
self.stop_event = threading.Event()
|
||||
self.changed_files = set()
|
||||
|
||||
self.watcher_thread = threading.Thread(target=self.watch_files, daemon=True)
|
||||
self.watcher_thread.start()
|
||||
|
||||
def stop(self):
|
||||
"""Stop watching for file changes"""
|
||||
if self.stop_event:
|
||||
self.stop_event.set()
|
||||
if self.watcher_thread:
|
||||
self.watcher_thread.join()
|
||||
self.watcher_thread = None
|
||||
self.stop_event = None
|
||||
|
||||
def process_changes(self):
|
||||
"""Get any detected file changes"""
|
||||
|
||||
has_action = None
|
||||
added = False
|
||||
for fname in self.changed_files:
|
||||
_, _, action = self.get_ai_comments(fname)
|
||||
if action in ("!", "?"):
|
||||
has_action = action
|
||||
|
||||
if fname in self.coder.abs_fnames:
|
||||
continue
|
||||
if self.analytics:
|
||||
self.analytics.event("ai-comments file-add")
|
||||
self.coder.abs_fnames.add(fname)
|
||||
rel_fname = self.coder.get_rel_fname(fname)
|
||||
if not added:
|
||||
self.io.tool_output()
|
||||
added = True
|
||||
self.io.tool_output(f"Added {rel_fname} to the chat")
|
||||
|
||||
if not has_action:
|
||||
if added:
|
||||
self.io.tool_output(
|
||||
"End your comment with AI! to request changes or AI? to ask questions"
|
||||
)
|
||||
return ""
|
||||
|
||||
if self.analytics:
|
||||
self.analytics.event("ai-comments execute")
|
||||
self.io.tool_output("Processing your request...")
|
||||
|
||||
if has_action == "!":
|
||||
res = watch_code_prompt
|
||||
elif has_action == "?":
|
||||
res = watch_ask_prompt
|
||||
|
||||
# Refresh all AI comments from tracked files
|
||||
for fname in self.coder.abs_fnames:
|
||||
line_nums, comments, _action = self.get_ai_comments(fname)
|
||||
if not line_nums:
|
||||
continue
|
||||
|
||||
code = self.io.read_text(fname)
|
||||
if not code:
|
||||
continue
|
||||
|
||||
rel_fname = self.coder.get_rel_fname(fname)
|
||||
res += f"\n{rel_fname}:\n"
|
||||
|
||||
# Convert comment line numbers to line indices (0-based)
|
||||
lois = [ln - 1 for ln, _ in zip(line_nums, comments) if ln > 0]
|
||||
|
||||
try:
|
||||
context = TreeContext(
|
||||
rel_fname,
|
||||
code,
|
||||
color=False,
|
||||
line_number=False,
|
||||
child_context=False,
|
||||
last_line=False,
|
||||
margin=0,
|
||||
mark_lois=True,
|
||||
loi_pad=3,
|
||||
show_top_of_file_parent_scope=False,
|
||||
)
|
||||
context.lines_of_interest = set()
|
||||
context.add_lines_of_interest(lois)
|
||||
context.add_context()
|
||||
res += context.format()
|
||||
except ValueError:
|
||||
for ln, comment in zip(line_nums, comments):
|
||||
res += f" Line {ln}: {comment}\n"
|
||||
|
||||
return res
|
||||
|
||||
def get_ai_comments(self, filepath):
|
||||
"""Extract AI comment line numbers, comments and action status from a file"""
|
||||
line_nums = []
|
||||
comments = []
|
||||
has_action = None # None, "!" or "?"
|
||||
content = self.io.read_text(filepath, silent=True)
|
||||
if not content:
|
||||
return None, None, None
|
||||
|
||||
for i, line in enumerate(content.splitlines(), 1):
|
||||
if match := self.ai_comment_pattern.search(line):
|
||||
comment = match.group(0).strip()
|
||||
if comment:
|
||||
line_nums.append(i)
|
||||
comments.append(comment)
|
||||
comment = comment.lower()
|
||||
comment = comment.lstrip("/#-")
|
||||
comment = comment.strip()
|
||||
if comment.startswith("ai!") or comment.endswith("ai!"):
|
||||
has_action = "!"
|
||||
elif comment.startswith("ai?") or comment.endswith("ai?"):
|
||||
has_action = "?"
|
||||
if not line_nums:
|
||||
return None, None, None
|
||||
return line_nums, comments, has_action
|
||||
|
||||
|
||||
def main():
|
||||
"""Example usage of the file watcher"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Watch source files for changes")
|
||||
parser.add_argument("directory", help="Directory to watch")
|
||||
parser.add_argument(
|
||||
"--gitignore",
|
||||
action="append",
|
||||
help="Path to .gitignore file (can be specified multiple times)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
directory = args.directory
|
||||
print(f"Watching source files in {directory}...")
|
||||
|
||||
# Example ignore function that ignores files with "test" in the name
|
||||
def ignore_test_files(path):
|
||||
return "test" in path.name.lower()
|
||||
|
||||
watcher = FileWatcher(directory, gitignores=args.gitignore)
|
||||
try:
|
||||
watcher.start()
|
||||
while True:
|
||||
if changes := watcher.get_changes():
|
||||
for file in sorted(changes.keys()):
|
||||
print(file)
|
||||
watcher.changed_files = None
|
||||
except KeyboardInterrupt:
|
||||
print("\nStopped watching files")
|
||||
watcher.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
12
aider/watch_prompts.py
Normal file
12
aider/watch_prompts.py
Normal file
@@ -0,0 +1,12 @@
|
||||
watch_code_prompt = """
|
||||
I've written your instructions in comments in the code and marked them with "ai"
|
||||
You can see the "AI" comments shown below (marked with █).
|
||||
Find them in the code files I've shared with you, and follow their instructions.
|
||||
|
||||
After completing those instructions, also be sure to remove all the "AI" comments from the code too.
|
||||
"""
|
||||
|
||||
watch_ask_prompt = """/ask
|
||||
Find the "AI" comments below (marked with █) in the code files I've shared with you.
|
||||
They contain my questions that I need you to answer and other instructions for you.
|
||||
"""
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Release history
|
||||
parent: More info
|
||||
nav_order: 900
|
||||
nav_order: 925
|
||||
highlight_image: /assets/blame.jpg
|
||||
description: Release notes and stats on aider writing its own code.
|
||||
---
|
||||
@@ -10,6 +9,12 @@ description: Release notes and stats on aider writing its own code.
|
||||
|
||||
{% include blame.md %}
|
||||
|
||||
The above
|
||||
[stats are based on the git commit history](/docs/faq.html#how-are-the-aider-wrote-xx-of-code-stats-computed)
|
||||
of the aider repo.
|
||||
|
||||
## Release notes
|
||||
|
||||
<!--[[[cog
|
||||
# This page is a copy of HISTORY.md, adding the front matter above.
|
||||
text = open("HISTORY.md").read()
|
||||
@@ -18,6 +23,309 @@ cog.out(text)
|
||||
]]]-->
|
||||
|
||||
|
||||
### Aider v0.76.1
|
||||
|
||||
- Added ignore_permission_denied option to file watcher to prevent errors when accessing restricted files, by Yutaka Matsubara.
|
||||
- Aider wrote 0% of the code in this release.
|
||||
|
||||
### Aider v0.76.0
|
||||
|
||||
- Improved support for thinking/reasoningmodels:
|
||||
- Added `--thinking-tokens` CLI option to control token budget for models that support thinking.
|
||||
- Display thinking/reasoning content from LLMs which return it.
|
||||
- Enhanced handling of reasoning tags to better clean up model responses.
|
||||
- Added deprecation warning for `remove_reasoning` setting, now replaced by `reasoning_tag`.
|
||||
- Aider will notify you when it's completed the last request and needs your input:
|
||||
- Added [notifications when LLM responses are ready](https://aider.chat/docs/usage/notifications.html) with `--notifications` flag.
|
||||
- Specify desktop notification command with `--notifications-command`.
|
||||
- Added support for QWQ 32B.
|
||||
- Switch to `tree-sitter-language-pack` for tree sitter support.
|
||||
- Improved error handling for EOF (Ctrl+D) in user input prompts.
|
||||
- Added helper function to ensure hex color values have a # prefix.
|
||||
- Fixed handling of Git errors when reading staged files.
|
||||
- Improved SSL verification control for model information requests.
|
||||
- Improved empty LLM response handling with clearer warning messages.
|
||||
- Fixed Git identity retrieval to respect global configuration, by Akira Komamura.
|
||||
- Offer to install dependencies for Bedrock and Vertex AI models.
|
||||
- Deprecated model shortcut args (like --4o, --opus) in favor of the --model flag.
|
||||
- Aider wrote 85% of the code in this release.
|
||||
|
||||
### Aider v0.75.3
|
||||
|
||||
- Support for V3 free on OpenRouter: `--model openrouter/deepseek/deepseek-chat:free`.
|
||||
|
||||
### Aider v0.75.2
|
||||
|
||||
- Added support for Claude 3.7 Sonnet models on OpenRouter, Bedrock and Vertex AI.
|
||||
- Updated default model to Claude 3.7 Sonnet on OpenRouter.
|
||||
- Added support for GPT-4.5-preview model.
|
||||
- Added support for Claude 3.7 Sonnet:beta on OpenRouter.
|
||||
- Fixed weak_model_name patterns to match main model name patterns for some models.
|
||||
|
||||
### Aider v0.75.1
|
||||
|
||||
- Added support for `openrouter/anthropic/claude-3.7-sonnet`
|
||||
|
||||
### Aider v0.75.0
|
||||
|
||||
- Basic support for Claude 3.7 Sonnet
|
||||
- Use `--model sonnet` to use the new 3.7
|
||||
- Thinking support coming soon.
|
||||
- Bugfix to `/editor` command.
|
||||
- Aider wrote 46% of the code in this release.
|
||||
|
||||
### Aider v0.74.3
|
||||
|
||||
- Downgrade streamlit dependency to avoid threading bug.
|
||||
- Added support for tree-sitter language pack.
|
||||
- Added openrouter/o3-mini-high model configuration.
|
||||
- Added build.gradle.kts to special files for Kotlin project support, by Lucas Shadler.
|
||||
|
||||
### Aider v0.74.2
|
||||
|
||||
- Prevent more than one cache warming thread from becoming active.
|
||||
- Fixed continuation prompt ". " for multiline input.
|
||||
- Added HCL (Terraform) syntax support, by Warren Krewenki.
|
||||
|
||||
### Aider v0.74.1
|
||||
|
||||
- Have o1 & o3-mini generate markdown by sending the magic "Formatting re-enabled." string.
|
||||
- Bugfix for multi-line inputs, which should not include the ". " continuation prompt.
|
||||
|
||||
### Aider v0.74.0
|
||||
|
||||
- Dynamically changes the Ollama context window to hold the current chat.
|
||||
- Better support for o3-mini, DeepSeek V3 & R1, o1-mini, o1 especially via third-party API providers.
|
||||
- Remove `<think>` tags from R1 responses for commit messages (and other weak model uses).
|
||||
- Can now specify `use_temperature: <float>` in model settings, not just true/false.
|
||||
- The full docker container now includes `boto3` for Bedrock.
|
||||
- Docker containers now set `HOME=/app` which is the normal project mount-point, to persist `~/.aider`.
|
||||
- Bugfix to prevent creating incorrect filenames like `python`, `php`, etc.
|
||||
- Bugfix for `--timeout`
|
||||
- Bugfix so that `/model` now correctly reports that the weak model is not changed.
|
||||
- Bugfix so that multi-line mode persists through ^C at confirmation prompts.
|
||||
- Watch files now fully ignores top-level directories named in ignore files, to reduce the chance of hitting OS watch limits. Helpful to ignore giant subtrees like `node_modules`.
|
||||
- Fast startup with more providers and when model metadata provided in local files.
|
||||
- Improved .gitignore handling:
|
||||
- Honor ignores already in effect regardless of how they've been configured.
|
||||
- Check for .env only when the file exists.
|
||||
- Yes/No prompts now accept All/Skip as alias for Y/N even when not processing a group of confirmations.
|
||||
- Aider wrote 77% of the code in this release.
|
||||
|
||||
### Aider v0.73.0
|
||||
|
||||
- Full support for o3-mini: `aider --model o3-mini`
|
||||
- New `--reasoning-effort` argument: low, medium, high.
|
||||
- Improved handling of context window size limits, with better messaging and Ollama-specific guidance.
|
||||
- Added support for removing model-specific reasoning tags from responses with `remove_reasoning: tagname` model setting.
|
||||
- Auto-create parent directories when creating new files, by xqyz.
|
||||
- Support for R1 free on OpenRouter: `--model openrouter/deepseek/deepseek-r1:free`
|
||||
- Aider wrote 69% of the code in this release.
|
||||
|
||||
### Aider v0.72.3
|
||||
|
||||
- Enforce user/assistant turn order to avoid R1 errors, by miradnanali.
|
||||
- Case-insensitive model name matching while preserving original case.
|
||||
|
||||
### Aider v0.72.2
|
||||
- Harden against user/assistant turn order problems which cause R1 errors.
|
||||
|
||||
### Aider v0.72.1
|
||||
- Fix model metadata for `openrouter/deepseek/deepseek-r1`
|
||||
|
||||
### Aider v0.72.0
|
||||
- Support for DeepSeek R1.
|
||||
- Use shortcut: `--model r1`
|
||||
- Also via OpenRouter: `--model openrouter/deepseek/deepseek-r1`
|
||||
- Added Kotlin syntax support to repo map, by Paul Walker.
|
||||
- Added `--line-endings` for file writing, by Titusz Pan.
|
||||
- Added examples_as_sys_msg=True for GPT-4o models, improves benchmark scores.
|
||||
- Bumped all dependencies, to pick up litellm support for o1 system messages.
|
||||
- Bugfix for turn taking when reflecting lint/test errors.
|
||||
- Aider wrote 52% of the code in this release.
|
||||
|
||||
### Aider v0.71.1
|
||||
|
||||
- Fix permissions issue in Docker images.
|
||||
- Added read-only file announcements.
|
||||
- Bugfix: ASCII fallback for unicode errors.
|
||||
- Bugfix: integer indices for list slicing in repomap calculations.
|
||||
|
||||
### Aider v0.71.0
|
||||
|
||||
- Prompts to help DeepSeek work better when alternating between `/ask` and `/code`.
|
||||
- Streaming pretty LLM responses is smoother and faster for long replies.
|
||||
- Streaming automatically turns of for model that don't support it
|
||||
- Can now switch to/from `/model o1` and a streaming model
|
||||
- Pretty output remains enabled even when editing files with triple-backtick fences
|
||||
- Bare `/ask`, `/code` and `/architect` commands now switch the chat mode.
|
||||
- Increased default size of the repomap.
|
||||
- Increased max chat history tokens limit from 4k to 8k.
|
||||
- Turn off fancy input and watch files if terminal is dumb.
|
||||
- Added support for custom voice format and input device settings.
|
||||
- Disabled Streamlit email prompt, by apaz-cli.
|
||||
- Docker container runs as non-root user.
|
||||
- Fixed lint command handling of nested spaced strings, by Aaron Weisberg.
|
||||
- Added token count feedback when adding command output to chat.
|
||||
- Improved error handling for large audio files with automatic format conversion.
|
||||
- Improved handling of git repo index errors, by Krazer.
|
||||
- Improved unicode handling in console output with ASCII fallback.
|
||||
- Added AssertionError, AttributeError to git error handling.
|
||||
- Aider wrote 60% of the code in this release.
|
||||
|
||||
### Aider v0.70.0
|
||||
|
||||
- Full support for o1 models.
|
||||
- Watch files now honors `--subtree-only`, and only watches that subtree.
|
||||
- Improved prompting for watch files, to work more reliably with more models.
|
||||
- New install methods via uv, including one-liners.
|
||||
- Support for openrouter/deepseek/deepseek-chat model.
|
||||
- Better error handling when interactive commands are attempted via `/load` or `--load`.
|
||||
- Display read-only files with abs path if its shorter than rel path.
|
||||
- Ask 10% of users to opt-in to analytics.
|
||||
- Bugfix for auto-suggest.
|
||||
- Gracefully handle unicode errors in git path names.
|
||||
- Aider wrote 74% of the code in this release.
|
||||
|
||||
### Aider v0.69.1
|
||||
|
||||
- Fix for gemini model names in model metadata.
|
||||
- Show hints about AI! and AI? when user makes AI comments.
|
||||
- Support for running without git installed.
|
||||
- Improved environment variable setup messages on Windows.
|
||||
|
||||
### Aider v0.69.0
|
||||
|
||||
- [Watch files](https://aider.chat/docs/usage/watch.html) improvements:
|
||||
- Use `# ... AI?` comments to trigger aider and ask questions about your code.
|
||||
- Now watches *all* files, not just certain source files.
|
||||
- Use `# AI comments`, `// AI comments`, or `-- AI comments` to give aider instructions in any text file.
|
||||
- Full support for Gemini Flash 2.0 Exp:
|
||||
- `aider --model flash` or `aider --model gemini/gemini-2.0-flash-exp`
|
||||
- [New `--multiline` flag and `/multiline-mode` command](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) makes ENTER a soft newline and META-ENTER send the message, by @miradnanali.
|
||||
- `/copy-context <instructions>` now takes optional "instructions" when [copying code context to the clipboard](https://aider.chat/docs/usage/copypaste.html#copy-aiders-code-context-to-your-clipboard-paste-into-the-web-ui).
|
||||
- Improved clipboard error handling with helpful requirements install info.
|
||||
- Ask 5% of users if they want to opt-in to analytics.
|
||||
- `/voice` now lets you edit the transcribed text before sending.
|
||||
- Disabled auto-complete in Y/N prompts.
|
||||
- Aider wrote 68% of the code in this release.
|
||||
|
||||
### Aider v0.68.0
|
||||
|
||||
- [Aider works with LLM web chat UIs](https://aider.chat/docs/usage/copypaste.html).
|
||||
- New `--copy-paste` mode.
|
||||
- New `/copy-context` command.
|
||||
- [Set API keys and other environment variables for all providers from command line or yaml conf file](https://aider.chat/docs/config/aider_conf.html#storing-llm-keys).
|
||||
- New `--api-key provider=key` setting.
|
||||
- New `--set-env VAR=value` setting.
|
||||
- Added bash and zsh support to `--watch-files`.
|
||||
- Better error messages when missing dependencies for Gemini and Bedrock models.
|
||||
- Control-D now properly exits the program.
|
||||
- Don't count token costs when API provider returns a hard error.
|
||||
- Bugfix so watch files works with files that don't have tree-sitter support.
|
||||
- Bugfix so o1 models can be used as weak model.
|
||||
- Updated shell command prompt.
|
||||
- Added docstrings for all Coders.
|
||||
- Reorganized command line arguments with improved help messages and grouping.
|
||||
- Use the exact `sys.python` for self-upgrades.
|
||||
- Added experimental Gemini models.
|
||||
- Aider wrote 71% of the code in this release.
|
||||
|
||||
### Aider v0.67.0
|
||||
|
||||
- [Use aider in your IDE or editor](https://aider.chat/docs/usage/watch.html).
|
||||
- Run `aider --watch-files` and it will watch for instructions you add to your source files.
|
||||
- One-liner `# ...` or `// ...` comments that start or end with "AI" are instructions to aider.
|
||||
- When aider sees "AI!" it reads and follows all the instructions in AI comments.
|
||||
- Support for new Amazon Bedrock Nova models.
|
||||
- When `/run` or `/test` have non-zero exit codes, pre-fill "Fix that" into the next message prompt.
|
||||
- `/diff` now invokes `git diff` to use your preferred diff tool.
|
||||
- Added Ctrl-Z support for process suspension.
|
||||
- Spinner now falls back to ASCII art if fancy symbols throw unicode errors.
|
||||
- `--read` now expands `~` home dirs.
|
||||
- Enabled exception capture in analytics.
|
||||
- [Aider wrote 61% of the code in this release.](https://aider.chat/HISTORY.html)
|
||||
|
||||
### Aider v0.66.0
|
||||
|
||||
- PDF support for Sonnet and Gemini models.
|
||||
- Added `--voice-input-device` to select audio input device for voice recording, by @preynal.
|
||||
- Added `--timeout` option to configure API call timeouts.
|
||||
- Set cwd to repo root when running shell commands.
|
||||
- Added Ctrl-Up/Down keyboard shortcuts for per-message history navigation.
|
||||
- Improved error handling for failed .gitignore file operations.
|
||||
- Improved error handling for input history file permissions.
|
||||
- Improved error handling for analytics file access.
|
||||
- Removed spurious warning about disabling pretty in VSCode.
|
||||
- Removed broken support for Dart.
|
||||
- Bugfix when scraping URLs found in chat messages.
|
||||
- Better handling of __version__ import errors.
|
||||
- Improved `/drop` command to support substring matching for non-glob patterns.
|
||||
- Aider wrote 82% of the code in this release.
|
||||
|
||||
### Aider v0.65.1
|
||||
|
||||
- Bugfix to `--alias`.
|
||||
|
||||
### Aider v0.65.0
|
||||
|
||||
- Added `--alias` config to define [custom model aliases](https://aider.chat/docs/config/model-aliases.html).
|
||||
- Added `--[no-]detect-urls` flag to disable detecting and offering to scrape URLs found in the chat.
|
||||
- Ollama models now default to an 8k context window.
|
||||
- Added [RepoMap support for Dart language](https://aider.chat/docs/languages.html) by @malkoG.
|
||||
- Ask 2.5% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
|
||||
- Skip suggesting files that share names with files already in chat.
|
||||
- `/editor` returns and prefill the file content into the prompt, so you can use `/editor` to compose messages that start with `/commands`, etc.
|
||||
- Enhanced error handling for analytics.
|
||||
- Improved handling of UnknownEditFormat exceptions with helpful documentation links.
|
||||
- Bumped dependencies to pick up grep-ast 0.4.0 for Dart language support.
|
||||
- Aider wrote 81% of the code in this release.
|
||||
|
||||
### Aider v0.64.1
|
||||
|
||||
- Disable streaming for o1 on OpenRouter.
|
||||
|
||||
### Aider v0.64.0
|
||||
|
||||
- Added [`/editor` command](https://aider.chat/docs/usage/commands.html) to open system editor for writing prompts, by @thehunmonkgroup.
|
||||
- Full support for `gpt-4o-2024-11-20`.
|
||||
- Stream o1 models by default.
|
||||
- `/run` and suggested shell commands are less mysterious and now confirm that they "Added XX lines of output to the chat."
|
||||
- Ask 1% of users if they want to opt-in to [analytics](https://aider.chat/docs/more/analytics.html).
|
||||
- Added support for [optional multiline input tags](https://aider.chat/docs/usage/commands.html#entering-multi-line-chat-messages) with matching closing tags.
|
||||
- Improved [model settings configuration](https://aider.chat/docs/config/adv-model-settings.html#global-extra-params) with support for global `extra_params` for `litellm.completion()`.
|
||||
- Architect mode now asks to add files suggested by the LLM.
|
||||
- Fixed bug in fuzzy model name matching.
|
||||
- Added Timeout exception to handle API provider timeouts.
|
||||
- Added `--show-release-notes` to control release notes display on first run of new version.
|
||||
- Save empty dict to cache file on model metadata download failure, to delay retry.
|
||||
- Improved error handling and code formatting.
|
||||
- Aider wrote 74% of the code in this release.
|
||||
|
||||
### Aider v0.63.2
|
||||
|
||||
- Fixed bug in fuzzy model name matching when litellm provider info is missing.
|
||||
- Modified model metadata file loading to allow override of resource file.
|
||||
- Allow recursive loading of dirs using `--read`.
|
||||
- Updated dependency versions to pick up litellm fix for ollama models.
|
||||
- Added exponential backoff retry when writing files to handle editor file locks.
|
||||
- Updated Qwen 2.5 Coder 32B model configuration.
|
||||
|
||||
### Aider v0.63.1
|
||||
|
||||
- Fixed bug in git ignored file handling.
|
||||
- Improved error handling for git operations.
|
||||
|
||||
### Aider v0.63.0
|
||||
|
||||
- Support for Qwen 2.5 Coder 32B.
|
||||
- `/web` command just adds the page to the chat, without triggering an LLM response.
|
||||
- Improved prompting for the user's preferred chat language.
|
||||
- Improved handling of LiteLLM exceptions.
|
||||
- Bugfix for double-counting tokens when reporting cache stats.
|
||||
- Bugfix for the LLM creating new files.
|
||||
- Other small bug fixes.
|
||||
- Aider wrote 55% of the code in this release.
|
||||
|
||||
### Aider v0.62.0
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
theme: just-the-docs
|
||||
url: "https://aider.chat"
|
||||
|
||||
# Analytics configuration
|
||||
analytics:
|
||||
enabled: false # Single switch to control analytics and cookie consent
|
||||
posthog_key: 'phc_99T7muzafUMMZX15H8XePbMSreEUzahHbtWjy3l5Qbv'
|
||||
posthog_host: 'https://us.i.posthog.com'
|
||||
|
||||
plugins:
|
||||
- jekyll-redirect-from
|
||||
- jekyll-sitemap
|
||||
@@ -45,4 +51,4 @@ callouts:
|
||||
note:
|
||||
title: Note
|
||||
color: yellow
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
130
aider/website/_data/deepseek-down.yml
Normal file
130
aider/website/_data/deepseek-down.yml
Normal file
@@ -0,0 +1,130 @@
|
||||
- dirname: 2024-12-25-13-31-51--deepseekv3preview-diff2
|
||||
test_cases: 225
|
||||
model: DeepSeek
|
||||
edit_format: diff
|
||||
commit_hash: 0a23c4a-dirty
|
||||
pass_rate_1: 22.7
|
||||
pass_rate_2: 48.4
|
||||
pass_num_1: 51
|
||||
pass_num_2: 109
|
||||
percent_cases_well_formed: 98.7
|
||||
error_outputs: 7
|
||||
num_malformed_responses: 7
|
||||
num_with_malformed_responses: 3
|
||||
user_asks: 19
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-chat
|
||||
date: 2024-12-25
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.8
|
||||
total_cost: 0.3369
|
||||
|
||||
|
||||
- dirname: 2025-01-28-17-47-49--v3-fireworks
|
||||
test_cases: 225
|
||||
model: Fireworks
|
||||
edit_format: diff
|
||||
commit_hash: 0336a98-dirty
|
||||
pass_rate_1: 22.2
|
||||
pass_rate_2: 48.4
|
||||
pass_num_1: 50
|
||||
pass_num_2: 109
|
||||
percent_cases_well_formed: 96.9
|
||||
error_outputs: 18
|
||||
num_malformed_responses: 16
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 14
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 2
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model fireworks_ai/accounts/fireworks/models/deepseek-v3
|
||||
date: 2025-01-28
|
||||
versions: 0.72.4.dev
|
||||
seconds_per_case: 115.9
|
||||
total_cost: 2.1177
|
||||
|
||||
- dirname: 2025-01-28-19-25-32--or-v3-deepinfra-diff
|
||||
test_cases: 222
|
||||
model: "OpenRouter: DeepInfra"
|
||||
edit_format: diff
|
||||
commit_hash: bfc5745, 77d2bc5-dirty
|
||||
pass_rate_1: 23.9
|
||||
pass_rate_2: 48.0
|
||||
pass_num_1: 53
|
||||
pass_num_2: 108
|
||||
percent_cases_well_formed: 99.5
|
||||
error_outputs: 18
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 17
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 2
|
||||
test_timeouts: 4
|
||||
total_tests: 225
|
||||
command: aider --model openrouter/deepseek/deepseek-chat
|
||||
date: 2025-01-28
|
||||
versions: 0.72.4.dev
|
||||
seconds_per_case: 187.0
|
||||
total_cost: 0.2733
|
||||
|
||||
- dirname: 2025-01-28-21-07-23--or-v3-novita-diff
|
||||
test_cases: 225
|
||||
model: "OpenRouter: Novita"
|
||||
edit_format: diff
|
||||
commit_hash: 66025a0
|
||||
pass_rate_1: 20.4
|
||||
pass_rate_2: 42.7
|
||||
pass_num_1: 46
|
||||
pass_num_2: 96
|
||||
percent_cases_well_formed: 84.0
|
||||
error_outputs: 265
|
||||
num_malformed_responses: 67
|
||||
num_with_malformed_responses: 36
|
||||
user_asks: 5
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model openrouter/deepseek/deepseek-chat
|
||||
date: 2025-01-28
|
||||
versions: 0.72.4.dev
|
||||
seconds_per_case: 472.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2025-01-29-00-36-49--v3-hyperolic-diff
|
||||
test_cases: 224
|
||||
model: Hyperbolic
|
||||
edit_format: diff
|
||||
commit_hash: 298f713
|
||||
pass_rate_1: 20.5
|
||||
pass_rate_2: 48.4
|
||||
pass_num_1: 46
|
||||
pass_num_2: 109
|
||||
percent_cases_well_formed: 97.3
|
||||
error_outputs: 29
|
||||
num_malformed_responses: 6
|
||||
num_with_malformed_responses: 6
|
||||
user_asks: 7
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 7
|
||||
total_tests: 225
|
||||
command: OPENAI_API_BASE=https://api.hyperbolic.xyz/v1/ aider --model openai/deepseek-ai/DeepSeek-V3
|
||||
date: 2025-01-29
|
||||
versions: 0.72.4.dev
|
||||
seconds_per_case: 365.4
|
||||
total_cost: 0.0000
|
||||
@@ -1,7 +1,7 @@
|
||||
- dirname: 2024-05-01-20-05-59--direct-opus-filenames-outside-fence
|
||||
test_cases: 133
|
||||
model: claude-3-opus-20240229
|
||||
released: 2024-02-29
|
||||
_released: 2024-02-29
|
||||
edit_format: diff
|
||||
commit_hash: f4b1797-dirty, f4b1797
|
||||
pass_rate_1: 53.4
|
||||
@@ -20,7 +20,7 @@
|
||||
versions: 0.30.2-dev
|
||||
seconds_per_case: 32.4
|
||||
total_cost: 13.8395
|
||||
|
||||
|
||||
- dirname: 2024-03-06-16-42-00--claude3-sonnet-whole
|
||||
test_cases: 133
|
||||
model: claude-3-sonnet-20240229
|
||||
@@ -43,10 +43,11 @@
|
||||
versions: 0.25.1-dev
|
||||
seconds_per_case: 23.1
|
||||
total_cost: 0.0000
|
||||
|
||||
|
||||
- dirname: 2024-05-03-20-47-24--gemini-1.5-pro-diff-fenced
|
||||
test_cases: 133
|
||||
model: gemini-1.5-pro-latest
|
||||
released: 2024-05-03
|
||||
model: gemini-1.5-pro-001
|
||||
edit_format: diff-fenced
|
||||
commit_hash: 3a48dfb, 5d32dd7
|
||||
pass_rate_1: 45.9
|
||||
@@ -88,7 +89,7 @@
|
||||
versions: 0.33.1-dev
|
||||
seconds_per_case: 6.5
|
||||
total_cost: 0.5032
|
||||
|
||||
|
||||
- dirname: 2023-11-06-21-23-59--gpt-3.5-turbo-0301
|
||||
test_cases: 133
|
||||
model: gpt-3.5-turbo-0301
|
||||
@@ -111,7 +112,7 @@
|
||||
versions: 0.16.4-dev
|
||||
seconds_per_case: 6.5
|
||||
total_cost: 0.4822
|
||||
|
||||
|
||||
- dirname: 2023-11-07-02-41-07--gpt-3.5-turbo-0613
|
||||
test_cases: 133
|
||||
model: gpt-3.5-turbo-0613
|
||||
@@ -155,7 +156,7 @@
|
||||
versions: 0.30.2-dev
|
||||
seconds_per_case: 5.3
|
||||
total_cost: 0.3261
|
||||
|
||||
|
||||
- dirname: 2024-01-25-23-37-15--jan-exercism-gpt-4-0125-preview-udiff
|
||||
test_cases: 133
|
||||
model: gpt-4-0125-preview
|
||||
@@ -178,7 +179,7 @@
|
||||
versions: 0.22.1-dev
|
||||
seconds_per_case: 44.8
|
||||
total_cost: 14.6428
|
||||
|
||||
|
||||
- dirname: 2024-05-04-15-07-30--redo-gpt-4-0314-diff-reminder-rules
|
||||
test_cases: 133
|
||||
model: gpt-4-0314
|
||||
@@ -201,7 +202,7 @@
|
||||
versions: 0.31.2-dev
|
||||
seconds_per_case: 19.8
|
||||
total_cost: 16.2689
|
||||
|
||||
|
||||
- dirname: 2023-12-16-21-24-28--editblock-gpt-4-0613-actual-main
|
||||
test_cases: 133
|
||||
model: gpt-4-0613
|
||||
@@ -228,7 +229,7 @@
|
||||
- dirname: 2024-05-08-21-16-03--may-gpt-4-1106-preview-udiff
|
||||
test_cases: 133
|
||||
model: gpt-4-1106-preview
|
||||
released: 2023-11-06
|
||||
released: 2023-11-06
|
||||
edit_format: udiff
|
||||
commit_hash: 87664dc
|
||||
pass_rate_1: 51.9
|
||||
@@ -247,7 +248,7 @@
|
||||
versions: 0.33.1-dev
|
||||
seconds_per_case: 20.4
|
||||
total_cost: 6.6061
|
||||
|
||||
|
||||
- dirname: 2024-05-01-02-09-20--gpt-4-turbo-examples
|
||||
test_cases: 133
|
||||
model: gpt-4-turbo-2024-04-09 (udiff)
|
||||
@@ -270,11 +271,11 @@
|
||||
versions: 0.30.2-dev
|
||||
seconds_per_case: 22.8
|
||||
total_cost: 6.3337
|
||||
|
||||
|
||||
- dirname: 2024-05-03-22-24-48--openrouter--llama3-diff-examples-sys-msg
|
||||
test_cases: 132
|
||||
model: llama3-70b-8192
|
||||
released: 2024-04-18
|
||||
_released: 2024-04-18
|
||||
edit_format: diff
|
||||
commit_hash: b5bb453
|
||||
pass_rate_1: 38.6
|
||||
@@ -293,11 +294,11 @@
|
||||
versions: 0.31.2-dev
|
||||
seconds_per_case: 14.5
|
||||
total_cost: 0.4311
|
||||
|
||||
|
||||
- dirname: 2024-05-06-18-31-08--command-r-plus-whole-final
|
||||
test_cases: 133
|
||||
model: command-r-plus
|
||||
released: 2024-04-04
|
||||
_released: 2024-04-04
|
||||
edit_format: whole
|
||||
commit_hash: fc3a43e-dirty
|
||||
pass_rate_1: 21.8
|
||||
@@ -316,11 +317,11 @@
|
||||
versions: 0.31.2-dev
|
||||
seconds_per_case: 22.9
|
||||
total_cost: 2.7494
|
||||
|
||||
|
||||
- dirname: 2024-05-07-20-32-37--qwen1.5-110b-chat-whole
|
||||
test_cases: 133
|
||||
model: qwen1.5-110b-chat
|
||||
released: 2024-02-04
|
||||
released: 2024-02-04
|
||||
edit_format: whole
|
||||
commit_hash: 70b1c0c
|
||||
pass_rate_1: 30.8
|
||||
@@ -339,7 +340,7 @@
|
||||
versions: 0.31.2-dev
|
||||
seconds_per_case: 46.9
|
||||
total_cost: 0.0000
|
||||
|
||||
|
||||
- dirname: 2024-05-07-20-57-04--wizardlm-2-8x22b-whole
|
||||
test_cases: 133
|
||||
model: WizardLM-2 8x22B
|
||||
@@ -384,7 +385,7 @@
|
||||
versions: 0.34.1-dev
|
||||
seconds_per_case: 6.0
|
||||
total_cost: 0.0000
|
||||
|
||||
|
||||
- dirname: 2024-04-12-22-18-20--gpt-4-turbo-2024-04-09-plain-diff
|
||||
test_cases: 33
|
||||
model: gpt-4-turbo-2024-04-09 (diff)
|
||||
@@ -410,6 +411,7 @@
|
||||
- dirname: 2024-06-08-22-37-55--qwen2-72b-instruct-whole
|
||||
test_cases: 133
|
||||
model: Qwen2 72B Instruct
|
||||
released: 2024-06-08
|
||||
edit_format: whole
|
||||
commit_hash: 02c7335-dirty, 1a97498-dirty
|
||||
pass_rate_1: 44.4
|
||||
@@ -568,7 +570,7 @@
|
||||
versions: 0.42.1-dev
|
||||
seconds_per_case: 17.6
|
||||
total_cost: 3.6346
|
||||
|
||||
|
||||
- dirname: 2024-07-01-21-41-48--haiku-whole
|
||||
test_cases: 133
|
||||
model: claude-3-haiku-20240307
|
||||
@@ -623,7 +625,7 @@
|
||||
commit_hash: d31eef3-dirty
|
||||
pass_rate_1: 40.6
|
||||
pass_rate_2: 55.6
|
||||
released: 2024-07-18
|
||||
_released: 2024-07-18
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
@@ -642,7 +644,7 @@
|
||||
|
||||
- dirname: 2024-07-19-08-57-13--openrouter-deepseek-chat-v2-0628
|
||||
test_cases: 133
|
||||
model: DeepSeek Chat V2 0628 (deprecated)
|
||||
model: DeepSeek Chat V2 0628
|
||||
edit_format: diff
|
||||
commit_hash: 96ff06e-dirty
|
||||
pass_rate_1: 60.9
|
||||
@@ -671,7 +673,7 @@
|
||||
commit_hash: f7ce78b-dirty
|
||||
pass_rate_1: 46.6
|
||||
pass_rate_2: 63.9
|
||||
released: 2024-07-23
|
||||
_released: 2024-07-23
|
||||
percent_cases_well_formed: 92.5
|
||||
error_outputs: 84
|
||||
num_malformed_responses: 19
|
||||
@@ -691,6 +693,7 @@
|
||||
- dirname: 2024-07-24-06-30-29--llama-405b-whole
|
||||
test_cases: 133
|
||||
model: llama-3.1-405b-instruct (whole)
|
||||
_released: 2024-07-23
|
||||
edit_format: whole
|
||||
commit_hash: a362dea-dirty
|
||||
pass_rate_1: 48.9
|
||||
@@ -698,7 +701,6 @@
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
released: 2024-07-23
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 0
|
||||
lazy_comments: 0
|
||||
@@ -714,7 +716,7 @@
|
||||
|
||||
- dirname: 2024-07-24-07-10-58--deepseek-coder2-0724-diff-direct
|
||||
test_cases: 133
|
||||
model: DeepSeek Coder V2 0724 (deprecated)
|
||||
model: DeepSeek Coder V2 0724
|
||||
edit_format: diff
|
||||
commit_hash: 89965bf
|
||||
pass_rate_1: 57.9
|
||||
@@ -770,7 +772,7 @@
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 27
|
||||
num_malformed_responses: 0
|
||||
released: 2024-07-23
|
||||
_released: 2024-07-23
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 23
|
||||
lazy_comments: 8
|
||||
@@ -796,7 +798,7 @@
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 0
|
||||
released: 2024-07-23
|
||||
_released: 2024-07-23
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
@@ -835,6 +837,7 @@
|
||||
- dirname: 2024-08-28-07-10-50--gemini-1.5-pro-exp-0827-diff-fenced
|
||||
test_cases: 133
|
||||
model: gemini-1.5-pro-exp-0827
|
||||
released: 2024-08-27
|
||||
edit_format: diff-fenced
|
||||
commit_hash: d8adc75
|
||||
pass_rate_1: 54.9
|
||||
@@ -946,7 +949,7 @@
|
||||
versions: 0.54.13.dev
|
||||
seconds_per_case: 8.3
|
||||
total_cost: 0.0000
|
||||
released: 2024-09-04
|
||||
_released: 2024-09-04
|
||||
|
||||
- dirname: 2024-09-04-16-17-33--yi-coder-9b-chat-q4_0-whole
|
||||
test_cases: 133
|
||||
@@ -973,6 +976,7 @@
|
||||
|
||||
- dirname: 2024-09-05-14-50-11--deepseek-sep5-no-shell
|
||||
test_cases: 133
|
||||
released: 2024-09-05
|
||||
model: DeepSeek V2.5
|
||||
edit_format: diff
|
||||
commit_hash: 1279c86
|
||||
@@ -1112,6 +1116,7 @@
|
||||
- dirname: 2024-09-21-16-45-11--o1-preview-flex-sr-markers
|
||||
test_cases: 133
|
||||
model: o1-preview
|
||||
_released: 2024-09-12
|
||||
edit_format: diff
|
||||
commit_hash: 5493654-dirty
|
||||
pass_rate_1: 57.9
|
||||
@@ -1131,7 +1136,7 @@
|
||||
versions: 0.56.1.dev
|
||||
seconds_per_case: 80.9
|
||||
total_cost: 63.9190
|
||||
|
||||
|
||||
- dirname: 2024-09-19-16-58-29--qwen2.5-coder:7b-instruct-q8_0
|
||||
test_cases: 133
|
||||
model: qwen2.5-coder:7b-instruct-q8_0
|
||||
@@ -1154,7 +1159,7 @@
|
||||
versions: 0.56.0
|
||||
seconds_per_case: 9.3
|
||||
total_cost: 0.0000
|
||||
|
||||
|
||||
- dirname: 2024-09-20-20-20-19--qwen-2.5-72b-instruct-diff
|
||||
test_cases: 133
|
||||
model: qwen-2.5-72b-instruct (bf16)
|
||||
@@ -1204,6 +1209,7 @@
|
||||
- dirname: 2024-09-24-16-26-45--gemini-1.5-pro-002-diff-fenced
|
||||
test_cases: 133
|
||||
model: gemini-1.5-pro-002
|
||||
released: 2024-09-24
|
||||
edit_format: diff-fenced
|
||||
commit_hash: 6b5fe9b, 3edcd71
|
||||
pass_rate_1: 49.6
|
||||
@@ -1226,7 +1232,7 @@
|
||||
|
||||
- dirname: 2024-09-24-16-33-23--gemini-1.5-flash-002-whole
|
||||
test_cases: 133
|
||||
model: gemini-1.5-flash-002
|
||||
model: gemini-1.5-flash-002 (0924)
|
||||
edit_format: whole
|
||||
commit_hash: 3edcd71
|
||||
pass_rate_1: 37.6
|
||||
@@ -1458,7 +1464,7 @@
|
||||
versions: 0.58.1.dev
|
||||
seconds_per_case: 63.7
|
||||
total_cost: 0.0000
|
||||
|
||||
|
||||
- dirname: 2024-10-01-16-50-09--hermes3-whole-4
|
||||
test_cases: 133
|
||||
model: ollama/hermes3
|
||||
@@ -1477,6 +1483,7 @@
|
||||
- dirname: 2024-10-04-16-30-08--chatgpt-4o-latest-diff-oct4
|
||||
test_cases: 133
|
||||
model: openai/chatgpt-4o-latest
|
||||
released: 2024-10-04
|
||||
edit_format: diff
|
||||
commit_hash: af10953
|
||||
pass_rate_1: 56.4
|
||||
@@ -1592,6 +1599,7 @@
|
||||
- dirname: 2024-10-22-17-45-28--sonnet-1022-diff-fixed-model-settings
|
||||
test_cases: 133
|
||||
model: claude-3-5-sonnet-20241022
|
||||
released: 2024-10-22
|
||||
edit_format: diff
|
||||
commit_hash: 3b14eb9
|
||||
pass_rate_1: 69.2
|
||||
@@ -1615,6 +1623,7 @@
|
||||
- dirname: 2024-11-04-19-19-32--haiku35-diff-ex-as-sys-false
|
||||
test_cases: 133
|
||||
model: claude-3-5-haiku-20241022
|
||||
released: 2024-10-22
|
||||
edit_format: diff
|
||||
commit_hash: 03bbdb0-dirty
|
||||
pass_rate_1: 61.7
|
||||
@@ -1633,4 +1642,591 @@
|
||||
date: 2024-11-04
|
||||
versions: 0.61.1.dev
|
||||
seconds_per_case: 18.4
|
||||
total_cost: 0.0000
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-07-06-15-36--Qwen2.5.1-Coder-7B-Instruct-GGUF:Q8_0-32k-whole
|
||||
test_cases: 133
|
||||
model: ollama/Qwen2.5.1-Coder-7B-Instruct-GGUF:Q8_0-32k
|
||||
edit_format: whole
|
||||
commit_hash: e76704e
|
||||
pass_rate_1: 52.6
|
||||
pass_rate_2: 63.9
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 4
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 1
|
||||
command: aider --model ollama/Qwen2.5.1-Coder-7B-Instruct-GGUF:Q8_0-32k
|
||||
date: 2024-11-07
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 18.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-10-29-00-29-09--Qwen2.5-Coder-0.5B-Instruct
|
||||
test_cases: 133
|
||||
model: Qwen2.5-Coder-0.5B-Instruct
|
||||
edit_format: whole
|
||||
commit_hash: 58bd375
|
||||
pass_rate_1: 14.3
|
||||
pass_rate_2: 14.3
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 20
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 45
|
||||
lazy_comments: 0
|
||||
syntax_errors: 2
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 20
|
||||
test_timeouts: 2
|
||||
command: aider --model openai/Qwen2.5-Coder-0.5B-Instruct
|
||||
date: 2024-10-29
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 16.0
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-11-19-37-01--Qwen2.5-Coder-1.5B-Instruct
|
||||
test_cases: 133
|
||||
model: Qwen2.5-Coder-1.5B-Instruct
|
||||
edit_format: whole
|
||||
commit_hash: bb5681c
|
||||
pass_rate_1: 28.6
|
||||
pass_rate_2: 31.6
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 5
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 13
|
||||
lazy_comments: 2
|
||||
syntax_errors: 1
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 5
|
||||
test_timeouts: 2
|
||||
command: aider --model openai/Qwen2.5-Coder-1.5B-Instruct
|
||||
date: 2024-11-11
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 27.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-04-02-25-32--Qwen2.5-Coder-3B-Instruct
|
||||
test_cases: 133
|
||||
model: Qwen2.5-Coder-3B-Instruct
|
||||
edit_format: whole
|
||||
commit_hash: 0ba3647
|
||||
pass_rate_1: 33.8
|
||||
pass_rate_2: 39.1
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 4
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 3
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 4
|
||||
test_timeouts: 6
|
||||
command: aider --model openai/Qwen2.5-Coder-3B-Instruct
|
||||
date: 2024-11-04
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 18.7
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-10-16-16-20-59--Qwen2.5-Coder-7B-Instruct
|
||||
test_cases: 133
|
||||
model: Qwen2.5-Coder-7B-Instruct
|
||||
edit_format: whole
|
||||
commit_hash: 92fe979-dirty
|
||||
pass_rate_1: 51.9
|
||||
pass_rate_2: 57.9
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 2
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 2
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 2
|
||||
test_timeouts: 5
|
||||
command: aider --model openai/Qwen2.5-Coder-7B-Instruct
|
||||
date: 2024-10-16
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 10.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-10-29-11-53-39--Qwen2.5-Coder-14B-Instruct
|
||||
test_cases: 133
|
||||
model: Qwen2.5-Coder-14B-Instruct
|
||||
edit_format: whole
|
||||
commit_hash: 58bd375
|
||||
pass_rate_1: 58.6
|
||||
pass_rate_2: 69.2
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 3
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 2
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 3
|
||||
test_timeouts: 0
|
||||
command: aider --model openai/Qwen2.5-Coder-14B-Instruct
|
||||
date: 2024-10-29
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 18.3
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-09-11-09-15--Qwen2.5-Coder-32B-Instruct
|
||||
test_cases: 133
|
||||
model: Qwen2.5-Coder-32B-Instruct
|
||||
released: 2024-11-12
|
||||
edit_format: diff
|
||||
commit_hash: ec9982a
|
||||
pass_rate_1: 59.4
|
||||
pass_rate_2: 71.4
|
||||
percent_cases_well_formed: 94.7
|
||||
error_outputs: 17
|
||||
num_malformed_responses: 17
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 1
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model openai/hf:Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://glhf.chat/api/openai/v1
|
||||
date: 2024-11-09
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 22.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-20-14-57-11--mistral-2411-direct-diff
|
||||
test_cases: 133
|
||||
model: Mistral Large (2411)
|
||||
released: 2024-11-18
|
||||
edit_format: diff
|
||||
commit_hash: dba844c
|
||||
pass_rate_1: 46.6
|
||||
pass_rate_2: 65.4
|
||||
percent_cases_well_formed: 96.2
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 5
|
||||
user_asks: 5
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 1
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 1
|
||||
command: aider --model mistral/mistral-large-latest
|
||||
date: 2024-11-20
|
||||
versions: 0.63.3.dev
|
||||
seconds_per_case: 24.9
|
||||
total_cost: 3.2334
|
||||
|
||||
- dirname: 2024-11-20-19-28-30--gpt-4o-2024-11-20
|
||||
test_cases: 133
|
||||
model: gpt-4o-2024-11-20
|
||||
released: 2024-11-20
|
||||
edit_format: diff
|
||||
commit_hash: 2ac0776-dirty
|
||||
pass_rate_1: 58.6
|
||||
pass_rate_2: 71.4
|
||||
percent_cases_well_formed: 99.2
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 4
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 5
|
||||
command: aider --model openai/gpt-4o-2024-11-20
|
||||
date: 2024-11-20
|
||||
versions: 0.63.3.dev
|
||||
seconds_per_case: 6.0
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-09-20-21-47-17--qwen2.5-32b-instruct-q8_0-whole
|
||||
test_cases: 133
|
||||
model: ollama/qwen2.5:32b-instruct-q8_0
|
||||
edit_format: whole
|
||||
commit_hash: 2753ac6
|
||||
pass_rate_1: 46.6
|
||||
pass_rate_2: 58.6
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 1
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
command: aider --model ollama/qwen2.5:32b-instruct-q8_0
|
||||
date: 2024-09-20
|
||||
versions: 0.56.1.dev
|
||||
seconds_per_case: 1763.7
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-20-15-17-37--qwen25-32b-or-diff
|
||||
test_cases: 133
|
||||
model: openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
edit_format: diff
|
||||
commit_hash: e917424
|
||||
pass_rate_1: 49.6
|
||||
pass_rate_2: 65.4
|
||||
percent_cases_well_formed: 84.2
|
||||
error_outputs: 43
|
||||
num_malformed_responses: 31
|
||||
num_with_malformed_responses: 21
|
||||
user_asks: 43
|
||||
lazy_comments: 0
|
||||
syntax_errors: 2
|
||||
indentation_errors: 2
|
||||
exhausted_context_windows: 12
|
||||
test_timeouts: 2
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-20
|
||||
versions: 0.63.3.dev
|
||||
seconds_per_case: 40.7
|
||||
total_cost: 0.1497
|
||||
|
||||
- dirname: 2024-11-21-17-46-36--gemini-exp-1121-diff
|
||||
test_cases: 133
|
||||
model: gemini-exp-1121
|
||||
released: 2024-11-21
|
||||
edit_format: diff
|
||||
commit_hash: e94961a
|
||||
pass_rate_1: 46.6
|
||||
pass_rate_2: 57.9
|
||||
percent_cases_well_formed: 83.5
|
||||
error_outputs: 101
|
||||
num_malformed_responses: 101
|
||||
num_with_malformed_responses: 22
|
||||
user_asks: 5
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 2
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model gemini/gemini-exp-1121
|
||||
date: 2024-11-21
|
||||
versions: 0.63.3.dev
|
||||
seconds_per_case: 60.3
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-15-20-33-31--gemini-exp-1114-diff
|
||||
test_cases: 133
|
||||
model: gemini-exp-1114
|
||||
released: 2024-11-14
|
||||
edit_format: diff
|
||||
commit_hash: 0bf17a4
|
||||
pass_rate_1: 50.4
|
||||
pass_rate_2: 60.9
|
||||
percent_cases_well_formed: 85.7
|
||||
error_outputs: 70
|
||||
num_malformed_responses: 70
|
||||
num_with_malformed_responses: 19
|
||||
user_asks: 2
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 4
|
||||
command: aider --model gemini/gemini-exp-1114
|
||||
date: 2024-11-15
|
||||
versions: 0.63.2.dev
|
||||
seconds_per_case: 38.6
|
||||
- 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
|
||||
|
||||
- dirname: 2024-12-18-01-50-08--o1
|
||||
test_cases: 133
|
||||
model: o1
|
||||
edit_format: diff
|
||||
commit_hash: 074c636-dirty
|
||||
pass_rate_1: 65.4
|
||||
pass_rate_2: 84.2
|
||||
percent_cases_well_formed: 99.2
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 0
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
command: aider --model openrouter/openai/o1
|
||||
date: 2024-12-18
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 29.9
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-21-22-06-01--polyglot-o1-mini-whole
|
||||
test_cases: 225
|
||||
model: o1-mini-2024-09-12
|
||||
edit_format: whole
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 8.9
|
||||
pass_rate_2: 27.1
|
||||
pass_num_1: 20
|
||||
pass_num_2: 61
|
||||
percent_cases_well_formed: 95.6
|
||||
error_outputs: 15
|
||||
num_malformed_responses: 14
|
||||
num_with_malformed_responses: 10
|
||||
user_asks: 37
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model o1-mini
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.3
|
||||
total_cost: 17.6270
|
||||
259
aider/website/_data/o1_polyglot_leaderboard.yml
Normal file
259
aider/website/_data/o1_polyglot_leaderboard.yml
Normal file
@@ -0,0 +1,259 @@
|
||||
- dirname: 2024-12-21-18-41-18--polyglot-gpt-4o-mini
|
||||
test_cases: 225
|
||||
model: gpt-4o-mini-2024-07-18
|
||||
edit_format: whole
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 0.9
|
||||
pass_rate_2: 3.6
|
||||
pass_num_1: 2
|
||||
pass_num_2: 8
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 36
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-mini-2024-07-18
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 17.3
|
||||
total_cost: 0.3236
|
||||
|
||||
- dirname: 2024-12-21-18-44-28--polyglot-sonnet
|
||||
test_cases: 225
|
||||
model: claude-3-5-sonnet-20241022
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 18.7
|
||||
pass_rate_2: 45.3
|
||||
pass_num_1: 42
|
||||
pass_num_2: 102
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 14
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 12
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-sonnet-20241022
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 30.8
|
||||
total_cost: 13.4847
|
||||
|
||||
- dirname: 2024-12-21-18-52-34--polyglot-gpt-4o-diff
|
||||
test_cases: 225
|
||||
model: gpt-4o-2024-11-20
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 4.9
|
||||
pass_rate_2: 15.1
|
||||
pass_num_1: 11
|
||||
pass_num_2: 34
|
||||
percent_cases_well_formed: 96.0
|
||||
error_outputs: 12
|
||||
num_malformed_responses: 11
|
||||
num_with_malformed_responses: 9
|
||||
user_asks: 34
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 19
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-2024-11-20
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 22.2
|
||||
total_cost: 7.1835
|
||||
|
||||
- dirname: 2024-12-21-19-23-03--polyglot-o1-hard-diff
|
||||
test_cases: 224
|
||||
model: o1-2024-12-17 (high)
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 23.7
|
||||
pass_rate_2: 61.7
|
||||
pass_num_1: 53
|
||||
pass_num_2: 139
|
||||
percent_cases_well_formed: 91.5
|
||||
error_outputs: 25
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 19
|
||||
user_asks: 16
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model openrouter/openai/o1
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 133.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-21-20-56-21--polyglot-deepseek-diff
|
||||
test_cases: 225
|
||||
model: DeepSeek Chat V2.5
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 5.3
|
||||
pass_rate_2: 17.8
|
||||
pass_num_1: 12
|
||||
pass_num_2: 40
|
||||
percent_cases_well_formed: 92.9
|
||||
error_outputs: 42
|
||||
num_malformed_responses: 37
|
||||
num_with_malformed_responses: 16
|
||||
user_asks: 23
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 5
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-chat
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 184.0
|
||||
total_cost: 0.5101
|
||||
|
||||
- dirname: 2024-12-21-21-46-27--polyglot-haiku-diff
|
||||
test_cases: 225
|
||||
model: claude-3-5-haiku-20241022
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 7.1
|
||||
pass_rate_2: 28.0
|
||||
pass_num_1: 16
|
||||
pass_num_2: 63
|
||||
percent_cases_well_formed: 91.1
|
||||
error_outputs: 31
|
||||
num_malformed_responses: 30
|
||||
num_with_malformed_responses: 20
|
||||
user_asks: 13
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-haiku-20241022
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 31.8
|
||||
total_cost: 6.0583
|
||||
|
||||
- dirname: 2024-12-22-13-22-32--polyglot-qwen-diff
|
||||
test_cases: 225
|
||||
model: Qwen2.5-Coder-32B-Instruct
|
||||
edit_format: diff
|
||||
commit_hash: 6d7e8be-dirty
|
||||
pass_rate_1: 4.4
|
||||
pass_rate_2: 8.0
|
||||
pass_num_1: 10
|
||||
pass_num_2: 18
|
||||
percent_cases_well_formed: 71.6
|
||||
error_outputs: 158
|
||||
num_malformed_responses: 148
|
||||
num_with_malformed_responses: 64
|
||||
user_asks: 132
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: "aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct # via hyperbolic"
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 84.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-21-26-35--polyglot-o1mini-whole
|
||||
test_cases: 225
|
||||
model: o1-mini-2024-09-12
|
||||
edit_format: whole
|
||||
commit_hash: 37df899
|
||||
pass_rate_1: 5.8
|
||||
pass_rate_2: 32.9
|
||||
pass_num_1: 13
|
||||
pass_num_2: 74
|
||||
percent_cases_well_formed: 96.9
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 27
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model o1-mini
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.7
|
||||
total_cost: 18.5770
|
||||
|
||||
- dirname: 2024-12-22-18-43-25--gemini-exp-1206-polyglot-whole-2
|
||||
test_cases: 225
|
||||
model: gemini-exp-1206
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 19.6
|
||||
pass_rate_2: 38.2
|
||||
pass_num_1: 44
|
||||
pass_num_2: 86
|
||||
percent_cases_well_formed: 98.2
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 4
|
||||
user_asks: 32
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-exp-1206
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 45.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-20-08-13--gemini-2.0-flash-exp-polyglot-whole
|
||||
test_cases: 225
|
||||
model: gemini-2.0-flash-exp
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 11.6
|
||||
pass_rate_2: 22.2
|
||||
pass_num_1: 26
|
||||
pass_num_2: 50
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 9
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-2.0-flash-exp
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 12.2
|
||||
total_cost: 0.0000
|
||||
730
aider/website/_data/polyglot_leaderboard.yml
Normal file
730
aider/website/_data/polyglot_leaderboard.yml
Normal file
@@ -0,0 +1,730 @@
|
||||
- dirname: 2025-02-25-20-23-07--gemini-pro
|
||||
test_cases: 225
|
||||
model: gemini/gemini-2.0-pro-exp-02-05
|
||||
edit_format: whole
|
||||
commit_hash: 2fccd47
|
||||
pass_rate_1: 20.4
|
||||
pass_rate_2: 35.6
|
||||
pass_num_1: 46
|
||||
pass_num_2: 80
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 430
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 13
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-2.0-pro-exp-02-05
|
||||
date: 2025-02-25
|
||||
versions: 0.75.2.dev
|
||||
seconds_per_case: 34.8
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-21-18-41-18--polyglot-gpt-4o-mini
|
||||
test_cases: 225
|
||||
model: gpt-4o-mini-2024-07-18
|
||||
edit_format: whole
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 0.9
|
||||
pass_rate_2: 3.6
|
||||
pass_num_1: 2
|
||||
pass_num_2: 8
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 36
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-mini-2024-07-18
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 17.3
|
||||
total_cost: 0.3236
|
||||
|
||||
- dirname: 2025-01-17-19-44-33--sonnet-baseline-jan-17
|
||||
test_cases: 225
|
||||
model: claude-3-5-sonnet-20241022
|
||||
edit_format: diff
|
||||
commit_hash: 6451d59
|
||||
pass_rate_1: 22.2
|
||||
pass_rate_2: 51.6
|
||||
pass_num_1: 50
|
||||
pass_num_2: 116
|
||||
percent_cases_well_formed: 99.6
|
||||
error_outputs: 2
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 11
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-sonnet-20241022
|
||||
date: 2025-01-17
|
||||
versions: 0.71.2.dev
|
||||
seconds_per_case: 21.4
|
||||
total_cost: 14.4063
|
||||
|
||||
- dirname: 2024-12-30-20-57-12--gpt-4o-2024-11-20-ex-as-sys
|
||||
test_cases: 225
|
||||
model: gpt-4o-2024-11-20
|
||||
edit_format: diff
|
||||
commit_hash: 09ee197-dirty
|
||||
pass_rate_1: 4.9
|
||||
pass_rate_2: 18.2
|
||||
pass_num_1: 11
|
||||
pass_num_2: 41
|
||||
percent_cases_well_formed: 95.1
|
||||
error_outputs: 12
|
||||
num_malformed_responses: 12
|
||||
num_with_malformed_responses: 11
|
||||
user_asks: 53
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 12
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-2024-11-20
|
||||
date: 2024-12-30
|
||||
versions: 0.70.1.dev
|
||||
seconds_per_case: 12.1
|
||||
total_cost: 6.7351
|
||||
|
||||
- dirname: 2024-12-30-20-44-54--gpt4o-ex-as-sys-clean-prompt
|
||||
test_cases: 225
|
||||
model: gpt-4o-2024-08-06
|
||||
edit_format: diff
|
||||
commit_hash: 09ee197-dirty
|
||||
pass_rate_1: 4.9
|
||||
pass_rate_2: 23.1
|
||||
pass_num_1: 11
|
||||
pass_num_2: 52
|
||||
percent_cases_well_formed: 94.2
|
||||
error_outputs: 21
|
||||
num_malformed_responses: 21
|
||||
num_with_malformed_responses: 13
|
||||
user_asks: 65
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model gpt-4o-2024-08-06
|
||||
date: 2024-12-30
|
||||
versions: 0.70.1.dev
|
||||
seconds_per_case: 16.0
|
||||
total_cost: 7.0286
|
||||
|
||||
- dirname: 2024-12-21-19-23-03--polyglot-o1-hard-diff
|
||||
test_cases: 224
|
||||
model: o1-2024-12-17 (high)
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 23.7
|
||||
pass_rate_2: 61.7
|
||||
pass_num_1: 53
|
||||
pass_num_2: 139
|
||||
percent_cases_well_formed: 91.5
|
||||
error_outputs: 25
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 19
|
||||
user_asks: 16
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model openrouter/openai/o1
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 133.2
|
||||
total_cost: 186.4958
|
||||
|
||||
- dirname: 2024-12-21-20-56-21--polyglot-deepseek-diff
|
||||
test_cases: 225
|
||||
model: DeepSeek Chat V2.5
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 5.3
|
||||
pass_rate_2: 17.8
|
||||
pass_num_1: 12
|
||||
pass_num_2: 40
|
||||
percent_cases_well_formed: 92.9
|
||||
error_outputs: 42
|
||||
num_malformed_responses: 37
|
||||
num_with_malformed_responses: 16
|
||||
user_asks: 23
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 5
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-chat
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 184.0
|
||||
total_cost: 0.5101
|
||||
|
||||
- dirname: 2024-12-21-21-46-27--polyglot-haiku-diff
|
||||
test_cases: 225
|
||||
model: claude-3-5-haiku-20241022
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 7.1
|
||||
pass_rate_2: 28.0
|
||||
pass_num_1: 16
|
||||
pass_num_2: 63
|
||||
percent_cases_well_formed: 91.1
|
||||
error_outputs: 31
|
||||
num_malformed_responses: 30
|
||||
num_with_malformed_responses: 20
|
||||
user_asks: 13
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model claude-3-5-haiku-20241022
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 31.8
|
||||
total_cost: 6.0583
|
||||
|
||||
- dirname: 2024-12-22-13-22-32--polyglot-qwen-diff
|
||||
test_cases: 225
|
||||
model: Qwen2.5-Coder-32B-Instruct
|
||||
edit_format: diff
|
||||
commit_hash: 6d7e8be-dirty
|
||||
pass_rate_1: 4.4
|
||||
pass_rate_2: 8.0
|
||||
pass_num_1: 10
|
||||
pass_num_2: 18
|
||||
percent_cases_well_formed: 71.6
|
||||
error_outputs: 158
|
||||
num_malformed_responses: 148
|
||||
num_with_malformed_responses: 64
|
||||
user_asks: 132
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: "aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct # via hyperbolic"
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 84.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-21-26-35--polyglot-o1mini-whole
|
||||
test_cases: 225
|
||||
model: o1-mini-2024-09-12
|
||||
edit_format: whole
|
||||
commit_hash: 37df899
|
||||
pass_rate_1: 5.8
|
||||
pass_rate_2: 32.9
|
||||
pass_num_1: 13
|
||||
pass_num_2: 74
|
||||
percent_cases_well_formed: 96.9
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 27
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
total_tests: 225
|
||||
command: aider --model o1-mini
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.7
|
||||
total_cost: 18.5770
|
||||
|
||||
- dirname: 2024-12-22-18-43-25--gemini-exp-1206-polyglot-whole-2
|
||||
test_cases: 225
|
||||
model: gemini-exp-1206
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 19.6
|
||||
pass_rate_2: 38.2
|
||||
pass_num_1: 44
|
||||
pass_num_2: 86
|
||||
percent_cases_well_formed: 98.2
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 4
|
||||
user_asks: 32
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-exp-1206
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 45.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-22-20-08-13--gemini-2.0-flash-exp-polyglot-whole
|
||||
test_cases: 225
|
||||
model: gemini-2.0-flash-exp
|
||||
edit_format: whole
|
||||
commit_hash: b1bc2f8
|
||||
pass_rate_1: 11.6
|
||||
pass_rate_2: 22.2
|
||||
pass_num_1: 26
|
||||
pass_num_2: 50
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 9
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-2.0-flash-exp
|
||||
date: 2024-12-22
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 12.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-23-01-11-56--yi-test
|
||||
test_cases: 225
|
||||
model: yi-lightning
|
||||
edit_format: whole
|
||||
commit_hash: 2b1625e
|
||||
pass_rate_1: 5.8
|
||||
pass_rate_2: 12.9
|
||||
pass_num_1: 13
|
||||
pass_num_2: 29
|
||||
percent_cases_well_formed: 92.9
|
||||
error_outputs: 87
|
||||
num_malformed_responses: 72
|
||||
num_with_malformed_responses: 16
|
||||
user_asks: 107
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 6
|
||||
total_tests: 225
|
||||
command: aider --model openai/yi-lightning
|
||||
date: 2024-12-23
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 146.7
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-12-25-13-31-51--deepseekv3preview-diff2
|
||||
test_cases: 225
|
||||
model: DeepSeek Chat V3
|
||||
edit_format: diff
|
||||
commit_hash: 0a23c4a-dirty
|
||||
pass_rate_1: 22.7
|
||||
pass_rate_2: 48.4
|
||||
pass_num_1: 51
|
||||
pass_num_2: 109
|
||||
percent_cases_well_formed: 98.7
|
||||
error_outputs: 7
|
||||
num_malformed_responses: 7
|
||||
num_with_malformed_responses: 3
|
||||
user_asks: 19
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-chat
|
||||
date: 2024-12-25
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.8
|
||||
total_cost: 0.3369
|
||||
|
||||
- dirname: 2024-12-26-00-55-20--Qwen2.5-Coder-32B-Instruct
|
||||
test_cases: 225
|
||||
model: Qwen2.5-Coder-32B-Instruct
|
||||
edit_format: whole
|
||||
commit_hash: b51768b0
|
||||
pass_rate_1: 4.9
|
||||
pass_rate_2: 16.4
|
||||
pass_num_1: 11
|
||||
pass_num_2: 37
|
||||
percent_cases_well_formed: 99.6
|
||||
error_outputs: 1
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 33
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 6
|
||||
total_tests: 225
|
||||
command: aider --model openai/Qwen2.5-Coder-32B-Instruct
|
||||
date: 2024-12-26
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 42.0
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2025-01-13-18-17-25--codestral-whole2
|
||||
test_cases: 225
|
||||
model: Codestral 25.01
|
||||
edit_format: whole
|
||||
commit_hash: 0cba898-dirty
|
||||
pass_rate_1: 4.0
|
||||
pass_rate_2: 11.1
|
||||
pass_num_1: 9
|
||||
pass_num_2: 25
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 0
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 47
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 4
|
||||
total_tests: 225
|
||||
command: aider --model mistral/codestral-latest
|
||||
date: 2025-01-13
|
||||
versions: 0.71.2.dev
|
||||
seconds_per_case: 9.3
|
||||
total_cost: 1.9834
|
||||
|
||||
- dirname: 2025-01-20-19-11-38--ds-turns-upd-cur-msgs-fix-with-summarizer
|
||||
test_cases: 225
|
||||
model: DeepSeek R1
|
||||
edit_format: diff
|
||||
commit_hash: 5650697-dirty
|
||||
pass_rate_1: 26.7
|
||||
pass_rate_2: 56.9
|
||||
pass_num_1: 60
|
||||
pass_num_2: 128
|
||||
percent_cases_well_formed: 96.9
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 7
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 15
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model deepseek/deepseek-reasoner
|
||||
date: 2025-01-20
|
||||
versions: 0.71.2.dev
|
||||
seconds_per_case: 113.7
|
||||
total_cost: 5.4193
|
||||
|
||||
- dirname: 2025-01-23-19-14-48--r1-architect-sonnet
|
||||
test_cases: 225
|
||||
model: DeepSeek R1 + claude-3-5-sonnet-20241022
|
||||
edit_format: architect
|
||||
commit_hash: 05a77c7
|
||||
editor_model: claude-3-5-sonnet-20241022
|
||||
editor_edit_format: editor-diff
|
||||
pass_rate_1: 27.1
|
||||
pass_rate_2: 64.0
|
||||
pass_num_1: 61
|
||||
pass_num_2: 144
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 2
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 392
|
||||
lazy_comments: 6
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --architect --model r1 --editor-model sonnet
|
||||
date: 2025-01-23
|
||||
versions: 0.72.3.dev
|
||||
seconds_per_case: 251.6
|
||||
total_cost: 13.2933
|
||||
|
||||
- dirname: 2025-01-28-16-00-03--qwen-max-2025-01-25-polyglot-diff
|
||||
test_cases: 225
|
||||
model: qwen-max-2025-01-25
|
||||
edit_format: diff
|
||||
commit_hash: ae7d459
|
||||
pass_rate_1: 9.3
|
||||
pass_rate_2: 21.8
|
||||
pass_num_1: 21
|
||||
pass_num_2: 49
|
||||
percent_cases_well_formed: 90.2
|
||||
error_outputs: 46
|
||||
num_malformed_responses: 44
|
||||
num_with_malformed_responses: 22
|
||||
user_asks: 23
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 9
|
||||
total_tests: 225
|
||||
command: OPENAI_API_BASE=https://dashscope-intl.aliyuncs.com/compatible-mode/v1 aider --model openai/qwen-max-2025-01-25
|
||||
date: 2025-01-28
|
||||
versions: 0.72.4.dev
|
||||
seconds_per_case: 39.5
|
||||
|
||||
- dirname: 2025-01-31-20-27-46--o3-mini-diff2
|
||||
test_cases: 225
|
||||
model: o3-mini (medium)
|
||||
edit_format: diff
|
||||
commit_hash: 2fb517b-dirty
|
||||
pass_rate_1: 19.1
|
||||
pass_rate_2: 53.8
|
||||
pass_num_1: 43
|
||||
pass_num_2: 121
|
||||
percent_cases_well_formed: 95.1
|
||||
error_outputs: 28
|
||||
num_malformed_responses: 28
|
||||
num_with_malformed_responses: 11
|
||||
user_asks: 17
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model o3-mini
|
||||
date: 2025-01-31
|
||||
versions: 0.72.4.dev
|
||||
seconds_per_case: 47.2
|
||||
total_cost: 8.8599
|
||||
|
||||
- dirname: 2025-01-31-20-42-47--o3-mini-diff-high
|
||||
test_cases: 224
|
||||
model: o3-mini (high)
|
||||
edit_format: diff
|
||||
commit_hash: b0d58d1-dirty
|
||||
pass_rate_1: 21.0
|
||||
pass_rate_2: 60.4
|
||||
pass_num_1: 47
|
||||
pass_num_2: 136
|
||||
percent_cases_well_formed: 93.3
|
||||
error_outputs: 26
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 15
|
||||
user_asks: 19
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 7
|
||||
total_tests: 225
|
||||
command: aider --model o3-mini --reasoning-effort high
|
||||
date: 2025-01-31
|
||||
versions: 0.72.4.dev
|
||||
seconds_per_case: 124.6
|
||||
total_cost: 18.1584
|
||||
|
||||
- dirname: 2025-01-21-22-51-49--gemini-2.0-flash-thinking-exp-01-21-polyglot-diff
|
||||
test_cases: 225
|
||||
model: gemini-2.0-flash-thinking-exp-01-21
|
||||
edit_format: diff
|
||||
commit_hash: 843720a
|
||||
pass_rate_1: 5.8
|
||||
pass_rate_2: 18.2
|
||||
pass_num_1: 13
|
||||
pass_num_2: 41
|
||||
percent_cases_well_formed: 77.8
|
||||
error_outputs: 182
|
||||
num_malformed_responses: 180
|
||||
num_with_malformed_responses: 50
|
||||
user_asks: 26
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 2
|
||||
test_timeouts: 7
|
||||
total_tests: 225
|
||||
command: aider --model gemini/gemini-2.0-flash-thinking-exp-01-21
|
||||
date: 2025-01-21
|
||||
versions: 0.72.2.dev
|
||||
seconds_per_case: 24.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2025-02-15-19-51-22--chatgpt4o-feb15-diff
|
||||
test_cases: 223
|
||||
model: chatgpt-4o-latest (2025-02-15)
|
||||
edit_format: diff
|
||||
commit_hash: 108ce18-dirty
|
||||
pass_rate_1: 9.0
|
||||
pass_rate_2: 27.1
|
||||
pass_num_1: 20
|
||||
pass_num_2: 61
|
||||
percent_cases_well_formed: 93.3
|
||||
error_outputs: 66
|
||||
num_malformed_responses: 21
|
||||
num_with_malformed_responses: 15
|
||||
user_asks: 57
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model chatgpt-4o-latest
|
||||
date: 2025-02-15
|
||||
versions: 0.74.3.dev
|
||||
seconds_per_case: 12.4
|
||||
total_cost: 14.3703
|
||||
|
||||
- dirname: 2025-02-24-19-54-07--sonnet37-diff
|
||||
test_cases: 225
|
||||
model: claude-3-7-sonnet-20250219 (no thinking)
|
||||
edit_format: diff
|
||||
commit_hash: 75e9ee6
|
||||
pass_rate_1: 24.4
|
||||
pass_rate_2: 60.4
|
||||
pass_num_1: 55
|
||||
pass_num_2: 136
|
||||
percent_cases_well_formed: 93.3
|
||||
error_outputs: 16
|
||||
num_malformed_responses: 16
|
||||
num_with_malformed_responses: 15
|
||||
user_asks: 12
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 0
|
||||
total_tests: 225
|
||||
command: aider --model sonnet
|
||||
date: 2025-02-24
|
||||
versions: 0.74.4.dev
|
||||
seconds_per_case: 28.3
|
||||
total_cost: 17.7191
|
||||
|
||||
- dirname: 2025-02-24-21-47-23--sonnet37-diff-think-32k-64k
|
||||
test_cases: 225
|
||||
model: claude-3-7-sonnet-20250219 (32k thinking tokens)
|
||||
edit_format: diff
|
||||
commit_hash: 60d11a6, 93edbda
|
||||
pass_rate_1: 29.3
|
||||
pass_rate_2: 64.9
|
||||
pass_num_1: 66
|
||||
pass_num_2: 146
|
||||
percent_cases_well_formed: 97.8
|
||||
error_outputs: 66
|
||||
num_malformed_responses: 5
|
||||
num_with_malformed_responses: 5
|
||||
user_asks: 5
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 1
|
||||
total_tests: 225
|
||||
command: "aider --model anthropic/claude-3-7-sonnet-20250219 # plus yml config"
|
||||
date: 2025-02-24
|
||||
versions: 0.75.1.dev
|
||||
seconds_per_case: 105.2
|
||||
total_cost: 36.8343
|
||||
|
||||
- dirname: 2025-02-27-20-26-15--gpt45-diff3
|
||||
test_cases: 224
|
||||
model: gpt-4.5-preview
|
||||
edit_format: diff
|
||||
commit_hash: b462e55-dirty
|
||||
pass_rate_1: 22.3
|
||||
pass_rate_2: 44.9
|
||||
pass_num_1: 50
|
||||
pass_num_2: 101
|
||||
percent_cases_well_formed: 97.3
|
||||
error_outputs: 10
|
||||
num_malformed_responses: 8
|
||||
num_with_malformed_responses: 6
|
||||
user_asks: 15
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model openai/gpt-4.5-preview
|
||||
date: 2025-02-27
|
||||
versions: 0.75.2.dev
|
||||
seconds_per_case: 113.5
|
||||
total_cost: 183.1802
|
||||
|
||||
- dirname: 2025-03-06-17-40-24--qwq32b-diff-temp-topp-ex-sys-remind-user-for-real
|
||||
test_cases: 225
|
||||
model: QwQ-32B
|
||||
edit_format: diff
|
||||
commit_hash: 51d118f-dirty
|
||||
pass_rate_1: 8.0
|
||||
pass_rate_2: 20.9
|
||||
pass_num_1: 18
|
||||
pass_num_2: 47
|
||||
percent_cases_well_formed: 67.6
|
||||
error_outputs: 145
|
||||
num_malformed_responses: 143
|
||||
num_with_malformed_responses: 73
|
||||
user_asks: 17
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 4
|
||||
total_tests: 225
|
||||
command: aider --model fireworks_ai/accounts/fireworks/models/qwq-32b
|
||||
date: 2025-03-06
|
||||
versions: 0.75.3.dev
|
||||
seconds_per_case: 228.6
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2025-03-07-15-11-27--qwq32b-arch-temp-topp-again
|
||||
test_cases: 225
|
||||
model: QwQ-32B + Qwen 2.5 Coder Instruct
|
||||
edit_format: architect
|
||||
commit_hash: 52162a5
|
||||
editor_model: fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct
|
||||
editor_edit_format: editor-diff
|
||||
pass_rate_1: 9.8
|
||||
pass_rate_2: 26.2
|
||||
pass_num_1: 22
|
||||
pass_num_2: 59
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 122
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 489
|
||||
lazy_comments: 8
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model fireworks_ai/accounts/fireworks/models/qwq-32b --architect
|
||||
date: 2025-03-07
|
||||
versions: 0.75.3.dev
|
||||
seconds_per_case: 137.4
|
||||
total_cost: 0
|
||||
322
aider/website/_data/quant.yml
Normal file
322
aider/website/_data/quant.yml
Normal file
@@ -0,0 +1,322 @@
|
||||
- dirname: 2024-11-09-11-09-15--Qwen2.5-Coder-32B-Instruct
|
||||
test_cases: 133
|
||||
model: "HuggingFace via GLHF: BF16"
|
||||
released: 2024-11-12
|
||||
edit_format: diff
|
||||
commit_hash: ec9982a
|
||||
pass_rate_1: 59.4
|
||||
pass_rate_2: 71.4
|
||||
percent_cases_well_formed: 94.7
|
||||
error_outputs: 17
|
||||
num_malformed_responses: 17
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 1
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model openai/hf:Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://glhf.chat/api/openai/v1
|
||||
date: 2024-11-09
|
||||
versions: 0.59.2.dev
|
||||
seconds_per_case: 22.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-22-18-56-13--ollama-qwen2.5-coder:32b-instruct-fp16
|
||||
test_cases: 132
|
||||
model: "Ollama: fp16"
|
||||
edit_format: diff
|
||||
commit_hash: f06452c-dirty, 6a0a97c-dirty, 4e9ae16-dirty, 5506d0f-dirty
|
||||
pass_rate_1: 58.3
|
||||
pass_rate_2: 71.4
|
||||
percent_cases_well_formed: 90.2
|
||||
error_outputs: 27
|
||||
num_malformed_responses: 26
|
||||
num_with_malformed_responses: 13
|
||||
user_asks: 2
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 0
|
||||
command: aider --model ollama/qwen2.5-coder:32b-instruct-fp16
|
||||
date: 2024-11-22
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 119.6
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-22-14-53-26--hyperbolic-qwen25coder32binstruct
|
||||
test_cases: 133
|
||||
model: "Hyperbolic: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: f9ef161, 17aef7b-dirty
|
||||
pass_rate_1: 57.9
|
||||
pass_rate_2: 69.2
|
||||
percent_cases_well_formed: 91.7
|
||||
error_outputs: 30
|
||||
num_malformed_responses: 29
|
||||
num_with_malformed_responses: 11
|
||||
user_asks: 9
|
||||
lazy_comments: 0
|
||||
syntax_errors: 4
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
command: aider --model openai/Qwen/Qwen2.5-Coder-32B-Instruct --openai-api-base https://api.hyperbolic.xyz/v1/
|
||||
date: 2024-11-22
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 33.2
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-22-17-53-35--qwen25-coder-32b-Instruct-4bit
|
||||
test_cases: 133
|
||||
model: "mlx-community: 4bit"
|
||||
edit_format: diff
|
||||
commit_hash: a16dcab-dirty
|
||||
pass_rate_1: 60.2
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 88.7
|
||||
error_outputs: 31
|
||||
num_malformed_responses: 30
|
||||
num_with_malformed_responses: 15
|
||||
user_asks: 6
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 0
|
||||
command: aider --model openai/mlx-community/Qwen2.5-Coder-32B-Instruct-4bit
|
||||
date: 2024-11-23
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 53.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-23-15-07-20--qwen25-coder-32b-Instruct-8bit
|
||||
test_cases: 133
|
||||
model: "mlx-community: 8bit"
|
||||
edit_format: diff
|
||||
commit_hash: a16dcab-dirty
|
||||
pass_rate_1: 59.4
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 92.5
|
||||
error_outputs: 20
|
||||
num_malformed_responses: 15
|
||||
num_with_malformed_responses: 10
|
||||
user_asks: 7
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 5
|
||||
test_timeouts: 2
|
||||
command: aider --model openai/mlx-community/Qwen2.5-Coder-32B-Instruct-8bit
|
||||
date: 2024-11-23
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 98.4
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-24-22-18-18--or-all-or-fixed-blank-messages2
|
||||
test_cases: 133
|
||||
model: "OpenRouter: multiple"
|
||||
edit_format: diff
|
||||
commit_hash: 0c59d32
|
||||
pass_rate_1: 57.1
|
||||
pass_rate_2: 67.7
|
||||
percent_cases_well_formed: 95.5
|
||||
error_outputs: 56
|
||||
num_malformed_responses: 10
|
||||
num_with_malformed_responses: 6
|
||||
user_asks: 14
|
||||
lazy_comments: 0
|
||||
syntax_errors: 6
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 3
|
||||
test_timeouts: 1
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 21.2
|
||||
total_cost: 0.1420
|
||||
|
||||
- dirname: 2024-11-23-21-08-53--ollama-qwen2.5-coder:32b-instruct-q4_K_M-8kctx
|
||||
test_cases: 133
|
||||
model: "Ollama: q4_K_M"
|
||||
edit_format: diff
|
||||
commit_hash: baa1335-dirty, e63df83-dirty, ff8c1aa-dirty
|
||||
pass_rate_1: 54.9
|
||||
pass_rate_2: 66.9
|
||||
percent_cases_well_formed: 94.0
|
||||
error_outputs: 21
|
||||
num_malformed_responses: 21
|
||||
num_with_malformed_responses: 8
|
||||
user_asks: 5
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 3
|
||||
command: aider --model ollama/qwen2.5-coder:32b-instruct-q4_K_M
|
||||
date: 2024-11-23
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 35.7
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-24-02-23-32--deepinfra-qwen-diff
|
||||
test_cases: 133
|
||||
model: "Deepinfra: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: bb78e2f
|
||||
pass_rate_1: 58.6
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 94.7
|
||||
error_outputs: 15
|
||||
num_malformed_responses: 13
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 3
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 2
|
||||
test_timeouts: 3
|
||||
command: aider --model deepinfra/Qwen/Qwen2.5-Coder-32B-Instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 17.5
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-24-04-12-58--fireworks-qwen-diff
|
||||
test_cases: 133
|
||||
model: "Fireworks: unknown"
|
||||
edit_format: diff
|
||||
commit_hash: 757eac0
|
||||
pass_rate_1: 57.9
|
||||
pass_rate_2: 72.2
|
||||
percent_cases_well_formed: 94.0
|
||||
error_outputs: 23
|
||||
num_malformed_responses: 19
|
||||
num_with_malformed_responses: 8
|
||||
user_asks: 8
|
||||
lazy_comments: 0
|
||||
syntax_errors: 6
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 4
|
||||
test_timeouts: 1
|
||||
command: aider --model fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 10.4
|
||||
total_cost: 0.5759
|
||||
|
||||
- dirname: 2024-11-24-02-04-59--ollama-qwen2.5-coder:32b-instruct-q2_K-8kctx
|
||||
test_cases: 133
|
||||
model: "Ollama: q2_K"
|
||||
edit_format: diff
|
||||
commit_hash: 757eac0, bb78e2f, 8d0ba40-dirty, 1d09e96
|
||||
pass_rate_1: 48.9
|
||||
pass_rate_2: 61.7
|
||||
percent_cases_well_formed: 91.7
|
||||
error_outputs: 32
|
||||
num_malformed_responses: 32
|
||||
num_with_malformed_responses: 11
|
||||
user_asks: 8
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 1
|
||||
command: aider --model ollama/qwen2.5-coder:32b-instruct-q2_K
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 97.8
|
||||
total_cost: 0.0000
|
||||
|
||||
- dirname: 2024-11-24-14-56-49--qwen25-32b-or-fireworks
|
||||
test_cases: 133
|
||||
model: "Fireworks via OpenRouter: unknown"
|
||||
edit_format: diff
|
||||
commit_hash: c2f184f
|
||||
pass_rate_1: 55.6
|
||||
pass_rate_2: 67.7
|
||||
percent_cases_well_formed: 94.0
|
||||
error_outputs: 39
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 8
|
||||
user_asks: 13
|
||||
lazy_comments: 0
|
||||
syntax_errors: 1
|
||||
indentation_errors: 1
|
||||
exhausted_context_windows: 7
|
||||
test_timeouts: 4
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 16.1
|
||||
total_cost: 0.1391
|
||||
|
||||
- dirname: 2024-11-24-22-03-19--or-hyperbolic-or-fixed-blank-messages2
|
||||
test_cases: 133
|
||||
model: "Hyperbolic via OpenRouter: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: 0c59d32
|
||||
pass_rate_1: 55.6
|
||||
pass_rate_2: 68.4
|
||||
percent_cases_well_formed: 89.5
|
||||
error_outputs: 28
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 14
|
||||
user_asks: 29
|
||||
lazy_comments: 0
|
||||
syntax_errors: 1
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 4
|
||||
test_timeouts: 1
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 41.5
|
||||
total_cost: 0.1402
|
||||
|
||||
- dirname: 2024-11-24-15-00-50--qwen25-32b-or-deepinfra
|
||||
test_cases: 133
|
||||
model: "Deepinfra via OpenRouter: BF16"
|
||||
edit_format: diff
|
||||
commit_hash: c2f184f
|
||||
pass_rate_1: 57.1
|
||||
pass_rate_2: 69.9
|
||||
percent_cases_well_formed: 89.5
|
||||
error_outputs: 35
|
||||
num_malformed_responses: 31
|
||||
num_with_malformed_responses: 14
|
||||
user_asks: 11
|
||||
lazy_comments: 0
|
||||
syntax_errors: 1
|
||||
indentation_errors: 1
|
||||
exhausted_context_windows: 4
|
||||
test_timeouts: 1
|
||||
command: aider --model openrouter/qwen/qwen-2.5-coder-32b-instruct
|
||||
date: 2024-11-24
|
||||
versions: 0.64.2.dev
|
||||
seconds_per_case: 28.5
|
||||
total_cost: 0.1390
|
||||
|
||||
- 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
|
||||
138
aider/website/_data/r1_architect.yml
Normal file
138
aider/website/_data/r1_architect.yml
Normal file
@@ -0,0 +1,138 @@
|
||||
|
||||
|
||||
|
||||
- dirname: 2025-01-23-19-14-48--r1-architect-sonnet
|
||||
test_cases: 225
|
||||
model: R1+Sonnet
|
||||
edit_format: architect
|
||||
commit_hash: 05a77c7
|
||||
editor_model: claude-3-5-sonnet-20241022
|
||||
editor_edit_format: editor-diff
|
||||
pass_rate_1: 27.1
|
||||
pass_rate_2: 64.0
|
||||
pass_num_1: 61
|
||||
pass_num_2: 144
|
||||
percent_cases_well_formed: 100.0
|
||||
error_outputs: 2
|
||||
num_malformed_responses: 0
|
||||
num_with_malformed_responses: 0
|
||||
user_asks: 392
|
||||
lazy_comments: 6
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --architect --model r1 --editor-model sonnet
|
||||
date: 2025-01-23
|
||||
versions: 0.72.3.dev
|
||||
seconds_per_case: 251.6
|
||||
total_cost: 13.2933
|
||||
|
||||
- dirname: 2025-01-20-19-11-38--ds-turns-upd-cur-msgs-fix-with-summarizer
|
||||
test_cases: 225
|
||||
model: R1
|
||||
edit_format: diff
|
||||
commit_hash: 5650697-dirty
|
||||
pass_rate_1: 26.7
|
||||
pass_rate_2: 56.9
|
||||
pass_num_1: 60
|
||||
pass_num_2: 128
|
||||
percent_cases_well_formed: 96.9
|
||||
error_outputs: 8
|
||||
num_malformed_responses: 7
|
||||
num_with_malformed_responses: 7
|
||||
user_asks: 15
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 5
|
||||
total_tests: 225
|
||||
command: aider --model r1
|
||||
date: 2025-01-20
|
||||
versions: 0.71.2.dev
|
||||
seconds_per_case: 113.7
|
||||
total_cost: 5.4193
|
||||
|
||||
|
||||
- dirname: 2024-12-21-19-23-03--polyglot-o1-hard-diff
|
||||
test_cases: 224
|
||||
model: o1
|
||||
edit_format: diff
|
||||
commit_hash: a755079-dirty
|
||||
pass_rate_1: 23.7
|
||||
pass_rate_2: 61.7
|
||||
pass_num_1: 53
|
||||
pass_num_2: 139
|
||||
percent_cases_well_formed: 91.5
|
||||
error_outputs: 25
|
||||
num_malformed_responses: 24
|
||||
num_with_malformed_responses: 19
|
||||
user_asks: 16
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 2
|
||||
total_tests: 225
|
||||
command: aider --model o1
|
||||
date: 2024-12-21
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 133.2
|
||||
total_cost: 186.4958
|
||||
|
||||
|
||||
- dirname: 2024-12-25-13-31-51--deepseekv3preview-diff2
|
||||
test_cases: 225
|
||||
model: DeepSeek V3
|
||||
edit_format: diff
|
||||
commit_hash: 0a23c4a-dirty
|
||||
pass_rate_1: 22.7
|
||||
pass_rate_2: 48.4
|
||||
pass_num_1: 51
|
||||
pass_num_2: 109
|
||||
percent_cases_well_formed: 98.7
|
||||
error_outputs: 7
|
||||
num_malformed_responses: 7
|
||||
num_with_malformed_responses: 3
|
||||
user_asks: 19
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 0
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model deepseek
|
||||
date: 2024-12-25
|
||||
versions: 0.69.2.dev
|
||||
seconds_per_case: 34.8
|
||||
total_cost: 0.3369
|
||||
|
||||
|
||||
|
||||
- dirname: 2025-01-17-19-44-33--sonnet-baseline-jan-17
|
||||
test_cases: 225
|
||||
model: Sonnet
|
||||
edit_format: diff
|
||||
commit_hash: 6451d59
|
||||
pass_rate_1: 22.2
|
||||
pass_rate_2: 51.6
|
||||
pass_num_1: 50
|
||||
pass_num_2: 116
|
||||
percent_cases_well_formed: 99.6
|
||||
error_outputs: 2
|
||||
num_malformed_responses: 1
|
||||
num_with_malformed_responses: 1
|
||||
user_asks: 11
|
||||
lazy_comments: 0
|
||||
syntax_errors: 0
|
||||
indentation_errors: 0
|
||||
exhausted_context_windows: 1
|
||||
test_timeouts: 8
|
||||
total_tests: 225
|
||||
command: aider --model sonnet
|
||||
date: 2025-01-17
|
||||
versions: 0.71.2.dev
|
||||
seconds_per_case: 21.4
|
||||
total_cost: 14.4063
|
||||
@@ -1,5 +1,18 @@
|
||||
<canvas id="blameChart" width="800" height="360" style="margin-top: 20px"></canvas>
|
||||
<canvas id="linesChart" width="800" height="360" style="margin-top: 20px"></canvas>
|
||||
<div class="chart-container">
|
||||
<canvas id="blameChart" style="margin-top: 20px"></canvas>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<canvas id="linesChart" style="margin-top: 20px"></canvas>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.chart-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
|
||||
@@ -24,10 +37,17 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
var linesData = {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: 'Aider\'s lines of new code',
|
||||
label: 'Aider',
|
||||
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.aider_total }} },{% endfor %}],
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.8)',
|
||||
borderColor: 'rgba(255, 99, 132, 1)',
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.8)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
},
|
||||
{
|
||||
label: 'Human',
|
||||
data: [{% for row in site.data.blame %}{ x: '{{ row.end_tag }}', y: {{ row.total_lines | minus: row.aider_total }} },{% endfor %}],
|
||||
backgroundColor: 'rgba(200, 200, 200, 0.8)',
|
||||
borderColor: 'rgba(200, 200, 200, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
@@ -36,6 +56,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
type: 'bar',
|
||||
data: blameData,
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
type: 'category',
|
||||
@@ -85,9 +106,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
type: 'bar',
|
||||
data: linesData,
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
type: 'category',
|
||||
stacked: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Version'
|
||||
@@ -98,6 +121,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
},
|
||||
y: {
|
||||
stacked: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Lines of new code'
|
||||
@@ -107,12 +131,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
display: true,
|
||||
position: 'chartArea',
|
||||
reverse: true
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
var label = 'New lines of code by aider';
|
||||
var label = context.dataset.label;
|
||||
var value = context.parsed.y || 0;
|
||||
return `${label}: ${value}`;
|
||||
}
|
||||
@@ -120,7 +146,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Lines of new code written by aider, by release',
|
||||
text: 'Lines of new code, by release',
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
|
||||
@@ -1,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,25 @@
|
||||
|
||||
You can get started quickly like this:
|
||||
If you already have python 3.8-3.13 installed, you can get started quickly like this:
|
||||
|
||||
```
|
||||
python -m pip install -U aider-chat
|
||||
|
||||
# Change directory into a git repo
|
||||
cd /to/your/git/repo
|
||||
|
||||
# Work with Claude 3.5 Sonnet on your repo
|
||||
export ANTHROPIC_API_KEY=your-key-goes-here
|
||||
aider
|
||||
|
||||
# Work with GPT-4o on your repo
|
||||
export OPENAI_API_KEY=your-key-goes-here
|
||||
aider
|
||||
```bash
|
||||
python -m pip install aider-install
|
||||
aider-install
|
||||
|
||||
# Change directory into your code base
|
||||
cd /to/your/project
|
||||
|
||||
# Work with DeepSeek via DeepSeek's API
|
||||
aider --model deepseek --api-key deepseek=your-key-goes-here
|
||||
|
||||
# Work with Claude 3.7 Sonnet via Anthropic's API
|
||||
aider --model sonnet --api-key anthropic=your-key-goes-here
|
||||
|
||||
# Work with GPT-4o via OpenAI's API
|
||||
aider --model gpt-4o --api-key openai=your-key-goes-here
|
||||
|
||||
# Work with Sonnet via OpenRouter's API
|
||||
aider --model openrouter/anthropic/claude-3.7-sonnet --api-key openrouter=your-key-goes-here
|
||||
|
||||
# Work with DeepSeek via OpenRouter's API
|
||||
aider --model openrouter/deepseek/deepseek-chat --api-key openrouter=your-key-goes-here
|
||||
```
|
||||
|
||||
@@ -18,3 +18,65 @@
|
||||
<link rel="mask-icon" href="{{ '/assets/icons/safari-pinned-tab.svg' | relative_url }}" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
{% if site.analytics.enabled %}
|
||||
<!-- Cookie Consent -->
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/cookieconsent@3/build/cookieconsent.min.js" data-cfasync="false"></script>
|
||||
<script>
|
||||
window.addEventListener('load', function(){
|
||||
window.cookieconsent.initialise({
|
||||
palette: {
|
||||
popup: {
|
||||
background: "#333333",
|
||||
text: "#ffffff"
|
||||
},
|
||||
button: {
|
||||
background: "#ffffff",
|
||||
text: "#333333"
|
||||
}
|
||||
},
|
||||
type: "opt-in",
|
||||
position: "bottom-left",
|
||||
showLink: false,
|
||||
dismissOnScroll: true,
|
||||
cookie: {
|
||||
name: 'cookieconsent_status',
|
||||
path: '/',
|
||||
domain: 'aider.chat',
|
||||
expiryDays: 365
|
||||
},
|
||||
content: {
|
||||
message: "This website uses analytics cookies to help us understand how you use the site.",
|
||||
dismiss: "Decline",
|
||||
allow: "Accept",
|
||||
link: "Learn more",
|
||||
href: "https://aider.chat/docs/legal/privacy.html"
|
||||
},
|
||||
onInitialise: function(status) {
|
||||
var type = this.options.type;
|
||||
var didConsent = this.hasConsented();
|
||||
if (didConsent) {
|
||||
initPostHog();
|
||||
}
|
||||
},
|
||||
onStatusChange: function(status, chosenBefore) {
|
||||
var type = this.options.type;
|
||||
var didConsent = this.hasConsented();
|
||||
if (didConsent) {
|
||||
initPostHog();
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// PostHog initialization function
|
||||
function initPostHog() {
|
||||
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
||||
posthog.init('{{ site.analytics.posthog_key }}', {
|
||||
api_host: '{{ site.analytics.posthog_host }}',
|
||||
person_profiles: 'identified_only'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
4
aider/website/_includes/keys.md
Normal file
4
aider/website/_includes/keys.md
Normal file
@@ -0,0 +1,4 @@
|
||||
{: .tip :}
|
||||
See the
|
||||
[API key configuration docs](/docs/config/api-keys.html)
|
||||
for information on how to configure and store your API keys.
|
||||
237
aider/website/_includes/leaderboard.js
Normal file
237
aider/website/_includes/leaderboard.js
Normal file
@@ -0,0 +1,237 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var ctx = document.getElementById('editChart').getContext('2d');
|
||||
const blueDiagonalPattern = pattern.draw('diagonal', 'rgba(54, 162, 235, 0.2)');
|
||||
const redDiagonalPattern = pattern.draw('diagonal', 'rgba(255, 99, 132, 0.2)');
|
||||
let displayedData = [];
|
||||
|
||||
const HIGHLIGHT_MODEL = '{{ highlight_model | default: "no no no" }}';
|
||||
var leaderboardData = {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'Percent completed correctly',
|
||||
data: [],
|
||||
backgroundColor: function(context) {
|
||||
const row = allData[context.dataIndex];
|
||||
if (row && row.edit_format === 'whole') {
|
||||
return diagonalPattern;
|
||||
}
|
||||
const label = leaderboardData.labels[context.dataIndex] || '';
|
||||
return (label && label.includes(HIGHLIGHT_MODEL)) ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)';
|
||||
},
|
||||
borderColor: function(context) {
|
||||
const label = context.chart.data.labels[context.dataIndex] || '';
|
||||
return (label && label.includes(HIGHLIGHT_MODEL)) ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)';
|
||||
},
|
||||
borderWidth: 1
|
||||
}, {
|
||||
label: 'Total Cost ($)',
|
||||
data: [],
|
||||
type: 'scatter',
|
||||
yAxisID: 'y1',
|
||||
backgroundColor: 'rgba(153, 102, 255, 1)',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 1,
|
||||
pointRadius: 5,
|
||||
pointHoverRadius: 7
|
||||
}]
|
||||
};
|
||||
|
||||
var allData = [];
|
||||
{% for row in data_source %}
|
||||
allData.push({
|
||||
model: '{{ row.model }}',
|
||||
pass_rate: {{ row[pass_rate_field] }},
|
||||
percent_cases_well_formed: {{ row.percent_cases_well_formed }},
|
||||
edit_format: '{{ row.edit_format | default: "diff" }}',
|
||||
total_cost: {{ row.total_cost | default: 0 }}
|
||||
});
|
||||
{% endfor %}
|
||||
|
||||
function updateChart() {
|
||||
var selectedRows = document.querySelectorAll('tr.selected');
|
||||
var showAll = selectedRows.length === 0;
|
||||
|
||||
displayedData = [];
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
leaderboardData.datasets[1].data = [];
|
||||
|
||||
allData.forEach(function(row, index) {
|
||||
var rowElement = document.getElementById('edit-row-' + index);
|
||||
if (showAll) {
|
||||
rowElement.classList.remove('selected');
|
||||
}
|
||||
if (showAll || rowElement.classList.contains('selected')) {
|
||||
displayedData.push(row);
|
||||
leaderboardData.labels.push(row.model);
|
||||
leaderboardData.datasets[0].data.push(row.pass_rate);
|
||||
// Only include cost if it's not zero (placeholder for unknown)
|
||||
leaderboardData.datasets[1].data.push(row.total_cost > 0 ? row.total_cost : null);
|
||||
}
|
||||
});
|
||||
|
||||
leaderboardChart.update();
|
||||
leaderboardChart.render();
|
||||
}
|
||||
|
||||
// Use displayedData in the backgroundColor callback instead of allData
|
||||
leaderboardData.datasets[0].backgroundColor = function(context) {
|
||||
const row = displayedData[context.dataIndex];
|
||||
const label = leaderboardData.labels[context.dataIndex] || '';
|
||||
if (label && label.includes(HIGHLIGHT_MODEL)) {
|
||||
if (row && row.edit_format === 'whole') return redDiagonalPattern;
|
||||
else return 'rgba(255, 99, 132, 0.2)';
|
||||
} else if (row && row.edit_format === 'whole') {
|
||||
return blueDiagonalPattern;
|
||||
} else {
|
||||
return 'rgba(54, 162, 235, 0.2)';
|
||||
}
|
||||
};
|
||||
|
||||
var tableBody = document.querySelector('table tbody');
|
||||
allData.forEach(function(row, index) {
|
||||
var tr = tableBody.children[index];
|
||||
if (!tr) {
|
||||
// If the row doesn't exist, create it
|
||||
tr = document.createElement('tr');
|
||||
tableBody.appendChild(tr);
|
||||
}
|
||||
tr.id = 'edit-row-' + index;
|
||||
tr.style.cursor = 'pointer';
|
||||
tr.onclick = function() {
|
||||
this.classList.toggle('selected');
|
||||
updateChart();
|
||||
};
|
||||
});
|
||||
|
||||
var leaderboardChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: leaderboardData,
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: {% if show_legend == false %}false{% else %}true{% endif %},
|
||||
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
|
||||
},
|
||||
{
|
||||
text: 'Total Cost ($)',
|
||||
fillStyle: 'rgba(153, 102, 255, 1)',
|
||||
strokeStyle: '#fff',
|
||||
lineWidth: 1,
|
||||
pointStyle: 'circle'
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
const datasetLabel = context.dataset.label || '';
|
||||
const value = context.parsed.y;
|
||||
if (datasetLabel === 'Total Cost ($)') {
|
||||
return datasetLabel + ': $' + value.toFixed(2);
|
||||
}
|
||||
return datasetLabel + ': ' + value.toFixed(1) + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Percent completed correctly'
|
||||
}
|
||||
},
|
||||
y1: {
|
||||
beginAtZero: true,
|
||||
position: 'right',
|
||||
grid: {
|
||||
drawOnChartArea: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Total Cost ($)'
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
callback: function(value, index) {
|
||||
const label = this.getLabelForValue(value);
|
||||
if (label.length <= "claude-3-5-sonnet".length) {
|
||||
return label;
|
||||
}
|
||||
|
||||
// Find all possible split positions
|
||||
const splitPositions = [];
|
||||
for (let i = 0; i < label.length; i++) {
|
||||
if (label[i] === '-' || label[i] === ' ') {
|
||||
splitPositions.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (splitPositions.length === 0) {
|
||||
return label;
|
||||
}
|
||||
|
||||
// Find split position closest to middle
|
||||
const middle = label.length / 2;
|
||||
const splitIndex = splitPositions.reduce((closest, current) => {
|
||||
return Math.abs(current - middle) < Math.abs(closest - middle) ? current : closest;
|
||||
});
|
||||
|
||||
return [
|
||||
label.slice(0, splitIndex),
|
||||
label.slice(splitIndex + 1)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateChart();
|
||||
|
||||
// Add search functionality for edit table
|
||||
document.getElementById('editSearchInput').addEventListener('keyup', function() {
|
||||
var searchWords = this.value.toLowerCase().split(' ').filter(word => word.length > 0);
|
||||
var tableBody = document.querySelector('table:first-of-type tbody');
|
||||
var rows = tableBody.getElementsByTagName('tr');
|
||||
|
||||
displayedData = [];
|
||||
leaderboardData.labels = [];
|
||||
leaderboardData.datasets[0].data = [];
|
||||
leaderboardData.datasets[1].data = [];
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var rowText = rows[i].textContent;
|
||||
if (searchWords.every(word => rowText.toLowerCase().includes(word))) {
|
||||
rows[i].style.display = '';
|
||||
displayedData.push(allData[i]);
|
||||
leaderboardData.labels.push(allData[i].model);
|
||||
leaderboardData.datasets[0].data.push(allData[i].pass_rate);
|
||||
// Only include cost if it's not zero (placeholder for unknown)
|
||||
leaderboardData.datasets[1].data.push(allData[i].total_cost > 0 ? allData[i].total_cost : null);
|
||||
} else {
|
||||
rows[i].style.display = 'none';
|
||||
}
|
||||
}
|
||||
leaderboardChart.update();
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,22 @@
|
||||
You can send long, multi-line messages in the chat in a few ways:
|
||||
- Paste a multi-line message directly into the chat.
|
||||
- Enter `{` alone on the first line to start a multiline message and `}` alone on the last line to end it.
|
||||
- Or, start with `{tag` (where "tag" is any sequence of letters/numbers) and end with `tag}`. This is useful when you need to include closing braces `}` in your message.
|
||||
- Use Meta-ENTER to start a new line without sending the message (Esc+ENTER in some environments).
|
||||
- Use `/paste` to paste text from the clipboard into the chat.
|
||||
- Use the `/editor` command to open your editor to create the next chat message. See [editor configuration docs](/docs/config/editor.html) for more info.
|
||||
- Use multiline-mode, which swaps the function of Meta-Enter and Enter, so that Enter inserts a newline, and Meta-Enter submits your command. To enable multiline mode:
|
||||
- Use the `/multiline-mode` command to toggle it during a session.
|
||||
- Use the `--multiline` switch.
|
||||
|
||||
Example with a tag:
|
||||
```
|
||||
{python
|
||||
def hello():
|
||||
print("Hello}") # Note: contains a brace
|
||||
python}
|
||||
```
|
||||
|
||||
{: .note }
|
||||
People often ask for SHIFT-ENTER to be a soft-newline.
|
||||
Unfortunately there is no portable way to detect that keystroke in terminals.
|
||||
|
||||
95
aider/website/_includes/quant-chart.js
Normal file
95
aider/website/_includes/quant-chart.js
Normal file
@@ -0,0 +1,95 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var ctx = document.getElementById('quantChart').getContext('2d');
|
||||
var allData = [];
|
||||
{% for row in site.data.quant %}
|
||||
allData.push({
|
||||
model: '{{ row.model }}',
|
||||
pass_rate_2: {{ row.pass_rate_2 }}
|
||||
});
|
||||
{% endfor %}
|
||||
|
||||
// Sort data by pass_rate_2 in descending order
|
||||
allData.sort((a, b) => b.pass_rate_2 - a.pass_rate_2);
|
||||
|
||||
var chart;
|
||||
|
||||
function updateChart(filterText) {
|
||||
var filteredData = allData.filter(row =>
|
||||
row.model.toLowerCase().includes(filterText.toLowerCase())
|
||||
);
|
||||
|
||||
var chartData = {
|
||||
labels: filteredData.map(row => row.model),
|
||||
datasets: [{
|
||||
label: 'Percent completed correctly',
|
||||
data: filteredData.map(row => row.pass_rate_2),
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
||||
borderColor: 'rgba(54, 162, 235, 1)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
};
|
||||
|
||||
if (chart) {
|
||||
chart.data = chartData;
|
||||
chart.update();
|
||||
} else {
|
||||
chart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: chartData,
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Aider code editing benchmark',
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Percent completed correctly',
|
||||
font: {
|
||||
size: 14
|
||||
}
|
||||
},
|
||||
ticks: {
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
size: 16
|
||||
}
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Provider: quantization',
|
||||
font: {
|
||||
size: 14
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initial chart render
|
||||
updateChart('');
|
||||
|
||||
// Connect search input to chart filtering
|
||||
document.getElementById('quantSearchInput').addEventListener('keyup', function() {
|
||||
updateChart(this.value);
|
||||
});
|
||||
});
|
||||
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:
|
||||
|
||||
```
|
||||
```bash
|
||||
pip install pipx
|
||||
pipx run aider-chat ...normal aider args...
|
||||
```
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user