jarvis-ai-assistant 0.1.134__py3-none-any.whl → 0.1.138__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 (78) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +201 -79
  3. jarvis/jarvis_agent/builtin_input_handler.py +16 -6
  4. jarvis/jarvis_agent/file_input_handler.py +9 -9
  5. jarvis/jarvis_agent/jarvis.py +10 -10
  6. jarvis/jarvis_agent/main.py +12 -11
  7. jarvis/jarvis_agent/output_handler.py +3 -3
  8. jarvis/jarvis_agent/patch.py +86 -62
  9. jarvis/jarvis_agent/shell_input_handler.py +5 -3
  10. jarvis/jarvis_code_agent/code_agent.py +134 -99
  11. jarvis/jarvis_code_agent/file_select.py +24 -24
  12. jarvis/jarvis_dev/main.py +45 -51
  13. jarvis/jarvis_git_details/__init__.py +0 -0
  14. jarvis/jarvis_git_details/main.py +179 -0
  15. jarvis/jarvis_git_squash/main.py +7 -7
  16. jarvis/jarvis_lsp/base.py +11 -11
  17. jarvis/jarvis_lsp/cpp.py +14 -14
  18. jarvis/jarvis_lsp/go.py +13 -13
  19. jarvis/jarvis_lsp/python.py +8 -8
  20. jarvis/jarvis_lsp/registry.py +21 -21
  21. jarvis/jarvis_lsp/rust.py +15 -15
  22. jarvis/jarvis_methodology/main.py +101 -0
  23. jarvis/jarvis_multi_agent/__init__.py +11 -11
  24. jarvis/jarvis_multi_agent/main.py +6 -6
  25. jarvis/jarvis_platform/__init__.py +1 -1
  26. jarvis/jarvis_platform/ai8.py +67 -89
  27. jarvis/jarvis_platform/base.py +14 -13
  28. jarvis/jarvis_platform/kimi.py +25 -28
  29. jarvis/jarvis_platform/ollama.py +24 -26
  30. jarvis/jarvis_platform/openai.py +15 -19
  31. jarvis/jarvis_platform/oyi.py +48 -50
  32. jarvis/jarvis_platform/registry.py +27 -28
  33. jarvis/jarvis_platform/yuanbao.py +38 -42
  34. jarvis/jarvis_platform_manager/main.py +81 -81
  35. jarvis/jarvis_platform_manager/openai_test.py +21 -21
  36. jarvis/jarvis_rag/file_processors.py +18 -18
  37. jarvis/jarvis_rag/main.py +261 -277
  38. jarvis/jarvis_smart_shell/main.py +12 -12
  39. jarvis/jarvis_tools/ask_codebase.py +28 -28
  40. jarvis/jarvis_tools/ask_user.py +8 -8
  41. jarvis/jarvis_tools/base.py +4 -4
  42. jarvis/jarvis_tools/chdir.py +9 -9
  43. jarvis/jarvis_tools/code_review.py +19 -19
  44. jarvis/jarvis_tools/create_code_agent.py +15 -15
  45. jarvis/jarvis_tools/execute_python_script.py +3 -3
  46. jarvis/jarvis_tools/execute_shell.py +11 -11
  47. jarvis/jarvis_tools/execute_shell_script.py +3 -3
  48. jarvis/jarvis_tools/file_analyzer.py +29 -29
  49. jarvis/jarvis_tools/file_operation.py +22 -20
  50. jarvis/jarvis_tools/find_caller.py +25 -25
  51. jarvis/jarvis_tools/find_methodolopy.py +65 -0
  52. jarvis/jarvis_tools/find_symbol.py +24 -24
  53. jarvis/jarvis_tools/function_analyzer.py +27 -27
  54. jarvis/jarvis_tools/git_commiter.py +9 -9
  55. jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -19
  56. jarvis/jarvis_tools/methodology.py +23 -62
  57. jarvis/jarvis_tools/project_analyzer.py +29 -33
  58. jarvis/jarvis_tools/rag.py +15 -15
  59. jarvis/jarvis_tools/read_code.py +24 -22
  60. jarvis/jarvis_tools/read_webpage.py +31 -31
  61. jarvis/jarvis_tools/registry.py +72 -52
  62. jarvis/jarvis_tools/tool_generator.py +18 -18
  63. jarvis/jarvis_utils/config.py +23 -23
  64. jarvis/jarvis_utils/embedding.py +83 -83
  65. jarvis/jarvis_utils/git_utils.py +20 -20
  66. jarvis/jarvis_utils/globals.py +18 -6
  67. jarvis/jarvis_utils/input.py +10 -9
  68. jarvis/jarvis_utils/methodology.py +140 -136
  69. jarvis/jarvis_utils/output.py +11 -11
  70. jarvis/jarvis_utils/utils.py +22 -70
  71. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/METADATA +1 -1
  72. jarvis_ai_assistant-0.1.138.dist-info/RECORD +85 -0
  73. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/entry_points.txt +2 -0
  74. jarvis/jarvis_tools/select_code_files.py +0 -62
  75. jarvis_ai_assistant-0.1.134.dist-info/RECORD +0 -82
  76. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/LICENSE +0 -0
  77. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/WHEEL +0 -0
  78. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # Shell command execution module
