jarvis-ai-assistant 0.1.125__py3-none-any.whl → 0.1.128__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 (49) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +205 -187
  3. jarvis/jarvis_code_agent/code_agent.py +116 -109
  4. jarvis/jarvis_code_agent/patch.py +157 -138
  5. jarvis/jarvis_code_agent/shell_input_handler.py +22 -0
  6. jarvis/jarvis_codebase/main.py +314 -288
  7. jarvis/jarvis_dev/main.py +695 -716
  8. jarvis/jarvis_lsp/base.py +0 -12
  9. jarvis/jarvis_lsp/cpp.py +0 -9
  10. jarvis/jarvis_lsp/go.py +0 -9
  11. jarvis/jarvis_lsp/python.py +0 -28
  12. jarvis/jarvis_lsp/registry.py +0 -1
  13. jarvis/jarvis_lsp/rust.py +0 -9
  14. jarvis/jarvis_multi_agent/__init__.py +52 -52
  15. jarvis/jarvis_platform/base.py +6 -5
  16. jarvis/jarvis_platform_manager/main.py +1 -1
  17. jarvis/jarvis_rag/main.py +250 -186
  18. jarvis/jarvis_smart_shell/main.py +0 -1
  19. jarvis/jarvis_tools/ask_codebase.py +10 -9
  20. jarvis/jarvis_tools/ask_user.py +2 -2
  21. jarvis/jarvis_tools/base.py +4 -4
  22. jarvis/jarvis_tools/chdir.py +28 -28
  23. jarvis/jarvis_tools/code_review.py +44 -39
  24. jarvis/jarvis_tools/create_code_agent.py +4 -4
  25. jarvis/jarvis_tools/create_sub_agent.py +7 -7
  26. jarvis/jarvis_tools/execute_shell.py +53 -23
  27. jarvis/jarvis_tools/execute_shell_script.py +3 -3
  28. jarvis/jarvis_tools/file_operation.py +70 -41
  29. jarvis/jarvis_tools/git_commiter.py +61 -51
  30. jarvis/jarvis_tools/lsp_find_definition.py +7 -7
  31. jarvis/jarvis_tools/lsp_prepare_rename.py +7 -7
  32. jarvis/jarvis_tools/methodology.py +6 -6
  33. jarvis/jarvis_tools/rag.py +5 -5
  34. jarvis/jarvis_tools/read_webpage.py +52 -32
  35. jarvis/jarvis_tools/registry.py +167 -180
  36. jarvis/jarvis_tools/search_web.py +66 -41
  37. jarvis/jarvis_tools/select_code_files.py +3 -3
  38. jarvis/jarvis_tools/tool_generator.py +68 -55
  39. jarvis/jarvis_utils/methodology.py +77 -59
  40. jarvis/jarvis_utils/output.py +1 -0
  41. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/METADATA +31 -17
  42. jarvis_ai_assistant-0.1.128.dist-info/RECORD +74 -0
  43. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/WHEEL +1 -1
  44. jarvis/jarvis_tools/lsp_validate_edit.py +0 -141
  45. jarvis/jarvis_tools/read_code.py +0 -192
  46. jarvis_ai_assistant-0.1.125.dist-info/RECORD +0 -75
  47. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/LICENSE +0 -0
  48. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/entry_points.txt +0 -0
  49. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@ import subprocess
4
4
  from typing import Dict, Any
5
5
  import tempfile
6
6
  import yaml
7
+ from yaspin import yaspin
7
8
  from jarvis.jarvis_platform.registry import PlatformRegistry
8
9
  import sys
9
10
  import argparse
@@ -15,13 +16,13 @@ from jarvis.jarvis_utils.utils import init_env
15
16
 
16
17
  class GitCommitTool:
17
18
  name = "git_commit_agent"
