auto-coder 0.1.259__py3-none-any.whl → 0.1.261__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.259.dist-info → auto_coder-0.1.261.dist-info}/METADATA +1 -1
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.261.dist-info}/RECORD +36 -27
- autocoder/agent/auto_review_commit.py +51 -24
- autocoder/auto_coder.py +24 -1
- autocoder/chat_auto_coder.py +377 -399
- autocoder/chat_auto_coder_lang.py +20 -0
- autocoder/commands/__init__.py +0 -0
- autocoder/commands/auto_command.py +1174 -0
- autocoder/commands/tools.py +533 -0
- autocoder/common/__init__.py +8 -0
- autocoder/common/auto_coder_lang.py +61 -8
- autocoder/common/auto_configure.py +304 -0
- autocoder/common/code_auto_merge.py +2 -2
- autocoder/common/code_auto_merge_diff.py +2 -2
- autocoder/common/code_auto_merge_editblock.py +2 -2
- autocoder/common/code_auto_merge_strict_diff.py +2 -2
- autocoder/common/code_modification_ranker.py +8 -7
- autocoder/common/command_completer.py +557 -0
- autocoder/common/conf_validator.py +245 -0
- autocoder/common/conversation_pruner.py +131 -0
- autocoder/common/git_utils.py +82 -1
- autocoder/common/index_import_export.py +101 -0
- autocoder/common/result_manager.py +115 -0
- autocoder/common/shells.py +22 -6
- autocoder/common/utils_code_auto_generate.py +2 -2
- autocoder/dispacher/actions/action.py +45 -4
- autocoder/dispacher/actions/plugins/action_regex_project.py +13 -1
- autocoder/index/filter/quick_filter.py +22 -7
- autocoder/utils/auto_coder_utils/chat_stream_out.py +13 -6
- autocoder/utils/project_structure.py +15 -0
- autocoder/utils/thread_utils.py +4 -0
- autocoder/version.py +1 -1
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.261.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.261.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.261.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.261.dist-info}/top_level.txt +0 -0
autocoder/chat_auto_coder.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from itertools import product
|
|
1
2
|
from prompt_toolkit.formatted_text import HTML
|
|
2
3
|
from prompt_toolkit.shortcuts import radiolist_dialog
|
|
3
4
|
from prompt_toolkit import prompt
|
|
@@ -22,6 +23,7 @@ from prompt_toolkit.completion import WordCompleter, Completer, Completion
|
|
|
22
23
|
from prompt_toolkit.shortcuts import confirm
|
|
23
24
|
from autocoder.common import AutoCoderArgs
|
|
24
25
|
from pydantic import Field, BaseModel
|
|
26
|
+
from autocoder.common.result_manager import ResultManager
|
|
25
27
|
from autocoder.version import __version__
|
|
26
28
|
from autocoder.auto_coder import main as auto_coder_main
|
|
27
29
|
from autocoder.common.command_completer import CommandTextParser
|
|
@@ -55,6 +57,8 @@ from autocoder.utils.llms import get_single_llm
|
|
|
55
57
|
import pkg_resources
|
|
56
58
|
from autocoder.common.printer import Printer
|
|
57
59
|
from autocoder.utils.thread_utils import run_in_thread,run_in_raw_thread
|
|
60
|
+
from autocoder.common.command_completer import CommandCompleter,FileSystemModel as CCFileSystemModel,MemoryConfig as CCMemoryModel
|
|
61
|
+
from autocoder.common.conf_validator import ConfigValidator
|
|
58
62
|
|
|
59
63
|
class SymbolItem(BaseModel):
|
|
60
64
|
symbol_name: str
|
|
@@ -83,8 +87,8 @@ def parse_arguments():
|
|
|
83
87
|
parser.add_argument(
|
|
84
88
|
"--product_mode",
|
|
85
89
|
type=str,
|
|
86
|
-
default="
|
|
87
|
-
help="The mode of the auto-coder.chat, lite/pro default is
|
|
90
|
+
default="lite",
|
|
91
|
+
help="The mode of the auto-coder.chat, lite/pro default is lite",
|
|
88
92
|
)
|
|
89
93
|
|
|
90
94
|
parser.add_argument("--lite", action="store_true", help="Lite mode")
|
|
@@ -127,6 +131,8 @@ commands = [
|
|
|
127
131
|
"/revert",
|
|
128
132
|
"/index/query",
|
|
129
133
|
"/index/build",
|
|
134
|
+
"/index/export",
|
|
135
|
+
"/index/import",
|
|
130
136
|
"/exclude_dirs",
|
|
131
137
|
"/help",
|
|
132
138
|
"/shell",
|
|
@@ -138,6 +144,7 @@ commands = [
|
|
|
138
144
|
"/design",
|
|
139
145
|
"/mcp",
|
|
140
146
|
"/models",
|
|
147
|
+
"/auto",
|
|
141
148
|
]
|
|
142
149
|
|
|
143
150
|
|
|
@@ -581,6 +588,9 @@ def configure(conf: str, skip_print=False):
|
|
|
581
588
|
if not value:
|
|
582
589
|
printer.print_in_terminal("config_value_empty", style="red")
|
|
583
590
|
return
|
|
591
|
+
product_mode = memory["conf"].get("product_mode",None)
|
|
592
|
+
if product_mode:
|
|
593
|
+
ConfigValidator.validate(key, value, product_mode)
|
|
584
594
|
memory["conf"][key] = value
|
|
585
595
|
save_memory()
|
|
586
596
|
if not skip_print:
|
|
@@ -630,384 +640,6 @@ def get_symbol_list() -> List[SymbolItem]:
|
|
|
630
640
|
return list_of_symbols
|
|
631
641
|
|
|
632
642
|
|
|
633
|
-
class CommandCompleter(Completer):
|
|
634
|
-
def __init__(self, commands):
|
|
635
|
-
self.commands = commands
|
|
636
|
-
self.all_file_names = get_all_file_names_in_project()
|
|
637
|
-
self.all_files = get_all_file_in_project()
|
|
638
|
-
self.all_dir_names = get_all_dir_names_in_project()
|
|
639
|
-
self.all_files_with_dot = get_all_file_in_project_with_dot()
|
|
640
|
-
self.symbol_list = get_symbol_list()
|
|
641
|
-
self.current_file_names = []
|
|
642
|
-
|
|
643
|
-
def get_completions(self, document, complete_event):
|
|
644
|
-
text = document.text_before_cursor
|
|
645
|
-
words = text.split()
|
|
646
|
-
|
|
647
|
-
if len(words) > 0:
|
|
648
|
-
if words[0] == "/mode":
|
|
649
|
-
left_word = text[len("/mode"):]
|
|
650
|
-
for mode in ["normal", "auto_detect", "voice_input"]:
|
|
651
|
-
if mode.startswith(left_word.strip()):
|
|
652
|
-
yield Completion(mode, start_position=-len(left_word.strip()))
|
|
653
|
-
|
|
654
|
-
if words[0] == "/add_files":
|
|
655
|
-
new_text = text[len("/add_files"):]
|
|
656
|
-
parser = CommandTextParser(new_text, words[0])
|
|
657
|
-
parser.add_files()
|
|
658
|
-
current_word = parser.current_word()
|
|
659
|
-
|
|
660
|
-
if parser.last_sub_command() == "/refresh":
|
|
661
|
-
return
|
|
662
|
-
|
|
663
|
-
for command in parser.get_sub_commands():
|
|
664
|
-
if command.startswith(current_word):
|
|
665
|
-
yield Completion(command, start_position=-len(current_word))
|
|
666
|
-
|
|
667
|
-
if parser.first_sub_command() == "/group" and (
|
|
668
|
-
parser.last_sub_command() == "/group"
|
|
669
|
-
or parser.last_sub_command() == "/drop"
|
|
670
|
-
):
|
|
671
|
-
group_names = memory["current_files"]["groups"].keys()
|
|
672
|
-
if "," in current_word:
|
|
673
|
-
current_word = current_word.split(",")[-1]
|
|
674
|
-
|
|
675
|
-
for group_name in group_names:
|
|
676
|
-
if group_name.startswith(current_word):
|
|
677
|
-
yield Completion(
|
|
678
|
-
group_name, start_position=-len(current_word)
|
|
679
|
-
)
|
|
680
|
-
|
|
681
|
-
if parser.first_sub_command() != "/group":
|
|
682
|
-
if current_word and current_word.startswith("."):
|
|
683
|
-
for file_name in self.all_files_with_dot:
|
|
684
|
-
if file_name.startswith(current_word):
|
|
685
|
-
yield Completion(
|
|
686
|
-
file_name, start_position=-
|
|
687
|
-
len(current_word)
|
|
688
|
-
)
|
|
689
|
-
else:
|
|
690
|
-
for file_name in self.all_file_names:
|
|
691
|
-
if file_name.startswith(current_word):
|
|
692
|
-
yield Completion(
|
|
693
|
-
file_name, start_position=-
|
|
694
|
-
len(current_word)
|
|
695
|
-
)
|
|
696
|
-
for file_name in self.all_files:
|
|
697
|
-
if current_word and current_word in file_name:
|
|
698
|
-
yield Completion(
|
|
699
|
-
file_name, start_position=-
|
|
700
|
-
len(current_word)
|
|
701
|
-
)
|
|
702
|
-
elif words[0] in ["/chat", "/coding"]:
|
|
703
|
-
image_extensions = (
|
|
704
|
-
".png",
|
|
705
|
-
".jpg",
|
|
706
|
-
".jpeg",
|
|
707
|
-
".gif",
|
|
708
|
-
".bmp",
|
|
709
|
-
".tiff",
|
|
710
|
-
".tif",
|
|
711
|
-
".webp",
|
|
712
|
-
".svg",
|
|
713
|
-
".ico",
|
|
714
|
-
".heic",
|
|
715
|
-
".heif",
|
|
716
|
-
".raw",
|
|
717
|
-
".cr2",
|
|
718
|
-
".nef",
|
|
719
|
-
".arw",
|
|
720
|
-
".dng",
|
|
721
|
-
".orf",
|
|
722
|
-
".rw2",
|
|
723
|
-
".pef",
|
|
724
|
-
".srw",
|
|
725
|
-
".eps",
|
|
726
|
-
".ai",
|
|
727
|
-
".psd",
|
|
728
|
-
".xcf",
|
|
729
|
-
)
|
|
730
|
-
new_text = text[len(words[0]):]
|
|
731
|
-
parser = CommandTextParser(new_text, words[0])
|
|
732
|
-
|
|
733
|
-
parser.coding()
|
|
734
|
-
current_word = parser.current_word()
|
|
735
|
-
|
|
736
|
-
if len(new_text.strip()) == 0 or new_text.strip() == "/":
|
|
737
|
-
for command in parser.get_sub_commands():
|
|
738
|
-
if command.startswith(current_word):
|
|
739
|
-
yield Completion(command, start_position=-len(current_word))
|
|
740
|
-
|
|
741
|
-
all_tags = parser.tags
|
|
742
|
-
|
|
743
|
-
if current_word.startswith("@"):
|
|
744
|
-
name = current_word[1:]
|
|
745
|
-
target_set = set()
|
|
746
|
-
|
|
747
|
-
for file_name in self.current_file_names:
|
|
748
|
-
base_file_name = os.path.basename(file_name)
|
|
749
|
-
if name in base_file_name:
|
|
750
|
-
target_set.add(base_file_name)
|
|
751
|
-
path_parts = file_name.split(os.sep)
|
|
752
|
-
display_name = (
|
|
753
|
-
os.sep.join(path_parts[-3:])
|
|
754
|
-
if len(path_parts) > 3
|
|
755
|
-
else file_name
|
|
756
|
-
)
|
|
757
|
-
relative_path = os.path.relpath(
|
|
758
|
-
file_name, project_root)
|
|
759
|
-
yield Completion(
|
|
760
|
-
relative_path,
|
|
761
|
-
start_position=-len(name),
|
|
762
|
-
display=f"{display_name} (in active files)",
|
|
763
|
-
)
|
|
764
|
-
|
|
765
|
-
for file_name in self.all_file_names:
|
|
766
|
-
if file_name.startswith(name) and file_name not in target_set:
|
|
767
|
-
target_set.add(file_name)
|
|
768
|
-
|
|
769
|
-
path_parts = file_name.split(os.sep)
|
|
770
|
-
display_name = (
|
|
771
|
-
os.sep.join(path_parts[-3:])
|
|
772
|
-
if len(path_parts) > 3
|
|
773
|
-
else file_name
|
|
774
|
-
)
|
|
775
|
-
relative_path = os.path.relpath(
|
|
776
|
-
file_name, project_root)
|
|
777
|
-
|
|
778
|
-
yield Completion(
|
|
779
|
-
relative_path,
|
|
780
|
-
start_position=-len(name),
|
|
781
|
-
display=f"{display_name}",
|
|
782
|
-
)
|
|
783
|
-
|
|
784
|
-
for file_name in self.all_files:
|
|
785
|
-
if name in file_name and file_name not in target_set:
|
|
786
|
-
path_parts = file_name.split(os.sep)
|
|
787
|
-
display_name = (
|
|
788
|
-
os.sep.join(path_parts[-3:])
|
|
789
|
-
if len(path_parts) > 3
|
|
790
|
-
else file_name
|
|
791
|
-
)
|
|
792
|
-
relative_path = os.path.relpath(
|
|
793
|
-
file_name, project_root)
|
|
794
|
-
yield Completion(
|
|
795
|
-
relative_path,
|
|
796
|
-
start_position=-len(name),
|
|
797
|
-
display=f"{display_name}",
|
|
798
|
-
)
|
|
799
|
-
|
|
800
|
-
if current_word.startswith("@@"):
|
|
801
|
-
name = current_word[2:]
|
|
802
|
-
for symbol in self.symbol_list:
|
|
803
|
-
if name in symbol.symbol_name:
|
|
804
|
-
file_name = symbol.file_name
|
|
805
|
-
path_parts = file_name.split(os.sep)
|
|
806
|
-
display_name = (
|
|
807
|
-
os.sep.join(path_parts[-3:])
|
|
808
|
-
if len(path_parts) > 3
|
|
809
|
-
else symbol.symbol_name
|
|
810
|
-
)
|
|
811
|
-
relative_path = os.path.relpath(
|
|
812
|
-
file_name, project_root)
|
|
813
|
-
yield Completion(
|
|
814
|
-
f"{symbol.symbol_name}(location: {relative_path})",
|
|
815
|
-
start_position=-len(name),
|
|
816
|
-
display=f"{symbol.symbol_name} ({display_name}/{symbol.symbol_type})",
|
|
817
|
-
)
|
|
818
|
-
|
|
819
|
-
tags = [tag for tag in parser.tags]
|
|
820
|
-
|
|
821
|
-
if current_word.startswith("<"):
|
|
822
|
-
name = current_word[1:]
|
|
823
|
-
for tag in ["<img>", "</img>"]:
|
|
824
|
-
if all_tags and all_tags[-1].start_tag == "<img>":
|
|
825
|
-
if tag.startswith(name):
|
|
826
|
-
yield Completion(
|
|
827
|
-
"</img>", start_position=-len(current_word)
|
|
828
|
-
)
|
|
829
|
-
elif tag.startswith(name):
|
|
830
|
-
yield Completion(tag, start_position=-len(current_word))
|
|
831
|
-
|
|
832
|
-
if tags and tags[-1].start_tag == "<img>" and tags[-1].end_tag == "":
|
|
833
|
-
raw_file_name = tags[0].content
|
|
834
|
-
file_name = raw_file_name.strip()
|
|
835
|
-
parent_dir = os.path.dirname(file_name)
|
|
836
|
-
file_basename = os.path.basename(file_name)
|
|
837
|
-
search_dir = parent_dir if parent_dir else "."
|
|
838
|
-
for root, dirs, files in os.walk(search_dir):
|
|
839
|
-
# 只处理直接子目录
|
|
840
|
-
if root != search_dir:
|
|
841
|
-
continue
|
|
842
|
-
|
|
843
|
-
# 补全子目录
|
|
844
|
-
for dir in dirs:
|
|
845
|
-
full_path = os.path.join(root, dir)
|
|
846
|
-
if full_path.startswith(file_name):
|
|
847
|
-
relative_path = os.path.relpath(
|
|
848
|
-
full_path, search_dir)
|
|
849
|
-
yield Completion(
|
|
850
|
-
relative_path,
|
|
851
|
-
start_position=-len(file_basename),
|
|
852
|
-
)
|
|
853
|
-
|
|
854
|
-
# 补全文件
|
|
855
|
-
for file in files:
|
|
856
|
-
if file.lower().endswith(
|
|
857
|
-
image_extensions
|
|
858
|
-
) and file.startswith(file_basename):
|
|
859
|
-
full_path = os.path.join(root, file)
|
|
860
|
-
relative_path = os.path.relpath(
|
|
861
|
-
full_path, search_dir)
|
|
862
|
-
yield Completion(
|
|
863
|
-
relative_path,
|
|
864
|
-
start_position=-len(file_basename),
|
|
865
|
-
)
|
|
866
|
-
|
|
867
|
-
# 只处理一层子目录,然后退出循环
|
|
868
|
-
break
|
|
869
|
-
|
|
870
|
-
elif words[0] == "/remove_files":
|
|
871
|
-
new_words = text[len("/remove_files"):].strip().split(",")
|
|
872
|
-
|
|
873
|
-
is_at_space = text[-1] == " "
|
|
874
|
-
last_word = new_words[-2] if len(new_words) > 1 else ""
|
|
875
|
-
current_word = new_words[-1] if new_words else ""
|
|
876
|
-
|
|
877
|
-
if is_at_space:
|
|
878
|
-
last_word = current_word
|
|
879
|
-
current_word = ""
|
|
880
|
-
|
|
881
|
-
# /remove_files /all [cursor] or /remove_files /all p[cursor]
|
|
882
|
-
if not last_word and not current_word:
|
|
883
|
-
if "/all".startswith(current_word):
|
|
884
|
-
yield Completion("/all", start_position=-len(current_word))
|
|
885
|
-
for file_name in self.current_file_names:
|
|
886
|
-
yield Completion(file_name, start_position=-len(current_word))
|
|
887
|
-
|
|
888
|
-
# /remove_files /a[cursor] or /remove_files p[cursor]
|
|
889
|
-
if current_word:
|
|
890
|
-
if "/all".startswith(current_word):
|
|
891
|
-
yield Completion("/all", start_position=-len(current_word))
|
|
892
|
-
for file_name in self.current_file_names:
|
|
893
|
-
if current_word and current_word in file_name:
|
|
894
|
-
yield Completion(
|
|
895
|
-
file_name, start_position=-len(current_word)
|
|
896
|
-
)
|
|
897
|
-
elif words[0] == "/exclude_dirs":
|
|
898
|
-
new_words = text[len("/exclude_dirs"):].strip().split(",")
|
|
899
|
-
current_word = new_words[-1]
|
|
900
|
-
|
|
901
|
-
for file_name in self.all_dir_names:
|
|
902
|
-
if current_word and current_word in file_name:
|
|
903
|
-
yield Completion(file_name, start_position=-len(current_word))
|
|
904
|
-
|
|
905
|
-
elif words[0] == "/lib":
|
|
906
|
-
new_text = text[len("/lib"):]
|
|
907
|
-
parser = CommandTextParser(new_text, words[0])
|
|
908
|
-
parser.lib()
|
|
909
|
-
current_word = parser.current_word()
|
|
910
|
-
|
|
911
|
-
for command in parser.get_sub_commands():
|
|
912
|
-
if command.startswith(current_word):
|
|
913
|
-
yield Completion(command, start_position=-len(current_word))
|
|
914
|
-
|
|
915
|
-
if parser.last_sub_command() in ["/add", "/remove", "/get"]:
|
|
916
|
-
for lib_name in memory.get("libs", {}).keys():
|
|
917
|
-
if lib_name.startswith(current_word):
|
|
918
|
-
yield Completion(
|
|
919
|
-
lib_name, start_position=-len(current_word)
|
|
920
|
-
)
|
|
921
|
-
elif words[0] == "/mcp":
|
|
922
|
-
new_text = text[len("/mcp"):]
|
|
923
|
-
parser = CommandTextParser(new_text, words[0])
|
|
924
|
-
parser.lib()
|
|
925
|
-
current_word = parser.current_word()
|
|
926
|
-
for command in parser.get_sub_commands():
|
|
927
|
-
if command.startswith(current_word):
|
|
928
|
-
yield Completion(command, start_position=-len(current_word))
|
|
929
|
-
elif words[0] == "/models":
|
|
930
|
-
new_text = text[len("/models"):]
|
|
931
|
-
parser = CommandTextParser(new_text, words[0])
|
|
932
|
-
parser.lib()
|
|
933
|
-
current_word = parser.current_word()
|
|
934
|
-
for command in parser.get_sub_commands():
|
|
935
|
-
if command.startswith(current_word):
|
|
936
|
-
yield Completion(command, start_position=-len(current_word))
|
|
937
|
-
|
|
938
|
-
elif words[0] == "/coding":
|
|
939
|
-
new_text = text[len("/coding"):]
|
|
940
|
-
parser = CommandTextParser(new_text, words[0])
|
|
941
|
-
parser.lib()
|
|
942
|
-
current_word = parser.current_word()
|
|
943
|
-
for command in parser.get_sub_commands():
|
|
944
|
-
if command.startswith(current_word):
|
|
945
|
-
yield Completion(command, start_position=-len(current_word))
|
|
946
|
-
|
|
947
|
-
elif words[0] == "/conf":
|
|
948
|
-
new_words = text[len("/conf"):].strip().split()
|
|
949
|
-
is_at_space = text[-1] == " "
|
|
950
|
-
last_word = new_words[-2] if len(new_words) > 1 else ""
|
|
951
|
-
current_word = new_words[-1] if new_words else ""
|
|
952
|
-
completions = []
|
|
953
|
-
|
|
954
|
-
if is_at_space:
|
|
955
|
-
last_word = current_word
|
|
956
|
-
current_word = ""
|
|
957
|
-
|
|
958
|
-
# /conf /drop [curor] or /conf /drop p[cursor]
|
|
959
|
-
if last_word == "/drop":
|
|
960
|
-
completions = [
|
|
961
|
-
field_name
|
|
962
|
-
for field_name in memory["conf"].keys()
|
|
963
|
-
if field_name.startswith(current_word)
|
|
964
|
-
]
|
|
965
|
-
# /conf [curosr]
|
|
966
|
-
elif not last_word and not current_word:
|
|
967
|
-
completions = [
|
|
968
|
-
"/drop"] if "/drop".startswith(current_word) else []
|
|
969
|
-
completions += [
|
|
970
|
-
field_name + ":"
|
|
971
|
-
for field_name in AutoCoderArgs.model_fields.keys()
|
|
972
|
-
if field_name.startswith(current_word)
|
|
973
|
-
]
|
|
974
|
-
# /conf p[cursor]
|
|
975
|
-
elif not last_word and current_word:
|
|
976
|
-
completions = [
|
|
977
|
-
"/drop"] if "/drop".startswith(current_word) else []
|
|
978
|
-
completions += [
|
|
979
|
-
field_name + ":"
|
|
980
|
-
for field_name in AutoCoderArgs.model_fields.keys()
|
|
981
|
-
if field_name.startswith(current_word)
|
|
982
|
-
]
|
|
983
|
-
|
|
984
|
-
for completion in completions:
|
|
985
|
-
yield Completion(completion, start_position=-len(current_word))
|
|
986
|
-
|
|
987
|
-
else:
|
|
988
|
-
for command in self.commands:
|
|
989
|
-
if command.startswith(text):
|
|
990
|
-
yield Completion(command, start_position=-len(text))
|
|
991
|
-
|
|
992
|
-
else:
|
|
993
|
-
for command in self.commands:
|
|
994
|
-
if command.startswith(text):
|
|
995
|
-
yield Completion(command, start_position=-len(text))
|
|
996
|
-
|
|
997
|
-
def update_current_files(self, files):
|
|
998
|
-
self.current_file_names = [f for f in files]
|
|
999
|
-
|
|
1000
|
-
def refresh_files(self):
|
|
1001
|
-
self.all_file_names = get_all_file_names_in_project()
|
|
1002
|
-
self.all_files = get_all_file_in_project()
|
|
1003
|
-
self.all_dir_names = get_all_dir_names_in_project()
|
|
1004
|
-
self.all_files_with_dot = get_all_file_in_project_with_dot()
|
|
1005
|
-
self.symbol_list = get_symbol_list()
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
completer = CommandCompleter(commands)
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
643
|
def save_memory():
|
|
1012
644
|
with open(os.path.join(base_persist_dir, "memory.json"), "w") as f:
|
|
1013
645
|
json.dump(memory, f, indent=2, ensure_ascii=False)
|
|
@@ -1023,6 +655,21 @@ def load_memory():
|
|
|
1023
655
|
completer.update_current_files(memory["current_files"]["files"])
|
|
1024
656
|
|
|
1025
657
|
|
|
658
|
+
completer = CommandCompleter(commands,
|
|
659
|
+
file_system_model=CCFileSystemModel(project_root=project_root,
|
|
660
|
+
defaut_exclude_dirs=defaut_exclude_dirs,
|
|
661
|
+
get_all_file_names_in_project=get_all_file_names_in_project,
|
|
662
|
+
get_all_file_in_project=get_all_file_in_project,
|
|
663
|
+
get_all_dir_names_in_project=get_all_dir_names_in_project,
|
|
664
|
+
get_all_file_in_project_with_dot=get_all_file_in_project_with_dot,
|
|
665
|
+
get_symbol_list=get_symbol_list
|
|
666
|
+
),
|
|
667
|
+
memory_model=CCMemoryModel(memory=memory,
|
|
668
|
+
save_memory_func=save_memory))
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
|
|
1026
673
|
def print_conf(content:Dict[str,Any]):
|
|
1027
674
|
"""Display configuration dictionary in a Rich table format with enhanced visual styling.
|
|
1028
675
|
|
|
@@ -1069,6 +716,7 @@ def print_conf(content:Dict[str,Any]):
|
|
|
1069
716
|
))
|
|
1070
717
|
|
|
1071
718
|
def revert():
|
|
719
|
+
result_manager = ResultManager()
|
|
1072
720
|
last_yaml_file = get_last_yaml_file("actions")
|
|
1073
721
|
if last_yaml_file:
|
|
1074
722
|
file_path = os.path.join("actions", last_yaml_file)
|
|
@@ -1078,16 +726,24 @@ def revert():
|
|
|
1078
726
|
s = output.getvalue()
|
|
1079
727
|
print(s, flush=True)
|
|
1080
728
|
if "Successfully reverted changes" in s:
|
|
729
|
+
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
730
|
+
}})
|
|
1081
731
|
print(
|
|
1082
732
|
"Reverted the last chat action successfully. Remove the yaml file {file_path}"
|
|
1083
733
|
)
|
|
1084
734
|
os.remove(file_path)
|
|
735
|
+
else:
|
|
736
|
+
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
737
|
+
}})
|
|
1085
738
|
else:
|
|
739
|
+
result_manager.append(content="No previous chat action found to revert.", meta={"action": "revert","success":False, "input":{
|
|
740
|
+
}})
|
|
1086
741
|
print("No previous chat action found to revert.")
|
|
1087
742
|
|
|
1088
743
|
|
|
1089
744
|
def add_files(args: List[str]):
|
|
1090
|
-
|
|
745
|
+
|
|
746
|
+
result_manager = ResultManager()
|
|
1091
747
|
if "groups" not in memory["current_files"]:
|
|
1092
748
|
memory["current_files"]["groups"] = {}
|
|
1093
749
|
if "groups_info" not in memory["current_files"]:
|
|
@@ -1102,6 +758,8 @@ def add_files(args: List[str]):
|
|
|
1102
758
|
|
|
1103
759
|
if not args:
|
|
1104
760
|
printer.print_in_terminal("add_files_no_args", style="red")
|
|
761
|
+
result_manager.append(content=printer.get_message_from_key("add_files_no_args"),
|
|
762
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1105
763
|
return
|
|
1106
764
|
|
|
1107
765
|
if args[0] == "/refresh":
|
|
@@ -1111,6 +769,8 @@ def add_files(args: List[str]):
|
|
|
1111
769
|
Panel("Refreshed file list.",
|
|
1112
770
|
title="Files Refreshed", border_style="green")
|
|
1113
771
|
)
|
|
772
|
+
result_manager.append(content="Files refreshed.",
|
|
773
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1114
774
|
return
|
|
1115
775
|
|
|
1116
776
|
if args[0] == "/group":
|
|
@@ -1120,6 +780,8 @@ def add_files(args: List[str]):
|
|
|
1120
780
|
Panel("No groups defined.", title="Groups",
|
|
1121
781
|
border_style="yellow")
|
|
1122
782
|
)
|
|
783
|
+
result_manager.append(content="No groups defined.",
|
|
784
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1123
785
|
else:
|
|
1124
786
|
table = Table(
|
|
1125
787
|
title="Defined Groups",
|
|
@@ -1150,6 +812,8 @@ def add_files(args: List[str]):
|
|
|
1150
812
|
end_section=(i == len(groups) - 1),
|
|
1151
813
|
)
|
|
1152
814
|
console.print(Panel(table, border_style="blue"))
|
|
815
|
+
result_manager.append(content="Defined groups.",
|
|
816
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1153
817
|
elif len(args) >= 2 and args[1] == "/reset":
|
|
1154
818
|
memory["current_files"]["current_groups"] = []
|
|
1155
819
|
console.print(
|
|
@@ -1159,6 +823,8 @@ def add_files(args: List[str]):
|
|
|
1159
823
|
border_style="green",
|
|
1160
824
|
)
|
|
1161
825
|
)
|
|
826
|
+
result_manager.append(content="Active group names have been reset. If you want to clear the active files, you should use the command /remove_files /all.",
|
|
827
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1162
828
|
elif len(args) >= 3 and args[1] == "/add":
|
|
1163
829
|
group_name = args[2]
|
|
1164
830
|
groups[group_name] = memory["current_files"]["files"].copy()
|
|
@@ -1169,6 +835,9 @@ def add_files(args: List[str]):
|
|
|
1169
835
|
border_style="green",
|
|
1170
836
|
)
|
|
1171
837
|
)
|
|
838
|
+
result_manager.append(content=f"Added group '{group_name}' with current files.",
|
|
839
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
840
|
+
|
|
1172
841
|
elif len(args) >= 3 and args[1] == "/drop":
|
|
1173
842
|
group_name = args[2]
|
|
1174
843
|
if group_name in groups:
|
|
@@ -1185,6 +854,8 @@ def add_files(args: List[str]):
|
|
|
1185
854
|
border_style="green",
|
|
1186
855
|
)
|
|
1187
856
|
)
|
|
857
|
+
result_manager.append(content=f"Dropped group '{group_name}'.",
|
|
858
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1188
859
|
else:
|
|
1189
860
|
console.print(
|
|
1190
861
|
Panel(
|
|
@@ -1193,6 +864,8 @@ def add_files(args: List[str]):
|
|
|
1193
864
|
border_style="red",
|
|
1194
865
|
)
|
|
1195
866
|
)
|
|
867
|
+
result_manager.append(content=f"Group '{group_name}' not found.",
|
|
868
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1196
869
|
elif len(args) == 3 and args[1] == "/set":
|
|
1197
870
|
group_name = args[2]
|
|
1198
871
|
|
|
@@ -1264,6 +937,8 @@ def add_files(args: List[str]):
|
|
|
1264
937
|
border_style="red",
|
|
1265
938
|
)
|
|
1266
939
|
)
|
|
940
|
+
result_manager.append(content=f"Group(s) not found: {', '.join(missing_groups)}",
|
|
941
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1267
942
|
|
|
1268
943
|
if merged_files:
|
|
1269
944
|
memory["current_files"]["files"] = list(merged_files)
|
|
@@ -1299,6 +974,8 @@ def add_files(args: List[str]):
|
|
|
1299
974
|
border_style="green",
|
|
1300
975
|
)
|
|
1301
976
|
)
|
|
977
|
+
result_manager.append(content=f"Active groups: {', '.join(memory['current_files']['current_groups'])}",
|
|
978
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1302
979
|
elif not missing_groups:
|
|
1303
980
|
console.print(
|
|
1304
981
|
Panel(
|
|
@@ -1306,7 +983,9 @@ def add_files(args: List[str]):
|
|
|
1306
983
|
title="No Files Added",
|
|
1307
984
|
border_style="yellow",
|
|
1308
985
|
)
|
|
1309
|
-
|
|
986
|
+
)
|
|
987
|
+
result_manager.append(content="No files in the specified groups.",
|
|
988
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1310
989
|
else:
|
|
1311
990
|
existing_files = memory["current_files"]["files"]
|
|
1312
991
|
matched_files = find_files_in_project(args)
|
|
@@ -1328,9 +1007,13 @@ def add_files(args: List[str]):
|
|
|
1328
1007
|
i == len(files_to_add) - 1
|
|
1329
1008
|
), # 在最后一行之后不添加分割线
|
|
1330
1009
|
)
|
|
1331
|
-
console.print(Panel(table, border_style="green"))
|
|
1010
|
+
console.print(Panel(table, border_style="green"))
|
|
1011
|
+
result_manager.append(content=f"Added files: {', '.join(files_to_add)}",
|
|
1012
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1332
1013
|
else:
|
|
1333
1014
|
printer.print_in_terminal("add_files_matched", style="yellow")
|
|
1015
|
+
result_manager.append(content=f"No files matched.",
|
|
1016
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1334
1017
|
|
|
1335
1018
|
completer.update_current_files(memory["current_files"]["files"])
|
|
1336
1019
|
save_memory()
|
|
@@ -1339,11 +1022,14 @@ def add_files(args: List[str]):
|
|
|
1339
1022
|
def remove_files(file_names: List[str]):
|
|
1340
1023
|
project_root = os.getcwd()
|
|
1341
1024
|
printer = Printer()
|
|
1025
|
+
result_manager = ResultManager()
|
|
1342
1026
|
|
|
1343
1027
|
if "/all" in file_names:
|
|
1344
1028
|
memory["current_files"]["files"] = []
|
|
1345
1029
|
memory["current_files"]["current_groups"] = []
|
|
1346
1030
|
printer.print_in_terminal("remove_files_all", style="green")
|
|
1031
|
+
result_manager.append(content="All files removed.",
|
|
1032
|
+
meta={"action": "remove_files","success":True, "input":{ "file_names": file_names}})
|
|
1347
1033
|
else:
|
|
1348
1034
|
removed_files = []
|
|
1349
1035
|
for file in memory["current_files"]["files"]:
|
|
@@ -1366,9 +1052,13 @@ def remove_files(file_names: List[str]):
|
|
|
1366
1052
|
console = Console()
|
|
1367
1053
|
console.print(
|
|
1368
1054
|
Panel(table, border_style="green",
|
|
1369
|
-
title=printer.get_message_from_key("files_removed")))
|
|
1055
|
+
title=printer.get_message_from_key("files_removed")))
|
|
1056
|
+
result_manager.append(content=f"Removed files: {', '.join(removed_files)}",
|
|
1057
|
+
meta={"action": "remove_files","success":True, "input":{ "file_names": file_names}})
|
|
1370
1058
|
else:
|
|
1371
1059
|
printer.print_in_terminal("remove_files_none", style="yellow")
|
|
1060
|
+
result_manager.append(content=printer.get_message_from_key("remove_files_none"),
|
|
1061
|
+
meta={"action": "remove_files","success":False, "input":{ "file_names": file_names}})
|
|
1372
1062
|
|
|
1373
1063
|
completer.update_current_files(memory["current_files"]["files"])
|
|
1374
1064
|
save_memory()
|
|
@@ -1890,6 +1580,8 @@ def coding(query: str):
|
|
|
1890
1580
|
|
|
1891
1581
|
yaml_content = convert_yaml_config_to_str(yaml_config=yaml_config)
|
|
1892
1582
|
|
|
1583
|
+
md5 = hashlib.md5(yaml_content.encode("utf-8")).hexdigest()
|
|
1584
|
+
|
|
1893
1585
|
execute_file = os.path.join("actions", latest_yaml_file)
|
|
1894
1586
|
with open(os.path.join(execute_file), "w") as f:
|
|
1895
1587
|
f.write(yaml_content)
|
|
@@ -1897,6 +1589,10 @@ def coding(query: str):
|
|
|
1897
1589
|
def execute_chat():
|
|
1898
1590
|
cmd = ["--file", execute_file]
|
|
1899
1591
|
auto_coder_main(cmd)
|
|
1592
|
+
result_manager = ResultManager()
|
|
1593
|
+
result_manager.append(content="", meta={"commit_message": f"auto_coder_{latest_yaml_file}_{md5}","action": "coding", "input":{
|
|
1594
|
+
"query": query
|
|
1595
|
+
}})
|
|
1900
1596
|
|
|
1901
1597
|
execute_chat()
|
|
1902
1598
|
else:
|
|
@@ -2174,11 +1870,18 @@ def generate_shell_command(input_text):
|
|
|
2174
1870
|
auto_coder_main(["agent", "generate_command", "--file", execute_file])
|
|
2175
1871
|
with open(os.path.join(".auto-coder", "exchange.txt"), "r") as f:
|
|
2176
1872
|
shell_script = f.read()
|
|
1873
|
+
result_manager = ResultManager()
|
|
1874
|
+
result_manager.add_result(content=shell_script,meta={
|
|
1875
|
+
"action": "generate_shell_command",
|
|
1876
|
+
"input": {
|
|
1877
|
+
"query": input_text
|
|
1878
|
+
}
|
|
1879
|
+
})
|
|
2177
1880
|
return shell_script
|
|
2178
1881
|
finally:
|
|
2179
1882
|
os.remove(execute_file)
|
|
2180
1883
|
|
|
2181
|
-
def manage_models(
|
|
1884
|
+
def manage_models(query: str):
|
|
2182
1885
|
"""
|
|
2183
1886
|
Handle /models subcommands:
|
|
2184
1887
|
/models /list - List all models (default + custom)
|
|
@@ -2189,7 +1892,8 @@ def manage_models(params, query: str):
|
|
|
2189
1892
|
printer = Printer()
|
|
2190
1893
|
console = Console()
|
|
2191
1894
|
|
|
2192
|
-
|
|
1895
|
+
product_mode = memory.get("product_mode", "lite")
|
|
1896
|
+
if product_mode != "lite":
|
|
2193
1897
|
printer.print_in_terminal("models_lite_only", style="red")
|
|
2194
1898
|
return
|
|
2195
1899
|
|
|
@@ -2240,7 +1944,8 @@ def manage_models(params, query: str):
|
|
|
2240
1944
|
|
|
2241
1945
|
if not subcmd:
|
|
2242
1946
|
printer.print_in_terminal("models_usage")
|
|
2243
|
-
|
|
1947
|
+
|
|
1948
|
+
result_manager = ResultManager()
|
|
2244
1949
|
if subcmd == "/list":
|
|
2245
1950
|
if models_data:
|
|
2246
1951
|
# Sort models by speed (average_speed)
|
|
@@ -2277,8 +1982,21 @@ def manage_models(params, query: str):
|
|
|
2277
1982
|
f"{m.get('average_speed', 0.0):.3f}"
|
|
2278
1983
|
)
|
|
2279
1984
|
console.print(table)
|
|
1985
|
+
result_manager.add_result(content=json.dumps(sorted_models,ensure_ascii=False),meta={
|
|
1986
|
+
"action": "models",
|
|
1987
|
+
"input": {
|
|
1988
|
+
"query": query
|
|
1989
|
+
}
|
|
1990
|
+
})
|
|
1991
|
+
|
|
2280
1992
|
else:
|
|
2281
1993
|
printer.print_in_terminal("models_no_models", style="yellow")
|
|
1994
|
+
result_manager.add_result(content="No models found",meta={
|
|
1995
|
+
"action": "models",
|
|
1996
|
+
"input": {
|
|
1997
|
+
"query": query
|
|
1998
|
+
}
|
|
1999
|
+
})
|
|
2282
2000
|
|
|
2283
2001
|
elif subcmd == "/input_price":
|
|
2284
2002
|
args = query.strip().split()
|
|
@@ -2288,11 +2006,35 @@ def manage_models(params, query: str):
|
|
|
2288
2006
|
price = float(args[1])
|
|
2289
2007
|
if models_module.update_model_input_price(name, price):
|
|
2290
2008
|
printer.print_in_terminal("models_input_price_updated", style="green", name=name, price=price)
|
|
2009
|
+
result_manager.add_result(content=f"models_input_price_updated: {name} {price}",meta={
|
|
2010
|
+
"action": "models",
|
|
2011
|
+
"input": {
|
|
2012
|
+
"query": query
|
|
2013
|
+
}
|
|
2014
|
+
})
|
|
2291
2015
|
else:
|
|
2292
2016
|
printer.print_in_terminal("models_not_found", style="red", name=name)
|
|
2017
|
+
result_manager.add_result(content=f"models_not_found: {name}",meta={
|
|
2018
|
+
"action": "models",
|
|
2019
|
+
"input": {
|
|
2020
|
+
"query": query
|
|
2021
|
+
}
|
|
2022
|
+
})
|
|
2293
2023
|
except ValueError as e:
|
|
2024
|
+
result_manager.add_result(content=f"models_invalid_price: {str(e)}",meta={
|
|
2025
|
+
"action": "models",
|
|
2026
|
+
"input": {
|
|
2027
|
+
"query": query
|
|
2028
|
+
}
|
|
2029
|
+
})
|
|
2294
2030
|
printer.print_in_terminal("models_invalid_price", style="red", error=str(e))
|
|
2295
2031
|
else:
|
|
2032
|
+
result_manager.add_result(content=printer.get_message_from_key("models_input_price_usage"),meta={
|
|
2033
|
+
"action": "models",
|
|
2034
|
+
"input": {
|
|
2035
|
+
"query": query
|
|
2036
|
+
}
|
|
2037
|
+
})
|
|
2296
2038
|
printer.print_in_terminal("models_input_price_usage", style="red")
|
|
2297
2039
|
|
|
2298
2040
|
elif subcmd == "/output_price":
|
|
@@ -2303,11 +2045,35 @@ def manage_models(params, query: str):
|
|
|
2303
2045
|
price = float(args[1])
|
|
2304
2046
|
if models_module.update_model_output_price(name, price):
|
|
2305
2047
|
printer.print_in_terminal("models_output_price_updated", style="green", name=name, price=price)
|
|
2048
|
+
result_manager.add_result(content=f"models_output_price_updated: {name} {price}",meta={
|
|
2049
|
+
"action": "models",
|
|
2050
|
+
"input": {
|
|
2051
|
+
"query": query
|
|
2052
|
+
}
|
|
2053
|
+
})
|
|
2306
2054
|
else:
|
|
2307
2055
|
printer.print_in_terminal("models_not_found", style="red", name=name)
|
|
2056
|
+
result_manager.add_result(content=f"models_not_found: {name}",meta={
|
|
2057
|
+
"action": "models",
|
|
2058
|
+
"input": {
|
|
2059
|
+
"query": query
|
|
2060
|
+
}
|
|
2061
|
+
})
|
|
2308
2062
|
except ValueError as e:
|
|
2309
2063
|
printer.print_in_terminal("models_invalid_price", style="red", error=str(e))
|
|
2064
|
+
result_manager.add_result(content=f"models_invalid_price: {str(e)}",meta={
|
|
2065
|
+
"action": "models",
|
|
2066
|
+
"input": {
|
|
2067
|
+
"query": query
|
|
2068
|
+
}
|
|
2069
|
+
})
|
|
2310
2070
|
else:
|
|
2071
|
+
result_manager.add_result(content=printer.get_message_from_key("models_output_price_usage"),meta={
|
|
2072
|
+
"action": "models",
|
|
2073
|
+
"input": {
|
|
2074
|
+
"query": query
|
|
2075
|
+
}
|
|
2076
|
+
})
|
|
2311
2077
|
printer.print_in_terminal("models_output_price_usage", style="red")
|
|
2312
2078
|
|
|
2313
2079
|
elif subcmd == "/speed":
|
|
@@ -2318,11 +2084,35 @@ def manage_models(params, query: str):
|
|
|
2318
2084
|
speed = float(args[1])
|
|
2319
2085
|
if models_module.update_model_speed(name, speed):
|
|
2320
2086
|
printer.print_in_terminal("models_speed_updated", style="green", name=name, speed=speed)
|
|
2087
|
+
result_manager.add_result(content=f"models_speed_updated: {name} {speed}",meta={
|
|
2088
|
+
"action": "models",
|
|
2089
|
+
"input": {
|
|
2090
|
+
"query": query
|
|
2091
|
+
}
|
|
2092
|
+
})
|
|
2321
2093
|
else:
|
|
2322
2094
|
printer.print_in_terminal("models_not_found", style="red", name=name)
|
|
2095
|
+
result_manager.add_result(content=f"models_not_found: {name}",meta={
|
|
2096
|
+
"action": "models",
|
|
2097
|
+
"input": {
|
|
2098
|
+
"query": query
|
|
2099
|
+
}
|
|
2100
|
+
})
|
|
2323
2101
|
except ValueError as e:
|
|
2324
2102
|
printer.print_in_terminal("models_invalid_speed", style="red", error=str(e))
|
|
2103
|
+
result_manager.add_result(content=f"models_invalid_speed: {str(e)}",meta={
|
|
2104
|
+
"action": "models",
|
|
2105
|
+
"input": {
|
|
2106
|
+
"query": query
|
|
2107
|
+
}
|
|
2108
|
+
})
|
|
2325
2109
|
else:
|
|
2110
|
+
result_manager.add_result(content=printer.get_message_from_key("models_speed_usage"),meta={
|
|
2111
|
+
"action": "models",
|
|
2112
|
+
"input": {
|
|
2113
|
+
"query": query
|
|
2114
|
+
}
|
|
2115
|
+
})
|
|
2326
2116
|
printer.print_in_terminal("models_speed_usage", style="red")
|
|
2327
2117
|
|
|
2328
2118
|
elif subcmd == "/speed-test":
|
|
@@ -2343,7 +2133,14 @@ def manage_models(params, query: str):
|
|
|
2343
2133
|
if args and args[0].isdigit():
|
|
2344
2134
|
test_rounds = int(args[0])
|
|
2345
2135
|
|
|
2346
|
-
render_speed_test_in_terminal(
|
|
2136
|
+
render_speed_test_in_terminal(product_mode, test_rounds,enable_long_context=enable_long_context)
|
|
2137
|
+
## 等待优化,获取明细数据
|
|
2138
|
+
result_manager.add_result(content="models test success",meta={
|
|
2139
|
+
"action": "models",
|
|
2140
|
+
"input": {
|
|
2141
|
+
"query": query
|
|
2142
|
+
}
|
|
2143
|
+
})
|
|
2347
2144
|
|
|
2348
2145
|
elif subcmd == "/add":
|
|
2349
2146
|
# Support both simplified and legacy formats
|
|
@@ -2353,11 +2150,29 @@ def manage_models(params, query: str):
|
|
|
2353
2150
|
name, api_key = args[0], args[1]
|
|
2354
2151
|
result = models_module.update_model_with_api_key(name, api_key)
|
|
2355
2152
|
if result:
|
|
2153
|
+
result_manager.add_result(content=f"models_added: {name}",meta={
|
|
2154
|
+
"action": "models",
|
|
2155
|
+
"input": {
|
|
2156
|
+
"query": query
|
|
2157
|
+
}
|
|
2158
|
+
})
|
|
2356
2159
|
printer.print_in_terminal("models_added", style="green", name=name)
|
|
2357
2160
|
else:
|
|
2161
|
+
result_manager.add_result(content=f"models_add_failed: {name}",meta={
|
|
2162
|
+
"action": "models",
|
|
2163
|
+
"input": {
|
|
2164
|
+
"query": query
|
|
2165
|
+
}
|
|
2166
|
+
})
|
|
2358
2167
|
printer.print_in_terminal("models_add_failed", style="red", name=name)
|
|
2359
2168
|
else:
|
|
2360
2169
|
printer.print_in_terminal("models_add_usage", style="red")
|
|
2170
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_usage"),meta={
|
|
2171
|
+
"action": "models",
|
|
2172
|
+
"input": {
|
|
2173
|
+
"query": query
|
|
2174
|
+
}
|
|
2175
|
+
})
|
|
2361
2176
|
|
|
2362
2177
|
elif subcmd == "/add_model":
|
|
2363
2178
|
# Parse key=value pairs: /models /add_model name=abc base_url=http://xx ...
|
|
@@ -2379,6 +2194,12 @@ def manage_models(params, query: str):
|
|
|
2379
2194
|
# Check duplication
|
|
2380
2195
|
if any(m["name"] == data_dict["name"] for m in models_data):
|
|
2381
2196
|
printer.print_in_terminal("models_add_model_exists", style="yellow", name=data_dict["name"])
|
|
2197
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_model_exists",name=data_dict["name"]),meta={
|
|
2198
|
+
"action": "models",
|
|
2199
|
+
"input": {
|
|
2200
|
+
"query": query
|
|
2201
|
+
}
|
|
2202
|
+
})
|
|
2382
2203
|
return
|
|
2383
2204
|
|
|
2384
2205
|
# Create model with defaults
|
|
@@ -2395,22 +2216,51 @@ def manage_models(params, query: str):
|
|
|
2395
2216
|
models_data.append(final_model)
|
|
2396
2217
|
models_module.save_models(models_data)
|
|
2397
2218
|
printer.print_in_terminal("models_add_model_success", style="green", name=data_dict["name"])
|
|
2219
|
+
result_manager.add_result(content=f"models_add_model_success: {data_dict['name']}",meta={
|
|
2220
|
+
"action": "models",
|
|
2221
|
+
"input": {
|
|
2222
|
+
"query": query
|
|
2223
|
+
}
|
|
2224
|
+
})
|
|
2398
2225
|
|
|
2399
2226
|
elif subcmd == "/remove":
|
|
2400
2227
|
args = query.strip().split(" ")
|
|
2401
2228
|
if len(args) < 1:
|
|
2402
2229
|
printer.print_in_terminal("models_add_usage", style="red")
|
|
2230
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_usage"),meta={
|
|
2231
|
+
"action": "models",
|
|
2232
|
+
"input": {
|
|
2233
|
+
"query": query
|
|
2234
|
+
}
|
|
2235
|
+
})
|
|
2403
2236
|
return
|
|
2404
2237
|
name = args[0]
|
|
2405
2238
|
filtered_models = [m for m in models_data if m["name"] != name]
|
|
2406
2239
|
if len(filtered_models) == len(models_data):
|
|
2407
2240
|
printer.print_in_terminal("models_add_model_remove", style="yellow", name=name)
|
|
2241
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_model_remove",name=name),meta={
|
|
2242
|
+
"action": "models",
|
|
2243
|
+
"input": {
|
|
2244
|
+
"query": query
|
|
2245
|
+
}
|
|
2246
|
+
})
|
|
2408
2247
|
return
|
|
2409
2248
|
models_module.save_models(filtered_models)
|
|
2410
2249
|
printer.print_in_terminal("models_add_model_removed", style="green", name=name)
|
|
2411
|
-
|
|
2250
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_model_removed",name=name),meta={
|
|
2251
|
+
"action": "models",
|
|
2252
|
+
"input": {
|
|
2253
|
+
"query": query
|
|
2254
|
+
}
|
|
2255
|
+
})
|
|
2412
2256
|
else:
|
|
2413
2257
|
printer.print_in_terminal("models_unknown_subcmd", style="yellow", subcmd=subcmd)
|
|
2258
|
+
result_manager.add_result(content=printer.get_message_from_key("models_unknown_subcmd",subcmd=subcmd),meta={
|
|
2259
|
+
"action": "models",
|
|
2260
|
+
"input": {
|
|
2261
|
+
"query": query
|
|
2262
|
+
}
|
|
2263
|
+
})
|
|
2414
2264
|
|
|
2415
2265
|
def exclude_dirs(dir_names: List[str]):
|
|
2416
2266
|
new_dirs = dir_names
|
|
@@ -2452,6 +2302,63 @@ def index_build():
|
|
|
2452
2302
|
os.remove(yaml_file)
|
|
2453
2303
|
|
|
2454
2304
|
|
|
2305
|
+
def get_final_config()->AutoCoderArgs:
|
|
2306
|
+
conf = memory.get("conf", {})
|
|
2307
|
+
yaml_config = {
|
|
2308
|
+
"include_file": ["./base/base.yml"],
|
|
2309
|
+
"auto_merge": conf.get("auto_merge", "editblock"),
|
|
2310
|
+
"human_as_model": conf.get("human_as_model", "false") == "true",
|
|
2311
|
+
"skip_build_index": conf.get("skip_build_index", "true") == "true",
|
|
2312
|
+
"skip_confirm": conf.get("skip_confirm", "true") == "true",
|
|
2313
|
+
"silence": conf.get("silence", "true") == "true",
|
|
2314
|
+
"include_project_structure": conf.get("include_project_structure", "true")
|
|
2315
|
+
== "true",
|
|
2316
|
+
}
|
|
2317
|
+
for key, value in conf.items():
|
|
2318
|
+
converted_value = convert_config_value(key, value)
|
|
2319
|
+
if converted_value is not None:
|
|
2320
|
+
yaml_config[key] = converted_value
|
|
2321
|
+
|
|
2322
|
+
temp_yaml = os.path.join("actions", f"{uuid.uuid4()}.yml")
|
|
2323
|
+
try:
|
|
2324
|
+
with open(temp_yaml, "w") as f:
|
|
2325
|
+
f.write(convert_yaml_config_to_str(yaml_config=yaml_config))
|
|
2326
|
+
args = convert_yaml_to_config(temp_yaml)
|
|
2327
|
+
finally:
|
|
2328
|
+
if os.path.exists(temp_yaml):
|
|
2329
|
+
os.remove(temp_yaml)
|
|
2330
|
+
return args
|
|
2331
|
+
|
|
2332
|
+
def help(query: str):
|
|
2333
|
+
from autocoder.common.auto_configure import ConfigAutoTuner,MemoryConfig,AutoConfigRequest
|
|
2334
|
+
args = get_final_config()
|
|
2335
|
+
product_mode = memory.get("product_mode", "lite")
|
|
2336
|
+
llm = get_single_llm(args.chat_model or args.model, product_mode=product_mode)
|
|
2337
|
+
auto_config_tuner = ConfigAutoTuner(llm=llm, memory_config=MemoryConfig(memory=memory, save_memory_func=save_memory))
|
|
2338
|
+
auto_config_tuner.tune(AutoConfigRequest(query=query))
|
|
2339
|
+
|
|
2340
|
+
@run_in_raw_thread()
|
|
2341
|
+
def index_export(export_path: str):
|
|
2342
|
+
from autocoder.common.index_import_export import export_index
|
|
2343
|
+
from autocoder.common.printer import Printer
|
|
2344
|
+
printer = Printer()
|
|
2345
|
+
project_root = os.getcwd()
|
|
2346
|
+
if export_index(project_root, export_path):
|
|
2347
|
+
printer.print_in_terminal("index_export_success", path=export_path)
|
|
2348
|
+
else:
|
|
2349
|
+
printer.print_in_terminal("index_export_fail", path=export_path)
|
|
2350
|
+
|
|
2351
|
+
@run_in_raw_thread()
|
|
2352
|
+
def index_import(import_path: str):
|
|
2353
|
+
from autocoder.common.index_import_export import import_index
|
|
2354
|
+
from autocoder.common.printer import Printer
|
|
2355
|
+
printer = Printer()
|
|
2356
|
+
project_root = os.getcwd()
|
|
2357
|
+
if import_index(project_root, import_path):
|
|
2358
|
+
printer.print_in_terminal("index_import_success", path=import_path)
|
|
2359
|
+
else:
|
|
2360
|
+
printer.print_in_terminal("index_import_fail", path=import_path)
|
|
2361
|
+
|
|
2455
2362
|
@run_in_raw_thread()
|
|
2456
2363
|
def index_query(query: str):
|
|
2457
2364
|
conf = memory.get("conf", {})
|
|
@@ -2634,6 +2541,58 @@ def lib_command(args: List[str]):
|
|
|
2634
2541
|
else:
|
|
2635
2542
|
console.print(f"Unknown subcommand: {subcommand}")
|
|
2636
2543
|
|
|
2544
|
+
@run_in_raw_thread()
|
|
2545
|
+
def auto_command(params,query: str):
|
|
2546
|
+
"""处理/auto指令"""
|
|
2547
|
+
from autocoder.commands.auto_command import CommandAutoTuner, AutoCommandRequest, CommandConfig, MemoryConfig
|
|
2548
|
+
args = get_final_config()
|
|
2549
|
+
# help(query)
|
|
2550
|
+
|
|
2551
|
+
# 准备请求参数
|
|
2552
|
+
request = AutoCommandRequest(
|
|
2553
|
+
user_input=query
|
|
2554
|
+
)
|
|
2555
|
+
|
|
2556
|
+
# 初始化调优器
|
|
2557
|
+
llm = get_single_llm(args.chat_model or args.model,product_mode=args.product_mode)
|
|
2558
|
+
tuner = CommandAutoTuner(llm,
|
|
2559
|
+
args=args,
|
|
2560
|
+
memory_config=MemoryConfig(memory=memory, save_memory_func=save_memory),
|
|
2561
|
+
command_config=CommandConfig(
|
|
2562
|
+
add_files=add_files,
|
|
2563
|
+
remove_files=remove_files,
|
|
2564
|
+
list_files=list_files,
|
|
2565
|
+
conf=configure,
|
|
2566
|
+
revert=revert,
|
|
2567
|
+
commit=commit,
|
|
2568
|
+
help=help,
|
|
2569
|
+
exclude_dirs=exclude_dirs,
|
|
2570
|
+
ask=ask,
|
|
2571
|
+
chat=chat,
|
|
2572
|
+
coding=coding,
|
|
2573
|
+
design=design,
|
|
2574
|
+
summon=summon,
|
|
2575
|
+
lib=lib_command,
|
|
2576
|
+
mcp=mcp,
|
|
2577
|
+
models=manage_models,
|
|
2578
|
+
index_build=index_build,
|
|
2579
|
+
index_query=index_query,
|
|
2580
|
+
execute_shell_command=execute_shell_command,
|
|
2581
|
+
generate_shell_command=generate_shell_command
|
|
2582
|
+
))
|
|
2583
|
+
|
|
2584
|
+
# 生成建议
|
|
2585
|
+
response = tuner.analyze(request)
|
|
2586
|
+
printer = Printer()
|
|
2587
|
+
# 显示建议
|
|
2588
|
+
console = Console()
|
|
2589
|
+
console.print(Panel(
|
|
2590
|
+
Markdown(response.reasoning or ""),
|
|
2591
|
+
title=printer.get_message_from_key_with_format("auto_command_reasoning_title"),
|
|
2592
|
+
border_style="blue",
|
|
2593
|
+
padding=(1, 2)
|
|
2594
|
+
))
|
|
2595
|
+
|
|
2637
2596
|
|
|
2638
2597
|
def main():
|
|
2639
2598
|
from autocoder.rag.variable_holder import VariableHolder
|
|
@@ -2691,7 +2650,7 @@ def main():
|
|
|
2691
2650
|
@kb.add("c-k")
|
|
2692
2651
|
def _(event):
|
|
2693
2652
|
if "mode" not in memory:
|
|
2694
|
-
memory["mode"] = "
|
|
2653
|
+
memory["mode"] = "auto_detect"
|
|
2695
2654
|
|
|
2696
2655
|
current_mode = memory["mode"]
|
|
2697
2656
|
if current_mode == "normal":
|
|
@@ -2715,7 +2674,7 @@ def main():
|
|
|
2715
2674
|
|
|
2716
2675
|
def get_bottom_toolbar():
|
|
2717
2676
|
if "mode" not in memory:
|
|
2718
|
-
memory["mode"] = "
|
|
2677
|
+
memory["mode"] = "auto_detect"
|
|
2719
2678
|
mode = memory["mode"]
|
|
2720
2679
|
human_as_model = memory["conf"].get("human_as_model", "false")
|
|
2721
2680
|
if mode not in MODES:
|
|
@@ -2777,7 +2736,7 @@ def main():
|
|
|
2777
2736
|
new_prompt = ""
|
|
2778
2737
|
|
|
2779
2738
|
if "mode" not in memory:
|
|
2780
|
-
memory["mode"] = "
|
|
2739
|
+
memory["mode"] = "auto_detect"
|
|
2781
2740
|
|
|
2782
2741
|
# 处理 user_input 的空格
|
|
2783
2742
|
if user_input:
|
|
@@ -2790,11 +2749,8 @@ def main():
|
|
|
2790
2749
|
and user_input
|
|
2791
2750
|
and not user_input.startswith("/")
|
|
2792
2751
|
):
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
execute_shell_command(shell_script)
|
|
2796
|
-
else:
|
|
2797
|
-
continue
|
|
2752
|
+
auto_command(ARGS,user_input)
|
|
2753
|
+
|
|
2798
2754
|
elif memory["mode"] == "voice_input" and not user_input.startswith("/"):
|
|
2799
2755
|
text = voice_input()
|
|
2800
2756
|
new_prompt = "/coding " + text
|
|
@@ -2816,6 +2772,20 @@ def main():
|
|
|
2816
2772
|
|
|
2817
2773
|
elif user_input.startswith("/index/build"):
|
|
2818
2774
|
index_build()
|
|
2775
|
+
|
|
2776
|
+
elif user_input.startswith("/index/export"):
|
|
2777
|
+
export_path = user_input[len("/index/export"):].strip()
|
|
2778
|
+
if not export_path:
|
|
2779
|
+
print("Please specify the export path")
|
|
2780
|
+
else:
|
|
2781
|
+
index_export(export_path)
|
|
2782
|
+
|
|
2783
|
+
elif user_input.startswith("/index/import"):
|
|
2784
|
+
import_path = user_input[len("/index/import"):].strip()
|
|
2785
|
+
if not import_path:
|
|
2786
|
+
print("Please specify the import path")
|
|
2787
|
+
else:
|
|
2788
|
+
index_import(import_path)
|
|
2819
2789
|
|
|
2820
2790
|
elif user_input.startswith("/list_files"):
|
|
2821
2791
|
list_files()
|
|
@@ -2825,7 +2795,7 @@ def main():
|
|
|
2825
2795
|
if not query:
|
|
2826
2796
|
print("Please enter your query.")
|
|
2827
2797
|
else:
|
|
2828
|
-
manage_models(
|
|
2798
|
+
manage_models(query)
|
|
2829
2799
|
|
|
2830
2800
|
elif user_input.startswith("/mode"):
|
|
2831
2801
|
conf = user_input[len("/mode"):].strip()
|
|
@@ -2846,7 +2816,12 @@ def main():
|
|
|
2846
2816
|
query = user_input[len("/commit"):].strip()
|
|
2847
2817
|
commit(query)
|
|
2848
2818
|
elif user_input.startswith("/help"):
|
|
2849
|
-
|
|
2819
|
+
query = user_input[len("/help"):].strip()
|
|
2820
|
+
if not query:
|
|
2821
|
+
show_help()
|
|
2822
|
+
else:
|
|
2823
|
+
help(query)
|
|
2824
|
+
|
|
2850
2825
|
elif user_input.startswith("/exclude_dirs"):
|
|
2851
2826
|
dir_names = user_input[len(
|
|
2852
2827
|
"/exclude_dirs"):].strip().split(",")
|
|
@@ -2899,6 +2874,9 @@ def main():
|
|
|
2899
2874
|
else:
|
|
2900
2875
|
mcp(query)
|
|
2901
2876
|
|
|
2877
|
+
elif user_input.startswith("/auto"):
|
|
2878
|
+
query = user_input[len("/auto"):].strip()
|
|
2879
|
+
auto_command(ARGS,query)
|
|
2902
2880
|
elif user_input.startswith("/debug"):
|
|
2903
2881
|
code = user_input[len("/debug"):].strip()
|
|
2904
2882
|
try:
|