2
- #
2
+ #
3
3
  # Provides functionality to execute shell commands safely with:
4
4
  # - Command escaping
5
5
  # - Output capturing
@@ -12,7 +12,7 @@ from pathlib import Path
12
12
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
13
13
  class ShellTool:
14
14
  """Shell command execution tool
15
-
15
+
16
16
  Attributes:
17
17
  name: Tool identifier used in API
18
18
  description: Tool description for API documentation
@@ -32,10 +32,10 @@ class ShellTool:
32
32
  }
33
33
  def _escape_command(self, cmd: str) -> str:
34
34
  """Escape special characters in command to prevent shell injection
35
-
35
+
36
36
  Args:
37
37
  cmd: Raw command string
38
-
38
+
39
39
  Returns:
40
40
  Escaped command string with single quotes properly handled
41
41
  """
@@ -44,21 +44,21 @@ class ShellTool:
44
44
  try:
45
45
  # Get and clean command input
46
46
  command = args["command"].strip()
47
-
47
+
48
48
  # Generate temporary file name using process ID for uniqueness
49
49
  script_file = os.path.join(tempfile.gettempdir(), f"jarvis_shell_{os.getpid()}.sh")
50
50
  output_file = os.path.join(tempfile.gettempdir(), f"jarvis_shell_{os.getpid()}.log")
51
-
51
+
52
52
  # Write command to script file
53
53
  with open(script_file, 'w', encoding='utf-8') as f:
54
54
  f.write(f"#!/bin/bash\n{command}")
55
-
55
+
56
56
  # Use script command to capture both stdout and stderr
57
57
  tee_command = f"script -q -c 'bash {script_file}' {output_file}"
58
-
58
+
59
59
  # Execute command and capture return code
60
60
  os.system(tee_command)
61
-
61
+
62
62
  # Read and process output file
63
63
  try:
64
64
  with open(output_file, 'r', encoding='utf-8', errors='ignore') as f:
@@ -74,14 +74,14 @@ class ShellTool:
74
74
  # Clean up temporary files
75
75
  Path(script_file).unlink(missing_ok=True)
76
76
  Path(output_file).unlink(missing_ok=True)
77
-
77
+
78
78
  # Return successful result
79
79
  return {
80
80
  "success": True,
81
81
  "stdout": output,
82
82
  "stderr": "",
83
83
  }
84
-
84
+
85
85
  except Exception as e:
86
86
  # Ensure temporary files are cleaned up even if error occurs
87
87
  if 'script_file' in locals():
@@ -29,7 +29,7 @@ class ShellScriptTool:
29
29
  "stdout": "",
30
30
  "stderr": "Missing or empty script_content parameter"
31
31
  }
32
-
32
+
33
33
  # Create temporary script file
34
34
  script_path = os.path.join(tempfile.gettempdir(), f"jarvis_shell_script_{os.getpid()}.sh")
35
35
  try:
@@ -39,7 +39,7 @@ class ShellScriptTool:
39
39
  from jarvis.jarvis_tools.execute_shell import ShellTool
40
40
  shell_tool = ShellTool()
41
41
  result = shell_tool.execute({"command": f"bash {script_path}"})
42
-
42
+
43
43
  return {
44
44
  "success": result["success"],
45
45
  "stdout": result["stdout"],
@@ -48,7 +48,7 @@ class ShellScriptTool:
48
48
  finally:
49
49
  # Clean up temporary script file
50
50
  Path(script_path).unlink(missing_ok=True)
51
-
51
+
52
52
  except Exception as e:
53
53
  PrettyOutput.print(str(e), OutputType.ERROR)
54
54
  return {
@@ -12,7 +12,7 @@ class FileAnalyzerTool:
12
12
  单文件分析工具
13
13
  使用agent深入分析单个文件的结构、实现细节和代码质量
14
14
  """
