aider-ce 0.88.20__py3-none-any.whl → 0.88.38__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aider/__init__.py +1 -1
- aider/_version.py +2 -2
- aider/args.py +63 -43
- aider/coders/agent_coder.py +331 -79
- aider/coders/agent_prompts.py +3 -15
- aider/coders/architect_coder.py +21 -5
- aider/coders/base_coder.py +661 -413
- aider/coders/base_prompts.py +6 -3
- aider/coders/chat_chunks.py +39 -17
- aider/commands.py +79 -15
- aider/diffs.py +10 -9
- aider/exceptions.py +1 -1
- aider/helpers/coroutines.py +8 -0
- aider/helpers/requests.py +45 -0
- aider/history.py +5 -0
- aider/io.py +179 -25
- aider/main.py +86 -35
- aider/models.py +16 -8
- aider/queries/tree-sitter-language-pack/c-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/clojure-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/commonlisp-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/cpp-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/csharp-tags.scm +6 -0
- aider/queries/tree-sitter-language-pack/dart-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/elixir-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/elm-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/go-tags.scm +7 -0
- aider/queries/tree-sitter-language-pack/java-tags.scm +6 -0
- aider/queries/tree-sitter-language-pack/javascript-tags.scm +8 -0
- aider/queries/tree-sitter-language-pack/lua-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/python-tags.scm +10 -0
- aider/queries/tree-sitter-language-pack/r-tags.scm +6 -0
- aider/queries/tree-sitter-language-pack/ruby-tags.scm +5 -0
- aider/queries/tree-sitter-language-pack/rust-tags.scm +3 -0
- aider/queries/tree-sitter-language-pack/solidity-tags.scm +1 -1
- aider/queries/tree-sitter-language-pack/swift-tags.scm +4 -1
- aider/queries/tree-sitter-languages/c-tags.scm +3 -0
- aider/queries/tree-sitter-languages/c_sharp-tags.scm +6 -0
- aider/queries/tree-sitter-languages/cpp-tags.scm +3 -0
- aider/queries/tree-sitter-languages/dart-tags.scm +2 -1
- aider/queries/tree-sitter-languages/elixir-tags.scm +5 -0
- aider/queries/tree-sitter-languages/elm-tags.scm +3 -0
- aider/queries/tree-sitter-languages/fortran-tags.scm +3 -0
- aider/queries/tree-sitter-languages/go-tags.scm +6 -0
- aider/queries/tree-sitter-languages/haskell-tags.scm +2 -0
- aider/queries/tree-sitter-languages/java-tags.scm +6 -0
- aider/queries/tree-sitter-languages/javascript-tags.scm +8 -0
- aider/queries/tree-sitter-languages/julia-tags.scm +2 -2
- aider/queries/tree-sitter-languages/kotlin-tags.scm +3 -0
- aider/queries/tree-sitter-languages/ocaml_interface-tags.scm +6 -0
- aider/queries/tree-sitter-languages/php-tags.scm +6 -0
- aider/queries/tree-sitter-languages/python-tags.scm +10 -0
- aider/queries/tree-sitter-languages/ruby-tags.scm +5 -0
- aider/queries/tree-sitter-languages/rust-tags.scm +3 -0
- aider/queries/tree-sitter-languages/scala-tags.scm +2 -3
- aider/queries/tree-sitter-languages/typescript-tags.scm +3 -0
- aider/queries/tree-sitter-languages/zig-tags.scm +20 -3
- aider/repomap.py +71 -11
- aider/resources/model-metadata.json +27335 -635
- aider/resources/model-settings.yml +190 -0
- aider/scrape.py +2 -0
- aider/tools/__init__.py +2 -0
- aider/tools/command.py +84 -94
- aider/tools/command_interactive.py +95 -110
- aider/tools/delete_block.py +131 -159
- aider/tools/delete_line.py +97 -132
- aider/tools/delete_lines.py +120 -160
- aider/tools/extract_lines.py +288 -312
- aider/tools/finished.py +30 -43
- aider/tools/git_branch.py +107 -109
- aider/tools/git_diff.py +44 -56
- aider/tools/git_log.py +39 -53
- aider/tools/git_remote.py +37 -51
- aider/tools/git_show.py +33 -47
- aider/tools/git_status.py +30 -44
- aider/tools/grep.py +214 -242
- aider/tools/indent_lines.py +175 -201
- aider/tools/insert_block.py +220 -253
- aider/tools/list_changes.py +65 -80
- aider/tools/ls.py +64 -80
- aider/tools/make_editable.py +57 -73
- aider/tools/make_readonly.py +50 -66
- aider/tools/remove.py +64 -80
- aider/tools/replace_all.py +96 -109
- aider/tools/replace_line.py +118 -156
- aider/tools/replace_lines.py +160 -197
- aider/tools/replace_text.py +159 -160
- aider/tools/show_numbered_context.py +115 -141
- aider/tools/thinking.py +52 -0
- aider/tools/undo_change.py +78 -91
- aider/tools/update_todo_list.py +130 -138
- aider/tools/utils/base_tool.py +64 -0
- aider/tools/utils/output.py +118 -0
- aider/tools/view.py +38 -54
- aider/tools/view_files_matching.py +131 -134
- aider/tools/view_files_with_symbol.py +108 -120
- aider/urls.py +1 -1
- aider/versioncheck.py +4 -3
- aider/website/docs/config/adv-model-settings.md +237 -0
- aider/website/docs/config/agent-mode.md +36 -3
- aider/website/docs/config/model-aliases.md +2 -1
- aider/website/docs/faq.md +6 -11
- aider/website/docs/languages.md +2 -2
- aider/website/docs/more/infinite-output.md +27 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/METADATA +112 -70
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/RECORD +112 -107
- aider_ce-0.88.38.dist-info/entry_points.txt +6 -0
- aider_ce-0.88.20.dist-info/entry_points.txt +0 -2
- /aider/tools/{tool_utils.py → utils/helpers.py} +0 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/WHEEL +0 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/licenses/LICENSE.txt +0 -0
- {aider_ce-0.88.20.dist-info → aider_ce-0.88.38.dist-info}/top_level.txt +0 -0
aider/coders/base_prompts.py
CHANGED
|
@@ -77,11 +77,14 @@ The user is going to provide you with a conversation.
|
|
|
77
77
|
This conversation is getting too long to fit in the context window of a language model.
|
|
78
78
|
You need to summarize the conversation to reduce its length, while retaining all the important information.
|
|
79
79
|
|
|
80
|
-
The summary should contain
|
|
80
|
+
The summary should contain four parts:
|
|
81
81
|
- Overall Goal: What is the user trying to achieve with this conversation?
|
|
82
82
|
- Next Steps: What are the next steps for the language model to take to help the user?
|
|
83
|
-
|
|
84
|
-
-
|
|
83
|
+
Describe the current investigation path and intention.
|
|
84
|
+
- Key Findings: Keep information most important to prevent having to search for it again
|
|
85
|
+
This should be quite specific (e/g. relevant files, method names, relevant lines of code, and code structure)
|
|
86
|
+
- Active files: What files are currently most relevant to the discussion?
|
|
87
|
+
Be confident in proceeding with any in progress edits.
|
|
85
88
|
|
|
86
89
|
Here is the conversation so far:
|
|
87
90
|
"""
|
aider/coders/chat_chunks.py
CHANGED
|
@@ -10,20 +10,34 @@ class ChatChunks:
|
|
|
10
10
|
repo: List = field(default_factory=list)
|
|
11
11
|
readonly_files: List = field(default_factory=list)
|
|
12
12
|
chat_files: List = field(default_factory=list)
|
|
13
|
+
edit_files: List = field(default_factory=list)
|
|
13
14
|
cur: List = field(default_factory=list)
|
|
14
15
|
reminder: List = field(default_factory=list)
|
|
16
|
+
chunk_ordering: List = field(default_factory=list)
|
|
17
|
+
|
|
18
|
+
def __init__(self, chunk_ordering=None):
|
|
19
|
+
self.chunk_ordering = chunk_ordering
|
|
15
20
|
|
|
16
21
|
def all_messages(self):
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
if self.chunk_ordering:
|
|
23
|
+
messages = []
|
|
24
|
+
for chunk_name in self.chunk_ordering:
|
|
25
|
+
chunk = getattr(self, chunk_name, [])
|
|
26
|
+
if chunk:
|
|
27
|
+
messages.extend(chunk)
|
|
28
|
+
return messages
|
|
29
|
+
else:
|
|
30
|
+
return (
|
|
31
|
+
self.format_list(self.system)
|
|
32
|
+
+ self.format_list(self.examples)
|
|
33
|
+
+ self.format_list(self.readonly_files)
|
|
34
|
+
+ self.format_list(self.chat_files)
|
|
35
|
+
+ self.format_list(self.repo)
|
|
36
|
+
+ self.format_list(self.done)
|
|
37
|
+
+ self.format_list(self.edit_files)
|
|
38
|
+
+ self.format_list(self.cur)
|
|
39
|
+
+ self.format_list(self.reminder)
|
|
40
|
+
)
|
|
27
41
|
|
|
28
42
|
def add_cache_control_headers(self):
|
|
29
43
|
if self.examples:
|
|
@@ -31,15 +45,17 @@ class ChatChunks:
|
|
|
31
45
|
else:
|
|
32
46
|
self.add_cache_control(self.system)
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
else:
|
|
38
|
-
# otherwise, just cache readonly_files if there are any
|
|
39
|
-
self.add_cache_control(self.readonly_files)
|
|
40
|
-
|
|
48
|
+
# The files form a cacheable block.
|
|
49
|
+
# The block starts with readonly_files and ends with chat_files.
|
|
50
|
+
# So we mark the end of chat_files.
|
|
41
51
|
self.add_cache_control(self.chat_files)
|
|
42
52
|
|
|
53
|
+
# The repo map is its own cacheable block.
|
|
54
|
+
self.add_cache_control(self.repo)
|
|
55
|
+
|
|
56
|
+
# The history is ephemeral on its own.
|
|
57
|
+
self.add_cache_control(self.done)
|
|
58
|
+
|
|
43
59
|
def add_cache_control(self, messages):
|
|
44
60
|
if not messages:
|
|
45
61
|
return
|
|
@@ -62,3 +78,9 @@ class ChatChunks:
|
|
|
62
78
|
):
|
|
63
79
|
return messages[: len(messages) - i]
|
|
64
80
|
return messages
|
|
81
|
+
|
|
82
|
+
def format_list(self, chunk):
|
|
83
|
+
if type(chunk) is not list:
|
|
84
|
+
return []
|
|
85
|
+
|
|
86
|
+
return chunk
|
aider/commands.py
CHANGED
|
@@ -89,7 +89,8 @@ class Commands:
|
|
|
89
89
|
async def cmd_model(self, args):
|
|
90
90
|
"Switch the Main Model to a new LLM"
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
arg_split = args.split(" ", 1)
|
|
93
|
+
model_name = arg_split[0].strip()
|
|
93
94
|
if not model_name:
|
|
94
95
|
announcements = "\n".join(self.coder.get_announcements())
|
|
95
96
|
self.io.tool_output(announcements)
|
|
@@ -111,19 +112,57 @@ class Commands:
|
|
|
111
112
|
# If the user was using the old model's default, switch to the new model's default
|
|
112
113
|
new_edit_format = model.edit_format
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
if len(arg_split) > 1:
|
|
116
|
+
# implement architect coder-like generation call for model
|
|
117
|
+
message = arg_split[1].strip()
|
|
115
118
|
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
# Store the original model configuration
|
|
120
|
+
original_main_model = self.coder.main_model
|
|
121
|
+
original_edit_format = self.coder.edit_format
|
|
118
122
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
# Create a temporary coder with the new model
|
|
124
|
+
from aider.coders import Coder
|
|
125
|
+
|
|
126
|
+
kwargs = dict()
|
|
127
|
+
kwargs["main_model"] = model
|
|
128
|
+
kwargs["edit_format"] = new_edit_format
|
|
129
|
+
kwargs["suggest_shell_commands"] = False
|
|
130
|
+
kwargs["total_cost"] = self.coder.total_cost
|
|
131
|
+
kwargs["num_cache_warming_pings"] = 0
|
|
132
|
+
kwargs["summarize_from_coder"] = False
|
|
133
|
+
|
|
134
|
+
new_kwargs = dict(io=self.io, from_coder=self.coder)
|
|
135
|
+
new_kwargs.update(kwargs)
|
|
136
|
+
|
|
137
|
+
temp_coder = await Coder.create(**new_kwargs)
|
|
138
|
+
temp_coder.cur_messages = []
|
|
139
|
+
temp_coder.done_messages = []
|
|
140
|
+
|
|
141
|
+
if self.verbose:
|
|
142
|
+
temp_coder.show_announcements()
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
await temp_coder.generate(user_message=message, preproc=False)
|
|
146
|
+
self.coder.move_back_cur_messages(
|
|
147
|
+
f"Model {model_name} made those changes to the files."
|
|
148
|
+
)
|
|
149
|
+
self.coder.total_cost = temp_coder.total_cost
|
|
150
|
+
self.coder.aider_commit_hashes = temp_coder.aider_commit_hashes
|
|
151
|
+
|
|
152
|
+
# Restore the original model configuration
|
|
153
|
+
raise SwitchCoder(main_model=original_main_model, edit_format=original_edit_format)
|
|
154
|
+
except Exception as e:
|
|
155
|
+
# If there's an error, still restore the original model
|
|
156
|
+
if not isinstance(e, SwitchCoder):
|
|
157
|
+
self.io.tool_error(e)
|
|
158
|
+
raise SwitchCoder(
|
|
159
|
+
main_model=original_main_model, edit_format=original_edit_format
|
|
160
|
+
)
|
|
161
|
+
else:
|
|
162
|
+
# Re-raise SwitchCoder if that's what was thrown
|
|
163
|
+
raise
|
|
164
|
+
else:
|
|
165
|
+
raise SwitchCoder(main_model=model, edit_format=new_edit_format)
|
|
127
166
|
|
|
128
167
|
async def cmd_weak_model(self, args):
|
|
129
168
|
"Switch the Weak Model to a new LLM"
|
|
@@ -414,7 +453,6 @@ class Commands:
|
|
|
414
453
|
)
|
|
415
454
|
|
|
416
455
|
lint_coder.add_rel_fname(fname)
|
|
417
|
-
await self.coder.io.recreate_input()
|
|
418
456
|
await lint_coder.run_one(errors, preproc=False)
|
|
419
457
|
lint_coder.abs_fnames = set()
|
|
420
458
|
|
|
@@ -999,6 +1037,22 @@ class Commands:
|
|
|
999
1037
|
if hasattr(self.coder, "_calculate_context_block_tokens"):
|
|
1000
1038
|
self.coder._calculate_context_block_tokens()
|
|
1001
1039
|
|
|
1040
|
+
if self.coder.repo_map:
|
|
1041
|
+
map_tokens = self.coder.repo_map.max_map_tokens
|
|
1042
|
+
map_mul_no_files = self.coder.repo_map.map_mul_no_files
|
|
1043
|
+
else:
|
|
1044
|
+
map_tokens = 0
|
|
1045
|
+
map_mul_no_files = 1
|
|
1046
|
+
|
|
1047
|
+
raise SwitchCoder(
|
|
1048
|
+
edit_format=self.coder.edit_format,
|
|
1049
|
+
summarize_from_coder=False,
|
|
1050
|
+
from_coder=self.coder,
|
|
1051
|
+
map_tokens=map_tokens,
|
|
1052
|
+
map_mul_no_files=map_mul_no_files,
|
|
1053
|
+
show_announcements=False,
|
|
1054
|
+
)
|
|
1055
|
+
|
|
1002
1056
|
def completions_drop(self):
|
|
1003
1057
|
files = self.coder.get_inchat_relative_files()
|
|
1004
1058
|
read_only_files = [
|
|
@@ -1095,7 +1149,7 @@ class Commands:
|
|
|
1095
1149
|
matched_files = [
|
|
1096
1150
|
self.coder.get_rel_fname(f)
|
|
1097
1151
|
for f in self.coder.abs_fnames
|
|
1098
|
-
if expanded_word in f
|
|
1152
|
+
if self.coder.abs_root_path(expanded_word) in f
|
|
1099
1153
|
]
|
|
1100
1154
|
|
|
1101
1155
|
if not matched_files:
|
|
@@ -1498,6 +1552,9 @@ class Commands:
|
|
|
1498
1552
|
|
|
1499
1553
|
from aider.coders.base_coder import Coder
|
|
1500
1554
|
|
|
1555
|
+
original_main_model = self.coder.main_model
|
|
1556
|
+
original_edit_format = self.coder.edit_format
|
|
1557
|
+
|
|
1501
1558
|
coder = await Coder.create(
|
|
1502
1559
|
io=self.io,
|
|
1503
1560
|
from_coder=self.coder,
|
|
@@ -1508,9 +1565,16 @@ class Commands:
|
|
|
1508
1565
|
)
|
|
1509
1566
|
|
|
1510
1567
|
user_msg = args
|
|
1511
|
-
await coder.
|
|
1568
|
+
await coder.generate(user_message=user_msg, preproc=False)
|
|
1512
1569
|
self.coder.aider_commit_hashes = coder.aider_commit_hashes
|
|
1513
1570
|
|
|
1571
|
+
raise SwitchCoder(
|
|
1572
|
+
main_model=original_main_model,
|
|
1573
|
+
edit_format=original_edit_format,
|
|
1574
|
+
done_messages=coder.done_messages,
|
|
1575
|
+
cur_messages=coder.cur_messages,
|
|
1576
|
+
)
|
|
1577
|
+
|
|
1514
1578
|
def get_help_md(self):
|
|
1515
1579
|
"Show help about all commands in markdown"
|
|
1516
1580
|
|
aider/diffs.py
CHANGED
|
@@ -63,17 +63,18 @@ def diff_partial_update(lines_orig, lines_updated, final=False, fname=None):
|
|
|
63
63
|
if last_non_deleted is None:
|
|
64
64
|
return ""
|
|
65
65
|
|
|
66
|
-
if num_orig_lines:
|
|
67
|
-
|
|
68
|
-
else:
|
|
69
|
-
|
|
70
|
-
bar = create_progress_bar(pct)
|
|
71
|
-
bar = f" {last_non_deleted:3d} / {num_orig_lines:3d} lines [{bar}] {pct:3.0f}%\n"
|
|
66
|
+
# if num_orig_lines:
|
|
67
|
+
# pct = last_non_deleted * 100 / num_orig_lines
|
|
68
|
+
# else:
|
|
69
|
+
# pct = 50
|
|
70
|
+
# bar = create_progress_bar(pct)
|
|
71
|
+
# bar = f" {last_non_deleted:3d} / {num_orig_lines:3d} lines [{bar}] {pct:3.0f}%\n"
|
|
72
72
|
|
|
73
73
|
lines_orig = lines_orig[:last_non_deleted]
|
|
74
74
|
|
|
75
75
|
if not final:
|
|
76
|
-
lines_updated = lines_updated[:-1] + [bar]
|
|
76
|
+
# lines_updated = lines_updated[:-1] + [bar]
|
|
77
|
+
lines_updated = lines_updated[:-1]
|
|
77
78
|
|
|
78
79
|
diff = difflib.unified_diff(lines_orig, lines_updated, n=5)
|
|
79
80
|
|
|
@@ -88,14 +89,14 @@ def diff_partial_update(lines_orig, lines_updated, final=False, fname=None):
|
|
|
88
89
|
if backticks not in diff:
|
|
89
90
|
break
|
|
90
91
|
|
|
91
|
-
show =
|
|
92
|
+
show = "diff\n"
|
|
92
93
|
if fname:
|
|
93
94
|
show += f"--- {fname} original\n"
|
|
94
95
|
show += f"+++ {fname} updated\n"
|
|
95
96
|
|
|
96
97
|
show += diff
|
|
97
98
|
|
|
98
|
-
show +=
|
|
99
|
+
show += "\n\n"
|
|
99
100
|
|
|
100
101
|
# print(diff)
|
|
101
102
|
|
aider/exceptions.py
CHANGED
|
@@ -20,7 +20,7 @@ EXCEPTIONS = [
|
|
|
20
20
|
"The API provider is not able to authenticate you. Check your API key.",
|
|
21
21
|
),
|
|
22
22
|
ExInfo("AzureOpenAIError", True, None),
|
|
23
|
-
ExInfo("BadGatewayError",
|
|
23
|
+
ExInfo("BadGatewayError", True, None),
|
|
24
24
|
ExInfo("BadRequestError", False, None),
|
|
25
25
|
ExInfo("BudgetExceededError", True, None),
|
|
26
26
|
ExInfo(
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from ..sendchat import ensure_alternating_roles
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def thought_signature(model, messages):
|
|
5
|
+
# Add thought signatures for Vertex AI and Gemini models
|
|
6
|
+
if model.name.startswith("vertex_ai/") or model.name.startswith("gemini/"):
|
|
7
|
+
for msg in messages:
|
|
8
|
+
if "tool_calls" in msg:
|
|
9
|
+
tool_calls = msg["tool_calls"]
|
|
10
|
+
|
|
11
|
+
if tool_calls:
|
|
12
|
+
for call in tool_calls:
|
|
13
|
+
if not call:
|
|
14
|
+
continue
|
|
15
|
+
|
|
16
|
+
# Check if thought signature is missing in extra_content.google.thought_signature
|
|
17
|
+
if "provider_specific_fields" not in call:
|
|
18
|
+
call["provider_specific_fields"] = {}
|
|
19
|
+
if "thought_signature" not in call["provider_specific_fields"]:
|
|
20
|
+
call["provider_specific_fields"][
|
|
21
|
+
"thought_signature"
|
|
22
|
+
] = "skip_thought_signature_validator"
|
|
23
|
+
|
|
24
|
+
if "function_call" in msg:
|
|
25
|
+
call = msg["function_call"]
|
|
26
|
+
|
|
27
|
+
if not call:
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
# Check if thought signature is missing in extra_content.google.thought_signature
|
|
31
|
+
if "provider_specific_fields" not in call:
|
|
32
|
+
call["provider_specific_fields"] = {}
|
|
33
|
+
if "thought_signature" not in call["provider_specific_fields"]:
|
|
34
|
+
call["provider_specific_fields"][
|
|
35
|
+
"thought_signature"
|
|
36
|
+
] = "skip_thought_signature_validator"
|
|
37
|
+
|
|
38
|
+
return messages
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def model_request_parser(model, messages):
|
|
42
|
+
messages = thought_signature(model, messages)
|
|
43
|
+
messages = ensure_alternating_roles(messages)
|
|
44
|
+
|
|
45
|
+
return messages
|
aider/history.py
CHANGED
|
@@ -30,6 +30,11 @@ class ChatSummary:
|
|
|
30
30
|
sized.append((tokens, msg))
|
|
31
31
|
return sized
|
|
32
32
|
|
|
33
|
+
def count_tokens(self, messages):
|
|
34
|
+
sized = self.tokenize(messages)
|
|
35
|
+
total = sum(tokens for tokens, _msg in sized)
|
|
36
|
+
return total
|
|
37
|
+
|
|
33
38
|
async def summarize(self, messages, depth=0):
|
|
34
39
|
messages = await self.summarize_real(messages)
|
|
35
40
|
if messages and messages[-1]["role"] != "assistant":
|