jarvis-ai-assistant 0.3.1__py3-none-any.whl → 0.3.3__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.
jarvis/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.3.1"
4
+ __version__ = "0.3.3"
@@ -190,7 +190,9 @@ class Agent:
190
190
 
191
191
  self.model = PlatformRegistry().create_platform(platform_name)
192
192
  if self.model is None:
193
- PrettyOutput.print(f"平台 {platform_name} 不存在,将使用普通模型", OutputType.WARNING)
193
+ PrettyOutput.print(
194
+ f"平台 {platform_name} 不存在,将使用普通模型", OutputType.WARNING
195
+ )
194
196
  self.model = PlatformRegistry().get_normal_platform()
195
197
 
196
198
  if model_name:
@@ -512,10 +514,6 @@ class Agent:
512
514
 
513
515
  if self.use_analysis:
514
516
  self.task_analyzer.analysis_task(satisfaction_feedback)
515
- else:
516
- # 如果没有开启分析,也提示用户是否有值得记忆的信息
517
- if self.force_save_memory:
518
- self.memory_manager.prompt_memory_save()
519
517
 
520
518
  if self.need_summary:
521
519
  print("📄 正在生成总结...")
@@ -689,7 +687,9 @@ class Agent:
689
687
  返回:
690
688
  str: "continue" 或 "complete"