15
-
15
+
16
16
  name = "file_analyzer"
17
17
  description = "深入分析单个文件的结构、实现细节和代码质量"
18
18
  parameters = {
@@ -35,26 +35,26 @@ class FileAnalyzerTool:
35
35
  },
36
36
  "required": ["file_path"]
37
37
  }
38
-
38
+
39
39
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
40
40
  """
41
41
  执行单文件分析工具
42
-
42
+
43
43
  Args:
44
44
  args: 包含参数的字典
45
-
45
+
46
46
  Returns:
47
47
  包含执行结果的字典
48
48
  """
49
49
  # 存储原始目录
50
50
  original_dir = os.getcwd()
51
-
51
+
52
52
  try:
53
53
  # 解析参数
54
54
  file_path = args.get("file_path", "")
55
55
  root_dir = args.get("root_dir", ".")
56
56
  objective = args.get("objective", "")
57
-
57
+
58
58
  # 验证参数
59
59
  if not file_path:
60
60
  return {
@@ -62,31 +62,31 @@ class FileAnalyzerTool:
62
62
  "stdout": "",
63
63
  "stderr": "必须提供文件路径"
64
64
  }
65
-
65
+
66
66
  # 确保文件路径是相对于root_dir的,如果是绝对路径则转换为相对路径
67
67
  abs_file_path = os.path.abspath(file_path)
68
68
  abs_root_dir = os.path.abspath(root_dir)
69
-
69
+
70
70
  if abs_file_path.startswith(abs_root_dir):
71
71
  rel_file_path = os.path.relpath(abs_file_path, abs_root_dir)
72
72
  else:
73
73
  rel_file_path = file_path
74
-
74
+
75
75
  # 获取文件扩展名和文件名
76
76
  file_ext = pathlib.Path(file_path).suffix
77
77
  file_name = os.path.basename(file_path)
78
-
78
+
79
79
  # 创建agent的system prompt
80
80
  system_prompt = self._create_system_prompt(
81
81
  rel_file_path, file_name, file_ext, root_dir, objective
82
82
  )
83
-
83
+
84
84
  # 创建agent的summary prompt
85
85
  summary_prompt = self._create_summary_prompt(rel_file_path, file_name)
86
-
86
+
87
87
  # 切换到根目录
88
88
  os.chdir(root_dir)
89
-
89
+
90
90
  # 检查文件是否存在
91
91
  if not os.path.isfile(rel_file_path):
92
92
  return {
@@ -94,18 +94,18 @@ class FileAnalyzerTool:
94
94
  "stdout": "",
95
95
  "stderr": f"文件不存在: {rel_file_path}"
96
96
  }
97
-
97
+
98
98
  # 构建使用的工具
99
99
  from jarvis.jarvis_tools.registry import ToolRegistry
100
100
  tool_registry = ToolRegistry()
101
101
  tool_registry.use_tools([
102
- "execute_shell",
103
- "read_code",
102
+ "execute_shell",
103
+ "read_code",
104
104
  "find_symbol",
105
- "function_analyzer",
105
+ "function_analyzer",
106
106
  "find_caller"
107
107
  ])
108
-
108
+
109
109
  # 创建并运行agent