18
- description = "Automatically generate and execute git commits based on code changes"
19
+ description = "根据代码变更自动生成并执行Git提交"
19
20
  parameters = {
20
21
  "type": "object",
21
22
  "properties": {
22
23
  "lang": {
23
24
  "type": "string",
24
- "description": "Language for commit message",
25
+ "description": "提交信息的语言",
25
26
  "default": "Chinese"
26
27
  }
27
28
  },
@@ -54,59 +55,68 @@ class GitCommitTool:
54
55
  PrettyOutput.print("没有未提交的更改", OutputType.SUCCESS)
55
56
  return {"success": True, "stdout": "No changes to commit", "stderr": ""}
56
57
 
57
- PrettyOutput.print("准备添加文件到提交...", OutputType.SYSTEM)
58
- subprocess.Popen(
59
- ["git", "add", "."],
60
- stdout=subprocess.DEVNULL,
61
- stderr=subprocess.DEVNULL
62
- ).wait()
63
-
64
- PrettyOutput.print("获取差异...", OutputType.SYSTEM)
65
- process = subprocess.Popen(
66
- ["git", "diff", "--cached", "--exit-code"],
67
- stdout=subprocess.PIPE,
68
- stderr=subprocess.PIPE
69
- )
70
- diff = process.communicate()[0].decode()
71
- PrettyOutput.print(diff, OutputType.CODE, lang="diff")
72
-
73
- prompt = f'''Generate commit message by the following rules:
74
- You should write commit message in {args.get('lang', 'Chinese')}
75
- # Required Structure
76
- YOU MUST USE EXACTLY THIS FORMAT:
77
- <COMMIT_MESSAGE>
78
- <type>(<scope>): <subject>
79
- Body description in imperative mood
80
- </COMMIT_MESSAGE>
81
- # Format Rules
82
- 1. Types: fix, feat, docs, style, refactor, test, chore
83
- 2. Scope indicates module (e.g. auth, database)
84
- 3. Subject line <= 72 chars, no period
85
- 4. Body explains WHAT and WHY for every change, using present tense
86
- 5. Do not omit any changes
87
- # Analysis Material
88
- {diff}
89
- '''
90
-
91
- PrettyOutput.print("生成提交消息...", OutputType.SYSTEM)
92
- platform = PlatformRegistry().get_codegen_platform()
93
- platform.set_suppress_output(True)
94
- commit_message = platform.chat_until_success(prompt)
95
- commit_message = self._extract_commit_message(commit_message)
96
-
97
- # 使用临时文件处理提交消息
98
- with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
99
- tmp_file.write(commit_message)
100
- tmp_file.flush() # 确保内容写入文件
101
- commit_cmd = ["git", "commit", "-F", tmp_file.name]
102
- PrettyOutput.print("提交...", OutputType.INFO)
58
+ with yaspin(text="正在初始化提交流程...", color="cyan") as spinner:
59
+ # 添加文件
60
+ spinner.text = "正在添加文件到提交..."
103
61
  subprocess.Popen(
104
- commit_cmd,
62
+ ["git", "add", "."],
105
63
  stdout=subprocess.DEVNULL,
106
64
  stderr=subprocess.DEVNULL
107
65
  ).wait()
66
+ spinner.write("✅ 添加文件到提交")
67
+
68
+ # 获取差异
69
+ spinner.text = "正在获取代码差异..."
70
+ process = subprocess.Popen(
71
+ ["git", "diff", "--cached", "--exit-code"],
72
+ stdout=subprocess.PIPE,
73
+ stderr=subprocess.PIPE
74
+ )
75
+ diff = process.communicate()[0].decode()
76
+ spinner.write("✅ 获取差异")
77
+
78
+ # 生成提交信息
79
+ spinner.text = "正在生成提交消息..."
80
+ prompt = f'''根据以下规则生成提交信息:
81
+ 提交信息应使用{args.get('lang', '中文')}书写
82
+ # 必需结构
83
+ 必须使用以下格式:
84
+ <COMMIT_MESSAGE>
85
+ <类型>(<范围>): <主题>
86
+ 使用祈使语气描述变更内容
87
+ </COMMIT_MESSAGE>
88
+ # 格式规则
89
+ 1. 类型: fix, feat, docs, style, refactor, test, chore
90
+ 2. 范围表示模块 (例如: auth, database)
91
+ 3. 主题行 <= 72个字符,不以句号结尾
92
+ 4. 正文使用现在时态解释每个变更的内容和原因
93
+ 5. 不要遗漏任何变更
94
+ # 分析材料
95
+ {diff}
96
+ '''
97
+ platform = PlatformRegistry().get_codegen_platform()
98
+ commit_message = platform.chat_until_success(prompt)
99
+ commit_message = self._extract_commit_message(commit_message)
100
+ spinner.write("✅ 生成提交消息")
101
+
102
+ # 执行提交
103
+ spinner.text = "正在准备提交..."
104
+ with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
105
+ tmp_file.write(commit_message)
106
+ tmp_file.flush()
107
+ spinner.text = "正在执行提交..."
108
+ commit_cmd = ["git", "commit", "-F", tmp_file.name]
109
+ subprocess.Popen(
110
+ commit_cmd,
111
+ stdout=subprocess.DEVNULL,
112
+ stderr=subprocess.DEVNULL
113
+ ).wait()
114
+ spinner.write("✅ 提交")
115
+
116
+ commit_hash = self._get_last_commit_hash()
117
+ spinner.text = "完成提交"
118
+ spinner.ok("✅")
108
119
 
109
- commit_hash = self._get_last_commit_hash()
110
120
  PrettyOutput.print(f"提交哈希: {commit_hash}\n提交消息: {commit_message}", OutputType.SUCCESS)
111
121
 
112
122
  return {
@@ -116,7 +126,7 @@ Body description in imperative mood
116
126
  "commit_message": commit_message
117
127
  }),
