jarvis-ai-assistant 0.1.104__py3-none-any.whl → 0.1.106__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/agent.py +124 -67
- jarvis/jarvis_code_agent/code_agent.py +133 -22
- jarvis/jarvis_code_agent/patch.py +4 -7
- jarvis/jarvis_code_agent/relevant_files.py +163 -72
- jarvis/jarvis_codebase/main.py +36 -15
- jarvis/jarvis_lsp/base.py +143 -0
- jarvis/jarvis_lsp/cpp.py +134 -0
- jarvis/jarvis_lsp/go.py +140 -0
- jarvis/jarvis_lsp/python.py +135 -0
- jarvis/jarvis_lsp/registry.py +234 -0
- jarvis/jarvis_lsp/rust.py +142 -0
- jarvis/jarvis_platform/__init__.py +3 -0
- jarvis/{models → jarvis_platform}/ai8.py +1 -1
- jarvis/{models → jarvis_platform}/kimi.py +1 -1
- jarvis/{models → jarvis_platform}/ollama.py +1 -1
- jarvis/{models → jarvis_platform}/openai.py +1 -1
- jarvis/{models → jarvis_platform}/oyi.py +1 -1
- jarvis/{models → jarvis_platform}/registry.py +11 -11
- jarvis/{jarvis_platform → jarvis_platform_manager}/main.py +1 -1
- jarvis/jarvis_rag/main.py +6 -6
- jarvis/jarvis_smart_shell/main.py +3 -3
- jarvis/jarvis_tools/__init__.py +0 -0
- jarvis/{tools → jarvis_tools}/ask_user.py +1 -1
- jarvis/{tools → jarvis_tools}/code_review.py +34 -8
- jarvis/jarvis_tools/create_code_agent.py +115 -0
- jarvis/{tools → jarvis_tools}/create_sub_agent.py +1 -1
- jarvis/jarvis_tools/deep_thinking.py +160 -0
- jarvis/jarvis_tools/deep_thinking_agent.py +146 -0
- jarvis/{tools → jarvis_tools}/git_commiter.py +2 -2
- jarvis/jarvis_tools/lsp_find_definition.py +134 -0
- jarvis/jarvis_tools/lsp_find_references.py +111 -0
- jarvis/jarvis_tools/lsp_get_diagnostics.py +121 -0
- jarvis/jarvis_tools/lsp_get_document_symbols.py +87 -0
- jarvis/jarvis_tools/lsp_prepare_rename.py +130 -0
- jarvis/jarvis_tools/lsp_validate_edit.py +141 -0
- jarvis/{tools → jarvis_tools}/methodology.py +6 -1
- jarvis/{tools → jarvis_tools}/registry.py +6 -5
- jarvis/{tools → jarvis_tools}/search.py +2 -2
- jarvis/utils.py +68 -25
- {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.106.dist-info}/METADATA +23 -16
- jarvis_ai_assistant-0.1.106.dist-info/RECORD +62 -0
- {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.106.dist-info}/entry_points.txt +3 -4
- jarvis/models/__init__.py +0 -3
- jarvis/tools/create_code_test_agent.py +0 -115
- jarvis/tools/create_ctags_agent.py +0 -164
- jarvis/tools/find_in_codebase.py +0 -78
- jarvis_ai_assistant-0.1.104.dist-info/RECORD +0 -50
- /jarvis/{models → jarvis_platform}/base.py +0 -0
- /jarvis/{tools → jarvis_platform_manager}/__init__.py +0 -0
- /jarvis/{tools → jarvis_tools}/ask_codebase.py +0 -0
- /jarvis/{tools → jarvis_tools}/base.py +0 -0
- /jarvis/{tools → jarvis_tools}/chdir.py +0 -0
- /jarvis/{tools → jarvis_tools}/execute_shell.py +0 -0
- /jarvis/{tools → jarvis_tools}/file_operation.py +0 -0
- /jarvis/{tools → jarvis_tools}/rag.py +0 -0
- /jarvis/{tools → jarvis_tools}/read_code.py +0 -0
- /jarvis/{tools → jarvis_tools}/read_webpage.py +0 -0
- /jarvis/{tools → jarvis_tools}/select_code_files.py +0 -0
- {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.106.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.106.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.106.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
from jarvis.agent import Agent
|
|
4
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
5
|
+
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
6
|
+
from jarvis.utils import OutputType, PrettyOutput
|
|
7
|
+
|
|
8
|
+
class DeepThinkingAgentTool:
|
|
9
|
+
"""Tool for deep thinking using an agent with thinking platform."""
|
|
10
|
+
|
|
11
|
+
name = "deep_thinking_agent"
|
|
12
|
+
description = "Use an agent to think deeply about problems and solutions"
|
|
13
|
+
parameters = {
|
|
14
|
+
"question": "The question or problem to think about"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
18
|
+
try:
|
|
19
|
+
question = args.get("question", "")
|
|
20
|
+
if not question:
|
|
21
|
+
return {
|
|
22
|
+
"success": False,
|
|
23
|
+
"stderr": "Question must be provided",
|
|
24
|
+
"stdout": ""
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Initialize tool registry
|
|
28
|
+
tool_registry = ToolRegistry()
|
|
29
|
+
tool_registry.dont_use_tools([
|
|
30
|
+
"deep_thinking_agent"
|
|
31
|
+
])
|
|
32
|
+
|
|
33
|
+
# Define system prompt for thinking agent
|
|
34
|
+
system_prompt = """You are a deep thinking agent that carefully analyzes problems and proposes solutions.
|
|
35
|
+
|
|
36
|
+
THINKING PROCESS:
|
|
37
|
+
1. Initial Analysis
|
|
38
|
+
```
|
|
39
|
+
Thought: Let me first understand the core problem...
|
|
40
|
+
Action: Use deep_thinking with mode=analysis
|
|
41
|
+
Observation: The analysis shows...
|
|
42
|
+
|
|
43
|
+
Thought: I need more information about...
|
|
44
|
+
Action: Use appropriate tool (search/ask_user/ask_codebase)
|
|
45
|
+
Observation: Found that...
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
2. Solution Exploration
|
|
49
|
+
```
|
|
50
|
+
Thought: Let me explore possible solutions...
|
|
51
|
+
Action: Use deep_thinking with mode=solution
|
|
52
|
+
Observation: The potential solutions are...
|
|
53
|
+
|
|
54
|
+
Thought: I should validate these approaches...
|
|
55
|
+
Action: Use appropriate tool to verify
|
|
56
|
+
Observation: Verification shows...
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
3. Critical Review
|
|
60
|
+
```
|
|
61
|
+
Thought: Let me critique the proposed solution...
|
|
62
|
+
Action: Use deep_thinking with mode=critique
|
|
63
|
+
Observation: The critique reveals...
|
|
64
|
+
|
|
65
|
+
Thought: These points need addressing...
|
|
66
|
+
Action: Revise solution based on critique
|
|
67
|
+
Observation: The improved solution...
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
4. Final Recommendation
|
|
71
|
+
```
|
|
72
|
+
Thought: Synthesize all findings...
|
|
73
|
+
Action: Compile final recommendation
|
|
74
|
+
Output: Detailed solution with rationale
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
GUIDELINES:
|
|
78
|
+
- Use deep_thinking tool for structured analysis
|
|
79
|
+
- Validate assumptions with search/ask_user
|
|
80
|
+
- Consider multiple perspectives
|
|
81
|
+
- Provide evidence for conclusions
|
|
82
|
+
- Be thorough but practical
|
|
83
|
+
- Focus on actionable recommendations
|
|
84
|
+
|
|
85
|
+
Please proceed with the analysis and provide a comprehensive response."""
|
|
86
|
+
|
|
87
|
+
# Create agent with thinking platform
|
|
88
|
+
agent = Agent(
|
|
89
|
+
system_prompt=system_prompt,
|
|
90
|
+
name="DeepThinkingAgent",
|
|
91
|
+
tool_registry=tool_registry,
|
|
92
|
+
platform=PlatformRegistry().get_thinking_platform(),
|
|
93
|
+
auto_complete=True,
|
|
94
|
+
is_sub_agent=True,
|
|
95
|
+
summary_prompt="""Please provide a structured summary of your thinking process and conclusions:
|
|
96
|
+
|
|
97
|
+
<THINKING_SUMMARY>
|
|
98
|
+
Analysis:
|
|
99
|
+
[Key findings from analysis]
|
|
100
|
+
|
|
101
|
+
Solutions:
|
|
102
|
+
[Proposed solutions and rationale]
|
|
103
|
+
|
|
104
|
+
Critique:
|
|
105
|
+
[Critical considerations]
|
|
106
|
+
|
|
107
|
+
Recommendation:
|
|
108
|
+
[Final recommendation with justification]
|
|
109
|
+
</THINKING_SUMMARY>"""
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Run agent
|
|
113
|
+
result = agent.run(question)
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
"success": True,
|
|
117
|
+
"stdout": result,
|
|
118
|
+
"stderr": ""
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
except Exception as e:
|
|
122
|
+
return {
|
|
123
|
+
"success": False,
|
|
124
|
+
"stderr": f"Deep thinking failed: {str(e)}",
|
|
125
|
+
"stdout": ""
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
def main():
|
|
129
|
+
"""CLI entry point"""
|
|
130
|
+
import argparse
|
|
131
|
+
|
|
132
|
+
parser = argparse.ArgumentParser(description='Deep thinking agent')
|
|
133
|
+
parser.add_argument('question', help='Question or problem to think about')
|
|
134
|
+
|
|
135
|
+
args = parser.parse_args()
|
|
136
|
+
|
|
137
|
+
tool = DeepThinkingAgentTool()
|
|
138
|
+
result = tool.execute({"question": args.question})
|
|
139
|
+
|
|
140
|
+
if result["success"]:
|
|
141
|
+
PrettyOutput.print(result["stdout"], OutputType.SUCCESS)
|
|
142
|
+
else:
|
|
143
|
+
PrettyOutput.print(result["stderr"], OutputType.ERROR)
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
main()
|
|
@@ -4,8 +4,8 @@ from typing import Dict, Any
|
|
|
4
4
|
|
|
5
5
|
import yaml
|
|
6
6
|
from jarvis.agent import Agent
|
|
7
|
-
from jarvis.
|
|
8
|
-
from jarvis.
|
|
7
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
8
|
+
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
9
9
|
from jarvis.utils import OutputType, PrettyOutput, init_env
|
|
10
10
|
import sys
|
|
11
11
|
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
|
+
|
|
5
|
+
class LSPFindDefinitionTool:
|
|
6
|
+
"""Tool for finding symbol definitions in code using LSP."""
|
|
7
|
+
|
|
8
|
+
name = "lsp_find_definition"
|
|
9
|
+
description = "Find the definition of a symbol in code"
|
|
10
|
+
parameters = {
|
|
11
|
+
"file_path": "Path to the file containing the symbol",
|
|
12
|
+
"line": "Line number (0-based) of the symbol",
|
|
13
|
+
"character": "Character position in the line",
|
|
14
|
+
"language": f"Programming language of the file ({', '.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.dirname(os.path.abspath(file_path))):
|
|
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
|
+
# Find definition
|
|
85
|
+
defn = lsp.find_definition(file_path, (line, character))
|
|
86
|
+
|
|
87
|
+
if not defn:
|
|
88
|
+
return {
|
|
89
|
+
"success": True,
|
|
90
|
+
"stdout": f"No definition found for '{symbol}'",
|
|
91
|
+
"stderr": ""
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Format output
|
|
95
|
+
def_line = defn["range"]["start"]["line"]
|
|
96
|
+
def_char = defn["range"]["start"]["character"]
|
|
97
|
+
context = LSPRegistry.get_line_at_position(defn["uri"], def_line).strip()
|
|
98
|
+
|
|
99
|
+
output = [
|
|
100
|
+
f"Definition of '{symbol}':",
|
|
101
|
+
f"File: {defn['uri']}",
|
|
102
|
+
f"Line {def_line + 1}, Col {def_char + 1}: {context}"
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
# Get a few lines of context around the definition
|
|
106
|
+
try:
|
|
107
|
+
with open(defn["uri"], 'r') as f:
|
|
108
|
+
lines = f.readlines()
|
|
109
|
+
start = max(0, def_line - 2)
|
|
110
|
+
end = min(len(lines), def_line + 3)
|
|
111
|
+
|
|
112
|
+
if start < def_line:
|
|
113
|
+
output.append("\nContext:")
|
|
114
|
+
for i in range(start, end):
|
|
115
|
+
prefix = ">" if i == def_line else " "
|
|
116
|
+
output.append(f"{prefix} {i+1:4d} | {lines[i].rstrip()}")
|
|
117
|
+
except Exception:
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
"success": True,
|
|
122
|
+
"stdout": "\n".join(output),
|
|
123
|
+
"stderr": ""
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
except Exception as e:
|
|
127
|
+
return {
|
|
128
|
+
"success": False,
|
|
129
|
+
"stderr": f"Error finding definition: {str(e)}",
|
|
130
|
+
"stdout": ""
|
|
131
|
+
}
|
|
132
|
+
finally:
|
|
133
|
+
if lsp:
|
|
134
|
+
lsp.shutdown()
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
|
+
|
|
5
|
+
class LSPFindReferencesTool:
|
|
6
|
+
"""Tool for finding references to symbols in code using LSP."""
|
|
7
|
+
|
|
8
|
+
name = "lsp_find_references"
|
|
9
|
+
description = "Find all references to a symbol in code"
|
|
10
|
+
parameters = {
|
|
11
|
+
"file_path": "Path to the file containing the symbol",
|
|
12
|
+
"line": "Line number (0-based) of the symbol",
|
|
13
|
+
"character": "Character position in the line",
|
|
14
|
+
"language": f"Programming language of the file ({', '.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.dirname(os.path.abspath(file_path))):
|
|
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
|
+
# Find references
|
|
85
|
+
refs = lsp.find_references(file_path, (line, character))
|
|
86
|
+
|
|
87
|
+
# Format output
|
|
88
|
+
output = [f"References to '{symbol}':\n"]
|
|
89
|
+
for ref in refs:
|
|
90
|
+
ref_line = ref["range"]["start"]["line"]
|
|
91
|
+
ref_char = ref["range"]["start"]["character"]
|
|
92
|
+
context = LSPRegistry.get_line_at_position(ref["uri"], ref_line).strip()
|
|
93
|
+
output.append(f"File: {ref['uri']}")
|
|
94
|
+
output.append(f"Line {ref_line + 1}, Col {ref_char + 1}: {context}")
|
|
95
|
+
output.append("-" * 40)
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
"success": True,
|
|
99
|
+
"stdout": "\n".join(output) if len(refs) > 0 else f"No references found for '{symbol}'",
|
|
100
|
+
"stderr": ""
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
except Exception as e:
|
|
104
|
+
return {
|
|
105
|
+
"success": False,
|
|
106
|
+
"stderr": f"Error finding references: {str(e)}",
|
|
107
|
+
"stdout": ""
|
|
108
|
+
}
|
|
109
|
+
finally:
|
|
110
|
+
if lsp:
|
|
111
|
+
lsp.shutdown()
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
|
+
|
|
5
|
+
class LSPGetDiagnosticsTool:
|
|
6
|
+
"""Tool for getting diagnostics (errors, warnings) from code using LSP."""
|
|
7
|
+
|
|
8
|
+
name = "lsp_get_diagnostics"
|
|
9
|
+
description = "Get diagnostic information (errors, warnings) from 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
|
+
# Validate inputs
|
|
27
|
+
if not all([file_path, language]):
|
|
28
|
+
return {
|
|
29
|
+
"success": False,
|
|
30
|
+
"stderr": "Both file_path and language must be provided",
|
|
31
|
+
"stdout": ""
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if not os.path.exists(file_path):
|
|
35
|
+
return {
|
|
36
|
+
"success": False,
|
|
37
|
+
"stderr": f"File not found: {file_path}",
|
|
38
|
+
"stdout": ""
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Get LSP instance
|
|
42
|
+
registry = LSPRegistry.get_global_lsp_registry()
|
|
43
|
+
lsp = registry.create_lsp(language)
|
|
44
|
+
|
|
45
|
+
if not lsp:
|
|
46
|
+
return {
|
|
47
|
+
"success": False,
|
|
48
|
+
"stderr": f"No LSP support for language: {language}",
|
|
49
|
+
"stdout": ""
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
# Initialize LSP
|
|
54
|
+
if not lsp.initialize(os.path.dirname(os.path.abspath(file_path))):
|
|
55
|
+
return {
|
|
56
|
+
"success": False,
|
|
57
|
+
"stderr": "LSP initialization failed",
|
|
58
|
+
"stdout": ""
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Get diagnostics
|
|
62
|
+
diagnostics = lsp.get_diagnostics(file_path)
|
|
63
|
+
|
|
64
|
+
if not diagnostics:
|
|
65
|
+
return {
|
|
66
|
+
"success": True,
|
|
67
|
+
"stdout": "No issues found in the file",
|
|
68
|
+
"stderr": ""
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Format output
|
|
72
|
+
output = ["Diagnostics:"]
|
|
73
|
+
severity_map = {1: "Error", 2: "Warning", 3: "Info", 4: "Hint"}
|
|
74
|
+
|
|
75
|
+
# Sort diagnostics by severity and line number
|
|
76
|
+
sorted_diagnostics = sorted(
|
|
77
|
+
diagnostics,
|
|
78
|
+
key=lambda x: (x["severity"], x["range"]["start"]["line"])
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
for diag in sorted_diagnostics:
|
|
82
|
+
severity = severity_map.get(diag["severity"], "Unknown")
|
|
83
|
+
start = diag["range"]["start"]
|
|
84
|
+
line = LSPRegistry.get_line_at_position(file_path, start["line"]).strip()
|
|
85
|
+
|
|
86
|
+
output.extend([
|
|
87
|
+
f"\n{severity} at line {start['line'] + 1}, column {start['character'] + 1}:",
|
|
88
|
+
f"Message: {diag['message']}",
|
|
89
|
+
f"Code: {line}",
|
|
90
|
+
"-" * 60
|
|
91
|
+
])
|
|
92
|
+
|
|
93
|
+
# Add related information if available
|
|
94
|
+
if diag.get("relatedInformation"):
|
|
95
|
+
output.append("Related information:")
|
|
96
|
+
for info in diag["relatedInformation"]:
|
|
97
|
+
info_line = LSPRegistry.get_line_at_position(
|
|
98
|
+
info["location"]["uri"],
|
|
99
|
+
info["location"]["range"]["start"]["line"]
|
|
100
|
+
).strip()
|
|
101
|
+
output.extend([
|
|
102
|
+
f" - {info['message']}",
|
|
103
|
+
f" at {info['location']['uri']}:{info['location']['range']['start']['line'] + 1}",
|
|
104
|
+
f" {info_line}"
|
|
105
|
+
])
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
"success": True,
|
|
109
|
+
"stdout": "\n".join(output),
|
|
110
|
+
"stderr": ""
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
return {
|
|
115
|
+
"success": False,
|
|
116
|
+
"stderr": f"Error getting diagnostics: {str(e)}",
|
|
117
|
+
"stdout": ""
|
|
118
|
+
}
|
|
119
|
+
finally:
|
|
120
|
+
if lsp:
|
|
121
|
+
lsp.shutdown()
|
|
@@ -0,0 +1,87 @@
|
|
|
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.dirname(os.path.abspath(file_path))):
|
|
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()
|