Skip to content

Commit 2cd9e57

Browse files
committed
Merge branch 'main' of https://github.com/Aider-AI/aider
2 parents 4c380a4 + a94c4b4 commit 2cd9e57

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1902
-843
lines changed

Diff for: HISTORY.md

+30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
# Release history
22

3+
### main branch
4+
5+
- Added support for Claude 3.7 Sonnet models on OpenRouter, Bedrock and Vertex AI.
6+
- Aider wrote 47% of the code in this release.
7+
8+
### Aider v0.75.1
9+
10+
- Added support for `openrouter/anthropic/claude-3.7-sonnet`
11+
12+
### Aider v0.75.0
13+
14+
- Basic support for Claude 3.7 Sonnet
15+
- Use `--model sonnet` to use the new 3.7
16+
- Thinking support coming soon.
17+
- Bugfix to `/editor` command.
18+
- Aider wrote 46% of the code in this release.
19+
20+
### Aider v0.74.3
21+
22+
- Downgrade streamlit dependency to avoid threading bug.
23+
- Added support for tree-sitter language pack.
24+
- Added openrouter/o3-mini-high model configuration.
25+
- Added build.gradle.kts to special files for Kotlin project support, by Lucas Shadler.
26+
27+
### Aider v0.74.2
28+
29+
- Prevent more than one cache warming thread from becoming active.
30+
- Fixed continuation prompt ". " for multiline input.
31+
- Added HCL (Terraform) syntax support, by Warren Krewenki.
32+
333
### Aider v0.74.1
434

535
- Have o1 & o3-mini generate markdown by sending the magic "Formatting re-enabled." string.

Diff for: aider/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from packaging import version
22

3-
__version__ = "0.74.2.dev"
3+
__version__ = "0.75.2.dev"
44
safe_version = __version__
55

66
try:

Diff for: aider/args.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def get_parser(default_config_files, git_root):
4646
const=opus_model,
4747
help=f"Use {opus_model} model for the main chat",
4848
)
49-
sonnet_model = "claude-3-5-sonnet-20241022"
49+
sonnet_model = "anthropic/claude-3-7-sonnet-20250219"
5050
group.add_argument(
5151
"--sonnet",
5252
action="store_const",
@@ -823,6 +823,12 @@ def get_parser(default_config_files, git_root):
823823
"--editor",
824824
help="Specify which editor to use for the /editor command",
825825
)
826+
group.add_argument(
827+
"--install-tree-sitter-language-pack",
828+
action="store_true",
829+
help="Install the tree_sitter_language_pack (experimental)",
830+
default=False,
831+
)
826832

827833
return parser
828834

Diff for: aider/coders/base_coder.py

+1
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,7 @@ def warm_cache(self, chunks):
12071207
return
12081208

12091209
delay = 5 * 60 - 5
1210+
delay = float(os.environ.get("AIDER_CACHE_KEEPALIVE_DELAY", delay))
12101211
self.next_cache_warm = time.time() + delay
12111212
self.warming_pings_left = self.num_cache_warming_pings
12121213
self.cache_warming_chunks = chunks

Diff for: aider/commands.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ def cmd_tokens(self, args):
404404

405405
fence = "`" * 3
406406

407+
file_res = []
407408
# files
408409
for fname in self.coder.abs_fnames:
409410
relative_fname = self.coder.get_rel_fname(fname)
@@ -414,7 +415,7 @@ def cmd_tokens(self, args):
414415
# approximate
415416
content = f"{relative_fname}\n{fence}\n" + content + "{fence}\n"
416417
tokens = self.coder.main_model.token_count(content)
417-
res.append((tokens, f"{relative_fname}", "/drop to remove"))
418+
file_res.append((tokens, f"{relative_fname}", "/drop to remove"))
418419

419420
# read-only files
420421
for fname in self.coder.abs_read_only_fnames:
@@ -424,7 +425,10 @@ def cmd_tokens(self, args):
424425
# approximate
425426
content = f"{relative_fname}\n{fence}\n" + content + "{fence}\n"
426427
tokens = self.coder.main_model.token_count(content)
427-
res.append((tokens, f"{relative_fname} (read-only)", "/drop to remove"))
428+
file_res.append((tokens, f"{relative_fname} (read-only)", "/drop to remove"))
429+
430+
file_res.sort()
431+
res.extend(file_res)
428432

