jarvis-ai-assistant 0.1.96__py3-none-any.whl → 0.1.98__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 jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (41) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +138 -144
  3. jarvis/jarvis_codebase/main.py +87 -54
  4. jarvis/jarvis_coder/git_utils.py +22 -25
  5. jarvis/jarvis_coder/main.py +166 -171
  6. jarvis/jarvis_coder/patch_handler.py +153 -453
  7. jarvis/jarvis_coder/plan_generator.py +76 -48
  8. jarvis/jarvis_platform/main.py +39 -39
  9. jarvis/jarvis_rag/main.py +182 -182
  10. jarvis/jarvis_smart_shell/main.py +34 -34
  11. jarvis/main.py +24 -24
  12. jarvis/models/ai8.py +22 -22
  13. jarvis/models/base.py +17 -13
  14. jarvis/models/kimi.py +31 -31
  15. jarvis/models/ollama.py +28 -28
  16. jarvis/models/openai.py +22 -24
  17. jarvis/models/oyi.py +25 -25
  18. jarvis/models/registry.py +33 -34
  19. jarvis/tools/ask_user.py +5 -5
  20. jarvis/tools/base.py +2 -2
  21. jarvis/tools/chdir.py +9 -9
  22. jarvis/tools/codebase_qa.py +4 -4
  23. jarvis/tools/coder.py +4 -4
  24. jarvis/tools/file_ops.py +1 -1
  25. jarvis/tools/generator.py +23 -23
  26. jarvis/tools/methodology.py +4 -4
  27. jarvis/tools/rag.py +4 -4
  28. jarvis/tools/registry.py +38 -38
  29. jarvis/tools/search.py +42 -42
  30. jarvis/tools/shell.py +13 -13
  31. jarvis/tools/sub_agent.py +16 -16
  32. jarvis/tools/thinker.py +41 -41
  33. jarvis/tools/webpage.py +17 -17
  34. jarvis/utils.py +59 -60
  35. {jarvis_ai_assistant-0.1.96.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/METADATA +1 -1
  36. jarvis_ai_assistant-0.1.98.dist-info/RECORD +47 -0
  37. jarvis_ai_assistant-0.1.96.dist-info/RECORD +0 -47
  38. {jarvis_ai_assistant-0.1.96.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/LICENSE +0 -0
  39. {jarvis_ai_assistant-0.1.96.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/WHEEL +0 -0
  40. {jarvis_ai_assistant-0.1.96.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/entry_points.txt +0 -0
  41. {jarvis_ai_assistant-0.1.96.dist-info → jarvis_ai_assistant-0.1.98.dist-info}/top_level.txt +0 -0
@@ -1,75 +1,103 @@
1
- from typing import Dict, List, Optional
1
+ import re
2
+ from typing import Dict, List, Tuple
2
3
  from jarvis.models.registry import PlatformRegistry
3
- from jarvis.utils import PrettyOutput, OutputType, get_multiline_input, while_success
4
- from jarvis.models.base import BasePlatform
4
+ from jarvis.utils import PrettyOutput, OutputType, get_multiline_input
5
5
 
6
6
  class PlanGenerator:
7
- """修改方案生成器"""
7
+ """Modification plan generator"""
8
8
 
9
- def __init__(self):
10
- """初始化
9
+ def _build_prompt(self, feature: str, related_files: List[Dict], additional_info: str) -> str:
10
+ """Build prompt
11
11
 
12
12
  Args:
13
- thinking_model: 用于思考的大模型
14
- """
15
- self.thinking_model = PlatformRegistry.get_global_platform_registry().get_thinking_platform()
16
-
17
- def _build_prompt(self, feature: str, related_files: List[Dict]) -> str:
18
- """构建提示词
19
-
20
- Args:
21
- feature: 功能描述
22
- related_files: 相关文件列表
23
- user_feedback: 用户反馈信息
13
+ feature: Feature description
14
+ related_files: Related files list
15
+ additional_info: User supplement information
24
16
 
25
17
  Returns:
26
- str: 完整的提示词
18
+ str: Complete prompt
27
19
  """
28
- prompt = "我需要你帮我分析如何实现以下功能:\n\n"
20
+ prompt = "You are a code modification expert who can generate modification plans based on requirements and relevant code snippets. I need your help to analyze how to implement the following feature:\n\n"
29
21
  prompt += f"{feature}\n\n"
30
22
 
31
- prompt += "以下是相关的代码文件片段:\n\n"
23
+ prompt += "Here are the relevant code file snippets:\n\n"
32
24
 
33
25
  for file in related_files:
34
- prompt += f"文件: {file['file_path']}\n"
26
+ prompt += f"File: {file['file_path']}\n"
35
27
  for part in file["parts"]:
36
28
  prompt += f"<PART>\n{part}\n</PART>\n"
37
29
 
38
- prompt += "\n请详细说明需要做哪些修改来实现这个功能。包括:\n"
39
- prompt += "1. 需要修改哪些文件\n"
40
- prompt += "2. 每个文件需要做什么修改\n"
41
- prompt += "3. 修改的主要逻辑和原因\n"
42
- prompt += "4. 不要生成具体的代码,只需要生成修改方案\n"
30
+ prompt += "\nPlease provide detailed modifications needed to implement this feature. Include:\n"
31
+ prompt += "1. Which files need to be modified\n"
32
+ prompt += "2. How to modify each file, no explanation needed\n"
33
+ prompt += "3. Don't assume other files or code exist, only generate modification plans based on provided file contents and description\n"
34
+ prompt += "4. Don't implement features outside the requirement\n"
35
+ prompt += "5. Output only one modification plan per file (can be multiple lines)\n"
36
+ prompt += "6. Output format as follows:\n"
37
+ prompt += "<PLAN>\n"
38
+ prompt += "> path/to/file1\n"
39
+ prompt += "modification plan\n"
40
+ prompt += "</PLAN>\n"
41
+ prompt += "<PLAN>\n"
42
+ prompt += "> path/to/file2\n"
43
+ prompt += "modification plan\n"
44
+ prompt += "</PLAN>\n"
45
+ if additional_info:
46
+ prompt += f"# Additional information:\n{additional_info}\n"
43
47
 
44
48
  return prompt
45
49
 
46
- def generate_plan(self, feature: str, related_files: List[Dict]) -> str:
47
- """生成修改方案
50
+
51
+ def generate_plan(self, feature: str, related_files: List[Dict]) -> Tuple[str, Dict[str,str]]:
52
+ """Generate modification plan
48
53
 
49
54
  Args:
50
- feature: 功能描述
51
- related_files: 相关文件列表
55
+ feature: Feature description
56
+ related_files: Related files list
52
57
 
53
58
  Returns:
54
- str: 修改方案,如果用户取消则返回 None
59
+ Tuple[str, Dict[str,str]]: Modification plan, return None if user cancels
55
60
  """
56
- prompt = self._build_prompt(feature, related_files)
61
+ additional_info = ""
57
62
  while True:
58
- # 构建提示词
59
- PrettyOutput.print("开始生成修改方案...", OutputType.PROGRESS)
60
-
61
- # 获取修改方案
62
- plan = while_success(lambda: self.thinking_model.chat(prompt), 5)
63
+ prompt = self._build_prompt(feature, related_files, additional_info)
64
+ # Build prompt
65
+ PrettyOutput.print("Start generating modification plan...", OutputType.PROGRESS)
63
66
 
64
- user_input = input("\n是否同意这个修改方案?(y/n/f) [y]: ").strip().lower() or 'y'
65
- if user_input == 'y':
66
- return plan
67
+ # Get modification plan
68
+ raw_plan = PlatformRegistry.get_global_platform_registry().get_thinking_platform().chat_until_success(prompt)
69
+ structed_plan = self._extract_code(raw_plan)
70
+ if not structed_plan:
71
+ PrettyOutput.print("Modification plan generation failed, please try again", OutputType.ERROR)
72
+ tmp = get_multiline_input("Please enter your additional information or suggestions (press Enter to cancel):")
73
+ if tmp == "__interrupt__" or prompt == "":
74
+ return "", {}
75
+ additional_info += tmp + "\n"
76
+ continue
77
+ user_input = input("\nDo you agree with this modification plan? (y/n) [y]: ").strip().lower() or 'y'
78
+ if user_input == 'y' or user_input == '':
79
+ return raw_plan, structed_plan
67
80
  elif user_input == 'n':
68
- return ""
69
- else: # 'f' - feedback
70
- # 获取用户反馈
71
- prompt = get_multiline_input("请输入您的补充意见或建议:")
72
- if prompt == "__interrupt__":
73
- return ""
74
- prompt = f"用户补充反馈:\n{prompt}\n\n请重新生成完整方案"
75
- continue
81
+ # Get user feedback
82
+ tmp = get_multiline_input("Please enter your additional information or suggestions (press Enter to cancel):")
83
+ if prompt == "__interrupt__" or prompt == "":
84
+ return "", {}
85
+ additional_info += tmp + "\n"
86
+ continue
87
+
88
+
89
+ def _extract_code(self, response: str) -> Dict[str, str]:
90
+ """Extract code from response
91
+
92
+ Args:
93
+ response: Model response content
94
+
95
+ Returns:
96
+ Dict[str, List[str]]: Code dictionary, key is file path, value is code snippet list
97
+ """
98
+ code_dict = {}
99
+ for match in re.finditer(r'<PLAN>\n> (.+?)\n(.*?)\n</PLAN>', response, re.DOTALL):
100
+ file_path = match.group(1)
101
+ code_part = match.group(2)
102
+ code_dict[file_path] = code_part
103
+ return code_dict
@@ -2,26 +2,26 @@ from jarvis.models.registry import PlatformRegistry
2
2
  from jarvis.utils import PrettyOutput, OutputType, load_env_from_file, get_multiline_input
3
3
 
4
4
  def list_platforms():
5
- """列出所有支持的平台和模型"""
5
+ """List all supported platforms and models"""
6
6
  registry = PlatformRegistry.get_global_platform_registry()
7
7
  platforms = registry.get_available_platforms()
8
8
 
9
- PrettyOutput.section("支持的平台和模型", OutputType.SUCCESS)
9
+ PrettyOutput.section("Supported platforms and models", OutputType.SUCCESS)
10
10
 
11
11
  for platform_name in platforms:
12
- # 创建平台实例
12
+ # Create platform instance
13
13
  platform = registry.create_platform(platform_name)
14
14
  if not platform:
15
15
  continue
16
16
 
17
- # 获取平台支持的模型列表
17
+ # Get the list of models supported by the platform
18
18
  try:
19
19
  models = platform.get_model_list()
20
20
 
21
- # 打印平台名称
21
+ # Print platform name
22
22
  PrettyOutput.section(f"{platform_name}", OutputType.SUCCESS)
23
23
 
24
- # 打印模型列表
24
+ # Print model list
25
25
  if models:
26
26
  for model_name, description in models:
27
27
  if description:
@@ -29,95 +29,95 @@ def list_platforms():
29
29
  else:
30
30
  PrettyOutput.print(f" • {model_name}", OutputType.SUCCESS)
31
31
  else:
32
- PrettyOutput.print(" 没有可用的模型信息", OutputType.WARNING)
32
+ PrettyOutput.print(" • No available model information", OutputType.WARNING)
33
33
 
34
34
  except Exception as e:
35
- PrettyOutput.print(f"获取 {platform_name} 平台模型列表失败: {str(e)}", OutputType.WARNING)
35
+ PrettyOutput.print(f"Failed to get model list for {platform_name}: {str(e)}", OutputType.WARNING)
36
36
 
37
37
  def chat_with_model(platform_name: str, model_name: str):
38
- """与指定平台和模型进行对话"""
38
+ """Chat with specified platform and model"""
39
39
  registry = PlatformRegistry.get_global_platform_registry()
40
40
 
41
- # 创建平台实例
41
+ # Create platform instance
42
42
  platform = registry.create_platform(platform_name)
43
43
  if not platform:
44
- PrettyOutput.print(f"创建平台 {platform_name} 失败", OutputType.ERROR)
44
+ PrettyOutput.print(f"Failed to create platform {platform_name}", OutputType.ERROR)
45
45
  return
46
46
 
47
47
  try:
48
- # 设置模型
48
+ # Set model
49
49
  platform.set_model_name(model_name)
50
- PrettyOutput.print(f"已连接到 {platform_name} 平台的 {model_name} 模型", OutputType.SUCCESS)
50
+ PrettyOutput.print(f"Connected to {platform_name} platform {model_name} model", OutputType.SUCCESS)
51
51
 
52
- # 开始对话循环
52
+ # Start conversation loop
53
53
  while True:
54
- # 获取用户输入
54
+ # Get user input
55
55
  user_input = get_multiline_input("")
56
56
 
57
- # 检查是否取消输入
57
+ # Check if input is cancelled
58
58
  if user_input == "__interrupt__" or user_input.strip() == "/bye":
59
- PrettyOutput.print("再见!", OutputType.SUCCESS)
59
+ PrettyOutput.print("Bye!", OutputType.SUCCESS)
60
60
  break
61
61
 
62
- # 检查是否为空输入
62
+ # Check if input is empty
63
63
  if not user_input.strip():
64
64
  continue
65
65
 
66
- # 检查是否为清除会话命令
66
+ # Check if it is a clear session command
67
67
  if user_input.strip() == "/clear":
68
68
  try:
69
69
  platform.delete_chat()
70
- platform.set_model_name(model_name) # 重新初始化会话
71
- PrettyOutput.print("会话已清除", OutputType.SUCCESS)
70
+ platform.set_model_name(model_name) # Reinitialize session
71
+ PrettyOutput.print("Session cleared", OutputType.SUCCESS)
72
72
  except Exception as e:
73
- PrettyOutput.print(f"清除会话失败: {str(e)}", OutputType.ERROR)
73
+ PrettyOutput.print(f"Failed to clear session: {str(e)}", OutputType.ERROR)
74
74
  continue
75
75
 
76
76
  try:
77
- # 发送到模型并获取回复
78
- response = platform.chat(user_input)
77
+ # Send to model and get reply
78
+ response = platform.chat_until_success(user_input)
79
79
  if not response:
80
- PrettyOutput.print("未获得有效回复", OutputType.WARNING)
80
+ PrettyOutput.print("No valid reply", OutputType.WARNING)
81
81
 
82
82
  except Exception as e:
83
- PrettyOutput.print(f"对话失败: {str(e)}", OutputType.ERROR)
83
+ PrettyOutput.print(f"Failed to chat: {str(e)}", OutputType.ERROR)
84
84
 
85
85
  except Exception as e:
86
- PrettyOutput.print(f"初始化对话失败: {str(e)}", OutputType.ERROR)
86
+ PrettyOutput.print(f"Failed to initialize conversation: {str(e)}", OutputType.ERROR)
87
87
  finally:
88
- # 清理资源
88
+ # Clean up resources
89
89
  try:
90
90
  platform.delete_chat()
91
91
  except:
92
92
  pass
93
93
 
94
94
  def info_command(args):
95
- """处理 info 子命令"""
95
+ """Process info subcommand"""
96
96
  list_platforms()
97
97
 
98
98
  def chat_command(args):
99
- """处理 chat 子命令"""
99
+ """Process chat subcommand"""
100
100
  if not args.platform or not args.model:
101
- PrettyOutput.print("请指定平台和模型。使用 'jarvis info' 查看可用的平台和模型。", OutputType.ERROR)
101
+ PrettyOutput.print("Please specify platform and model. Use 'jarvis info' to view available platforms and models.", OutputType.ERROR)
102
102
  return
103
103
  chat_with_model(args.platform, args.model)
104
104
 
105
105
  def main():
106
- """主函数"""
106
+ """Main function"""
107
107
  import argparse
108
108
 
109
109
  load_env_from_file()
110
110
 
111
111
  parser = argparse.ArgumentParser(description='Jarvis AI Platform')
112
- subparsers = parser.add_subparsers(dest='command', help='可用的子命令')
112
+ subparsers = parser.add_subparsers(dest='command', help='Available subcommands')
113
113
 
114
- # info 子命令
115
- info_parser = subparsers.add_parser('info', help='显示支持的平台和模型信息')
114
+ # info subcommand
115
+ info_parser = subparsers.add_parser('info', help='Display supported platforms and models information')
116
116
 
117
- # chat 子命令
118
- chat_parser = subparsers.add_parser('chat', help='与指定的平台和模型进行对话')
119
- chat_parser.add_argument('--platform', '-p', help='指定要使用的平台')
120
- chat_parser.add_argument('--model', '-m', help='指定要使用的模型')
117
+ # chat subcommand
118
+ chat_parser = subparsers.add_parser('chat', help='Chat with specified platform and model')
119
+ chat_parser.add_argument('--platform', '-p', help='Specify the platform to use')
120
+ chat_parser.add_argument('--model', '-m', help='Specify the model to use')
121
121
 
122
122
  args = parser.parse_args()
123
123