auto-coder 0.1.258__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.

Files changed (30) hide show
  1. {auto_coder-0.1.258.dist-info → auto_coder-0.1.260.dist-info}/METADATA +1 -1
  2. {auto_coder-0.1.258.dist-info → auto_coder-0.1.260.dist-info}/RECORD +30 -25
  3. autocoder/auto_coder.py +25 -23
  4. autocoder/auto_coder_rag.py +7 -7
  5. autocoder/auto_coder_rag_client_mcp.py +1 -1
  6. autocoder/chat_auto_coder.py +471 -523
  7. autocoder/chat_auto_coder_lang.py +2 -0
  8. autocoder/commands/__init__.py +0 -0
  9. autocoder/commands/auto_command.py +1145 -0
  10. autocoder/commands/tools.py +533 -0
  11. autocoder/common/auto_coder_lang.py +34 -6
  12. autocoder/common/auto_configure.py +304 -0
  13. autocoder/common/code_modification_ranker.py +8 -7
  14. autocoder/common/command_completer.py +566 -0
  15. autocoder/common/command_templates.py +7 -3
  16. autocoder/common/git_utils.py +82 -1
  17. autocoder/common/result_manager.py +115 -0
  18. autocoder/common/utils_code_auto_generate.py +2 -2
  19. autocoder/dispacher/actions/action.py +8 -4
  20. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -1
  21. autocoder/index/entry.py +1 -1
  22. autocoder/index/filter/quick_filter.py +14 -2
  23. autocoder/rag/raw_rag.py +1 -1
  24. autocoder/utils/auto_coder_utils/chat_stream_out.py +13 -6
  25. autocoder/utils/thread_utils.py +4 -0
  26. autocoder/version.py +1 -1
  27. {auto_coder-0.1.258.dist-info → auto_coder-0.1.260.dist-info}/LICENSE +0 -0
  28. {auto_coder-0.1.258.dist-info → auto_coder-0.1.260.dist-info}/WHEEL +0 -0
  29. {auto_coder-0.1.258.dist-info → auto_coder-0.1.260.dist-info}/entry_points.txt +0 -0
  30. {auto_coder-0.1.258.dist-info → auto_coder-0.1.260.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,9 @@
1
1
  from prompt_toolkit.completion import Completer, Completion, CompleteEvent
2
2
  from prompt_toolkit.document import Document
3
3
  import pydantic
4
+ from typing import Callable,Dict,Any
5
+ from pydantic import BaseModel,SkipValidation
6
+ from autocoder.common import AutoCoderArgs
4
7
  import os
5
8
 
6
9
  COMMANDS = {
@@ -38,6 +41,8 @@ COMMANDS = {
38
41
  "/speed-test": "",
39
42
  "/input_price": "",
40
43
  "/output_price": "",
44
+ },
45
+ "/auto": {
41
46
  }
42
47
  }
43
48
 
@@ -48,6 +53,24 @@ class Tag(pydantic.BaseModel):
48
53
  end_tag: str
49
54
 
50
55
 
56
+ class FileSystemModel(pydantic.BaseModel):
57
+ project_root: str
58
+ get_all_file_names_in_project: SkipValidation[Callable]
59
+ get_all_file_in_project: SkipValidation[Callable]
60
+ get_all_dir_names_in_project: SkipValidation[Callable]
61
+ get_all_file_in_project_with_dot: SkipValidation[Callable]
62
+ get_symbol_list: SkipValidation[Callable]
63
+
64
+ class MemoryConfig(BaseModel):
65
+ """
66
+ A model to encapsulate memory configuration and operations.
67
+ """
68
+ memory: Dict[str, Any]
69
+ save_memory_func: SkipValidation[Callable]
70
+
71
+ class Config:
72
+ arbitrary_types_allowed = True
73
+
51
74
  class CommandTextParser:
52
75
  def __init__(self, text: str, command: str):
53
76
  self.text = text
@@ -322,3 +345,546 @@ class CommandTextParser:
322
345
  self.consume_tag()
323
346
  else:
324
347
  self.consume_coding_value()
348
+
349
+
350
+ class CommandCompleter(Completer):
351
+ def __init__(self, commands, file_system_model: FileSystemModel, memory_model: MemoryConfig):
352
+ self.commands = commands
353
+ self.file_system_model = file_system_model
354
+ self.memory_model = memory_model
355
+ self.all_file_names = file_system_model.get_all_file_names_in_project()
356
+ self.all_files = file_system_model.get_all_file_in_project()
357
+ self.all_dir_names = file_system_model.get_all_dir_names_in_project()
358
+ self.all_files_with_dot = file_system_model.get_all_file_in_project_with_dot()
359
+ self.symbol_list = file_system_model.get_symbol_list()
360
+ self.current_file_names = []
361
+
362
+ def get_completions(self, document, complete_event):
363
+ text = document.text_before_cursor
364
+ words = text.split()
365
+
366
+ if len(words) > 0:
367
+ if words[0] == "/mode":
368
+ left_word = text[len("/mode"):]
369
+ for mode in ["normal", "auto_detect", "voice_input"]:
370
+ if mode.startswith(left_word.strip()):
371
+ yield Completion(mode, start_position=-len(left_word.strip()))
372
+
373
+ if words[0] == "/add_files":
374
+ new_text = text[len("/add_files"):]
375
+ parser = CommandTextParser(new_text, words[0])
376
+ parser.add_files()
377
+ current_word = parser.current_word()
378
+
379
+ if parser.last_sub_command() == "/refresh":
380
+ return
381
+
382
+ for command in parser.get_sub_commands():
383
+ if command.startswith(current_word):
384
+ yield Completion(command, start_position=-len(current_word))
385
+
386
+ if parser.first_sub_command() == "/group" and (
387
+ parser.last_sub_command() == "/group"
388
+ or parser.last_sub_command() == "/drop"
389
+ ):
390
+ group_names = self.memory_model.memory["current_files"]["groups"].keys()
391
+ if "," in current_word:
392
+ current_word = current_word.split(",")[-1]
393
+
394
+ for group_name in group_names:
395
+ if group_name.startswith(current_word):
396
+ yield Completion(
397
+ group_name, start_position=-len(current_word)
398
+ )
399
+
400
+ if parser.first_sub_command() != "/group":
401
+ if current_word and current_word.startswith("."):
402
+ for file_name in self.all_files_with_dot:
403
+ if file_name.startswith(current_word):
404
+ yield Completion(
405
+ file_name, start_position=-
406
+ len(current_word)
407
+ )
408
+ else:
409
+ for file_name in self.all_file_names:
410
+ if file_name.startswith(current_word):
411
+ yield Completion(
412
+ file_name, start_position=-
413
+ len(current_word)
414
+ )
415
+ for file_name in self.all_files:
416
+ if current_word and current_word in file_name:
417
+ yield Completion(
418
+ file_name, start_position=-
419
+ len(current_word)
420
+ )
421
+ elif words[0] == "/remove_files":
422
+ new_words = text[len("/remove_files"):].strip().split(",")
423
+
424
+ is_at_space = text[-1] == " "
425
+ last_word = new_words[-2] if len(new_words) > 1 else ""
426
+ current_word = new_words[-1] if new_words else ""
427
+
428
+ if is_at_space:
429
+ last_word = current_word
430
+ current_word = ""
431
+
432
+ # /remove_files /all [cursor] or /remove_files /all p[cursor]
433
+ if not last_word and not current_word:
434
+ if "/all".startswith(current_word):
435
+ yield Completion("/all", start_position=-len(current_word))
436
+ for file_name in self.current_file_names:
437
+ yield Completion(file_name, start_position=-len(current_word))
438
+
439
+ # /remove_files /a[cursor] or /remove_files p[cursor]
440
+ if current_word:
441
+ if "/all".startswith(current_word):
442
+ yield Completion("/all", start_position=-len(current_word))
443
+ for file_name in self.current_file_names:
444
+ if current_word and current_word in file_name:
445
+ yield Completion(
446
+ file_name, start_position=-len(current_word)
447
+ )
448
+ elif words[0] == "/exclude_dirs":
449
+ new_words = text[len("/exclude_dirs"):].strip().split(",")
450
+ current_word = new_words[-1]
451
+
452
+ for file_name in self.all_dir_names:
453
+ if current_word and current_word in file_name:
454
+ yield Completion(file_name, start_position=-len(current_word))
455
+
456
+ elif words[0] == "/lib":
457
+ new_text = text[len("/lib"):]
458
+ parser = CommandTextParser(new_text, words[0])
459
+ parser.lib()
460
+ current_word = parser.current_word()
461
+
462
+ for command in parser.get_sub_commands():
463
+ if command.startswith(current_word):
464
+ yield Completion(command, start_position=-len(current_word))
465
+
466
+ if parser.last_sub_command() in ["/add", "/remove", "/get"]:
467
+ for lib_name in self.memory_model.memory.get("libs", {}).keys():
468
+ if lib_name.startswith(current_word):
469
+ yield Completion(
470
+ lib_name, start_position=-len(current_word)
471
+ )
472
+ elif words[0] == "/mcp":
473
+ new_text = text[len("/mcp"):]
474
+ parser = CommandTextParser(new_text, words[0])
475
+ parser.lib()
476
+ current_word = parser.current_word()
477
+ for command in parser.get_sub_commands():
478
+ if command.startswith(current_word):
479
+ yield Completion(command, start_position=-len(current_word))
480
+ elif words[0] == "/models":
481
+ new_text = text[len("/models"):]
482
+ parser = CommandTextParser(new_text, words[0])
483
+ parser.lib()
484
+ current_word = parser.current_word()
485
+ for command in parser.get_sub_commands():
486
+ if command.startswith(current_word):
487
+ yield Completion(command, start_position=-len(current_word))
488
+
489
+ elif words[0] == "/coding":
490
+ new_text = text[len("/coding"):]
491
+ parser = CommandTextParser(new_text, words[0])
492
+ parser.lib()
493
+ current_word = parser.current_word()
494
+ for command in parser.get_sub_commands():
495
+ if command.startswith(current_word):
496
+ yield Completion(command, start_position=-len(current_word))
497
+
498
+ elif words[0] == "/conf":
499
+ new_words = text[len("/conf"):].strip().split()
500
+ is_at_space = text[-1] == " "
501
+ last_word = new_words[-2] if len(new_words) > 1 else ""
502
+ current_word = new_words[-1] if new_words else ""
503
+ completions = []
504
+
505
+ if is_at_space:
506
+ last_word = current_word
507
+ current_word = ""
508
+
509
+ # /conf /drop [curor] or /conf /drop p[cursor]
510
+ if last_word == "/drop":
511
+ completions = [
512
+ field_name
513
+ for field_name in self.memory_model.memory["conf"].keys()
514
+ if field_name.startswith(current_word)
515
+ ]
516
+ # /conf [curosr]
517
+ elif not last_word and not current_word:
518
+ completions = [
519
+ "/drop"] if "/drop".startswith(current_word) else []
520
+ completions += [
521
+ field_name + ":"
522
+ for field_name in AutoCoderArgs.model_fields.keys()
523
+ if field_name.startswith(current_word)
524
+ ]
525
+ # /conf p[cursor]
526
+ elif not last_word and current_word:
527
+ completions = [
528
+ "/drop"] if "/drop".startswith(current_word) else []
529
+ completions += [
530
+ field_name + ":"
531
+ for field_name in AutoCoderArgs.model_fields.keys()
532
+ if field_name.startswith(current_word)
533
+ ]
534
+
535
+ for completion in completions:
536
+ yield Completion(completion, start_position=-len(current_word))
537
+ elif words[0] in ["/chat", "/coding","/auto"]:
538
+ image_extensions = (
539
+ ".png",
540
+ ".jpg",
541
+ ".jpeg",
542
+ ".gif",
543
+ ".bmp",
544
+ ".tiff",
545
+ ".tif",
546
+ ".webp",
547
+ ".svg",
548
+ ".ico",
549
+ ".heic",
550
+ ".heif",
551
+ ".raw",
552
+ ".cr2",
553
+ ".nef",
554
+ ".arw",
555
+ ".dng",
556
+ ".orf",
557
+ ".rw2",
558
+ ".pef",
559
+ ".srw",
560
+ ".eps",
561
+ ".ai",
562
+ ".psd",
563
+ ".xcf",
564
+ )
565
+ new_text = text[len(words[0]):]
566
+ parser = CommandTextParser(new_text, words[0])
567
+
568
+ parser.coding()
569
+ current_word = parser.current_word()
570
+
571
+ if len(new_text.strip()) == 0 or new_text.strip() == "/":
572
+ for command in parser.get_sub_commands():
573
+ if command.startswith(current_word):
574
+ yield Completion(command, start_position=-len(current_word))
575
+
576
+ all_tags = parser.tags
577
+
578
+ if current_word.startswith("@"):
579
+ name = current_word[1:]
580
+ target_set = set()
581
+
582
+ for file_name in self.current_file_names:
583
+ base_file_name = os.path.basename(file_name)
584
+ if name in base_file_name:
585
+ target_set.add(base_file_name)
586
+ path_parts = file_name.split(os.sep)
587
+ display_name = (
588
+ os.sep.join(path_parts[-3:])
589
+ if len(path_parts) > 3
590
+ else file_name
591
+ )
592
+ relative_path = os.path.relpath(
593
+ file_name, self.file_system_model.project_root)
594
+ yield Completion(
595
+ relative_path,
596
+ start_position=-len(name),
597
+ display=f"{display_name} (in active files)",
598
+ )
599
+
600
+ for file_name in self.all_file_names:
601
+ if file_name.startswith(name) and file_name not in target_set:
602
+ target_set.add(file_name)
603
+
604
+ path_parts = file_name.split(os.sep)
605
+ display_name = (
606
+ os.sep.join(path_parts[-3:])
607
+ if len(path_parts) > 3
608
+ else file_name
609
+ )
610
+ relative_path = os.path.relpath(
611
+ file_name, self.file_system_model.project_root)
612
+
613
+ yield Completion(
614
+ relative_path,
615
+ start_position=-len(name),
616
+ display=f"{display_name}",
617
+ )
618
+
619
+ for file_name in self.all_files:
620
+ if name in file_name and file_name not in target_set:
621
+ path_parts = file_name.split(os.sep)
622
+ display_name = (
623
+ os.sep.join(path_parts[-3:])
624
+ if len(path_parts) > 3
625
+ else file_name
626
+ )
627
+ relative_path = os.path.relpath(
628
+ file_name, self.file_system_model.project_root)
629
+ yield Completion(
630
+ relative_path,
631
+ start_position=-len(name),
632
+ display=f"{display_name}",
633
+ )
634
+
635
+ if current_word.startswith("@@"):
636
+ name = current_word[2:]
637
+ for symbol in self.symbol_list:
638
+ if name in symbol.symbol_name:
639
+ file_name = symbol.file_name
640
+ path_parts = file_name.split(os.sep)
641
+ display_name = (
642
+ os.sep.join(path_parts[-3:])
643
+ if len(path_parts) > 3
644
+ else symbol.symbol_name
645
+ )
646
+ relative_path = os.path.relpath(
647
+ file_name, self.file_system_model.project_root)
648
+ yield Completion(
649
+ f"{symbol.symbol_name}(location: {relative_path})",
650
+ start_position=-len(name),
651
+ display=f"{symbol.symbol_name} ({display_name}/{symbol.symbol_type})",
652
+ )
653
+
654
+ tags = [tag for tag in parser.tags]
655
+
656
+ if current_word.startswith("<"):
657
+ name = current_word[1:]
658
+ for tag in ["<img>", "</img>"]:
659
+ if all_tags and all_tags[-1].start_tag == "<img>":
660
+ if tag.startswith(name):
661
+ yield Completion(
662
+ "</img>", start_position=-len(current_word)
663
+ )
664
+ elif tag.startswith(name):
665
+ yield Completion(tag, start_position=-len(current_word))
666
+
667
+ if tags and tags[-1].start_tag == "<img>" and tags[-1].end_tag == "":
668
+ raw_file_name = tags[0].content
669
+ file_name = raw_file_name.strip()
670
+ parent_dir = os.path.dirname(file_name)
671
+ file_basename = os.path.basename(file_name)
672
+ search_dir = parent_dir if parent_dir else "."
673
+ for root, dirs, files in os.walk(search_dir):
674
+ # 只处理直接子目录
675
+ if root != search_dir:
676
+ continue
677
+
678
+ # 补全子目录
679
+ for dir in dirs:
680
+ full_path = os.path.join(root, dir)
681
+ if full_path.startswith(file_name):
682
+ relative_path = os.path.relpath(
683
+ full_path, search_dir)
684
+ yield Completion(
685
+ relative_path,
686
+ start_position=-len(file_basename),
687
+ )
688
+
689
+ # 补全文件
690
+ for file in files:
691
+ if file.lower().endswith(
692
+ image_extensions
693
+ ) and file.startswith(file_basename):
694
+ full_path = os.path.join(root, file)
695
+ relative_path = os.path.relpath(
696
+ full_path, search_dir)
697
+ yield Completion(
698
+ relative_path,
699
+ start_position=-len(file_basename),
700
+ )
701
+
702
+ # 只处理一层子目录,然后退出循环
703
+ break
704
+
705
+ elif not words[0].startswith("/"):
706
+ image_extensions = (
707
+ ".png",
708
+ ".jpg",
709
+ ".jpeg",
710
+ ".gif",
711
+ ".bmp",
712
+ ".tiff",
713
+ ".tif",
714
+ ".webp",
715
+ ".svg",
716
+ ".ico",
717
+ ".heic",
718
+ ".heif",
719
+ ".raw",
720
+ ".cr2",
721
+ ".nef",
722
+ ".arw",
723
+ ".dng",
724
+ ".orf",
725
+ ".rw2",
726
+ ".pef",
727
+ ".srw",
728
+ ".eps",
729
+ ".ai",
730
+ ".psd",
731
+ ".xcf",
732
+ )
733
+ new_text = text
734
+ parser = CommandTextParser(new_text, "/auto")
735
+
736
+ parser.coding()
737
+ current_word = parser.current_word()
738
+
739
+ if len(new_text.strip()) == 0 or new_text.strip() == "/":
740
+ for command in parser.get_sub_commands():
741
+ if command.startswith(current_word):
742
+ yield Completion(command, start_position=-len(current_word))
743
+
744
+ all_tags = parser.tags
745
+
746
+ if current_word.startswith("@"):
747
+ name = current_word[1:]
748
+ target_set = set()
749
+
750
+ for file_name in self.current_file_names:
751
+ base_file_name = os.path.basename(file_name)
752
+ if name in base_file_name:
753
+ target_set.add(base_file_name)
754
+ path_parts = file_name.split(os.sep)
755
+ display_name = (
756
+ os.sep.join(path_parts[-3:])
757
+ if len(path_parts) > 3
758
+ else file_name
759
+ )
760
+ relative_path = os.path.relpath(
761
+ file_name, self.file_system_model.project_root)
762
+ yield Completion(
763
+ relative_path,
764
+ start_position=-len(name),
765
+ display=f"{display_name} (in active files)",
766
+ )
767
+
768
+ for file_name in self.all_file_names:
769
+ if file_name.startswith(name) and file_name not in target_set:
770
+ target_set.add(file_name)
771
+
772
+ path_parts = file_name.split(os.sep)
773
+ display_name = (
774
+ os.sep.join(path_parts[-3:])
775
+ if len(path_parts) > 3
776
+ else file_name
777
+ )
778
+ relative_path = os.path.relpath(
779
+ file_name, self.file_system_model.project_root)
780
+
781
+ yield Completion(
782
+ relative_path,
783
+ start_position=-len(name),
784
+ display=f"{display_name}",
785
+ )
786
+
787
+ for file_name in self.all_files:
788
+ if name in file_name and file_name not in target_set:
789
+ path_parts = file_name.split(os.sep)
790
+ display_name = (
791
+ os.sep.join(path_parts[-3:])
792
+ if len(path_parts) > 3
793
+ else file_name
794
+ )
795
+ relative_path = os.path.relpath(
796
+ file_name, self.file_system_model.project_root)
797
+ yield Completion(
798
+ relative_path,
799
+ start_position=-len(name),
800
+ display=f"{display_name}",
801
+ )
802
+
803
+ if current_word.startswith("@@"):
804
+ name = current_word[2:]
805
+ for symbol in self.symbol_list:
806
+ if name in symbol.symbol_name:
807
+ file_name = symbol.file_name
808
+ path_parts = file_name.split(os.sep)
809
+ display_name = (
810
+ os.sep.join(path_parts[-3:])
811
+ if len(path_parts) > 3
812
+ else symbol.symbol_name
813
+ )
814
+ relative_path = os.path.relpath(
815
+ file_name, self.file_system_model.project_root)
816
+ yield Completion(
817
+ f"{symbol.symbol_name}(location: {relative_path})",
818
+ start_position=-len(name),
819
+ display=f"{symbol.symbol_name} ({display_name}/{symbol.symbol_type})",
820
+ )
821
+
822
+ tags = [tag for tag in parser.tags]
823
+
824
+ if current_word.startswith("<"):
825
+ name = current_word[1:]
826
+ for tag in ["<img>", "</img>"]:
827
+ if all_tags and all_tags[-1].start_tag == "<img>":
828
+ if tag.startswith(name):
829
+ yield Completion(
830
+ "</img>", start_position=-len(current_word)
831
+ )
832
+ elif tag.startswith(name):
833
+ yield Completion(tag, start_position=-len(current_word))
834
+
835
+ if tags and tags[-1].start_tag == "<img>" and tags[-1].end_tag == "":
836
+ raw_file_name = tags[0].content
837
+ file_name = raw_file_name.strip()
838
+ parent_dir = os.path.dirname(file_name)
839
+ file_basename = os.path.basename(file_name)
840
+ search_dir = parent_dir if parent_dir else "."
841
+ for root, dirs, files in os.walk(search_dir):
842
+ # 只处理直接子目录
843
+ if root != search_dir:
844
+ continue
845
+
846
+ # 补全子目录
847
+ for dir in dirs:
848
+ full_path = os.path.join(root, dir)
849
+ if full_path.startswith(file_name):
850
+ relative_path = os.path.relpath(
851
+ full_path, search_dir)
852
+ yield Completion(
853
+ relative_path,
854
+ start_position=-len(file_basename),
855
+ )
856
+
857
+ # 补全文件
858
+ for file in files:
859
+ if file.lower().endswith(
860
+ image_extensions
861
+ ) and file.startswith(file_basename):
862
+ full_path = os.path.join(root, file)
863
+ relative_path = os.path.relpath(
864
+ full_path, search_dir)
865
+ yield Completion(
866
+ relative_path,
867
+ start_position=-len(file_basename),
868
+ )
869
+
870
+ # 只处理一层子目录,然后退出循环
871
+ break
872
+ else:
873
+ for command in self.commands:
874
+ if command.startswith(text):
875
+ yield Completion(command, start_position=-len(text))
876
+
877
+ else:
878
+ for command in self.commands:
879
+ if command.startswith(text):
880
+ yield Completion(command, start_position=-len(text))
881
+
882
+ def update_current_files(self, files):
883
+ self.current_file_names = [f for f in files]
884
+
885
+ def refresh_files(self):
886
+ self.all_file_names = self.file_system_model.get_all_file_names_in_project()
887
+ self.all_files = self.file_system_model.get_all_file_in_project()
888
+ self.all_dir_names = self.file_system_model.get_all_dir_names_in_project()
889
+ self.all_files_with_dot = self.file_system_model.get_all_file_in_project_with_dot()
890
+ self.symbol_list = self.file_system_model.get_symbol_list()
@@ -30,7 +30,11 @@ def init_command_template(source_dir:str):
30
30
  project_type: py
31
31
 
32
32
  ## The model you want to drive AutoCoder to run
33
- model: deepseek_chat
33
+ model: v3_chat
34
+ chat_model: r1_chat
35
+ generate_rerank_model: r1_chat
36
+ code_model: v3_chat
37
+ index_filter_model: r1_chat
34
38
 
35
39
 
36
40
  ## Enable the index building which can help you find the related files by your query
@@ -38,7 +42,7 @@ def init_command_template(source_dir:str):
38
42
  skip_build_index: false
39
43
  ## The model to build index for the project (Optional)
40
44
  ## 用于为项目构建索引的模型(可选)
41
- index_model: deepseek_chat
45
+ index_model: v3_chat
42
46
 
43
47
  ## the filter level to find the related files
44
48
  ## 0: only find the files with the file name
@@ -170,7 +174,7 @@ def base_base(source_dir:str,project_type:str)->str:
170
174
  source_dir: {{ source_dir }}
171
175
  target_file: {{ target_file }}
172
176
 
173
- model: deepseek_chat
177
+ model: v3_chat
174
178
  model_max_input_length: 100000
175
179
  model_max_input_length: 120000
176
180
  enable_multi_round_generate: false