110
110
  analyzer_agent = Agent(
111
111
  system_prompt=system_prompt,
@@ -117,17 +117,17 @@ class FileAnalyzerTool:
117
117
  execute_tool_confirm=False,
118
118
  auto_complete=True
119
119
  )
120
-
120
+
121
121
  # 运行agent并获取结果
122
122
  task_input = f"深入分析文件 {rel_file_path} 的结构、实现细节和代码质量"
123
123
  result = analyzer_agent.run(task_input)
124
-
124
+
125
125
  return {
126
126
  "success": True,
127
127
  "stdout": result,
128
128
  "stderr": ""
129
129
  }
130
-
130
+
131
131
  except Exception as e:
132
132
  PrettyOutput.print(str(e), OutputType.ERROR)
133
133
  return {
@@ -138,24 +138,24 @@ class FileAnalyzerTool:
138
138
  finally:
139
139
  # 恢复原始目录
140
140
  os.chdir(original_dir)
141
-
141
+
142
142
  def _create_system_prompt(self, file_path: str, file_name: str, file_ext: str,
143
143
  root_dir: str, objective: str) -> str:
144
144
  """
145
145
  创建Agent的system prompt
146
-
146
+
147
147
  Args:
148
148
  file_path: 文件路径
149
149
  file_name: 文件名
150
150
  file_ext: 文件扩展名
151
151
  root_dir: 代码库根目录
152
152
  objective: 分析目标
153
-
153
+
154
154
  Returns:
155
155
  系统提示文本
156
156
  """
157
157
  objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
158
-
158
+
159
159
  return f"""# 文件分析专家
160
160
 
161
161
  ## 任务描述
@@ -164,7 +164,7 @@ class FileAnalyzerTool:
164
164
  ## 工具使用优先级
165
165
  1. **优先使用 read_code**: 直接读取文件内容是分析文件的首选方式
166
166
  2. **优先使用 execute_shell**:
167
- - 使用 rg 搜索文件内容: `rg "pattern" {file_path}`
167
+ - 使用 rg 搜索文件内容: `rg "pattern" {file_path}`
168
168
  - 使用 loc 统计代码: `loc {file_path}`
169
169
  3. **仅在必要时使用其他分析工具**
170
170
 
@@ -259,11 +259,11 @@ class FileAnalyzerTool:
259
259
  def _create_summary_prompt(self, file_path: str, file_name: str) -> str:
260
260
  """
261
261
  创建Agent的summary prompt
262
-
262
+
263
263
  Args:
264
264
  file_path: 文件路径
265
265
  file_name: 文件名
266
-
266
+
267
267
  Returns:
268
268
  总结提示文本
269
269
  """
@@ -279,4 +279,4 @@ class FileAnalyzerTool:
279
279
  - 使用具体的代码片段和实例支持你的观点
280
280
  - 以清晰的Markdown格式呈现,简洁明了
281
281
 
282
- 在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的文件概览,而是直接解决分析目标中提出的具体问题。"""
282
+ 在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的文件概览,而是直接解决分析目标中提出的具体问题。"""
@@ -3,6 +3,7 @@ import os
3
3
 
4
4
  from yaspin import yaspin
5
5
 
6
+ from jarvis.jarvis_utils.globals import add_read_file_record
6
7
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
8
 
8
9
 
@@ -34,11 +35,12 @@ class FileOperationTool:
34
35
  "required": ["operation", "files"]
35
36
  }
36
37
 
37
- def _handle_single_file(self, operation: str, filepath: str, content: str = "",
38
+ def _handle_single_file(self, operation: str, filepath: str, content: str = "",
38
39
  start_line: int = 1, end_line: int = -1) -> Dict[str, Any]:
39
40
  """Handle operations for a single file"""
40
41
  try:
41
42
  abs_path = os.path.abspath(filepath)
43
+ add_read_file_record(abs_path)
42
44
  if operation == "read":
43
45
  with yaspin(text=f"正在读取文件: {abs_path}...", color="cyan") as spinner:
44
46
  if not os.path.exists(abs_path):
@@ -47,18 +49,18 @@ class FileOperationTool:
47
49
  "stdout": "",
48
50
  "stderr": f"文件不存在: {abs_path}"
49
51
  }
50
-
52
+
51
53
  if os.path.getsize(abs_path) > 10 * 1024 * 1024: # 10MB
52
54
  return {
53
55
  "success": False,
54
56
  "stdout": "",
55
57
  "stderr": "File too large (>10MB)"
56
58
  }
57
-
59
+
58
60
  with open(abs_path, 'r', encoding='utf-8', errors="ignore") as f:
59
61
  lines = f.readlines()
60
-
61
-
62
+
63
+
62
64
  total_lines = len(lines)
63
65
  start_line = start_line if start_line >= 0 else total_lines + start_line + 1
64
66
  end_line = end_line if end_line >= 0 else total_lines + end_line + 1
@@ -66,7 +68,7 @@ class FileOperationTool:
66
68
  end_line = max(1, min(end_line, total_lines))
67
69
  if end_line == -1:
68
70
  end_line = total_lines
69
-
71
+
70
72
  if start_line > end_line:
71
73
  spinner.text = "无效的行范围"
72
74
  spinner.fail("❌")
@@ -76,10 +78,10 @@ class FileOperationTool:
76
78
  "stdout": "",
77
79
  "stderr": error_msg
78
80
  }
79
-
81
+
80
82
  content = "".join(lines[start_line - 1:end_line])
81
- output = f"\n文件: {abs_path}\n行: [{start_line}-{end_line}]\n{content}" + "\n\n" + "="*80 + "\n\n"
82
-
83
+ output = f"\n文件: {abs_path}\n行: [{start_line}-{end_line}]\n{content}" + "\n\n"
84
+
83
85
  spinner.text = f"文件读取完成: {abs_path}"
84
86
  spinner.ok("✅")
85
87
  return {
@@ -104,7 +106,7 @@ class FileOperationTool:
104
106
  "stdout": "",
105
107
  "stderr": f"Unknown operation: {operation}"
106
108
  }
107
-
109
+
108
110
  except Exception as e:
109
111
  PrettyOutput.print(str(e), OutputType.ERROR)
110
112
  return {
@@ -115,10 +117,10 @@ class FileOperationTool:
115
117
 
116
118
  def execute(self, args: Dict) -> Dict[str, Any]:
117
119
  """Execute file operations for multiple files
118
-
120
+
119
121
  Args:
120
122
  args: Dictionary containing operation and files list
121
-
123
+
122
124
  Returns:
123
125
  Dict containing:
124
126
  - success: Boolean indicating overall success
@@ -127,21 +129,21 @@ class FileOperationTool:
127
129
  """
128
130
  try:
129
131
  operation = args["operation"].strip()
130
-
132
+
131
133
  if "files" not in args or not isinstance(args["files"], list):
132
134
  return {
133
135
  "success": False,
134
136
  "stdout": "",
135
137
  "stderr": "files parameter is required and must be a list"
136
138
  }
137
-
139
+
138
140
  all_outputs = []
139
141
  success = True
140
-
142
+
141
143
  for file_info in args["files"]:
142
144
  if not isinstance(file_info, dict) or "path" not in file_info:
143
145
  continue
144
-
146
+
145
147
  content = file_info.get("content", "") if operation == "write" else ""
146
148
  result = self._handle_single_file(
147
149
  operation,
@@ -150,22 +152,22 @@ class FileOperationTool:
150
152
  file_info.get("start_line", 1),
151
153
  file_info.get("end_line", -1)
152
154
  )
153
-
155
+
154
156
  if result["success"]:
155
157
  all_outputs.append(result["stdout"])
156
158
  else:
157
159
  all_outputs.append(f"Error with {file_info['path']}: {result['stderr']}")
158
160
  success = success and result["success"]
159
-
161
+
160
162
  # Combine all outputs with separators
161
163
  combined_output = "\n\n" + "="*80 + "\n\n".join(all_outputs)
162
-
164
+
163
165
  return {
164
166
  "success": success,
165
167
  "stdout": combined_output,
166
168
  "stderr": ""
167
169
  }
168
-
170
+
169
171
  except Exception as e:
170
172
  PrettyOutput.print(str(e), OutputType.ERROR)
171
173
  return {
@@ -11,7 +11,7 @@ class FindCallerTool:
11
11
  函数调用者查找工具
12
12
  使用agent查找代码库中所有调用指定函数的位置
13
13
  """
14
-
14
+
15
15
  name = "find_caller"
16
16
  description = "查找所有调用指定函数的代码位置"
17
17
  parameters = {
@@ -50,20 +50,20 @@ class FindCallerTool:
50
50
  },
51
51
  "required": ["function_name"]
52
52
  }