429433
self.io.tool_output(
430434
f"Approximate context window usage for {self.coder.main_model.name}, in tokens:"

Diff for: aider/editor.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010

1111
import os
1212
import platform
13-
import shlex
1413
import subprocess
1514
import tempfile
1615

1716
from rich.console import Console
1817

18+
from aider.dump import dump # noqa
19+
1920
DEFAULT_EDITOR_NIX = "vi"
2021
DEFAULT_EDITOR_OS_X = "vim"
2122
DEFAULT_EDITOR_WINDOWS = "notepad"
@@ -87,13 +88,13 @@ def get_environment_editor(default=None):
8788

8889
def discover_editor(editor_override=None):
8990
"""
90-
Discovers and returns the appropriate editor command as a list of arguments.
91+
Discovers and returns the appropriate editor command.
9192
9293
Handles cases where the editor command includes arguments, including quoted arguments
9394
with spaces (e.g. 'vim -c "set noswapfile"').
9495
95-
:return: A list of command parts ready for subprocess execution
96-
:rtype: list[str]
96+
:return: The editor command as a string
97+
:rtype: str
9798
"""
9899
system = platform.system()
99100
if system == "Windows":
@@ -102,14 +103,13 @@ def discover_editor(editor_override=None):
102103
default_editor = DEFAULT_EDITOR_OS_X
103104
else:
104105
default_editor = DEFAULT_EDITOR_NIX
106+
105107
if editor_override:
106108
editor = editor_override
107109
else:
108110
editor = get_environment_editor(default_editor)
109-
try:
110-
return shlex.split(editor)
111-
except ValueError as e:
112-
raise RuntimeError(f"Invalid editor command format '{editor}': {e}")
111+
112+
return editor
113113

114114

115115
def pipe_editor(input_data="", suffix=None, editor=None):
@@ -128,9 +128,10 @@ def pipe_editor(input_data="", suffix=None, editor=None):
128128
:rtype: str
129129
"""
130130
filepath = write_temp_file(input_data, suffix)
131-
command_parts = discover_editor(editor)
132-
command_parts.append(filepath)
133-
subprocess.call(command_parts)
131+
command_str = discover_editor(editor)
132+
command_str += " " + filepath
133+
134+
subprocess.call(command_str, shell=True)
134135
with open(filepath, "r") as f:
135136
output_data = f.read()
136137
try:

Diff for: aider/linter.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pathlib import Path
99

1010
from grep_ast import TreeContext, filename_to_lang
11-
from tree_sitter_languages import get_parser # noqa: E402
11+
from grep_ast.tsl import get_parser # noqa: E402
1212

1313
from aider.dump import dump # noqa: F401
1414
from aider.run_cmd import run_cmd_subprocess # noqa: F401

Diff for: aider/main.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,18 @@ def check_streamlit_install(io):
214214
)
215215

216216

217+
def install_tree_sitter_language_pack(io):
218+
return utils.check_pip_install_extra(
219+
io,
220+
"tree_sitter_language_pack",
221+
"Install tree_sitter_language_pack?",
222+
[
223+
"tree-sitter-language-pack==0.4.0",
224+
"tree-sitter==0.24.0",
225+
],
226+
)
227+
228+
217229
def write_streamlit_credentials():
218230
from streamlit.file_util import get_streamlit_file_path
219231

@@ -706,6 +718,11 @@ def get_io(pretty):
706718
analytics.event("exit", reason="Upgrade completed")
707719
return 0 if success else 1
708720

721+
if args.install_tree_sitter_language_pack:
722+
success = install_tree_sitter_language_pack(io)
723+
analytics.event("exit", reason="Install TSLP completed")
724+
return 0 if success else 1
725+
709726
if args.check_update:
710727
check_version(io, verbose=args.verbose)
711728

@@ -1060,7 +1077,7 @@ def get_io(pretty):
10601077

10611078
while True:
10621079
try:
1063-
coder.ok_to_warm_cache = True
1080+
coder.ok_to_warm_cache = bool(args.cache_keepalive_pings)
10641081
coder.run()
10651082
analytics.event("exit", reason="Completed main CLI coder.run")
10661083
return

Diff for: aider/models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
# Mapping of model aliases to their canonical names
7777
MODEL_ALIASES = {
7878
# Claude models
79-
"sonnet": "claude-3-5-sonnet-20241022",
79+
"sonnet": "anthropic/claude-3-7-sonnet-20250219",
8080
"haiku": "claude-3-5-haiku-20241022",
8181
"opus": "claude-3-opus-20240229",
8282
# GPT models
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
(
2+
(comment)* @doc
3+
.
4+
(method_definition
5+
name: (property_identifier) @name.definition.method) @definition.method
6+
(#not-eq? @name.definition.method "constructor")
7+
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
8+
(#select-adjacent! @doc @definition.method)
9+
)
10+
11+
(
12+
(comment)* @doc
13+
.
14+
[
15+
(class
16+
name: (_) @name.definition.class)
17+
(class_declaration
18+
name: (_) @name.definition.class)
19+
] @definition.class
20+
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
21+
(#select-adjacent! @doc @definition.class)
22+
)
23+
24+
(
25+
(comment)* @doc
26+
.
27+
[
28+
(function_expression
29+
name: (identifier) @name.definition.function)
30+
(function_declaration
31+
name: (identifier) @name.definition.function)
32+
(generator_function
33+
name: (identifier) @name.definition.function)
34+
(generator_function_declaration
35+
name: (identifier) @name.definition.function)
36+
] @definition.function
37+
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
38+
(#select-adjacent! @doc @definition.function)
39+
)
40+
41+
(
42+
(comment)* @doc
43+
.
44+
(lexical_declaration
45+
(variable_declarator
46+
name: (identifier) @name.definition.function
47+
value: [(arrow_function) (function_expression)]) @definition.function)
48+
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
49+
(#select-adjacent! @doc @definition.function)
50+
)
51+
52+
(
53+
(comment)* @doc
54+
.
55+
(variable_declaration
56+
(variable_declarator
57+
name: (identifier) @name.definition.function
58+
value: [(arrow_function) (function_expression)]) @definition.function)
59+
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
60+
(#select-adjacent! @doc @definition.function)
61+
)
62+
63+
(assignment_expression
64+
left: [
65+
(identifier) @name.definition.function
66+
(member_expression
67+
property: (property_identifier) @name.definition.function)
68+
]
69+
right: [(arrow_function) (function_expression)]
70+
) @definition.function
71+
72+
(pair
73+
key: (property_identifier) @name.definition.function
74+
value: [(arrow_function) (function_expression)]) @definition.function
75+
76+
(
77+
(call_expression
78+
function: (identifier) @name.reference.call) @reference.call
79+
(#not-match? @name.reference.call "^(require)$")
80+
)
81+
82+
(call_expression
83+
function: (member_expression
84+
property: (property_identifier) @name.reference.call)
85+
arguments: (_) @reference.call)
86+
87+
(new_expression
88+
constructor: (_) @name.reference.class) @reference.class
File renamed without changes.

Diff for: aider/repomap.py

+34-6
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,20 @@
2323

2424
# tree_sitter is throwing a FutureWarning
2525
warnings.simplefilter("ignore", category=FutureWarning)
26-
from tree_sitter_languages import get_language, get_parser # noqa: E402
26+
from grep_ast.tsl import USING_TSL_PACK, get_language, get_parser # noqa: E402
2727

2828
Tag = namedtuple("Tag", "rel_fname fname line name kind".split())
2929

3030

3131
SQLITE_ERRORS = (sqlite3.OperationalError, sqlite3.DatabaseError, OSError)
3232

3333

34+
CACHE_VERSION = 3
35+
if USING_TSL_PACK:
36+
CACHE_VERSION = 4
37+
38+
3439
class RepoMap:
35-
CACHE_VERSION = 3
3640
TAGS_CACHE_DIR = f".aider.tags.cache.v{CACHE_VERSION}"
3741

3842
warned_files = set()
@@ -282,10 +286,15 @@ def get_tags_raw(self, fname, rel_fname):
282286
query = language.query(query_scm)
283287
captures = query.captures(tree.root_node)
284288

285-
captures = list(captures)
286-
287289
saw = set()
288-
for node, tag in captures:
290+
if USING_TSL_PACK:
291+
all_nodes = []
292+
for tag, nodes in captures.items():
293+
all_nodes += [(node, tag) for node in nodes]
294+
else:
295+
all_nodes = list(captures)
296+
297+
for node, tag in all_nodes:
289298
if tag.startswith("name.definition."):
290299
kind = "def"
291300
elif tag.startswith("name.reference."):
@@ -732,8 +741,27 @@ def get_random_color():
732741

733742
def get_scm_fname(lang):
734743
# Load the tags queries
744+
if USING_TSL_PACK:
745+
subdir = "tree-sitter-language-pack"
746+
try:
747+
path = resources.files(__package__).joinpath(
748+
"queries",
749+
subdir,
750+
f"{lang}-tags.scm",
751+
)
752+
if path.exists():
753+
return path
754+
except KeyError:
755+
pass
756+
757+
# Fall back to tree-sitter-languages
758+
subdir = "tree-sitter-languages"
735759
try:
736-
return resources.files(__package__).joinpath("queries", f"tree-sitter-{lang}-tags.scm")
760+
return resources.files(__package__).joinpath(
761+
"queries",
762+
subdir,
763+
f"{lang}-tags.scm",
764+
)
737765
except KeyError:
738766
return
739767

0 commit comments

Comments
 (0)