jarvis-ai-assistant 0.1.130__py3-none-any.whl → 0.1.132__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.
Files changed (72) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +71 -38
  3. jarvis/jarvis_agent/builtin_input_handler.py +73 -0
  4. jarvis/{jarvis_code_agent → jarvis_agent}/file_input_handler.py +1 -1
  5. jarvis/jarvis_agent/main.py +1 -1
  6. jarvis/{jarvis_code_agent → jarvis_agent}/patch.py +77 -55
  7. jarvis/{jarvis_code_agent → jarvis_agent}/shell_input_handler.py +1 -2
  8. jarvis/jarvis_code_agent/code_agent.py +93 -88
  9. jarvis/jarvis_dev/main.py +335 -626
  10. jarvis/jarvis_git_squash/main.py +11 -32
  11. jarvis/jarvis_lsp/base.py +2 -26
  12. jarvis/jarvis_lsp/cpp.py +2 -14
  13. jarvis/jarvis_lsp/go.py +0 -13
  14. jarvis/jarvis_lsp/python.py +1 -30
  15. jarvis/jarvis_lsp/registry.py +10 -14
  16. jarvis/jarvis_lsp/rust.py +0 -12
  17. jarvis/jarvis_multi_agent/__init__.py +20 -29
  18. jarvis/jarvis_platform/ai8.py +7 -32
  19. jarvis/jarvis_platform/base.py +2 -7
  20. jarvis/jarvis_platform/kimi.py +3 -144
  21. jarvis/jarvis_platform/ollama.py +54 -68
  22. jarvis/jarvis_platform/openai.py +0 -4
  23. jarvis/jarvis_platform/oyi.py +0 -75
  24. jarvis/jarvis_platform/registry.py +1 -1
  25. jarvis/jarvis_platform/yuanbao.py +264 -0
  26. jarvis/jarvis_platform_manager/main.py +3 -3
  27. jarvis/jarvis_rag/file_processors.py +138 -0
  28. jarvis/jarvis_rag/main.py +1305 -425
  29. jarvis/jarvis_tools/ask_codebase.py +227 -41
  30. jarvis/jarvis_tools/code_review.py +229 -166
  31. jarvis/jarvis_tools/create_code_agent.py +76 -72
  32. jarvis/jarvis_tools/create_sub_agent.py +32 -15
  33. jarvis/jarvis_tools/execute_python_script.py +58 -0
  34. jarvis/jarvis_tools/execute_shell.py +15 -28
  35. jarvis/jarvis_tools/execute_shell_script.py +2 -2
  36. jarvis/jarvis_tools/file_analyzer.py +271 -0
  37. jarvis/jarvis_tools/file_operation.py +3 -3
  38. jarvis/jarvis_tools/find_caller.py +213 -0
  39. jarvis/jarvis_tools/find_symbol.py +211 -0
  40. jarvis/jarvis_tools/function_analyzer.py +248 -0
  41. jarvis/jarvis_tools/git_commiter.py +89 -70
  42. jarvis/jarvis_tools/lsp_find_definition.py +83 -67
  43. jarvis/jarvis_tools/lsp_find_references.py +62 -46
  44. jarvis/jarvis_tools/lsp_get_diagnostics.py +90 -74
  45. jarvis/jarvis_tools/methodology.py +89 -48
  46. jarvis/jarvis_tools/project_analyzer.py +220 -0
  47. jarvis/jarvis_tools/read_code.py +24 -3
  48. jarvis/jarvis_tools/read_webpage.py +195 -81
  49. jarvis/jarvis_tools/registry.py +132 -11
  50. jarvis/jarvis_tools/search_web.py +73 -30
  51. jarvis/jarvis_tools/tool_generator.py +7 -9
  52. jarvis/jarvis_utils/__init__.py +1 -0
  53. jarvis/jarvis_utils/config.py +67 -3
  54. jarvis/jarvis_utils/embedding.py +344 -45
  55. jarvis/jarvis_utils/git_utils.py +18 -2
  56. jarvis/jarvis_utils/input.py +7 -4
  57. jarvis/jarvis_utils/methodology.py +379 -7
  58. jarvis/jarvis_utils/output.py +5 -3
  59. jarvis/jarvis_utils/utils.py +62 -10
  60. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/METADATA +3 -4
  61. jarvis_ai_assistant-0.1.132.dist-info/RECORD +82 -0
  62. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/entry_points.txt +2 -0
  63. jarvis/jarvis_c2rust/c2rust.yaml +0 -734
  64. jarvis/jarvis_code_agent/builtin_input_handler.py +0 -43
  65. jarvis/jarvis_codebase/__init__.py +0 -0
  66. jarvis/jarvis_codebase/main.py +0 -1011
  67. jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -87
  68. jarvis/jarvis_tools/lsp_prepare_rename.py +0 -130
  69. jarvis_ai_assistant-0.1.130.dist-info/RECORD +0 -79
  70. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/LICENSE +0 -0
  71. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/WHEEL +0 -0
  72. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,213 @@