53
-
53
+
54
54
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
55
55
  """
56
56
  执行调用者查找工具
57
-
57
+
58
58
  Args:
59
59
  args: 包含参数的字典
60
-
60
+
61
61
  Returns:
62
62
  包含执行结果的字典
63
63
  """
64
64
  # 存储原始目录
65
65
  original_dir = os.getcwd()
66
-
66
+
67
67
  try:
68
68
  # 解析参数
69
69
  function_name = args.get("function_name", "")
@@ -71,7 +71,7 @@ class FindCallerTool:
71
71
  file_extensions = args.get("file_extensions", [])
72
72
  exclude_dirs = args.get("exclude_dirs", [])
73
73
  objective = args.get("objective", "")
74
-
74
+
75
75
  # 验证参数
76
76
  if not function_name:
77
77
  return {
@@ -79,23 +79,23 @@ class FindCallerTool:
79
79
  "stdout": "",
80
80
  "stderr": "必须提供函数名称"
81
81
  }
82
-
82
+
83
83
  # 创建agent的system prompt
84
84
  system_prompt = self._create_system_prompt(
85
85
  function_name, root_dir, file_extensions, exclude_dirs, objective
86
86
  )
87
-
87
+
88
88
  # 创建agent的summary prompt
89
89
  summary_prompt = self._create_summary_prompt(function_name)
