jarvis-ai-assistant 0.1.97__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.

@@ -15,13 +15,13 @@ class PatchHandler:
15
15
 
16
16
 
17
17
  def _extract_patches(self, response: str) -> List[Patch]:
18
- """从响应中提取补丁
18
+ """Extract patches from response
19
19
 
20
20
  Args:
21
- response: 模型响应内容
21
+ response: Model response content
22
22
 
23
23
  Returns:
24
- List[Tuple[str, str, str]]: 补丁列表,每个补丁是 (格式, 文件路径, 补丁内容) 的元组
24
+ List[Tuple[str, str, str]]: Patch list, each patch is a tuple of (format, file path, patch content)
25
25
  """
26
26
  # 修改后的正则表达式匹配三种补丁格式
27
27
  fmt_pattern = r'<PATCH>\n>>>>>> SEARCH\n(.*?)\n?(={5,})\n(.*?)\n?<<<<<< REPLACE\n</PATCH>'
@@ -32,21 +32,21 @@ class PatchHandler:
32
32
 
33
33
 
34
34
  def _confirm_and_apply_changes(self, file_path: str) -> bool:
35
- """确认并应用修改"""
35
+ """Confirm and apply changes"""
36
36
  os.system(f"git diff --cached {file_path}")
37
- confirm = input(f"\n是否接受 {file_path} 的修改?(y/n) [y]: ").lower() or "y"
37
+ confirm = input(f"\nAccept {file_path} changes? (y/n) [y]: ").lower() or "y"
38
38
  if confirm == "y":
39
39
  return True
40
40
  else:
41
- # 回退修改
41
+ # Rollback changes
42
42
  os.system(f"git reset {file_path}")
43
43
  os.system(f"git checkout -- {file_path}")
44
- PrettyOutput.print(f"已回退 {file_path} 的修改", OutputType.WARNING)
44
+ PrettyOutput.print(f"Changes to {file_path} have been rolled back", OutputType.WARNING)
45
45
  return False
46
46
 
47
47
 
48
48
  def apply_file_patch(self, file_path: str, patches: List[Patch]) -> bool:
49
- """应用文件补丁"""
49
+ """Apply file patch"""
50
50
  if not os.path.exists(file_path):
51
51
  base_dir = os.path.dirname(file_path)
52
52
  os.makedirs(base_dir, exist_ok=True)
@@ -54,20 +54,20 @@ class PatchHandler:
54
54
  file_content = open(file_path, "r", encoding="utf-8").read()
55
55
  for i, patch in enumerate(patches):
56
56
  if patch.old_code == "" and patch.new_code == "":
57
- PrettyOutput.print(f"应用第 {i+1}/{len(patches)} 个补丁:删除文件 {file_path}", OutputType.INFO)
57
+ PrettyOutput.print(f"Apply patch {i+1}/{len(patches)}: Delete file {file_path}", OutputType.INFO)
58
58
  file_content = ""
59
59
  os.system(f"git rm {file_path}")
60
- PrettyOutput.print(f"应用第 {i+1}/{len(patches)} 个补丁成功", OutputType.SUCCESS)
60
+ PrettyOutput.print(f"Apply patch {i+1}/{len(patches)} successfully", OutputType.SUCCESS)
61
61
  elif patch.old_code == "":
62
- PrettyOutput.print(f"应用第 {i+1}/{len(patches)} 个补丁:替换文件 {file_path} 内容:\n{patch.new_code}", OutputType.INFO)
62
+ PrettyOutput.print(f"Apply patch {i+1}/{len(patches)}: Replace file {file_path} content: \n{patch.new_code}", OutputType.INFO)
63
63
  file_content = patch.new_code
64
64
  open(file_path, "w", encoding="utf-8").write(patch.new_code)
65
65
  os.system(f"git add {file_path}")
66
- PrettyOutput.print(f"应用第 {i+1}/{len(patches)} 个补丁成功", OutputType.SUCCESS)
66
+ PrettyOutput.print(f"Apply patch {i+1}/{len(patches)} successfully", OutputType.SUCCESS)
67
67
  else:
68
- PrettyOutput.print(f"应用第 {i+1}/{len(patches)} 个补丁:文件原始内容:\n{patch.old_code}\n替换为:\n{patch.new_code}", OutputType.INFO)
68
+ PrettyOutput.print(f"Apply patch {i+1}/{len(patches)}: File original content: \n{patch.old_code}\nReplace with: \n{patch.new_code}", OutputType.INFO)
69
69
  if file_content.find(patch.old_code) == -1:
70
- PrettyOutput.print(f"文件 {file_path} 中不存在 {patch.old_code}", OutputType.WARNING)
70
+ PrettyOutput.print(f"File {file_path} does not contain {patch.old_code}", OutputType.WARNING)
71
71
  os.system(f"git reset {file_path}")
72
72
  os.system(f"git checkout -- {file_path}")
73
73
  return False
@@ -75,20 +75,20 @@ class PatchHandler:
75
75
  file_content = file_content.replace(patch.old_code, patch.new_code, 1)
76
76
  open(file_path, "w", encoding="utf-8").write(file_content)
77
77
  os.system(f"git add {file_path}")
78
- PrettyOutput.print(f"应用第 {i+1}/{len(patches)} 个补丁成功", OutputType.SUCCESS)
78
+ PrettyOutput.print(f"Apply patch {i+1}/{len(patches)} successfully", OutputType.SUCCESS)
79
79
  return True
80
80
 
81
81
 
82
- def retry_comfirm(self) -> Tuple[str, str]:# 恢复用户选择逻辑
83
- choice = input("\n请选择操作: (1) 重试 (2) 跳过 (3) 完全中止 [1]: ") or "1"
82
+ def retry_comfirm(self) -> Tuple[str, str]:# Restore user selection logic
83
+ choice = input("\nPlease choose an action: (1) Retry (2) Skip (3) Completely stop [1]: ") or "1"
84
84
  if choice == "2":
85
85
  return "skip", ""
86
86
  if choice == "3":
87
87
  return "break", ""
88
- return "continue", get_multiline_input("请输入补充说明和要求:")
88
+ return "continue", get_multiline_input("Please enter additional information and requirements:")
89
89
 
90
90
  def apply_patch(self, feature: str, raw_plan: str, structed_plan: Dict[str, str]) -> Tuple[bool, str]:
91
- """应用补丁(主入口)"""
91
+ """Apply patch (main entry)"""
92
92
  for file_path, current_plan in structed_plan.items():
93
93
  additional_info = ""
94
94
  while True:
@@ -96,7 +96,7 @@ class PatchHandler:
96
96
  if os.path.exists(file_path):
97
97
  content = open(file_path, "r", encoding="utf-8").read()
98
98
  else:
99
- content = "<文件不存在,需要创建>"
99
+ content = "<File does not exist, need to create>"
100
100
  prompt = """You are a senior software development expert who can generate code patches based on the complete modification plan, current original code file path, code content, and current file's modification plan. The output format should be as follows:
