auto-coder 0.1.209__py3-none-any.whl → 0.1.211__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.209.dist-info → auto_coder-0.1.211.dist-info}/METADATA +1 -1
- {auto_coder-0.1.209.dist-info → auto_coder-0.1.211.dist-info}/RECORD +18 -14
- autocoder/chat_auto_coder.py +153 -150
- autocoder/common/buildin_tokenizer.py +37 -0
- autocoder/common/code_auto_generate.py +1 -3
- autocoder/common/code_auto_generate_diff.py +1 -3
- autocoder/common/code_auto_generate_editblock.py +1 -3
- autocoder/common/code_auto_generate_strict_diff.py +1 -3
- autocoder/common/code_modification_ranker.py +35 -17
- autocoder/common/mcp_hub.py +326 -0
- autocoder/common/mcp_server.py +83 -0
- autocoder/common/mcp_tools.py +682 -0
- autocoder/dispacher/actions/action.py +40 -21
- autocoder/version.py +1 -1
- {auto_coder-0.1.209.dist-info → auto_coder-0.1.211.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.209.dist-info → auto_coder-0.1.211.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.209.dist-info → auto_coder-0.1.211.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.209.dist-info → auto_coder-0.1.211.dist-info}/top_level.txt +0 -0
autocoder/chat_auto_coder.py
CHANGED
|
@@ -60,7 +60,8 @@ from byzerllm.utils import format_str_jinja2
|
|
|
60
60
|
from autocoder.chat_auto_coder_lang import get_message
|
|
61
61
|
from autocoder.utils import operate_config_api
|
|
62
62
|
from autocoder.agent.auto_guess_query import AutoGuessQuery
|
|
63
|
-
|
|
63
|
+
from autocoder.common.mcp_server import get_mcp_server, McpRequest
|
|
64
|
+
import asyncio
|
|
64
65
|
|
|
65
66
|
class SymbolItem(BaseModel):
|
|
66
67
|
symbol_name: str
|
|
@@ -72,8 +73,7 @@ def parse_arguments():
|
|
|
72
73
|
import argparse
|
|
73
74
|
|
|
74
75
|
parser = argparse.ArgumentParser(description="Chat Auto Coder")
|
|
75
|
-
parser.add_argument("--debug", action="store_true",
|
|
76
|
-
help="Enable debug mode")
|
|
76
|
+
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
|
|
77
77
|
parser.add_argument(
|
|
78
78
|
"--quick",
|
|
79
79
|
action="store_true",
|
|
@@ -125,6 +125,7 @@ commands = [
|
|
|
125
125
|
"/mode",
|
|
126
126
|
"/lib",
|
|
127
127
|
"/design",
|
|
128
|
+
"/mcp",
|
|
128
129
|
]
|
|
129
130
|
|
|
130
131
|
|
|
@@ -155,10 +156,8 @@ def show_help():
|
|
|
155
156
|
print(
|
|
156
157
|
f" \033[94m/summon\033[0m \033[93m<query>\033[0m - \033[92m{get_message('summon_desc')}\033[0m"
|
|
157
158
|
)
|
|
158
|
-
print(
|
|
159
|
-
|
|
160
|
-
print(
|
|
161
|
-
f" \033[94m/commit\033[0m - \033[92m{get_message('commit_desc')}\033[0m")
|
|
159
|
+
print(f" \033[94m/revert\033[0m - \033[92m{get_message('revert_desc')}\033[0m")
|
|
160
|
+
print(f" \033[94m/commit\033[0m - \033[92m{get_message('commit_desc')}\033[0m")
|
|
162
161
|
print(
|
|
163
162
|
f" \033[94m/conf\033[0m \033[93m<key>:<value>\033[0m - \033[92m{get_message('conf_desc')}\033[0m"
|
|
164
163
|
)
|
|
@@ -171,8 +170,7 @@ def show_help():
|
|
|
171
170
|
print(
|
|
172
171
|
f" \033[94m/list_files\033[0m - \033[92m{get_message('list_files_desc')}\033[0m"
|
|
173
172
|
)
|
|
174
|
-
print(
|
|
175
|
-
f" \033[94m/help\033[0m - \033[92m{get_message('help_desc')}\033[0m")
|
|
173
|
+
print(f" \033[94m/help\033[0m - \033[92m{get_message('help_desc')}\033[0m")
|
|
176
174
|
print(
|
|
177
175
|
f" \033[94m/exclude_dirs\033[0m \033[93m<dir1>,<dir2> ...\033[0m - \033[92m{get_message('exclude_dirs_desc')}\033[0m"
|
|
178
176
|
)
|
|
@@ -182,11 +180,9 @@ def show_help():
|
|
|
182
180
|
print(
|
|
183
181
|
f" \033[94m/voice_input\033[0m - \033[92m{get_message('voice_input_desc')}\033[0m"
|
|
184
182
|
)
|
|
185
|
-
print(
|
|
186
|
-
f" \033[94m/mode\033[0m - \033[92m{get_message('mode_desc')}\033[0m")
|
|
183
|
+
print(f" \033[94m/mode\033[0m - \033[92m{get_message('mode_desc')}\033[0m")
|
|
187
184
|
print(f" \033[94m/lib\033[0m - \033[92m{get_message('lib_desc')}\033[0m")
|
|
188
|
-
print(
|
|
189
|
-
f" \033[94m/exit\033[0m - \033[92m{get_message('exit_desc')}\033[0m")
|
|
185
|
+
print(f" \033[94m/exit\033[0m - \033[92m{get_message('exit_desc')}\033[0m")
|
|
190
186
|
print()
|
|
191
187
|
|
|
192
188
|
|
|
@@ -211,12 +207,10 @@ def configure_project_type():
|
|
|
211
207
|
print_formatted_text(HTML(f"<info>{escape(text)}</info>"), style=style)
|
|
212
208
|
|
|
213
209
|
def print_warning(text):
|
|
214
|
-
print_formatted_text(
|
|
215
|
-
HTML(f"<warning>{escape(text)}</warning>"), style=style)
|
|
210
|
+
print_formatted_text(HTML(f"<warning>{escape(text)}</warning>"), style=style)
|
|
216
211
|
|
|
217
212
|
def print_header(text):
|
|
218
|
-
print_formatted_text(
|
|
219
|
-
HTML(f"<header>{escape(text)}</header>"), style=style)
|
|
213
|
+
print_formatted_text(HTML(f"<header>{escape(text)}</header>"), style=style)
|
|
220
214
|
|
|
221
215
|
print_header(f"\n=== {get_message('project_type_config')} ===\n")
|
|
222
216
|
print_info(get_message("project_type_supports"))
|
|
@@ -262,8 +256,7 @@ def initialize_system():
|
|
|
262
256
|
if not os.path.exists(".auto-coder"):
|
|
263
257
|
first_time = True
|
|
264
258
|
print_status(get_message("not_initialized"), "warning")
|
|
265
|
-
init_choice = input(
|
|
266
|
-
f" {get_message('init_prompt')}").strip().lower()
|
|
259
|
+
init_choice = input(f" {get_message('init_prompt')}").strip().lower()
|
|
267
260
|
if init_choice == "y":
|
|
268
261
|
try:
|
|
269
262
|
subprocess.run(
|
|
@@ -280,8 +273,7 @@ def initialize_system():
|
|
|
280
273
|
|
|
281
274
|
if not os.path.exists(base_persist_dir):
|
|
282
275
|
os.makedirs(base_persist_dir, exist_ok=True)
|
|
283
|
-
print_status(get_message("created_dir").format(
|
|
284
|
-
base_persist_dir), "success")
|
|
276
|
+
print_status(get_message("created_dir").format(base_persist_dir), "success")
|
|
285
277
|
|
|
286
278
|
if first_time:
|
|
287
279
|
configure_project_type()
|
|
@@ -291,8 +283,7 @@ def initialize_system():
|
|
|
291
283
|
init_project()
|
|
292
284
|
# Check if Ray is running
|
|
293
285
|
print_status(get_message("checking_ray"), "")
|
|
294
|
-
ray_status = subprocess.run(
|
|
295
|
-
["ray", "status"], capture_output=True, text=True)
|
|
286
|
+
ray_status = subprocess.run(["ray", "status"], capture_output=True, text=True)
|
|
296
287
|
if ray_status.returncode != 0:
|
|
297
288
|
print_status(get_message("ray_not_running"), "warning")
|
|
298
289
|
try:
|
|
@@ -435,8 +426,7 @@ def get_all_file_in_project_with_dot() -> List[str]:
|
|
|
435
426
|
for root, dirs, files in os.walk(project_root, followlinks=True):
|
|
436
427
|
dirs[:] = [d for d in dirs if d not in final_exclude_dirs]
|
|
437
428
|
for file in files:
|
|
438
|
-
file_names.append(os.path.join(
|
|
439
|
-
root, file).replace(project_root, "."))
|
|
429
|
+
file_names.append(os.path.join(root, file).replace(project_root, "."))
|
|
440
430
|
return file_names
|
|
441
431
|
|
|
442
432
|
|
|
@@ -564,10 +554,8 @@ def show_help():
|
|
|
564
554
|
print(
|
|
565
555
|
f" \033[94m/summon\033[0m \033[93m<query>\033[0m - \033[92m{get_message('summon_desc')}\033[0m"
|
|
566
556
|
)
|
|
567
|
-
print(
|
|
568
|
-
|
|
569
|
-
print(
|
|
570
|
-
f" \033[94m/commit\033[0m - \033[92m{get_message('commit_desc')}\033[0m")
|
|
557
|
+
print(f" \033[94m/revert\033[0m - \033[92m{get_message('revert_desc')}\033[0m")
|
|
558
|
+
print(f" \033[94m/commit\033[0m - \033[92m{get_message('commit_desc')}\033[0m")
|
|
571
559
|
print(
|
|
572
560
|
f" \033[94m/conf\033[0m \033[93m<key>:<value>\033[0m - \033[92m{get_message('conf_desc')}\033[0m"
|
|
573
561
|
)
|
|
@@ -580,8 +568,7 @@ def show_help():
|
|
|
580
568
|
print(
|
|
581
569
|
f" \033[94m/list_files\033[0m - \033[92m{get_message('list_files_desc')}\033[0m"
|
|
582
570
|
)
|
|
583
|
-
print(
|
|
584
|
-
f" \033[94m/help\033[0m - \033[92m{get_message('help_desc')}\033[0m")
|
|
571
|
+
print(f" \033[94m/help\033[0m - \033[92m{get_message('help_desc')}\033[0m")
|
|
585
572
|
print(
|
|
586
573
|
f" \033[94m/exclude_dirs\033[0m \033[93m<dir1>,<dir2> ...\033[0m - \033[92m{get_message('exclude_dirs_desc')}\033[0m"
|
|
587
574
|
)
|
|
@@ -591,11 +578,9 @@ def show_help():
|
|
|
591
578
|
print(
|
|
592
579
|
f" \033[94m/voice_input\033[0m - \033[92m{get_message('voice_input_desc')}\033[0m"
|
|
593
580
|
)
|
|
594
|
-
print(
|
|
595
|
-
f" \033[94m/mode\033[0m - \033[92m{get_message('mode_desc')}\033[0m")
|
|
581
|
+
print(f" \033[94m/mode\033[0m - \033[92m{get_message('mode_desc')}\033[0m")
|
|
596
582
|
print(f" \033[94m/lib\033[0m - \033[92m{get_message('lib_desc')}\033[0m")
|
|
597
|
-
print(
|
|
598
|
-
f" \033[94m/exit\033[0m - \033[92m{get_message('exit_desc')}\033[0m")
|
|
583
|
+
print(f" \033[94m/exit\033[0m - \033[92m{get_message('exit_desc')}\033[0m")
|
|
599
584
|
print()
|
|
600
585
|
|
|
601
586
|
|
|
@@ -659,13 +644,13 @@ class CommandCompleter(Completer):
|
|
|
659
644
|
|
|
660
645
|
if len(words) > 0:
|
|
661
646
|
if words[0] == "/mode":
|
|
662
|
-
left_word = text[len("/mode"):]
|
|
647
|
+
left_word = text[len("/mode") :]
|
|
663
648
|
for mode in ["normal", "auto_detect", "voice_input"]:
|
|
664
649
|
if mode.startswith(left_word.strip()):
|
|
665
650
|
yield Completion(mode, start_position=-len(left_word.strip()))
|
|
666
651
|
|
|
667
652
|
if words[0] == "/add_files":
|
|
668
|
-
new_text = text[len("/add_files"):]
|
|
653
|
+
new_text = text[len("/add_files") :]
|
|
669
654
|
parser = CommandTextParser(new_text, words[0])
|
|
670
655
|
parser.add_files()
|
|
671
656
|
current_word = parser.current_word()
|
|
@@ -696,21 +681,18 @@ class CommandCompleter(Completer):
|
|
|
696
681
|
for file_name in self.all_files_with_dot:
|
|
697
682
|
if file_name.startswith(current_word):
|
|
698
683
|
yield Completion(
|
|
699
|
-
file_name, start_position=-
|
|
700
|
-
len(current_word)
|
|
684
|
+
file_name, start_position=-len(current_word)
|
|
701
685
|
)
|
|
702
686
|
else:
|
|
703
687
|
for file_name in self.all_file_names:
|
|
704
688
|
if file_name.startswith(current_word):
|
|
705
689
|
yield Completion(
|
|
706
|
-
file_name, start_position=-
|
|
707
|
-
len(current_word)
|
|
690
|
+
file_name, start_position=-len(current_word)
|
|
708
691
|
)
|
|
709
692
|
for file_name in self.all_files:
|
|
710
693
|
if current_word and current_word in file_name:
|
|
711
694
|
yield Completion(
|
|
712
|
-
file_name, start_position=-
|
|
713
|
-
len(current_word)
|
|
695
|
+
file_name, start_position=-len(current_word)
|
|
714
696
|
)
|
|
715
697
|
elif words[0] in ["/chat", "/coding"]:
|
|
716
698
|
image_extensions = (
|
|
@@ -740,7 +722,7 @@ class CommandCompleter(Completer):
|
|
|
740
722
|
".psd",
|
|
741
723
|
".xcf",
|
|
742
724
|
)
|
|
743
|
-
new_text = text[len(words[0]):]
|
|
725
|
+
new_text = text[len(words[0]) :]
|
|
744
726
|
parser = CommandTextParser(new_text, words[0])
|
|
745
727
|
|
|
746
728
|
parser.coding()
|
|
@@ -767,8 +749,7 @@ class CommandCompleter(Completer):
|
|
|
767
749
|
if len(path_parts) > 3
|
|
768
750
|
else file_name
|
|
769
751
|
)
|
|
770
|
-
relative_path = os.path.relpath(
|
|
771
|
-
file_name, project_root)
|
|
752
|
+
relative_path = os.path.relpath(file_name, project_root)
|
|
772
753
|
yield Completion(
|
|
773
754
|
relative_path,
|
|
774
755
|
start_position=-len(name),
|
|
@@ -785,8 +766,7 @@ class CommandCompleter(Completer):
|
|
|
785
766
|
if len(path_parts) > 3
|
|
786
767
|
else file_name
|
|
787
768
|
)
|
|
788
|
-
relative_path = os.path.relpath(
|
|
789
|
-
file_name, project_root)
|
|
769
|
+
relative_path = os.path.relpath(file_name, project_root)
|
|
790
770
|
|
|
791
771
|
yield Completion(
|
|
792
772
|
relative_path,
|
|
@@ -802,8 +782,7 @@ class CommandCompleter(Completer):
|
|
|
802
782
|
if len(path_parts) > 3
|
|
803
783
|
else file_name
|
|
804
784
|
)
|
|
805
|
-
relative_path = os.path.relpath(
|
|
806
|
-
file_name, project_root)
|
|
785
|
+
relative_path = os.path.relpath(file_name, project_root)
|
|
807
786
|
yield Completion(
|
|
808
787
|
relative_path,
|
|
809
788
|
start_position=-len(name),
|
|
@@ -821,8 +800,7 @@ class CommandCompleter(Completer):
|
|
|
821
800
|
if len(path_parts) > 3
|
|
822
801
|
else symbol.symbol_name
|
|
823
802
|
)
|
|
824
|
-
relative_path = os.path.relpath(
|
|
825
|
-
file_name, project_root)
|
|
803
|
+
relative_path = os.path.relpath(file_name, project_root)
|
|
826
804
|
yield Completion(
|
|
827
805
|
f"{symbol.symbol_name}(location: {relative_path})",
|
|
828
806
|
start_position=-len(name),
|
|
@@ -857,8 +835,7 @@ class CommandCompleter(Completer):
|
|
|
857
835
|
for dir in dirs:
|
|
858
836
|
full_path = os.path.join(root, dir)
|
|
859
837
|
if full_path.startswith(file_name):
|
|
860
|
-
relative_path = os.path.relpath(
|
|
861
|
-
full_path, search_dir)
|
|
838
|
+
relative_path = os.path.relpath(full_path, search_dir)
|
|
862
839
|
yield Completion(
|
|
863
840
|
relative_path,
|
|
864
841
|
start_position=-len(file_basename),
|
|
@@ -870,8 +847,7 @@ class CommandCompleter(Completer):
|
|
|
870
847
|
image_extensions
|
|
871
848
|
) and file.startswith(file_basename):
|
|
872
849
|
full_path = os.path.join(root, file)
|
|
873
|
-
relative_path = os.path.relpath(
|
|
874
|
-
full_path, search_dir)
|
|
850
|
+
relative_path = os.path.relpath(full_path, search_dir)
|
|
875
851
|
yield Completion(
|
|
876
852
|
relative_path,
|
|
877
853
|
start_position=-len(file_basename),
|
|
@@ -881,7 +857,7 @@ class CommandCompleter(Completer):
|
|
|
881
857
|
break
|
|
882
858
|
|
|
883
859
|
elif words[0] == "/remove_files":
|
|
884
|
-
new_words = text[len("/remove_files"):].strip().split(",")
|
|
860
|
+
new_words = text[len("/remove_files") :].strip().split(",")
|
|
885
861
|
|
|
886
862
|
is_at_space = text[-1] == " "
|
|
887
863
|
last_word = new_words[-2] if len(new_words) > 1 else ""
|
|
@@ -908,7 +884,7 @@ class CommandCompleter(Completer):
|
|
|
908
884
|
file_name, start_position=-len(current_word)
|
|
909
885
|
)
|
|
910
886
|
elif words[0] == "/exclude_dirs":
|
|
911
|
-
new_words = text[len("/exclude_dirs"):].strip().split(",")
|
|
887
|
+
new_words = text[len("/exclude_dirs") :].strip().split(",")
|
|
912
888
|
current_word = new_words[-1]
|
|
913
889
|
|
|
914
890
|
for file_name in self.all_dir_names:
|
|
@@ -916,7 +892,7 @@ class CommandCompleter(Completer):
|
|
|
916
892
|
yield Completion(file_name, start_position=-len(current_word))
|
|
917
893
|
|
|
918
894
|
elif words[0] == "/lib":
|
|
919
|
-
new_text = text[len("/lib"):]
|
|
895
|
+
new_text = text[len("/lib") :]
|
|
920
896
|
parser = CommandTextParser(new_text, words[0])
|
|
921
897
|
parser.lib()
|
|
922
898
|
current_word = parser.current_word()
|
|
@@ -932,7 +908,7 @@ class CommandCompleter(Completer):
|
|
|
932
908
|
lib_name, start_position=-len(current_word)
|
|
933
909
|
)
|
|
934
910
|
elif words[0] == "/coding":
|
|
935
|
-
new_text = text[len("/coding"):]
|
|
911
|
+
new_text = text[len("/coding") :]
|
|
936
912
|
parser = CommandTextParser(new_text, words[0])
|
|
937
913
|
parser.lib()
|
|
938
914
|
current_word = parser.current_word()
|
|
@@ -941,7 +917,7 @@ class CommandCompleter(Completer):
|
|
|
941
917
|
yield Completion(command, start_position=-len(current_word))
|
|
942
918
|
|
|
943
919
|
elif words[0] == "/conf":
|
|
944
|
-
new_words = text[len("/conf"):].strip().split()
|
|
920
|
+
new_words = text[len("/conf") :].strip().split()
|
|
945
921
|
is_at_space = text[-1] == " "
|
|
946
922
|
last_word = new_words[-2] if len(new_words) > 1 else ""
|
|
947
923
|
current_word = new_words[-1] if new_words else ""
|
|
@@ -960,8 +936,7 @@ class CommandCompleter(Completer):
|
|
|
960
936
|
]
|
|
961
937
|
# /conf [curosr]
|
|
962
938
|
elif not last_word and not current_word:
|
|
963
|
-
completions = [
|
|
964
|
-
"/drop"] if "/drop".startswith(current_word) else []
|
|
939
|
+
completions = ["/drop"] if "/drop".startswith(current_word) else []
|
|
965
940
|
completions += [
|
|
966
941
|
field_name + ":"
|
|
967
942
|
for field_name in AutoCoderArgs.model_fields.keys()
|
|
@@ -969,8 +944,7 @@ class CommandCompleter(Completer):
|
|
|
969
944
|
]
|
|
970
945
|
# /conf p[cursor]
|
|
971
946
|
elif not last_word and current_word:
|
|
972
|
-
completions = [
|
|
973
|
-
"/drop"] if "/drop".startswith(current_word) else []
|
|
947
|
+
completions = ["/drop"] if "/drop".startswith(current_word) else []
|
|
974
948
|
completions += [
|
|
975
949
|
field_name + ":"
|
|
976
950
|
for field_name in AutoCoderArgs.model_fields.keys()
|
|
@@ -1064,8 +1038,7 @@ def add_files(args: List[str]):
|
|
|
1064
1038
|
completer.refresh_files()
|
|
1065
1039
|
load_memory()
|
|
1066
1040
|
console.print(
|
|
1067
|
-
Panel("Refreshed file list.",
|
|
1068
|
-
title="Files Refreshed", border_style="green")
|
|
1041
|
+
Panel("Refreshed file list.", title="Files Refreshed", border_style="green")
|
|
1069
1042
|
)
|
|
1070
1043
|
return
|
|
1071
1044
|
|
|
@@ -1073,8 +1046,7 @@ def add_files(args: List[str]):
|
|
|
1073
1046
|
if len(args) == 1 or (len(args) == 2 and args[1] == "list"):
|
|
1074
1047
|
if not groups:
|
|
1075
1048
|
console.print(
|
|
1076
|
-
Panel("No groups defined.", title="Groups",
|
|
1077
|
-
border_style="yellow")
|
|
1049
|
+
Panel("No groups defined.", title="Groups", border_style="yellow")
|
|
1078
1050
|
)
|
|
1079
1051
|
else:
|
|
1080
1052
|
table = Table(
|
|
@@ -1099,8 +1071,7 @@ def add_files(args: List[str]):
|
|
|
1099
1071
|
)
|
|
1100
1072
|
table.add_row(
|
|
1101
1073
|
group_name,
|
|
1102
|
-
"\n".join([os.path.relpath(f, project_root)
|
|
1103
|
-
for f in files]),
|
|
1074
|
+
"\n".join([os.path.relpath(f, project_root) for f in files]),
|
|
1104
1075
|
query_prefix,
|
|
1105
1076
|
is_active,
|
|
1106
1077
|
end_section=(i == len(groups) - 1),
|
|
@@ -1132,8 +1103,7 @@ def add_files(args: List[str]):
|
|
|
1132
1103
|
if group_name in groups_info:
|
|
1133
1104
|
del memory["current_files"]["groups_info"][group_name]
|
|
1134
1105
|
if group_name in memory["current_files"]["current_groups"]:
|
|
1135
|
-
memory["current_files"]["current_groups"].remove(
|
|
1136
|
-
group_name)
|
|
1106
|
+
memory["current_files"]["current_groups"].remove(group_name)
|
|
1137
1107
|
console.print(
|
|
1138
1108
|
Panel(
|
|
1139
1109
|
f"Dropped group '{group_name}'.",
|
|
@@ -1306,8 +1276,7 @@ def remove_files(file_names: List[str]):
|
|
|
1306
1276
|
memory["current_files"]["files"] = []
|
|
1307
1277
|
memory["current_files"]["current_groups"] = []
|
|
1308
1278
|
console.print(
|
|
1309
|
-
Panel("Removed all files.",
|
|
1310
|
-
title="Files Removed", border_style="green")
|
|
1279
|
+
Panel("Removed all files.", title="Files Removed", border_style="green")
|
|
1311
1280
|
)
|
|
1312
1281
|
else:
|
|
1313
1282
|
removed_files = []
|
|
@@ -1423,6 +1392,7 @@ def get_llm_friendly_package_docs(
|
|
|
1423
1392
|
|
|
1424
1393
|
def convert_yaml_to_config(yaml_file: str):
|
|
1425
1394
|
from autocoder.auto_coder import AutoCoderArgs, load_include_files, Template
|
|
1395
|
+
|
|
1426
1396
|
args = AutoCoderArgs()
|
|
1427
1397
|
with open(yaml_file, "r") as f:
|
|
1428
1398
|
config = yaml.safe_load(f)
|
|
@@ -1437,6 +1407,46 @@ def convert_yaml_to_config(yaml_file: str):
|
|
|
1437
1407
|
return args
|
|
1438
1408
|
|
|
1439
1409
|
|
|
1410
|
+
def mcp(query: str):
|
|
1411
|
+
conf = memory.get("conf", {})
|
|
1412
|
+
yaml_config = {
|
|
1413
|
+
"include_file": ["./base/base.yml"],
|
|
1414
|
+
"auto_merge": conf.get("auto_merge", "editblock"),
|
|
1415
|
+
"human_as_model": conf.get("human_as_model", "false") == "true",
|
|
1416
|
+
"skip_build_index": conf.get("skip_build_index", "true") == "true",
|
|
1417
|
+
"skip_confirm": conf.get("skip_confirm", "true") == "true",
|
|
1418
|
+
"silence": conf.get("silence", "true") == "true",
|
|
1419
|
+
"include_project_structure": conf.get("include_project_structure", "true")
|
|
1420
|
+
== "true",
|
|
1421
|
+
}
|
|
1422
|
+
for key, value in conf.items():
|
|
1423
|
+
converted_value = convert_config_value(key, value)
|
|
1424
|
+
if converted_value is not None:
|
|
1425
|
+
yaml_config[key] = converted_value
|
|
1426
|
+
|
|
1427
|
+
temp_yaml = os.path.join("actions", f"{uuid.uuid4()}.yml")
|
|
1428
|
+
try:
|
|
1429
|
+
with open(temp_yaml, "w") as f:
|
|
1430
|
+
f.write(convert_yaml_config_to_str(yaml_config=yaml_config))
|
|
1431
|
+
args = convert_yaml_to_config(temp_yaml)
|
|
1432
|
+
finally:
|
|
1433
|
+
if os.path.exists(temp_yaml):
|
|
1434
|
+
os.remove(temp_yaml)
|
|
1435
|
+
|
|
1436
|
+
mcp_server = get_mcp_server()
|
|
1437
|
+
response = mcp_server.send_request(
|
|
1438
|
+
McpRequest(
|
|
1439
|
+
query=query,
|
|
1440
|
+
model=args.inference_model or args.model
|
|
1441
|
+
)
|
|
1442
|
+
)
|
|
1443
|
+
|
|
1444
|
+
if response.error:
|
|
1445
|
+
print(f"Error from MCP server: {response.error}")
|
|
1446
|
+
else:
|
|
1447
|
+
print(response.result)
|
|
1448
|
+
|
|
1449
|
+
|
|
1440
1450
|
def code_next(query: str):
|
|
1441
1451
|
conf = memory.get("conf", {})
|
|
1442
1452
|
yaml_config = {
|
|
@@ -1463,17 +1473,13 @@ def code_next(query: str):
|
|
|
1463
1473
|
if os.path.exists(temp_yaml):
|
|
1464
1474
|
os.remove(temp_yaml)
|
|
1465
1475
|
|
|
1466
|
-
llm = byzerllm.ByzerLLM.from_default_model(
|
|
1467
|
-
args.inference_model or args.model)
|
|
1476
|
+
llm = byzerllm.ByzerLLM.from_default_model(args.inference_model or args.model)
|
|
1468
1477
|
|
|
1469
|
-
auto_guesser = AutoGuessQuery(
|
|
1470
|
-
llm=llm,
|
|
1471
|
-
project_dir=os.getcwd(),
|
|
1472
|
-
skip_diff=True
|
|
1473
|
-
)
|
|
1478
|
+
auto_guesser = AutoGuessQuery(llm=llm, project_dir=os.getcwd(), skip_diff=True)
|
|
1474
1479
|
|
|
1475
1480
|
predicted_tasks = auto_guesser.predict_next_tasks(
|
|
1476
|
-
5, is_human_as_model=args.human_as_model
|
|
1481
|
+
5, is_human_as_model=args.human_as_model
|
|
1482
|
+
)
|
|
1477
1483
|
|
|
1478
1484
|
if not predicted_tasks:
|
|
1479
1485
|
console = Console()
|
|
@@ -1483,39 +1489,34 @@ def code_next(query: str):
|
|
|
1483
1489
|
console = Console()
|
|
1484
1490
|
|
|
1485
1491
|
# Create main panel for all predicted tasks
|
|
1486
|
-
table = Table(show_header=True,
|
|
1487
|
-
header_style="bold magenta", show_lines=True)
|
|
1492
|
+
table = Table(show_header=True, header_style="bold magenta", show_lines=True)
|
|
1488
1493
|
table.add_column("Priority", style="cyan", width=8)
|
|
1489
|
-
table.add_column("Task Description", style="green",
|
|
1490
|
-
width=40, overflow="fold")
|
|
1494
|
+
table.add_column("Task Description", style="green", width=40, overflow="fold")
|
|
1491
1495
|
table.add_column("Files", style="yellow", width=30, overflow="fold")
|
|
1492
1496
|
table.add_column("Reason", style="blue", width=30, overflow="fold")
|
|
1493
|
-
table.add_column("Dependencies", style="magenta",
|
|
1494
|
-
width=30, overflow="fold")
|
|
1497
|
+
table.add_column("Dependencies", style="magenta", width=30, overflow="fold")
|
|
1495
1498
|
|
|
1496
1499
|
for task in predicted_tasks:
|
|
1497
1500
|
# Format file paths to be more readable
|
|
1498
|
-
file_list = "\n".join([os.path.relpath(f, os.getcwd())
|
|
1499
|
-
for f in task.urls])
|
|
1501
|
+
file_list = "\n".join([os.path.relpath(f, os.getcwd()) for f in task.urls])
|
|
1500
1502
|
|
|
1501
1503
|
# Format dependencies to be more readable
|
|
1502
|
-
dependencies =
|
|
1503
|
-
task.dependency_queries) if task.dependency_queries else "None"
|
|
1504
|
+
dependencies = (
|
|
1505
|
+
"\n".join(task.dependency_queries) if task.dependency_queries else "None"
|
|
1506
|
+
)
|
|
1504
1507
|
|
|
1505
1508
|
table.add_row(
|
|
1506
|
-
str(task.priority),
|
|
1507
|
-
task.query,
|
|
1508
|
-
file_list,
|
|
1509
|
-
task.reason,
|
|
1510
|
-
dependencies
|
|
1509
|
+
str(task.priority), task.query, file_list, task.reason, dependencies
|
|
1511
1510
|
)
|
|
1512
1511
|
|
|
1513
|
-
console.print(
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1512
|
+
console.print(
|
|
1513
|
+
Panel(
|
|
1514
|
+
table,
|
|
1515
|
+
title="[bold]Predicted Next Tasks[/bold]",
|
|
1516
|
+
border_style="blue",
|
|
1517
|
+
padding=(1, 2), # Add more horizontal padding
|
|
1518
|
+
)
|
|
1519
|
+
)
|
|
1519
1520
|
|
|
1520
1521
|
|
|
1521
1522
|
def commit(query: str):
|
|
@@ -1560,30 +1561,29 @@ def commit(query: str):
|
|
|
1560
1561
|
temp_yaml = os.path.join("actions", f"{uuid.uuid4()}.yml")
|
|
1561
1562
|
try:
|
|
1562
1563
|
with open(temp_yaml, "w") as f:
|
|
1563
|
-
f.write(convert_yaml_config_to_str(
|
|
1564
|
-
yaml_config=yaml_config))
|
|
1564
|
+
f.write(convert_yaml_config_to_str(yaml_config=yaml_config))
|
|
1565
1565
|
args = convert_yaml_to_config(temp_yaml)
|
|
1566
1566
|
finally:
|
|
1567
1567
|
if os.path.exists(temp_yaml):
|
|
1568
1568
|
os.remove(temp_yaml)
|
|
1569
1569
|
|
|
1570
|
-
llm = byzerllm.ByzerLLM.from_default_model(
|
|
1571
|
-
args.code_model or args.model)
|
|
1570
|
+
llm = byzerllm.ByzerLLM.from_default_model(args.code_model or args.model)
|
|
1572
1571
|
uncommitted_changes = git_utils.get_uncommitted_changes(".")
|
|
1573
|
-
commit_message = git_utils.generate_commit_message.with_llm(
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1572
|
+
commit_message = git_utils.generate_commit_message.with_llm(llm).run(
|
|
1573
|
+
uncommitted_changes
|
|
1574
|
+
)
|
|
1575
|
+
memory["conversation"].append({"role": "user", "content": commit_message})
|
|
1577
1576
|
yaml_config["query"] = commit_message
|
|
1578
1577
|
yaml_content = convert_yaml_config_to_str(yaml_config=yaml_config)
|
|
1579
1578
|
with open(os.path.join(execute_file), "w") as f:
|
|
1580
1579
|
f.write(yaml_content)
|
|
1581
1580
|
|
|
1582
1581
|
file_content = open(execute_file).read()
|
|
1583
|
-
md5 = hashlib.md5(file_content.encode(
|
|
1582
|
+
md5 = hashlib.md5(file_content.encode("utf-8")).hexdigest()
|
|
1584
1583
|
file_name = os.path.basename(execute_file)
|
|
1585
1584
|
commit_result = git_utils.commit_changes(
|
|
1586
|
-
".", f"auto_coder_{file_name}_{md5}"
|
|
1585
|
+
".", f"auto_coder_{file_name}_{md5}"
|
|
1586
|
+
)
|
|
1587
1587
|
git_utils.print_commit_info(commit_result=commit_result)
|
|
1588
1588
|
except Exception as e:
|
|
1589
1589
|
print(f"Failed to commit: {e}")
|
|
@@ -1650,8 +1650,7 @@ def coding(query: str):
|
|
|
1650
1650
|
active_groups_context = "下面是对上面文件按分组给到的一些描述,当用户的需求正好匹配描述的时候,参考描述来做修改:\n"
|
|
1651
1651
|
for group in current_groups:
|
|
1652
1652
|
group_files = groups.get(group, [])
|
|
1653
|
-
query_prefix = groups_info.get(
|
|
1654
|
-
group, {}).get("query_prefix", "")
|
|
1653
|
+
query_prefix = groups_info.get(group, {}).get("query_prefix", "")
|
|
1655
1654
|
active_groups_context += f"组名: {group}\n"
|
|
1656
1655
|
active_groups_context += f"文件列表:\n"
|
|
1657
1656
|
for file in group_files:
|
|
@@ -1718,18 +1717,18 @@ def coding(query: str):
|
|
|
1718
1717
|
@byzerllm.prompt()
|
|
1719
1718
|
def code_review(query: str) -> str:
|
|
1720
1719
|
"""
|
|
1721
|
-
对代码进行review,参考如下检查点。
|
|
1720
|
+
对代码进行review,参考如下检查点。
|
|
1722
1721
|
1. 有没有调用不符合方法,类的签名的调用
|
|
1723
1722
|
2. 有没有未声明直接使用的变量,方法,类
|
|
1724
1723
|
3. 有没有明显的语法错误
|
|
1725
|
-
4. 如果是python代码,检查有没有缩进方面的错误
|
|
1724
|
+
4. 如果是python代码,检查有没有缩进方面的错误
|
|
1726
1725
|
5. 如果是python代码,检查是否 try 后面缺少 except 或者 finally
|
|
1727
1726
|
{% if query %}
|
|
1728
1727
|
6. 用户的额外的检查需求:{{ query }}
|
|
1729
1728
|
{% endif %}
|
|
1730
1729
|
|
|
1731
1730
|
如果用户的需求包含了@一个文件名 或者 @@符号, 那么重点关注这些文件或者符号(函数,类)进行上述的review。
|
|
1732
|
-
review 过程中严格遵循上述的检查点,不要遗漏,没有发现异常的点直接跳过,只对发现的异常点,给出具体的修改后的代码。
|
|
1731
|
+
review 过程中严格遵循上述的检查点,不要遗漏,没有发现异常的点直接跳过,只对发现的异常点,给出具体的修改后的代码。
|
|
1733
1732
|
"""
|
|
1734
1733
|
|
|
1735
1734
|
|
|
@@ -1738,7 +1737,8 @@ def chat(query: str):
|
|
|
1738
1737
|
|
|
1739
1738
|
yaml_config = {
|
|
1740
1739
|
"include_file": ["./base/base.yml"],
|
|
1741
|
-
"include_project_structure": conf.get("include_project_structure", "true")
|
|
1740
|
+
"include_project_structure": conf.get("include_project_structure", "true")
|
|
1741
|
+
in ["true", "True"],
|
|
1742
1742
|
"human_as_model": conf.get("human_as_model", "false") == "true",
|
|
1743
1743
|
"skip_build_index": conf.get("skip_build_index", "true") == "true",
|
|
1744
1744
|
"skip_confirm": conf.get("skip_confirm", "true") == "true",
|
|
@@ -2095,8 +2095,7 @@ def execute_shell_command(command: str):
|
|
|
2095
2095
|
f"[bold red]Command failed with return code {process.returncode}[/bold red]"
|
|
2096
2096
|
)
|
|
2097
2097
|
else:
|
|
2098
|
-
console.print(
|
|
2099
|
-
"[bold green]Command completed successfully[/bold green]")
|
|
2098
|
+
console.print("[bold green]Command completed successfully[/bold green]")
|
|
2100
2099
|
|
|
2101
2100
|
except FileNotFoundError:
|
|
2102
2101
|
console.print(
|
|
@@ -2144,8 +2143,7 @@ def lib_command(args: List[str]):
|
|
|
2144
2143
|
proxy_url,
|
|
2145
2144
|
llm_friendly_packages_dir,
|
|
2146
2145
|
)
|
|
2147
|
-
console.print(
|
|
2148
|
-
"Successfully cloned llm_friendly_packages repository")
|
|
2146
|
+
console.print("Successfully cloned llm_friendly_packages repository")
|
|
2149
2147
|
except git.exc.GitCommandError as e:
|
|
2150
2148
|
console.print(f"Error cloning repository: {e}")
|
|
2151
2149
|
|
|
@@ -2206,8 +2204,7 @@ def lib_command(args: List[str]):
|
|
|
2206
2204
|
console.print(f"Updated remote URL to: {new_url}")
|
|
2207
2205
|
|
|
2208
2206
|
origin.pull()
|
|
2209
|
-
console.print(
|
|
2210
|
-
"Successfully updated llm_friendly_packages repository")
|
|
2207
|
+
console.print("Successfully updated llm_friendly_packages repository")
|
|
2211
2208
|
|
|
2212
2209
|
except git.exc.GitCommandError as e:
|
|
2213
2210
|
console.print(f"Error updating repository: {e}")
|
|
@@ -2229,8 +2226,7 @@ def lib_command(args: List[str]):
|
|
|
2229
2226
|
table.add_row(doc)
|
|
2230
2227
|
console.print(table)
|
|
2231
2228
|
else:
|
|
2232
|
-
console.print(
|
|
2233
|
-
f"No markdown files found for package: {package_name}")
|
|
2229
|
+
console.print(f"No markdown files found for package: {package_name}")
|
|
2234
2230
|
|
|
2235
2231
|
else:
|
|
2236
2232
|
console.print(f"Unknown subcommand: {subcommand}")
|
|
@@ -2300,9 +2296,7 @@ def main():
|
|
|
2300
2296
|
memory["mode"] = "normal"
|
|
2301
2297
|
mode = memory["mode"]
|
|
2302
2298
|
human_as_model = memory["conf"].get("human_as_model", "false")
|
|
2303
|
-
return (
|
|
2304
|
-
f" Mode: {MODES[mode]} (ctl+k) | Human as Model: {human_as_model} (ctl+n or /conf human_as_model:true/false)"
|
|
2305
|
-
)
|
|
2299
|
+
return f" Mode: {MODES[mode]} (ctl+k) | Human as Model: {human_as_model} (ctl+n or /conf human_as_model:true/false)"
|
|
2306
2300
|
|
|
2307
2301
|
session = PromptSession(
|
|
2308
2302
|
history=InMemoryHistory(),
|
|
@@ -2354,8 +2348,7 @@ def main():
|
|
|
2354
2348
|
FormattedText(prompt_message), default=new_prompt, style=style
|
|
2355
2349
|
)
|
|
2356
2350
|
else:
|
|
2357
|
-
user_input = session.prompt(
|
|
2358
|
-
FormattedText(prompt_message), style=style)
|
|
2351
|
+
user_input = session.prompt(FormattedText(prompt_message), style=style)
|
|
2359
2352
|
new_prompt = ""
|
|
2360
2353
|
|
|
2361
2354
|
if "mode" not in memory:
|
|
@@ -2380,14 +2373,13 @@ def main():
|
|
|
2380
2373
|
new_prompt = "/coding " + text
|
|
2381
2374
|
|
|
2382
2375
|
elif user_input.startswith("/add_files"):
|
|
2383
|
-
args = user_input[len("/add_files"):].strip().split()
|
|
2376
|
+
args = user_input[len("/add_files") :].strip().split()
|
|
2384
2377
|
add_files(args)
|
|
2385
2378
|
elif user_input.startswith("/remove_files"):
|
|
2386
|
-
file_names = user_input[len(
|
|
2387
|
-
"/remove_files"):].strip().split(",")
|
|
2379
|
+
file_names = user_input[len("/remove_files") :].strip().split(",")
|
|
2388
2380
|
remove_files(file_names)
|
|
2389
2381
|
elif user_input.startswith("/index/query"):
|
|
2390
|
-
query = user_input[len("/index/query"):].strip()
|
|
2382
|
+
query = user_input[len("/index/query") :].strip()
|
|
2391
2383
|
index_query(query)
|
|
2392
2384
|
|
|
2393
2385
|
elif user_input.startswith("/index/build"):
|
|
@@ -2397,14 +2389,14 @@ def main():
|
|
|
2397
2389
|
list_files()
|
|
2398
2390
|
|
|
2399
2391
|
elif user_input.startswith("/mode"):
|
|
2400
|
-
conf = user_input[len("/mode"):].strip()
|
|
2392
|
+
conf = user_input[len("/mode") :].strip()
|
|
2401
2393
|
if not conf:
|
|
2402
2394
|
print(memory["mode"])
|
|
2403
2395
|
else:
|
|
2404
2396
|
memory["mode"] = conf
|
|
2405
2397
|
|
|
2406
2398
|
elif user_input.startswith("/conf"):
|
|
2407
|
-
conf = user_input[len("/conf"):].strip()
|
|
2399
|
+
conf = user_input[len("/conf") :].strip()
|
|
2408
2400
|
if not conf:
|
|
2409
2401
|
print(memory["conf"])
|
|
2410
2402
|
else:
|
|
@@ -2412,16 +2404,15 @@ def main():
|
|
|
2412
2404
|
elif user_input.startswith("/revert"):
|
|
2413
2405
|
revert()
|
|
2414
2406
|
elif user_input.startswith("/commit"):
|
|
2415
|
-
query = user_input[len("/commit"):].strip()
|
|
2407
|
+
query = user_input[len("/commit") :].strip()
|
|
2416
2408
|
commit(query)
|
|
2417
2409
|
elif user_input.startswith("/help"):
|
|
2418
2410
|
show_help()
|
|
2419
2411
|
elif user_input.startswith("/exclude_dirs"):
|
|
2420
|
-
dir_names = user_input[len(
|
|
2421
|
-
"/exclude_dirs"):].strip().split(",")
|
|
2412
|
+
dir_names = user_input[len("/exclude_dirs") :].strip().split(",")
|
|
2422
2413
|
exclude_dirs(dir_names)
|
|
2423
2414
|
elif user_input.startswith("/ask"):
|
|
2424
|
-
query = user_input[len("/ask"):].strip()
|
|
2415
|
+
query = user_input[len("/ask") :].strip()
|
|
2425
2416
|
if not query:
|
|
2426
2417
|
print("Please enter your question.")
|
|
2427
2418
|
else:
|
|
@@ -2431,38 +2422,45 @@ def main():
|
|
|
2431
2422
|
raise EOFError()
|
|
2432
2423
|
|
|
2433
2424
|
elif user_input.startswith("/coding"):
|
|
2434
|
-
query = user_input[len("/coding"):].strip()
|
|
2425
|
+
query = user_input[len("/coding") :].strip()
|
|
2435
2426
|
if not query:
|
|
2436
2427
|
print("\033[91mPlease enter your request.\033[0m")
|
|
2437
2428
|
continue
|
|
2438
2429
|
coding(query)
|
|
2439
2430
|
elif user_input.startswith("/chat"):
|
|
2440
|
-
query = user_input[len("/chat"):].strip()
|
|
2431
|
+
query = user_input[len("/chat") :].strip()
|
|
2441
2432
|
if not query:
|
|
2442
2433
|
print("\033[91mPlease enter your request.\033[0m")
|
|
2443
2434
|
else:
|
|
2444
2435
|
chat(query)
|
|
2445
2436
|
|
|
2446
2437
|
elif user_input.startswith("/design"):
|
|
2447
|
-
query = user_input[len("/design"):].strip()
|
|
2438
|
+
query = user_input[len("/design") :].strip()
|
|
2448
2439
|
if not query:
|
|
2449
2440
|
print("\033[91mPlease enter your design request.\033[0m")
|
|
2450
2441
|
else:
|
|
2451
2442
|
design(query)
|
|
2452
2443
|
|
|
2453
2444
|
elif user_input.startswith("/summon"):
|
|
2454
|
-
query = user_input[len("/summon"):].strip()
|
|
2445
|
+
query = user_input[len("/summon") :].strip()
|
|
2455
2446
|
if not query:
|
|
2456
2447
|
print("\033[91mPlease enter your request.\033[0m")
|
|
2457
2448
|
else:
|
|
2458
2449
|
summon(query)
|
|
2459
2450
|
|
|
2460
2451
|
elif user_input.startswith("/lib"):
|
|
2461
|
-
args = user_input[len("/lib"):].strip().split()
|
|
2452
|
+
args = user_input[len("/lib") :].strip().split()
|
|
2462
2453
|
lib_command(args)
|
|
2463
2454
|
|
|
2455
|
+
elif user_input.startswith("/mcp"):
|
|
2456
|
+
query = user_input[len("/mcp") :].strip()
|
|
2457
|
+
if not query:
|
|
2458
|
+
print("Please enter your query.")
|
|
2459
|
+
else:
|
|
2460
|
+
mcp(query)
|
|
2461
|
+
|
|
2464
2462
|
elif user_input.startswith("/debug"):
|
|
2465
|
-
code = user_input[len("/debug"):].strip()
|
|
2463
|
+
code = user_input[len("/debug") :].strip()
|
|
2466
2464
|
try:
|
|
2467
2465
|
result = eval(code)
|
|
2468
2466
|
print(f"Debug result: {result}")
|
|
@@ -2473,7 +2471,7 @@ def main():
|
|
|
2473
2471
|
else:
|
|
2474
2472
|
command = user_input
|
|
2475
2473
|
if user_input.startswith("/shell"):
|
|
2476
|
-
command = user_input[len("/shell"):].strip()
|
|
2474
|
+
command = user_input[len("/shell") :].strip()
|
|
2477
2475
|
if not command:
|
|
2478
2476
|
print("Please enter a shell command to execute.")
|
|
2479
2477
|
else:
|
|
@@ -2484,6 +2482,11 @@ def main():
|
|
|
2484
2482
|
except EOFError:
|
|
2485
2483
|
try:
|
|
2486
2484
|
save_memory()
|
|
2485
|
+
try:
|
|
2486
|
+
if get_mcp_server():
|
|
2487
|
+
get_mcp_server().stop()
|
|
2488
|
+
except Exception as e:
|
|
2489
|
+
pass
|
|
2487
2490
|
except Exception as e:
|
|
2488
2491
|
print(
|
|
2489
2492
|
f"\033[91mAn error occurred while saving memory:\033[0m \033[93m{type(e).__name__}\033[0m - {str(e)}"
|