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
jarvis/tools/chdir.py CHANGED
@@ -6,13 +6,13 @@ class ChdirTool:
6
6
  """修改当前工作目录的工具"""
7
7
 
8
8
  name = "chdir"
9
- description = "修改当前工作目录"
9
+ description = "Change current working directory"
10
10
  parameters = {
11
11
  "type": "object",
12
12
  "properties": {
13
13
  "path": {
14
14
  "type": "string",
15
- "description": "要切换到的目录路径,支持相对路径和绝对路径"
15
+ "description": "Directory path to switch to, supports both relative and absolute paths"
16
16
  }
17
17
  },
18
18
  "required": ["path"]
@@ -38,14 +38,14 @@ class ChdirTool:
38
38
  if not os.path.exists(path):
39
39
  return {
40
40
  "success": False,
41
- "error": f"目录不存在: {path}"
41
+ "error": f"Directory does not exist: {path}"
42
42
  }
43
43
 
44
44
  # 检查是否是目录
45
45
  if not os.path.isdir(path):
46
46
  return {
47
47
  "success": False,
48
- "error": f"路径不是目录: {path}"
48
+ "error": f"The path is not a directory: {path}"
49
49
  }
50
50
 
51
51
  # 尝试切换目录
@@ -54,27 +54,27 @@ class ChdirTool:
54
54
 
55
55
  return {
56
56
  "success": True,
57
- "stdout": f"已切换工作目录:\n从: {old_path}\n到: {path}",
57
+ "stdout": f"Changed working directory:\nFrom: {old_path}\nTo: {path}",
58
58
  "stderr": ""
59
59
  }
60
60
 
61
61
  except PermissionError:
62
62
  return {
63
63
  "success": False,
64
- "error": f"没有权限访问目录: {path}"
64
+ "error": f"No permission to access directory: {path}"
65
65
  }
66
66
  except Exception as e:
67
67
  return {
68
68
  "success": False,
69
- "error": f"切换目录失败: {str(e)}"
69
+ "error": f"Failed to switch directory: {str(e)}"
70
70
  }
71
71
 
72
72
  def main():
73
73
  """命令行直接运行工具"""
74
74
  import argparse
75
75
 
76
- parser = argparse.ArgumentParser(description='修改当前工作目录')
77
- parser.add_argument('path', help='要切换到的目录路径')
76
+ parser = argparse.ArgumentParser(description='Change current working directory')
77
+ parser.add_argument('path', help='Directory path to switch to, supports both relative and absolute paths')
78
78
  args = parser.parse_args()
79
79
 
80
80
  tool = ChdirTool()
@@ -7,21 +7,21 @@ class CodebaseQATool:
7
7
  """代码库问答工具,用于回答关于代码库的问题"""
8
8
 
9
9
  name = "codebase_qa"
10
- description = "回答关于代码库的问题,可以查询和理解代码的功能、结构和实现细节"
10
+ description = "Answer questions about the codebase, can query and understand code functionality, structure, and implementation details"
11
11
  parameters = {
12
12
  "type": "object",
13
13
  "properties": {
14
14
  "dir": {
15
15
  "type": "string",
16
- "description": "项目根目录"
16
+ "description": "Project root directory"
17
17
  },
18
18
  "question": {
19
19
  "type": "string",
20
- "description": "关于代码库的问题"
20
+ "description": "Question about the codebase"
21
21
  },
22
22
  "top_k": {
23
23
  "type": "integer",
24
- "description": "搜索相关文件的数量",
24
+ "description": "Number of relevant files to search",
25
25
  "default": 5
26
26
  }
27
27
  },
jarvis/tools/coder.py CHANGED
@@ -7,21 +7,21 @@ class CoderTool:
7
7
  """代码修改工具"""
8
8
 
9
9
  name = "coder"
10
- description = "分析并修改现有代码,用于实现新功能、修复bug、重构代码等。能理解代码上下文并进行精确的代码编辑。"
10
+ description = "Analyze and modify existing code for implementing new features, fixing bugs, refactoring code, etc. Can understand code context and perform precise code edits."
11
11
  parameters = {
12
12
  "feature": {
13
13
  "type": "string",
14
- "description": "要实现的功能描述或需要修改的内容,例如:'添加日志功能''修复内存泄漏''优化性能'",
14
+ "description": "Description of the feature to implement or content to modify, e.g., 'add logging functionality', 'fix memory leak', 'optimize performance', etc.",
15
15
  "required": True
16
16
  },
17
17
  "dir": {
18
18
  "type": "string",
19
- "description": "项目根目录,默认为当前目录",
19
+ "description": "Project root directory, defaults to current directory",
20
20
  "required": False
21
21
  },
22
22
  "language": {
23
23
  "type": "string",
24
- "description": "项目的主要编程语言,默认为python",
24
+ "description": "Main programming language of the project, defaults to python",
25
25
  "required": False
26
26
  }
27
27
  }
jarvis/tools/file_ops.py CHANGED
@@ -7,7 +7,7 @@ from jarvis.utils import OutputType, PrettyOutput
7
7
 
8
8
  class FileOperationTool:
9
9
  name = "file_operation"
10
- description = "文件操作 (read/write/append/exists)"
10
+ description = "File operations (read/write/append/exists)"
11
11
  parameters = {
12
12
  "type": "object",
13
13
  "properties": {
jarvis/tools/generator.py CHANGED
@@ -7,25 +7,25 @@ from jarvis.utils import OutputType, PrettyOutput
7
7
 
8
8
  class ToolGeneratorTool:
9
9
  name = "generate_tool"
10
- description = "生成新的工具代码并自动注册到Jarvis,自动扩充Jarvis的能力"
10
+ description = "Generate new tool code and automatically register it to Jarvis, automatically expanding Jarvis's capabilities"
11
11
  parameters = {
12
12
  "type": "object",
13
13
  "properties": {
14
14
  "tool_name": {
15
15
  "type": "string",
16
- "description": "工具的名称(snake_case格式)"
16
+ "description": "Name of the tool (in snake_case format)"
17
17
  },
18
18
  "class_name": {
19
19
  "type": "string",
20
- "description": "工具类的名称(PascalCase格式)"
20
+ "description": "Name of the tool class (in PascalCase format)"
21
21
  },
22
22
  "description": {
23
23
  "type": "string",
24
- "description": "工具的功能描述"
24
+ "description": "Description of the tool's functionality"
25
25
  },
26
26
  "parameters": {
27
27
  "type": "object",
28
- "description": "工具参数的JSON Schema定义"
28
+ "description": "JSON Schema definition of tool parameters"
29
29
  }
30
30
  },
31
31
  "required": ["tool_name", "class_name", "description", "parameters"]
@@ -44,14 +44,14 @@ class ToolGeneratorTool:
44
44
  """使用大模型生成工具代码"""
45
45
  model = PlatformRegistry.get_global_platform_registry().get_codegen_platform()
46
46
 
47
- prompt = f"""请生成一个Python工具类的代码,要求如下,除了代码,不要输出任何内容:
47
+ prompt = f"""Please generate the code for a Python tool class, with the following requirements, and do not output any content except the code:
48
48
 
49
- 1. 类名: {class_name}
50
- 2. 工具名称: {tool_name}
51
- 3. 功能描述: {description}
52
- 4. 参数定义: {parameters}
49
+ 1. Class name: {class_name}
50
+ 2. Tool name: {tool_name}
51
+ 3. Function description: {description}
52
+ 4. Parameter definition: {parameters}
53
53
 
54
- 严格按照以下格式生成代码(各函数的参数和返回值一定要与示例一致)
54
+ Strictly follow the following format to generate code (the parameters and return values of each function must be consistent with the example):
55
55
 
56
56
  ```python
57
57
  from typing import Dict, Any, Protocol, Optional
@@ -60,7 +60,7 @@ from jarvis.models.registry import ModelRegistry
60
60
 
61
61
  class ExampleTool:
62
62
  name = "example_tool"
63
- description = "示例工具"
63
+ description = "Example tool"
64
64
  parameters = {{
65
65
  "type": "object",
66
66
  "properties": {{
@@ -70,22 +70,22 @@ class ExampleTool:
70
70
  }}
71
71
 
72
72
  def __init__(self):
73
- self.model = ModelRegistry.get_global_model()
73
+ self.model = ModelRegistry.get_global_platform_registry().get_normal_platform()
74
74
 
75
75
  def execute(self, args: Dict) -> Dict[str, Any]:
76
76
  try:
77
- # 验证参数示例
77
+ # Validate parameter example
78
78
  if "param1" not in args:
79
- return {{"success": False, "error": "缺少必需参数: param1"}}
79
+ return {{"success": False, "error": "Missing required parameter: param1"}}
80
80
 
81
- # 记录操作示例
82
- PrettyOutput.print(f"处理参数: {{args['param1']}}", OutputType.INFO)
81
+ # Record operation example
82
+ PrettyOutput.print(f"Processing parameter: {{args['param1']}}", OutputType.INFO)
83
83
 
84
- # 使用大模型示例
85
- response = self.model.chat("prompt")
84
+ # Use large model example
85
+ response = self.model.chat_until_success("prompt")
86
86
 
87
- # 实现具体功能
88
- result = "处理结果"
87
+ # Implement specific functionality
88
+ result = "Processing result"
89
89
 
90
90
  return {{
91
91
  "success": True,
@@ -101,7 +101,7 @@ class ExampleTool:
101
101
  ```"""
102
102
 
103
103
  # 调用模型生成代码
104
- response = model.chat(prompt)
104
+ response = model.chat_until_success(prompt)
105
105
 
106
106
  # 提取代码块
107
107
  code_start = response.find("```python")
@@ -147,7 +147,7 @@ class ExampleTool:
147
147
  f.write("# Jarvis Tools\n")
148
148
 
149
149
  # 注册工具
150
- success = ToolRegistry.get_global_tool_registry().register_tool_by_file(tool_file)
150
+ success = ToolRegistry.get_global_tool_registry().register_tool_by_file(str(tool_file))
151
151
  if not success:
152
152
  return {
153
153
  "success": False,
@@ -8,22 +8,22 @@ class MethodologyTool:
8
8
  """经验管理工具"""
9
9
 
10
10
  name = "methodology"
11
- description = "管理问题处理方法论,支持添加、更新、删除操作"
11
+ description = "Manage problem-solving methodologies, supporting add, update, and delete operations"
12
12
  parameters = {
13
13
  "type": "object",
14
14
  "properties": {
15
15
  "operation": {
16
16
  "type": "string",
17
- "description": "操作类型 (delete/update/add)",
17
+ "description": "Operation type (delete/update/add)",
18
18
  "enum": ["delete", "update", "add"]
19
19
  },
20
20
  "problem_type": {
21
21
  "type": "string",
22
- "description": "问题类型,例如:code_review, bug_fix "
22
+ "description": "Problem type, e.g., code_review, bug_fix, etc."
23
23
  },
24
24
  "content": {
25
25
  "type": "string",
26
- "description": "方法论内容 (update/add 时必需)",
26
+ "description": "Methodology content (required for update/add)",
27
27
  "optional": True
28
28
  }
29
29
  },
jarvis/tools/rag.py CHANGED
@@ -5,21 +5,21 @@ from jarvis.jarvis_rag.main import RAGTool as RAGCore
5
5
 
6
6
  class RAGTool:
7
7
  name = "rag"
8
- description = "基于文档目录进行问答,支持多种文档格式(txtpdfdocx等)"
8
+ description = "Ask questions based on a document directory, supporting multiple document formats (txt, pdf, docx, etc.)"
9
9
  parameters = {
10
10
  "type": "object",
11
11
  "properties": {
12
12
  "dir": {
13
13
  "type": "string",
14
- "description": "文档目录路径,支持相对路径和绝对路径"
14
+ "description": "Document directory path, supports both relative and absolute paths"
15
15
  },
16
16
  "question": {
17
17
  "type": "string",
18
- "description": "要询问的问题"
18
+ "description": "The question to ask"
19
19
  },
20
20
  "rebuild_index": {
21
21
  "type": "boolean",
22
- "description": "是否重建索引",
22
+ "description": "Whether to rebuild the index",
23
23
  "default": False
24
24
  }
25
25
  },
jarvis/tools/registry.py CHANGED
@@ -39,7 +39,7 @@ class ToolRegistry:
39
39
  if file_path.name in ["base.py", "__init__.py", "registry.py"]:
40
40
  continue
41
41
 
42
- self.register_tool_by_file(file_path)
42
+ self.register_tool_by_file(str(file_path))
43
43
 
44
44
  def _load_external_tools(self):
45
45
  """从~/.jarvis_tools加载外部工具"""
@@ -53,7 +53,7 @@ class ToolRegistry:
53
53
  if file_path.name == "__init__.py":
54
54
  continue
55
55
 
56
- self.register_tool_by_file(file_path)
56
+ self.register_tool_by_file(str(file_path))
57
57
 
58
58
  def register_tool_by_file(self, file_path: str):
59
59
  """从指定文件加载并注册工具
@@ -65,19 +65,19 @@ class ToolRegistry:
65
65
  bool: 是否成功加载工具
66
66
  """
67
67
  try:
68
- file_path = Path(file_path).resolve() # 获取绝对路径
69
- if not file_path.exists() or not file_path.is_file():
70
- PrettyOutput.print(f"文件不存在: {file_path}", OutputType.ERROR)
68
+ p_file_path = Path(file_path).resolve() # 获取绝对路径
69
+ if not p_file_path.exists() or not p_file_path.is_file():
70
+ PrettyOutput.print(f"File does not exist: {p_file_path}", OutputType.ERROR)
71
71
  return False
72
72
 
73
73
  # 动态导入模块
74
- module_name = file_path.stem
75
- spec = importlib.util.spec_from_file_location(module_name, file_path)
74
+ module_name = p_file_path.stem
75
+ spec = importlib.util.spec_from_file_location(module_name, p_file_path) # type: ignore
76
76
  if not spec or not spec.loader:
77
- PrettyOutput.print(f"无法加载模块: {file_path}", OutputType.ERROR)
77
+ PrettyOutput.print(f"Failed to load module: {p_file_path}", OutputType.ERROR)
78
78
  return False
79
79
 
80
- module = importlib.util.module_from_spec(spec)
80
+ module = importlib.util.module_from_spec(spec) # type: ignore
81
81
  sys.modules[module_name] = module # 添加到 sys.modules 以支持相对导入
82
82
  spec.loader.exec_module(module)
83
83
 
@@ -101,18 +101,18 @@ class ToolRegistry:
101
101
  parameters=tool_instance.parameters,
102
102
  func=tool_instance.execute
103
103
  )
104
- PrettyOutput.print(f" {file_path} 加载工具: {tool_instance.name}: {tool_instance.description}", OutputType.SUCCESS)
104
+ PrettyOutput.print(f"Loaded tool from {p_file_path}: {tool_instance.name}: {tool_instance.description}", OutputType.SUCCESS)
105
105
  tool_found = True
106
106
  break
107
107
 
108
108
  if not tool_found:
109
- PrettyOutput.print(f"文件中未找到有效的工具类: {file_path}", OutputType.WARNING)
109
+ PrettyOutput.print(f"No valid tool class found in the file: {p_file_path}", OutputType.WARNING)
110
110
  return False
111
111
 
112
112
  return True
113
113
 
114
114
  except Exception as e:
115
- PrettyOutput.print(f"加载工具失败 {file_path.name}: {str(e)}", OutputType.ERROR)
115
+ PrettyOutput.print(f"Failed to load tool from {p_file_path.name}: {str(e)}", OutputType.ERROR)
116
116
  return False
117
117
 
118
118
  def register_tool(self, name: str, description: str, parameters: Dict, func: Callable):
@@ -149,16 +149,16 @@ class ToolRegistry:
149
149
  try:
150
150
  args = json.loads(args)
151
151
  except json.JSONDecodeError:
152
- PrettyOutput.print(f"工具参数格式无效: {name}", OutputType.ERROR)
152
+ PrettyOutput.print(f"Invalid tool parameters format: {name}", OutputType.ERROR)
153
153
  return ""
154
154
 
155
155
  # 显示工具调用信息
156
- PrettyOutput.section(f"执行工具: {name}", OutputType.TOOL)
156
+ PrettyOutput.section(f"Executing tool: {name}", OutputType.TOOL)
157
157
  if isinstance(args, dict):
158
158
  for key, value in args.items():
159
- PrettyOutput.print(f"参数: {key} = {value}", OutputType.DEBUG)
159
+ PrettyOutput.print(f"Parameter: {key} = {value}", OutputType.DEBUG)
160
160
  else:
161
- PrettyOutput.print(f"参数: {args}", OutputType.DEBUG)
161
+ PrettyOutput.print(f"Parameter: {args}", OutputType.DEBUG)
162
162
 
163
163
  # 执行工具调用
164
164
  result = self.execute_tool(name, args)
@@ -169,58 +169,58 @@ class ToolRegistry:
169
169
  stderr = result.get("stderr", "")
170
170
  output_parts = []
171
171
  if stdout:
172
- output_parts.append(f"输出:\n{stdout}")
172
+ output_parts.append(f"Output:\n{stdout}")
173
173
  if stderr:
174
- output_parts.append(f"错误:\n{stderr}")
174
+ output_parts.append(f"Error:\n{stderr}")
175
175
  output = "\n\n".join(output_parts)
176
- output = "没有输出和错误" if not output else output
177
- PrettyOutput.section("执行成功", OutputType.SUCCESS)
176
+ output = "No output and error" if not output else output
177
+ PrettyOutput.section("Execution successful", OutputType.SUCCESS)
178
178
 
179
179
  # 如果输出超过4k字符,使用大模型总结
180
180
  if len(output) > self.max_context_length:
181
181
  try:
182
- PrettyOutput.print("输出较长,正在总结...", OutputType.PROGRESS)
182
+ PrettyOutput.print("Output is too long, summarizing...", OutputType.PROGRESS)
183
183
  model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
184
184
 
185
185
  # 如果输出超过最大上下文长度,只取最后部分
186
186
  max_len = self.max_context_length
187
187
  if len(output) > max_len:
188
188
  output_to_summarize = output[-max_len:]
189
- truncation_notice = f"\n(注意: 由于输出过长,仅总结最后{max_len}字符)"
189
+ truncation_notice = f"\n(Note: Due to the length of the output, only the last {max_len} characters are summarized)"
190
190
  else:
191
191
  output_to_summarize = output
192
192
  truncation_notice = ""
193
193
 
194
- prompt = f"""请总结以下工具执行结果,提取关键信息和重要结果。注意:
195
- 1. 保留所有重要的数值、路径、错误信息等关键数据
196
- 2. 保持结果的准确性
197
- 3. 用简洁的语言描述主要内容
198
- 4. 如果有错误信息,确保包含在总结中
194
+ prompt = f"""Please summarize the execution result of the following tool, extracting key information and important results. Note:
195
+ 1. Keep all important numerical values, paths, error information, etc.
196
+ 2. Maintain the accuracy of the results
197
+ 3. Describe the main content in concise language
198
+ 4. If there is error information, ensure it is included in the summary
199
199
 
200
- 工具名称: {name}
201
- 执行结果:
200
+ Tool name: {name}
201
+ Execution result:
202
202
  {output_to_summarize}
203
203
 
204
- 请提供总结:"""
204
+ Please provide a summary:"""
205
205
 
206
- summary = model.chat(prompt)
207
- output = f"""--- 原始输出较长,以下是总结 ---{truncation_notice}
206
+ summary = model.chat_until_success(prompt)
207
+ output = f"""--- Original output is too long, here is the summary ---{truncation_notice}
208
208
 
209
209
  {summary}
210
210
 
211
- --- 总结结束 ---"""
211
+ --- Summary ends ---"""
212
212
 
213
213
  except Exception as e:
214
- PrettyOutput.print(f"总结失败: {str(e)}", OutputType.ERROR)
215
- output = f"输出较长 ({len(output)} 字符),建议查看原始输出。\n前300字符预览:\n{output[:300]}..."
214
+ PrettyOutput.print(f"Summary failed: {str(e)}", OutputType.ERROR)
215
+ output = f"Output is too long ({len(output)} characters), it is recommended to view the original output.\nPreview of the first 300 characters:\n{output[:300]}..."
216
216
 
217
217
  else:
218
218
  error_msg = result["error"]
219
- output = f"执行失败: {error_msg}"
220
- PrettyOutput.section("执行失败", OutputType.ERROR)
219
+ output = f"Execution failed: {error_msg}"
220
+ PrettyOutput.section("Execution failed", OutputType.ERROR)
221
221
 
222
222
  return output
223
223
 
224
224
  except Exception as e:
225
- PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
225
+ PrettyOutput.print(f"Tool execution failed: {str(e)}", OutputType.ERROR)
226
226
  return f"Tool call failed: {str(e)}"