auto-coder 0.1.259__py3-none-any.whl → 0.1.260__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.260.dist-info}/METADATA +1 -1
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.260.dist-info}/RECORD +25 -20
- autocoder/auto_coder.py +24 -1
- autocoder/chat_auto_coder.py +327 -399
- autocoder/chat_auto_coder_lang.py +2 -0
- autocoder/commands/__init__.py +0 -0
- autocoder/commands/auto_command.py +1145 -0
- autocoder/commands/tools.py +533 -0
- autocoder/common/auto_coder_lang.py +34 -6
- autocoder/common/auto_configure.py +304 -0
- autocoder/common/code_modification_ranker.py +8 -7
- autocoder/common/command_completer.py +566 -0
- autocoder/common/git_utils.py +82 -1
- autocoder/common/result_manager.py +115 -0
- autocoder/common/utils_code_auto_generate.py +2 -2
- autocoder/dispacher/actions/action.py +8 -4
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -1
- autocoder/index/filter/quick_filter.py +14 -2
- autocoder/utils/auto_coder_utils/chat_stream_out.py +13 -6
- autocoder/utils/thread_utils.py +4 -0
- autocoder/version.py +1 -1
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.260.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.260.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.260.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.259.dist-info → auto_coder-0.1.260.dist-info}/top_level.txt +0 -0
autocoder/chat_auto_coder.py
CHANGED
|
@@ -22,6 +22,7 @@ from prompt_toolkit.completion import WordCompleter, Completer, Completion
|
|
|
22
22
|
from prompt_toolkit.shortcuts import confirm
|
|
23
23
|
from autocoder.common import AutoCoderArgs
|
|
24
24
|
from pydantic import Field, BaseModel
|
|
25
|
+
from autocoder.common.result_manager import ResultManager
|
|
25
26
|
from autocoder.version import __version__
|
|
26
27
|
from autocoder.auto_coder import main as auto_coder_main
|
|
27
28
|
from autocoder.common.command_completer import CommandTextParser
|
|
@@ -55,6 +56,7 @@ from autocoder.utils.llms import get_single_llm
|
|
|
55
56
|
import pkg_resources
|
|
56
57
|
from autocoder.common.printer import Printer
|
|
57
58
|
from autocoder.utils.thread_utils import run_in_thread,run_in_raw_thread
|
|
59
|
+
from autocoder.common.command_completer import CommandCompleter,FileSystemModel as CCFileSystemModel,MemoryConfig as CCMemoryModel
|
|
58
60
|
|
|
59
61
|
class SymbolItem(BaseModel):
|
|
60
62
|
symbol_name: str
|
|
@@ -83,8 +85,8 @@ def parse_arguments():
|
|
|
83
85
|
parser.add_argument(
|
|
84
86
|
"--product_mode",
|
|
85
87
|
type=str,
|
|
86
|
-
default="
|
|
87
|
-
help="The mode of the auto-coder.chat, lite/pro default is
|
|
88
|
+
default="lite",
|
|
89
|
+
help="The mode of the auto-coder.chat, lite/pro default is lite",
|
|
88
90
|
)
|
|
89
91
|
|
|
90
92
|
parser.add_argument("--lite", action="store_true", help="Lite mode")
|
|
@@ -138,6 +140,7 @@ commands = [
|
|
|
138
140
|
"/design",
|
|
139
141
|
"/mcp",
|
|
140
142
|
"/models",
|
|
143
|
+
"/auto",
|
|
141
144
|
]
|
|
142
145
|
|
|
143
146
|
|
|
@@ -630,384 +633,6 @@ def get_symbol_list() -> List[SymbolItem]:
|
|
|
630
633
|
return list_of_symbols
|
|
631
634
|
|
|
632
635
|
|
|
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
636
|
def save_memory():
|
|
1012
637
|
with open(os.path.join(base_persist_dir, "memory.json"), "w") as f:
|
|
1013
638
|
json.dump(memory, f, indent=2, ensure_ascii=False)
|
|
@@ -1023,6 +648,21 @@ def load_memory():
|
|
|
1023
648
|
completer.update_current_files(memory["current_files"]["files"])
|
|
1024
649
|
|
|
1025
650
|
|
|
651
|
+
completer = CommandCompleter(commands,
|
|
652
|
+
file_system_model=CCFileSystemModel(project_root=project_root,
|
|
653
|
+
defaut_exclude_dirs=defaut_exclude_dirs,
|
|
654
|
+
get_all_file_names_in_project=get_all_file_names_in_project,
|
|
655
|
+
get_all_file_in_project=get_all_file_in_project,
|
|
656
|
+
get_all_dir_names_in_project=get_all_dir_names_in_project,
|
|
657
|
+
get_all_file_in_project_with_dot=get_all_file_in_project_with_dot,
|
|
658
|
+
get_symbol_list=get_symbol_list
|
|
659
|
+
),
|
|
660
|
+
memory_model=CCMemoryModel(memory=memory,
|
|
661
|
+
save_memory_func=save_memory))
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
|
|
1026
666
|
def print_conf(content:Dict[str,Any]):
|
|
1027
667
|
"""Display configuration dictionary in a Rich table format with enhanced visual styling.
|
|
1028
668
|
|
|
@@ -1069,6 +709,7 @@ def print_conf(content:Dict[str,Any]):
|
|
|
1069
709
|
))
|
|
1070
710
|
|
|
1071
711
|
def revert():
|
|
712
|
+
result_manager = ResultManager()
|
|
1072
713
|
last_yaml_file = get_last_yaml_file("actions")
|
|
1073
714
|
if last_yaml_file:
|
|
1074
715
|
file_path = os.path.join("actions", last_yaml_file)
|
|
@@ -1078,16 +719,24 @@ def revert():
|
|
|
1078
719
|
s = output.getvalue()
|
|
1079
720
|
print(s, flush=True)
|
|
1080
721
|
if "Successfully reverted changes" in s:
|
|
722
|
+
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
723
|
+
}})
|
|
1081
724
|
print(
|
|
1082
725
|
"Reverted the last chat action successfully. Remove the yaml file {file_path}"
|
|
1083
726
|
)
|
|
1084
727
|
os.remove(file_path)
|
|
728
|
+
else:
|
|
729
|
+
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
730
|
+
}})
|
|
1085
731
|
else:
|
|
732
|
+
result_manager.append(content="No previous chat action found to revert.", meta={"action": "revert","success":False, "input":{
|
|
733
|
+
}})
|
|
1086
734
|
print("No previous chat action found to revert.")
|
|
1087
735
|
|
|
1088
736
|
|
|
1089
737
|
def add_files(args: List[str]):
|
|
1090
|
-
|
|
738
|
+
|
|
739
|
+
result_manager = ResultManager()
|
|
1091
740
|
if "groups" not in memory["current_files"]:
|
|
1092
741
|
memory["current_files"]["groups"] = {}
|
|
1093
742
|
if "groups_info" not in memory["current_files"]:
|
|
@@ -1102,6 +751,8 @@ def add_files(args: List[str]):
|
|
|
1102
751
|
|
|
1103
752
|
if not args:
|
|
1104
753
|
printer.print_in_terminal("add_files_no_args", style="red")
|
|
754
|
+
result_manager.append(content=printer.get_message_from_key("add_files_no_args"),
|
|
755
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1105
756
|
return
|
|
1106
757
|
|
|
1107
758
|
if args[0] == "/refresh":
|
|
@@ -1111,6 +762,8 @@ def add_files(args: List[str]):
|
|
|
1111
762
|
Panel("Refreshed file list.",
|
|
1112
763
|
title="Files Refreshed", border_style="green")
|
|
1113
764
|
)
|
|
765
|
+
result_manager.append(content="Files refreshed.",
|
|
766
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1114
767
|
return
|
|
1115
768
|
|
|
1116
769
|
if args[0] == "/group":
|
|
@@ -1120,6 +773,8 @@ def add_files(args: List[str]):
|
|
|
1120
773
|
Panel("No groups defined.", title="Groups",
|
|
1121
774
|
border_style="yellow")
|
|
1122
775
|
)
|
|
776
|
+
result_manager.append(content="No groups defined.",
|
|
777
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1123
778
|
else:
|
|
1124
779
|
table = Table(
|
|
1125
780
|
title="Defined Groups",
|
|
@@ -1150,6 +805,8 @@ def add_files(args: List[str]):
|
|
|
1150
805
|
end_section=(i == len(groups) - 1),
|
|
1151
806
|
)
|
|
1152
807
|
console.print(Panel(table, border_style="blue"))
|
|
808
|
+
result_manager.append(content="Defined groups.",
|
|
809
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1153
810
|
elif len(args) >= 2 and args[1] == "/reset":
|
|
1154
811
|
memory["current_files"]["current_groups"] = []
|
|
1155
812
|
console.print(
|
|
@@ -1159,6 +816,8 @@ def add_files(args: List[str]):
|
|
|
1159
816
|
border_style="green",
|
|
1160
817
|
)
|
|
1161
818
|
)
|
|
819
|
+
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.",
|
|
820
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1162
821
|
elif len(args) >= 3 and args[1] == "/add":
|
|
1163
822
|
group_name = args[2]
|
|
1164
823
|
groups[group_name] = memory["current_files"]["files"].copy()
|
|
@@ -1169,6 +828,9 @@ def add_files(args: List[str]):
|
|
|
1169
828
|
border_style="green",
|
|
1170
829
|
)
|
|
1171
830
|
)
|
|
831
|
+
result_manager.append(content=f"Added group '{group_name}' with current files.",
|
|
832
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
833
|
+
|
|
1172
834
|
elif len(args) >= 3 and args[1] == "/drop":
|
|
1173
835
|
group_name = args[2]
|
|
1174
836
|
if group_name in groups:
|
|
@@ -1185,6 +847,8 @@ def add_files(args: List[str]):
|
|
|
1185
847
|
border_style="green",
|
|
1186
848
|
)
|
|
1187
849
|
)
|
|
850
|
+
result_manager.append(content=f"Dropped group '{group_name}'.",
|
|
851
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1188
852
|
else:
|
|
1189
853
|
console.print(
|
|
1190
854
|
Panel(
|
|
@@ -1193,6 +857,8 @@ def add_files(args: List[str]):
|
|
|
1193
857
|
border_style="red",
|
|
1194
858
|
)
|
|
1195
859
|
)
|
|
860
|
+
result_manager.append(content=f"Group '{group_name}' not found.",
|
|
861
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1196
862
|
elif len(args) == 3 and args[1] == "/set":
|
|
1197
863
|
group_name = args[2]
|
|
1198
864
|
|
|
@@ -1264,6 +930,8 @@ def add_files(args: List[str]):
|
|
|
1264
930
|
border_style="red",
|
|
1265
931
|
)
|
|
1266
932
|
)
|
|
933
|
+
result_manager.append(content=f"Group(s) not found: {', '.join(missing_groups)}",
|
|
934
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1267
935
|
|
|
1268
936
|
if merged_files:
|
|
1269
937
|
memory["current_files"]["files"] = list(merged_files)
|
|
@@ -1299,6 +967,8 @@ def add_files(args: List[str]):
|
|
|
1299
967
|
border_style="green",
|
|
1300
968
|
)
|
|
1301
969
|
)
|
|
970
|
+
result_manager.append(content=f"Active groups: {', '.join(memory['current_files']['current_groups'])}",
|
|
971
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1302
972
|
elif not missing_groups:
|
|
1303
973
|
console.print(
|
|
1304
974
|
Panel(
|
|
@@ -1306,7 +976,9 @@ def add_files(args: List[str]):
|
|
|
1306
976
|
title="No Files Added",
|
|
1307
977
|
border_style="yellow",
|
|
1308
978
|
)
|
|
1309
|
-
|
|
979
|
+
)
|
|
980
|
+
result_manager.append(content="No files in the specified groups.",
|
|
981
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1310
982
|
else:
|
|
1311
983
|
existing_files = memory["current_files"]["files"]
|
|
1312
984
|
matched_files = find_files_in_project(args)
|
|
@@ -1328,9 +1000,13 @@ def add_files(args: List[str]):
|
|
|
1328
1000
|
i == len(files_to_add) - 1
|
|
1329
1001
|
), # 在最后一行之后不添加分割线
|
|
1330
1002
|
)
|
|
1331
|
-
console.print(Panel(table, border_style="green"))
|
|
1003
|
+
console.print(Panel(table, border_style="green"))
|
|
1004
|
+
result_manager.append(content=f"Added files: {', '.join(files_to_add)}",
|
|
1005
|
+
meta={"action": "add_files","success":True, "input":{ "args": args}})
|
|
1332
1006
|
else:
|
|
1333
1007
|
printer.print_in_terminal("add_files_matched", style="yellow")
|
|
1008
|
+
result_manager.append(content=f"No files matched.",
|
|
1009
|
+
meta={"action": "add_files","success":False, "input":{ "args": args}})
|
|
1334
1010
|
|
|
1335
1011
|
completer.update_current_files(memory["current_files"]["files"])
|
|
1336
1012
|
save_memory()
|
|
@@ -1339,11 +1015,14 @@ def add_files(args: List[str]):
|
|
|
1339
1015
|
def remove_files(file_names: List[str]):
|
|
1340
1016
|
project_root = os.getcwd()
|
|
1341
1017
|
printer = Printer()
|
|
1018
|
+
result_manager = ResultManager()
|
|
1342
1019
|
|
|
1343
1020
|
if "/all" in file_names:
|
|
1344
1021
|
memory["current_files"]["files"] = []
|
|
1345
1022
|
memory["current_files"]["current_groups"] = []
|
|
1346
1023
|
printer.print_in_terminal("remove_files_all", style="green")
|
|
1024
|
+
result_manager.append(content="All files removed.",
|
|
1025
|
+
meta={"action": "remove_files","success":True, "input":{ "file_names": file_names}})
|
|
1347
1026
|
else:
|
|
1348
1027
|
removed_files = []
|
|
1349
1028
|
for file in memory["current_files"]["files"]:
|
|
@@ -1366,9 +1045,13 @@ def remove_files(file_names: List[str]):
|
|
|
1366
1045
|
console = Console()
|
|
1367
1046
|
console.print(
|
|
1368
1047
|
Panel(table, border_style="green",
|
|
1369
|
-
title=printer.get_message_from_key("files_removed")))
|
|
1048
|
+
title=printer.get_message_from_key("files_removed")))
|
|
1049
|
+
result_manager.append(content=f"Removed files: {', '.join(removed_files)}",
|
|
1050
|
+
meta={"action": "remove_files","success":True, "input":{ "file_names": file_names}})
|
|
1370
1051
|
else:
|
|
1371
1052
|
printer.print_in_terminal("remove_files_none", style="yellow")
|
|
1053
|
+
result_manager.append(content=printer.get_message_from_key("remove_files_none"),
|
|
1054
|
+
meta={"action": "remove_files","success":False, "input":{ "file_names": file_names}})
|
|
1372
1055
|
|
|
1373
1056
|
completer.update_current_files(memory["current_files"]["files"])
|
|
1374
1057
|
save_memory()
|
|
@@ -1890,6 +1573,8 @@ def coding(query: str):
|
|
|
1890
1573
|
|
|
1891
1574
|
yaml_content = convert_yaml_config_to_str(yaml_config=yaml_config)
|
|
1892
1575
|
|
|
1576
|
+
md5 = hashlib.md5(yaml_content.encode("utf-8")).hexdigest()
|
|
1577
|
+
|
|
1893
1578
|
execute_file = os.path.join("actions", latest_yaml_file)
|
|
1894
1579
|
with open(os.path.join(execute_file), "w") as f:
|
|
1895
1580
|
f.write(yaml_content)
|
|
@@ -1897,6 +1582,10 @@ def coding(query: str):
|
|
|
1897
1582
|
def execute_chat():
|
|
1898
1583
|
cmd = ["--file", execute_file]
|
|
1899
1584
|
auto_coder_main(cmd)
|
|
1585
|
+
result_manager = ResultManager()
|
|
1586
|
+
result_manager.append(content="", meta={"commit_message": f"auto_coder_{latest_yaml_file}_{md5}","action": "coding", "input":{
|
|
1587
|
+
"query": query
|
|
1588
|
+
}})
|
|
1900
1589
|
|
|
1901
1590
|
execute_chat()
|
|
1902
1591
|
else:
|
|
@@ -2178,7 +1867,7 @@ def generate_shell_command(input_text):
|
|
|
2178
1867
|
finally:
|
|
2179
1868
|
os.remove(execute_file)
|
|
2180
1869
|
|
|
2181
|
-
def manage_models(
|
|
1870
|
+
def manage_models(query: str):
|
|
2182
1871
|
"""
|
|
2183
1872
|
Handle /models subcommands:
|
|
2184
1873
|
/models /list - List all models (default + custom)
|
|
@@ -2189,7 +1878,8 @@ def manage_models(params, query: str):
|
|
|
2189
1878
|
printer = Printer()
|
|
2190
1879
|
console = Console()
|
|
2191
1880
|
|
|
2192
|
-
|
|
1881
|
+
product_mode = memory.get("product_mode", "lite")
|
|
1882
|
+
if product_mode != "lite":
|
|
2193
1883
|
printer.print_in_terminal("models_lite_only", style="red")
|
|
2194
1884
|
return
|
|
2195
1885
|
|
|
@@ -2240,7 +1930,8 @@ def manage_models(params, query: str):
|
|
|
2240
1930
|
|
|
2241
1931
|
if not subcmd:
|
|
2242
1932
|
printer.print_in_terminal("models_usage")
|
|
2243
|
-
|
|
1933
|
+
|
|
1934
|
+
result_manager = ResultManager()
|
|
2244
1935
|
if subcmd == "/list":
|
|
2245
1936
|
if models_data:
|
|
2246
1937
|
# Sort models by speed (average_speed)
|
|
@@ -2277,8 +1968,21 @@ def manage_models(params, query: str):
|
|
|
2277
1968
|
f"{m.get('average_speed', 0.0):.3f}"
|
|
2278
1969
|
)
|
|
2279
1970
|
console.print(table)
|
|
1971
|
+
result_manager.add_result(content=json.dumps(sorted_models,ensure_ascii=False),meta={
|
|
1972
|
+
"action": "models",
|
|
1973
|
+
"input": {
|
|
1974
|
+
"query": query
|
|
1975
|
+
}
|
|
1976
|
+
})
|
|
1977
|
+
|
|
2280
1978
|
else:
|
|
2281
1979
|
printer.print_in_terminal("models_no_models", style="yellow")
|
|
1980
|
+
result_manager.add_result(content="No models found",meta={
|
|
1981
|
+
"action": "models",
|
|
1982
|
+
"input": {
|
|
1983
|
+
"query": query
|
|
1984
|
+
}
|
|
1985
|
+
})
|
|
2282
1986
|
|
|
2283
1987
|
elif subcmd == "/input_price":
|
|
2284
1988
|
args = query.strip().split()
|
|
@@ -2288,11 +1992,35 @@ def manage_models(params, query: str):
|
|
|
2288
1992
|
price = float(args[1])
|
|
2289
1993
|
if models_module.update_model_input_price(name, price):
|
|
2290
1994
|
printer.print_in_terminal("models_input_price_updated", style="green", name=name, price=price)
|
|
1995
|
+
result_manager.add_result(content=f"models_input_price_updated: {name} {price}",meta={
|
|
1996
|
+
"action": "models",
|
|
1997
|
+
"input": {
|
|
1998
|
+
"query": query
|
|
1999
|
+
}
|
|
2000
|
+
})
|
|
2291
2001
|
else:
|
|
2292
2002
|
printer.print_in_terminal("models_not_found", style="red", name=name)
|
|
2003
|
+
result_manager.add_result(content=f"models_not_found: {name}",meta={
|
|
2004
|
+
"action": "models",
|
|
2005
|
+
"input": {
|
|
2006
|
+
"query": query
|
|
2007
|
+
}
|
|
2008
|
+
})
|
|
2293
2009
|
except ValueError as e:
|
|
2010
|
+
result_manager.add_result(content=f"models_invalid_price: {str(e)}",meta={
|
|
2011
|
+
"action": "models",
|
|
2012
|
+
"input": {
|
|
2013
|
+
"query": query
|
|
2014
|
+
}
|
|
2015
|
+
})
|
|
2294
2016
|
printer.print_in_terminal("models_invalid_price", style="red", error=str(e))
|
|
2295
2017
|
else:
|
|
2018
|
+
result_manager.add_result(content=printer.get_message_from_key("models_input_price_usage"),meta={
|
|
2019
|
+
"action": "models",
|
|
2020
|
+
"input": {
|
|
2021
|
+
"query": query
|
|
2022
|
+
}
|
|
2023
|
+
})
|
|
2296
2024
|
printer.print_in_terminal("models_input_price_usage", style="red")
|
|
2297
2025
|
|
|
2298
2026
|
elif subcmd == "/output_price":
|
|
@@ -2303,11 +2031,35 @@ def manage_models(params, query: str):
|
|
|
2303
2031
|
price = float(args[1])
|
|
2304
2032
|
if models_module.update_model_output_price(name, price):
|
|
2305
2033
|
printer.print_in_terminal("models_output_price_updated", style="green", name=name, price=price)
|
|
2034
|
+
result_manager.add_result(content=f"models_output_price_updated: {name} {price}",meta={
|
|
2035
|
+
"action": "models",
|
|
2036
|
+
"input": {
|
|
2037
|
+
"query": query
|
|
2038
|
+
}
|
|
2039
|
+
})
|
|
2306
2040
|
else:
|
|
2307
2041
|
printer.print_in_terminal("models_not_found", style="red", name=name)
|
|
2042
|
+
result_manager.add_result(content=f"models_not_found: {name}",meta={
|
|
2043
|
+
"action": "models",
|
|
2044
|
+
"input": {
|
|
2045
|
+
"query": query
|
|
2046
|
+
}
|
|
2047
|
+
})
|
|
2308
2048
|
except ValueError as e:
|
|
2309
2049
|
printer.print_in_terminal("models_invalid_price", style="red", error=str(e))
|
|
2050
|
+
result_manager.add_result(content=f"models_invalid_price: {str(e)}",meta={
|
|
2051
|
+
"action": "models",
|
|
2052
|
+
"input": {
|
|
2053
|
+
"query": query
|
|
2054
|
+
}
|
|
2055
|
+
})
|
|
2310
2056
|
else:
|
|
2057
|
+
result_manager.add_result(content=printer.get_message_from_key("models_output_price_usage"),meta={
|
|
2058
|
+
"action": "models",
|
|
2059
|
+
"input": {
|
|
2060
|
+
"query": query
|
|
2061
|
+
}
|
|
2062
|
+
})
|
|
2311
2063
|
printer.print_in_terminal("models_output_price_usage", style="red")
|
|
2312
2064
|
|
|
2313
2065
|
elif subcmd == "/speed":
|
|
@@ -2318,11 +2070,35 @@ def manage_models(params, query: str):
|
|
|
2318
2070
|
speed = float(args[1])
|
|
2319
2071
|
if models_module.update_model_speed(name, speed):
|
|
2320
2072
|
printer.print_in_terminal("models_speed_updated", style="green", name=name, speed=speed)
|
|
2073
|
+
result_manager.add_result(content=f"models_speed_updated: {name} {speed}",meta={
|
|
2074
|
+
"action": "models",
|
|
2075
|
+
"input": {
|
|
2076
|
+
"query": query
|
|
2077
|
+
}
|
|
2078
|
+
})
|
|
2321
2079
|
else:
|
|
2322
2080
|
printer.print_in_terminal("models_not_found", style="red", name=name)
|
|
2081
|
+
result_manager.add_result(content=f"models_not_found: {name}",meta={
|
|
2082
|
+
"action": "models",
|
|
2083
|
+
"input": {
|
|
2084
|
+
"query": query
|
|
2085
|
+
}
|
|
2086
|
+
})
|
|
2323
2087
|
except ValueError as e:
|
|
2324
2088
|
printer.print_in_terminal("models_invalid_speed", style="red", error=str(e))
|
|
2089
|
+
result_manager.add_result(content=f"models_invalid_speed: {str(e)}",meta={
|
|
2090
|
+
"action": "models",
|
|
2091
|
+
"input": {
|
|
2092
|
+
"query": query
|
|
2093
|
+
}
|
|
2094
|
+
})
|
|
2325
2095
|
else:
|
|
2096
|
+
result_manager.add_result(content=printer.get_message_from_key("models_speed_usage"),meta={
|
|
2097
|
+
"action": "models",
|
|
2098
|
+
"input": {
|
|
2099
|
+
"query": query
|
|
2100
|
+
}
|
|
2101
|
+
})
|
|
2326
2102
|
printer.print_in_terminal("models_speed_usage", style="red")
|
|
2327
2103
|
|
|
2328
2104
|
elif subcmd == "/speed-test":
|
|
@@ -2343,7 +2119,14 @@ def manage_models(params, query: str):
|
|
|
2343
2119
|
if args and args[0].isdigit():
|
|
2344
2120
|
test_rounds = int(args[0])
|
|
2345
2121
|
|
|
2346
|
-
render_speed_test_in_terminal(
|
|
2122
|
+
render_speed_test_in_terminal(product_mode, test_rounds,enable_long_context=enable_long_context)
|
|
2123
|
+
## 等待优化,获取明细数据
|
|
2124
|
+
result_manager.add_result(content="models test success",meta={
|
|
2125
|
+
"action": "models",
|
|
2126
|
+
"input": {
|
|
2127
|
+
"query": query
|
|
2128
|
+
}
|
|
2129
|
+
})
|
|
2347
2130
|
|
|
2348
2131
|
elif subcmd == "/add":
|
|
2349
2132
|
# Support both simplified and legacy formats
|
|
@@ -2353,11 +2136,29 @@ def manage_models(params, query: str):
|
|
|
2353
2136
|
name, api_key = args[0], args[1]
|
|
2354
2137
|
result = models_module.update_model_with_api_key(name, api_key)
|
|
2355
2138
|
if result:
|
|
2139
|
+
result_manager.add_result(content=f"models_added: {name}",meta={
|
|
2140
|
+
"action": "models",
|
|
2141
|
+
"input": {
|
|
2142
|
+
"query": query
|
|
2143
|
+
}
|
|
2144
|
+
})
|
|
2356
2145
|
printer.print_in_terminal("models_added", style="green", name=name)
|
|
2357
2146
|
else:
|
|
2147
|
+
result_manager.add_result(content=f"models_add_failed: {name}",meta={
|
|
2148
|
+
"action": "models",
|
|
2149
|
+
"input": {
|
|
2150
|
+
"query": query
|
|
2151
|
+
}
|
|
2152
|
+
})
|
|
2358
2153
|
printer.print_in_terminal("models_add_failed", style="red", name=name)
|
|
2359
2154
|
else:
|
|
2360
2155
|
printer.print_in_terminal("models_add_usage", style="red")
|
|
2156
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_usage"),meta={
|
|
2157
|
+
"action": "models",
|
|
2158
|
+
"input": {
|
|
2159
|
+
"query": query
|
|
2160
|
+
}
|
|
2161
|
+
})
|
|
2361
2162
|
|
|
2362
2163
|
elif subcmd == "/add_model":
|
|
2363
2164
|
# Parse key=value pairs: /models /add_model name=abc base_url=http://xx ...
|
|
@@ -2379,6 +2180,12 @@ def manage_models(params, query: str):
|
|
|
2379
2180
|
# Check duplication
|
|
2380
2181
|
if any(m["name"] == data_dict["name"] for m in models_data):
|
|
2381
2182
|
printer.print_in_terminal("models_add_model_exists", style="yellow", name=data_dict["name"])
|
|
2183
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_model_exists",name=data_dict["name"]),meta={
|
|
2184
|
+
"action": "models",
|
|
2185
|
+
"input": {
|
|
2186
|
+
"query": query
|
|
2187
|
+
}
|
|
2188
|
+
})
|
|
2382
2189
|
return
|
|
2383
2190
|
|
|
2384
2191
|
# Create model with defaults
|
|
@@ -2395,22 +2202,51 @@ def manage_models(params, query: str):
|
|
|
2395
2202
|
models_data.append(final_model)
|
|
2396
2203
|
models_module.save_models(models_data)
|
|
2397
2204
|
printer.print_in_terminal("models_add_model_success", style="green", name=data_dict["name"])
|
|
2205
|
+
result_manager.add_result(content=f"models_add_model_success: {data_dict['name']}",meta={
|
|
2206
|
+
"action": "models",
|
|
2207
|
+
"input": {
|
|
2208
|
+
"query": query
|
|
2209
|
+
}
|
|
2210
|
+
})
|
|
2398
2211
|
|
|
2399
2212
|
elif subcmd == "/remove":
|
|
2400
2213
|
args = query.strip().split(" ")
|
|
2401
2214
|
if len(args) < 1:
|
|
2402
2215
|
printer.print_in_terminal("models_add_usage", style="red")
|
|
2216
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_usage"),meta={
|
|
2217
|
+
"action": "models",
|
|
2218
|
+
"input": {
|
|
2219
|
+
"query": query
|
|
2220
|
+
}
|
|
2221
|
+
})
|
|
2403
2222
|
return
|
|
2404
2223
|
name = args[0]
|
|
2405
2224
|
filtered_models = [m for m in models_data if m["name"] != name]
|
|
2406
2225
|
if len(filtered_models) == len(models_data):
|
|
2407
2226
|
printer.print_in_terminal("models_add_model_remove", style="yellow", name=name)
|
|
2227
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_model_remove",name=name),meta={
|
|
2228
|
+
"action": "models",
|
|
2229
|
+
"input": {
|
|
2230
|
+
"query": query
|
|
2231
|
+
}
|
|
2232
|
+
})
|
|
2408
2233
|
return
|
|
2409
2234
|
models_module.save_models(filtered_models)
|
|
2410
2235
|
printer.print_in_terminal("models_add_model_removed", style="green", name=name)
|
|
2411
|
-
|
|
2236
|
+
result_manager.add_result(content=printer.get_message_from_key("models_add_model_removed",name=name),meta={
|
|
2237
|
+
"action": "models",
|
|
2238
|
+
"input": {
|
|
2239
|
+
"query": query
|
|
2240
|
+
}
|
|
2241
|
+
})
|
|
2412
2242
|
else:
|
|
2413
2243
|
printer.print_in_terminal("models_unknown_subcmd", style="yellow", subcmd=subcmd)
|
|
2244
|
+
result_manager.add_result(content=printer.get_message_from_key("models_unknown_subcmd",subcmd=subcmd),meta={
|
|
2245
|
+
"action": "models",
|
|
2246
|
+
"input": {
|
|
2247
|
+
"query": query
|
|
2248
|
+
}
|
|
2249
|
+
})
|
|
2414
2250
|
|
|
2415
2251
|
def exclude_dirs(dir_names: List[str]):
|
|
2416
2252
|
new_dirs = dir_names
|
|
@@ -2452,6 +2288,41 @@ def index_build():
|
|
|
2452
2288
|
os.remove(yaml_file)
|
|
2453
2289
|
|
|
2454
2290
|
|
|
2291
|
+
def get_final_config()->AutoCoderArgs:
|
|
2292
|
+
conf = memory.get("conf", {})
|
|
2293
|
+
yaml_config = {
|
|
2294
|
+
"include_file": ["./base/base.yml"],
|
|
2295
|
+
"auto_merge": conf.get("auto_merge", "editblock"),
|
|
2296
|
+
"human_as_model": conf.get("human_as_model", "false") == "true",
|
|
2297
|
+
"skip_build_index": conf.get("skip_build_index", "true") == "true",
|
|
2298
|
+
"skip_confirm": conf.get("skip_confirm", "true") == "true",
|
|
2299
|
+
"silence": conf.get("silence", "true") == "true",
|
|
2300
|
+
"include_project_structure": conf.get("include_project_structure", "true")
|
|
2301
|
+
== "true",
|
|
2302
|
+
}
|
|
2303
|
+
for key, value in conf.items():
|
|
2304
|
+
converted_value = convert_config_value(key, value)
|
|
2305
|
+
if converted_value is not None:
|
|
2306
|
+
yaml_config[key] = converted_value
|
|
2307
|
+
|
|
2308
|
+
temp_yaml = os.path.join("actions", f"{uuid.uuid4()}.yml")
|
|
2309
|
+
try:
|
|
2310
|
+
with open(temp_yaml, "w") as f:
|
|
2311
|
+
f.write(convert_yaml_config_to_str(yaml_config=yaml_config))
|
|
2312
|
+
args = convert_yaml_to_config(temp_yaml)
|
|
2313
|
+
finally:
|
|
2314
|
+
if os.path.exists(temp_yaml):
|
|
2315
|
+
os.remove(temp_yaml)
|
|
2316
|
+
return args
|
|
2317
|
+
|
|
2318
|
+
def help(query: str):
|
|
2319
|
+
from autocoder.common.auto_configure import ConfigAutoTuner,MemoryConfig,AutoConfigRequest
|
|
2320
|
+
args = get_final_config()
|
|
2321
|
+
product_mode = memory.get("product_mode", "lite")
|
|
2322
|
+
llm = get_single_llm(args.chat_model or args.model, product_mode=product_mode)
|
|
2323
|
+
auto_config_tuner = ConfigAutoTuner(llm=llm, memory_config=MemoryConfig(memory=memory, save_memory_func=save_memory))
|
|
2324
|
+
auto_config_tuner.tune(AutoConfigRequest(query=query))
|
|
2325
|
+
|
|
2455
2326
|
@run_in_raw_thread()
|
|
2456
2327
|
def index_query(query: str):
|
|
2457
2328
|
conf = memory.get("conf", {})
|
|
@@ -2634,6 +2505,58 @@ def lib_command(args: List[str]):
|
|
|
2634
2505
|
else:
|
|
2635
2506
|
console.print(f"Unknown subcommand: {subcommand}")
|
|
2636
2507
|
|
|
2508
|
+
@run_in_raw_thread()
|
|
2509
|
+
def auto_command(params,query: str):
|
|
2510
|
+
"""处理/auto指令"""
|
|
2511
|
+
from autocoder.commands.auto_command import CommandAutoTuner, AutoCommandRequest, CommandConfig, MemoryConfig
|
|
2512
|
+
args = get_final_config()
|
|
2513
|
+
# help(query)
|
|
2514
|
+
|
|
2515
|
+
# 准备请求参数
|
|
2516
|
+
request = AutoCommandRequest(
|
|
2517
|
+
user_input=query
|
|
2518
|
+
)
|
|
2519
|
+
|
|
2520
|
+
# 初始化调优器
|
|
2521
|
+
llm = get_single_llm(args.chat_model or args.model,product_mode=args.product_mode)
|
|
2522
|
+
tuner = CommandAutoTuner(llm,
|
|
2523
|
+
args=args,
|
|
2524
|
+
memory_config=MemoryConfig(memory=memory, save_memory_func=save_memory),
|
|
2525
|
+
command_config=CommandConfig(
|
|
2526
|
+
add_files=add_files,
|
|
2527
|
+
remove_files=remove_files,
|
|
2528
|
+
list_files=list_files,
|
|
2529
|
+
conf=configure,
|
|
2530
|
+
revert=revert,
|
|
2531
|
+
commit=commit,
|
|
2532
|
+
help=help,
|
|
2533
|
+
exclude_dirs=exclude_dirs,
|
|
2534
|
+
ask=ask,
|
|
2535
|
+
chat=chat,
|
|
2536
|
+
coding=coding,
|
|
2537
|
+
design=design,
|
|
2538
|
+
summon=summon,
|
|
2539
|
+
lib=lib_command,
|
|
2540
|
+
mcp=mcp,
|
|
2541
|
+
models=manage_models,
|
|
2542
|
+
index_build=index_build,
|
|
2543
|
+
index_query=index_query,
|
|
2544
|
+
execute_shell_command=execute_shell_command,
|
|
2545
|
+
generate_shell_command=generate_shell_command
|
|
2546
|
+
))
|
|
2547
|
+
|
|
2548
|
+
# 生成建议
|
|
2549
|
+
response = tuner.analyze(request)
|
|
2550
|
+
|
|
2551
|
+
# 显示建议
|
|
2552
|
+
console = Console()
|
|
2553
|
+
console.print(Panel(
|
|
2554
|
+
Markdown(response.reasoning or ""),
|
|
2555
|
+
title="Reasoning",
|
|
2556
|
+
border_style="blue",
|
|
2557
|
+
padding=(1, 2)
|
|
2558
|
+
))
|
|
2559
|
+
|
|
2637
2560
|
|
|
2638
2561
|
def main():
|
|
2639
2562
|
from autocoder.rag.variable_holder import VariableHolder
|
|
@@ -2691,7 +2614,7 @@ def main():
|
|
|
2691
2614
|
@kb.add("c-k")
|
|
2692
2615
|
def _(event):
|
|
2693
2616
|
if "mode" not in memory:
|
|
2694
|
-
memory["mode"] = "
|
|
2617
|
+
memory["mode"] = "auto_detect"
|
|
2695
2618
|
|
|
2696
2619
|
current_mode = memory["mode"]
|
|
2697
2620
|
if current_mode == "normal":
|
|
@@ -2715,7 +2638,7 @@ def main():
|
|
|
2715
2638
|
|
|
2716
2639
|
def get_bottom_toolbar():
|
|
2717
2640
|
if "mode" not in memory:
|
|
2718
|
-
memory["mode"] = "
|
|
2641
|
+
memory["mode"] = "auto_detect"
|
|
2719
2642
|
mode = memory["mode"]
|
|
2720
2643
|
human_as_model = memory["conf"].get("human_as_model", "false")
|
|
2721
2644
|
if mode not in MODES:
|
|
@@ -2777,7 +2700,7 @@ def main():
|
|
|
2777
2700
|
new_prompt = ""
|
|
2778
2701
|
|
|
2779
2702
|
if "mode" not in memory:
|
|
2780
|
-
memory["mode"] = "
|
|
2703
|
+
memory["mode"] = "auto_detect"
|
|
2781
2704
|
|
|
2782
2705
|
# 处理 user_input 的空格
|
|
2783
2706
|
if user_input:
|
|
@@ -2790,11 +2713,8 @@ def main():
|
|
|
2790
2713
|
and user_input
|
|
2791
2714
|
and not user_input.startswith("/")
|
|
2792
2715
|
):
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
execute_shell_command(shell_script)
|
|
2796
|
-
else:
|
|
2797
|
-
continue
|
|
2716
|
+
auto_command(ARGS,user_input)
|
|
2717
|
+
|
|
2798
2718
|
elif memory["mode"] == "voice_input" and not user_input.startswith("/"):
|
|
2799
2719
|
text = voice_input()
|
|
2800
2720
|
new_prompt = "/coding " + text
|
|
@@ -2825,7 +2745,7 @@ def main():
|
|
|
2825
2745
|
if not query:
|
|
2826
2746
|
print("Please enter your query.")
|
|
2827
2747
|
else:
|
|
2828
|
-
manage_models(
|
|
2748
|
+
manage_models(query)
|
|
2829
2749
|
|
|
2830
2750
|
elif user_input.startswith("/mode"):
|
|
2831
2751
|
conf = user_input[len("/mode"):].strip()
|
|
@@ -2846,7 +2766,12 @@ def main():
|
|
|
2846
2766
|
query = user_input[len("/commit"):].strip()
|
|
2847
2767
|
commit(query)
|
|
2848
2768
|
elif user_input.startswith("/help"):
|
|
2849
|
-
|
|
2769
|
+
query = user_input[len("/help"):].strip()
|
|
2770
|
+
if not query:
|
|
2771
|
+
show_help()
|
|
2772
|
+
else:
|
|
2773
|
+
help(query)
|
|
2774
|
+
|
|
2850
2775
|
elif user_input.startswith("/exclude_dirs"):
|
|
2851
2776
|
dir_names = user_input[len(
|
|
2852
2777
|
"/exclude_dirs"):].strip().split(",")
|
|
@@ -2899,6 +2824,9 @@ def main():
|
|
|
2899
2824
|
else:
|
|
2900
2825
|
mcp(query)
|
|
2901
2826
|
|
|
2827
|
+
elif user_input.startswith("/auto"):
|
|
2828
|
+
query = user_input[len("/auto"):].strip()
|
|
2829
|
+
auto_command(ARGS,query)
|
|
2902
2830
|
elif user_input.startswith("/debug"):
|
|
2903
2831
|
code = user_input[len("/debug"):].strip()
|
|
2904
2832
|
try:
|