jarvis-ai-assistant 0.1.102__py3-none-any.whl → 0.1.104__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.

Files changed (55) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +138 -117
  3. jarvis/jarvis_code_agent/code_agent.py +234 -0
  4. jarvis/{jarvis_coder → jarvis_code_agent}/file_select.py +19 -22
  5. jarvis/jarvis_code_agent/patch.py +120 -0
  6. jarvis/jarvis_code_agent/relevant_files.py +97 -0
  7. jarvis/jarvis_codebase/main.py +871 -0
  8. jarvis/jarvis_platform/main.py +5 -3
  9. jarvis/jarvis_rag/main.py +818 -0
  10. jarvis/jarvis_smart_shell/main.py +2 -2
  11. jarvis/models/ai8.py +3 -1
  12. jarvis/models/kimi.py +36 -30
  13. jarvis/models/ollama.py +17 -11
  14. jarvis/models/openai.py +15 -12
  15. jarvis/models/oyi.py +24 -7
  16. jarvis/models/registry.py +1 -25
  17. jarvis/tools/__init__.py +0 -6
  18. jarvis/tools/ask_codebase.py +96 -0
  19. jarvis/tools/ask_user.py +1 -9
  20. jarvis/tools/chdir.py +2 -37
  21. jarvis/tools/code_review.py +210 -0
  22. jarvis/tools/create_code_test_agent.py +115 -0
  23. jarvis/tools/create_ctags_agent.py +164 -0
  24. jarvis/tools/create_sub_agent.py +2 -2
  25. jarvis/tools/execute_shell.py +2 -2
  26. jarvis/tools/file_operation.py +2 -2
  27. jarvis/tools/find_in_codebase.py +78 -0
  28. jarvis/tools/git_commiter.py +68 -0
  29. jarvis/tools/methodology.py +3 -3
  30. jarvis/tools/rag.py +141 -0
  31. jarvis/tools/read_code.py +116 -0
  32. jarvis/tools/read_webpage.py +1 -1
  33. jarvis/tools/registry.py +47 -31
  34. jarvis/tools/search.py +8 -6
  35. jarvis/tools/select_code_files.py +4 -4
  36. jarvis/utils.py +375 -85
  37. {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.104.dist-info}/METADATA +107 -32
  38. jarvis_ai_assistant-0.1.104.dist-info/RECORD +50 -0
  39. jarvis_ai_assistant-0.1.104.dist-info/entry_points.txt +11 -0
  40. jarvis/jarvis_code_agent/main.py +0 -200
  41. jarvis/jarvis_coder/git_utils.py +0 -123
  42. jarvis/jarvis_coder/patch_handler.py +0 -340
  43. jarvis/jarvis_github/main.py +0 -232
  44. jarvis/tools/create_code_sub_agent.py +0 -56
  45. jarvis/tools/execute_code_modification.py +0 -70
  46. jarvis/tools/find_files.py +0 -119
  47. jarvis/tools/generate_tool.py +0 -174
  48. jarvis/tools/thinker.py +0 -151
  49. jarvis_ai_assistant-0.1.102.dist-info/RECORD +0 -46
  50. jarvis_ai_assistant-0.1.102.dist-info/entry_points.txt +0 -6
  51. /jarvis/{jarvis_coder → jarvis_codebase}/__init__.py +0 -0
  52. /jarvis/{jarvis_github → jarvis_rag}/__init__.py +0 -0
  53. {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.104.dist-info}/LICENSE +0 -0
  54. {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.104.dist-info}/WHEEL +0 -0
  55. {jarvis_ai_assistant-0.1.102.dist-info → jarvis_ai_assistant-0.1.104.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,210 @@
1
+ from typing import Dict, Any, List
2
+ import subprocess
3
+ import yaml
4
+ from jarvis.models.registry import PlatformRegistry
5
+ from jarvis.tools.registry import ToolRegistry
6
+ from jarvis.utils import OutputType, PrettyOutput, init_env, find_git_root
7
+ from jarvis.agent import Agent
8
+ import re
9
+
10
+ class CodeReviewTool:
11
+ name = "code_review"
12
+ description = "Autonomous code review agent for code changes analysis"
13
+ parameters = {
14
+ "type": "object",
15
+ "properties": {
16
+ "review_type": {
17
+ "type": "string",
18
+ "description": "Type of review: 'commit' for specific commit, 'current' for current changes",
19
+ "enum": ["commit", "current"],
20
+ "default": "current"
21
+ },
22
+ "commit_sha": {
23
+ "type": "string",
24
+ "description": "Target commit SHA to analyze (required for review_type='commit')"
25
+ }
26
+ },
27
+ "required": []
28
+ }
29
+
30
+ def __init__(self):
31
+ init_env()
32
+ self.repo_root = find_git_root()
33
+
34
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
35
+ try:
36
+ review_type = args.get("review_type", "current").strip()
37
+
38
+ # Build git diff command based on review type
39
+ if review_type == "commit":
40
+ if "commit_sha" not in args:
41
+ return {
42
+ "success": False,
43
+ "stdout": {},
44
+ "stderr": "commit_sha is required for commit review type"
45
+ }
46
+ commit_sha = args["commit_sha"].strip()
47
+ diff_cmd = f"git show {commit_sha} | cat -"
48
+ else: # current changes
49
+ diff_cmd = "git diff HEAD | cat -"
50
+
51
+ # Execute git diff command
52
+ try:
53
+ diff_output = subprocess.check_output(diff_cmd, shell=True, text=True)
54
+ if not diff_output:
55
+ return {
56
+ "success": False,
57
+ "stdout": {},
58
+ "stderr": "No changes to review"
59
+ }
60
+ PrettyOutput.print(diff_output, OutputType.CODE, lang="diff")
61
+ except subprocess.CalledProcessError as e:
62
+ return {
63
+ "success": False,
64
+ "stdout": {},
65
+ "stderr": f"Failed to get diff: {str(e)}"
66
+ }
67
+
68
+ system_prompt = """You are an autonomous code review expert. Perform in-depth analysis following these guidelines:
69
+
70
+ IMPORTANT:
71
+ - Only analyze the provided diff content
72
+ - Do NOT make assumptions about code not shown
73
+ - Do NOT invent or imagine potential issues
74
+ - Report ONLY issues that can be directly observed
75
+ - If something is unclear, state it explicitly rather than making assumptions
76
+
77
+ REVIEW FOCUS AREAS:
78
+ 1. Requirement Alignment:
79
+ - Verify implementation matches original requirements
80
+ - Check for missing functionality
81
+ - Identify over-implementation
82
+
83
+ 2. Code Quality:
84
+ - Code readability and structure
85
+ - Proper error handling
86
+ - Code duplication
87
+ - Adherence to style guides
88
+ - Meaningful variable/method names
89
+
90
+ 3. Security:
91
+ - Input validation
92
+ - Authentication/Authorization checks
93
+ - Sensitive data handling
94
+ - Potential injection vulnerabilities
95
+ - Secure communication practices
96
+
97
+ 4. Testing:
98
+ - Test coverage for new code
99
+ - Edge case handling
100
+ - Test readability and maintainability
101
+ - Missing test scenarios
102
+
103
+ 5. Performance:
104
+ - Algorithm efficiency
105
+ - Unnecessary resource consumption
106
+ - Proper caching mechanisms
107
+ - Database query optimization
108
+
109
+ 6. Maintainability:
110
+ - Documentation quality
111
+ - Logging and monitoring
112
+ - Configuration management
113
+ - Technical debt indicators
114
+
115
+ 7. Operational Considerations:
116
+ - Backward compatibility
117
+ - Migration script safety
118
+ - Environment-specific configurations
119
+ - Deployment impacts
120
+
121
+ REVIEW PROCESS:
122
+ 1. Retrieve full commit context using git commands
123
+ 2. Analyze code changes line-by-line
124
+ 3. Cross-reference with project standards
125
+ 4. Verify test coverage adequacy
126
+ 5. Check documentation updates
127
+ 6. Generate prioritized findings
128
+
129
+ OUTPUT REQUIREMENTS:
130
+ - Categorize issues by severity (Critical/Major/Minor)
131
+ - Reference specific code locations
132
+ - Provide concrete examples from the diff
133
+ - Suggest actionable improvements based on observed code
134
+ - Highlight security risks clearly with evidence from the code
135
+ - Separate technical debt from blockers
136
+ - If certain aspects cannot be reviewed due to limited context, note this explicitly
137
+ - Do not speculate about code not shown in the diff
138
+ """
139
+ tool_registry = ToolRegistry()
140
+ tool_registry.dont_use_tools(["code_review"])
141
+ agent = Agent(
142
+ system_prompt=system_prompt,
143
+ name="Code Review Agent",
144
+ summary_prompt="""Please generate a concise summary report of the code review, format as yaml:
145
+ <REPORT>
146
+ - file: xxxx.py
147
+ location: [start_line_number, end_line_number]
148
+ description: # Only describe issues directly observable in the diff
149
+ severity: # Critical/Major/Minor based on concrete evidence
150
+ suggestion: # Specific, actionable improvements for the observed code
151
+ </REPORT>""",
152
+ is_sub_agent=True,
153
+ tool_registry=tool_registry,
154
+ platform=PlatformRegistry().get_thinking_platform(),
155
+ auto_complete=True
156
+ )
157
+ result = agent.run(diff_output)
158
+ return {
159
+ "success": True,
160
+ "stdout": result,
161
+ "stderr": ""
162
+ }
163
+
164
+ except Exception as e:
165
+ return {
166
+ "success": False,
167
+ "stdout": {},
168
+ "stderr": f"Review failed: {str(e)}"
169
+ }
170
+
171
+
172
+ def _extract_code_report(result: str) -> str:
173
+ sm = re.search(r"<REPORT>(.*?)</REPORT>", result, re.DOTALL)
174
+ if sm:
175
+ return sm.group(1)
176
+ return ""
177
+
178
+ def main():
179
+ """CLI entry point"""
180
+ import argparse
181
+
182
+ parser = argparse.ArgumentParser(description='Autonomous code review tool')
183
+ parser.add_argument('--type', choices=['commit', 'current'], default='current',
184
+ help='Type of review: commit or current changes')
185
+ parser.add_argument('--commit', help='Commit SHA to review (required for commit type)')
186
+ args = parser.parse_args()
187
+
188
+ # Validate arguments
189
+ if args.type == 'commit' and not args.commit:
190
+ parser.error("--commit is required when type is 'commit'")
191
+
192
+ tool = CodeReviewTool()
193
+ tool_args = {
194
+ "review_type": args.type
195
+ }
196
+ if args.commit:
197
+ tool_args["commit_sha"] = args.commit
198
+
199
+ result = tool.execute(tool_args)
200
+
201
+ if result["success"]:
202
+ PrettyOutput.section("Autonomous Review Result:", OutputType.SUCCESS)
203
+ report = _extract_code_report(result["stdout"])
204
+ PrettyOutput.print(report, OutputType.SUCCESS, lang="yaml")
205
+
206
+ else:
207
+ PrettyOutput.print(result["stderr"], OutputType.ERROR)
208
+
209
+ if __name__ == "__main__":
210
+ main()
@@ -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,164 @@
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
+ }
@@ -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
 
@@ -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": return_code == 0,
64
+ "success": True,
65
65
  "stdout": output,
66
66
  "stderr": "",
67
67
  }
@@ -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,78 @@
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
+ }
@@ -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, lang="diff")
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())