jarvis-ai-assistant 0.1.132__py3-none-any.whl → 0.1.134__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 +140 -279
- jarvis/jarvis_agent/jarvis.py +143 -0
- jarvis/jarvis_agent/main.py +0 -2
- jarvis/jarvis_agent/patch.py +16 -12
- jarvis/jarvis_code_agent/code_agent.py +155 -104
- jarvis/jarvis_dev/main.py +0 -8
- jarvis/jarvis_lsp/base.py +0 -42
- jarvis/jarvis_lsp/cpp.py +0 -15
- jarvis/jarvis_lsp/go.py +0 -15
- jarvis/jarvis_lsp/python.py +0 -19
- jarvis/jarvis_lsp/registry.py +0 -62
- jarvis/jarvis_lsp/rust.py +0 -15
- jarvis/jarvis_multi_agent/__init__.py +0 -41
- jarvis/jarvis_multi_agent/main.py +43 -0
- jarvis/jarvis_platform/registry.py +2 -16
- jarvis/jarvis_platform/yuanbao.py +1 -1
- jarvis/jarvis_rag/main.py +1 -1
- jarvis/jarvis_tools/ask_codebase.py +61 -54
- jarvis/jarvis_tools/code_review.py +21 -2
- jarvis/jarvis_tools/create_sub_agent.py +0 -1
- jarvis/jarvis_tools/file_analyzer.py +84 -73
- jarvis/jarvis_tools/find_caller.py +83 -18
- jarvis/jarvis_tools/find_symbol.py +102 -18
- jarvis/jarvis_tools/function_analyzer.py +115 -32
- jarvis/jarvis_tools/git_commiter.py +1 -1
- jarvis/jarvis_tools/methodology.py +0 -6
- jarvis/jarvis_tools/project_analyzer.py +116 -28
- jarvis/jarvis_tools/rag.py +0 -5
- jarvis/jarvis_tools/read_code.py +1 -1
- jarvis/jarvis_tools/search_web.py +23 -353
- jarvis/jarvis_tools/tool_generator.py +2 -2
- jarvis/jarvis_utils/config.py +13 -73
- jarvis/jarvis_utils/methodology.py +8 -11
- jarvis/jarvis_utils/output.py +2 -2
- jarvis/jarvis_utils/utils.py +1 -1
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/METADATA +6 -15
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/RECORD +42 -42
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/entry_points.txt +2 -3
- jarvis/jarvis_tools/lsp_find_definition.py +0 -150
- jarvis/jarvis_tools/lsp_find_references.py +0 -127
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/top_level.txt +0 -0
|
@@ -138,45 +138,4 @@ content: {msg['content']}
|
|
|
138
138
|
last_agent = self.agents[msg['to']].name
|
|
139
139
|
msg = self.agents[msg['to']].run(prompt)
|
|
140
140
|
return ""
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def main():
|
|
144
|
-
"""从YAML配置文件初始化并运行多智能体系统
|
|
145
|
-
|
|
146
|
-
Returns:
|
|
147
|
-
最终处理结果
|
|
148
|
-
"""
|
|
149
|
-
init_env()
|
|
150
|
-
import argparse
|
|
151
|
-
parser = argparse.ArgumentParser(description="多智能体系统启动器")
|
|
152
|
-
parser.add_argument("--config", "-c", required=True, help="YAML配置文件路径")
|
|
153
|
-
parser.add_argument("--input", "-i", help="用户输入(可选)")
|
|
154
|
-
args = parser.parse_args()
|
|
155
|
-
|
|
156
|
-
try:
|
|
157
|
-
with open(args.config, 'r', errors="ignore") as f:
|
|
158
|
-
config_data = yaml.safe_load(f)
|
|
159
|
-
|
|
160
|
-
# 获取agents配置
|
|
161
|
-
agents_config = config_data.get('agents', [])
|
|
162
|
-
|
|
163
|
-
main_agent_name = config_data.get('main_agent', '')
|
|
164
|
-
if not main_agent_name:
|
|
165
|
-
raise ValueError("必须指定main_agent作为主智能体")
|
|
166
|
-
|
|
167
|
-
# 创建并运行多智能体系统
|
|
168
|
-
multi_agent = MultiAgent(agents_config, main_agent_name)
|
|
169
|
-
user_input = args.input if args.input is not None else get_multiline_input("请输入内容(输入空行结束):")
|
|
170
|
-
if user_input == "":
|
|
171
|
-
return
|
|
172
|
-
return multi_agent.run(user_input)
|
|
173
|
-
|
|
174
|
-
except yaml.YAMLError as e:
|
|
175
|
-
raise ValueError(f"YAML配置文件解析错误: {str(e)}")
|
|
176
|
-
except Exception as e:
|
|
177
|
-
raise RuntimeError(f"多智能体系统初始化失败: {str(e)}")
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if __name__ == "__main__":
|
|
181
|
-
result = main()
|
|
182
141
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import yaml
|
|
2
|
+
from jarvis.jarvis_multi_agent import MultiAgent
|
|
3
|
+
from jarvis.jarvis_utils.utils import init_env
|
|
4
|
+
from jarvis.jarvis_utils.input import get_multiline_input
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
"""从YAML配置文件初始化并运行多智能体系统
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
最终处理结果
|
|
11
|
+
"""
|
|
12
|
+
init_env()
|
|
13
|
+
import argparse
|
|
14
|
+
parser = argparse.ArgumentParser(description="多智能体系统启动器")
|
|
15
|
+
parser.add_argument("--config", "-c", required=True, help="YAML配置文件路径")
|
|
16
|
+
parser.add_argument("--input", "-i", help="用户输入(可选)")
|
|
17
|
+
args = parser.parse_args()
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
with open(args.config, 'r', errors="ignore") as f:
|
|
21
|
+
config_data = yaml.safe_load(f)
|
|
22
|
+
|
|
23
|
+
# 获取agents配置
|
|
24
|
+
agents_config = config_data.get('agents', [])
|
|
25
|
+
|
|
26
|
+
main_agent_name = config_data.get('main_agent', '')
|
|
27
|
+
if not main_agent_name:
|
|
28
|
+
raise ValueError("必须指定main_agent作为主智能体")
|
|
29
|
+
|
|
30
|
+
# 创建并运行多智能体系统
|
|
31
|
+
multi_agent = MultiAgent(agents_config, main_agent_name)
|
|
32
|
+
user_input = args.input if args.input is not None else get_multiline_input("请输入内容(输入空行结束):")
|
|
33
|
+
if user_input == "":
|
|
34
|
+
return
|
|
35
|
+
return multi_agent.run(user_input)
|
|
36
|
+
|
|
37
|
+
except yaml.YAMLError as e:
|
|
38
|
+
raise ValueError(f"YAML配置文件解析错误: {str(e)}")
|
|
39
|
+
except Exception as e:
|
|
40
|
+
raise RuntimeError(f"多智能体系统初始化失败: {str(e)}")
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
result = main()
|
|
@@ -4,7 +4,7 @@ import os
|
|
|
4
4
|
import sys
|
|
5
5
|
from typing import Dict, Type, Optional, List
|
|
6
6
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
7
|
-
from jarvis.jarvis_utils.config import
|
|
7
|
+
from jarvis.jarvis_utils.config import get_normal_model_name, get_normal_platform_name, get_thinking_model_name, get_thinking_platform_name
|
|
8
8
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
9
9
|
|
|
10
10
|
REQUIRED_METHODS = [
|
|
@@ -21,7 +21,7 @@ REQUIRED_METHODS = [
|
|
|
21
21
|
class PlatformRegistry:
|
|
22
22
|
"""Platform registry"""
|
|
23
23
|
|
|
24
|
-
global_platform_name = "
|
|
24
|
+
global_platform_name = "yuanbao"
|
|
25
25
|
global_platform_registry = None
|
|
26
26
|
|
|
27
27
|
@staticmethod
|
|
@@ -161,20 +161,6 @@ class PlatformRegistry:
|
|
|
161
161
|
platform.set_model_name(model_name) # type: ignore
|
|
162
162
|
return platform # type: ignore
|
|
163
163
|
|
|
164
|
-
def get_codegen_platform(self) -> BasePlatform:
|
|
165
|
-
platform_name = get_codegen_platform_name()
|
|
166
|
-
model_name = get_codegen_model_name()
|
|
167
|
-
platform = self.create_platform(platform_name)
|
|
168
|
-
platform.set_model_name(model_name) # type: ignore
|
|
169
|
-
return platform # type: ignore
|
|
170
|
-
|
|
171
|
-
def get_cheap_platform(self) -> BasePlatform:
|
|
172
|
-
platform_name = get_cheap_platform_name()
|
|
173
|
-
model_name = get_cheap_model_name()
|
|
174
|
-
platform = self.create_platform(platform_name)
|
|
175
|
-
platform.set_model_name(model_name) # type: ignore
|
|
176
|
-
return platform # type: ignore
|
|
177
|
-
|
|
178
164
|
def get_thinking_platform(self) -> BasePlatform:
|
|
179
165
|
platform_name = get_thinking_platform_name()
|
|
180
166
|
model_name = get_thinking_model_name()
|
|
@@ -6,7 +6,7 @@ from jarvis.jarvis_platform.base import BasePlatform
|
|
|
6
6
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
7
7
|
from jarvis.jarvis_utils.utils import while_success
|
|
8
8
|
|
|
9
|
-
class
|
|
9
|
+
class YuanbaoPlatform(BasePlatform):
|
|
10
10
|
"""Hunyuan model implementation"""
|
|
11
11
|
|
|
12
12
|
platform_name = "yuanbao"
|
jarvis/jarvis_rag/main.py
CHANGED
|
@@ -18,7 +18,7 @@ from jarvis.jarvis_utils.embedding import get_context_token_count, get_embedding
|
|
|
18
18
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
19
19
|
from jarvis.jarvis_utils.utils import ct, get_file_md5, init_env, init_gpu_config, ot
|
|
20
20
|
|
|
21
|
-
from .file_processors import TextFileProcessor, PDFProcessor, DocxProcessor, PPTProcessor, ExcelProcessor
|
|
21
|
+
from jarvis.jarvis_rag.file_processors import TextFileProcessor, PDFProcessor, DocxProcessor, PPTProcessor, ExcelProcessor
|
|
22
22
|
|
|
23
23
|
"""
|
|
24
24
|
Jarvis RAG (Retrieval-Augmented Generation) Module
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
from typing import Dict, Any
|
|
2
2
|
import os
|
|
3
|
-
import pathlib
|
|
4
3
|
|
|
5
|
-
from colorama import init
|
|
6
4
|
|
|
7
5
|
from jarvis.jarvis_agent import Agent
|
|
8
6
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
9
7
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
10
8
|
from jarvis.jarvis_utils.git_utils import find_git_root
|
|
11
|
-
from jarvis.jarvis_utils.config import dont_use_local_model
|
|
12
9
|
from jarvis.jarvis_utils.utils import init_env
|
|
13
10
|
|
|
14
11
|
class AskCodebaseTool:
|
|
15
12
|
"""用于智能代码库查询和分析的工具
|
|
16
13
|
|
|
17
14
|
适用场景:
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
- 查找特定API
|
|
15
|
+
- 查询特定功能所在的文件位置(支持所有文件类型)
|
|
16
|
+
- 了解单个功能点的实现原理(支持所有文件类型)
|
|
17
|
+
- 查找特定API或接口的用法(支持所有文件类型)
|
|
21
18
|
|
|
22
19
|
不适用场景:
|
|
23
20
|
- 跨越多文件的大范围分析
|
|
@@ -43,9 +40,8 @@ class AskCodebaseTool:
|
|
|
43
40
|
"required": ["question"]
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return not dont_use_local_model()
|
|
43
|
+
def __init__(self, auto_complete: bool = True):
|
|
44
|
+
self.auto_complete = auto_complete
|
|
49
45
|
|
|
50
46
|
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
51
47
|
"""Execute codebase analysis using an Agent with execute_shell and rag tools
|
|
@@ -98,14 +94,10 @@ class AskCodebaseTool:
|
|
|
98
94
|
name=f"CodebaseAnalyzer",
|
|
99
95
|
description=f"分析代码库中的功能实现和定位",
|
|
100
96
|
summary_prompt=summary_prompt,
|
|
101
|
-
platform=PlatformRegistry().
|
|
97
|
+
platform=PlatformRegistry().get_normal_platform(),
|
|
102
98
|
output_handler=[tool_registry],
|
|
103
|
-
need_summary=True,
|
|
104
|
-
is_sub_agent=True,
|
|
105
|
-
use_methodology=False,
|
|
106
|
-
record_methodology=False,
|
|
107
99
|
execute_tool_confirm=False,
|
|
108
|
-
auto_complete=
|
|
100
|
+
auto_complete=self.auto_complete
|
|
109
101
|
)
|
|
110
102
|
|
|
111
103
|
# Run agent and get result
|
|
@@ -149,62 +141,67 @@ class AskCodebaseTool:
|
|
|
149
141
|
- 代码库根目录: {git_root}
|
|
150
142
|
|
|
151
143
|
## 工具使用优先级
|
|
152
|
-
1.
|
|
153
|
-
|
|
154
|
-
|
|
144
|
+
1. **绝对优先使用 execute_shell**:
|
|
145
|
+
- 使用 fd 查找文件: `fd -t f -e py` 查找Python文件等
|
|
146
|
+
- 使用 rg 搜索代码: `rg "pattern" --type py` 在Python文件中搜索等
|
|
147
|
+
- 使用 loc 统计代码: `loc --include="*.py"` 统计Python代码量等
|
|
148
|
+
|
|
149
|
+
2. **优先使用 read_code**:
|
|
150
|
+
- 找到相关文件后优先使用read_code读取文件内容
|
|
151
|
+
- 对大文件使用行范围参数读取指定区域
|
|
152
|
+
|
|
153
|
+
3. **避免使用 rag**:
|
|
154
|
+
- 仅在fd、rg和read_code无法解决问题时作为最后手段
|
|
155
|
+
- 使用rag前必须先尝试使用shell命令解决问题
|
|
155
156
|
|
|
156
157
|
## 分析策略
|
|
157
158
|
1. 首先理解问题,确定需要查找的关键信息和代码组件
|
|
158
|
-
2. 使用
|
|
159
|
-
3. 使用
|
|
160
|
-
4.
|
|
161
|
-
5.
|
|
159
|
+
2. 使用fd命令查找可能相关的文件
|
|
160
|
+
3. 使用rg命令搜索关键词和代码模式
|
|
161
|
+
4. 使用read_code工具直接读取和分析相关文件内容
|
|
162
|
+
5. 只有在fd、rg和read_code都无法解决问题时才考虑使用RAG工具
|
|
163
|
+
6. 根据文件内容提供具体、准确的回答
|
|
164
|
+
7. 确保分析的完整性,收集充分的信息后再得出结论
|
|
165
|
+
8. 优先查阅README文件、文档目录和项目文档
|
|
162
166
|
|
|
163
167
|
## 分析步骤
|
|
164
|
-
1.
|
|
165
|
-
- 使用
|
|
166
|
-
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
1. **确定项目的编程语言**:
|
|
169
|
+
- 使用loc命令: `loc` 统计各类文件数量
|
|
170
|
+
- 查看构建文件和配置文件
|
|
171
|
+
- 了解项目使用的框架和主要依赖
|
|
172
|
+
|
|
173
|
+
2. **探索代码库结构**:
|
|
174
|
+
- 使用 `fd -t d` 了解目录结构
|
|
175
|
+
- 使用 `fd README.md` 查找README文件
|
|
176
|
+
- 使用 `fd -e md -g "doc*"` 查找文档文件
|
|
177
|
+
|
|
178
|
+
3. **定位相关文件**:
|
|
179
|
+
- 使用fd和rg命令查找关键词
|
|
180
|
+
- 示例: `rg -w "登录|login" --type py` 查找登录相关代码
|
|
181
|
+
- 示例: `fd -e py -g "*auth*"` 查找认证相关文件
|
|
182
|
+
|
|
183
|
+
4. **深入分析代码**:
|
|
173
184
|
- 使用read_code工具直接读取文件内容
|
|
174
185
|
- 分析关键文件的实现细节
|
|
175
|
-
- 识别功能的实现方式和关键逻辑
|
|
186
|
+
- 使用rg识别功能的实现方式和关键逻辑
|
|
176
187
|
|
|
177
|
-
|
|
188
|
+
5. **回答问题**:
|
|
178
189
|
- 提供基于直接分析代码的具体回答
|
|
179
190
|
- 引用具体文件和代码片段作为依据
|
|
180
191
|
|
|
181
192
|
## 关于RAG工具使用
|
|
182
|
-
- RAG工具应作为最后选择,仅在
|
|
183
|
-
- RAG工具返回的信息可能存在偏差或不准确之处
|
|
193
|
+
- RAG工具应作为最后选择,仅在fd、rg和read_code都无法解决问题时使用
|
|
184
194
|
- 必须通过查看实际代码文件验证RAG返回的每条重要信息
|
|
185
195
|
- 对于关键发现,始终使用`read_code`工具查看原始文件内容进行求证
|
|
186
196
|
- 如发现RAG结果与实际代码不符,以实际代码为准
|
|
187
197
|
|
|
188
|
-
## 探索命令示例
|
|
189
|
-
```bash
|
|
190
|
-
# 查看目录结构
|
|
191
|
-
find . -type d -not -path "*/\\.*" | sort
|
|
192
|
-
|
|
193
|
-
# 搜索与问题相关的文件
|
|
194
|
-
find . -type f -name "*.py" -o -name "*.js" | xargs grep -l "关键词"
|
|
195
|
-
grep -r "关键词" --include="*.py" .
|
|
196
|
-
|
|
197
|
-
# 查看文件内容
|
|
198
|
-
cat 文件路径
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
|
|
202
198
|
## 输出要求
|
|
203
199
|
- 提供准确、具体的回答,避免模糊不清的描述
|
|
204
200
|
- 引用具体文件路径和代码片段作为依据
|
|
205
201
|
- 如果无法找到答案,明确说明并提供原因
|
|
206
202
|
- 组织信息的逻辑清晰,便于理解
|
|
207
203
|
- 对复杂概念提供简明解释
|
|
204
|
+
- 确保全面收集相关信息后再形成结论
|
|
208
205
|
- 明确区分已验证的信息和待验证的信息"""
|
|
209
206
|
|
|
210
207
|
def _create_summary_prompt(self, question: str) -> str:
|
|
@@ -225,25 +222,35 @@ cat 文件路径
|
|
|
225
222
|
|
|
226
223
|
报告应包含:
|
|
227
224
|
|
|
228
|
-
1.
|
|
225
|
+
1. **项目基本信息**:
|
|
226
|
+
- 项目的主要编程语言和技术栈
|
|
227
|
+
- 项目的主要框架和依赖
|
|
228
|
+
- 项目的基本结构
|
|
229
|
+
|
|
230
|
+
2. **问题回答**:
|
|
229
231
|
- 直接、具体地回答问题
|
|
230
232
|
- 基于代码库中的实际代码
|
|
231
233
|
- 避免模糊或推测性的回答
|
|
232
234
|
|
|
233
|
-
|
|
235
|
+
3. **核心发现**:
|
|
234
236
|
- 相关文件和代码位置
|
|
235
237
|
- 关键实现细节
|
|
236
238
|
- 功能运作机制
|
|
237
239
|
|
|
238
|
-
|
|
240
|
+
4. **证据引用**:
|
|
239
241
|
- 引用具体文件路径
|
|
240
242
|
- 包含关键代码片段
|
|
241
243
|
- 解释代码如何支持你的回答
|
|
242
244
|
|
|
243
|
-
|
|
245
|
+
5. **局限性**(如有):
|
|
244
246
|
- 指出分析的任何局限
|
|
245
247
|
- 说明任何无法确定的信息
|
|
246
248
|
|
|
249
|
+
6. **分析完整性**:
|
|
250
|
+
- 确保在得出结论前已全面收集和分析相关信息
|
|
251
|
+
- 避免基于部分信息形成不完整或偏颇的判断
|
|
252
|
+
- 明确标识哪些是已确认的结论,哪些可能需要进一步验证
|
|
253
|
+
|
|
247
254
|
使用清晰的Markdown格式,重点突出对问题的回答和支持证据。"""
|
|
248
255
|
|
|
249
256
|
|
|
@@ -270,7 +277,7 @@ def main():
|
|
|
270
277
|
args = parser.parse_args()
|
|
271
278
|
|
|
272
279
|
# 创建并执行工具
|
|
273
|
-
tool = AskCodebaseTool()
|
|
280
|
+
tool = AskCodebaseTool(auto_complete=False)
|
|
274
281
|
result = tool.execute({
|
|
275
282
|
"question": args.question,
|
|
276
283
|
"root_dir": args.root_dir
|
|
@@ -4,6 +4,7 @@ import os
|
|
|
4
4
|
|
|
5
5
|
from yaspin import yaspin
|
|
6
6
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
7
|
+
from jarvis.jarvis_tools.read_code import ReadCodeTool
|
|
7
8
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
8
9
|
from jarvis.jarvis_agent import Agent
|
|
9
10
|
import re
|
|
@@ -89,7 +90,7 @@ class CodeReviewTool:
|
|
|
89
90
|
"stderr": "file_path is required for file review type"
|
|
90
91
|
}
|
|
91
92
|
file_path = args["file_path"].strip()
|
|
92
|
-
diff_cmd =
|
|
93
|
+
diff_cmd = ReadCodeTool().execute({"files": [{"path": file_path}]})["stdout"]
|
|
93
94
|
else: # current changes
|
|
94
95
|
diff_cmd = "git diff HEAD | cat -"
|
|
95
96
|
|
|
@@ -114,6 +115,25 @@ class CodeReviewTool:
|
|
|
114
115
|
|
|
115
116
|
system_prompt = """你是一位精益求精的首席代码审查专家,拥有多年企业级代码审计经验。你需要对所有代码变更进行极其全面、严谨且深入的审查,确保代码质量达到最高标准。
|
|
116
117
|
|
|
118
|
+
# 代码审查工具选择
|
|
119
|
+
优先使用执行shell命令进行静态分析,而非依赖内置代码审查功能:
|
|
120
|
+
|
|
121
|
+
| 分析需求 | 首选工具 | 备选工具 |
|
|
122
|
+
|---------|---------|----------|
|
|
123
|
+
| 代码质量检查 | execute_shell | - |
|
|
124
|
+
| 语法检查 | 语言特定lint工具 | - |
|
|
125
|
+
| 安全分析 | 安全扫描工具 | - |
|
|
126
|
+
| 代码统计 | loc | - |
|
|
127
|
+
|
|
128
|
+
# 推荐命令
|
|
129
|
+
- Python: `pylint <file_path>`, `flake8 <file_path>`, `mypy <file_path>`
|
|
130
|
+
- JavaScript/TypeScript: `eslint <file_path>`, `tsc --noEmit <file_path>`
|
|
131
|
+
- Java: `checkstyle <file_path>`, `pmd -d <file_path>`
|
|
132
|
+
- C/C++: `cppcheck <file_path>`, `clang-tidy <file_path>`
|
|
133
|
+
- Go: `golint <file_path>`, `go vet <file_path>`
|
|
134
|
+
- Rust: `cargo clippy`, `rustfmt --check <file_path>`
|
|
135
|
+
- 通用搜索:`rg "pattern" <files>` 查找特定代码模式
|
|
136
|
+
|
|
117
137
|
# 专家审查标准
|
|
118
138
|
1. 必须逐行分析每个修改文件,细致审查每一处变更,不遗漏任何细节
|
|
119
139
|
2. 基于坚实的证据识别问题,不做主观臆测,给出明确的问题定位和详细分析
|
|
@@ -226,7 +246,6 @@ class CodeReviewTool:
|
|
|
226
246
|
|
|
227
247
|
如果没有发现任何问题,请在REPORT标签内进行全面分析后明确说明"经过全面审查,未发现问题"并解释原因。
|
|
228
248
|
必须确保对所有修改的文件都进行了审查,并在报告中明确提及每个文件,即使某些文件没有发现问题。""",
|
|
229
|
-
is_sub_agent=True,
|
|
230
249
|
output_handler=[tool_registry],
|
|
231
250
|
platform=PlatformRegistry().get_thinking_platform(),
|
|
232
251
|
auto_complete=True
|
|
@@ -112,12 +112,8 @@ class FileAnalyzerTool:
|
|
|
112
112
|
name=f"FileAnalyzer-{file_name}",
|
|
113
113
|
description=f"分析 {file_name} 文件的结构和实现",
|
|
114
114
|
summary_prompt=summary_prompt,
|
|
115
|
-
platform=PlatformRegistry().
|
|
115
|
+
platform=PlatformRegistry().get_normal_platform(),
|
|
116
116
|
output_handler=[tool_registry],
|
|
117
|
-
need_summary=True,
|
|
118
|
-
is_sub_agent=True,
|
|
119
|
-
use_methodology=False,
|
|
120
|
-
record_methodology=False,
|
|
121
117
|
execute_tool_confirm=False,
|
|
122
118
|
auto_complete=True
|
|
123
119
|
)
|
|
@@ -149,101 +145,116 @@ class FileAnalyzerTool:
|
|
|
149
145
|
创建Agent的system prompt
|
|
150
146
|
|
|
151
147
|
Args:
|
|
152
|
-
file_path:
|
|
148
|
+
file_path: 文件路径
|
|
153
149
|
file_name: 文件名
|
|
154
150
|
file_ext: 文件扩展名
|
|
155
|
-
root_dir:
|
|
151
|
+
root_dir: 代码库根目录
|
|
156
152
|
objective: 分析目标
|
|
157
153
|
|
|
158
154
|
Returns:
|
|
159
155
|
系统提示文本
|
|
160
156
|
"""
|
|
161
|
-
# 根据文件扩展名确定语言
|
|
162
|
-
language_map = {
|
|
163
|
-
'.py': 'Python',
|
|
164
|
-
'.js': 'JavaScript',
|
|
165
|
-
'.ts': 'TypeScript',
|
|
166
|
-
'.java': 'Java',
|
|
167
|
-
'.c': 'C',
|
|
168
|
-
'.cpp': 'C++',
|
|
169
|
-
'.cs': 'C#',
|
|
170
|
-
'.go': 'Go',
|
|
171
|
-
'.rs': 'Rust',
|
|
172
|
-
'.php': 'PHP',
|
|
173
|
-
'.rb': 'Ruby',
|
|
174
|
-
'.swift': 'Swift',
|
|
175
|
-
'.kt': 'Kotlin',
|
|
176
|
-
'.sh': 'Shell',
|
|
177
|
-
'.html': 'HTML',
|
|
178
|
-
'.css': 'CSS',
|
|
179
|
-
'.scss': 'SCSS',
|
|
180
|
-
'.json': 'JSON',
|
|
181
|
-
'.xml': 'XML',
|
|
182
|
-
'.yaml': 'YAML',
|
|
183
|
-
'.md': 'Markdown'
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
language = language_map.get(file_ext, '未知')
|
|
187
157
|
objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
|
|
188
158
|
|
|
189
|
-
return f"""#
|
|
159
|
+
return f"""# 文件分析专家
|
|
190
160
|
|
|
191
161
|
## 任务描述
|
|
192
|
-
分析文件 `{file_path}`
|
|
162
|
+
分析文件 `{file_path}` 的结构、实现细节和代码质量,专注于分析目标所需的内容,生成有针对性、深入且有洞察力的文件分析报告。{objective_text}
|
|
163
|
+
|
|
164
|
+
## 工具使用优先级
|
|
165
|
+
1. **优先使用 read_code**: 直接读取文件内容是分析文件的首选方式
|
|
166
|
+
2. **优先使用 execute_shell**:
|
|
167
|
+
- 使用 rg 搜索文件内容: `rg "pattern" {file_path}`
|
|
168
|
+
- 使用 loc 统计代码: `loc {file_path}`
|
|
169
|
+
3. **仅在必要时使用其他分析工具**
|
|
193
170
|
|
|
194
171
|
## 文件信息
|
|
195
172
|
- 文件路径: `{file_path}`
|
|
196
|
-
-
|
|
173
|
+
- 文件名称: `{file_name}`
|
|
174
|
+
- 文件类型: `{file_ext}`
|
|
197
175
|
- 项目根目录: `{root_dir}`
|
|
198
176
|
|
|
199
177
|
## 分析策略
|
|
200
|
-
1.
|
|
201
|
-
2.
|
|
202
|
-
3.
|
|
203
|
-
4.
|
|
178
|
+
1. 首先使用read_code直接读取整个文件内容或分段读取
|
|
179
|
+
2. 使用rg命令搜索文件中的特定模式和结构
|
|
180
|
+
3. 使用loc命令获取文件统计信息
|
|
181
|
+
4. 根据文件类型和分析目标确定重点关注的方面
|
|
182
|
+
5. 保证分析的完整性,收集充分的信息后再得出结论
|
|
183
|
+
|
|
184
|
+
## 分析步骤
|
|
185
|
+
以下步骤应根据具体分析目标灵活应用:
|
|
186
|
+
|
|
187
|
+
1. **文件基本信息分析**:
|
|
188
|
+
- 使用 `loc {file_path}` 获取代码统计
|
|
189
|
+
- 使用 read_code 读取文件头部注释和文档
|
|
190
|
+
- 确定文件的编程语言和主要功能
|
|
191
|
+
|
|
192
|
+
2. **结构分析**:
|
|
193
|
+
- 使用 read_code 阅读完整文件
|
|
194
|
+
- 对于大文件,可分段读取主要部分
|
|
195
|
+
- 识别文件的主要组成部分:
|
|
196
|
+
- 类定义: `rg "class\\s+" {file_path}`
|
|
197
|
+
- 函数定义: `rg "def\\s+|function\\s+" {file_path}`
|
|
198
|
+
- 重要变量: `rg "const\\s+|var\\s+|let\\s+" {file_path}`
|
|
199
|
+
|
|
200
|
+
3. **核心组件分析**:
|
|
201
|
+
- 识别文件中的关键接口、类和函数
|
|
202
|
+
- 使用 rg 搜索重要的代码模式
|
|
203
|
+
- 分析组件间的交互和依赖关系
|
|
204
|
+
|
|
205
|
+
4. **实现细节分析**:
|
|
206
|
+
- 读取并分析关键函数的实现
|
|
207
|
+
- 关注异常处理: `rg "try|catch|except" {file_path}`
|
|
208
|
+
- 检查资源管理: `rg "open|close|with" {file_path}`
|
|
209
|
+
|
|
210
|
+
5. **引用分析**:
|
|
211
|
+
- 找出引用的外部依赖: `rg "import|require|include" {file_path}`
|
|
212
|
+
- 分析与其他模块的交互
|
|
213
|
+
|
|
214
|
+
## 分析工具使用指南
|
|
215
|
+
|
|
216
|
+
### read_code
|
|
217
|
+
- **首选工具**: 用于读取和分析文件内容
|
|
218
|
+
- **用法指南**:
|
|
219
|
+
- 读取整个文件: 直接指定文件路径
|
|
220
|
+
- 读取部分内容: 指定文件路径和行范围
|
|
221
|
+
- 读取头部或关键部分: 根据目的选择合适的行范围
|
|
222
|
+
|
|
223
|
+
### execute_shell
|
|
224
|
+
- **用途**: 执行辅助命令进行分析
|
|
225
|
+
- **推荐命令**:
|
|
226
|
+
- `rg "pattern" {file_path}`: 在文件中搜索模式
|
|
227
|
+
- `loc {file_path}`: 获取文件代码统计
|
|
228
|
+
- `rg -n "class|def|function" {file_path}`: 查找结构元素
|
|
204
229
|
|
|
205
|
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
230
|
+
### 其他专业工具
|
|
231
|
+
- **使用时机**: 仅当read_code和execute_shell不足以完成分析时
|
|
232
|
+
- **使用前提**: 必须先尝试使用基本工具解决问题
|
|
233
|
+
- **选择原则**: 根据实际需要选择最简洁有效的工具
|
|
209
234
|
|
|
210
|
-
##
|
|
211
|
-
|
|
212
|
-
```
|
|
213
|
-
read_code {{
|
|
214
|
-
"files": [{{
|
|
215
|
-
"path": "{file_path}",
|
|
216
|
-
"start_line": 1,
|
|
217
|
-
"end_line": -1
|
|
218
|
-
}}]
|
|
219
|
-
}}
|
|
220
|
-
```
|
|
235
|
+
## 分析框架适应
|
|
236
|
+
根据文件类型和编程范式调整分析重点:
|
|
221
237
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
238
|
+
### 不同编程范式
|
|
239
|
+
- 面向对象: 类层次、继承、封装、接口实现
|
|
240
|
+
- 函数式: 函数组合、不可变性、纯函数
|
|
241
|
+
- 过程式: 流程控制、状态管理、数据处理
|
|
242
|
+
- 声明式: 规则定义、约束表达、模式匹配
|
|
226
243
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}}
|
|
233
|
-
|
|
234
|
-
function_analyzer {{
|
|
235
|
-
"function_name": "关键函数名称",
|
|
236
|
-
"file_path": "{file_path}"
|
|
237
|
-
}}
|
|
238
|
-
```
|
|
244
|
+
### 不同文件类型
|
|
245
|
+
- 源代码文件: 实现逻辑、算法、接口设计
|
|
246
|
+
- 配置文件: 参数设置、环境变量、系统选项
|
|
247
|
+
- 模板文件: 渲染逻辑、变量占位符、条件分支
|
|
248
|
+
- 数据文件: 结构组织、关系定义、索引设计
|
|
239
249
|
|
|
240
250
|
## 输出要求
|
|
241
251
|
- 直接回应分析目标的关键问题
|
|
242
252
|
- 提供与目标相关的深入洞察
|
|
243
253
|
- 分析内容应直接服务于分析目标
|
|
244
254
|
- 避免与目标无关的冗余信息
|
|
245
|
-
-
|
|
246
|
-
-
|
|
255
|
+
- 使用具体代码片段支持分析结论
|
|
256
|
+
- 提供针对分析目标的具体建议
|
|
257
|
+
- 保证全面分析相关信息后再得出结论"""
|
|
247
258
|
|
|
248
259
|
def _create_summary_prompt(self, file_path: str, file_name: str) -> str:
|
|
249
260
|
"""
|