auto-coder 0.1.233__py3-none-any.whl → 0.1.237__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.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- {auto_coder-0.1.233.dist-info → auto_coder-0.1.237.dist-info}/METADATA +2 -3
- {auto_coder-0.1.233.dist-info → auto_coder-0.1.237.dist-info}/RECORD +24 -21
- autocoder/auto_coder.py +68 -35
- autocoder/chat_auto_coder.py +107 -84
- autocoder/chat_auto_coder_lang.py +69 -17
- autocoder/common/__init__.py +3 -0
- autocoder/common/auto_coder_lang.py +141 -0
- autocoder/common/code_auto_merge.py +12 -9
- autocoder/common/code_auto_merge_diff.py +5 -4
- autocoder/common/code_auto_merge_editblock.py +35 -33
- autocoder/common/code_auto_merge_strict_diff.py +5 -4
- autocoder/common/code_modification_ranker.py +74 -44
- autocoder/common/printer.py +49 -0
- autocoder/dispacher/actions/action.py +68 -19
- autocoder/dispacher/actions/plugins/action_regex_project.py +5 -0
- autocoder/index/entry.py +57 -14
- autocoder/index/filter/quick_filter.py +7 -6
- autocoder/index/index.py +54 -16
- autocoder/utils/types.py +0 -0
- autocoder/version.py +1 -1
- {auto_coder-0.1.233.dist-info → auto_coder-0.1.237.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.233.dist-info → auto_coder-0.1.237.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.233.dist-info → auto_coder-0.1.237.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.233.dist-info → auto_coder-0.1.237.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.panel import Panel
|
|
3
|
+
from rich.text import Text
|
|
4
|
+
from typing import Optional,Dict,Any
|
|
5
|
+
from byzerllm.utils import format_str_jinja2
|
|
6
|
+
from autocoder.common.auto_coder_lang import get_message
|
|
7
|
+
from autocoder.chat_auto_coder_lang import get_message as get_chat_message
|
|
8
|
+
class Printer:
|
|
9
|
+
def __init__(self,console:Optional[Console]=None):
|
|
10
|
+
if console is None:
|
|
11
|
+
self.console = Console()
|
|
12
|
+
else:
|
|
13
|
+
self.console = console
|
|
14
|
+
|
|
15
|
+
def get_message_from_key(self, msg_key: str):
|
|
16
|
+
try:
|
|
17
|
+
return get_message(msg_key)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
return get_chat_message(msg_key)
|
|
20
|
+
|
|
21
|
+
def get_message_from_key_with_format(self, msg_key: str, **kwargs):
|
|
22
|
+
try:
|
|
23
|
+
return format_str_jinja2(self.get_message_from_key(msg_key), **kwargs)
|
|
24
|
+
except Exception as e:
|
|
25
|
+
return format_str_jinja2(self.get_chat_message_from_key(msg_key), **kwargs)
|
|
26
|
+
|
|
27
|
+
def print_in_terminal(self, msg_key: str, style: str = None,**kwargs):
|
|
28
|
+
try:
|
|
29
|
+
if style:
|
|
30
|
+
self.console.print(format_str_jinja2(self.get_message_from_key(msg_key),**kwargs), style=style)
|
|
31
|
+
else:
|
|
32
|
+
self.console.print(format_str_jinja2(self.get_message_from_key(msg_key),**kwargs))
|
|
33
|
+
except Exception as e:
|
|
34
|
+
print(self.get_message_from_key(msg_key))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def print_str_in_terminal(self, content: str, style: str = None):
|
|
38
|
+
try:
|
|
39
|
+
if style:
|
|
40
|
+
self.console.print(content, style=style)
|
|
41
|
+
else:
|
|
42
|
+
self.console.print(content)
|
|
43
|
+
except Exception as e:
|
|
44
|
+
print(content)
|
|
45
|
+
|
|
46
|
+
def print_panel(self, content: str, text_options:Dict[str,Any], panel_options:Dict[str,Any]):
|
|
47
|
+
panel = Panel(Text(content, **text_options), **panel_options)
|
|
48
|
+
self.console.print(panel)
|
|
49
|
+
|
|
@@ -25,9 +25,10 @@ from autocoder.common.image_to_page import ImageToPage, ImageToPageDirectly
|
|
|
25
25
|
from autocoder.utils.conversation_store import store_code_model_conversation
|
|
26
26
|
from loguru import logger
|
|
27
27
|
import time
|
|
28
|
+
from autocoder.common.printer import Printer
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
class BaseAction:
|
|
31
|
+
class BaseAction:
|
|
31
32
|
def _get_content_length(self, content: str) -> int:
|
|
32
33
|
try:
|
|
33
34
|
tokenizer = BuildinTokenizer()
|
|
@@ -43,6 +44,7 @@ class ActionTSProject(BaseAction):
|
|
|
43
44
|
self.args = args
|
|
44
45
|
self.llm = llm
|
|
45
46
|
self.pp = None
|
|
47
|
+
self.printer = Printer()
|
|
46
48
|
|
|
47
49
|
def run(self):
|
|
48
50
|
args = self.args
|
|
@@ -54,9 +56,14 @@ class ActionTSProject(BaseAction):
|
|
|
54
56
|
|
|
55
57
|
source_code = pp.output()
|
|
56
58
|
if self.llm:
|
|
59
|
+
if args.in_code_apply:
|
|
60
|
+
old_query = args.query
|
|
61
|
+
args.query = (args.context or "") + "\n\n" + args.query
|
|
57
62
|
source_code = build_index_and_filter_files(
|
|
58
63
|
llm=self.llm, args=args, sources=pp.sources
|
|
59
64
|
)
|
|
65
|
+
if args.in_code_apply:
|
|
66
|
+
args.query = old_query
|
|
60
67
|
|
|
61
68
|
if args.image_file:
|
|
62
69
|
if args.image_mode == "iterative":
|
|
@@ -91,8 +98,8 @@ class ActionTSProject(BaseAction):
|
|
|
91
98
|
f"Content(send to model) is {content_length} tokens, which is larger than the maximum input length {self.args.model_max_input_length}"
|
|
92
99
|
)
|
|
93
100
|
|
|
94
|
-
if args.execute:
|
|
95
|
-
|
|
101
|
+
if args.execute:
|
|
102
|
+
self.printer.print_in_terminal("code_generation_start")
|
|
96
103
|
start_time = time.time()
|
|
97
104
|
if args.auto_merge == "diff":
|
|
98
105
|
generate = CodeAutoGenerateDiff(
|
|
@@ -116,10 +123,15 @@ class ActionTSProject(BaseAction):
|
|
|
116
123
|
generate_result = generate.single_round_run(
|
|
117
124
|
query=args.query, source_content=content
|
|
118
125
|
)
|
|
119
|
-
|
|
126
|
+
self.printer.print_in_terminal(
|
|
127
|
+
"code_generation_complete",
|
|
128
|
+
duration=time.time() - start_time,
|
|
129
|
+
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
130
|
+
output_tokens=generate_result.metadata.get('generated_tokens_count', 0)
|
|
131
|
+
)
|
|
120
132
|
merge_result = None
|
|
121
133
|
if args.execute and args.auto_merge:
|
|
122
|
-
|
|
134
|
+
self.printer.print_in_terminal("code_merge_start")
|
|
123
135
|
if args.auto_merge == "diff":
|
|
124
136
|
code_merge = CodeAutoMergeDiff(llm=self.llm, args=self.args)
|
|
125
137
|
merge_result = code_merge.merge_code(generate_result=generate_result)
|
|
@@ -160,6 +172,7 @@ class ActionPyScriptProject(BaseAction):
|
|
|
160
172
|
) -> None:
|
|
161
173
|
self.args = args
|
|
162
174
|
self.llm = llm
|
|
175
|
+
self.printer = Printer()
|
|
163
176
|
|
|
164
177
|
def run(self) -> bool:
|
|
165
178
|
args = self.args
|
|
@@ -175,7 +188,7 @@ class ActionPyScriptProject(BaseAction):
|
|
|
175
188
|
def process_content(self, content: str):
|
|
176
189
|
args = self.args
|
|
177
190
|
if args.execute:
|
|
178
|
-
|
|
191
|
+
self.printer.print_in_terminal("code_generation_start")
|
|
179
192
|
start_time = time.time()
|
|
180
193
|
if args.auto_merge == "diff":
|
|
181
194
|
generate = CodeAutoGenerateDiff(
|
|
@@ -200,10 +213,15 @@ class ActionPyScriptProject(BaseAction):
|
|
|
200
213
|
query=args.query, source_content=content
|
|
201
214
|
)
|
|
202
215
|
|
|
203
|
-
|
|
216
|
+
self.printer.print_in_terminal(
|
|
217
|
+
"code_generation_complete",
|
|
218
|
+
duration=time.time() - start_time,
|
|
219
|
+
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
220
|
+
output_tokens=generate_result.metadata.get('generated_tokens_count', 0)
|
|
221
|
+
)
|
|
204
222
|
merge_result = None
|
|
205
223
|
if args.execute and args.auto_merge:
|
|
206
|
-
|
|
224
|
+
self.printer.print_in_terminal("code_merge_start")
|
|
207
225
|
if args.auto_merge == "diff":
|
|
208
226
|
code_merge = CodeAutoMergeDiff(llm=self.llm, args=self.args)
|
|
209
227
|
merge_result = code_merge.merge_code(generate_result=generate_result)
|
|
@@ -236,7 +254,12 @@ class ActionPyScriptProject(BaseAction):
|
|
|
236
254
|
)
|
|
237
255
|
|
|
238
256
|
end_time = time.time()
|
|
239
|
-
|
|
257
|
+
self.printer.print_in_terminal(
|
|
258
|
+
"code_generation_complete",
|
|
259
|
+
duration=end_time - start_time,
|
|
260
|
+
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
261
|
+
output_tokens=generate_result.metadata.get('generated_tokens_count', 0)
|
|
262
|
+
)
|
|
240
263
|
with open(self.args.target_file, "w") as file:
|
|
241
264
|
file.write(content)
|
|
242
265
|
|
|
@@ -248,6 +271,7 @@ class ActionPyProject(BaseAction):
|
|
|
248
271
|
self.args = args
|
|
249
272
|
self.llm = llm
|
|
250
273
|
self.pp = None
|
|
274
|
+
self.printer = Printer()
|
|
251
275
|
|
|
252
276
|
def run(self):
|
|
253
277
|
args = self.args
|
|
@@ -256,11 +280,17 @@ class ActionPyProject(BaseAction):
|
|
|
256
280
|
pp = PyProject(args=self.args, llm=self.llm)
|
|
257
281
|
self.pp = pp
|
|
258
282
|
pp.run(packages=args.py_packages.split(",") if args.py_packages else [])
|
|
259
|
-
source_code = pp.output()
|
|
283
|
+
source_code = pp.output()
|
|
284
|
+
|
|
260
285
|
if self.llm:
|
|
286
|
+
old_query = args.query
|
|
287
|
+
if args.in_code_apply:
|
|
288
|
+
args.query = (args.context or "") + "\n\n" + args.query
|
|
261
289
|
source_code = build_index_and_filter_files(
|
|
262
290
|
llm=self.llm, args=args, sources=pp.sources
|
|
263
291
|
)
|
|
292
|
+
if args.in_code_apply:
|
|
293
|
+
args.query = old_query
|
|
264
294
|
|
|
265
295
|
self.process_content(source_code)
|
|
266
296
|
return True
|
|
@@ -271,12 +301,15 @@ class ActionPyProject(BaseAction):
|
|
|
271
301
|
if args.execute and self.llm and not args.human_as_model:
|
|
272
302
|
content_length = self._get_content_length(content)
|
|
273
303
|
if content_length > self.args.model_max_input_length:
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
304
|
+
self.printer.print_in_terminal(
|
|
305
|
+
"code_execution_warning",
|
|
306
|
+
style="yellow",
|
|
307
|
+
content_length=content_length,
|
|
308
|
+
max_length=self.args.model_max_input_length
|
|
309
|
+
)
|
|
277
310
|
|
|
278
311
|
if args.execute:
|
|
279
|
-
|
|
312
|
+
self.printer.print_in_terminal("code_generation_start")
|
|
280
313
|
start_time = time.time()
|
|
281
314
|
if args.auto_merge == "diff":
|
|
282
315
|
generate = CodeAutoGenerateDiff(
|
|
@@ -302,10 +335,15 @@ class ActionPyProject(BaseAction):
|
|
|
302
335
|
generate_result = generate.single_round_run(
|
|
303
336
|
query=args.query, source_content=content
|
|
304
337
|
)
|
|
305
|
-
|
|
338
|
+
self.printer.print_in_terminal(
|
|
339
|
+
"code_generation_complete",
|
|
340
|
+
duration=time.time() - start_time,
|
|
341
|
+
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
342
|
+
output_tokens=generate_result.metadata.get('generated_tokens_count', 0)
|
|
343
|
+
)
|
|
306
344
|
merge_result = None
|
|
307
345
|
if args.execute and args.auto_merge:
|
|
308
|
-
|
|
346
|
+
self.printer.print_in_terminal("code_merge_start")
|
|
309
347
|
if args.auto_merge == "diff":
|
|
310
348
|
code_merge = CodeAutoMergeDiff(llm=self.llm, args=self.args)
|
|
311
349
|
merge_result = code_merge.merge_code(generate_result=generate_result)
|
|
@@ -347,6 +385,7 @@ class ActionSuffixProject(BaseAction):
|
|
|
347
385
|
self.args = args
|
|
348
386
|
self.llm = llm
|
|
349
387
|
self.pp = None
|
|
388
|
+
self.printer = Printer()
|
|
350
389
|
|
|
351
390
|
def run(self):
|
|
352
391
|
args = self.args
|
|
@@ -355,9 +394,14 @@ class ActionSuffixProject(BaseAction):
|
|
|
355
394
|
pp.run()
|
|
356
395
|
source_code = pp.output()
|
|
357
396
|
if self.llm:
|
|
397
|
+
if args.in_code_apply:
|
|
398
|
+
old_query = args.query
|
|
399
|
+
args.query = (args.context or "") + "\n\n" + args.query
|
|
358
400
|
source_code = build_index_and_filter_files(
|
|
359
401
|
llm=self.llm, args=args, sources=pp.sources
|
|
360
402
|
)
|
|
403
|
+
if args.in_code_apply:
|
|
404
|
+
args.query = old_query
|
|
361
405
|
self.process_content(source_code)
|
|
362
406
|
|
|
363
407
|
def process_content(self, content: str):
|
|
@@ -371,7 +415,7 @@ class ActionSuffixProject(BaseAction):
|
|
|
371
415
|
)
|
|
372
416
|
|
|
373
417
|
if args.execute:
|
|
374
|
-
|
|
418
|
+
self.printer.print_in_terminal("code_generation_start")
|
|
375
419
|
start_time = time.time()
|
|
376
420
|
if args.auto_merge == "diff":
|
|
377
421
|
generate = CodeAutoGenerateDiff(
|
|
@@ -396,10 +440,15 @@ class ActionSuffixProject(BaseAction):
|
|
|
396
440
|
query=args.query, source_content=content
|
|
397
441
|
)
|
|
398
442
|
|
|
399
|
-
|
|
443
|
+
self.printer.print_in_terminal(
|
|
444
|
+
"code_generation_complete",
|
|
445
|
+
duration=time.time() - start_time,
|
|
446
|
+
input_tokens=generate_result.metadata.get('input_tokens_count', 0),
|
|
447
|
+
output_tokens=generate_result.metadata.get('generated_tokens_count', 0)
|
|
448
|
+
)
|
|
400
449
|
merge_result = None
|
|
401
450
|
if args.execute and args.auto_merge:
|
|
402
|
-
|
|
451
|
+
self.printer.print_in_terminal("code_merge_start")
|
|
403
452
|
if args.auto_merge == "diff":
|
|
404
453
|
code_merge = CodeAutoMergeDiff(llm=self.llm, args=self.args)
|
|
405
454
|
merge_result = code_merge.merge_code(generate_result=generate_result)
|
|
@@ -36,9 +36,14 @@ class ActionRegexProject:
|
|
|
36
36
|
pp.run()
|
|
37
37
|
source_code = pp.output()
|
|
38
38
|
if self.llm:
|
|
39
|
+
if args.in_code_apply:
|
|
40
|
+
old_query = args.query
|
|
41
|
+
args.query = (args.context or "") + "\n\n" + args.query
|
|
39
42
|
source_code = build_index_and_filter_files(
|
|
40
43
|
llm=self.llm, args=args, sources=pp.sources
|
|
41
44
|
)
|
|
45
|
+
if args.in_code_apply:
|
|
46
|
+
args.query = old_query
|
|
42
47
|
self.process_content(source_code)
|
|
43
48
|
|
|
44
49
|
def process_content(self, content: str):
|
autocoder/index/entry.py
CHANGED
|
@@ -9,7 +9,7 @@ from rich.console import Console
|
|
|
9
9
|
from rich.table import Table
|
|
10
10
|
from rich.panel import Panel
|
|
11
11
|
|
|
12
|
-
from
|
|
12
|
+
from autocoder.common.printer import Printer
|
|
13
13
|
from autocoder.utils.queue_communicate import (
|
|
14
14
|
queue_communicate,
|
|
15
15
|
CommunicateEvent,
|
|
@@ -22,6 +22,7 @@ from autocoder.index.types import (
|
|
|
22
22
|
from autocoder.index.filter.quick_filter import QuickFilter
|
|
23
23
|
from autocoder.index.filter.normal_filter import NormalFilter
|
|
24
24
|
from autocoder.index.index import IndexManager
|
|
25
|
+
from loguru import logger
|
|
25
26
|
|
|
26
27
|
def build_index_and_filter_files(
|
|
27
28
|
llm, args: AutoCoderArgs, sources: List[SourceCode]
|
|
@@ -58,7 +59,8 @@ def build_index_and_filter_files(
|
|
|
58
59
|
final_files: Dict[str, TargetFile] = {}
|
|
59
60
|
|
|
60
61
|
# Phase 1: Process REST/RAG/Search sources
|
|
61
|
-
|
|
62
|
+
printer = Printer()
|
|
63
|
+
printer.print_in_terminal("phase1_processing_sources")
|
|
62
64
|
phase_start = time.monotonic()
|
|
63
65
|
for source in sources:
|
|
64
66
|
if source.tag in ["REST", "RAG", "SEARCH"]:
|
|
@@ -79,7 +81,7 @@ def build_index_and_filter_files(
|
|
|
79
81
|
)
|
|
80
82
|
)
|
|
81
83
|
|
|
82
|
-
|
|
84
|
+
printer.print_in_terminal("phase2_building_index")
|
|
83
85
|
phase_start = time.monotonic()
|
|
84
86
|
index_manager = IndexManager(llm=llm, sources=sources, args=args)
|
|
85
87
|
index_data = index_manager.build_index()
|
|
@@ -98,11 +100,14 @@ def build_index_and_filter_files(
|
|
|
98
100
|
})
|
|
99
101
|
)
|
|
100
102
|
)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
|
|
104
|
+
#MARK
|
|
105
|
+
printer.print_in_terminal("quick_filter_start", style="blue")
|
|
106
|
+
quick_filter = QuickFilter(index_manager,stats,sources)
|
|
103
107
|
final_files = quick_filter.filter(index_manager.read_index(),args.query)
|
|
104
108
|
|
|
105
109
|
if not final_files:
|
|
110
|
+
printer.print_in_terminal("normal_filter_start", style="blue")
|
|
106
111
|
normal_filter = NormalFilter(index_manager,stats,sources)
|
|
107
112
|
final_files = normal_filter.filter(index_manager.read_index(),args.query)
|
|
108
113
|
|
|
@@ -133,19 +138,48 @@ def build_index_and_filter_files(
|
|
|
133
138
|
|
|
134
139
|
return [file for file in result] if result else []
|
|
135
140
|
|
|
141
|
+
def shorten_path(path: str, keep_levels: int = 3) -> str:
|
|
142
|
+
"""
|
|
143
|
+
优化长路径显示,保留最后指定层级
|
|
144
|
+
示例:/a/b/c/d/e/f.py -> .../c/d/e/f.py
|
|
145
|
+
"""
|
|
146
|
+
parts = path.split(os.sep)
|
|
147
|
+
if len(parts) > keep_levels:
|
|
148
|
+
return ".../" + os.sep.join(parts[-keep_levels:])
|
|
149
|
+
return path
|
|
150
|
+
|
|
136
151
|
def print_selected(data):
|
|
137
152
|
console = Console()
|
|
153
|
+
|
|
154
|
+
# 获取终端宽度
|
|
155
|
+
console_width = console.width
|
|
138
156
|
|
|
139
157
|
table = Table(
|
|
140
158
|
title="Files Used as Context",
|
|
141
159
|
show_header=True,
|
|
142
160
|
header_style="bold magenta",
|
|
161
|
+
# 设置表格最大宽度为终端宽度(留 10 字符边距)
|
|
162
|
+
width=min(console_width - 10, 120),
|
|
163
|
+
expand=True
|
|
143
164
|
)
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
|
|
166
|
+
# 优化列配置
|
|
167
|
+
table.add_column("File Path",
|
|
168
|
+
style="cyan",
|
|
169
|
+
width=int((console_width - 10) * 0.6), # 分配 60% 宽度给文件路径
|
|
170
|
+
overflow="fold", # 自动折叠过长的路径
|
|
171
|
+
no_wrap=False) # 允许换行
|
|
172
|
+
|
|
173
|
+
table.add_column("Reason",
|
|
174
|
+
style="green",
|
|
175
|
+
width=int((console_width - 10) * 0.4), # 分配 40% 宽度给原因
|
|
176
|
+
no_wrap=False)
|
|
146
177
|
|
|
178
|
+
# 添加处理过的文件路径
|
|
147
179
|
for file, reason in data:
|
|
148
|
-
|
|
180
|
+
# 路径截取优化:保留最后 3 级路径
|
|
181
|
+
processed_path = shorten_path(file, keep_levels=3)
|
|
182
|
+
table.add_row(processed_path, reason)
|
|
149
183
|
|
|
150
184
|
panel = Panel(
|
|
151
185
|
table,
|
|
@@ -157,7 +191,7 @@ def build_index_and_filter_files(
|
|
|
157
191
|
console.print(panel)
|
|
158
192
|
|
|
159
193
|
# Phase 6: File selection and limitation
|
|
160
|
-
|
|
194
|
+
printer.print_in_terminal("phase6_file_selection")
|
|
161
195
|
phase_start = time.monotonic()
|
|
162
196
|
|
|
163
197
|
if args.index_filter_file_num > 0:
|
|
@@ -188,7 +222,7 @@ def build_index_and_filter_files(
|
|
|
188
222
|
stats["timings"]["file_selection"] = phase_end - phase_start
|
|
189
223
|
|
|
190
224
|
# Phase 7: Display results and prepare output
|
|
191
|
-
|
|
225
|
+
printer.print_in_terminal("phase7_preparing_output")
|
|
192
226
|
phase_start = time.monotonic()
|
|
193
227
|
try:
|
|
194
228
|
print_selected(
|
|
@@ -249,7 +283,7 @@ def build_index_and_filter_files(
|
|
|
249
283
|
|
|
250
284
|
# Print final statistics in a more structured way
|
|
251
285
|
summary = f"""
|
|
252
|
-
===
|
|
286
|
+
=== File Stat ===
|
|
253
287
|
• Total files scanned: {stats['total_files']}
|
|
254
288
|
• Files indexed: {stats['indexed_files']}
|
|
255
289
|
• Files filtered:
|
|
@@ -258,7 +292,7 @@ def build_index_and_filter_files(
|
|
|
258
292
|
- Relevance verified: {stats.get('verified_files', 0)}
|
|
259
293
|
• Final files selected: {stats['final_files']}
|
|
260
294
|
|
|
261
|
-
=== Time
|
|
295
|
+
=== Time Stat ===
|
|
262
296
|
• Index build: {stats['timings'].get('build_index', 0):.2f}s
|
|
263
297
|
• Quick filter: {stats['timings'].get('quick_filter', 0):.2f}s
|
|
264
298
|
• Normal filter:
|
|
@@ -267,9 +301,18 @@ def build_index_and_filter_files(
|
|
|
267
301
|
- Relevance check: {stats['timings']["normal_filter"].get('relevance_verification', 0):.2f}s
|
|
268
302
|
• File selection: {stats['timings'].get('file_selection', 0):.2f}s
|
|
269
303
|
• Total time: {total_time:.2f}s
|
|
270
|
-
|
|
304
|
+
|
|
271
305
|
"""
|
|
272
|
-
|
|
306
|
+
printer.print_panel(
|
|
307
|
+
summary,
|
|
308
|
+
text_options={"justify": "left", "style": "bold white"},
|
|
309
|
+
panel_options={
|
|
310
|
+
"title": "Indexing and Filtering Summary",
|
|
311
|
+
"border_style": "bold blue",
|
|
312
|
+
"padding": (1, 2),
|
|
313
|
+
"expand": False
|
|
314
|
+
}
|
|
315
|
+
)
|
|
273
316
|
|
|
274
317
|
if args.request_id and not args.skip_events:
|
|
275
318
|
queue_communicate.send_event(
|
|
@@ -55,7 +55,10 @@ class QuickFilter():
|
|
|
55
55
|
}
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
特别注意
|
|
59
|
+
1. 如果用户的query里 @文件 或者 @@符号,那么被@的文件或者@@的符号必须要返回,并且查看他们依赖的文件是否相关。
|
|
60
|
+
2. 如果 query 里是一段历史对话,那么对话里的内容提及的文件路径必须要返回。
|
|
61
|
+
3. json格式数据不允许有注释
|
|
59
62
|
'''
|
|
60
63
|
file_meta_str = "\n".join([f"##[{index}]{item.module_name}\n{item.symbols}" for index,item in enumerate(file_meta_list)])
|
|
61
64
|
context = {
|
|
@@ -66,15 +69,13 @@ class QuickFilter():
|
|
|
66
69
|
|
|
67
70
|
def filter(self, index_items: List[IndexItem], query: str) -> Dict[str, TargetFile]:
|
|
68
71
|
final_files: Dict[str, TargetFile] = {}
|
|
69
|
-
if not self.args.skip_filter_index and self.
|
|
72
|
+
if not self.args.skip_filter_index and self.index_manager.llm.get_sub_client("index_filter_model"):
|
|
70
73
|
start_time = time.monotonic()
|
|
71
74
|
index_items = self.index_manager.read_index()
|
|
72
75
|
|
|
73
|
-
prompt_str = self.quick_filter_files.prompt(index_items,query)
|
|
74
|
-
|
|
75
|
-
print(prompt_str)
|
|
76
|
+
prompt_str = self.quick_filter_files.prompt(index_items,query)
|
|
76
77
|
|
|
77
|
-
tokens_len = count_tokens(prompt_str)
|
|
78
|
+
tokens_len = count_tokens(prompt_str)
|
|
78
79
|
|
|
79
80
|
if tokens_len > 55*1024:
|
|
80
81
|
logger.warning(f"Quick filter prompt is too long, tokens_len: {tokens_len}/{55*1024} fallback to normal filter")
|
autocoder/index/index.py
CHANGED
|
@@ -15,7 +15,8 @@ import threading
|
|
|
15
15
|
import byzerllm
|
|
16
16
|
import hashlib
|
|
17
17
|
|
|
18
|
-
from
|
|
18
|
+
from autocoder.common.printer import Printer
|
|
19
|
+
from autocoder.common.auto_coder_lang import get_message
|
|
19
20
|
from autocoder.index.types import (
|
|
20
21
|
IndexItem,
|
|
21
22
|
TargetFile,
|
|
@@ -48,6 +49,7 @@ class IndexManager:
|
|
|
48
49
|
self.max_input_length = (
|
|
49
50
|
args.index_model_max_input_length or args.model_max_input_length
|
|
50
51
|
)
|
|
52
|
+
self.printer = Printer()
|
|
51
53
|
|
|
52
54
|
# 如果索引目录不存在,则创建它
|
|
53
55
|
if not os.path.exists(self.index_dir):
|
|
@@ -206,8 +208,12 @@ class IndexManager:
|
|
|
206
208
|
start_time = time.monotonic()
|
|
207
209
|
source_code = source.source_code
|
|
208
210
|
if len(source.source_code) > self.max_input_length:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
+
self.printer.print_in_terminal(
|
|
212
|
+
"index_file_too_large",
|
|
213
|
+
style="yellow",
|
|
214
|
+
file_path=source.module_name,
|
|
215
|
+
file_size=len(source.source_code),
|
|
216
|
+
max_length=self.max_input_length
|
|
211
217
|
)
|
|
212
218
|
chunks = self.split_text_into_chunks(
|
|
213
219
|
source_code, self.max_input_length - 1000
|
|
@@ -224,12 +230,23 @@ class IndexManager:
|
|
|
224
230
|
self.index_llm).run(source.module_name, source_code)
|
|
225
231
|
time.sleep(self.anti_quota_limit)
|
|
226
232
|
|
|
227
|
-
|
|
228
|
-
|
|
233
|
+
self.printer.print_in_terminal(
|
|
234
|
+
"index_update_success",
|
|
235
|
+
style="green",
|
|
236
|
+
file_path=file_path,
|
|
237
|
+
md5=md5,
|
|
238
|
+
duration=time.monotonic() - start_time
|
|
229
239
|
)
|
|
230
240
|
|
|
231
241
|
except Exception as e:
|
|
232
|
-
|
|
242
|
+
# import traceback
|
|
243
|
+
# traceback.print_exc()
|
|
244
|
+
self.printer.print_in_terminal(
|
|
245
|
+
"index_build_error",
|
|
246
|
+
style="red",
|
|
247
|
+
file_path=file_path,
|
|
248
|
+
error=str(e)
|
|
249
|
+
)
|
|
233
250
|
return None
|
|
234
251
|
|
|
235
252
|
return {
|
|
@@ -255,8 +272,11 @@ class IndexManager:
|
|
|
255
272
|
|
|
256
273
|
for item in index_data.keys():
|
|
257
274
|
if not item.startswith(self.source_dir):
|
|
258
|
-
|
|
259
|
-
|
|
275
|
+
self.printer.print_in_terminal(
|
|
276
|
+
"index_source_dir_mismatch",
|
|
277
|
+
style="yellow",
|
|
278
|
+
source_dir=self.source_dir,
|
|
279
|
+
file_path=item
|
|
260
280
|
)
|
|
261
281
|
break
|
|
262
282
|
|
|
@@ -291,8 +311,12 @@ class IndexManager:
|
|
|
291
311
|
counter = 0
|
|
292
312
|
num_files = len(wait_to_build_files)
|
|
293
313
|
total_files = len(self.sources)
|
|
294
|
-
|
|
295
|
-
|
|
314
|
+
self.printer.print_in_terminal(
|
|
315
|
+
"index_build_summary",
|
|
316
|
+
style="bold blue",
|
|
317
|
+
total_files=total_files,
|
|
318
|
+
num_files=num_files
|
|
319
|
+
)
|
|
296
320
|
|
|
297
321
|
futures = [
|
|
298
322
|
executor.submit(self.build_index_for_single_source, source)
|
|
@@ -302,7 +326,12 @@ class IndexManager:
|
|
|
302
326
|
result = future.result()
|
|
303
327
|
if result is not None:
|
|
304
328
|
counter += 1
|
|
305
|
-
|
|
329
|
+
self.printer.print_in_terminal(
|
|
330
|
+
"building_index_progress",
|
|
331
|
+
style="blue",
|
|
332
|
+
counter=counter,
|
|
333
|
+
num_files=num_files
|
|
334
|
+
)
|
|
306
335
|
module_name = result["module_name"]
|
|
307
336
|
index_data[module_name] = result
|
|
308
337
|
updated_sources.append(module_name)
|
|
@@ -404,8 +433,10 @@ class IndexManager:
|
|
|
404
433
|
with lock:
|
|
405
434
|
all_results.extend(result.file_list)
|
|
406
435
|
else:
|
|
407
|
-
|
|
408
|
-
|
|
436
|
+
self.printer.print_in_terminal(
|
|
437
|
+
"index_related_files_fail",
|
|
438
|
+
style="yellow",
|
|
439
|
+
chunk_count=chunk_count
|
|
409
440
|
)
|
|
410
441
|
time.sleep(self.args.anti_quota_limit)
|
|
411
442
|
|
|
@@ -442,8 +473,10 @@ class IndexManager:
|
|
|
442
473
|
all_results.extend(result.file_list)
|
|
443
474
|
completed_threads += 1
|
|
444
475
|
else:
|
|
445
|
-
|
|
446
|
-
|
|
476
|
+
self.printer.print_in_terminal(
|
|
477
|
+
"index_related_files_fail",
|
|
478
|
+
style="yellow",
|
|
479
|
+
chunk_count="unknown"
|
|
447
480
|
)
|
|
448
481
|
time.sleep(self.args.anti_quota_limit)
|
|
449
482
|
|
|
@@ -457,7 +490,12 @@ class IndexManager:
|
|
|
457
490
|
for future in as_completed(futures):
|
|
458
491
|
future.result()
|
|
459
492
|
|
|
460
|
-
|
|
493
|
+
self.printer.print_in_terminal(
|
|
494
|
+
"index_threads_completed",
|
|
495
|
+
style="green",
|
|
496
|
+
completed_threads=completed_threads,
|
|
497
|
+
total_threads=total_threads
|
|
498
|
+
)
|
|
461
499
|
return all_results, total_threads, completed_threads
|
|
462
500
|
|
|
463
501
|
def get_target_files_by_query(self, query: str) -> FileList:
|
autocoder/utils/types.py
ADDED
|
File without changes
|
autocoder/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.237"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|