101
101
  <PATCH>
102
102
  >>>>>> SEARCH
@@ -135,20 +135,20 @@ class PatchHandler:
135
135
  """
136
136
 
137
137
 
138
- PrettyOutput.print(f"{file_path}生成格式化补丁...", OutputType.PROGRESS)
138
+ PrettyOutput.print(f"Generating formatted patches for {file_path}...", OutputType.PROGRESS)
139
139
  response = PlatformRegistry.get_global_platform_registry().get_codegen_platform().chat_until_success(prompt)
140
140
  patches = self._extract_patches(response)
141
141
 
142
142
  if not patches or not self.apply_file_patch(file_path, patches) or not self._confirm_and_apply_changes(file_path):
143
143
  os.system(f"git reset {file_path}")
144
144
  os.system(f"git checkout -- {file_path}")
145
- PrettyOutput.print("补丁生成失败", OutputType.WARNING)
145
+ PrettyOutput.print("Patch generation failed", OutputType.WARNING)
146
146
  act, msg = self.retry_comfirm()
147
147
  if act == "break":
148
- PrettyOutput.print("终止补丁应用", OutputType.WARNING)
148
+ PrettyOutput.print("Terminate patch application", OutputType.WARNING)
149
149
  return False, msg
150
150
  if act == "skip":
151
- PrettyOutput.print(f"跳过文件 {file_path}", OutputType.WARNING)
151
+ PrettyOutput.print(f"Skip file {file_path}", OutputType.WARNING)
152
152
  break
153
153
  else:
154
154
  additional_info += msg + "\n"
@@ -161,31 +161,31 @@ class PatchHandler:
161
161
 
162
162
 
163
163
  def handle_patch_application(self, feature: str, raw_plan: str, structed_plan: Dict[str,str]) -> bool:
164
- """处理补丁应用流程
164
+ """Process patch application process
165
165
 
166
166
  Args:
167
- related_files: 相关文件列表
168
- feature: 功能描述
169
- modification_plan: 修改方案
167
+ related_files: Related files list
168
+ feature: Feature description
169
+ modification_plan: Modification plan
170
170
 
171
171
  Returns:
172
- bool: 是否成功应用补丁
172
+ bool: Whether patch application is successful
173
173
  """
174
- PrettyOutput.print("\n将要应用以下修改方案:", OutputType.INFO)
174
+ PrettyOutput.print("\nThe following modification plan will be applied:", OutputType.INFO)
175
175
  for file_path, patches_code in structed_plan.items():
176
- PrettyOutput.print(f"\n文件: {file_path}", OutputType.INFO)
177
- PrettyOutput.print(f"修改方案: \n{patches_code}", OutputType.INFO)
178
- # 3. 应用补丁
176
+ PrettyOutput.print(f"\nFile: {file_path}", OutputType.INFO)
177
+ PrettyOutput.print(f"Modification plan: \n{patches_code}", OutputType.INFO)
178
+ # 3. Apply patches
179
179
  success, error_msg = self.apply_patch(feature, raw_plan, structed_plan)
180
180
  if not success:
181
181
  os.system("git reset --hard")
182
182
  return False
