jarvis-ai-assistant 0.1.102__py3-none-any.whl → 0.1.103__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 +138 -117
- jarvis/jarvis_code_agent/code_agent.py +234 -0
- jarvis/{jarvis_coder → jarvis_code_agent}/file_select.py +16 -17
- jarvis/jarvis_code_agent/patch.py +118 -0
- jarvis/jarvis_code_agent/relevant_files.py +66 -0
- jarvis/jarvis_codebase/main.py +878 -0
- jarvis/jarvis_platform/main.py +5 -3
- jarvis/jarvis_rag/main.py +818 -0
- jarvis/jarvis_smart_shell/main.py +2 -2
- jarvis/models/ai8.py +3 -1
- jarvis/models/kimi.py +36 -30
- jarvis/models/ollama.py +17 -11
- jarvis/models/openai.py +15 -12
- jarvis/models/oyi.py +24 -7
- jarvis/models/registry.py +1 -25
- jarvis/tools/__init__.py +0 -6
- jarvis/tools/ask_codebase.py +99 -0
- jarvis/tools/ask_user.py +1 -9
- jarvis/tools/chdir.py +1 -1
- jarvis/tools/code_review.py +163 -0
- jarvis/tools/create_code_sub_agent.py +19 -45
- jarvis/tools/create_code_test_agent.py +115 -0
- jarvis/tools/create_ctags_agent.py +176 -0
- jarvis/tools/create_sub_agent.py +2 -2
- jarvis/tools/execute_shell.py +2 -2
- jarvis/tools/file_operation.py +2 -2
- jarvis/tools/find_in_codebase.py +108 -0
- jarvis/tools/git_commiter.py +68 -0
- jarvis/tools/methodology.py +3 -3
- jarvis/tools/rag.py +141 -0
- jarvis/tools/read_code.py +147 -0
- jarvis/tools/read_webpage.py +1 -1
- jarvis/tools/registry.py +47 -31
- jarvis/tools/search.py +8 -6
- jarvis/tools/select_code_files.py +4 -4
- jarvis/utils.py +374 -84
- {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/METADATA +52 -2
- jarvis_ai_assistant-0.1.103.dist-info/RECORD +51 -0
- jarvis_ai_assistant-0.1.103.dist-info/entry_points.txt +11 -0
- jarvis/jarvis_code_agent/main.py +0 -200
- jarvis/jarvis_coder/git_utils.py +0 -123
- jarvis/jarvis_coder/patch_handler.py +0 -340
- jarvis/jarvis_github/main.py +0 -232
- jarvis/tools/execute_code_modification.py +0 -70
- jarvis/tools/find_files.py +0 -119
- jarvis/tools/generate_tool.py +0 -174
- jarvis/tools/thinker.py +0 -151
- jarvis_ai_assistant-0.1.102.dist-info/RECORD +0 -46
- jarvis_ai_assistant-0.1.102.dist-info/entry_points.txt +0 -6
- /jarvis/{jarvis_coder → jarvis_codebase}/__init__.py +0 -0
- /jarvis/{jarvis_github → jarvis_rag}/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/top_level.txt +0 -0
|
@@ -1,56 +1,30 @@
|
|
|
1
|
-
from typing import Dict, Any
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from typing import Any, Dict
|
|
5
|
+
from jarvis.jarvis_code_agent.code_agent import CodeAgent
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class CodeSubAgentTool:
|
|
9
9
|
name = "create_code_sub_agent"
|
|
10
|
-
description = "Create a sub-agent to handle
|
|
10
|
+
description = "Create a sub-agent to handle the code modification"
|
|
11
11
|
parameters = {
|
|
12
12
|
"type": "object",
|
|
13
13
|
"properties": {
|
|
14
|
-
"
|
|
15
|
-
"type": "string",
|
|
16
|
-
"description": "The name of the sub-agent"
|
|
17
|
-
},
|
|
18
|
-
"subtask": {
|
|
14
|
+
"requirement": {
|
|
19
15
|
"type": "string",
|
|
20
|
-
"description": "The
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
"required": ["subtask", "name"]
|
|
16
|
+
"description": "The requirement of the sub-agent"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
24
19
|
}
|
|
25
|
-
|
|
20
|
+
|
|
26
21
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
27
|
-
"""Execute
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
system_prompt=system_prompt,
|
|
37
|
-
name=name,
|
|
38
|
-
is_sub_agent=True
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
# Execute subtask
|
|
42
|
-
result = sub_agent.run(subtask)
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
"success": True,
|
|
46
|
-
"stdout": f"Code Development Subtask Results:\n\n{result}",
|
|
47
|
-
"stderr": ""
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
except Exception as e:
|
|
51
|
-
PrettyOutput.print(str(e), OutputType.ERROR)
|
|
52
|
-
return {
|
|
53
|
-
"success": False,
|
|
54
|
-
"stdout": "",
|
|
55
|
-
"stderr": f"Failed to execute code development subtask: {str(e)}"
|
|
56
|
-
}
|
|
22
|
+
"""Execute the sub-agent"""
|
|
23
|
+
requirement = args["requirement"]
|
|
24
|
+
agent = CodeAgent()
|
|
25
|
+
output = agent.run(requirement)
|
|
26
|
+
return {
|
|
27
|
+
"success": True,
|
|
28
|
+
"stdout": output,
|
|
29
|
+
"stderr": ""
|
|
30
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
from jarvis.agent import Agent
|
|
3
|
+
from jarvis.tools.registry import ToolRegistry
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
6
|
+
class TestAgentTool:
|
|
7
|
+
name = "create_code_test_agent"
|
|
8
|
+
description = "Create testing agent for specific commit analysis"
|
|
9
|
+
parameters = {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"name": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Identifier for the test agent"
|
|
15
|
+
},
|
|
16
|
+
"test_scope": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"enum": ["unit", "integration", "e2e"],
|
|
19
|
+
"description": "Testing focus area"
|
|
20
|
+
},
|
|
21
|
+
"commit_sha": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Commit SHA to analyze"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": ["name", "test_scope", "commit_sha"]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
30
|
+
"""Execute commit-focused testing"""
|
|
31
|
+
try:
|
|
32
|
+
if not self._is_valid_commit(args["commit_sha"]):
|
|
33
|
+
return {
|
|
34
|
+
"success": False,
|
|
35
|
+
"stdout": "",
|
|
36
|
+
"stderr": f"Invalid commit SHA: {args['commit_sha']}"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
tool_registry = ToolRegistry()
|
|
40
|
+
tool_registry.dont_use_tools(["create_code_test_agent"])
|
|
41
|
+
|
|
42
|
+
test_agent = Agent(
|
|
43
|
+
system_prompt=self._build_system_prompt(args),
|
|
44
|
+
name=f"TestAgent({args['name']})",
|
|
45
|
+
is_sub_agent=True,
|
|
46
|
+
tool_registry=tool_registry
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
result = test_agent.run(
|
|
50
|
+
f"Analyze and test changes in commit {args['commit_sha'].strip()}"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
"success": True,
|
|
55
|
+
"stdout": result,
|
|
56
|
+
"stderr": ""
|
|
57
|
+
}
|
|
58
|
+
except Exception as e:
|
|
59
|
+
return {
|
|
60
|
+
"success": False,
|
|
61
|
+
"stdout": "",
|
|
62
|
+
"stderr": f"Commit testing failed: {str(e)}"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
def _is_valid_commit(self, commit_sha: str) -> bool:
|
|
66
|
+
"""Validate commit exists in repository"""
|
|
67
|
+
try:
|
|
68
|
+
cmd = f"git cat-file -t {commit_sha}"
|
|
69
|
+
result = subprocess.run(
|
|
70
|
+
cmd.split(),
|
|
71
|
+
capture_output=True,
|
|
72
|
+
text=True,
|
|
73
|
+
check=True
|
|
74
|
+
)
|
|
75
|
+
return "commit" in result.stdout
|
|
76
|
+
except subprocess.CalledProcessError:
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
def _build_system_prompt(self, args: Dict) -> str:
|
|
80
|
+
return """You are a Commit Testing Specialist. Follow this protocol:
|
|
81
|
+
|
|
82
|
+
【Testing Protocol】
|
|
83
|
+
1. Commit Analysis:
|
|
84
|
+
- Analyze code changes in target commit
|
|
85
|
+
- Identify modified components
|
|
86
|
+
- Assess change impact scope
|
|
87
|
+
|
|
88
|
+
2. Test Strategy:
|
|
89
|
+
- Determine required test types
|
|
90
|
+
- Verify backward compatibility
|
|
91
|
+
- Check interface contracts
|
|
92
|
+
|
|
93
|
+
3. Test Execution:
|
|
94
|
+
- Execute relevant test suites
|
|
95
|
+
- Compare pre/post-commit behavior
|
|
96
|
+
- Validate cross-component interactions
|
|
97
|
+
|
|
98
|
+
4. Reporting:
|
|
99
|
+
- List affected modules
|
|
100
|
+
- Risk assessment matrix
|
|
101
|
+
- Performance impact analysis
|
|
102
|
+
- Security implications
|
|
103
|
+
|
|
104
|
+
【Output Requirements】
|
|
105
|
+
- Test coverage analysis
|
|
106
|
+
- Behavioral change summary
|
|
107
|
+
- Critical issues prioritized
|
|
108
|
+
- Actionable recommendations
|
|
109
|
+
|
|
110
|
+
【Key Principles】
|
|
111
|
+
1. Focus on delta changes
|
|
112
|
+
2. Maintain test isolation
|
|
113
|
+
3. Preserve historical baselines
|
|
114
|
+
4. Automate verification steps
|
|
115
|
+
5. Document test evidence"""
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
import subprocess
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import yaml
|
|
7
|
+
from jarvis.agent import Agent
|
|
8
|
+
from jarvis.tools.registry import ToolRegistry
|
|
9
|
+
from jarvis.utils import OutputType, PrettyOutput, get_multiline_input, init_env
|
|
10
|
+
|
|
11
|
+
ctags_system_prompt = """You are a Ctags Expert Agent specializing in code analysis using Exuberant Ctags. Follow this protocol:
|
|
12
|
+
|
|
13
|
+
【OUTPUT OPTIMIZATION】
|
|
14
|
+
1. Filter with grep:
|
|
15
|
+
ctags -x <symbol> | grep -E 'pattern'
|
|
16
|
+
2. Limit output lines:
|
|
17
|
+
head -n 20
|
|
18
|
+
3. Context preview:
|
|
19
|
+
grep -A 3 -B 3 <line> <file>
|
|
20
|
+
4. Column selection:
|
|
21
|
+
cut -f 1,3
|
|
22
|
+
5. Sort and deduplicate:
|
|
23
|
+
sort | uniq
|
|
24
|
+
|
|
25
|
+
【WORKFLOW】
|
|
26
|
+
1. REQUIREMENT ANALYSIS
|
|
27
|
+
- Analyze query for symbols/patterns
|
|
28
|
+
- Determine search scope
|
|
29
|
+
- Select ctags options
|
|
30
|
+
- Plan output filtering
|
|
31
|
+
|
|
32
|
+
2. TAGS MANAGEMENT
|
|
33
|
+
- Generate/update tags file:
|
|
34
|
+
ctags -R --languages=<lang> --exclude=<pattern>
|
|
35
|
+
- Verify tags file integrity
|
|
36
|
+
- Maintain tags file versioning
|
|
37
|
+
|
|
38
|
+
3. SYMBOL PROCESSING
|
|
39
|
+
- Search symbols using:
|
|
40
|
+
grep -n <symbol> tags
|
|
41
|
+
ctags -x --<filter>
|
|
42
|
+
- Analyze symbol relationships
|
|
43
|
+
- Map symbol dependencies
|
|
44
|
+
- Apply output filters:
|
|
45
|
+
* Remove noise with grep -v
|
|
46
|
+
* Highlight key fields with awk
|
|
47
|
+
* Truncate long lines with cut
|
|
48
|
+
|
|
49
|
+
4. OUTPUT GENERATION
|
|
50
|
+
- Format results as YAML
|
|
51
|
+
- Include file paths and line numbers
|
|
52
|
+
- Add symbol metadata
|
|
53
|
+
- Limit to 20 key results
|
|
54
|
+
- Exclude temporary files
|
|
55
|
+
- Compress repetitive info
|
|
56
|
+
|
|
57
|
+
【COMMAND REFERENCE】
|
|
58
|
+
1. Generate Tags:
|
|
59
|
+
ctags -R --fields=+nKSt --extras=+fq -V *
|
|
60
|
+
|
|
61
|
+
2. Search Patterns:
|
|
62
|
+
ctags -x --c-types=f
|
|
63
|
+
ctags -x --sort=no <symbol>
|
|
64
|
+
ctags -x | grep '^main' | head -n 5
|
|
65
|
+
|
|
66
|
+
3. Language Specific:
|
|
67
|
+
--languages=Python,Java,C++
|
|
68
|
+
--python-kinds=-iv
|
|
69
|
+
|
|
70
|
+
4. Filtering:
|
|
71
|
+
--exclude=.git
|
|
72
|
+
--exclude=*.min.js
|
|
73
|
+
ctags -x | grep -v '_test' # Exclude tests
|
|
74
|
+
|
|
75
|
+
【ERROR HANDLING】
|
|
76
|
+
- Missing tags: Regenerate tags
|
|
77
|
+
- Invalid symbols: Use fuzzy search
|
|
78
|
+
- Encoding issues: Use --input-encoding
|
|
79
|
+
- Large codebase: Limit scope
|
|
80
|
+
- Output too long: Add head/grep filters
|
|
81
|
+
|
|
82
|
+
【NATURAL LANGUAGE PROCESSING】
|
|
83
|
+
1. Query Interpretation:
|
|
84
|
+
- Identify key terms: "find", "locate", "list", "show"
|
|
85
|
+
- Detect symbol types: class, function, variable
|
|
86
|
+
- Recognize relationships: "calls", "inherits", "uses"
|
|
87
|
+
|
|
88
|
+
2. Query Types:
|
|
89
|
+
- Location: "Where is X defined?"
|
|
90
|
+
- References: "Who calls Y?"
|
|
91
|
+
- Hierarchy: "Show subclasses of Z"
|
|
92
|
+
- Impact: "What uses this module?"
|
|
93
|
+
|
|
94
|
+
3. Auto Command Mapping:
|
|
95
|
+
| Query Pattern | Ctags Command |
|
|
96
|
+
|------------------------------|------------------------------------|
|
|
97
|
+
| Find definitions of X | ctags -x --<lang>-kinds=f | less |
|
|
98
|
+
| List all functions in Y | ctags -x --filter='function' |
|
|
99
|
+
| Show callers of Z | ctags --extra=+q -x | grep Z |
|
|
100
|
+
| Find interface implementations| ctags -x --_traits=yes |
|
|
101
|
+
|
|
102
|
+
4. Context Handling:
|
|
103
|
+
- Detect language from file extensions
|
|
104
|
+
- Auto-detect project root
|
|
105
|
+
- Apply language-specific filters
|
|
106
|
+
- Choose appropriate output format:
|
|
107
|
+
* Simple list for single results
|
|
108
|
+
* Table for multiple entries
|
|
109
|
+
* Tree view for hierarchies
|
|
110
|
+
* JSON when programmatic access needed
|
|
111
|
+
|
|
112
|
+
【EXAMPLE QUERIES】
|
|
113
|
+
1. "Find all Python functions in src/ that use Redis"
|
|
114
|
+
2. "Show Java classes implementing PaymentService"
|
|
115
|
+
3. "List called methods in auth module"
|
|
116
|
+
4. "Where is User model defined?"
|
|
117
|
+
5. "What config files reference database settings?"
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
class CtagsTool:
|
|
121
|
+
name = "create_ctags_agent"
|
|
122
|
+
description = "Analyze code structure and symbols using natural language queries"
|
|
123
|
+
parameters = {
|
|
124
|
+
"type": "object",
|
|
125
|
+
"properties": {
|
|
126
|
+
"query": {
|
|
127
|
+
"type": "string",
|
|
128
|
+
"description": "Natural language description of code analysis needs"
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"required": ["query"]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
135
|
+
"""Execute code analysis based on natural language query"""
|
|
136
|
+
try:
|
|
137
|
+
tool_registry = ToolRegistry()
|
|
138
|
+
tool_registry.use_tools(["execute_shell"])
|
|
139
|
+
|
|
140
|
+
ctags_agent = Agent(
|
|
141
|
+
system_prompt=ctags_system_prompt,
|
|
142
|
+
name="Ctags Analysis Agent",
|
|
143
|
+
is_sub_agent=True,
|
|
144
|
+
tool_registry=tool_registry
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
analysis_request = f"""
|
|
148
|
+
Analysis Request: {args['query']}
|
|
149
|
+
Context: {args.get('context', {})}
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
result = ctags_agent.run(analysis_request)
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
"success": True,
|
|
156
|
+
"stdout": result,
|
|
157
|
+
"stderr": ""
|
|
158
|
+
}
|
|
159
|
+
except Exception as e:
|
|
160
|
+
return {
|
|
161
|
+
"success": False,
|
|
162
|
+
"stdout": "",
|
|
163
|
+
"stderr": f"Analysis failed: {str(e)}"
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
def main():
|
|
167
|
+
"""CLI testing"""
|
|
168
|
+
init_env()
|
|
169
|
+
tool = CtagsTool()
|
|
170
|
+
query = get_multiline_input("Please enter your query:")
|
|
171
|
+
result = tool.execute({
|
|
172
|
+
"query": query
|
|
173
|
+
})
|
|
174
|
+
PrettyOutput.print(yaml.dump(result, default_style='|'), OutputType.INFO)
|
|
175
|
+
if __name__ == "__main__":
|
|
176
|
+
main()
|
jarvis/tools/create_sub_agent.py
CHANGED
|
@@ -2,6 +2,7 @@ from typing import Dict, Any
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
from jarvis.agent import Agent, origin_agent_system_prompt
|
|
5
|
+
from jarvis.tools.registry import ToolRegistry
|
|
5
6
|
from jarvis.utils import OutputType, PrettyOutput
|
|
6
7
|
|
|
7
8
|
|
|
@@ -58,12 +59,11 @@ class SubAgentTool:
|
|
|
58
59
|
if goal:
|
|
59
60
|
task_description += f"\n\nCompletion goal:\n{goal}"
|
|
60
61
|
|
|
61
|
-
|
|
62
62
|
|
|
63
63
|
# Create sub-agent
|
|
64
64
|
sub_agent = Agent(
|
|
65
65
|
system_prompt=origin_agent_system_prompt,
|
|
66
|
-
name=agent_name,
|
|
66
|
+
name=f"Agent({agent_name})",
|
|
67
67
|
is_sub_agent=True
|
|
68
68
|
)
|
|
69
69
|
|
jarvis/tools/execute_shell.py
CHANGED
|
@@ -29,7 +29,7 @@ class ShellTool:
|
|
|
29
29
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
30
30
|
"""Execute shell command"""
|
|
31
31
|
try:
|
|
32
|
-
command = args["command"]
|
|
32
|
+
command = args["command"].strip()
|
|
33
33
|
|
|
34
34
|
# Generate temporary file name
|
|
35
35
|
output_file = os.path.join(tempfile.gettempdir(), f"jarvis_shell_{os.getpid()}.log")
|
|
@@ -61,7 +61,7 @@ class ShellTool:
|
|
|
61
61
|
Path(output_file).unlink(missing_ok=True)
|
|
62
62
|
|
|
63
63
|
return {
|
|
64
|
-
"success":
|
|
64
|
+
"success": True,
|
|
65
65
|
"stdout": output,
|
|
66
66
|
"stderr": "",
|
|
67
67
|
}
|
jarvis/tools/file_operation.py
CHANGED
|
@@ -37,8 +37,8 @@ class FileOperationTool:
|
|
|
37
37
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
38
38
|
"""Execute file operations"""
|
|
39
39
|
try:
|
|
40
|
-
operation = args["operation"]
|
|
41
|
-
filepath = args["filepath"]
|
|
40
|
+
operation = args["operation"].strip()
|
|
41
|
+
filepath = args["filepath"].strip()
|
|
42
42
|
encoding = args.get("encoding", "utf-8")
|
|
43
43
|
|
|
44
44
|
# Record the operation and the full path
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
from jarvis.jarvis_code_agent.file_select import select_files
|
|
3
|
+
from jarvis.utils import OutputType, PrettyOutput, dont_use_local_model, find_git_root
|
|
4
|
+
from jarvis.jarvis_codebase.main import CodeBase
|
|
5
|
+
|
|
6
|
+
class FindInCodebaseTool:
|
|
7
|
+
"""Tool for searching files in codebase based on requirements"""
|
|
8
|
+
|
|
9
|
+
name = "find_in_codebase"
|
|
10
|
+
description = "Search and identify relevant code files in the codebase based on requirements description, using semantic search"
|
|
11
|
+
parameters = {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"properties": {
|
|
14
|
+
"query": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "The search query or requirement description"
|
|
17
|
+
},
|
|
18
|
+
"top_k": {
|
|
19
|
+
"type": "integer",
|
|
20
|
+
"description": "Maximum number of results to return",
|
|
21
|
+
"default": 20
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"required": ["query"]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def check() -> bool:
|
|
29
|
+
return not dont_use_local_model()
|
|
30
|
+
|
|
31
|
+
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
32
|
+
"""Execute the search
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
args: Dictionary containing:
|
|
36
|
+
- query: Search query string
|
|
37
|
+
- top_k: Maximum number of results (optional)
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Dict containing:
|
|
41
|
+
- success: Boolean indicating success
|
|
42
|
+
- stdout: Search results in YAML format
|
|
43
|
+
- stderr: Error message if any
|
|
44
|
+
"""
|
|
45
|
+
try:
|
|
46
|
+
query = args["query"]
|
|
47
|
+
top_k = args.get("top_k", 20)
|
|
48
|
+
|
|
49
|
+
root_dir = find_git_root()
|
|
50
|
+
|
|
51
|
+
codebase = CodeBase(root_dir)
|
|
52
|
+
|
|
53
|
+
# Search for relevant files
|
|
54
|
+
results = codebase.search_similar(query, top_k)
|
|
55
|
+
|
|
56
|
+
results = select_files(results, root_dir)
|
|
57
|
+
|
|
58
|
+
if not results:
|
|
59
|
+
return {
|
|
60
|
+
"success": True,
|
|
61
|
+
"stdout": "files: []\n",
|
|
62
|
+
"stderr": "No relevant files found"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
"success": True,
|
|
68
|
+
"stdout": "\n".join(results),
|
|
69
|
+
"stderr": ""
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
except Exception as e:
|
|
73
|
+
PrettyOutput.print(f"Search error: {str(e)}", OutputType.ERROR)
|
|
74
|
+
return {
|
|
75
|
+
"success": False,
|
|
76
|
+
"stdout": "",
|
|
77
|
+
"stderr": f"Failed to execute search: {str(e)}"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
def main():
|
|
81
|
+
"""Command line interface for the tool"""
|
|
82
|
+
import argparse
|
|
83
|
+
|
|
84
|
+
parser = argparse.ArgumentParser(description='Search for relevant files in codebase')
|
|
85
|
+
parser.add_argument('query', help='Search query or requirement description')
|
|
86
|
+
parser.add_argument('--top-k', type=int, default=20, help='Maximum number of results to return')
|
|
87
|
+
|
|
88
|
+
args = parser.parse_args()
|
|
89
|
+
|
|
90
|
+
tool = FindInCodebaseTool()
|
|
91
|
+
result = tool.execute({
|
|
92
|
+
"query": args.query,
|
|
93
|
+
"top_k": args.top_k
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
if result["success"]:
|
|
97
|
+
if result["stdout"]:
|
|
98
|
+
print(result["stdout"])
|
|
99
|
+
else:
|
|
100
|
+
PrettyOutput.print("No relevant files found", OutputType.WARNING)
|
|
101
|
+
else:
|
|
102
|
+
PrettyOutput.print(result["stderr"], OutputType.ERROR)
|
|
103
|
+
return 1
|
|
104
|
+
|
|
105
|
+
return 0
|
|
106
|
+
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
exit(main())
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
from typing import Dict, Any
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
from jarvis.agent import Agent
|
|
7
|
+
from jarvis.models.registry import PlatformRegistry
|
|
8
|
+
from jarvis.tools.registry import ToolRegistry
|
|
9
|
+
from jarvis.utils import OutputType, PrettyOutput, init_env
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GitCommitTool:
|
|
14
|
+
name = "git_commit_agent"
|
|
15
|
+
description = "Automatically generate and execute git commits based on code changes"
|
|
16
|
+
parameters = {"properties": {}, "required": []}
|
|
17
|
+
|
|
18
|
+
def _extract_commit_message(self, message):
|
|
19
|
+
r = re.search(r"<COMMIT_MESSAGE>(.*)</COMMIT_MESSAGE>", message, re.DOTALL)
|
|
20
|
+
if r:
|
|
21
|
+
return ';'.join(r.group(1).strip().splitlines())
|
|
22
|
+
return "Unknown commit message"
|
|
23
|
+
|
|
24
|
+
def _get_last_commit_hash(self):
|
|
25
|
+
return os.popen("git log -1 --pretty=%H").read().strip()
|
|
26
|
+
|
|
27
|
+
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
28
|
+
"""Execute automatic commit process"""
|
|
29
|
+
try:
|
|
30
|
+
PrettyOutput.print("Add files to commit...", OutputType.SYSTEM)
|
|
31
|
+
os.system("git add .")
|
|
32
|
+
PrettyOutput.print("Get diff...", OutputType.SYSTEM)
|
|
33
|
+
diff = os.popen("git diff --cached --exit-code").read()
|
|
34
|
+
PrettyOutput.print(diff, OutputType.CODE)
|
|
35
|
+
prompt = f'''Please generate a commit message for the following changes.
|
|
36
|
+
Format:
|
|
37
|
+
<COMMIT_MESSAGE>
|
|
38
|
+
type(scope): description
|
|
39
|
+
</COMMIT_MESSAGE>
|
|
40
|
+
|
|
41
|
+
Don't include any other information.
|
|
42
|
+
|
|
43
|
+
{diff}
|
|
44
|
+
'''
|
|
45
|
+
PrettyOutput.print("Generate commit message...", OutputType.SYSTEM)
|
|
46
|
+
platform = PlatformRegistry().get_codegen_platform()
|
|
47
|
+
platform.set_suppress_output(True)
|
|
48
|
+
commit_message = platform.chat_until_success(prompt)
|
|
49
|
+
commit_message = self._extract_commit_message(commit_message)
|
|
50
|
+
PrettyOutput.print("Commit...", OutputType.INFO)
|
|
51
|
+
os.popen(f"git commit -m '{commit_message}'")
|
|
52
|
+
|
|
53
|
+
commit_hash = self._get_last_commit_hash()
|
|
54
|
+
|
|
55
|
+
PrettyOutput.section(f"Commit hash: {commit_hash}\nCommit message: {commit_message}", OutputType.SUCCESS)
|
|
56
|
+
|
|
57
|
+
return {"success": True, "stdout": yaml.safe_dump({"commit_hash": commit_hash, "commit_message": commit_message}), "stderr": ""}
|
|
58
|
+
|
|
59
|
+
except Exception as e:
|
|
60
|
+
return {"success": False, "stdout": "", "stderr": f"Commit error: {str(e)}"}
|
|
61
|
+
|
|
62
|
+
def main():
|
|
63
|
+
init_env()
|
|
64
|
+
tool = GitCommitTool()
|
|
65
|
+
tool.execute({})
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
sys.exit(main())
|
jarvis/tools/methodology.py
CHANGED
|
@@ -73,9 +73,9 @@ class MethodologyTool:
|
|
|
73
73
|
Returns:
|
|
74
74
|
Dict[str, Any]: A dictionary containing the execution result
|
|
75
75
|
"""
|
|
76
|
-
operation = args.get("operation")
|
|
77
|
-
problem_type = args.get("problem_type")
|
|
78
|
-
content = args.get("content")
|
|
76
|
+
operation = args.get("operation", "").strip()
|
|
77
|
+
problem_type = args.get("problem_type", "").strip()
|
|
78
|
+
content = args.get("content", "").strip()
|
|
79
79
|
|
|
80
80
|
if not operation or not problem_type:
|
|
81
81
|
return {
|