691
689
  """
692
- user_input = self.multiline_inputer(f"{self.name}: 请输入,或输入空行来结束当前任务:")
690
+ user_input = self.multiline_inputer(
691
+ f"{self.name}: 请输入,或输入空行来结束当前任务:"
692
+ )
693
693
 
694
694
  if user_input:
695
695
  self.session.prompt = user_input
@@ -19,17 +19,17 @@ def run_cli(
19
19
  ctx: typer.Context,
20
20
  llm_type: str = typer.Option(
21
21
  "normal",
22
- "--llm_type",
22
+ "-t", "--llm_type",
23
23
  help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
24
24
  ),
25
25
  task: Optional[str] = typer.Option(
26
- None, "-t", "--task", help="从命令行直接输入任务内容"
26
+ None, "-T", "--task", help="从命令行直接输入任务内容"
27
27
  ),
28
28
  model_group: Optional[str] = typer.Option(
29
- None, "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
29
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
30
30
  ),
31
31
  tool_group: Optional[str] = typer.Option(
32
- None, "--tool_group", help="使用的工具组,覆盖配置文件中的设置"
32
+ None, "-G", "--tool_group", help="使用的工具组,覆盖配置文件中的设置"
33
33
  ),
34
34
  config_file: Optional[str] = typer.Option(
35
35
  None, "-f", "--config", help="自定义配置文件路径"
@@ -50,13 +50,12 @@ def cli(
50
50
  ),
51
51
  llm_type: str = typer.Option(
52
52
  "normal",
53
- "--llm_type",
53
+ "-t", "--llm_type",
54
54
  help="使用的LLM类型,覆盖配置文件中的设置",
55
55
  ),
56
56
  model_group: Optional[str] = typer.Option(
57
- None, "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
58
- ),
59
- ):
57
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
58
+ ),):
60
59
  """Main entry point for Jarvis agent"""
61
60
  # Initialize environment
62
61
  init_env("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=config_file)
@@ -60,6 +60,28 @@ class ShareManager(ABC):
60
60
  subprocess.run(
61
61
  ["git", "clone", self.central_repo_url, self.repo_path], check=True
62
62
  )
63
+ # 检查并添加.gitignore文件
64
+ gitignore_path = os.path.join(self.repo_path, ".gitignore")
65
+ modified = False
66
+ if not os.path.exists(gitignore_path):
67
+ with open(gitignore_path, "w") as f:
68
+ f.write("__pycache__/\n")
69
+ modified = True
70
+ else:
71
+ with open(gitignore_path, "r+") as f:
72
+ content = f.read()
73
+ if "__pycache__" not in content:
74
+ f.write("\n__pycache__/\n")
75
+ modified = True
76
+
77
+ if modified:
78
+ subprocess.run(["git", "add", ".gitignore"], cwd=self.repo_path, check=True)
79
+ subprocess.run(
80
+ ["git", "commit", "-m", "chore: add __pycache__ to .gitignore"],
81
+ cwd=self.repo_path,
82
+ check=True
83
+ )
84
+ subprocess.run(["git", "push"], cwd=self.repo_path, check=True)
63
85
  else:
64
86
  PrettyOutput.print(
65
87
  f"正在更新中心{self.get_resource_type()}仓库...", OutputType.INFO
@@ -76,6 +98,27 @@ class ShareManager(ABC):
76
98
  )
77
99
  # 如果有远程分支,执行pull
78
100
  if result.stdout.strip():
101
+ # 检查是否有未提交的更改
102
+ status_result = subprocess.run(
103
+ ["git", "status", "--porcelain"],
104
+ cwd=self.repo_path,
105
+ capture_output=True,
106
+ text=True,
107
+ check=True,
108
+ )
109
+ if status_result.stdout:
110
+ if user_confirm(
111
+ f"检测到中心{self.get_resource_type()}仓库 '{self.repo_name}' 存在未提交的更改,是否放弃这些更改并更新?"
112
+ ):
113
+ subprocess.run(
114
+ ["git", "checkout", "."], cwd=self.repo_path, check=True
115
+ )
116
+ else:
117
+ PrettyOutput.print(
118
+ f"跳过更新 '{self.repo_name}' 以保留未提交的更改。",
119
+ OutputType.INFO,
120
+ )
121
+ return
79
122
  subprocess.run(["git", "pull"], cwd=self.repo_path, check=True)
80
123
  else:
81
124
  PrettyOutput.print(
@@ -431,9 +431,6 @@ class CodeAgent:
431
431
  ["git", "commit", "-m", f"CheckPoint #{commit_count + 1}"],
432
432
  check=True,
433
433
  )
434
-
435
- # 统计提交次数
436
- StatsManager.increment("code_commits_accepted", group="code_agent")
437
434
  except subprocess.CalledProcessError as e:
438
435
  PrettyOutput.print(f"提交失败: {str(e)}", OutputType.ERROR)
439
436
 
@@ -484,6 +481,10 @@ class CodeAgent:
484
481
  )
485
482
  git_commiter = GitCommitTool()
486
483
  git_commiter.execute({})
484
+
485
+ # 在用户接受commit后,根据配置决定是否保存记忆
486
+ if self.agent.force_save_memory:
487
+ self.agent.memory_manager.prompt_memory_save()
487
488
  elif start_commit:
488
489
  os.system(f"git reset --hard {str(start_commit)}") # 确保转换为字符串
489
490
  PrettyOutput.print("已重置到初始提交", OutputType.INFO)
@@ -642,11 +643,12 @@ class CodeAgent:
642
643
  def cli(
643
644
  llm_type: str = typer.Option(
644
645
  "normal",
646
+ "-t",
645
647
  "--llm_type",
646
648
  help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
647
649
  ),
648
650
  model_group: Optional[str] = typer.Option(
649
- None, "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
651
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
650
652
  ),
651
653
  requirement: Optional[str] = typer.Option(
652
654
  None, "-r", "--requirement", help="要处理的需求描述"
@@ -300,7 +300,11 @@ class CodeReviewTool:
300
300
 
301
301
  # Execute git command and get diff output
302
302
  diff_output = subprocess.check_output(
303
- diff_cmd, shell=True, text=True, encoding="utf-8", errors="replace"
303
+ diff_cmd,
304
+ shell=True,
305
+ text=True,
306
+ encoding="utf-8",
307
+ errors="replace",
304
308
  )
305
309
  if not diff_output:
306
310
  return {
@@ -339,7 +343,11 @@ class CodeReviewTool:
339
343
 
340
344
  # Execute git command and get diff output
341
345
  diff_output = subprocess.check_output(
342
- diff_cmd, shell=True, text=True, encoding="utf-8", errors="replace"
346
+ diff_cmd,
347
+ shell=True,
348
+ text=True,
349
+ encoding="utf-8",
350
+ errors="replace",
343
351
  )
344
352
  if not diff_output:
345
353
  return {
@@ -381,7 +389,11 @@ class CodeReviewTool:
381
389
 
382
390
  # Execute git command and get diff output
383
391
  diff_output = subprocess.check_output(
384
- diff_cmd, shell=True, text=True, encoding="utf-8", errors="replace"
392
+ diff_cmd,
393
+ shell=True,
394
+ text=True,
395
+ encoding="utf-8",
396
+ errors="replace",
385
397
  )
386
398
  if not diff_output:
387
399
  return {
@@ -581,16 +593,48 @@ class CodeReviewTool:
581
593
  tool_registry = ToolRegistry()
582
594
  tool_registry.dont_use_tools(["code_review"])
583
595
 
584
- # Use the provided agent's model_group or get it from globals
596
+ # Get llm_type and model_group from args
597
+ llm_type = args.get("llm_type", "normal")
598
+ model_group = args.get("model_group")
599
+
600
+ # Get platform and model based on llm_type and model_group
601
+ from jarvis.jarvis_utils.config import (
602
+ get_normal_platform_name,
603
+ get_normal_model_name,
604
+ get_thinking_platform_name,
605
+ get_thinking_model_name,
606
+ )
607
+
608
+ if llm_type == "thinking":
609
+ platform_name = get_thinking_platform_name(model_group)
610
+ model_name = get_thinking_model_name(model_group)
611
+ else:
612
+ platform_name = get_normal_platform_name(model_group)
613
+ model_name = get_normal_model_name(model_group)
614
+
615
+ # If no explicit parameters, try to get from existing agent
585
616
  calling_agent = agent or get_agent(current_agent_name)
586
- model_group = None
587
- if calling_agent and hasattr(calling_agent, "model") and calling_agent.model:
588
- model_group = calling_agent.model.model_group
617
+ if (
618
+ not platform_name
619
+ and calling_agent
620
+ and hasattr(calling_agent, "model")
621
+ and calling_agent.model
622
+ ):
623
+ platform_name = calling_agent.model.platform_name()
624
+ model_name = calling_agent.model.name()
625
+
626
+ # Create a new platform instance
627
+ review_model = None
628
+ if platform_name:
629
+ review_model = PlatformRegistry().create_platform(platform_name)
630
+ if review_model and model_name:
631
+ review_model.set_model_name(model_name)
632
+ if model_group:
633
+ review_model.model_group = model_group
589
634
 
590
635
  agent = Agent(
591
636
  system_prompt=system_prompt,
592
637
  name="Code Review Agent",
593
- model_group=model_group,
594
638
  summary_prompt=f"""<code_review_report>