1
+ from typing import Dict, Any, List
2
+ import os
3
+
4
+ from jarvis.jarvis_agent import Agent
5
+ from jarvis.jarvis_platform.registry import PlatformRegistry
6
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
+
8
+
9
+ class FindCallerTool:
10
+ """
11
+ 函数调用者查找工具
12
+ 使用agent查找代码库中所有调用指定函数的位置
13
+ """
14
+
15
+ name = "find_caller"
16
+ description = "查找所有调用指定函数的代码位置"
17
+ parameters = {
18
+ "type": "object",
19
+ "properties": {
20
+ "function_name": {
21
+ "type": "string",
22
+ "description": "要查找调用者的函数名称"
23
+ },
24
+ "root_dir": {
25
+ "type": "string",
26
+ "description": "代码库根目录路径(可选)",
27
+ "default": "."
28
+ },
29
+ "file_extensions": {
30
+ "type": "array",
31
+ "items": {
32
+ "type": "string"
33
+ },
34
+ "description": "要搜索的文件扩展名列表(如:['.py', '.js'])(可选)",
35
+ "default": []
36
+ },
37
+ "exclude_dirs": {
38
+ "type": "array",
39
+ "items": {
40
+ "type": "string"
41
+ },
42
+ "description": "要排除的目录列表(可选)",
43
+ "default": []
44
+ },
45
+ "objective": {
46
+ "type": "string",
47
+ "description": "描述本次调用者查找的目标和用途,例如'评估修改函数的影响范围'",
48
+ "default": ""
49
+ }
50
+ },
51
+ "required": ["function_name"]
52
+ }
53
+
54
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
55
+ """
56
+ 执行调用者查找工具
57
+
58
+ Args:
59
+ args: 包含参数的字典
60
+
61
+ Returns:
62
+ 包含执行结果的字典
63
+ """
64
+ # 存储原始目录
65
+ original_dir = os.getcwd()
66
+
67
+ try:
68
+ # 解析参数
69
+ function_name = args.get("function_name", "")
70
+ root_dir = args.get("root_dir", ".")
71
+ file_extensions = args.get("file_extensions", [])
72
+ exclude_dirs = args.get("exclude_dirs", [])
73
+ objective = args.get("objective", "")
74
+
75
+ # 验证参数
76
+ if not function_name:
77
+ return {
78
+ "success": False,
79
+ "stdout": "",
80
+ "stderr": "必须提供函数名称"
81
+ }
82
+
83
+ # 创建agent的system prompt
84
+ system_prompt = self._create_system_prompt(
85
+ function_name, root_dir, file_extensions, exclude_dirs, objective
86
+ )
87
+
88
+ # 创建agent的summary prompt
89
+ summary_prompt = self._create_summary_prompt(function_name)
90
+
91
+ # 切换到根目录
92
+ os.chdir(root_dir)
93
+
94
+ # 构建使用的工具
95
+ from jarvis.jarvis_tools.registry import ToolRegistry
96
+ tool_registry = ToolRegistry()
97
+ tool_registry.use_tools(["execute_shell", "read_code"])
98
+
99
+ # 创建并运行agent
100
+ caller_agent = Agent(
101
+ system_prompt=system_prompt,
102
+ name=f"CallerFinder-{function_name}",
103
+ description=f"查找 '{function_name}' 函数的所有调用位置",
104
+ summary_prompt=summary_prompt,
105
+ platform=PlatformRegistry().get_codegen_platform(),
106
+ output_handler=[tool_registry],
107
+ need_summary=True,
108
+ is_sub_agent=True,
109
+ use_methodology=False,
110
+ record_methodology=False,
111
+ execute_tool_confirm=False,
112
+ auto_complete=True
113
+ )
114
+
115
+ # 运行agent并获取结果
116
+ task_input = f"查找所有调用 '{function_name}' 函数的代码位置"
117
+ result = caller_agent.run(task_input)
118
+
119
+ return {
120
+ "success": True,
121
+ "stdout": result,
122
+ "stderr": ""
123
+ }
124
+
125
+ except Exception as e:
126
+ PrettyOutput.print(str(e), OutputType.ERROR)
127
+ return {
128
+ "success": False,
129
+ "stdout": "",
130
+ "stderr": f"查找调用者失败: {str(e)}"
131
+ }
132
+ finally:
133
+ # 恢复原始目录
134
+ os.chdir(original_dir)
135
+
136
+ def _create_system_prompt(self, function_name: str, root_dir: str,
137
+ file_extensions: List[str], exclude_dirs: List[str],
138
+ objective: str) -> str:
139
+ """
140
+ 创建Agent的system prompt
141
+
142
+ Args:
143
+ function_name: 函数名称
144
+ root_dir: 代码库根目录
145
+ file_extensions: 文件扩展名列表
146
+ exclude_dirs: 排除目录列表
147
+ objective: 分析目标
148
+
149
+ Returns:
150
+ 系统提示文本
151
+ """
152
+ file_ext_str = " ".join([f"*{ext}" for ext in file_extensions]) if file_extensions else ""
153
+ exclude_str = " ".join([f"--glob '!{excl}'" for excl in exclude_dirs]) if exclude_dirs else ""
154
+ objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
155
+
156
+ search_pattern = f"\\b{function_name}\\s*\\("
157
+
158
+ return f"""# 函数调用分析专家
159
+
160
+ ## 任务描述
161
+ 查找所有调用 `{function_name}` 函数的代码位置,专注于分析目标所需的信息,生成有针对性的调用分析报告。{objective_text}
162
+
163
+ ## 工作环境
164
+ - 工作目录: `{root_dir}`
165
+ - 文件类型: {file_ext_str if file_ext_str else "所有文件"}
166
+ - 排除目录: {", ".join(exclude_dirs) if exclude_dirs else "无"}
167
+
168
+ ## 分析策略
169
+ 1. 首先理解分析目标,明确需要查找的信息类型
170
+ 2. 使用适当的搜索模式查找函数调用
171
+ 3. 验证搜索结果,确认是对目标函数的真正调用
172
+ 4. 分析调用上下文,了解调用的目的和方式
173
+ 5. 根据分析目标自行确定需要的分析深度和广度
174
+
175
+ ## 执行指令
176
+ - 使用ripgrep(rg)或grep搜索函数调用:
177
+ ```
178
+ rg -n "{search_pattern}" {file_ext_str} {exclude_str}
179
+ ```
180
+ - 使用`read_code`查看上下文分析调用情况
181
+ - 可能需要先找到函数定义以确认正确的函数签名
182
+
183
+ ## 输出要求
184
+ - 直接回应分析目标的关键问题
185
+ - 提供与目标相关的调用信息
186
+ - 分析内容应直接服务于分析目标
187
+ - 避免与目标无关的冗余信息
188
+ - 使用具体代码路径和调用示例支持分析结论
189
+ - 提供针对分析目标的具体见解和建议"""
190
+
191
+ def _create_summary_prompt(self, function_name: str) -> str:
192
+ """
193
+ 创建Agent的summary prompt
194
+
195
+ Args:
196
+ function_name: 函数名称
197
+
198
+ Returns:
199
+ 总结提示文本
200
+ """
201
+ return f"""# 函数 `{function_name}` 调用分析报告
202
+
203
+ ## 报告要求
204
+ 生成一份完全以分析目标为导向的函数调用分析报告。不要遵循固定的报告模板,而是完全根据分析目标来组织内容:
205
+
206
+ - 专注回答分析目标提出的问题
207
+ - 只包含与分析目标直接相关的调用发现和洞察
208
+ - 完全跳过与分析目标无关的内容,无需做全面分析
209
+ - 分析深度应与目标的具体需求匹配
210
+ - 使用具体的代码调用示例支持你的观点
211
+ - 以清晰的Markdown格式呈现,简洁明了
212
+
213
+ 在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的函数调用概览,而是直接解决分析目标中提出的具体问题。"""
@@ -0,0 +1,211 @@
1
+ from typing import Dict, Any, List
2
+ import os
3
+
4
+ from jarvis.jarvis_agent import Agent
5
+ from jarvis.jarvis_platform.registry import PlatformRegistry
6
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
+
8
+
9
+ class SymbolTool:
10
+ """
11
+ 符号查找工具
12
+ 使用agent查找代码库中的符号引用、定义和声明位置
13
+ """
14
+
15
+ name = "find_symbol"
16
+ description = "查找代码符号的引用、定义和声明位置"
17
+ parameters = {
18
+ "type": "object",
19
+ "properties": {
20
+ "symbol": {
21
+ "type": "string",
22
+ "description": "要查找的符号名称"
23
+ },
24
+ "root_dir": {
25
+ "type": "string",
26
+ "description": "代码库根目录路径(可选)",
27
+ "default": "."
28
+ },
29
+ "file_extensions": {
30
+ "type": "array",
31
+ "items": {
32
+ "type": "string"
33
+ },
34
+ "description": "要搜索的文件扩展名列表(如:['.py', '.js'])(可选)",
35
+ "default": []
36
+ },
37
+ "exclude_dirs": {
38
+ "type": "array",
39
+ "items": {
40
+ "type": "string"
41
+ },
42
+ "description": "要排除的目录列表(可选)",
43
+ "default": []
44
+ },
45
+ "objective": {
46
+ "type": "string",
47
+ "description": "描述本次符号查找的目标和用途,例如'了解该符号的使用模式以便重构'",
48
+ "default": ""
49
+ }
50
+ },
51
+ "required": ["symbol"]
52
+ }
53
+
54
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
55
+ """
56
+ 执行符号查找工具
57
+
58
+ Args:
59
+ args: 包含参数的字典
60
+
61
+ Returns:
62
+ 包含执行结果的字典
63
+ """
64
+ # 存储原始目录
65
+ original_dir = os.getcwd()
66
+
67
+ try:
68
+ # 解析参数
69
+ symbol = args.get("symbol", "")
70
+ root_dir = args.get("root_dir", ".")
71
+ file_extensions = args.get("file_extensions", [])
72
+ exclude_dirs = args.get("exclude_dirs", [])
73
+ objective = args.get("objective", "")
74
+
75
+ # 验证参数
76
+ if not symbol:
77
+ return {
78
+ "success": False,
79
+ "stdout": "",
80
+ "stderr": "必须提供符号名称"
81
+ }
82
+
83
+ # 创建agent的system prompt
84
+ system_prompt = self._create_system_prompt(
85
+ symbol, root_dir, file_extensions, exclude_dirs, objective
86
+ )
87
+
88
+ # 创建agent的summary prompt
89
+ summary_prompt = self._create_summary_prompt(symbol)
90
+
91
+ # 切换到根目录
92
+ os.chdir(root_dir)
93
+
94
+ # 构建使用的工具
95
+ from jarvis.jarvis_tools.registry import ToolRegistry
96
+ tool_registry = ToolRegistry()
97
+ tool_registry.use_tools(["execute_shell", "read_code"])
98
+
99
+ # 创建并运行agent
100
+ symbol_agent = Agent(
101
+ system_prompt=system_prompt,
102
+ name=f"SymbolFinder-{symbol}",
103
+ description=f"查找符号 '{symbol}' 的引用和定义位置",
104
+ summary_prompt=summary_prompt,
105
+ platform=PlatformRegistry().get_codegen_platform(),
106
+ output_handler=[tool_registry],
107
+ need_summary=True,
108
+ is_sub_agent=True,
109
+ use_methodology=False,
110
+ record_methodology=False,
111
+ execute_tool_confirm=False,
112
+ auto_complete=True
113
+ )
114
+
115
+ # 运行agent并获取结果
116
+ task_input = f"查找符号 '{symbol}' 在代码库中的引用、定义和声明位置"
117
+ result = symbol_agent.run(task_input)
118
+
119
+ return {
120
+ "success": True,
121
+ "stdout": result,
122
+ "stderr": ""
123
+ }
124
+
125
+ except Exception as e:
126
+ PrettyOutput.print(str(e), OutputType.ERROR)
127
+ return {
128
+ "success": False,
129
+ "stdout": "",
130
+ "stderr": f"符号查找失败: {str(e)}"
131
+ }
132
+ finally:
133
+ # 恢复原始目录
134
+ os.chdir(original_dir)
135
+
136
+ def _create_system_prompt(self, symbol: str, root_dir: str,
137
+ file_extensions: List[str], exclude_dirs: List[str],
138
+ objective: str) -> str:
139
+ """
140
+ 创建Agent的system prompt
141
+
142
+ Args:
143
+ symbol: 符号名称
144
+ root_dir: 代码库根目录
145
+ file_extensions: 文件扩展名列表
146
+ exclude_dirs: 排除目录列表
147
+ objective: 分析目标
148
+
149
+ Returns:
150
+ 系统提示文本
151
+ """
152
+ file_ext_str = " ".join([f"*{ext}" for ext in file_extensions]) if file_extensions else ""
153
+ exclude_str = " ".join([f"--glob '!{excl}'" for excl in exclude_dirs]) if exclude_dirs else ""
154
+ objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
155
+
156
+ return f"""# 代码符号分析专家
157
+
158
+ ## 任务描述
159
+ 查找符号 `{symbol}` 在代码库中的定义、声明和引用位置,专注于分析目标所需的信息,生成有针对性的符号分析报告。{objective_text}
160
+
161
+ ## 工作环境
162
+ - 工作目录: `{root_dir}`
163
+ - 文件类型: {file_ext_str if file_ext_str else "所有文件"}
164
+ - 排除目录: {", ".join(exclude_dirs) if exclude_dirs else "无"}
165
+
166
+ ## 分析策略
167
+ 1. 首先理解分析目标,明确需要查找的信息类型
168
+ 2. 使用适当的搜索模式查找符号定义和引用
169
+ 3. 验证搜索结果,确认是目标符号的真正使用
170
+ 4. 分析符号上下文,了解其用途和使用方式
171
+ 5. 根据分析目标自行确定需要的分析深度和广度
172
+
173
+ ## 执行指令
174
+ - 使用ripgrep(rg)或grep工具搜索代码库:
175
+ ```
176
+ rg -n "def\\s+{symbol}\\b|class\\s+{symbol}\\b|{symbol}\\s*=" {file_ext_str} {exclude_str}
177
+ rg -n "\\b{symbol}\\b" {file_ext_str} {exclude_str}
178
+ ```
179
+ - 使用`read_code`查看上下文确认结果
180
+
181
+ ## 输出要求
182
+ - 直接回应分析目标的关键问题
183
+ - 提供与目标相关的符号信息
184
+ - 分析内容应直接服务于分析目标
185
+ - 避免与目标无关的冗余信息
186
+ - 使用具体代码路径和使用示例支持分析结论
187
+ - 提供针对分析目标的具体见解和建议"""
188
+
189
+ def _create_summary_prompt(self, symbol: str) -> str:
190
+ """
191
+ 创建Agent的summary prompt
192
+
193
+ Args:
194
+ symbol: 符号名称
195
+
196
+ Returns:
197
+ 总结提示文本
198
+ """
199
+ return f"""# 符号 `{symbol}` 分析报告
200
+
201
+ ## 报告要求
202
+ 生成一份完全以分析目标为导向的符号分析报告。不要遵循固定的报告模板,而是完全根据分析目标来组织内容:
203
+
204
+ - 专注回答分析目标提出的问题
205
+ - 只包含与分析目标直接相关的符号发现和洞察
206
+ - 完全跳过与分析目标无关的内容,无需做全面分析
207
+ - 分析深度应与目标的具体需求匹配
208
+ - 使用具体的代码示例支持你的观点
209
+ - 以清晰的Markdown格式呈现,简洁明了
210
+
211
+ 在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的符号概览,而是直接解决分析目标中提出的具体问题。"""
@@ -0,0 +1,248 @@
1
+ from typing import Dict, Any, List
2
+ import os
3
+
4
+ from jarvis.jarvis_agent import Agent
5
+ from jarvis.jarvis_platform.registry import PlatformRegistry
6
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
+
8
+
9
+ class FunctionAnalyzerTool:
10
+ """
11
+ 函数分析工具
12
+ 使用agent深入分析函数内部实现,包括子函数调用、全局变量使用等
13
+ """
14
+
15
+ name = "function_analyzer"
16
+ description = "深入分析函数内部实现,查找子函数调用、全局变量使用等详细信息"
17
+ parameters = {
18
+ "type": "object",
19
+ "properties": {
20
+ "function_name": {
21
+ "type": "string",
22
+ "description": "要分析的函数名称"
23
+ },
24
+ "file_path": {
25
+ "type": "string",
26
+ "description": "函数所在文件路径(如果已知)",
27
+ "default": ""
28
+ },
29
+ "root_dir": {
30
+ "type": "string",
31
+ "description": "代码库根目录路径(可选)",
32
+ "default": "."
33
+ },
34
+ "file_extensions": {
35
+ "type": "array",
36
+ "items": {
37
+ "type": "string"
38
+ },
39
+ "description": "要搜索的文件扩展名列表(如:['.py', '.js'])(可选)",
40
+ "default": []
41
+ },
42
+ "exclude_dirs": {
43
+ "type": "array",
44
+ "items": {
45
+ "type": "string"
46
+ },
47
+ "description": "要排除的目录列表(可选)",
48
+ "default": []
49
+ },
50
+ "analysis_depth": {
51
+ "type": "integer",
52
+ "description": "子函数分析深度(可选),0表示不分析子函数,1表示分析直接子函数,以此类推",
53
+ "default": 1
54
+ },
55
+ "objective": {
56
+ "type": "string",
57
+ "description": "描述本次函数分析的目标和用途,例如'理解函数实现以便重构'或'评估性能瓶颈'",
58
+ "default": ""
59
+ }
60
+ },
61
+ "required": ["function_name"]
62
+ }
63
+
64
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
65
+ """
66
+ 执行函数分析工具
67
+
68
+ Args:
69
+ args: 包含参数的字典
70
+
71
+ Returns:
72
+ 包含执行结果的字典
73
+ """
74
+ # 存储原始目录
75
+ original_dir = os.getcwd()
76
+
77
+ try:
78
+ # 解析参数
79
+ function_name = args.get("function_name", "")
80
+ file_path = args.get("file_path", "")
81
+ root_dir = args.get("root_dir", ".")
82
+ file_extensions = args.get("file_extensions", [])
83
+ exclude_dirs = args.get("exclude_dirs", [])
84
+ analysis_depth = args.get("analysis_depth", 1)
85
+ objective = args.get("objective", "")
86
+
87
+ # 验证参数
88
+ if not function_name:
89
+ return {
90
+ "success": False,
91
+ "stdout": "",
92
+ "stderr": "必须提供函数名称"
93
+ }
94
+
95
+ # 创建agent的system prompt
96
+ system_prompt = self._create_system_prompt(
97
+ function_name, file_path, root_dir,
98
+ file_extensions, exclude_dirs, analysis_depth, objective
99
+ )
100
+
101
+ # 创建agent的summary prompt
102
+ summary_prompt = self._create_summary_prompt(function_name, analysis_depth)
103
+
104
+ # 切换到根目录
105
+ os.chdir(root_dir)
106
+
107
+ # 构建使用的工具
108
+ from jarvis.jarvis_tools.registry import ToolRegistry
109
+ tool_registry = ToolRegistry()
110
+ tool_registry.use_tools(["execute_shell", "read_code"])
111
+
112
+ # 创建并运行agent
113
+ analyzer_agent = Agent(
114
+ system_prompt=system_prompt,
115
+ name=f"FunctionAnalyzer-{function_name}",
116
+ description=f"分析 '{function_name}' 函数的内部实现",
117
+ summary_prompt=summary_prompt,
118
+ platform=PlatformRegistry().get_codegen_platform(),
119
+ output_handler=[tool_registry],
120
+ need_summary=True,
121
+ is_sub_agent=True,
122
+ use_methodology=False,
123
+ record_methodology=False,
124
+ execute_tool_confirm=False,
125
+ auto_complete=True
126
+ )
127
+
128
+ # 运行agent并获取结果
129
+ task_input = f"深入分析 '{function_name}' 函数的内部实现,包括子函数调用、全局变量使用等详细信息"
130
+ result = analyzer_agent.run(task_input)
131
+
132
+ return {
133
+ "success": True,
134
+ "stdout": result,
135
+ "stderr": ""
136
+ }
137
+
138
+ except Exception as e:
139
+ PrettyOutput.print(str(e), OutputType.ERROR)
140
+ return {
141
+ "success": False,
142
+ "stdout": "",
143
+ "stderr": f"函数分析失败: {str(e)}"
144
+ }
145
+ finally:
146
+ # 恢复原始目录
147
+ os.chdir(original_dir)
148
+
149
+ def _create_system_prompt(self, function_name: str, file_path: str, root_dir: str,
150
+ file_extensions: List[str], exclude_dirs: List[str],
151
+ analysis_depth: int, objective: str) -> str:
152
+ """
153
+ 创建Agent的system prompt
154
+
155
+ Args:
156
+ function_name: 函数名称
157
+ file_path: 函数所在文件路径
158
+ root_dir: 代码库根目录
159
+ file_extensions: 文件扩展名列表
160
+ exclude_dirs: 排除目录列表
161
+ analysis_depth: 子函数分析深度
162
+ objective: 分析目标
163
+
164
+ Returns:
165
+ 系统提示文本
166
+ """
167
+ file_ext_str = " ".join([f"*{ext}" for ext in file_extensions]) if file_extensions else ""
168
+ exclude_str = " ".join([f"--glob '!{excl}'" for excl in exclude_dirs]) if exclude_dirs else ""
169
+
170
+ depth_description = "不分析子函数" if analysis_depth == 0 else f"分析 {analysis_depth} 层子函数"
171
+ file_info = f"已知文件路径: {file_path}" if file_path else "需要首先查找函数定义位置"
172
+ objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
173
+
174
+ return f"""# 函数实现分析专家
175
+
176
+ ## 任务描述
177
+ 分析函数 `{function_name}` 的实现,专注于分析目标所需的信息,生成有针对性的函数分析报告。{objective_text}
178
+
179
+ ## 函数信息
180
+ - 函数名称: `{function_name}`
181
+ - {file_info}
182
+ - 分析深度: {depth_description}
183
+ - 代码范围: {file_ext_str if file_ext_str else "所有文件"}
184
+ - 排除目录: {", ".join(exclude_dirs) if exclude_dirs else "无"}
185
+
186
+ ## 分析策略
187
+ 1. 首先理解分析目标,明确需要查找的信息
188
+ 2. {"在指定文件中定位函数定义" if file_path else "搜索代码库查找函数定义位置"}
189
+ 3. 根据分析目标,确定重点分析的方面
190
+ 4. 灵活调整分析深度,关注与目标相关的实现细节
191
+ 5. 根据目标需要自行判断是否需要分析子函数
192
+
193
+ ## 执行指令
194
+ - 查找函数定义:
195
+ ```
196
+ rg -n "def\\s+{function_name}\\b" {file_ext_str} {exclude_str}
197
+ ```
198
+
199
+ - 读取函数实现:
200
+ ```
201
+ read_code {{
202
+ "files": [{{
203
+ "path": "{file_path or '找到的文件路径'}",
204
+ "start_line": 函数起始行,
205
+ "end_line": 函数结束行
206
+ }}]
207
+ }}
208
+ ```
209
+
210
+ - 查找全局变量:
211
+ ```
212
+ rg -n "global\\s+\\w+" --include="{file_path or '找到的文件路径'}"
213
+ ```
214
+
215
+ ## 输出要求
216
+ - 直接回应分析目标的关键问题
217
+ - 提供与目标相关的函数实现信息
218
+ - 分析内容应直接服务于分析目标
219
+ - 避免与目标无关的冗余信息
220
+ - 使用具体代码片段和示例支持分析结论
221
+ - 提供针对分析目标的具体见解和建议"""
222
+
223
+ def _create_summary_prompt(self, function_name: str, analysis_depth: int) -> str:
224
+ """
225
+ 创建Agent的summary prompt
226
+
227
+ Args:
228
+ function_name: 函数名称
229
+ analysis_depth: 子函数分析深度
230
+
231
+ Returns:
232
+ 总结提示文本
233
+ """
234
+ depth_description = "不包含子函数分析" if analysis_depth == 0 else f"包含 {analysis_depth} 层子函数分析"
235
+
236
+ return f"""# 函数分析报告: `{function_name}`
237
+
238
+ ## 报告要求
239
+ 生成一份完全以分析目标为导向的函数分析报告,{depth_description}。不要遵循固定的报告模板,而是完全根据分析目标来组织内容:
240
+
241
+ - 专注回答分析目标提出的问题
242
+ - 只包含与分析目标直接相关的实现发现和洞察
243
+ - 完全跳过与分析目标无关的内容,无需做全面分析
244
+ - 分析深度应与目标的具体需求匹配
245
+ - 使用具体的代码片段支持你的观点
246
+ - 以清晰的Markdown格式呈现,简洁明了
247
+
248
+ 在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的函数概览,而是直接解决分析目标中提出的具体问题。"""