auto-coder 0.1.209__py3-none-any.whl → 0.1.211__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of auto-coder might be problematic. Click here for more details.

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