595
639
  <overview>
596
640
  # 整体评估
@@ -660,6 +704,10 @@ class CodeReviewTool:
660
704
  auto_complete=False,
661
705
  )
662
706
 
707
+ # Replace the agent's model with our custom platform instance
708
+ if review_model:
709
+ agent.model = review_model
710
+
663
711
  # Determine if we need to split the diff due to size
664
712
  max_diff_size = 100 * 1024 * 1024 # Limit to 100MB
665
713
 
@@ -693,7 +741,9 @@ class CodeReviewTool:
693
741
 
694
742
  try:
695
743
  # Check if content is too large
696
- is_large_content = is_context_overflow(diff_output, model_group)
744
+ is_large_content = is_context_overflow(
745
+ diff_output, review_model.model_group if review_model else None
746
+ )
697
747
 
698
748
  # Upload the file to the agent's model
699
749
  if is_large_content:
@@ -773,10 +823,25 @@ def extract_code_report(result: str) -> str:
773
823
  def review_commit(
774
824
  commit: str = typer.Argument(..., help="要审查的提交SHA"),
775
825
  root_dir: str = typer.Option(".", "--root-dir", help="代码库根目录路径"),
826
+ llm_type: str = typer.Option(
827
+ "normal",
828
+ "-t",
829
+ "--llm_type",
830
+ help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
831
+ ),
832
+ model_group: Optional[str] = typer.Option(
833
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
834
+ ),
776
835
  ):