183
- # 6. 应用成功,让用户确认修改
184
- PrettyOutput.print("\n补丁已应用,请检查修改效果。", OutputType.SUCCESS)
185
- confirm = input("\n是否保留这些修改?(y/n) [y]: ").lower() or "y"
183
+ # 6. Apply successfully, let user confirm changes
184
+ PrettyOutput.print("\nPatches applied, please check the modification effect.", OutputType.SUCCESS)
185
+ confirm = input("\nKeep these changes? (y/n) [y]: ").lower() or "y"
186
186
  if confirm != "y":
187
- PrettyOutput.print("用户取消修改,正在回退", OutputType.WARNING)
188
- os.system("git reset --hard") # 回退所有修改
187
+ PrettyOutput.print("User cancelled changes, rolling back", OutputType.WARNING)
188
+ os.system("git reset --hard") # Rollback all changes
189
189
  return False
190
190
  else:
191
191
  return True
@@ -4,18 +4,18 @@ from jarvis.models.registry import PlatformRegistry
4
4
  from jarvis.utils import PrettyOutput, OutputType, get_multiline_input
5
5
 
6
6
  class PlanGenerator:
7
- """修改方案生成器"""
7
+ """Modification plan generator"""
8
8
 
9
9
  def _build_prompt(self, feature: str, related_files: List[Dict], additional_info: str) -> str:
10
- """构建提示词
10
+ """Build prompt
11
11
 
12
12
  Args:
13
- feature: 功能描述
14
- related_files: 相关文件列表
15
- additional_info: 用户补充信息
13
+ feature: Feature description
14
+ related_files: Related files list
15
+ additional_info: User supplement information
16
16
 
17
17
  Returns:
18
- str: 完整的提示词
18
+ str: Complete prompt
19
19
  """
20
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"
21
21
  prompt += f"{feature}\n\n"
@@ -49,37 +49,37 @@ class PlanGenerator:
49
49
 
50
50
 
51
51
  def generate_plan(self, feature: str, related_files: List[Dict]) -> Tuple[str, Dict[str,str]]:
52
- """生成修改方案
52
+ """Generate modification plan
53
53
 
54
54
  Args:
55
- feature: 功能描述
56
- related_files: 相关文件列表
55
+ feature: Feature description
56
+ related_files: Related files list
57
57
 
58
58
  Returns:
59
- Tuple[str, Dict[str,str]]: 修改方案,如果用户取消则返回 None
59
+ Tuple[str, Dict[str,str]]: Modification plan, return None if user cancels
60
60
  """
61
61
  additional_info = ""
62
62
  while True:
63
63
  prompt = self._build_prompt(feature, related_files, additional_info)
64
- # 构建提示词
65
- PrettyOutput.print("开始生成修改方案...", OutputType.PROGRESS)
64
+ # Build prompt
65
+ PrettyOutput.print("Start generating modification plan...", OutputType.PROGRESS)
66
66
 
67
- # 获取修改方案
67
+ # Get modification plan
68
68
  raw_plan = PlatformRegistry.get_global_platform_registry().get_thinking_platform().chat_until_success(prompt)
69
69
  structed_plan = self._extract_code(raw_plan)
70
70
  if not structed_plan:
71
- PrettyOutput.print("修改方案生成失败,请重试", OutputType.ERROR)
72
- tmp = get_multiline_input("请输入您的补充意见或建议(直接回车取消):")
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
73
  if tmp == "__interrupt__" or prompt == "":
74
74
  return "", {}
75
75
  additional_info += tmp + "\n"
76
76
  continue
77
- user_input = input("\n是否同意这个修改方案?(y/n) [y]: ").strip().lower() or 'y'
77
+ user_input = input("\nDo you agree with this modification plan? (y/n) [y]: ").strip().lower() or 'y'
78
78
  if user_input == 'y' or user_input == '':
79
79
  return raw_plan, structed_plan
80
80
  elif user_input == 'n':
81
- # 获取用户反馈
82
- tmp = get_multiline_input("请输入您的补充意见或建议(直接回车取消):")
81
+ # Get user feedback
82
+ tmp = get_multiline_input("Please enter your additional information or suggestions (press Enter to cancel):")
83
83
  if prompt == "__interrupt__" or prompt == "":
84
84
  return "", {}
85
85
  additional_info += tmp + "\n"
@@ -87,13 +87,13 @@ class PlanGenerator:
87
87
 
88
88
 
89
89
  def _extract_code(self, response: str) -> Dict[str, str]:
90
- """从响应中提取代码
90
+ """Extract code from response
91
91
 
92
92
  Args:
93
- response: 模型响应内容
93
+ response: Model response content
94
94
 
95
95
  Returns:
96
- Dict[str, List[str]]: 代码字典,key为文件路径,value为代码片段列表
96
+ Dict[str, List[str]]: Code dictionary, key is file path, value is code snippet list
97
97
  """
98
98
  code_dict = {}
99
99
  for match in re.finditer(r'<PLAN>\n> (.+?)\n(.*?)\n</PLAN>', response, re.DOTALL):
@@ -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
- # 发送到模型并获取回复
77
+ # Send to model and get reply
78
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