jarvis-ai-assistant 0.1.132__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +330 -347
- jarvis/jarvis_agent/builtin_input_handler.py +16 -6
- jarvis/jarvis_agent/file_input_handler.py +9 -9
- jarvis/jarvis_agent/jarvis.py +143 -0
- jarvis/jarvis_agent/main.py +12 -13
- jarvis/jarvis_agent/output_handler.py +3 -3
- jarvis/jarvis_agent/patch.py +92 -64
- jarvis/jarvis_agent/shell_input_handler.py +5 -3
- jarvis/jarvis_code_agent/code_agent.py +263 -177
- jarvis/jarvis_code_agent/file_select.py +24 -24
- jarvis/jarvis_dev/main.py +45 -59
- jarvis/jarvis_git_details/__init__.py +0 -0
- jarvis/jarvis_git_details/main.py +179 -0
- jarvis/jarvis_git_squash/main.py +7 -7
- jarvis/jarvis_lsp/base.py +11 -53
- jarvis/jarvis_lsp/cpp.py +13 -28
- jarvis/jarvis_lsp/go.py +13 -28
- jarvis/jarvis_lsp/python.py +8 -27
- jarvis/jarvis_lsp/registry.py +21 -83
- jarvis/jarvis_lsp/rust.py +15 -30
- jarvis/jarvis_methodology/main.py +101 -0
- jarvis/jarvis_multi_agent/__init__.py +10 -51
- jarvis/jarvis_multi_agent/main.py +43 -0
- jarvis/jarvis_platform/__init__.py +1 -1
- jarvis/jarvis_platform/ai8.py +67 -89
- jarvis/jarvis_platform/base.py +14 -13
- jarvis/jarvis_platform/kimi.py +25 -28
- jarvis/jarvis_platform/ollama.py +24 -26
- jarvis/jarvis_platform/openai.py +15 -19
- jarvis/jarvis_platform/oyi.py +48 -50
- jarvis/jarvis_platform/registry.py +29 -44
- jarvis/jarvis_platform/yuanbao.py +39 -43
- jarvis/jarvis_platform_manager/main.py +81 -81
- jarvis/jarvis_platform_manager/openai_test.py +21 -21
- jarvis/jarvis_rag/file_processors.py +18 -18
- jarvis/jarvis_rag/main.py +262 -278
- jarvis/jarvis_smart_shell/main.py +12 -12
- jarvis/jarvis_tools/ask_codebase.py +85 -78
- jarvis/jarvis_tools/ask_user.py +8 -8
- jarvis/jarvis_tools/base.py +4 -4
- jarvis/jarvis_tools/chdir.py +9 -9
- jarvis/jarvis_tools/code_review.py +40 -21
- jarvis/jarvis_tools/create_code_agent.py +15 -15
- jarvis/jarvis_tools/create_sub_agent.py +0 -1
- jarvis/jarvis_tools/execute_python_script.py +3 -3
- jarvis/jarvis_tools/execute_shell.py +11 -11
- jarvis/jarvis_tools/execute_shell_script.py +3 -3
- jarvis/jarvis_tools/file_analyzer.py +116 -105
- jarvis/jarvis_tools/file_operation.py +22 -20
- jarvis/jarvis_tools/find_caller.py +105 -40
- jarvis/jarvis_tools/find_methodolopy.py +65 -0
- jarvis/jarvis_tools/find_symbol.py +123 -39
- jarvis/jarvis_tools/function_analyzer.py +140 -57
- jarvis/jarvis_tools/git_commiter.py +10 -10
- jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -19
- jarvis/jarvis_tools/methodology.py +22 -67
- jarvis/jarvis_tools/project_analyzer.py +137 -53
- jarvis/jarvis_tools/rag.py +15 -20
- jarvis/jarvis_tools/read_code.py +25 -23
- jarvis/jarvis_tools/read_webpage.py +31 -31
- jarvis/jarvis_tools/registry.py +72 -52
- jarvis/jarvis_tools/search_web.py +23 -353
- jarvis/jarvis_tools/tool_generator.py +19 -19
- jarvis/jarvis_utils/config.py +36 -96
- jarvis/jarvis_utils/embedding.py +83 -83
- jarvis/jarvis_utils/git_utils.py +20 -20
- jarvis/jarvis_utils/globals.py +18 -6
- jarvis/jarvis_utils/input.py +10 -9
- jarvis/jarvis_utils/methodology.py +141 -140
- jarvis/jarvis_utils/output.py +13 -13
- jarvis/jarvis_utils/utils.py +23 -71
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/METADATA +6 -15
- jarvis_ai_assistant-0.1.138.dist-info/RECORD +85 -0
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/entry_points.txt +4 -3
- jarvis/jarvis_tools/lsp_find_definition.py +0 -150
- jarvis/jarvis_tools/lsp_find_references.py +0 -127
- jarvis/jarvis_tools/select_code_files.py +0 -62
- jarvis_ai_assistant-0.1.132.dist-info/RECORD +0 -82
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/top_level.txt +0 -0
|
@@ -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,49 +79,45 @@ 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,
|
|
102
102
|
name=f"CallerFinder-{function_name}",
|
|
103
103
|
description=f"查找 '{function_name}' 函数的所有调用位置",
|
|
104
104
|
summary_prompt=summary_prompt,
|
|
105
|
-
platform=PlatformRegistry().
|
|
105
|
+
platform=PlatformRegistry().get_normal_platform(),
|
|
106
106
|
output_handler=[tool_registry],
|
|
107
|
-
need_summary=True,
|
|
108
|
-
is_sub_agent=True,
|
|
109
|
-
use_methodology=False,
|
|
110
|
-
record_methodology=False,
|
|
111
107
|
execute_tool_confirm=False,
|
|
112
108
|
auto_complete=True
|
|
113
109
|
)
|
|
114
|
-
|
|
110
|
+
|
|
115
111
|
# 运行agent并获取结果
|
|
116
112
|
task_input = f"查找所有调用 '{function_name}' 函数的代码位置"
|
|
117
113
|
result = caller_agent.run(task_input)
|
|
118
|
-
|
|
114
|
+
|
|
119
115
|
return {
|
|
120
116
|
"success": True,
|
|
121
117
|
"stdout": result,
|
|
122
118
|
"stderr": ""
|
|
123
119
|
}
|
|
124
|
-
|
|
120
|
+
|
|
125
121
|
except Exception as e:
|
|
126
122
|
PrettyOutput.print(str(e), OutputType.ERROR)
|
|
127
123
|
return {
|
|
@@ -132,53 +128,121 @@ class FindCallerTool:
|
|
|
132
128
|
finally:
|
|
133
129
|
# 恢复原始目录
|
|
134
130
|
os.chdir(original_dir)
|
|
135
|
-
|
|
136
|
-
def _create_system_prompt(self, function_name: str, root_dir: str,
|
|
131
|
+
|
|
132
|
+
def _create_system_prompt(self, function_name: str, root_dir: str,
|
|
137
133
|
file_extensions: List[str], exclude_dirs: List[str],
|
|
138
134
|
objective: str) -> str:
|
|
139
135
|
"""
|
|
140
136
|
创建Agent的system prompt
|
|
141
|
-
|
|
137
|
+
|
|
142
138
|
Args:
|
|
143
139
|
function_name: 函数名称
|
|
144
140
|
root_dir: 代码库根目录
|
|
145
141
|
file_extensions: 文件扩展名列表
|
|
146
142
|
exclude_dirs: 排除目录列表
|
|
147
143
|
objective: 分析目标
|
|
148
|
-
|
|
144
|
+
|
|
149
145
|
Returns:
|
|
150
146
|
系统提示文本
|
|
151
147
|
"""
|
|
152
148
|
file_ext_str = " ".join([f"*{ext}" for ext in file_extensions]) if file_extensions else ""
|
|
153
149
|
exclude_str = " ".join([f"--glob '!{excl}'" for excl in exclude_dirs]) if exclude_dirs else ""
|
|
154
150
|
objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
|
|
155
|
-
|
|
151
|
+
|
|
156
152
|
search_pattern = f"\\b{function_name}\\s*\\("
|
|
157
|
-
|
|
153
|
+
|
|
158
154
|
return f"""# 函数调用分析专家
|
|
159
155
|
|
|
160
156
|
## 任务描述
|
|
161
157
|
查找所有调用 `{function_name}` 函数的代码位置,专注于分析目标所需的信息,生成有针对性的调用分析报告。{objective_text}
|
|
162
158
|
|
|
159
|
+
## 工具使用优先级
|
|
160
|
+
1. **优先使用 execute_shell 执行 rg 命令**:
|
|
161
|
+
- `rg "\\b{function_name}\\s*\\(" --type py` 查找Python文件中的调用
|
|
162
|
+
- `rg "\\b{function_name}\\s*\\(" --type js` 查找JavaScript文件中的调用
|
|
163
|
+
- `rg -w "{function_name}" -A 2 -B 2` 查看调用上下文
|
|
164
|
+
|
|
165
|
+
2. **辅以 read_code**:
|
|
166
|
+
- 找到调用位置后使用read_code阅读上下文
|
|
167
|
+
- 读取关键调用者的完整实现
|
|
168
|
+
|
|
169
|
+
3. **避免使用专用分析工具**:
|
|
170
|
+
- 只有当rg命令和read_code工具无法满足需求时才考虑
|
|
171
|
+
|
|
163
172
|
## 工作环境
|
|
164
173
|
- 工作目录: `{root_dir}`
|
|
165
174
|
- 文件类型: {file_ext_str if file_ext_str else "所有文件"}
|
|
166
175
|
- 排除目录: {", ".join(exclude_dirs) if exclude_dirs else "无"}
|
|
167
176
|
|
|
168
177
|
## 分析策略
|
|
169
|
-
1.
|
|
170
|
-
2.
|
|
171
|
-
3.
|
|
172
|
-
4.
|
|
173
|
-
5.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
178
|
+
1. 首先确定项目的主要编程语言和技术栈,以便更精确地查找函数调用
|
|
179
|
+
2. 理解分析目标,明确需要查找的信息类型
|
|
180
|
+
3. 使用适当的rg搜索模式查找函数调用
|
|
181
|
+
4. 验证搜索结果,确认是对目标函数的真正调用
|
|
182
|
+
5. 分析调用上下文,了解调用的目的和方式
|
|
183
|
+
6. 根据分析目标自行确定需要的分析深度和广度
|
|
184
|
+
|
|
185
|
+
## 调用者查找工具指南
|
|
186
|
+
|
|
187
|
+
### execute_shell 搜索命令
|
|
188
|
+
- **基本搜索**:
|
|
189
|
+
- `rg "\\b{function_name}\\s*\\(" --type=文件类型`
|
|
190
|
+
- 示例: `rg "\\b{function_name}\\s*\\(" --type py` 搜索Python文件中的调用
|
|
191
|
+
|
|
192
|
+
- **查看上下文**:
|
|
193
|
+
- `rg "\\b{function_name}\\s*\\(" -A 5 -B 5` 显示调用前后5行
|
|
194
|
+
- `rg "\\b{function_name}\\s*\\(" --context=10` 显示调用前后10行
|
|
195
|
+
|
|
196
|
+
- **排除目录**:
|
|
197
|
+
- `rg "\\b{function_name}\\s*\\(" --type py -g '!tests/'` 排除测试目录
|
|
198
|
+
- `rg "\\b{function_name}\\s*\\(" -g '!node_modules/'` 排除node_modules
|
|
199
|
+
|
|
200
|
+
- **统计调用**:
|
|
201
|
+
- `rg -c "\\b{function_name}\\s*\\(" --type py` 统计每个Python文件中的调用次数
|
|
202
|
+
- `rg "\\b{function_name}\\s*\\(" --count-matches --stats` 显示调用统计信息
|
|
203
|
+
|
|
204
|
+
### read_code
|
|
205
|
+
- **用途**:读取找到的调用点上下文
|
|
206
|
+
- **典型用法**:
|
|
207
|
+
- 读取调用函数的整个方法或类
|
|
208
|
+
- 读取调用点的上下文行(前后5-10行)
|
|
209
|
+
- **使用策略**:
|
|
210
|
+
- 首先读取足够的上下文以理解调用目的
|
|
211
|
+
- 对于复杂调用,可能需要读取整个调用函数
|
|
212
|
+
- 关注调用前的参数准备和调用后的结果处理
|
|
213
|
+
|
|
214
|
+
### 调用者分析模式
|
|
215
|
+
|
|
216
|
+
1. **影响范围评估模式**:
|
|
217
|
+
- 查找所有调用点: `rg -l "\\b{function_name}\\s*\\("`
|
|
218
|
+
- 按模块/组件分类调用位置
|
|
219
|
+
- 评估修改函数可能影响的范围和严重性
|
|
220
|
+
|
|
221
|
+
2. **使用模式分析**:
|
|
222
|
+
- 分析各调用点的参数传递方式
|
|
223
|
+
- 识别典型的调用模式和变体
|
|
224
|
+
- 总结函数的不同使用场景
|
|
225
|
+
|
|
226
|
+
3. **依赖关系追踪**:
|
|
227
|
+
- 识别直接调用者
|
|
228
|
+
- 分析这些调用者自身被谁调用
|
|
229
|
+
- 构建完整的调用链或调用树
|
|
230
|
+
|
|
231
|
+
4. **调用频率分析**:
|
|
232
|
+
- 统计不同模块中的调用频率: `rg -c "\\b{function_name}\\s*\\(" --sort path`
|
|
233
|
+
- 识别高频调用点和关键路径
|
|
234
|
+
- 评估函数在系统中的重要性
|
|
235
|
+
|
|
236
|
+
5. **异常使用检测**:
|
|
237
|
+
- 检查是否存在异常的调用模式
|
|
238
|
+
- 识别可能存在问题的调用点
|
|
239
|
+
- 提出优化或修正建议
|
|
240
|
+
|
|
241
|
+
## 搜索技巧
|
|
242
|
+
- 根据不同编程语言调整函数调用模式的搜索方式
|
|
243
|
+
- 考虑各种编程范式下的不同调用方式(面向对象、函数式等)
|
|
244
|
+
- 考虑函数可能通过变量或回调方式间接调用
|
|
245
|
+
- 检查可能存在的同名函数,确保找到的是目标函数的调用
|
|
182
246
|
|
|
183
247
|
## 输出要求
|
|
184
248
|
- 直接回应分析目标的关键问题
|
|
@@ -191,10 +255,10 @@ class FindCallerTool:
|
|
|
191
255
|
def _create_summary_prompt(self, function_name: str) -> str:
|
|
192
256
|
"""
|
|
193
257
|
创建Agent的summary prompt
|
|
194
|
-
|
|
258
|
+
|
|
195
259
|
Args:
|
|
196
260
|
function_name: 函数名称
|
|
197
|
-
|
|
261
|
+
|
|
198
262
|
Returns:
|
|
199
263
|
总结提示文本
|
|
200
264
|
"""
|
|
@@ -203,6 +267,7 @@ class FindCallerTool:
|
|
|
203
267
|
## 报告要求
|
|
204
268
|
生成一份完全以分析目标为导向的函数调用分析报告。不要遵循固定的报告模板,而是完全根据分析目标来组织内容:
|
|
205
269
|
|
|
270
|
+
- 首先简要说明项目的主要编程语言和技术栈
|
|
206
271
|
- 专注回答分析目标提出的问题
|
|
207
272
|
- 只包含与分析目标直接相关的调用发现和洞察
|
|
208
273
|
- 完全跳过与分析目标无关的内容,无需做全面分析
|
|
@@ -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
|
+
}
|
|
@@ -11,7 +11,7 @@ class SymbolTool:
|
|
|
11
11
|
符号查找工具
|
|
12
12
|
使用agent查找代码库中的符号引用、定义和声明位置
|
|
13
13
|
"""
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
name = "find_symbol"
|
|
16
16
|
description = "查找代码符号的引用、定义和声明位置"
|
|
17
17
|
parameters = {
|
|
@@ -50,20 +50,20 @@ class SymbolTool:
|
|
|
50
50
|
},
|
|
51
51
|
"required": ["symbol"]
|
|
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
|
symbol = args.get("symbol", "")
|
|
@@ -71,7 +71,7 @@ class SymbolTool:
|
|
|
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 symbol:
|
|
77
77
|
return {
|
|
@@ -79,49 +79,45 @@ class SymbolTool:
|
|
|
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
|
symbol, root_dir, file_extensions, exclude_dirs, objective
|
|
86
86
|
)
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
# 创建agent的summary prompt
|
|
89
89
|
summary_prompt = self._create_summary_prompt(symbol)
|
|
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
|
symbol_agent = Agent(
|
|
101
101
|
system_prompt=system_prompt,
|
|
102
102
|
name=f"SymbolFinder-{symbol}",
|
|
103
103
|
description=f"查找符号 '{symbol}' 的引用和定义位置",
|
|
104
104
|
summary_prompt=summary_prompt,
|
|
105
|
-
platform=PlatformRegistry().
|
|
105
|
+
platform=PlatformRegistry().get_normal_platform(),
|
|
106
106
|
output_handler=[tool_registry],
|
|
107
|
-
need_summary=True,
|
|
108
|
-
is_sub_agent=True,
|
|
109
|
-
use_methodology=False,
|
|
110
|
-
record_methodology=False,
|
|
111
107
|
execute_tool_confirm=False,
|
|
112
108
|
auto_complete=True
|
|
113
109
|
)
|
|
114
|
-
|
|
110
|
+
|
|
115
111
|
# 运行agent并获取结果
|
|
116
112
|
task_input = f"查找符号 '{symbol}' 在代码库中的引用、定义和声明位置"
|
|
117
113
|
result = symbol_agent.run(task_input)
|
|
118
|
-
|
|
114
|
+
|
|
119
115
|
return {
|
|
120
116
|
"success": True,
|
|
121
117
|
"stdout": result,
|
|
122
118
|
"stderr": ""
|
|
123
119
|
}
|
|
124
|
-
|
|
120
|
+
|
|
125
121
|
except Exception as e:
|
|
126
122
|
PrettyOutput.print(str(e), OutputType.ERROR)
|
|
127
123
|
return {
|
|
@@ -132,51 +128,138 @@ class SymbolTool:
|
|
|
132
128
|
finally:
|
|
133
129
|
# 恢复原始目录
|
|
134
130
|
os.chdir(original_dir)
|
|
135
|
-
|
|
136
|
-
def _create_system_prompt(self, symbol: str, root_dir: str,
|
|
131
|
+
|
|
132
|
+
def _create_system_prompt(self, symbol: str, root_dir: str,
|
|
137
133
|
file_extensions: List[str], exclude_dirs: List[str],
|
|
138
134
|
objective: str) -> str:
|
|
139
135
|
"""
|
|
140
136
|
创建Agent的system prompt
|
|
141
|
-
|
|
137
|
+
|
|
142
138
|
Args:
|
|
143
139
|
symbol: 符号名称
|
|
144
140
|
root_dir: 代码库根目录
|
|
145
141
|
file_extensions: 文件扩展名列表
|
|
146
142
|
exclude_dirs: 排除目录列表
|
|
147
143
|
objective: 分析目标
|
|
148
|
-
|
|
144
|
+
|
|
149
145
|
Returns:
|
|
150
146
|
系统提示文本
|
|
151
147
|
"""
|
|
152
148
|
file_ext_str = " ".join([f"*{ext}" for ext in file_extensions]) if file_extensions else ""
|
|
153
149
|
exclude_str = " ".join([f"--glob '!{excl}'" for excl in exclude_dirs]) if exclude_dirs else ""
|
|
154
150
|
objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
|
|
155
|
-
|
|
151
|
+
|
|
156
152
|
return f"""# 代码符号分析专家
|
|
157
153
|
|
|
158
154
|
## 任务描述
|
|
159
155
|
查找符号 `{symbol}` 在代码库中的定义、声明和引用位置,专注于分析目标所需的信息,生成有针对性的符号分析报告。{objective_text}
|
|
160
156
|
|
|
157
|
+
## 工具使用优先级
|
|
158
|
+
1. **优先使用 execute_shell 执行 rg 命令**:
|
|
159
|
+
- `rg -w "{symbol}" --type py` 查找Python文件中的符号
|
|
160
|
+
- `rg "class\\s+{symbol}|def\\s+{symbol}" --type py` 查找定义
|
|
161
|
+
- `rg -w "{symbol}" -A 2 -B 2` 查看符号上下文
|
|
162
|
+
|
|
163
|
+
2. **辅以 read_code**:
|
|
164
|
+
- 找到符号位置后使用read_code阅读上下文
|
|
165
|
+
- 读取符号定义和关键引用的完整实现
|
|
166
|
+
|
|
167
|
+
3. **避免使用专用分析工具**:
|
|
168
|
+
- 只有当rg命令和read_code工具无法满足需求时才考虑
|
|
169
|
+
|
|
161
170
|
## 工作环境
|
|
162
171
|
- 工作目录: `{root_dir}`
|
|
163
172
|
- 文件类型: {file_ext_str if file_ext_str else "所有文件"}
|
|
164
173
|
- 排除目录: {", ".join(exclude_dirs) if exclude_dirs else "无"}
|
|
165
174
|
|
|
166
175
|
## 分析策略
|
|
167
|
-
1.
|
|
168
|
-
2.
|
|
169
|
-
3.
|
|
170
|
-
4.
|
|
171
|
-
5.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
-
|
|
176
|
+
1. 首先确定项目的主要编程语言和技术栈,以便更精确地查找符号
|
|
177
|
+
2. 理解分析目标,明确需要查找的信息类型
|
|
178
|
+
3. 使用适当的rg搜索模式查找符号定义和引用
|
|
179
|
+
4. 验证搜索结果,确认是目标符号的真正使用
|
|
180
|
+
5. 分析符号上下文,了解其用途和使用方式
|
|
181
|
+
6. 根据分析目标自行确定需要的分析深度和广度
|
|
182
|
+
|
|
183
|
+
## 符号查找工具指南
|
|
184
|
+
|
|
185
|
+
### execute_shell 搜索命令
|
|
186
|
+
- **基本搜索**:
|
|
187
|
+
- `rg -w "{symbol}" --type=文件类型`
|
|
188
|
+
- 示例: `rg -w "{symbol}" --type py` 搜索Python文件中的符号
|
|
189
|
+
|
|
190
|
+
- **查找定义**:
|
|
191
|
+
- `rg "class\\s+{symbol}\\b|def\\s+{symbol}\\b|function\\s+{symbol}\\b" --type py` 查找Python定义
|
|
192
|
+
- `rg "class\\s+{symbol}\\b|function\\s+{symbol}\\b" --type js` 查找JavaScript定义
|
|
193
|
+
- `rg "const\\s+{symbol}\\b|let\\s+{symbol}\\b|var\\s+{symbol}\\b" --type js` 查找JavaScript变量声明
|
|
194
|
+
|
|
195
|
+
- **查看上下文**:
|
|
196
|
+
- `rg -w "{symbol}" -A 5 -B 5` 显示符号前后5行
|
|
197
|
+
- `rg -w "{symbol}" --context=10` 显示符号前后10行
|
|
198
|
+
|
|
199
|
+
- **排除目录**:
|
|
200
|
+
- `rg -w "{symbol}" --type py -g '!tests/'` 排除测试目录
|
|
201
|
+
- `rg -w "{symbol}" -g '!node_modules/'` 排除node_modules
|
|
202
|
+
|
|
203
|
+
- **统计引用**:
|
|
204
|
+
- `rg -c -w "{symbol}" --type py` 统计每个Python文件中的引用次数
|
|
205
|
+
- `rg -w "{symbol}" --count-matches --stats` 显示引用统计信息
|
|
206
|
+
|
|
207
|
+
### read_code
|
|
208
|
+
- **用途**:读取符号定义和使用的上下文
|
|
209
|
+
- **典型用法**:
|
|
210
|
+
- 读取符号定义所在的文件区域
|
|
211
|
+
- 读取关键使用位置的上下文
|
|
212
|
+
- **使用策略**:
|
|
213
|
+
- 首先读取符号的定义以理解其属性和行为
|
|
214
|
+
- 然后读取典型使用场景的代码
|
|
215
|
+
- 重点关注频繁使用的模式和关键功能点
|
|
216
|
+
|
|
217
|
+
### 符号分析模式
|
|
218
|
+
|
|
219
|
+
1. **定义分析模式**:
|
|
220
|
+
- 首先找到符号的所有定义位置
|
|
221
|
+
- 分析定义的类型(类、函数、变量、常量等)
|
|
222
|
+
- 理解符号的属性、参数、返回值等特性
|
|
223
|
+
- 查看相关注释和文档字符串
|
|
224
|
+
|
|
225
|
+
2. **使用模式分析**:
|
|
226
|
+
- 分类统计不同类型的使用方式
|
|
227
|
+
- 识别典型的使用模式和上下文
|
|
228
|
+
- 总结符号的主要用途和功能
|
|
229
|
+
|
|
230
|
+
3. **影响范围评估**:
|
|
231
|
+
- 统计符号在不同模块中的使用频率
|
|
232
|
+
- 分析符号修改可能影响的代码范围
|
|
233
|
+
- 识别关键依赖点和潜在风险区域
|
|
234
|
+
|
|
235
|
+
4. **符号关系网络分析**:
|
|
236
|
+
- 分析与目标符号相关的其他符号
|
|
237
|
+
- 识别依赖该符号的组件
|
|
238
|
+
- 了解该符号依赖的其他组件
|
|
239
|
+
|
|
240
|
+
## 编程范式适应
|
|
241
|
+
|
|
242
|
+
无论项目使用什么编程语言或范式,符号分析都应考虑以下方面:
|
|
243
|
+
|
|
244
|
+
### 对象导向程序
|
|
245
|
+
- 类定义、继承关系和实例化
|
|
246
|
+
- 方法重载和覆盖
|
|
247
|
+
- 成员变量和属性访问
|
|
248
|
+
|
|
249
|
+
### 函数式编程
|
|
250
|
+
- 高阶函数和函数传递
|
|
251
|
+
- 不可变数据结构
|
|
252
|
+
- 闭包和作用域
|
|
253
|
+
|
|
254
|
+
### 过程式编程
|
|
255
|
+
- 全局和局部变量
|
|
256
|
+
- 函数调用关系
|
|
257
|
+
- 数据流动
|
|
258
|
+
|
|
259
|
+
### 声明式编程
|
|
260
|
+
- 规则和约束定义
|
|
261
|
+
- 模式匹配
|
|
262
|
+
- 数据转换
|
|
180
263
|
|
|
181
264
|
## 输出要求
|
|
182
265
|
- 直接回应分析目标的关键问题
|
|
@@ -189,10 +272,10 @@ class SymbolTool:
|
|
|
189
272
|
def _create_summary_prompt(self, symbol: str) -> str:
|
|
190
273
|
"""
|
|
191
274
|
创建Agent的summary prompt
|
|
192
|
-
|
|
275
|
+
|
|
193
276
|
Args:
|
|
194
277
|
symbol: 符号名称
|
|
195
|
-
|
|
278
|
+
|
|
196
279
|
Returns:
|
|
197
280
|
总结提示文本
|
|
198
281
|
"""
|
|
@@ -201,6 +284,7 @@ class SymbolTool:
|
|
|
201
284
|
## 报告要求
|
|
202
285
|
生成一份完全以分析目标为导向的符号分析报告。不要遵循固定的报告模板,而是完全根据分析目标来组织内容:
|
|
203
286
|
|
|
287
|
+
- 首先简要说明项目的主要编程语言和技术栈
|
|
204
288
|
- 专注回答分析目标提出的问题
|
|
205
289
|
- 只包含与分析目标直接相关的符号发现和洞察
|
|
206
290
|
- 完全跳过与分析目标无关的内容,无需做全面分析
|