777
836
  """审查指定的提交"""
778
837
  tool = CodeReviewTool()
779
- tool_args = {"review_type": "commit", "commit_sha": commit, "root_dir": root_dir}
838
+ tool_args = {
839
+ "review_type": "commit",
840
+ "commit_sha": commit,
841
+ "root_dir": root_dir,
842
+ "llm_type": llm_type,
843
+ "model_group": model_group,
844
+ }
780
845
  result = tool.execute(tool_args)
781
846
  if result["success"]:
782
847
  PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
@@ -789,10 +854,24 @@ def review_commit(
789
854
  @app.command("current")
790
855
  def review_current(
791
856
  root_dir: str = typer.Option(".", "--root-dir", help="代码库根目录路径"),
857
+ llm_type: str = typer.Option(
858
+ "normal",
859
+ "-t",
860
+ "--llm_type",
861
+ help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
862
+ ),
863
+ model_group: Optional[str] = typer.Option(
864
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
865
+ ),
792
866
  ):
793
867
  """审查当前的变更"""
794
868
  tool = CodeReviewTool()
795
- tool_args = {"review_type": "current", "root_dir": root_dir}
869
+ tool_args = {
870
+ "review_type": "current",
871
+ "root_dir": root_dir,
872
+ "llm_type": llm_type,
873
+ "model_group": model_group,
874
+ }
796
875
  result = tool.execute(tool_args)
797
876
  if result["success"]:
798
877
  PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
@@ -807,6 +886,15 @@ def review_range(
807
886
  start_commit: str = typer.Argument(..., help="起始提交SHA"),
808
887
  end_commit: str = typer.Argument(..., help="结束提交SHA"),
809
888
  root_dir: str = typer.Option(".", "--root-dir", help="代码库根目录路径"),
889
+ llm_type: str = typer.Option(
890
+ "normal",
891
+ "-t",
892
+ "--llm_type",
893
+ help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
894
+ ),
895
+ model_group: Optional[str] = typer.Option(
896
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
897
+ ),
810
898
  ):
811
899
  """审查提交范围"""
812
900
  tool = CodeReviewTool()
@@ -815,6 +903,8 @@ def review_range(
815
903
  "start_commit": start_commit,
816
904
  "end_commit": end_commit,
817
905
  "root_dir": root_dir,
906
+ "llm_type": llm_type,
907
+ "model_group": model_group,
818
908
  }
819
909
  result = tool.execute(tool_args)
820
910
  if result["success"]:
@@ -829,10 +919,25 @@ def review_range(
829
919
  def review_file(
830
920
  file: str = typer.Argument(..., help="要审查的文件路径"),
831
921
  root_dir: str = typer.Option(".", "--root-dir", help="代码库根目录路径"),
922
+ llm_type: str = typer.Option(
923
+ "normal",
924
+ "-t",
925
+ "--llm_type",
926
+ help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
927
+ ),
928
+ model_group: Optional[str] = typer.Option(
929
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
930
+ ),
832
931
  ):
833
932
  """审查指定的文件"""
834
933
  tool = CodeReviewTool()
835
- tool_args = {"review_type": "file", "file_path": file, "root_dir": root_dir}
934
+ tool_args = {
935
+ "review_type": "file",
936
+ "file_path": file,
937
+ "root_dir": root_dir,
938
+ "llm_type": llm_type,
939
+ "model_group": model_group,
940
+ }
836
941
  result = tool.execute(tool_args)
837
942
  if result["success"]:
838
943
  PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
@@ -164,14 +164,59 @@ commit信息
164
164
  {ct("COMMIT_MESSAGE")}
165
165
  """
166
166
 
167
- # 获取模型并尝试上传文件
167
+ # Get llm_type and model_group from args
168
+ llm_type = args.get("llm_type", "normal")
169
+ model_group = args.get("model_group")
170
+
171
+ # Get platform and model based on llm_type and model_group
172
+ from jarvis.jarvis_utils.config import (
173
+ get_normal_platform_name,
174
+ get_normal_model_name,
175
+ get_thinking_platform_name,
176
+ get_thinking_model_name,
177
+ )
178
+
179
+ if llm_type == "thinking":
180
+ platform_name = get_thinking_platform_name(model_group)
181
+ model_name = get_thinking_model_name(model_group)
182
+ else:
183
+ platform_name = get_normal_platform_name(model_group)
184
+ model_name = get_normal_model_name(model_group)
185
+
186
+ # If no explicit parameters, try to get from existing agent
168
187
  agent = get_agent(current_agent_name)
169
- if agent:
170
- platform = agent.model
171
- model_group = agent.model.model_group
188
+ if (
189
+ not platform_name
190
+ and agent
191
+ and hasattr(agent, "model")
192
+ and agent.model
193
+ ):
194
+ platform_name = agent.model.platform_name()
195
+ model_name = agent.model.name()
196
+ if not model_group:
197
+ model_group = agent.model.model_group
198
+
199
+ # Create a new platform instance
200
+ if platform_name:
201
+ platform = PlatformRegistry().create_platform(platform_name)
202
+ if platform and model_name:
203
+ platform.set_model_name(model_name)
204
+ if model_group:
205
+ platform.model_group = model_group
172
206
  else:
173
- platform = PlatformRegistry().get_normal_platform()
174
- model_group = None
207
+ if llm_type == "thinking":
208
+ platform = PlatformRegistry().get_thinking_platform()
209
+ else:
210
+ platform = PlatformRegistry().get_normal_platform()
211
+
212
+ # Ensure platform is not None
213
+ if not platform:
214
+ return {
215
+ "success": False,
216
+ "stdout": "",
217
+ "stderr": "错误:无法创建平台实例",
218
+ }
219
+
175
220
  upload_success = False
176
221
 
177
222
  # Check if content is too large
@@ -330,9 +375,7 @@ commit信息
330
375
 
331
376
  @app.command()
332
377
  def cli(
333
- root_dir: str = typer.Option(
334
- ".", "--root-dir", help="Git仓库的根目录路径"
335
- ),
378
+ root_dir: str = typer.Option(".", "--root-dir", help="Git仓库的根目录路径"),
336
379
  prefix: str = typer.Option(
337
380
  "",
338
381
  "--prefix",
@@ -343,6 +386,15 @@ def cli(
343
386
  "--suffix",
344
387
  help="提交信息后缀(用换行分隔)",
345
388
  ),
389
+ llm_type: str = typer.Option(
390
+ "normal",
391
+ "-t",
392
+ "--llm_type",
393
+ help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
394
+ ),
395
+ model_group: Optional[str] = typer.Option(
396
+ None, "-g", "--llm_group", help="使用的模型组,覆盖配置文件中的设置"
397
+ ),
346
398
  ):
347
399
  init_env("欢迎使用 Jarvis-GitCommitTool,您的Git提交助手已准备就绪!")
348
400
  tool = GitCommitTool()
@@ -351,6 +403,8 @@ def cli(
351
403
  "root_dir": root_dir,
352
404
  "prefix": prefix,
353
405
  "suffix": suffix,
406
+ "llm_type": llm_type,
407
+ "model_group": model_group,
354
408
  }
355
409
  )
356
410
 
File without changes