jarvis-ai-assistant 0.1.129__py3-none-any.whl → 0.1.131__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 +41 -27
- jarvis/jarvis_agent/builtin_input_handler.py +73 -0
- jarvis/{jarvis_code_agent → jarvis_agent}/file_input_handler.py +1 -1
- jarvis/jarvis_agent/main.py +1 -1
- jarvis/jarvis_agent/patch.py +461 -0
- jarvis/{jarvis_code_agent → jarvis_agent}/shell_input_handler.py +0 -1
- jarvis/jarvis_code_agent/code_agent.py +94 -89
- jarvis/jarvis_codebase/main.py +5 -5
- jarvis/jarvis_dev/main.py +833 -741
- jarvis/jarvis_git_squash/main.py +1 -1
- jarvis/jarvis_lsp/base.py +2 -26
- jarvis/jarvis_lsp/cpp.py +2 -14
- jarvis/jarvis_lsp/go.py +0 -13
- jarvis/jarvis_lsp/python.py +1 -30
- jarvis/jarvis_lsp/registry.py +10 -14
- jarvis/jarvis_lsp/rust.py +0 -12
- jarvis/jarvis_multi_agent/__init__.py +63 -53
- jarvis/jarvis_platform/registry.py +1 -2
- jarvis/jarvis_platform_manager/main.py +3 -3
- jarvis/jarvis_rag/main.py +1 -1
- jarvis/jarvis_tools/ask_codebase.py +40 -20
- jarvis/jarvis_tools/code_review.py +180 -143
- jarvis/jarvis_tools/create_code_agent.py +76 -72
- jarvis/jarvis_tools/create_sub_agent.py +31 -21
- jarvis/jarvis_tools/execute_shell.py +2 -2
- jarvis/jarvis_tools/execute_shell_script.py +1 -1
- jarvis/jarvis_tools/file_operation.py +2 -2
- jarvis/jarvis_tools/git_commiter.py +88 -68
- jarvis/jarvis_tools/lsp_find_definition.py +83 -67
- jarvis/jarvis_tools/lsp_find_references.py +62 -46
- jarvis/jarvis_tools/lsp_get_diagnostics.py +90 -74
- jarvis/jarvis_tools/methodology.py +3 -3
- jarvis/jarvis_tools/read_code.py +2 -2
- jarvis/jarvis_tools/search_web.py +18 -20
- jarvis/jarvis_tools/tool_generator.py +1 -1
- jarvis/jarvis_tools/treesitter_analyzer.py +331 -0
- jarvis/jarvis_treesitter/README.md +104 -0
- jarvis/jarvis_treesitter/__init__.py +20 -0
- jarvis/jarvis_treesitter/database.py +258 -0
- jarvis/jarvis_treesitter/example.py +115 -0
- jarvis/jarvis_treesitter/grammar_builder.py +182 -0
- jarvis/jarvis_treesitter/language.py +117 -0
- jarvis/jarvis_treesitter/symbol.py +31 -0
- jarvis/jarvis_treesitter/tools_usage.md +121 -0
- jarvis/jarvis_utils/git_utils.py +10 -2
- jarvis/jarvis_utils/input.py +3 -1
- jarvis/jarvis_utils/methodology.py +1 -1
- jarvis/jarvis_utils/output.py +2 -2
- jarvis/jarvis_utils/utils.py +3 -3
- {jarvis_ai_assistant-0.1.129.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/METADATA +2 -4
- jarvis_ai_assistant-0.1.131.dist-info/RECORD +85 -0
- jarvis/jarvis_code_agent/builtin_input_handler.py +0 -43
- jarvis/jarvis_code_agent/patch.py +0 -276
- jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -87
- jarvis/jarvis_tools/lsp_prepare_rename.py +0 -130
- jarvis_ai_assistant-0.1.129.dist-info/RECORD +0 -78
- {jarvis_ai_assistant-0.1.129.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.129.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.129.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.129.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/top_level.txt +0 -0
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
from typing import Dict, Any, Tuple
|
|
3
|
-
import os
|
|
4
|
-
|
|
5
|
-
from yaspin import yaspin
|
|
6
|
-
|
|
7
|
-
from jarvis.jarvis_agent.output_handler import OutputHandler
|
|
8
|
-
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
9
|
-
from jarvis.jarvis_tools.git_commiter import GitCommitTool
|
|
10
|
-
from jarvis.jarvis_tools.execute_shell_script import ShellScriptTool
|
|
11
|
-
from jarvis.jarvis_tools.file_operation import FileOperationTool
|
|
12
|
-
from jarvis.jarvis_tools.read_code import ReadCodeTool
|
|
13
|
-
from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
|
|
14
|
-
from jarvis.jarvis_utils.git_utils import get_commits_between, get_latest_commit_hash
|
|
15
|
-
from jarvis.jarvis_utils.input import get_multiline_input
|
|
16
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
17
|
-
from jarvis.jarvis_utils.utils import user_confirm
|
|
18
|
-
|
|
19
|
-
class PatchOutputHandler(OutputHandler):
|
|
20
|
-
def name(self) -> str:
|
|
21
|
-
return "PATCH"
|
|
22
|
-
def handle(self, response: str) -> Tuple[bool, Any]:
|
|
23
|
-
return False, apply_patch(response)
|
|
24
|
-
|
|
25
|
-
def can_handle(self, response: str) -> bool:
|
|
26
|
-
if _parse_patch(response):
|
|
27
|
-
return True
|
|
28
|
-
return False
|
|
29
|
-
|
|
30
|
-
def prompt(self) -> str:
|
|
31
|
-
return """
|
|
32
|
-
# 🛠️ 上下文代码补丁规范
|
|
33
|
-
使用<PATCH>块来指定代码更改:
|
|
34
|
-
--------------------------------
|
|
35
|
-
<PATCH>
|
|
36
|
-
File: [文件路径]
|
|
37
|
-
Reason: [修改原因]
|
|
38
|
-
[上下文代码片段]
|
|
39
|
-
</PATCH>
|
|
40
|
-
--------------------------------
|
|
41
|
-
规则:
|
|
42
|
-
1. 代码片段必须包含足够的上下文(前后各3行)
|
|
43
|
-
2. 我可以看到完整代码,所以只需显示修改的代码部分,不需要将整个文件内容都显示出来
|
|
44
|
-
3. 保留原始缩进和格式
|
|
45
|
-
4. 对于新文件,提供完整代码
|
|
46
|
-
5. 修改现有文件时,保留周围未更改的代码
|
|
47
|
-
示例:
|
|
48
|
-
<PATCH>
|
|
49
|
-
File: src/utils/math.py
|
|
50
|
-
Reason: 修复除零处理
|
|
51
|
-
def safe_divide(a, b):
|
|
52
|
-
# 添加参数验证
|
|
53
|
-
if b == 0:
|
|
54
|
-
raise ValueError("除数不能为零")
|
|
55
|
-
return a / b
|
|
56
|
-
# 现有代码 ...
|
|
57
|
-
def add(a, b):
|
|
58
|
-
return a + b
|
|
59
|
-
</PATCH>
|
|
60
|
-
"""
|
|
61
|
-
|
|
62
|
-
def _parse_patch(patch_str: str) -> Dict[str, str]:
|
|
63
|
-
"""解析新的上下文补丁格式"""
|
|
64
|
-
result = {}
|
|
65
|
-
patches = re.findall(r'<PATCH>\n?(.*?)\n?</PATCH>', patch_str, re.DOTALL)
|
|
66
|
-
if patches:
|
|
67
|
-
for patch in patches:
|
|
68
|
-
first_line = patch.splitlines()[0]
|
|
69
|
-
sm = re.match(r'^File:\s*(.+)$', first_line)
|
|
70
|
-
if not sm:
|
|
71
|
-
PrettyOutput.print("无效的补丁格式", OutputType.WARNING)
|
|
72
|
-
continue
|
|
73
|
-
filepath = sm.group(1).strip()
|
|
74
|
-
result[filepath] = patch
|
|
75
|
-
return result
|
|
76
|
-
|
|
77
|
-
def apply_patch(output_str: str) -> str:
|
|
78
|
-
"""Apply patches to files"""
|
|
79
|
-
with yaspin(text="正在应用补丁...", color="cyan") as spinner:
|
|
80
|
-
try:
|
|
81
|
-
patches = _parse_patch(output_str)
|
|
82
|
-
except Exception as e:
|
|
83
|
-
PrettyOutput.print(f"解析补丁失败: {str(e)}", OutputType.ERROR)
|
|
84
|
-
return ""
|
|
85
|
-
|
|
86
|
-
# 获取当前提交hash作为起始点
|
|
87
|
-
spinner.text= "开始获取当前提交hash..."
|
|
88
|
-
start_hash = get_latest_commit_hash()
|
|
89
|
-
spinner.write("✅ 当前提交hash获取完成")
|
|
90
|
-
|
|
91
|
-
# 按文件逐个处理
|
|
92
|
-
for filepath, patch_content in patches.items():
|
|
93
|
-
try:
|
|
94
|
-
spinner.text = f"正在处理文件: {filepath}"
|
|
95
|
-
with spinner.hidden():
|
|
96
|
-
handle_code_operation(filepath, patch_content)
|
|
97
|
-
spinner.write(f"✅ 文件 {filepath} 处理完成")
|
|
98
|
-
except Exception as e:
|
|
99
|
-
spinner.text = f"文件 {filepath} 处理失败: {str(e)}, 回滚文件"
|
|
100
|
-
revert_file(filepath) # 回滚单个文件
|
|
101
|
-
spinner.write(f"✅ 文件 {filepath} 回滚完成")
|
|
102
|
-
|
|
103
|
-
final_ret = ""
|
|
104
|
-
diff = get_diff()
|
|
105
|
-
if diff:
|
|
106
|
-
PrettyOutput.print(diff, OutputType.CODE, lang="diff")
|
|
107
|
-
with spinner.hidden():
|
|
108
|
-
commited = handle_commit_workflow()
|
|
109
|
-
if commited:
|
|
110
|
-
# 获取提交信息
|
|
111
|
-
end_hash = get_latest_commit_hash()
|
|
112
|
-
commits = get_commits_between(start_hash, end_hash)
|
|
113
|
-
|
|
114
|
-
# 添加提交信息到final_ret
|
|
115
|
-
if commits:
|
|
116
|
-
final_ret += "✅ 补丁已应用\n"
|
|
117
|
-
final_ret += "提交信息:\n"
|
|
118
|
-
for commit_hash, commit_message in commits:
|
|
119
|
-
final_ret += f"- {commit_hash[:7]}: {commit_message}\n"
|
|
120
|
-
|
|
121
|
-
final_ret += f"应用补丁:\n{diff}"
|
|
122
|
-
|
|
123
|
-
else:
|
|
124
|
-
final_ret += "✅ 补丁已应用(没有新的提交)"
|
|
125
|
-
else:
|
|
126
|
-
final_ret += "❌ 我不想提交代码\n"
|
|
127
|
-
final_ret += "补丁预览:\n"
|
|
128
|
-
final_ret += diff
|
|
129
|
-
else:
|
|
130
|
-
final_ret += "❌ 没有要提交的更改\n"
|
|
131
|
-
# 用户确认最终结果
|
|
132
|
-
PrettyOutput.print(final_ret, OutputType.USER)
|
|
133
|
-
if not is_confirm_before_apply_patch() or user_confirm("是否使用此回复?", default=True):
|
|
134
|
-
return final_ret
|
|
135
|
-
return get_multiline_input("请输入自定义回复")
|
|
136
|
-
def revert_file(filepath: str):
|
|
137
|
-
"""增强版git恢复,处理新文件"""
|
|
138
|
-
import subprocess
|
|
139
|
-
try:
|
|
140
|
-
# 检查文件是否在版本控制中
|
|
141
|
-
result = subprocess.run(
|
|
142
|
-
['git', 'ls-files', '--error-unmatch', filepath],
|
|
143
|
-
stderr=subprocess.PIPE
|
|
144
|
-
)
|
|
145
|
-
if result.returncode == 0:
|
|
146
|
-
subprocess.run(['git', 'checkout', 'HEAD', '--', filepath], check=True)
|
|
147
|
-
else:
|
|
148
|
-
if os.path.exists(filepath):
|
|
149
|
-
os.remove(filepath)
|
|
150
|
-
subprocess.run(['git', 'clean', '-f', '--', filepath], check=True)
|
|
151
|
-
except subprocess.CalledProcessError as e:
|
|
152
|
-
PrettyOutput.print(f"恢复文件失败: {str(e)}", OutputType.ERROR)
|
|
153
|
-
# 修改后的恢复函数
|
|
154
|
-
def revert_change():
|
|
155
|
-
import subprocess
|
|
156
|
-
subprocess.run(['git', 'reset', '--hard', 'HEAD'], check=True)
|
|
157
|
-
subprocess.run(['git', 'clean', '-fd'], check=True)
|
|
158
|
-
# 修改后的获取差异函数
|
|
159
|
-
def get_diff() -> str:
|
|
160
|
-
"""使用git获取暂存区差异"""
|
|
161
|
-
import subprocess
|
|
162
|
-
try:
|
|
163
|
-
subprocess.run(['git', 'add', '.'], check=True)
|
|
164
|
-
result = subprocess.run(
|
|
165
|
-
['git', 'diff', '--cached'],
|
|
166
|
-
capture_output=True,
|
|
167
|
-
text=True,
|
|
168
|
-
check=True
|
|
169
|
-
)
|
|
170
|
-
ret = result.stdout
|
|
171
|
-
subprocess.run(['git', "reset", "--soft", "HEAD"], check=True)
|
|
172
|
-
return ret
|
|
173
|
-
except subprocess.CalledProcessError as e:
|
|
174
|
-
return f"获取差异失败: {str(e)}"
|
|
175
|
-
def handle_commit_workflow()->bool:
|
|
176
|
-
"""Handle the git commit workflow and return the commit details.
|
|
177
|
-
|
|
178
|
-
Returns:
|
|
179
|
-
tuple[bool, str, str]: (continue_execution, commit_id, commit_message)
|
|
180
|
-
"""
|
|
181
|
-
if is_confirm_before_apply_patch() and not user_confirm("是否要提交代码?", default=True):
|
|
182
|
-
revert_change()
|
|
183
|
-
return False
|
|
184
|
-
git_commiter = GitCommitTool()
|
|
185
|
-
commit_result = git_commiter.execute({})
|
|
186
|
-
return commit_result["success"]
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def handle_code_operation(filepath: str, patch_content: str) -> bool:
|
|
190
|
-
"""处理基于上下文的代码片段"""
|
|
191
|
-
with yaspin(text=f"正在修改文件 {filepath}...", color="cyan") as spinner:
|
|
192
|
-
try:
|
|
193
|
-
if not os.path.exists(filepath):
|
|
194
|
-
# 新建文件
|
|
195
|
-
spinner.text = "文件不存在,正在创建文件..."
|
|
196
|
-
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
|
197
|
-
open(filepath, 'w', encoding='utf-8').close()
|
|
198
|
-
spinner.write("✅ 文件创建完成")
|
|
199
|
-
with spinner.hidden():
|
|
200
|
-
old_file_content = FileOperationTool().execute({"operation": "read", "files": [{"path": filepath}]})
|
|
201
|
-
if not old_file_content["success"]:
|
|
202
|
-
spinner.write("❌ 文件读取失败")
|
|
203
|
-
return False
|
|
204
|
-
|
|
205
|
-
prompt = f"""
|
|
206
|
-
你是一个代码审查员,请审查以下代码并将其与上下文合并。
|
|
207
|
-
原始代码:
|
|
208
|
-
{old_file_content["stdout"]}
|
|
209
|
-
补丁内容:
|
|
210
|
-
{patch_content}
|
|
211
|
-
"""
|
|
212
|
-
prompt += f"""
|
|
213
|
-
请将代码与上下文合并并返回完整的合并代码,每次最多输出300行代码。
|
|
214
|
-
|
|
215
|
-
要求:
|
|
216
|
-
1. 严格保留原始代码的格式、空行和缩进
|
|
217
|
-
2. 仅在<MERGED_CODE>块中包含实际代码内容,包括空行和缩进
|
|
218
|
-
3. 绝对不要使用markdown代码块(```)或反引号,除非修改的是markdown文件
|
|
219
|
-
4. 除了合并后的代码,不要输出任何其他文本
|
|
220
|
-
5. 所有代码输出完成后,输出<!!!FINISHED!!!>
|
|
221
|
-
|
|
222
|
-
输出格式:
|
|
223
|
-
<MERGED_CODE>
|
|
224
|
-
[merged_code]
|
|
225
|
-
</MERGED_CODE>
|
|
226
|
-
"""
|
|
227
|
-
model = PlatformRegistry().get_codegen_platform()
|
|
228
|
-
model.set_suppress_output(True)
|
|
229
|
-
count = 30
|
|
230
|
-
start_line = -1
|
|
231
|
-
end_line = -1
|
|
232
|
-
code = []
|
|
233
|
-
finished = False
|
|
234
|
-
while count>0:
|
|
235
|
-
count -= 1
|
|
236
|
-
response = model.chat_until_success(prompt).splitlines()
|
|
237
|
-
try:
|
|
238
|
-
start_line = response.index("<MERGED_CODE>") + 1
|
|
239
|
-
try:
|
|
240
|
-
end_line = response.index("</MERGED_CODE>")
|
|
241
|
-
code = response[start_line:end_line]
|
|
242
|
-
except:
|
|
243
|
-
pass
|
|
244
|
-
except:
|
|
245
|
-
pass
|
|
246
|
-
|
|
247
|
-
try:
|
|
248
|
-
response.index("<!!!FINISHED!!!>")
|
|
249
|
-
finished = True
|
|
250
|
-
break
|
|
251
|
-
except:
|
|
252
|
-
prompt += f"""继续输出接下来的300行代码
|
|
253
|
-
要求:
|
|
254
|
-
1. 严格保留原始代码的格式、空行和缩进
|
|
255
|
-
2. 仅在<MERGED_CODE>块中包含实际代码内容,包括空行和缩进
|
|
256
|
-
3. 绝对不要使用markdown代码块(```)或反引号,除非修改的是markdown文件
|
|
257
|
-
4. 除了合并后的代码,不要输出任何其他文本
|
|
258
|
-
5. 所有代码输出完成后,输出<!!!FINISHED!!!>
|
|
259
|
-
"""
|
|
260
|
-
pass
|
|
261
|
-
if not finished:
|
|
262
|
-
spinner.text = "生成代码失败"
|
|
263
|
-
spinner.fail("❌")
|
|
264
|
-
return False
|
|
265
|
-
# 写入合并后的代码
|
|
266
|
-
spinner.text = "写入合并后的代码..."
|
|
267
|
-
with open(filepath, 'w', encoding='utf-8') as f:
|
|
268
|
-
f.write("\n".join(code)+"\n")
|
|
269
|
-
spinner.write("✅ 合并后的代码写入完成")
|
|
270
|
-
spinner.text = "代码修改完成"
|
|
271
|
-
spinner.ok("✅")
|
|
272
|
-
return True
|
|
273
|
-
except Exception as e:
|
|
274
|
-
spinner.text = "代码修改失败"
|
|
275
|
-
spinner.fail("❌")
|
|
276
|
-
return False
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Dict, Any
|
|
3
|
-
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
|
-
|
|
5
|
-
class LSPGetDocumentSymbolsTool:
|
|
6
|
-
"""Tool for getting document symbols in code files using LSP."""
|
|
7
|
-
|
|
8
|
-
name = "lsp_get_document_symbols"
|
|
9
|
-
description = "Get document symbols (functions, classes, variables) in code files"
|
|
10
|
-
parameters = {
|
|
11
|
-
"file_path": "Path to the file to analyze",
|
|
12
|
-
"language": f"Programming language of the file ({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
@staticmethod
|
|
16
|
-
def check() -> bool:
|
|
17
|
-
"""Check if any LSP server is available."""
|
|
18
|
-
registry = LSPRegistry.get_global_lsp_registry()
|
|
19
|
-
return len(registry.get_supported_languages()) > 0
|
|
20
|
-
|
|
21
|
-
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
22
|
-
"""Execute the tool."""
|
|
23
|
-
file_path = args.get("file_path", "")
|
|
24
|
-
language = args.get("language", "")
|
|
25
|
-
|
|
26
|
-
if not file_path or not language:
|
|
27
|
-
return {
|
|
28
|
-
"success": False,
|
|
29
|
-
"stderr": "Both file_path and language must be provided",
|
|
30
|
-
"stdout": ""
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if not os.path.exists(file_path):
|
|
34
|
-
return {
|
|
35
|
-
"success": False,
|
|
36
|
-
"stderr": f"File not found: {file_path}",
|
|
37
|
-
"stdout": ""
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
# Get LSP instance
|
|
41
|
-
registry = LSPRegistry.get_global_lsp_registry()
|
|
42
|
-
lsp = registry.create_lsp(language)
|
|
43
|
-
|
|
44
|
-
if not lsp:
|
|
45
|
-
return {
|
|
46
|
-
"success": False,
|
|
47
|
-
"stderr": f"No LSP support for language: {language}",
|
|
48
|
-
"stdout": ""
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
try:
|
|
52
|
-
# Initialize LSP
|
|
53
|
-
if not lsp.initialize(os.path.abspath(os.getcwd())):
|
|
54
|
-
return {
|
|
55
|
-
"success": False,
|
|
56
|
-
"stderr": "LSP initialization failed",
|
|
57
|
-
"stdout": ""
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
# Get symbols
|
|
61
|
-
symbols = lsp.get_document_symbols(file_path)
|
|
62
|
-
|
|
63
|
-
# Format output
|
|
64
|
-
output = []
|
|
65
|
-
for symbol in symbols:
|
|
66
|
-
start = symbol["range"]["start"]
|
|
67
|
-
name = LSPRegistry.get_text_at_position(file_path, start["line"], start["character"])
|
|
68
|
-
line = LSPRegistry.get_line_at_position(file_path, start["line"]).strip()
|
|
69
|
-
output.append(f"Symbol: {name}")
|
|
70
|
-
output.append(f"Line {start['line'] + 1}: {line}")
|
|
71
|
-
output.append("-" * 40)
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
"success": True,
|
|
75
|
-
"stdout": "\n".join(output) if output else "No symbols found",
|
|
76
|
-
"stderr": ""
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
except Exception as e:
|
|
80
|
-
return {
|
|
81
|
-
"success": False,
|
|
82
|
-
"stderr": f"Error finding symbols: {str(e)}",
|
|
83
|
-
"stdout": ""
|
|
84
|
-
}
|
|
85
|
-
finally:
|
|
86
|
-
if lsp:
|
|
87
|
-
lsp.shutdown()
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Dict, Any
|
|
3
|
-
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
|
-
|
|
5
|
-
class LSPPrepareRenameTool:
|
|
6
|
-
"""使用LSP检查符号是否可以安全重命名并显示所有受影响位置的工具"""
|
|
7
|
-
|
|
8
|
-
name = "lsp_prepare_rename"
|
|
9
|
-
description = "检查符号是否可以安全重命名,并显示所有受影响的位置"
|
|
10
|
-
parameters = {
|
|
11
|
-
"file_path": "包含符号的文件路径",
|
|
12
|
-
"line": "符号所在的行号(从0开始)",
|
|
13
|
-
"character": "符号在行中的字符位置",
|
|
14
|
-
"language": f"文件的编程语言({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@staticmethod
|
|
18
|
-
def check() -> bool:
|
|
19
|
-
"""Check if any LSP server is available."""
|
|
20
|
-
registry = LSPRegistry.get_global_lsp_registry()
|
|
21
|
-
return len(registry.get_supported_languages()) > 0
|
|
22
|
-
|
|
23
|
-
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
24
|
-
"""Execute the tool."""
|
|
25
|
-
file_path = args.get("file_path", "")
|
|
26
|
-
line = args.get("line", None)
|
|
27
|
-
character = args.get("character", None)
|
|
28
|
-
language = args.get("language", "")
|
|
29
|
-
|
|
30
|
-
# Validate inputs
|
|
31
|
-
if not all([file_path, line is not None, character is not None, language]):
|
|
32
|
-
return {
|
|
33
|
-
"success": False,
|
|
34
|
-
"stderr": "All parameters (file_path, line, character, language) must be provided",
|
|
35
|
-
"stdout": ""
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
try:
|
|
39
|
-
line = int(line)
|
|
40
|
-
character = int(character)
|
|
41
|
-
except ValueError:
|
|
42
|
-
return {
|
|
43
|
-
"success": False,
|
|
44
|
-
"stderr": "Line and character must be integers",
|
|
45
|
-
"stdout": ""
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if not os.path.exists(file_path):
|
|
49
|
-
return {
|
|
50
|
-
"success": False,
|
|
51
|
-
"stderr": f"File not found: {file_path}",
|
|
52
|
-
"stdout": ""
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
# Get LSP instance
|
|
56
|
-
registry = LSPRegistry.get_global_lsp_registry()
|
|
57
|
-
lsp = registry.create_lsp(language)
|
|
58
|
-
|
|
59
|
-
if not lsp:
|
|
60
|
-
return {
|
|
61
|
-
"success": False,
|
|
62
|
-
"stderr": f"No LSP support for language: {language}",
|
|
63
|
-
"stdout": ""
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
try:
|
|
67
|
-
# Initialize LSP
|
|
68
|
-
if not lsp.initialize(os.path.abspath(os.getcwd())):
|
|
69
|
-
return {
|
|
70
|
-
"success": False,
|
|
71
|
-
"stderr": "LSP initialization failed",
|
|
72
|
-
"stdout": ""
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
# Get symbol at position
|
|
76
|
-
symbol = LSPRegistry.get_text_at_position(file_path, line, character)
|
|
77
|
-
if not symbol:
|
|
78
|
-
return {
|
|
79
|
-
"success": False,
|
|
80
|
-
"stderr": f"No symbol found at position {line}:{character}",
|
|
81
|
-
"stdout": ""
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
# Check if rename is possible
|
|
85
|
-
rename_info = lsp.prepare_rename(file_path, (line, character))
|
|
86
|
-
if not rename_info:
|
|
87
|
-
return {
|
|
88
|
-
"success": True,
|
|
89
|
-
"stdout": f"Symbol '{symbol}' cannot be renamed. It might be:\n" +
|
|
90
|
-
"- A built-in or library symbol\n" +
|
|
91
|
-
"- A read-only symbol\n" +
|
|
92
|
-
"- Not a valid identifier",
|
|
93
|
-
"stderr": ""
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
# Get all references to show affected locations
|
|
97
|
-
refs = lsp.find_references(file_path, (line, character))
|
|
98
|
-
|
|
99
|
-
# Format output
|
|
100
|
-
output = [
|
|
101
|
-
f"Symbol '{symbol}' can be renamed.",
|
|
102
|
-
f"\nRenaming will affect the following locations:"
|
|
103
|
-
]
|
|
104
|
-
|
|
105
|
-
for ref in refs:
|
|
106
|
-
ref_line = ref["range"]["start"]["line"]
|
|
107
|
-
ref_char = ref["range"]["start"]["character"]
|
|
108
|
-
context = LSPRegistry.get_line_at_position(ref["uri"], ref_line).strip()
|
|
109
|
-
output.extend([
|
|
110
|
-
f"\nFile: {ref['uri']}",
|
|
111
|
-
f"Line {ref_line + 1}, Col {ref_char + 1}: {context}"
|
|
112
|
-
])
|
|
113
|
-
|
|
114
|
-
output.append("\nNote: Make sure to review all locations before performing the rename.")
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
"success": True,
|
|
118
|
-
"stdout": "\n".join(output),
|
|
119
|
-
"stderr": ""
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
except Exception as e:
|
|
123
|
-
return {
|
|
124
|
-
"success": False,
|
|
125
|
-
"stderr": f"Error checking rename possibility: {str(e)}",
|
|
126
|
-
"stdout": ""
|
|
127
|
-
}
|
|
128
|
-
finally:
|
|
129
|
-
if lsp:
|
|
130
|
-
lsp.shutdown()
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
jarvis/__init__.py,sha256=za4oKG0K-1ZuhjUPmJNltAW9-yWKxirJqtMEK3RpcwQ,51
|
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=4W0HYKKaDlAXrOIsvwNVsGOTHfbyQTgEpkXIJwRQM_4,22684
|
|
3
|
-
jarvis/jarvis_agent/main.py,sha256=PfuoMkLH-QsqOXUMpJYi9GB7ewx-Ub84b1GTxqV7UBo,2515
|
|
4
|
-
jarvis/jarvis_agent/output_handler.py,sha256=kJeFTjjSu0K_2p0wyhq2veSZuhRXoaFC_8wVaoBKX0w,401
|
|
5
|
-
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
jarvis/jarvis_code_agent/builtin_input_handler.py,sha256=HBza949NZyzZrbVlG31ITk5h0DD6MY_yjCieatvigd0,1366
|
|
7
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=A1mmswsCj3JT0l6iwZmIGzPUADODrVuUQJPOKiSeEYQ,8077
|
|
8
|
-
jarvis/jarvis_code_agent/file_input_handler.py,sha256=yooXbtWGziNzQKxM6xDyAmnJe4fKcD6kYakxKEJBAdw,3338
|
|
9
|
-
jarvis/jarvis_code_agent/file_select.py,sha256=2nSy1FW-kK-wvtz0YbbgSbd4ZwXMlA7sBP0nC80FzLI,8160
|
|
10
|
-
jarvis/jarvis_code_agent/patch.py,sha256=qwfpUgWcTzSrun7EWDkfbG1oiU5o_HdNUluSf20Nu1E,10898
|
|
11
|
-
jarvis/jarvis_code_agent/shell_input_handler.py,sha256=LTXKHNbqTKf5S2kXU255iBx_e-EsDTRaZ0aokFWkUU4,1075
|
|
12
|
-
jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
jarvis/jarvis_codebase/main.py,sha256=KSNf2RoPDn_jnfjUA5Sry7sh7iJ9Q267Z8k4dsQANRM,41325
|
|
14
|
-
jarvis/jarvis_dev/main.py,sha256=tDdv28nbcYlsy9wz1RbMNEModOdicNg4JfnBOYl4JnU,21414
|
|
15
|
-
jarvis/jarvis_git_squash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
jarvis/jarvis_git_squash/main.py,sha256=g4csaRDYH3n3MCHc8aZb2N4wWVCVZ-pIgd0oanXDnD8,2798
|
|
17
|
-
jarvis/jarvis_lsp/base.py,sha256=ceJBQoOU7JHsvQEAA3agUTedh7_ki_HgK0re7-V9rqg,4119
|
|
18
|
-
jarvis/jarvis_lsp/cpp.py,sha256=Fx2c57omtBQVWB2648TBXufAV2za-u9bF0oe4928pHU,4605
|
|
19
|
-
jarvis/jarvis_lsp/go.py,sha256=fgYBhZaiU2OQPAFQh4fBFOO--HKxkXcr8PEYyF_YlcE,4930
|
|
20
|
-
jarvis/jarvis_lsp/python.py,sha256=NYatk1rlah-bPnTKOn_BXwkYp0IsCUFYRGdLTVVYsCM,3708
|
|
21
|
-
jarvis/jarvis_lsp/registry.py,sha256=slD6p3FAMjL8pQx2id-RxX1pwMjP4FgyMsM3ZbckQJI,9884
|
|
22
|
-
jarvis/jarvis_lsp/rust.py,sha256=nV1EKtq5y57E47DbQlD2DsfvwFVE2JoUTs-9paxeyDo,5161
|
|
23
|
-
jarvis/jarvis_multi_agent/__init__.py,sha256=LpXq9baBg4Rp0m4dfL172UcNyijSx3yjyupz2CNhjKE,5687
|
|
24
|
-
jarvis/jarvis_platform/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
|
|
25
|
-
jarvis/jarvis_platform/ai8.py,sha256=xjgoiF7QHx_5FHj-npTFVvZFYg8RBzkqTGAOQ-MJiL0,11972
|
|
26
|
-
jarvis/jarvis_platform/base.py,sha256=2chHt0pMx4rr0OFTeDpZcVqFUxF_q4YslUt30E5Augk,3277
|
|
27
|
-
jarvis/jarvis_platform/kimi.py,sha256=Qwb81flbKPvj-qZyJAMS_u0lQatRFQztYxUGDbj1keM,15713
|
|
28
|
-
jarvis/jarvis_platform/ollama.py,sha256=NHQMJSpC91WtSFuHKJuwD8qO-z4yDTF9mZX6BzWTKRU,5658
|
|
29
|
-
jarvis/jarvis_platform/openai.py,sha256=GSxTB69WitXJS3pL0sxCoB2F0EVHmvhrwLBC_JT8s34,4470
|
|
30
|
-
jarvis/jarvis_platform/oyi.py,sha256=pa72TtBYlhs3KPpqO4Y78a1Jvx4mN0pojBklu8X3F-k,15024
|
|
31
|
-
jarvis/jarvis_platform/registry.py,sha256=DrL6ZoIX9ZKAvFgDadiWPpVnO9GdWJMcXM8dsoNR3ds,8559
|
|
32
|
-
jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
-
jarvis/jarvis_platform_manager/main.py,sha256=84j3voQDOVhvCqWxf-SGpdrYQPcf0pA5qUKe7b5oPUE,20898
|
|
34
|
-
jarvis/jarvis_platform_manager/openai_test.py,sha256=bkcVG6o2nNazj4zjkENgA4yOEzdTI9Qbm5dco-2MGYM,5190
|
|
35
|
-
jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
jarvis/jarvis_rag/main.py,sha256=yEvzQQZ4YQoOovQvH9MqQDbdnFw11bC_fyrNFo3QRq8,35873
|
|
37
|
-
jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
-
jarvis/jarvis_smart_shell/main.py,sha256=5gyBKgxuaTrDToE7Xy4DhsJPDOEviPi7ktm1vOZoIno,4618
|
|
39
|
-
jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
-
jarvis/jarvis_tools/ask_codebase.py,sha256=DyqOsVgVPefhGKC5L2bQqKj8KMFZE-PDgfdoHQ9ajH4,3300
|
|
41
|
-
jarvis/jarvis_tools/ask_user.py,sha256=kU6BOhFz_mKfqABd0l_00TL7Mqp_dhV3r0qkKLy8yRM,1745
|
|
42
|
-
jarvis/jarvis_tools/base.py,sha256=8gIgIx9LJAKOxdpPu7zMDItWqwXmXVTWAGfUkpQonzw,1196
|
|
43
|
-
jarvis/jarvis_tools/chdir.py,sha256=GLbH2fOKESUn3XYhNg0uOI5axTO2csC0B9HUL0bMZ5U,2790
|
|
44
|
-
jarvis/jarvis_tools/code_review.py,sha256=4TMsTehbIq3W-K-LvHjMwbaGtt66sbSM6nij30YsxlU,10039
|
|
45
|
-
jarvis/jarvis_tools/create_code_agent.py,sha256=lVnTP1Kq4q8aWOJ97YTf8POds-Hb3qeYS6MNOiM0wF4,3768
|
|
46
|
-
jarvis/jarvis_tools/create_sub_agent.py,sha256=lPiTXU0F8RZ-mEBB0ec9fdZ1UUtrpUQ2WoV8g-M5lHg,2774
|
|
47
|
-
jarvis/jarvis_tools/execute_shell.py,sha256=5LWWae8LKX4Qe3DIkSiLpcEvkCcF1ruvY0gbAIrT1Nw,3914
|
|
48
|
-
jarvis/jarvis_tools/execute_shell_script.py,sha256=JLs_4p3rXS_d0PdfS6lP_4ojFlD0SayAe0PNEGVfyzE,2030
|
|
49
|
-
jarvis/jarvis_tools/file_operation.py,sha256=3dcbugrzSaXHV7m98k1E_CpEIK2v4DYqZNZQim-fuxM,6973
|
|
50
|
-
jarvis/jarvis_tools/git_commiter.py,sha256=mjGturix6uP6HmqzqX8APJuofaLWGQ4-D6DOk8jj7WI,5533
|
|
51
|
-
jarvis/jarvis_tools/lsp_find_definition.py,sha256=LqAOf6W4_WZR2GmtQXb7pMSduJzK_g3ysaOrgxu8CDE,4755
|
|
52
|
-
jarvis/jarvis_tools/lsp_find_references.py,sha256=IR1QcRi-p4zHS0YENb7vDNMUSuGQUTA4W9bPa9-VO-Y,4028
|
|
53
|
-
jarvis/jarvis_tools/lsp_get_diagnostics.py,sha256=_u2lsSFY7GkOlyKD2CFnvEpkZzAjNfEUMsM9dKGQz40,4754
|
|
54
|
-
jarvis/jarvis_tools/lsp_get_document_symbols.py,sha256=c7_9jP1toe_kepaTmZf1R1jn-JZVCwr6_0ox-KRd8bo,3065
|
|
55
|
-
jarvis/jarvis_tools/lsp_prepare_rename.py,sha256=HIeJjup8luIH25XuLqTVdejWDT5vOn-IWSo-TKDFjZ4,4821
|
|
56
|
-
jarvis/jarvis_tools/methodology.py,sha256=jLYFji3hP7Gff7WFRuR-_VmPHI8Rqq0EGDIgackhqtc,5787
|
|
57
|
-
jarvis/jarvis_tools/rag.py,sha256=WuTlyGV5rgZTRxts9eJPC3QABrsoNYKratdO8UzUFDw,5132
|
|
58
|
-
jarvis/jarvis_tools/read_code.py,sha256=rHizUi2nh-bXp3BNtzuXLWSWDfevxNTjrML2Xu1Y8EA,5382
|
|
59
|
-
jarvis/jarvis_tools/read_webpage.py,sha256=TkVNgirvcjns8-MHaDXOmliOKWCYcq3WzcbVXBi0IxY,4173
|
|
60
|
-
jarvis/jarvis_tools/registry.py,sha256=pYyjdyjYgvHfdglhp0I7YXfVIV8_jTSncoSgIG6HFUw,13719
|
|
61
|
-
jarvis/jarvis_tools/search_web.py,sha256=yzu2EP63It2but0LFUR0x1hlCkyTyr1AwY4APvxmniE,12903
|
|
62
|
-
jarvis/jarvis_tools/select_code_files.py,sha256=xCqHTjIGju9Pb1Yh2C1Y7l6uT_3pfVB6ARU0VQmeRNI,1879
|
|
63
|
-
jarvis/jarvis_tools/tool_generator.py,sha256=rBx5PsXJDQRkWfZFHiHon6q0KsU8kPYHmPCQ6yRi_cU,7722
|
|
64
|
-
jarvis/jarvis_utils/__init__.py,sha256=THxqKNkLvhnuoZRSQHCJ2-0epoZRrtrekJPQ3savarM,824
|
|
65
|
-
jarvis/jarvis_utils/config.py,sha256=j1Hqqluxo7W6BUpScjBtKUJpYKRw-DU0qlQSa8vvUtQ,4999
|
|
66
|
-
jarvis/jarvis_utils/embedding.py,sha256=vaY4lTE9Yw0joQVWTX1FxV0ZnnOz6W9vjQE1NASzXIk,6110
|
|
67
|
-
jarvis/jarvis_utils/git_utils.py,sha256=wU2CPmRP4cUnm5Omz1-a7l4HYML-dYZAZ5bwNrLoQH8,4467
|
|
68
|
-
jarvis/jarvis_utils/globals.py,sha256=nvykWxBnqfAFqAIyJfxP5Y1yYIXIQXjippVE5i2Bubg,2269
|
|
69
|
-
jarvis/jarvis_utils/input.py,sha256=_PjnmRFWoe2dSxY6nBaKZoMkFLkkMJsDjXybiASYLek,6466
|
|
70
|
-
jarvis/jarvis_utils/methodology.py,sha256=915rbvNbrOAJHBRUFq_h06BC_lA2eezCtBmZMbIk0B0,6351
|
|
71
|
-
jarvis/jarvis_utils/output.py,sha256=eboIP02NAFVFntP51hqMKGUOCUEAjs0e0VLkmJgGfOo,8335
|
|
72
|
-
jarvis/jarvis_utils/utils.py,sha256=DfnCwgPfQpX5DZz9WGbXkWoDYrB7qnVmA6JVPoFnBuk,5564
|
|
73
|
-
jarvis_ai_assistant-0.1.129.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
74
|
-
jarvis_ai_assistant-0.1.129.dist-info/METADATA,sha256=fJjo3cbS48iGf5QBtlUR1WVelXtpwbpMeoag7y-vD3U,10519
|
|
75
|
-
jarvis_ai_assistant-0.1.129.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
76
|
-
jarvis_ai_assistant-0.1.129.dist-info/entry_points.txt,sha256=npKEpBACgZAF97wZgHSJNnturrh9DP33usD0kzjMXPo,771
|
|
77
|
-
jarvis_ai_assistant-0.1.129.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
78
|
-
jarvis_ai_assistant-0.1.129.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.129.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.129.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/top_level.txt
RENAMED
|
File without changes
|