118
128
  "stderr": ""
119
- }
129
+ }
120
130
 
121
131
  except Exception as e:
122
132
  return {
@@ -3,15 +3,15 @@ from typing import Dict, Any
3
3
  from jarvis.jarvis_lsp.registry import LSPRegistry
4
4
 
5
5
  class LSPFindDefinitionTool:
6
- """Tool for finding symbol definitions in code using LSP."""
6
+ """使用LSP在代码中查找符号定义的工具"""
7
7
 
8
8
  name = "lsp_find_definition"
9
- description = "Find the definition of a symbol in code"
9
+ description = "在代码中查找符号的定义"
10
10
  parameters = {
11
- "file_path": "Path to the file containing the symbol",
12
- "line": "Line number (0-based) of the symbol",
13
- "character": "Character position in the line",
14
- "language": f"Programming language of the file ({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
11
+ "file_path": "包含符号的文件路径",
12
+ "line": "符号所在的行号(从0开始)",
13
+ "character": "符号在行中的字符位置",
14
+ "language": f"文件的编程语言({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())}"
15
15
  }
16
16
 
17
17
  @staticmethod
@@ -131,4 +131,4 @@ class LSPFindDefinitionTool:
131
131
  }
132
132
  finally:
133
133
  if lsp:
134
- lsp.shutdown()
134
+ lsp.shutdown()
@@ -3,15 +3,15 @@ from typing import Dict, Any
3
3
  from jarvis.jarvis_lsp.registry import LSPRegistry
4
4
 
5
5
  class LSPPrepareRenameTool:
6
- """Tool for checking if a symbol can be renamed using LSP."""
6
+ """使用LSP检查符号是否可以安全重命名并显示所有受影响位置的工具"""
7
7
 
8
8
  name = "lsp_prepare_rename"