90
-
90
+
91
91
  # 切换到根目录
92
92
  os.chdir(root_dir)
93
-
93
+
94
94
  # 构建使用的工具
95
95
  from jarvis.jarvis_tools.registry import ToolRegistry
96
96
  tool_registry = ToolRegistry()
97
97
  tool_registry.use_tools(["execute_shell", "read_code"])
98
-
98
+
99
99
  # 创建并运行agent
100
100
  caller_agent = Agent(
101
101
  system_prompt=system_prompt,
@@ -107,17 +107,17 @@ class FindCallerTool:
107
107
  execute_tool_confirm=False,
108
108
  auto_complete=True
109
109
  )
110
-
110
+
111
111
  # 运行agent并获取结果
112
112
  task_input = f"查找所有调用 '{function_name}' 函数的代码位置"
113
113
  result = caller_agent.run(task_input)
114
-
114
+
115
115
  return {
116
116
  "success": True,
117
117
  "stdout": result,
118
118
  "stderr": ""
119
119
  }
120
-
120
+
121
121
  except Exception as e:
122
122
  PrettyOutput.print(str(e), OutputType.ERROR)
123
123
  return {
@@ -128,41 +128,41 @@ class FindCallerTool:
128
128
  finally:
129
129
  # 恢复原始目录
130
130
  os.chdir(original_dir)
131
-
132
- def _create_system_prompt(self, function_name: str, root_dir: str,
131
+
132
+ def _create_system_prompt(self, function_name: str, root_dir: str,
133
133
  file_extensions: List[str], exclude_dirs: List[str],
134
134
  objective: str) -> str:
135
135
  """
136
136
  创建Agent的system prompt
137
-
137
+
138
138
  Args:
139
139
  function_name: 函数名称
140
140
  root_dir: 代码库根目录
141
141
  file_extensions: 文件扩展名列表
142
142
  exclude_dirs: 排除目录列表
143
143
  objective: 分析目标
144
-
144
+
145
145
  Returns:
146
146
  系统提示文本
147
147
  """
148
148
  file_ext_str = " ".join([f"*{ext}" for ext in file_extensions]) if file_extensions else ""
149
149
  exclude_str = " ".join([f"--glob '!{excl}'" for excl in exclude_dirs]) if exclude_dirs else ""
150
150
  objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
151
-
151
+
152
152
  search_pattern = f"\\b{function_name}\\s*\\("
153
-
153
+
154
154
  return f"""# 函数调用分析专家
155
155
 
156
156
  ## 任务描述
157
157
  查找所有调用 `{function_name}` 函数的代码位置,专注于分析目标所需的信息,生成有针对性的调用分析报告。{objective_text}
158
158
 
159
159
  ## 工具使用优先级
160
- 1. **优先使用 execute_shell 执行 rg 命令**:
160
+ 1. **优先使用 execute_shell 执行 rg 命令**:
161
161
  - `rg "\\b{function_name}\\s*\\(" --type py` 查找Python文件中的调用
162
162
  - `rg "\\b{function_name}\\s*\\(" --type js` 查找JavaScript文件中的调用
163
163
  - `rg -w "{function_name}" -A 2 -B 2` 查看调用上下文
164
164
 
165
- 2. **辅以 read_code**:
165
+ 2. **辅以 read_code**:
166
166
  - 找到调用位置后使用read_code阅读上下文
167
167
  - 读取关键调用者的完整实现
168
168
 
@@ -185,7 +185,7 @@ class FindCallerTool:
185
185
  ## 调用者查找工具指南
186
186
 
187
187
  ### execute_shell 搜索命令
188
- - **基本搜索**:
188
+ - **基本搜索**:
189
189
  - `rg "\\b{function_name}\\s*\\(" --type=文件类型`
190
190
  - 示例: `rg "\\b{function_name}\\s*\\(" --type py` 搜索Python文件中的调用
191
191
 
@@ -255,10 +255,10 @@ class FindCallerTool:
255
255
  def _create_summary_prompt(self, function_name: str) -> str:
256
256
  """
257
257
  创建Agent的summary prompt
258
-
258
+
259
259
  Args:
260
260
  function_name: 函数名称
261
-
261
+
262
262
  Returns:
263
263
  总结提示文本
264
264
  """
@@ -0,0 +1,65 @@
1
+ from typing import Dict, Any
2
+ from yaspin import yaspin
3
+
4
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
5
+ from jarvis.jarvis_utils.methodology import load_methodology
6
+
7
+ class FindMethodologyTool:
8
+ name = "find_methodology"
9
+ description = "方法论查找工具,用于在执行过程中查看历史方法论辅助决策"
10
+ parameters = {
11
+ "type": "object",
12
+ "properties": {
13
+ "query": {
14
+ "type": "string",
15
+ "description": "要搜索的查询文本"
16
+ }
17
+ },
18
+ "required": ["query"]
19
+ }
20
+
21
+ def execute(self, args: Dict) -> Dict[str, Any]:
22
+ """执行方法论查找操作
23
+
24
+ Args:
25
+ args (Dict): 包含查询文本的参数字典
26
+
27
+ Returns:
28
+ Dict[str, Any]: 包含成功状态、输出内容和错误信息的字典
29
+ """
30
+ try:
31
+ if "query" not in args:
32
+ return {
33
+ "success": False,
34
+ "stdout": "",
35
+ "stderr": "参数中必须包含查询文本"
36
+ }
37
+
38
+ with yaspin(text="搜索相关方法论...", color="cyan") as spinner:
39
+ methodology_prompt = load_methodology(args["query"])
40
+
41
+ if methodology_prompt:
42
+ spinner.text = "找到相关方法论"
43
+ spinner.ok("✅")
44
+ PrettyOutput.print(methodology_prompt, OutputType.INFO)
45
+ return {
46
+ "success": True,
47
+ "stdout": methodology_prompt,
48
+ "stderr": ""
49
+ }
50
+ else:
51
+ spinner.text = "未找到相关方法论"
52
+ spinner.fail("❌")
53
+ return {
54
+ "success": True,
55
+ "stdout": "未找到相关的方法论",
56
+ "stderr": ""
57
+ }
58
+
59
+ except Exception as e:
60
+ PrettyOutput.print(str(e), OutputType.ERROR)
61
+ return {
62
+ "success": False,
63
+ "stdout": "",
64
+ "stderr": f"方法论查找失败: {str(e)}"
65
+ }