jarvis-ai-assistant 0.1.103__py3-none-any.whl → 0.1.105__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/file_select.py +4 -6
- jarvis/jarvis_code_agent/patch.py +6 -7
- jarvis/jarvis_code_agent/relevant_files.py +163 -41
- jarvis/jarvis_codebase/main.py +43 -29
- 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 +2 -2
- jarvis/jarvis_rag/main.py +8 -8
- jarvis/jarvis_smart_shell/main.py +3 -3
- jarvis/jarvis_tools/__init__.py +0 -0
- jarvis/{tools → jarvis_tools}/ask_codebase.py +1 -4
- jarvis/{tools → jarvis_tools}/ask_user.py +1 -1
- jarvis/{tools → jarvis_tools}/chdir.py +2 -37
- jarvis/jarvis_tools/code_review.py +236 -0
- 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 +3 -3
- 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}/rag.py +1 -1
- jarvis/{tools → jarvis_tools}/read_code.py +0 -31
- jarvis/{tools → jarvis_tools}/registry.py +6 -5
- jarvis/{tools → jarvis_tools}/search.py +2 -2
- jarvis/utils.py +71 -28
- {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/METADATA +98 -62
- jarvis_ai_assistant-0.1.105.dist-info/RECORD +62 -0
- {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/entry_points.txt +4 -4
- jarvis/models/__init__.py +0 -3
- jarvis/tools/code_review.py +0 -163
- jarvis/tools/create_code_sub_agent.py +0 -30
- jarvis/tools/create_code_test_agent.py +0 -115
- jarvis/tools/create_ctags_agent.py +0 -176
- jarvis/tools/find_in_codebase.py +0 -108
- jarvis_ai_assistant-0.1.103.dist-info/RECORD +0 -51
- /jarvis/{models → jarvis_platform}/base.py +0 -0
- /jarvis/{tools → jarvis_platform_manager}/__init__.py +0 -0
- /jarvis/{tools → jarvis_tools}/base.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}/read_webpage.py +0 -0
- /jarvis/{tools → jarvis_tools}/select_code_files.py +0 -0
- {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.103.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/top_level.txt +0 -0
|
@@ -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()
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
|
+
|
|
5
|
+
class LSPPrepareRenameTool:
|
|
6
|
+
"""Tool for checking if a symbol can be renamed using LSP."""
|
|
7
|
+
|
|
8
|
+
name = "lsp_prepare_rename"
|
|
9
|
+
description = "Check if a symbol can be safely renamed and show all locations that would be affected"
|
|
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
|
+
# 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()
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Dict, Any
|
|
3
|
+
from jarvis.jarvis_lsp.registry import LSPRegistry
|
|
4
|
+
|
|
5
|
+
class LSPValidateEditTool:
|
|
6
|
+
"""Tool for validating code edits using LSP."""
|
|
7
|
+
|
|
8
|
+
name = "lsp_validate_edit"
|
|
9
|
+
description = "Validate if a proposed code edit is syntactically correct"
|
|
10
|
+
parameters = {
|
|
11
|
+
"file_path": "Path to the file to edit",
|
|
12
|
+
"start_line": "Starting line number (0-based) of the edit",
|
|
13
|
+
"start_character": "Starting character position in the start line",
|
|
14
|
+
"end_line": "Ending line number (0-based) of the edit",
|
|
15
|
+
"end_character": "Ending character position in the end line",
|
|
16
|
+
"new_text": "New text to insert",
|
|
17
|
+
"language": f"Programming language of the file ({', '.join(LSPRegistry.get_global_lsp_registry().get_supported_languages())})"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def check() -> bool:
|
|
22
|
+
"""Check if any LSP server is available."""
|
|
23
|
+
registry = LSPRegistry.get_global_lsp_registry()
|
|
24
|
+
return len(registry.get_supported_languages()) > 0
|
|
25
|
+
|
|
26
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
27
|
+
"""Execute the tool."""
|
|
28
|
+
file_path = args.get("file_path", "")
|
|
29
|
+
start_line = args.get("start_line", None)
|
|
30
|
+
start_character = args.get("start_character", None)
|
|
31
|
+
end_line = args.get("end_line", None)
|
|
32
|
+
end_character = args.get("end_character", None)
|
|
33
|
+
new_text = args.get("new_text", "")
|
|
34
|
+
language = args.get("language", "")
|
|
35
|
+
|
|
36
|
+
# Validate inputs
|
|
37
|
+
if not all([file_path, start_line is not None, start_character is not None,
|
|
38
|
+
end_line is not None, end_character is not None, language]):
|
|
39
|
+
return {
|
|
40
|
+
"success": False,
|
|
41
|
+
"stderr": "All parameters except new_text must be provided",
|
|
42
|
+
"stdout": ""
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
start_line = int(start_line)
|
|
47
|
+
start_character = int(start_character)
|
|
48
|
+
end_line = int(end_line)
|
|
49
|
+
end_character = int(end_character)
|
|
50
|
+
except ValueError:
|
|
51
|
+
return {
|
|
52
|
+
"success": False,
|
|
53
|
+
"stderr": "Line and character positions must be integers",
|
|
54
|
+
"stdout": ""
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if not os.path.exists(file_path):
|
|
58
|
+
return {
|
|
59
|
+
"success": False,
|
|
60
|
+
"stderr": f"File not found: {file_path}",
|
|
61
|
+
"stdout": ""
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# Get LSP instance
|
|
65
|
+
registry = LSPRegistry.get_global_lsp_registry()
|
|
66
|
+
lsp = registry.create_lsp(language)
|
|
67
|
+
|
|
68
|
+
if not lsp:
|
|
69
|
+
return {
|
|
70
|
+
"success": False,
|
|
71
|
+
"stderr": f"No LSP support for language: {language}",
|
|
72
|
+
"stdout": ""
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
# Initialize LSP
|
|
77
|
+
if not lsp.initialize(os.path.dirname(os.path.abspath(file_path))):
|
|
78
|
+
return {
|
|
79
|
+
"success": False,
|
|
80
|
+
"stderr": "LSP initialization failed",
|
|
81
|
+
"stdout": ""
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# Prepare edit operation
|
|
85
|
+
edit = {
|
|
86
|
+
"range": {
|
|
87
|
+
"start": {"line": start_line, "character": start_character},
|
|
88
|
+
"end": {"line": end_line, "character": end_character}
|
|
89
|
+
},
|
|
90
|
+
"newText": new_text
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Show the edit preview
|
|
94
|
+
output = ["Edit Preview:"]
|
|
95
|
+
|
|
96
|
+
# Show original code
|
|
97
|
+
try:
|
|
98
|
+
with open(file_path, 'r') as f:
|
|
99
|
+
lines = f.readlines()
|
|
100
|
+
context_start = max(0, start_line - 2)
|
|
101
|
+
context_end = min(len(lines), end_line + 3)
|
|
102
|
+
|
|
103
|
+
output.append("\nOriginal code:")
|
|
104
|
+
for i in range(context_start, context_end):
|
|
105
|
+
prefix = ">" if start_line <= i <= end_line else " "
|
|
106
|
+
output.append(f"{prefix} {i+1:4d} | {lines[i].rstrip()}")
|
|
107
|
+
except Exception:
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
# Show new text
|
|
111
|
+
output.extend([
|
|
112
|
+
"\nNew text to insert:",
|
|
113
|
+
new_text,
|
|
114
|
+
"\nEdit range:",
|
|
115
|
+
f"From line {start_line + 1}, character {start_character}",
|
|
116
|
+
f"To line {end_line + 1}, character {end_character}"
|
|
117
|
+
])
|
|
118
|
+
|
|
119
|
+
# Validate edit
|
|
120
|
+
is_valid = lsp.validate_edit(file_path, edit)
|
|
121
|
+
|
|
122
|
+
if is_valid:
|
|
123
|
+
output.append("\nValidation Result: The edit is syntactically correct ✓")
|
|
124
|
+
else:
|
|
125
|
+
output.append("\nValidation Result: The edit would introduce syntax errors ✗")
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
"success": True,
|
|
129
|
+
"stdout": "\n".join(output),
|
|
130
|
+
"stderr": ""
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
except Exception as e:
|
|
134
|
+
return {
|
|
135
|
+
"success": False,
|
|
136
|
+
"stderr": f"Error validating edit: {str(e)}",
|
|
137
|
+
"stdout": ""
|
|
138
|
+
}
|
|
139
|
+
finally:
|
|
140
|
+
if lsp:
|
|
141
|
+
lsp.shutdown()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import yaml
|
|
3
3
|
from typing import Dict, Optional, Any
|
|
4
|
-
from jarvis.utils import OutputType, PrettyOutput
|
|
4
|
+
from jarvis.utils import OutputType, PrettyOutput, is_use_methodology
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class MethodologyTool:
|
|
@@ -29,6 +29,11 @@ class MethodologyTool:
|
|
|
29
29
|
},
|
|
30
30
|
"required": ["operation", "problem_type"]
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def check()->bool:
|
|
35
|
+
"""Check if the methodology is enabled"""
|
|
36
|
+
return is_use_methodology()
|
|
32
37
|
|
|
33
38
|
def __init__(self):
|
|
34
39
|
"""Initialize the experience management tool"""
|
|
@@ -133,7 +133,7 @@ def main():
|
|
|
133
133
|
})
|
|
134
134
|
|
|
135
135
|
if result["success"]:
|
|
136
|
-
PrettyOutput.print(f"
|
|
136
|
+
PrettyOutput.print(f"{result['stdout']}", OutputType.INFO, lang="markdown")
|
|
137
137
|
else:
|
|
138
138
|
PrettyOutput.print(result["stderr"], OutputType.ERROR)
|
|
139
139
|
|
|
@@ -114,34 +114,3 @@ class ReadCodeTool:
|
|
|
114
114
|
"stdout": "",
|
|
115
115
|
"stderr": f"Failed to read code: {str(e)}"
|
|
116
116
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def main():
|
|
120
|
-
"""Command line interface for the tool"""
|
|
121
|
-
import argparse
|
|
122
|
-
|
|
123
|
-
parser = argparse.ArgumentParser(description='Read code file with line numbers')
|
|
124
|
-
parser.add_argument('filepath', help='Path to the code file')
|
|
125
|
-
parser.add_argument('--start', type=int, default=0, help='Start line number (0-based)')
|
|
126
|
-
parser.add_argument('--end', type=int, default=-1, help='End line number (0-based)')
|
|
127
|
-
|
|
128
|
-
args = parser.parse_args()
|
|
129
|
-
|
|
130
|
-
tool = ReadCodeTool()
|
|
131
|
-
result = tool.execute({
|
|
132
|
-
"filepath": args.filepath,
|
|
133
|
-
"start_line": args.start,
|
|
134
|
-
"end_line": args.end
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
if result["success"]:
|
|
138
|
-
print(result["stdout"])
|
|
139
|
-
else:
|
|
140
|
-
PrettyOutput.print(result["stderr"], OutputType.ERROR)
|
|
141
|
-
return 1
|
|
142
|
-
|
|
143
|
-
return 0
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if __name__ == "__main__":
|
|
147
|
-
main()
|
|
@@ -3,12 +3,12 @@ from pathlib import Path
|
|
|
3
3
|
import sys
|
|
4
4
|
from typing import Any, Callable, Dict, List, Optional
|
|
5
5
|
|
|
6
|
-
from jarvis.
|
|
7
|
-
from jarvis.
|
|
6
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
7
|
+
from jarvis.jarvis_tools.base import Tool
|
|
8
8
|
from jarvis.utils import OutputType, PrettyOutput, get_max_context_length
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
tool_call_help = """Tool Usage Format
|
|
11
|
+
tool_call_help = """## Tool Usage Format
|
|
12
12
|
|
|
13
13
|
<TOOL_CALL>
|
|
14
14
|
name: tool_name
|
|
@@ -49,7 +49,7 @@ class ToolRegistry:
|
|
|
49
49
|
"""Load tools"""
|
|
50
50
|
tools = self.get_all_tools()
|
|
51
51
|
if tools:
|
|
52
|
-
tools_prompt = "Available tools:\n"
|
|
52
|
+
tools_prompt = "## Available tools:\n"
|
|
53
53
|
for tool in tools:
|
|
54
54
|
tools_prompt += f"- Name: {tool['name']}\n"
|
|
55
55
|
tools_prompt += f" Description: {tool['description']}\n"
|
|
@@ -136,7 +136,8 @@ class ToolRegistry:
|
|
|
136
136
|
if (isinstance(item, type) and
|
|
137
137
|
hasattr(item, 'name') and
|
|
138
138
|
hasattr(item, 'description') and
|
|
139
|
-
hasattr(item, 'parameters')
|
|
139
|
+
hasattr(item, 'parameters') and
|
|
140
|
+
hasattr(item, 'execute')):
|
|
140
141
|
|
|
141
142
|
if hasattr(item, "check"):
|
|
142
143
|
if not item.check():
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Dict, Any, List
|
|
2
|
-
from jarvis.
|
|
2
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
3
3
|
from jarvis.utils import PrettyOutput, OutputType
|
|
4
|
-
from jarvis.
|
|
4
|
+
from jarvis.jarvis_tools.read_webpage import WebpageTool
|
|
5
5
|
from playwright.sync_api import sync_playwright
|
|
6
6
|
from urllib.parse import quote
|
|
7
7
|
|
jarvis/utils.py
CHANGED
|
@@ -4,7 +4,7 @@ import time
|
|
|
4
4
|
import os
|
|
5
5
|
from enum import Enum
|
|
6
6
|
from datetime import datetime
|
|
7
|
-
from typing import Any, Dict
|
|
7
|
+
from typing import Any, Dict, Optional
|
|
8
8
|
import colorama
|
|
9
9
|
from colorama import Fore, Style as ColoramaStyle
|
|
10
10
|
import numpy as np
|
|
@@ -85,7 +85,7 @@ class PrettyOutput:
|
|
|
85
85
|
"""Pretty output using rich"""
|
|
86
86
|
|
|
87
87
|
# Icons for different output types
|
|
88
|
-
|
|
88
|
+
_ICONS = {
|
|
89
89
|
OutputType.SYSTEM: "🤖", # Robot - AI assistant
|
|
90
90
|
OutputType.CODE: "📝", # Notebook - Code
|
|
91
91
|
OutputType.RESULT: "✨", # Flash - Result
|
|
@@ -147,7 +147,7 @@ class PrettyOutput:
|
|
|
147
147
|
return default_lang
|
|
148
148
|
|
|
149
149
|
@staticmethod
|
|
150
|
-
def
|
|
150
|
+
def _format(text: str, output_type: OutputType, timestamp: bool = True) -> Text:
|
|
151
151
|
"""Format output text using rich Text"""
|
|
152
152
|
# Create rich Text object
|
|
153
153
|
formatted = Text()
|
|
@@ -157,17 +157,17 @@ class PrettyOutput:
|
|
|
157
157
|
formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}] ", style="white")
|
|
158
158
|
formatted.append(f"[{get_agent_list()}]", style="blue")
|
|
159
159
|
# Add icon
|
|
160
|
-
icon = PrettyOutput.
|
|
160
|
+
icon = PrettyOutput._ICONS.get(output_type, "")
|
|
161
161
|
formatted.append(f"{icon} ", style=output_type.value)
|
|
162
162
|
|
|
163
163
|
return formatted
|
|
164
164
|
|
|
165
165
|
@staticmethod
|
|
166
|
-
def print(text: str, output_type: OutputType, timestamp: bool = True):
|
|
166
|
+
def print(text: str, output_type: OutputType, timestamp: bool = True, lang: Optional[str] = None):
|
|
167
167
|
"""Print formatted output using rich console"""
|
|
168
168
|
# Get formatted header
|
|
169
|
-
lang = PrettyOutput._detect_language(text, default_lang='markdown')
|
|
170
|
-
header = PrettyOutput.
|
|
169
|
+
lang = lang if lang is not None else PrettyOutput._detect_language(text, default_lang='markdown')
|
|
170
|
+
header = PrettyOutput._format("", output_type, timestamp)
|
|
171
171
|
|
|
172
172
|
content = Syntax(text, lang, theme="monokai")
|
|
173
173
|
|
|
@@ -208,14 +208,6 @@ def get_single_line_input(tip: str) -> str:
|
|
|
208
208
|
})
|
|
209
209
|
return session.prompt(f"{tip}", style=style)
|
|
210
210
|
|
|
211
|
-
def make_choice_input(tip: str, choices: list) -> str:
|
|
212
|
-
"""Get choice input, support direction key, history function, etc."""
|
|
213
|
-
session = PromptSession(history=None)
|
|
214
|
-
style = PromptStyle.from_dict({
|
|
215
|
-
'prompt': 'ansicyan',
|
|
216
|
-
})
|
|
217
|
-
return session.prompt(f"{tip}", style=style)
|
|
218
|
-
|
|
219
211
|
class FileCompleter(Completer):
|
|
220
212
|
"""Custom completer for file paths with fuzzy matching."""
|
|
221
213
|
def __init__(self):
|
|
@@ -341,7 +333,7 @@ def init_env():
|
|
|
341
333
|
with open(env_file, "r", encoding="utf-8") as f:
|
|
342
334
|
for line in f:
|
|
343
335
|
line = line.strip()
|
|
344
|
-
if line and not line.startswith("#"):
|
|
336
|
+
if line and not line.startswith(("#", ";")):
|
|
345
337
|
try:
|
|
346
338
|
key, value = line.split("=", 1)
|
|
347
339
|
os.environ[key.strip()] = value.strip().strip("'").strip('"')
|
|
@@ -445,8 +437,7 @@ def load_rerank_model():
|
|
|
445
437
|
|
|
446
438
|
return model, tokenizer
|
|
447
439
|
|
|
448
|
-
|
|
449
|
-
return int(os.getenv('JARVIS_MAX_CONTEXT_LENGTH', '131072')) # 默认128k
|
|
440
|
+
|
|
450
441
|
|
|
451
442
|
def is_long_context(files: list) -> bool:
|
|
452
443
|
"""Check if the file list belongs to a long context (total characters exceed 80% of the maximum context length)"""
|
|
@@ -468,15 +459,12 @@ def is_long_context(files: list) -> bool:
|
|
|
468
459
|
|
|
469
460
|
return total_chars > threshold
|
|
470
461
|
|
|
471
|
-
|
|
472
|
-
return int(os.getenv('JARVIS_THREAD_COUNT', '1'))
|
|
462
|
+
|
|
473
463
|
|
|
474
464
|
def get_file_md5(filepath: str)->str:
|
|
475
465
|
return hashlib.md5(open(filepath, "rb").read(100*1024*1024)).hexdigest()
|
|
476
466
|
|
|
477
467
|
|
|
478
|
-
def dont_use_local_model():
|
|
479
|
-
return os.getenv('JARVIS_DONT_USE_LOCAL_MODEL', 'false') == 'true'
|
|
480
468
|
|
|
481
469
|
|
|
482
470
|
def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -> np.ndarray:
|
|
@@ -576,12 +564,7 @@ def load_methodology(user_input: str) -> str:
|
|
|
576
564
|
import traceback
|
|
577
565
|
PrettyOutput.print(f"Error trace: {traceback.format_exc()}", OutputType.INFO)
|
|
578
566
|
return ""
|
|
579
|
-
|
|
580
|
-
def is_auto_complete() -> bool:
|
|
581
|
-
return os.getenv('JARVIS_AUTO_COMPLETE', 'false') == 'true'
|
|
582
567
|
|
|
583
|
-
def is_disable_codebase() -> bool:
|
|
584
|
-
return os.getenv('JARVIS_DISABLE_CODEBASE', 'false') == 'true'
|
|
585
568
|
|
|
586
569
|
def user_confirm(tip: str, default: bool = True) -> bool:
|
|
587
570
|
"""Prompt the user for confirmation.
|
|
@@ -601,4 +584,64 @@ def get_file_line_count(filename: str) -> int:
|
|
|
601
584
|
try:
|
|
602
585
|
return len(open(filename, "r", encoding="utf-8").readlines())
|
|
603
586
|
except Exception as e:
|
|
604
|
-
return 0
|
|
587
|
+
return 0
|
|
588
|
+
|
|
589
|
+
def get_max_context_length():
|
|
590
|
+
return int(os.getenv('JARVIS_MAX_CONTEXT_LENGTH', '131072')) # 默认128k
|
|
591
|
+
|
|
592
|
+
def get_thread_count():
|
|
593
|
+
return int(os.getenv('JARVIS_THREAD_COUNT', '1'))
|
|
594
|
+
|
|
595
|
+
def dont_use_local_model():
|
|
596
|
+
return os.getenv('JARVIS_DONT_USE_LOCAL_MODEL', 'false') == 'true'
|
|
597
|
+
|
|
598
|
+
def is_auto_complete() -> bool:
|
|
599
|
+
return os.getenv('JARVIS_AUTO_COMPLETE', 'false') == 'true'
|
|
600
|
+
|
|
601
|
+
def is_disable_codebase() -> bool:
|
|
602
|
+
return os.getenv('JARVIS_DISABLE_CODEBASE', 'false') == 'true'
|
|
603
|
+
|
|
604
|
+
def is_use_methodology() -> bool:
|
|
605
|
+
return os.getenv('JARVIS_USE_METHODOLOGY', 'true') == 'true'
|
|
606
|
+
|
|
607
|
+
def is_record_methodology() -> bool:
|
|
608
|
+
return os.getenv('JARVIS_RECORD_METHODOLOGY', 'true') == 'true'
|
|
609
|
+
|
|
610
|
+
def is_need_summary() -> bool:
|
|
611
|
+
return os.getenv('JARVIS_NEED_SUMMARY', 'true') == 'true'
|
|
612
|
+
|
|
613
|
+
def get_min_paragraph_length() -> int:
|
|
614
|
+
return int(os.getenv('JARVIS_MIN_PARAGRAPH_LENGTH', '50'))
|
|
615
|
+
|
|
616
|
+
def get_max_paragraph_length() -> int:
|
|
617
|
+
return int(os.getenv('JARVIS_MAX_PARAGRAPH_LENGTH', '1000'))
|
|
618
|
+
|
|
619
|
+
def get_context_window() -> int:
|
|
620
|
+
return int(os.getenv('JARVIS_CONTEXT_WINDOW', '5'))
|
|
621
|
+
|
|
622
|
+
def get_shell_name() -> str:
|
|
623
|
+
return os.getenv('SHELL', 'bash')
|
|
624
|
+
|
|
625
|
+
def get_normal_platform_name() -> str:
|
|
626
|
+
return os.getenv('JARVIS_PLATFORM', 'kimi')
|
|
627
|
+
|
|
628
|
+
def get_normal_model_name() -> str:
|
|
629
|
+
return os.getenv('JARVIS_MODEL', 'kimi')
|
|
630
|
+
|
|
631
|
+
def get_codegen_platform_name() -> str:
|
|
632
|
+
return os.getenv('JARVIS_CODEGEN_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
|
|
633
|
+
|
|
634
|
+
def get_codegen_model_name() -> str:
|
|
635
|
+
return os.getenv('JARVIS_CODEGEN_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
|
|
636
|
+
|
|
637
|
+
def get_thinking_platform_name() -> str:
|
|
638
|
+
return os.getenv('JARVIS_THINKING_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
|
|
639
|
+
|
|
640
|
+
def get_thinking_model_name() -> str:
|
|
641
|
+
return os.getenv('JARVIS_THINKING_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
|
|
642
|
+
|
|
643
|
+
def get_cheap_platform_name() -> str:
|
|
644
|
+
return os.getenv('JARVIS_CHEAP_PLATFORM', os.getenv('JARVIS_PLATFORM', 'kimi'))
|
|
645
|
+
|
|
646
|
+
def get_cheap_model_name() -> str:
|
|
647
|
+
return os.getenv('JARVIS_CHEAP_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
|