9
- description = "Check if a symbol can be safely renamed and show all locations that would be affected"
9
+ description = "检查符号是否可以安全重命名,并显示所有受影响的位置"
10
10
  parameters = {
11
- "file_path": "Path to the file containing the symbol",
12
- "line": "Line number (0-based) of the symbol",
13
- "character": "Character position in the line",
14
- "language": f"Programming language of the file ({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
11
+ "file_path": "包含符号的文件路径",
12
+ "line": "符号所在的行号(从0开始)",
13
+ "character": "符号在行中的字符位置",
14
+ "language": f"文件的编程语言({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())}"
15
15
  }
16
16
 
17
17
  @staticmethod
@@ -127,4 +127,4 @@ class LSPPrepareRenameTool:
127
127
  }
128
128
  finally:
129
129
  if lsp:
130
- lsp.shutdown()
130
+ lsp.shutdown()
@@ -8,25 +8,25 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
8
8
 
9
9
 
10
10
  class MethodologyTool:
11
- """Experience management tool"""
11
+ """经验管理工具"""
12
12
 
13
13
  name = "methodology"
14
- description = "Manage problem-solving methodologies, supporting add, update, and delete operations"
14
+ description = "管理问题解决方法论,支持添加、更新和删除操作"
15
15
  parameters = {
16
16
  "type": "object",
17
17
  "properties": {
18
18
  "operation": {
19
19
  "type": "string",
20
- "description": "Operation type (delete/update/add)",
20
+ "description": "操作类型(delete/update/add",
21
21
  "enum": ["delete", "update", "add"]
22
22
  },
23
23
  "problem_type": {
24
24
  "type": "string",
25
- "description": "Problem type, e.g., code_review, bug_fix, etc."
25
+ "description": "问题类型,例如:code_review, bug_fix "
26
26
  },
27
27
  "content": {
28
28
  "type": "string",
29
- "description": "Methodology content (required for update/add)",
29
+ "description": "方法论内容(更新和添加时必填)",
30
30
  "optional": True
31
31
  }
32
32
  },
@@ -60,7 +60,7 @@ class MethodologyTool:
60
60
  except Exception as e:
61
61
  PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
62
62
  return {}
63
-
63
+
64
64
  def _save_methodologies(self, methodologies: Dict):
65
65
  """Save all methodologies"""
66
66
  try:
@@ -6,21 +6,21 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
6
 
7
7
  class RAGTool:
8
8
  name = "rag"
9
- description = "Ask questions based on a document directory, supporting multiple document formats (txt, pdf, docx, etc.)"
9
+ description = "基于文档目录进行问答,支持多种文档格式(txtpdfdocx等)"
10
10
  parameters = {
11
11
  "type": "object",
12
12
  "properties": {
13
13
  "dir": {
14
14
  "type": "string",
15
- "description": "Document directory path, supports both relative and absolute paths"
15
+ "description": "文档目录路径,支持相对路径和绝对路径"
16
16
  },
17
17
  "question": {
18
18
  "type": "string",
19
- "description": "The question to ask"
19
+ "description": "要询问的问题"
20
20
  },
21
21
  "rebuild_index": {
22
22
  "type": "boolean",
23
- "description": "Whether to rebuild the index",
23
+ "description": "是否重建索引",
24
24
  "default": False
25
25
  }
26
26
  },
@@ -145,4 +145,4 @@ def main():
145
145
  PrettyOutput.print(result["stderr"], OutputType.WARNING)
146
146
 
147
147
  if __name__ == "__main__":
148
- main()
148
+ main()
@@ -1,18 +1,19 @@
1
1
  from typing import Dict, Any
2
2
  import requests
3
3
  from bs4 import BeautifulSoup
4
+ from yaspin import yaspin
4
5
 
5
6
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
7
 
7
8
  class WebpageTool:
8
9
  name = "read_webpage"
9
- description = "Read webpage content, extract title, text and hyperlinks"
10
+ description = "读取网页内容,提取标题、文本和超链接"
10
11
  parameters = {
11
12
  "type": "object",
12
13
  "properties": {
13
14
  "url": {
14
15
  "type": "string",
15
- "description": "The URL of the webpage to read"
16
+ "description": "要读取的网页URL"
16
17
  }
17
18
  },
18
19
  "required": ["url"]
@@ -29,48 +30,67 @@ class WebpageTool:
29
30
  }
30
31
 
31
32
  # Send request
32
- PrettyOutput.print(f"正在读取网页:{url}", OutputType.INFO)
33
- response = requests.get(url, headers=headers, timeout=10)
34
- response.raise_for_status()
33
+ with yaspin(text="正在读取网页...", color="cyan") as spinner:
34
+ response = requests.get(url, headers=headers, timeout=10)
35
+ response.raise_for_status()
36
+ spinner.text = "网页读取完成"
37
+ spinner.ok("✅")
38
+
35
39
 
36
40
  # Use correct encoding
41
+
37
42
  response.encoding = response.apparent_encoding
38
43
 
39
44
  # Parse HTML
40
- soup = BeautifulSoup(response.text, 'html.parser')
45
+ with yaspin(text="正在解析网页...", color="cyan") as spinner:
46
+ soup = BeautifulSoup(response.text, 'html.parser')
47
+ spinner.text = "网页解析完成"
48
+ spinner.ok("✅")
41
49
 
42
50
  # Remove script and style tags
43
- for script in soup(["script", "style"]):
44
- script.decompose()
51
+ with yaspin(text="正在移除脚本和样式...", color="cyan") as spinner:
52
+ for script in soup(["script", "style"]):
53
+ script.decompose()
54
+ spinner.text = "脚本和样式移除完成"
55
+ spinner.ok("✅")
45
56
 
46
57
  # Extract title
47
- title = soup.title.string if soup.title else ""
48
- title = title.strip() if title else "No title"
49
-
50
- # Extract text and links
51
- text_parts = []
52
- links = []
58
+ with yaspin(text="正在提取标题...", color="cyan") as spinner:
59
+ title = soup.title.string if soup.title else ""
60
+ title = title.strip() if title else "No title"
61
+ spinner.text = "标题提取完成"
62
+ spinner.ok("✅")
53
63
 
54
- # Process content and collect links
55
- for element in soup.descendants:
56
- if element.name == 'a' and element.get('href'): # type: ignore
57
- href = element.get('href') # type: ignore
58
- text = element.get_text(strip=True)
59
- if text and href:
60
- links.append(f"[{text}]({href})")
61
- elif isinstance(element, str) and element.strip():
62
- text_parts.append(element.strip())
64
+ with yaspin(text="正在提取文本和链接...", color="cyan") as spinner:
65
+ # Extract text and links
66
+ text_parts = []
67
+ links = []
68
+
69
+ # Process content and collect links
70
+ for element in soup.descendants:
71
+ if element.name == 'a' and element.get('href'): # type: ignore
72
+ href = element.get('href') # type: ignore
73
+ text = element.get_text(strip=True)
74
+ if text and href:
75
+ links.append(f"[{text}]({href})")
76
+ elif isinstance(element, str) and element.strip():
77
+ text_parts.append(element.strip())
78
+ spinner.text = "文本和链接提取完成"
79
+ spinner.ok("✅")
63
80
 
64
81
  # Build output
65
- output = [
66
- f"Title: {title}",
67
- "",
68
- "Text content:",
69
- "\n".join(text_parts),
70
- "",
71
- "Links found:",
72
- "\n".join(links) if links else "No links found"
73
- ]
82
+ with yaspin(text="正在构建输出...", color="cyan") as spinner:
83
+ output = [
84
+ f"Title: {title}",
85
+ "",
86
+ "Text content:",
87
+ "\n".join(text_parts),
88
+ "",
89
+ "Links found:",
90
+ "\n".join(links) if links else "No links found"
91
+ ]
92
+ spinner.text = "输出构建完成"
93
+ spinner.ok("✅")
74
94
 
75
95
  return {
76
96
  "success": True,