jarvis-ai-assistant 0.1.121__tar.gz → 0.1.122__tar.gz
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_ai_assistant-0.1.121/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.122}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/pyproject.toml +1 -2
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/setup.py +1 -2
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/__init__.py +1 -1
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/code_agent.py +36 -58
- jarvis_ai_assistant-0.1.122/src/jarvis/jarvis_code_agent/patch.py +269 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/relevant_files.py +2 -4
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/kimi.py +0 -2
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/file_operation.py +0 -3
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/read_code.py +1 -2
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_utils/__init__.py +3 -3
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -1
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -1
- jarvis_ai_assistant-0.1.121/src/jarvis/jarvis_code_agent/patch.py +0 -446
- jarvis_ai_assistant-0.1.121/src/jarvis/jarvis_dev/main.py +0 -878
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/README.md +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_code_agent/file_select.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_codebase/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_codebase/main.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/base.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/cpp.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/go.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/python.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/registry.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_lsp/rust.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/base.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/ollama.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/oyi.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_platform_manager/openai_test.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_rag/main.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/ask_codebase.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/chdir.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/code_review.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/create_code_agent.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/create_sub_agent.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/execute_shell.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/git_commiter.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_find_definition.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_find_references.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_get_diagnostics.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_prepare_rename.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/lsp_validate_edit.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/rag.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/registry.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/search.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/select_code_files.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/tool_generator.py +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "jarvis-ai-assistant"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.122"
|
|
8
8
|
description = "Jarvis: An AI assistant that uses tools to interact with the system"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Your Name", email = "your.email@example.com" }]
|
|
@@ -64,4 +64,3 @@ jarvis-platform-manager = "jarvis.jarvis_platform_manager.main:main"
|
|
|
64
64
|
jarvis-git-commit = "jarvis.jarvis_tools.git_commiter:main"
|
|
65
65
|
jarvis-code-review = "jarvis.jarvis_tools.code_review:main"
|
|
66
66
|
jgc = "jarvis.jarvis_tools.git_commiter:main"
|
|
67
|
-
jarvis-dev = "jarvis.jarvis_dev.main:main"
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="jarvis-ai-assistant",
|
|
5
|
-
version="0.1.
|
|
5
|
+
version="0.1.122",
|
|
6
6
|
author="skyfire",
|
|
7
7
|
author_email="skyfireitdiy@hotmail.com",
|
|
8
8
|
description="An AI assistant that uses various tools to interact with the system",
|
|
@@ -48,7 +48,6 @@ setup(
|
|
|
48
48
|
"jarvis-platform-manager=jarvis.jarvis_platform_manager.main:main",
|
|
49
49
|
"jarvis-git-commit=jarvis.jarvis_tools.git_commiter:main",
|
|
50
50
|
"jarvis-code-review=jarvis.jarvis_tools.code_review:main",
|
|
51
|
-
"jarvis-dev=jarvis.jarvis_dev.main:main",
|
|
52
51
|
"jgc=jarvis.jarvis_tools.git_commiter:main",
|
|
53
52
|
],
|
|
54
53
|
},
|
|
@@ -29,66 +29,44 @@ class CodeAgent:
|
|
|
29
29
|
"lsp_prepare_rename",
|
|
30
30
|
"lsp_validate_edit"])
|
|
31
31
|
code_system_prompt = """
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
## Core Principles
|
|
46
|
-
1. Deep Code Analysis
|
|
47
|
-
- Thoroughly analyze existing code using `read_code` and LSP tools
|
|
48
|
-
- Identify patterns, conventions, and dependencies
|
|
49
|
-
|
|
50
|
-
2. Change Implementation
|
|
51
|
-
- Produce minimal, focused changes
|
|
52
|
-
- Maintain backward compatibility
|
|
53
|
-
- Follow existing style and patterns exactly
|
|
54
|
-
- Complete implementations (NO TODOs/stubs)
|
|
32
|
+
# Role: Senior Code Engineer
|
|
33
|
+
Expert in precise code modifications with minimal impact.
|
|
34
|
+
|
|
35
|
+
## Key Responsibilities
|
|
36
|
+
1. Code Analysis
|
|
37
|
+
- Use `read_code` and LSP tools before changes
|
|
38
|
+
- Identify dependencies and patterns
|
|
39
|
+
|
|
40
|
+
2. Modification Rules
|
|
41
|
+
- Single atomic change per operation
|
|
42
|
+
- Strict style consistency
|
|
43
|
+
- Complete implementations (no stubs)
|
|
44
|
+
- Full error handling
|
|
55
45
|
|
|
56
46
|
3. Quality Assurance
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
## Tools
|
|
81
|
-
Primary:
|
|
82
|
-
- `read_code` (MUST use for code understanding)
|
|
83
|
-
- LSP tools (analysis/validation)
|
|
84
|
-
- `ask_user` for clarifications
|
|
85
|
-
|
|
86
|
-
## Quality Checklist
|
|
87
|
-
- Maintains all interfaces
|
|
88
|
-
- Matches existing style
|
|
89
|
-
- Complete error handling
|
|
90
|
-
- No overlapping modifications
|
|
91
|
-
- Proper documentation
|
|
47
|
+
- Validate with LSP tools
|
|
48
|
+
- Document complex logic
|
|
49
|
+
- Maintain API contracts
|
|
50
|
+
|
|
51
|
+
## Workflow
|
|
52
|
+
1. File Operations Order:
|
|
53
|
+
a) Move/Remove files
|
|
54
|
+
b) Create new files
|
|
55
|
+
c) Delete code blocks
|
|
56
|
+
d) Replace existing code
|
|
57
|
+
e) Insert new code
|
|
58
|
+
|
|
59
|
+
2. Large File Handling:
|
|
60
|
+
- Locate specific sections first
|
|
61
|
+
- Read targeted ranges
|
|
62
|
+
- Make focused changes
|
|
63
|
+
|
|
64
|
+
## Best Practices
|
|
65
|
+
- Prefer minimal changes over rewrites
|
|
66
|
+
- Preserve existing interfaces
|
|
67
|
+
- Verify line ranges carefully
|
|
68
|
+
- Test edge cases implicitly
|
|
69
|
+
- Document non-obvious logic
|
|
92
70
|
"""
|
|
93
71
|
self.agent = Agent(system_prompt=code_system_prompt,
|
|
94
72
|
name="CodeAgent",
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Dict, Any, List, Tuple
|
|
3
|
+
import os
|
|
4
|
+
from jarvis.jarvis_agent.output_handler import OutputHandler
|
|
5
|
+
from jarvis.jarvis_tools.git_commiter import GitCommitTool
|
|
6
|
+
from jarvis.jarvis_tools.read_code import ReadCodeTool
|
|
7
|
+
from jarvis.jarvis_utils import OutputType, PrettyOutput, get_multiline_input, has_uncommitted_changes, user_confirm
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PatchOutputHandler(OutputHandler):
|
|
11
|
+
def name(self) -> str:
|
|
12
|
+
return "PATCH"
|
|
13
|
+
|
|
14
|
+
def handle(self, response: str) -> Tuple[bool, Any]:
|
|
15
|
+
return False, apply_patch(response)
|
|
16
|
+
|
|
17
|
+
def can_handle(self, response: str) -> bool:
|
|
18
|
+
if _parse_patch(response):
|
|
19
|
+
return True
|
|
20
|
+
return False
|
|
21
|
+
|
|
22
|
+
def prompt(self) -> str:
|
|
23
|
+
return """
|
|
24
|
+
# 🛠️ Simplified Patch Format
|
|
25
|
+
<PATCH>
|
|
26
|
+
File path [Operation parameters]
|
|
27
|
+
Code content
|
|
28
|
+
</PATCH>
|
|
29
|
+
|
|
30
|
+
Operation types:
|
|
31
|
+
- Replace: [Start line,End line] Replace line range (e.g. [5,8] replaces lines 5-8)
|
|
32
|
+
- Delete: [Start line,End line] Delete line range (e.g. [10,10] deletes line 10)
|
|
33
|
+
- Insert: [Line number] Insert before specified line (e.g. [3] inserts before line 3)
|
|
34
|
+
- New file: [1] Create new file
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
# Replace operation
|
|
38
|
+
<PATCH>
|
|
39
|
+
src/app.py [5,8]
|
|
40
|
+
def updated_function():
|
|
41
|
+
print("Replaced lines 5-8")
|
|
42
|
+
return new_value * 2
|
|
43
|
+
</PATCH>
|
|
44
|
+
|
|
45
|
+
# Delete operation
|
|
46
|
+
<PATCH>
|
|
47
|
+
src/old.py [10,10]
|
|
48
|
+
</PATCH>
|
|
49
|
+
|
|
50
|
+
# Insert operation
|
|
51
|
+
<PATCH>
|
|
52
|
+
utils/logger.py [3]
|
|
53
|
+
print("Inserted before original line 3")
|
|
54
|
+
</PATCH>
|
|
55
|
+
|
|
56
|
+
# New file creation
|
|
57
|
+
<PATCH>
|
|
58
|
+
config.yaml [1]
|
|
59
|
+
database:
|
|
60
|
+
host: localhost
|
|
61
|
+
port: 5432
|
|
62
|
+
</PATCH>
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
|
|
67
|
+
"""解析补丁格式"""
|
|
68
|
+
result = {}
|
|
69
|
+
header_pattern = re.compile(
|
|
70
|
+
r'^\s*"?(.+?)"?\s*\[(\d+)(?:,(\d+))?\]\s*$' # Match file path and line number
|
|
71
|
+
)
|
|
72
|
+
patches = re.findall(r'<PATCH>\n?(.*?)\n?</PATCH>', patch_str, re.DOTALL)
|
|
73
|
+
|
|
74
|
+
for patch in patches:
|
|
75
|
+
# 分割首行和内容
|
|
76
|
+
parts = patch.split('\n', 1)
|
|
77
|
+
if len(parts) < 1:
|
|
78
|
+
continue
|
|
79
|
+
header_line = parts[0].strip()
|
|
80
|
+
content = parts[1] if len(parts) > 1 else ''
|
|
81
|
+
|
|
82
|
+
# 仅在内容非空时添加换行符
|
|
83
|
+
if content and not content.endswith('\n'):
|
|
84
|
+
content += '\n'
|
|
85
|
+
|
|
86
|
+
# 解析文件路径和行号
|
|
87
|
+
header_match = header_pattern.match(header_line)
|
|
88
|
+
if not header_match:
|
|
89
|
+
continue
|
|
90
|
+
|
|
91
|
+
filepath = header_match.group(1)
|
|
92
|
+
start = int(header_match.group(2)) # 保持1-based行号
|
|
93
|
+
end = int(header_match.group(3)) + 1 if header_match.group(3) else start
|
|
94
|
+
|
|
95
|
+
# 存储参数
|
|
96
|
+
if filepath not in result:
|
|
97
|
+
result[filepath] = []
|
|
98
|
+
result[filepath].append({
|
|
99
|
+
'filepath': filepath,
|
|
100
|
+
'start': start,
|
|
101
|
+
'end': end,
|
|
102
|
+
'content': content # 保留原始内容(可能为空)
|
|
103
|
+
})
|
|
104
|
+
for filepath in result.keys():
|
|
105
|
+
result[filepath] = sorted(result[filepath], key=lambda x: x['start'], reverse=True)
|
|
106
|
+
return result
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def apply_patch(output_str: str) -> str:
|
|
110
|
+
"""Apply patches to files"""
|
|
111
|
+
try:
|
|
112
|
+
patches = _parse_patch(output_str)
|
|
113
|
+
except Exception as e:
|
|
114
|
+
PrettyOutput.print(f"解析补丁失败: {str(e)}", OutputType.ERROR)
|
|
115
|
+
return ""
|
|
116
|
+
|
|
117
|
+
ret = ""
|
|
118
|
+
|
|
119
|
+
for filepath, patch_list in patches.items():
|
|
120
|
+
for patch in patch_list:
|
|
121
|
+
try:
|
|
122
|
+
handle_code_operation(filepath, patch)
|
|
123
|
+
PrettyOutput.print(f"成功处理 操作", OutputType.SUCCESS)
|
|
124
|
+
except Exception as e:
|
|
125
|
+
PrettyOutput.print(f"操作失败: {str(e)}", OutputType.ERROR)
|
|
126
|
+
|
|
127
|
+
if has_uncommitted_changes():
|
|
128
|
+
diff = get_diff()
|
|
129
|
+
if handle_commit_workflow(diff):
|
|
130
|
+
ret += "Successfully applied the patch\n"
|
|
131
|
+
# Get modified line ranges
|
|
132
|
+
modified_ranges = get_modified_line_ranges()
|
|
133
|
+
modified_code = ReadCodeTool().execute({"files": [{"path": filepath, "start_line": start, "end_line": end} for filepath, (start, end) in modified_ranges.items()]})
|
|
134
|
+
if modified_code["success"]:
|
|
135
|
+
ret += "New code:\n"
|
|
136
|
+
ret += modified_code["stdout"]
|
|
137
|
+
else:
|
|
138
|
+
ret += "User rejected the patch\nThis is your patch preview:\n"
|
|
139
|
+
ret += diff
|
|
140
|
+
user_input = get_multiline_input("你可以继续输入(输入空行重试,Ctrl+C退出): ")
|
|
141
|
+
if user_input:
|
|
142
|
+
ret += "\n" + user_input
|
|
143
|
+
else:
|
|
144
|
+
ret = ""
|
|
145
|
+
|
|
146
|
+
return ret # Ensure a string is always returned
|
|
147
|
+
|
|
148
|
+
def get_diff() -> str:
|
|
149
|
+
"""使用更安全的subprocess代替os.system"""
|
|
150
|
+
import subprocess
|
|
151
|
+
try:
|
|
152
|
+
subprocess.run(['git', 'add', '.'], check=True)
|
|
153
|
+
result = subprocess.run(
|
|
154
|
+
['git', 'diff', 'HEAD'],
|
|
155
|
+
capture_output=True,
|
|
156
|
+
text=True,
|
|
157
|
+
check=True
|
|
158
|
+
)
|
|
159
|
+
return result.stdout
|
|
160
|
+
finally:
|
|
161
|
+
subprocess.run(['git', 'reset', 'HEAD'], check=True)
|
|
162
|
+
|
|
163
|
+
def handle_commit_workflow(diff:str)->bool:
|
|
164
|
+
"""Handle the git commit workflow and return the commit details.
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
tuple[bool, str, str]: (continue_execution, commit_id, commit_message)
|
|
168
|
+
"""
|
|
169
|
+
if not user_confirm("是否要提交代码?", default=True):
|
|
170
|
+
os.system("git reset HEAD")
|
|
171
|
+
os.system("git checkout -- .")
|
|
172
|
+
os.system("git clean -fd")
|
|
173
|
+
return False
|
|
174
|
+
|
|
175
|
+
git_commiter = GitCommitTool()
|
|
176
|
+
commit_result = git_commiter.execute({})
|
|
177
|
+
return commit_result["success"]
|
|
178
|
+
|
|
179
|
+
def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
|
|
180
|
+
"""Get modified line ranges from git diff for all changed files.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Dictionary mapping file paths to tuple with (start_line, end_line) ranges
|
|
184
|
+
for modified sections. Line numbers are 1-based.
|
|
185
|
+
"""
|
|
186
|
+
# Get git diff for all files
|
|
187
|
+
diff_output = os.popen("git show").read()
|
|
188
|
+
|
|
189
|
+
# Parse the diff to get modified files and their line ranges
|
|
190
|
+
result = {}
|
|
191
|
+
current_file = None
|
|
192
|
+
|
|
193
|
+
for line in diff_output.splitlines():
|
|
194
|
+
# Match lines like "+++ b/path/to/file"
|
|
195
|
+
file_match = re.match(r"^\+\+\+ b/(.*)", line)
|
|
196
|
+
if file_match:
|
|
197
|
+
current_file = file_match.group(1)
|
|
198
|
+
continue
|
|
199
|
+
|
|
200
|
+
# Match lines like "@@ -100,5 +100,7 @@" where the + part shows new lines
|
|
201
|
+
range_match = re.match(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", line)
|
|
202
|
+
if range_match and current_file:
|
|
203
|
+
start_line = int(range_match.group(1)) # Keep as 1-based
|
|
204
|
+
line_count = int(range_match.group(2)) if range_match.group(2) else 1
|
|
205
|
+
end_line = start_line + line_count - 1
|
|
206
|
+
result[current_file] = (start_line, end_line)
|
|
207
|
+
|
|
208
|
+
return result
|
|
209
|
+
# New handler functions below ▼▼▼
|
|
210
|
+
|
|
211
|
+
def handle_new_file(filepath: str, patch: Dict[str, Any]):
|
|
212
|
+
"""统一参数格式处理新文件"""
|
|
213
|
+
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
|
214
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
215
|
+
f.write(patch['content'])
|
|
216
|
+
|
|
217
|
+
def handle_code_operation(filepath: str, patch: Dict[str, Any]):
|
|
218
|
+
"""处理紧凑格式补丁"""
|
|
219
|
+
try:
|
|
220
|
+
# 新建文件时强制覆盖
|
|
221
|
+
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
|
222
|
+
if not os.path.exists(filepath):
|
|
223
|
+
open(filepath, 'w', encoding='utf-8').close()
|
|
224
|
+
with open(filepath, 'r+', encoding='utf-8') as f:
|
|
225
|
+
lines = f.readlines()
|
|
226
|
+
|
|
227
|
+
new_lines = validate_and_apply_changes(
|
|
228
|
+
lines,
|
|
229
|
+
patch['start'],
|
|
230
|
+
patch['end'],
|
|
231
|
+
patch['content']
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
f.seek(0)
|
|
235
|
+
f.writelines(new_lines)
|
|
236
|
+
f.truncate()
|
|
237
|
+
|
|
238
|
+
PrettyOutput.print(f"成功更新 {filepath}", OutputType.SUCCESS)
|
|
239
|
+
|
|
240
|
+
except Exception as e:
|
|
241
|
+
PrettyOutput.print(f"操作失败: {str(e)}", OutputType.ERROR)
|
|
242
|
+
|
|
243
|
+
def validate_and_apply_changes(
|
|
244
|
+
lines: List[str],
|
|
245
|
+
start: int,
|
|
246
|
+
end: int,
|
|
247
|
+
content: str
|
|
248
|
+
) -> List[str]:
|
|
249
|
+
|
|
250
|
+
new_content = content.splitlines(keepends=True)
|
|
251
|
+
|
|
252
|
+
# 插入操作处理
|
|
253
|
+
if start == end:
|
|
254
|
+
if start < 1 or start > len(lines)+1:
|
|
255
|
+
raise ValueError(f"无效插入位置: {start}")
|
|
256
|
+
# 在指定位置前插入
|
|
257
|
+
return lines[:start-1] + new_content + lines[start-1:]
|
|
258
|
+
|
|
259
|
+
# 范围替换/删除操作
|
|
260
|
+
if start > end:
|
|
261
|
+
raise ValueError(f"起始行{start}不能大于结束行{end}")
|
|
262
|
+
|
|
263
|
+
max_line = len(lines)
|
|
264
|
+
# 自动修正行号范围
|
|
265
|
+
start = max(1, min(start, max_line+1))
|
|
266
|
+
end = max(start, min(end, max_line+1))
|
|
267
|
+
|
|
268
|
+
# 执行替换
|
|
269
|
+
return lines[:start-1] + new_content + lines[end-1:]
|
|
@@ -60,14 +60,12 @@ Identify customization options:
|
|
|
60
60
|
- "Should we create a new class?"
|
|
61
61
|
|
|
62
62
|
# 🎨 Question Template
|
|
63
|
-
|
|
63
|
+
3-5 specific questions about existing implementations:
|
|
64
64
|
<QUESTION>
|
|
65
|
-
[3-5 specific questions about existing implementations:
|
|
66
65
|
1. System architecture question
|
|
67
66
|
2. Implementation details question
|
|
68
|
-
3. Integration or extension question
|
|
67
|
+
3. Integration or extension question
|
|
69
68
|
</QUESTION>
|
|
70
|
-
```
|
|
71
69
|
|
|
72
70
|
# 🔎 Investigation Focus
|
|
73
71
|
1. Current System
|
|
@@ -57,9 +57,6 @@ class FileOperationTool:
|
|
|
57
57
|
content = open(abs_path, 'r', encoding='utf-8').read()
|
|
58
58
|
output = f"File: {abs_path}\n{content}"
|
|
59
59
|
|
|
60
|
-
# Print file content
|
|
61
|
-
PrettyOutput.print(f"读取文件: {abs_path}\n{content}", OutputType.INFO)
|
|
62
|
-
|
|
63
60
|
return {
|
|
64
61
|
"success": True,
|
|
65
62
|
"stdout": output,
|
{jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_tools/read_code.py
RENAMED
|
@@ -52,7 +52,7 @@ class ReadCodeTool:
|
|
|
52
52
|
"""
|
|
53
53
|
try:
|
|
54
54
|
abs_path = os.path.abspath(filepath.strip())
|
|
55
|
-
PrettyOutput.print(f"正在读取代码文件:{abs_path}", OutputType.INFO)
|
|
55
|
+
PrettyOutput.print(f"正在读取代码文件:{abs_path} [范围: [{start_line},{end_line}]]", OutputType.INFO)
|
|
56
56
|
|
|
57
57
|
if not os.path.exists(abs_path):
|
|
58
58
|
PrettyOutput.print(f"文件不存在: {abs_path}", OutputType.WARNING)
|
|
@@ -120,7 +120,6 @@ class ReadCodeTool:
|
|
|
120
120
|
|
|
121
121
|
content = "".join(formatted_lines)
|
|
122
122
|
output = f"File: {filepath}\nLines: [{start_line}, {end_line}]\n{content}"
|
|
123
|
-
PrettyOutput.print(output, OutputType.CODE)
|
|
124
123
|
return {
|
|
125
124
|
"success": True,
|
|
126
125
|
"stdout": output,
|
{jarvis_ai_assistant-0.1.121 → jarvis_ai_assistant-0.1.122}/src/jarvis/jarvis_utils/__init__.py
RENAMED
|
@@ -174,7 +174,9 @@ class PrettyOutput:
|
|
|
174
174
|
# Add timestamp and agent info
|
|
175
175
|
if timestamp:
|
|
176
176
|
formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}][{output_type.value}]", style=output_type.value)
|
|
177
|
-
|
|
177
|
+
agent_info = get_agent_list()
|
|
178
|
+
if agent_info: # Only add brackets if there's agent info
|
|
179
|
+
formatted.append(f"[{agent_info}]", style="blue")
|
|
178
180
|
# Add icon
|
|
179
181
|
icon = PrettyOutput._ICONS.get(output_type, "")
|
|
180
182
|
formatted.append(f" {icon} ", style=output_type.value)
|
|
@@ -211,7 +213,6 @@ class PrettyOutput:
|
|
|
211
213
|
color="bright_blue",
|
|
212
214
|
bold=True,
|
|
213
215
|
italic=True,
|
|
214
|
-
overline=True,
|
|
215
216
|
bgcolor="navy_blue"
|
|
216
217
|
),
|
|
217
218
|
OutputType.ERROR: RichStyle(
|
|
@@ -267,7 +268,6 @@ class PrettyOutput:
|
|
|
267
268
|
color="dark_sea_green4",
|
|
268
269
|
italic=True,
|
|
269
270
|
bgcolor="grey19",
|
|
270
|
-
overline=True
|
|
271
271
|
)
|
|
272
272
|
}
|
|
273
273
|
|
|
@@ -13,7 +13,6 @@ src/jarvis/jarvis_code_agent/patch.py
|
|
|
13
13
|
src/jarvis/jarvis_code_agent/relevant_files.py
|
|
14
14
|
src/jarvis/jarvis_codebase/__init__.py
|
|
15
15
|
src/jarvis/jarvis_codebase/main.py
|
|
16
|
-
src/jarvis/jarvis_dev/main.py
|
|
17
16
|
src/jarvis/jarvis_lsp/base.py
|
|
18
17
|
src/jarvis/jarvis_lsp/cpp.py
|
|
19
18
|
src/jarvis/jarvis_lsp/go.py
|
|
@@ -3,7 +3,6 @@ jarvis = jarvis.jarvis_agent:main
|
|
|
3
3
|
jarvis-code-agent = jarvis.jarvis_code_agent.code_agent:main
|
|
4
4
|
jarvis-code-review = jarvis.jarvis_tools.code_review:main
|
|
5
5
|
jarvis-codebase = jarvis.jarvis_codebase.main:main
|
|
6
|
-
jarvis-dev = jarvis.jarvis_dev.main:main
|
|
7
6
|
jarvis-git-commit = jarvis.jarvis_tools.git_commiter:main
|
|
8
7
|
jarvis-platform-manager = jarvis.jarvis_platform_manager.main:main
|
|
9
8
|
jarvis-rag = jarvis.jarvis_rag.main:main
|