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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +201 -79
- jarvis/jarvis_agent/builtin_input_handler.py +16 -6
- jarvis/jarvis_agent/file_input_handler.py +9 -9
- jarvis/jarvis_agent/jarvis.py +10 -10
- jarvis/jarvis_agent/main.py +12 -11
- jarvis/jarvis_agent/output_handler.py +3 -3
- jarvis/jarvis_agent/patch.py +86 -62
- jarvis/jarvis_agent/shell_input_handler.py +5 -3
- jarvis/jarvis_code_agent/code_agent.py +134 -99
- jarvis/jarvis_code_agent/file_select.py +24 -24
- jarvis/jarvis_dev/main.py +45 -51
- 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 -11
- jarvis/jarvis_lsp/cpp.py +14 -14
- jarvis/jarvis_lsp/go.py +13 -13
- jarvis/jarvis_lsp/python.py +8 -8
- jarvis/jarvis_lsp/registry.py +21 -21
- jarvis/jarvis_lsp/rust.py +15 -15
- jarvis/jarvis_methodology/main.py +101 -0
- jarvis/jarvis_multi_agent/__init__.py +11 -11
- jarvis/jarvis_multi_agent/main.py +6 -6
- 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 +27 -28
- jarvis/jarvis_platform/yuanbao.py +38 -42
- 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 +261 -277
- jarvis/jarvis_smart_shell/main.py +12 -12
- jarvis/jarvis_tools/ask_codebase.py +28 -28
- 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 +19 -19
- jarvis/jarvis_tools/create_code_agent.py +15 -15
- 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 +29 -29
- jarvis/jarvis_tools/file_operation.py +22 -20
- jarvis/jarvis_tools/find_caller.py +25 -25
- jarvis/jarvis_tools/find_methodolopy.py +65 -0
- jarvis/jarvis_tools/find_symbol.py +24 -24
- jarvis/jarvis_tools/function_analyzer.py +27 -27
- jarvis/jarvis_tools/git_commiter.py +9 -9
- jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -19
- jarvis/jarvis_tools/methodology.py +23 -62
- jarvis/jarvis_tools/project_analyzer.py +29 -33
- jarvis/jarvis_tools/rag.py +15 -15
- jarvis/jarvis_tools/read_code.py +24 -22
- jarvis/jarvis_tools/read_webpage.py +31 -31
- jarvis/jarvis_tools/registry.py +72 -52
- jarvis/jarvis_tools/tool_generator.py +18 -18
- jarvis/jarvis_utils/config.py +23 -23
- 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 +140 -136
- jarvis/jarvis_utils/output.py +11 -11
- jarvis/jarvis_utils/utils.py +22 -70
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/METADATA +1 -1
- jarvis_ai_assistant-0.1.138.dist-info/RECORD +85 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/entry_points.txt +2 -0
- jarvis/jarvis_tools/select_code_files.py +0 -62
- jarvis_ai_assistant-0.1.134.dist-info/RECORD +0 -82
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/top_level.txt +0 -0
|
@@ -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,23 +79,23 @@ 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,
|
|
@@ -107,17 +107,17 @@ class SymbolTool:
|
|
|
107
107
|
execute_tool_confirm=False,
|
|
108
108
|
auto_complete=True
|
|
109
109
|
)
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
# 运行agent并获取结果
|
|
112
112
|
task_input = f"查找符号 '{symbol}' 在代码库中的引用、定义和声明位置"
|
|
113
113
|
result = symbol_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,39 +128,39 @@ class SymbolTool:
|
|
|
128
128
|
finally:
|
|
129
129
|
# 恢复原始目录
|
|
130
130
|
os.chdir(original_dir)
|
|
131
|
-
|
|
132
|
-
def _create_system_prompt(self, symbol: str, root_dir: str,
|
|
131
|
+
|
|
132
|
+
def _create_system_prompt(self, symbol: 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
|
symbol: 符号名称
|
|
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
|
return f"""# 代码符号分析专家
|
|
153
153
|
|
|
154
154
|
## 任务描述
|
|
155
155
|
查找符号 `{symbol}` 在代码库中的定义、声明和引用位置,专注于分析目标所需的信息,生成有针对性的符号分析报告。{objective_text}
|
|
156
156
|
|
|
157
157
|
## 工具使用优先级
|
|
158
|
-
1. **优先使用 execute_shell 执行 rg 命令**:
|
|
158
|
+
1. **优先使用 execute_shell 执行 rg 命令**:
|
|
159
159
|
- `rg -w "{symbol}" --type py` 查找Python文件中的符号
|
|
160
160
|
- `rg "class\\s+{symbol}|def\\s+{symbol}" --type py` 查找定义
|
|
161
161
|
- `rg -w "{symbol}" -A 2 -B 2` 查看符号上下文
|
|
162
162
|
|
|
163
|
-
2. **辅以 read_code**:
|
|
163
|
+
2. **辅以 read_code**:
|
|
164
164
|
- 找到符号位置后使用read_code阅读上下文
|
|
165
165
|
- 读取符号定义和关键引用的完整实现
|
|
166
166
|
|
|
@@ -183,7 +183,7 @@ class SymbolTool:
|
|
|
183
183
|
## 符号查找工具指南
|
|
184
184
|
|
|
185
185
|
### execute_shell 搜索命令
|
|
186
|
-
- **基本搜索**:
|
|
186
|
+
- **基本搜索**:
|
|
187
187
|
- `rg -w "{symbol}" --type=文件类型`
|
|
188
188
|
- 示例: `rg -w "{symbol}" --type py` 搜索Python文件中的符号
|
|
189
189
|
|
|
@@ -272,10 +272,10 @@ class SymbolTool:
|
|
|
272
272
|
def _create_summary_prompt(self, symbol: str) -> str:
|
|
273
273
|
"""
|
|
274
274
|
创建Agent的summary prompt
|
|
275
|
-
|
|
275
|
+
|
|
276
276
|
Args:
|
|
277
277
|
symbol: 符号名称
|
|
278
|
-
|
|
278
|
+
|
|
279
279
|
Returns:
|
|
280
280
|
总结提示文本
|
|
281
281
|
"""
|
|
@@ -11,7 +11,7 @@ class FunctionAnalyzerTool:
|
|
|
11
11
|
函数分析工具
|
|
12
12
|
使用agent深入分析函数内部实现,包括子函数调用、全局变量使用等
|
|
13
13
|
"""
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
name = "function_analyzer"
|
|
16
16
|
description = "深入分析函数内部实现,查找子函数调用、全局变量使用等详细信息"
|
|
17
17
|
parameters = {
|
|
@@ -60,20 +60,20 @@ class FunctionAnalyzerTool:
|
|
|
60
60
|
},
|
|
61
61
|
"required": ["function_name"]
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
65
65
|
"""
|
|
66
66
|
执行函数分析工具
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
Args:
|
|
69
69
|
args: 包含参数的字典
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
Returns:
|
|
72
72
|
包含执行结果的字典
|
|
73
73
|
"""
|
|
74
74
|
# 存储原始目录
|
|
75
75
|
original_dir = os.getcwd()
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
try:
|
|
78
78
|
# 解析参数
|
|
79
79
|
function_name = args.get("function_name", "")
|
|
@@ -83,7 +83,7 @@ class FunctionAnalyzerTool:
|
|
|
83
83
|
exclude_dirs = args.get("exclude_dirs", [])
|
|
84
84
|
analysis_depth = args.get("analysis_depth", 1)
|
|
85
85
|
objective = args.get("objective", "")
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
# 验证参数
|
|
88
88
|
if not function_name:
|
|
89
89
|
return {
|
|
@@ -91,24 +91,24 @@ class FunctionAnalyzerTool:
|
|
|
91
91
|
"stdout": "",
|
|
92
92
|
"stderr": "必须提供函数名称"
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
|
|
95
95
|
# 创建agent的system prompt
|
|
96
96
|
system_prompt = self._create_system_prompt(
|
|
97
|
-
function_name, file_path, root_dir,
|
|
97
|
+
function_name, file_path, root_dir,
|
|
98
98
|
file_extensions, exclude_dirs, analysis_depth, objective
|
|
99
99
|
)
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
# 创建agent的summary prompt
|
|
102
102
|
summary_prompt = self._create_summary_prompt(function_name, analysis_depth)
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
# 切换到根目录
|
|
105
105
|
os.chdir(root_dir)
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
# 构建使用的工具
|
|
108
108
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
109
109
|
tool_registry = ToolRegistry()
|
|
110
110
|
tool_registry.use_tools(["execute_shell", "read_code"])
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
# 创建并运行agent
|
|
113
113
|
analyzer_agent = Agent(
|
|
114
114
|
system_prompt=system_prompt,
|
|
@@ -120,17 +120,17 @@ class FunctionAnalyzerTool:
|
|
|
120
120
|
execute_tool_confirm=False,
|
|
121
121
|
auto_complete=True
|
|
122
122
|
)
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
# 运行agent并获取结果
|
|
125
125
|
task_input = f"深入分析 '{function_name}' 函数的内部实现,包括子函数调用、全局变量使用等详细信息"
|
|
126
126
|
result = analyzer_agent.run(task_input)
|
|
127
|
-
|
|
127
|
+
|
|
128
128
|
return {
|
|
129
129
|
"success": True,
|
|
130
130
|
"stdout": result,
|
|
131
131
|
"stderr": ""
|
|
132
132
|
}
|
|
133
|
-
|
|
133
|
+
|
|
134
134
|
except Exception as e:
|
|
135
135
|
PrettyOutput.print(str(e), OutputType.ERROR)
|
|
136
136
|
return {
|
|
@@ -141,13 +141,13 @@ class FunctionAnalyzerTool:
|
|
|
141
141
|
finally:
|
|
142
142
|
# 恢复原始目录
|
|
143
143
|
os.chdir(original_dir)
|
|
144
|
-
|
|
145
|
-
def _create_system_prompt(self, function_name: str, file_path: str, root_dir: str,
|
|
144
|
+
|
|
145
|
+
def _create_system_prompt(self, function_name: str, file_path: str, root_dir: str,
|
|
146
146
|
file_extensions: List[str], exclude_dirs: List[str],
|
|
147
147
|
analysis_depth: int, objective: str) -> str:
|
|
148
148
|
"""
|
|
149
149
|
创建Agent的system prompt
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
Args:
|
|
152
152
|
function_name: 函数名称
|
|
153
153
|
file_path: 函数所在文件路径
|
|
@@ -156,29 +156,29 @@ class FunctionAnalyzerTool:
|
|
|
156
156
|
exclude_dirs: 排除目录列表
|
|
157
157
|
analysis_depth: 子函数分析深度
|
|
158
158
|
objective: 分析目标
|
|
159
|
-
|
|
159
|
+
|
|
160
160
|
Returns:
|
|
161
161
|
系统提示文本
|
|
162
162
|
"""
|
|
163
163
|
file_ext_str = " ".join([f"*{ext}" for ext in file_extensions]) if file_extensions else ""
|
|
164
164
|
exclude_str = " ".join([f"--glob '!{excl}'" for excl in exclude_dirs]) if exclude_dirs else ""
|
|
165
|
-
|
|
165
|
+
|
|
166
166
|
depth_description = "不分析子函数" if analysis_depth == 0 else f"分析 {analysis_depth} 层子函数"
|
|
167
167
|
file_info = f"已知文件路径: {file_path}" if file_path else "需要首先查找函数定义位置"
|
|
168
168
|
objective_text = f"\n\n## 分析目标\n{objective}" if objective else ""
|
|
169
|
-
|
|
169
|
+
|
|
170
170
|
return f"""# 函数实现分析专家
|
|
171
171
|
|
|
172
172
|
## 任务描述
|
|
173
173
|
分析函数 `{function_name}` 的实现,专注于分析目标所需的信息,生成有针对性的函数分析报告。{objective_text}
|
|
174
174
|
|
|
175
175
|
## 工具使用优先级
|
|
176
|
-
1. **首先使用 execute_shell 执行 rg 命令查找函数定义**:
|
|
176
|
+
1. **首先使用 execute_shell 执行 rg 命令查找函数定义**:
|
|
177
177
|
- `rg "def\\s+{function_name}\\s*\\(" --type py` 查找Python函数定义
|
|
178
178
|
- `rg "function\\s+{function_name}\\s*\\(" --type js` 查找JavaScript函数定义
|
|
179
179
|
- `rg "func\\s+{function_name}\\s*\\(" --type go` 查找Go函数定义
|
|
180
180
|
|
|
181
|
-
2. **优先使用 read_code 阅读函数实现**:
|
|
181
|
+
2. **优先使用 read_code 阅读函数实现**:
|
|
182
182
|
- 找到函数位置后使用read_code阅读完整实现
|
|
183
183
|
- 对于长函数可分段读取关键部分
|
|
184
184
|
|
|
@@ -305,16 +305,16 @@ class FunctionAnalyzerTool:
|
|
|
305
305
|
def _create_summary_prompt(self, function_name: str, analysis_depth: int) -> str:
|
|
306
306
|
"""
|
|
307
307
|
创建Agent的summary prompt
|
|
308
|
-
|
|
308
|
+
|
|
309
309
|
Args:
|
|
310
310
|
function_name: 函数名称
|
|
311
311
|
analysis_depth: 子函数分析深度
|
|
312
|
-
|
|
312
|
+
|
|
313
313
|
Returns:
|
|
314
314
|
总结提示文本
|
|
315
315
|
"""
|
|
316
316
|
depth_description = "不包含子函数分析" if analysis_depth == 0 else f"包含 {analysis_depth} 层子函数分析"
|
|
317
|
-
|
|
317
|
+
|
|
318
318
|
return f"""# 函数分析报告: `{function_name}`
|
|
319
319
|
|
|
320
320
|
## 报告要求
|
|
@@ -328,4 +328,4 @@ class FunctionAnalyzerTool:
|
|
|
328
328
|
- 使用具体的代码片段支持你的观点
|
|
329
329
|
- 以清晰的Markdown格式呈现,简洁明了
|
|
330
330
|
|
|
331
|
-
在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的函数概览,而是直接解决分析目标中提出的具体问题。"""
|
|
331
|
+
在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的函数概览,而是直接解决分析目标中提出的具体问题。"""
|
|
@@ -37,14 +37,14 @@ class GitCommitTool:
|
|
|
37
37
|
def _extract_commit_message(self, message):
|
|
38
38
|
"""Raw extraction preserving all characters"""
|
|
39
39
|
r = re.search(
|
|
40
|
-
r"(?i)" + ot("COMMIT_MESSAGE") + r"\s*([\s\S]*?)\s*" + ct("COMMIT_MESSAGE"),
|
|
40
|
+
r"(?i)" + ot("COMMIT_MESSAGE") + r"\s*([\s\S]*?)\s*" + ct("COMMIT_MESSAGE"),
|
|
41
41
|
message
|
|
42
42
|
)
|
|
43
43
|
if r:
|
|
44
44
|
# 直接返回原始内容,仅去除外围空白
|
|
45
45
|
return shlex.quote(r.group(1).strip())
|
|
46
46
|
return "<<FORMAT VIOLATION>> Invalid commit message structure"
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
def _get_last_commit_hash(self):
|
|
49
49
|
process = subprocess.Popen(
|
|
50
50
|
["git", "log", "-1", "--pretty=%H"],
|
|
@@ -58,19 +58,19 @@ class GitCommitTool:
|
|
|
58
58
|
"""Execute automatic commit process with support for multi-line messages and special characters"""
|
|
59
59
|
try:
|
|
60
60
|
root_dir = args.get("root_dir", ".")
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
# Store current directory
|
|
63
63
|
original_dir = os.getcwd()
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
try:
|
|
66
66
|
# Change to root_dir
|
|
67
67
|
os.chdir(root_dir)
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
find_git_root()
|
|
70
70
|
if not has_uncommitted_changes():
|
|
71
71
|
PrettyOutput.print("没有未提交的更改", OutputType.SUCCESS)
|
|
72
72
|
return {"success": True, "stdout": "No changes to commit", "stderr": ""}
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
with yaspin(text="正在初始化提交流程...", color="cyan") as spinner:
|
|
75
75
|
# 添加文件
|
|
76
76
|
spinner.text = "正在添加文件到提交..."
|
|
@@ -80,7 +80,7 @@ class GitCommitTool:
|
|
|
80
80
|
stderr=subprocess.DEVNULL
|
|
81
81
|
).wait()
|
|
82
82
|
spinner.write("✅ 添加文件到提交")
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
# 获取差异
|
|
85
85
|
spinner.text = "正在获取代码差异..."
|
|
86
86
|
process = subprocess.Popen(
|
|
@@ -90,7 +90,7 @@ class GitCommitTool:
|
|
|
90
90
|
)
|
|
91
91
|
diff = process.communicate()[0].decode()
|
|
92
92
|
spinner.write("✅ 获取差异")
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
# 生成提交信息
|
|
95
95
|
spinner.text = "正在生成提交消息..."
|
|
96
96
|
prompt = f'''根据以下规则生成提交信息:
|
|
@@ -114,7 +114,7 @@ class GitCommitTool:
|
|
|
114
114
|
commit_message = platform.chat_until_success(prompt)
|
|
115
115
|
commit_message = self._extract_commit_message(commit_message)
|
|
116
116
|
spinner.write("✅ 生成提交消息")
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
# 执行提交
|
|
119
119
|
spinner.text = "正在准备提交..."
|
|
120
120
|
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
|
|
@@ -3,7 +3,7 @@ from typing import Dict, Any
|
|
|
3
3
|
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
4
|
class LSPGetDiagnosticsTool:
|
|
5
5
|
"""Tool for getting diagnostics (errors, warnings) from code using LSP."""
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
# 工具名称
|
|
8
8
|
name = "lsp_get_diagnostics"
|
|
9
9
|
# 工具描述
|
|
@@ -18,19 +18,19 @@ class LSPGetDiagnosticsTool:
|
|
|
18
18
|
"default": "."
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
@staticmethod
|
|
23
23
|
def check() -> bool:
|
|
24
24
|
"""检查是否有可用的LSP服务器"""
|
|
25
25
|
registry = LSPRegistry.get_global_lsp_registry()
|
|
26
26
|
return len(registry.get_supported_languages()) > 0
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
29
29
|
"""执行工具的主要逻辑"""
|
|
30
30
|
file_path = args.get("file_path", "")
|
|
31
31
|
language = args.get("language", "")
|
|
32
32
|
root_dir = args.get("root_dir", ".")
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
# 验证输入参数
|
|
35
35
|
if not all([file_path, language]):
|
|
36
36
|
return {
|
|
@@ -38,7 +38,7 @@ class LSPGetDiagnosticsTool:
|
|
|
38
38
|
"stderr": "Both file_path and language must be provided",
|
|
39
39
|
"stdout": ""
|
|
40
40
|
}
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
# 检查文件是否存在
|
|
43
43
|
if not os.path.exists(file_path):
|
|
44
44
|
return {
|
|
@@ -46,18 +46,18 @@ class LSPGetDiagnosticsTool:
|
|
|
46
46
|
"stderr": f"File not found: {file_path}",
|
|
47
47
|
"stdout": ""
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
# 存储当前目录
|
|
51
51
|
original_dir = os.getcwd()
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
try:
|
|
54
54
|
# 切换到root_dir
|
|
55
55
|
os.chdir(root_dir)
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
# 获取LSP实例
|
|
58
58
|
registry = LSPRegistry.get_global_lsp_registry()
|
|
59
59
|
lsp = registry.create_lsp(language)
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
# 检查语言是否支持
|
|
62
62
|
if not lsp:
|
|
63
63
|
return {
|
|
@@ -65,7 +65,7 @@ class LSPGetDiagnosticsTool:
|
|
|
65
65
|
"stderr": f"No LSP support for language: {language}",
|
|
66
66
|
"stdout": ""
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
try:
|
|
70
70
|
# 初始化LSP
|
|
71
71
|
if not lsp.initialize(os.path.abspath(os.getcwd())):
|
|
@@ -74,10 +74,10 @@ class LSPGetDiagnosticsTool:
|
|
|
74
74
|
"stderr": "LSP initialization failed",
|
|
75
75
|
"stdout": ""
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
# 获取诊断信息
|
|
79
79
|
diagnostics = lsp.get_diagnostics(file_path)
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
# 如果没有诊断信息
|
|
82
82
|
if not diagnostics:
|
|
83
83
|
return {
|
|
@@ -85,31 +85,31 @@ class LSPGetDiagnosticsTool:
|
|
|
85
85
|
"stdout": "No issues found in the file",
|
|
86
86
|
"stderr": ""
|
|
87
87
|
}
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
# 格式化输出
|
|
90
90
|
output = ["Diagnostics:"]
|
|
91
91
|
# 严重程度映射
|
|
92
92
|
severity_map = {1: "Error", 2: "Warning", 3: "Info", 4: "Hint"}
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
# 按严重程度和行号排序诊断信息
|
|
95
95
|
sorted_diagnostics = sorted(
|
|
96
96
|
diagnostics,
|
|
97
97
|
key=lambda x: (x["severity"], x["range"]["start"]["line"])
|
|
98
98
|
)
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
# 处理每个诊断信息
|
|
101
101
|
for diag in sorted_diagnostics:
|
|
102
102
|
severity = severity_map.get(diag["severity"], "Unknown")
|
|
103
103
|
start = diag["range"]["start"]
|
|
104
104
|
line = LSPRegistry.get_line_at_position(file_path, start["line"]).strip()
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
output.extend([
|
|
107
107
|
f"\n{severity} at line {start['line'] + 1}, column {start['character'] + 1}:",
|
|
108
108
|
f"Message: {diag['message']}",
|
|
109
109
|
f"Code: {line}",
|
|
110
110
|
"-" * 60
|
|
111
111
|
])
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
# 处理相关附加信息
|
|
114
114
|
if diag.get("relatedInformation"):
|
|
115
115
|
output.append("Related information:")
|
|
@@ -123,13 +123,13 @@ class LSPGetDiagnosticsTool:
|
|
|
123
123
|
f" at {info['location']['uri']}:{info['location']['range']['start']['line'] + 1}",
|
|
124
124
|
f" {info_line}"
|
|
125
125
|
])
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
return {
|
|
128
128
|
"success": True,
|
|
129
129
|
"stdout": "\n".join(output),
|
|
130
130
|
"stderr": ""
|
|
131
131
|
}
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
except Exception as e:
|
|
134
134
|
return {
|
|
135
135
|
"success": False,
|