jarvis-ai-assistant 0.1.119__tar.gz → 0.1.121__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.119/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.121}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/pyproject.toml +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/setup.py +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/__init__.py +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_agent/__init__.py +3 -3
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_code_agent/file_select.py +3 -3
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_code_agent/patch.py +74 -34
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_codebase/main.py +2 -2
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_lsp/registry.py +7 -7
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/ai8.py +10 -10
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/base.py +15 -2
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/kimi.py +3 -3
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/oyi.py +11 -11
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/registry.py +3 -3
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform_manager/main.py +2 -2
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/ask_codebase.py +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/code_review.py +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/create_code_agent.py +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/git_commiter.py +26 -7
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/rag.py +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_utils/__init__.py +120 -47
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/README.md +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_code_agent/code_agent.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_code_agent/relevant_files.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_codebase/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_dev/main.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_lsp/base.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_lsp/cpp.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_lsp/go.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_lsp/python.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_lsp/rust.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/ollama.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform_manager/openai_test.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_rag/main.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/chdir.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/create_sub_agent.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/execute_shell.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/file_operation.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/lsp_find_definition.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/lsp_find_references.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/lsp_get_diagnostics.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/lsp_prepare_rename.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/lsp_validate_edit.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/read_code.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/registry.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/search.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/select_code_files.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/tool_generator.py +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/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.121"
|
|
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" }]
|
|
@@ -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.121",
|
|
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",
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_agent/__init__.py
RENAMED
|
@@ -222,7 +222,7 @@ Please continue the task based on the above information.
|
|
|
222
222
|
if handler.can_handle(response):
|
|
223
223
|
tool_list.append(handler)
|
|
224
224
|
if len(tool_list) > 1:
|
|
225
|
-
PrettyOutput.print(f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([handler.name() for handler in tool_list])}", OutputType.
|
|
225
|
+
PrettyOutput.print(f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([handler.name() for handler in tool_list])}", OutputType.WARNING)
|
|
226
226
|
return False, f"Action failed: Multiple actions detected. Please only perform one action at a time. Actions attempted: {', '.join([handler.name() for handler in tool_list])}"
|
|
227
227
|
if len(tool_list) == 0:
|
|
228
228
|
return False, ""
|
|
@@ -376,7 +376,7 @@ def _load_tasks() -> dict:
|
|
|
376
376
|
if desc: # Ensure description is not empty
|
|
377
377
|
tasks[str(name)] = str(desc)
|
|
378
378
|
else:
|
|
379
|
-
PrettyOutput.print("警告: ~/.jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.
|
|
379
|
+
PrettyOutput.print("警告: ~/.jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.WARNING)
|
|
380
380
|
except Exception as e:
|
|
381
381
|
PrettyOutput.print(f"加载 ~/.jarvis/pre-command 文件失败: {str(e)}", OutputType.ERROR)
|
|
382
382
|
|
|
@@ -392,7 +392,7 @@ def _load_tasks() -> dict:
|
|
|
392
392
|
if desc: # Ensure description is not empty
|
|
393
393
|
tasks[str(name)] = str(desc)
|
|
394
394
|
else:
|
|
395
|
-
PrettyOutput.print("警告: .jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.
|
|
395
|
+
PrettyOutput.print("警告: .jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.WARNING)
|
|
396
396
|
except Exception as e:
|
|
397
397
|
PrettyOutput.print(f"加载 .jarvis/pre-command 文件失败: {str(e)}", OutputType.ERROR)
|
|
398
398
|
|
|
@@ -231,7 +231,7 @@ def file_input_handler(user_input: str, agent: Any) -> str:
|
|
|
231
231
|
file_refs = re.findall(r'`([^`]+)`', user_input)
|
|
232
232
|
|
|
233
233
|
for ref in file_refs:
|
|
234
|
-
# Handle file:start,end format
|
|
234
|
+
# Handle file:start,end or file:start:end format
|
|
235
235
|
if ':' in ref:
|
|
236
236
|
file_path, line_range = ref.split(':', 1)
|
|
237
237
|
# Initialize with default values
|
|
@@ -239,9 +239,9 @@ def file_input_handler(user_input: str, agent: Any) -> str:
|
|
|
239
239
|
end_line = -1
|
|
240
240
|
|
|
241
241
|
# Process line range if specified
|
|
242
|
-
if ',' in line_range:
|
|
242
|
+
if ',' in line_range or ':' in line_range:
|
|
243
243
|
try:
|
|
244
|
-
raw_start, raw_end = map(int,
|
|
244
|
+
raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
|
|
245
245
|
|
|
246
246
|
# Handle special values and Python-style negative indices
|
|
247
247
|
with open(file_path, 'r', encoding='utf-8') as f:
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_code_agent/patch.py
RENAMED
|
@@ -21,23 +21,20 @@ class PatchOutputHandler(OutputHandler):
|
|
|
21
21
|
|
|
22
22
|
def prompt(self) -> str:
|
|
23
23
|
return """
|
|
24
|
-
# 📝 Code Modification Format
|
|
25
|
-
Use specific blocks for different operations:
|
|
26
|
-
|
|
27
24
|
# 🔄 REPLACE: Modify existing code
|
|
28
25
|
<REPLACE>
|
|
29
26
|
File: path/to/file
|
|
30
27
|
Lines: [start,end] or [start,end)
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
[new content]
|
|
29
|
+
...
|
|
33
30
|
</REPLACE>
|
|
34
31
|
|
|
35
32
|
# ➕ INSERT: Add new code
|
|
36
33
|
<INSERT>
|
|
37
34
|
File: path/to/file
|
|
38
35
|
Line: position
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
[new content]
|
|
37
|
+
...
|
|
41
38
|
</INSERT>
|
|
42
39
|
|
|
43
40
|
# 🗑️ DELETE: Remove existing code
|
|
@@ -49,8 +46,8 @@ Lines: [start,end] or [start,end)
|
|
|
49
46
|
# 🆕 NEW_FILE: Create new file
|
|
50
47
|
<NEW_FILE>
|
|
51
48
|
File: path/to/file
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
[new content]
|
|
50
|
+
...
|
|
54
51
|
</NEW_FILE>
|
|
55
52
|
|
|
56
53
|
# ➡️ MOVE_FILE: Relocate a file
|
|
@@ -77,7 +74,6 @@ File: path/to/file
|
|
|
77
74
|
- Omit for NEW_FILE/REMOVE_FILE
|
|
78
75
|
|
|
79
76
|
3. Content
|
|
80
|
-
- Use "-----" separator
|
|
81
77
|
- Maintain original indentation
|
|
82
78
|
- Follow existing code style
|
|
83
79
|
|
|
@@ -86,7 +82,6 @@ File: path/to/file
|
|
|
86
82
|
<REPLACE>
|
|
87
83
|
File: src/utils.py
|
|
88
84
|
Lines: [9,13]
|
|
89
|
-
-----
|
|
90
85
|
def updated_function():
|
|
91
86
|
# Replaces lines 9-13 inclusive
|
|
92
87
|
return "new_implementation"
|
|
@@ -96,7 +91,6 @@ def updated_function():
|
|
|
96
91
|
<REPLACE>
|
|
97
92
|
File: src/calculator.py
|
|
98
93
|
Lines: [5,8)
|
|
99
|
-
-----
|
|
100
94
|
def new_calculation():
|
|
101
95
|
# Replaces lines 5-7 (excludes line 8)
|
|
102
96
|
return 42
|
|
@@ -106,7 +100,6 @@ def new_calculation():
|
|
|
106
100
|
<INSERT>
|
|
107
101
|
File: src/main.py
|
|
108
102
|
Line: 19
|
|
109
|
-
-----
|
|
110
103
|
# Inserted before line 19
|
|
111
104
|
new_feature()
|
|
112
105
|
</INSERT>
|
|
@@ -114,7 +107,6 @@ Line: 19
|
|
|
114
107
|
## NEW_FILE Example
|
|
115
108
|
<NEW_FILE>
|
|
116
109
|
File: src/new_module.py
|
|
117
|
-
-----
|
|
118
110
|
# New file creation
|
|
119
111
|
def feature_entry():
|
|
120
112
|
pass
|
|
@@ -146,6 +138,37 @@ File: src/obsolete.py
|
|
|
146
138
|
6. Handle edge cases properly
|
|
147
139
|
7. Include error handling
|
|
148
140
|
8. Maintain code consistency
|
|
141
|
+
|
|
142
|
+
# 🚫 Invalid Format Examples
|
|
143
|
+
## BAD EXAMPLE 1 - Do not use diff format
|
|
144
|
+
<REPLACE>
|
|
145
|
+
File: src/file.py
|
|
146
|
+
Lines: [5,8)
|
|
147
|
+
- old_line_1
|
|
148
|
+
+ new_line_1
|
|
149
|
+
</REPLACE>
|
|
150
|
+
|
|
151
|
+
## BAD EXAMPLE 2 - Do not include previous and new tags
|
|
152
|
+
<REPLACE>
|
|
153
|
+
File: src/file.py
|
|
154
|
+
Lines: [10,12]
|
|
155
|
+
<PREVIOUS>
|
|
156
|
+
old_code
|
|
157
|
+
</PREVIOUS>
|
|
158
|
+
<NEW>
|
|
159
|
+
new_code
|
|
160
|
+
</NEW>
|
|
161
|
+
</REPLACE>
|
|
162
|
+
|
|
163
|
+
## BAD EXAMPLE 3 - Do not use comment to explain
|
|
164
|
+
<REPLACE>
|
|
165
|
+
File: src/file.py
|
|
166
|
+
Lines: [15,18]
|
|
167
|
+
# Replace the following code
|
|
168
|
+
old_function()
|
|
169
|
+
# With the new implementation
|
|
170
|
+
new_function()
|
|
171
|
+
</REPLACE>
|
|
149
172
|
"""
|
|
150
173
|
|
|
151
174
|
|
|
@@ -172,13 +195,13 @@ def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
|
|
|
172
195
|
if patch_type in ['REPLACE', 'DELETE']:
|
|
173
196
|
# 增强正则表达式兼容性
|
|
174
197
|
line_match = re.match(
|
|
175
|
-
r"^Lines:\s*\[\s*(\d+)\s
|
|
198
|
+
r"^Lines:\s*\[\s*(\d+)\s*(?:,\s*(\d+)\s*)?([\]\)])\s*$", # 支持单数字格式
|
|
176
199
|
lines[1].strip(), # 去除前后空格
|
|
177
200
|
re.IGNORECASE
|
|
178
201
|
)
|
|
179
202
|
if line_match:
|
|
180
203
|
start_line = int(line_match.group(1))
|
|
181
|
-
end_value = int(line_match.group(2))
|
|
204
|
+
end_value = int(line_match.group(2) or line_match.group(1)) # 第二个数字不存在时使用第一个
|
|
182
205
|
bracket_type = line_match.group(3).strip()
|
|
183
206
|
|
|
184
207
|
# 根据括号类型处理区间
|
|
@@ -204,9 +227,21 @@ def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
|
|
|
204
227
|
else:
|
|
205
228
|
continue
|
|
206
229
|
|
|
207
|
-
# Get content (after
|
|
208
|
-
|
|
209
|
-
|
|
230
|
+
# Get content (after metadata)
|
|
231
|
+
if patch_type in ['REPLACE', 'DELETE']:
|
|
232
|
+
content_start = 2 # File + Lines
|
|
233
|
+
elif patch_type == 'INSERT':
|
|
234
|
+
content_start = 2 # File + Line
|
|
235
|
+
elif patch_type == 'NEW_FILE':
|
|
236
|
+
content_start = 1 # File
|
|
237
|
+
elif patch_type == 'MOVE_FILE':
|
|
238
|
+
content_start = 2 # File + NewPath
|
|
239
|
+
elif patch_type == 'REMOVE_FILE':
|
|
240
|
+
content_start = 1 # File
|
|
241
|
+
|
|
242
|
+
content_lines = lines[content_start:]
|
|
243
|
+
# 保留原始缩进和空行
|
|
244
|
+
content = '\n'.join(content_lines).rstrip('\n') + '\n' # 保留末尾换行
|
|
210
245
|
|
|
211
246
|
if filepath not in result:
|
|
212
247
|
result[filepath] = []
|
|
@@ -257,7 +292,8 @@ def apply_patch(output_str: str) -> str:
|
|
|
257
292
|
continue
|
|
258
293
|
|
|
259
294
|
if has_uncommitted_changes():
|
|
260
|
-
|
|
295
|
+
diff = get_diff()
|
|
296
|
+
if handle_commit_workflow(diff):
|
|
261
297
|
ret += "Successfully applied the patch\n"
|
|
262
298
|
# Get modified line ranges
|
|
263
299
|
modified_ranges = get_modified_line_ranges()
|
|
@@ -266,25 +302,27 @@ def apply_patch(output_str: str) -> str:
|
|
|
266
302
|
ret += "New code:\n"
|
|
267
303
|
ret += modified_code["stdout"]
|
|
268
304
|
else:
|
|
269
|
-
ret += "User rejected the patch"
|
|
270
|
-
|
|
305
|
+
ret += "User rejected the patch\nThis is your patch preview:\n"
|
|
306
|
+
ret += diff
|
|
307
|
+
user_input = get_multiline_input("你可以继续输入(输入空行重试,Ctrl+C退出): ")
|
|
271
308
|
if user_input:
|
|
272
309
|
ret += "\n" + user_input
|
|
273
310
|
else:
|
|
274
|
-
|
|
311
|
+
ret += "Please check the patch again"
|
|
275
312
|
|
|
276
313
|
return ret # Ensure a string is always returned
|
|
277
|
-
|
|
278
|
-
def
|
|
314
|
+
|
|
315
|
+
def get_diff()->str:
|
|
316
|
+
os.system("git add .")
|
|
317
|
+
diff = os.popen("git diff HEAD").read()
|
|
318
|
+
os.system("git reset HEAD")
|
|
319
|
+
return diff
|
|
320
|
+
def handle_commit_workflow(diff:str)->bool:
|
|
279
321
|
"""Handle the git commit workflow and return the commit details.
|
|
280
322
|
|
|
281
323
|
Returns:
|
|
282
324
|
tuple[bool, str, str]: (continue_execution, commit_id, commit_message)
|
|
283
325
|
"""
|
|
284
|
-
os.system("git add .")
|
|
285
|
-
diff = os.popen("git diff HEAD").read()
|
|
286
|
-
os.system("git reset HEAD")
|
|
287
|
-
PrettyOutput.print(diff, OutputType.CODE, lang="diff")
|
|
288
326
|
if not user_confirm("是否要提交代码?", default=True):
|
|
289
327
|
os.system("git reset HEAD")
|
|
290
328
|
os.system("git checkout -- .")
|
|
@@ -300,7 +338,7 @@ def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
|
|
|
300
338
|
|
|
301
339
|
Returns:
|
|
302
340
|
Dictionary mapping file paths to tuple with (start_line, end_line) ranges
|
|
303
|
-
for modified sections. Line numbers are
|
|
341
|
+
for modified sections. Line numbers are 1-based.
|
|
304
342
|
"""
|
|
305
343
|
# Get git diff for all files
|
|
306
344
|
diff_output = os.popen("git show").read()
|
|
@@ -319,13 +357,12 @@ def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
|
|
|
319
357
|
# Match lines like "@@ -100,5 +100,7 @@" where the + part shows new lines
|
|
320
358
|
range_match = re.match(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", line)
|
|
321
359
|
if range_match and current_file:
|
|
322
|
-
start_line = int(range_match.group(1))
|
|
360
|
+
start_line = int(range_match.group(1)) # Keep as 1-based
|
|
323
361
|
line_count = int(range_match.group(2)) if range_match.group(2) else 1
|
|
324
|
-
end_line = start_line + line_count
|
|
362
|
+
end_line = start_line + line_count - 1
|
|
325
363
|
result[current_file] = (start_line, end_line)
|
|
326
364
|
|
|
327
365
|
return result
|
|
328
|
-
|
|
329
366
|
# New handler functions below ▼▼▼
|
|
330
367
|
|
|
331
368
|
def handle_move_file(filepath: str, patch: Dict[str, Any]):
|
|
@@ -364,7 +401,10 @@ def handle_code_operation(filepath: str, patch: Dict[str, Any]):
|
|
|
364
401
|
end_line = patch.get('end_line', 0)
|
|
365
402
|
new_content = patch.get('content', '').splitlines(keepends=True)
|
|
366
403
|
|
|
367
|
-
|
|
404
|
+
if not new_content:
|
|
405
|
+
new_content = ['']
|
|
406
|
+
|
|
407
|
+
PrettyOutput.print(f"patch_type: {patch_type}\nstart_line: {start_line}\nend_line: {end_line}\nnew_content:\n{''.join(new_content)}", OutputType.INFO)
|
|
368
408
|
|
|
369
409
|
if new_content and new_content[-1] and new_content[-1][-1] != '\n':
|
|
370
410
|
new_content[-1] += '\n'
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_codebase/main.py
RENAMED
|
@@ -336,7 +336,7 @@ Content: {content}
|
|
|
336
336
|
vectors = np.vstack(vectors)
|
|
337
337
|
if len(vectors) != len(ids):
|
|
338
338
|
PrettyOutput.print(f"向量数量不匹配: {len(vectors)} 个向量 vs {len(ids)} 个ID",
|
|
339
|
-
output_type=OutputType.
|
|
339
|
+
output_type=OutputType.WARNING)
|
|
340
340
|
self.index = None
|
|
341
341
|
return
|
|
342
342
|
|
|
@@ -441,7 +441,7 @@ Content: {content}
|
|
|
441
441
|
output_lines.append("删除的文件:")
|
|
442
442
|
output_lines.extend(f" {f}" for f in deleted_files)
|
|
443
443
|
|
|
444
|
-
PrettyOutput.print("\n".join(output_lines), output_type=OutputType.
|
|
444
|
+
PrettyOutput.print("\n".join(output_lines), output_type=OutputType.INFO)
|
|
445
445
|
|
|
446
446
|
# If force is True, continue directly
|
|
447
447
|
if not force:
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_lsp/registry.py
RENAMED
|
@@ -59,8 +59,8 @@ class LSPRegistry:
|
|
|
59
59
|
|
|
60
60
|
if missing_methods:
|
|
61
61
|
PrettyOutput.print(
|
|
62
|
-
f"LSP {lsp_class.__name__}
|
|
63
|
-
OutputType.
|
|
62
|
+
f"LSP {lsp_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
|
|
63
|
+
OutputType.WARNING
|
|
64
64
|
)
|
|
65
65
|
return False
|
|
66
66
|
|
|
@@ -72,7 +72,7 @@ class LSPRegistry:
|
|
|
72
72
|
lsp_servers = {}
|
|
73
73
|
|
|
74
74
|
if not os.path.exists(directory):
|
|
75
|
-
PrettyOutput.print(f"LSP 目录不存在: {directory}", OutputType.
|
|
75
|
+
PrettyOutput.print(f"LSP 目录不存在: {directory}", OutputType.WARNING)
|
|
76
76
|
return lsp_servers
|
|
77
77
|
|
|
78
78
|
package_name = None
|
|
@@ -138,7 +138,7 @@ class LSPRegistry:
|
|
|
138
138
|
def create_lsp(self, language: str) -> Optional[BaseLSP]:
|
|
139
139
|
"""Create LSP instance for specified language."""
|
|
140
140
|
if language not in self.lsp_servers:
|
|
141
|
-
PrettyOutput.print(f"没有找到 LSP 支持的语言: {language}", OutputType.
|
|
141
|
+
PrettyOutput.print(f"没有找到 LSP 支持的语言: {language}", OutputType.WARNING)
|
|
142
142
|
return None
|
|
143
143
|
|
|
144
144
|
try:
|
|
@@ -186,11 +186,11 @@ def main():
|
|
|
186
186
|
lsp = registry.create_lsp(args.language)
|
|
187
187
|
|
|
188
188
|
if not lsp:
|
|
189
|
-
PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.
|
|
189
|
+
PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.WARNING)
|
|
190
190
|
return 1
|
|
191
191
|
|
|
192
192
|
if not lsp.initialize(os.path.dirname(os.path.abspath(args.file))):
|
|
193
|
-
PrettyOutput.print("LSP 初始化失败", OutputType.
|
|
193
|
+
PrettyOutput.print("LSP 初始化失败", OutputType.WARNING)
|
|
194
194
|
return 1
|
|
195
195
|
|
|
196
196
|
try:
|
|
@@ -208,7 +208,7 @@ def main():
|
|
|
208
208
|
|
|
209
209
|
elif args.action in ('references', 'definition'):
|
|
210
210
|
if args.line is None or args.character is None:
|
|
211
|
-
PrettyOutput.print("需要行和字符位置用于 references/definition", OutputType.
|
|
211
|
+
PrettyOutput.print("需要行和字符位置用于 references/definition", OutputType.WARNING)
|
|
212
212
|
return 1
|
|
213
213
|
|
|
214
214
|
if args.action == 'references':
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/ai8.py
RENAMED
|
@@ -60,12 +60,12 @@ class AI8Model(BasePlatform):
|
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
if response.status_code != 200:
|
|
63
|
-
PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.
|
|
63
|
+
PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.WARNING)
|
|
64
64
|
return False
|
|
65
65
|
|
|
66
66
|
data = response.json()
|
|
67
67
|
if data['code'] != 0:
|
|
68
|
-
PrettyOutput.print(f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.
|
|
68
|
+
PrettyOutput.print(f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
|
|
69
69
|
return False
|
|
70
70
|
|
|
71
71
|
self.conversation = data['data']
|
|
@@ -93,10 +93,10 @@ class AI8Model(BasePlatform):
|
|
|
93
93
|
self.conversation = data['data']
|
|
94
94
|
return True
|
|
95
95
|
else:
|
|
96
|
-
PrettyOutput.print(f"更新会话设置失败: {data.get('msg', '未知错误')}", OutputType.
|
|
96
|
+
PrettyOutput.print(f"更新会话设置失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
|
|
97
97
|
return False
|
|
98
98
|
else:
|
|
99
|
-
PrettyOutput.print(f"更新会话设置失败: {response.status_code}", OutputType.
|
|
99
|
+
PrettyOutput.print(f"更新会话设置失败: {response.status_code}", OutputType.WARNING)
|
|
100
100
|
return False
|
|
101
101
|
|
|
102
102
|
except Exception as e:
|
|
@@ -162,7 +162,7 @@ class AI8Model(BasePlatform):
|
|
|
162
162
|
|
|
163
163
|
if response.status_code != 200:
|
|
164
164
|
error_msg = f"Failed to chat: {response.status_code} {response.text}"
|
|
165
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
165
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
166
166
|
raise Exception(error_msg)
|
|
167
167
|
|
|
168
168
|
# 处理流式响应
|
|
@@ -229,11 +229,11 @@ class AI8Model(BasePlatform):
|
|
|
229
229
|
return True
|
|
230
230
|
else:
|
|
231
231
|
error_msg = f"删除会话失败: {data.get('msg', '未知错误')}"
|
|
232
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
232
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
233
233
|
return False
|
|
234
234
|
else:
|
|
235
235
|
error_msg = f"删除会话请求失败: {response.status_code}"
|
|
236
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
236
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
237
237
|
return False
|
|
238
238
|
|
|
239
239
|
except Exception as e:
|
|
@@ -265,12 +265,12 @@ class AI8Model(BasePlatform):
|
|
|
265
265
|
)
|
|
266
266
|
|
|
267
267
|
if response.status_code != 200:
|
|
268
|
-
PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.
|
|
268
|
+
PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.WARNING)
|
|
269
269
|
return []
|
|
270
270
|
|
|
271
271
|
data = response.json()
|
|
272
272
|
if data['code'] != 0:
|
|
273
|
-
PrettyOutput.print(f"获取模型列表失败: {data.get('msg', '未知错误')}", OutputType.
|
|
273
|
+
PrettyOutput.print(f"获取模型列表失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
|
|
274
274
|
return []
|
|
275
275
|
|
|
276
276
|
# 保存模型信息
|
|
@@ -309,6 +309,6 @@ class AI8Model(BasePlatform):
|
|
|
309
309
|
return list(self.models.keys())
|
|
310
310
|
|
|
311
311
|
except Exception as e:
|
|
312
|
-
PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.
|
|
312
|
+
PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.ERROR)
|
|
313
313
|
return []
|
|
314
314
|
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/base.py
RENAMED
|
@@ -45,9 +45,22 @@ class BasePlatform(ABC):
|
|
|
45
45
|
duration = end_time - start_time
|
|
46
46
|
char_count = len(response)
|
|
47
47
|
|
|
48
|
+
# Calculate token count and tokens per second
|
|
49
|
+
try:
|
|
50
|
+
from jarvis.jarvis_utils import get_context_token_count
|
|
51
|
+
token_count = get_context_token_count(response)
|
|
52
|
+
tokens_per_second = token_count / duration if duration > 0 else 0
|
|
53
|
+
except Exception as e:
|
|
54
|
+
PrettyOutput.print(f"Tokenization failed: {str(e)}", OutputType.WARNING)
|
|
55
|
+
token_count = 0
|
|
56
|
+
tokens_per_second = 0
|
|
57
|
+
|
|
48
58
|
# Print statistics
|
|
49
|
-
PrettyOutput.print(
|
|
50
|
-
|
|
59
|
+
PrettyOutput.print(
|
|
60
|
+
f"对话完成 - 耗时: {duration:.2f}秒, 输出字符数: {char_count}, 输出Token数量: {token_count}, 每秒Token数量: {tokens_per_second:.2f}",
|
|
61
|
+
OutputType.INFO,
|
|
62
|
+
)
|
|
63
|
+
|
|
51
64
|
# Keep original think tag handling
|
|
52
65
|
response = re.sub(r'<<think>>.*?</</think>>', '', response, flags=re.DOTALL)
|
|
53
66
|
return response
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/kimi.py
RENAMED
|
@@ -198,11 +198,11 @@ class KimiModel(BasePlatform):
|
|
|
198
198
|
if self._wait_for_parse(file_info["id"]):
|
|
199
199
|
uploaded_files.append(file_info)
|
|
200
200
|
else:
|
|
201
|
-
PrettyOutput.print(f"✗ 文件解析失败: {file_path}", OutputType.
|
|
201
|
+
PrettyOutput.print(f"✗ 文件解析失败: {file_path}", OutputType.WARNING)
|
|
202
202
|
else:
|
|
203
203
|
uploaded_files.append(file_info)
|
|
204
204
|
else:
|
|
205
|
-
PrettyOutput.print(f"错误:文件上传失败: {file_path}", OutputType.
|
|
205
|
+
PrettyOutput.print(f"错误:文件上传失败: {file_path}", OutputType.WARNING)
|
|
206
206
|
|
|
207
207
|
except Exception as e:
|
|
208
208
|
PrettyOutput.print(f"✗ 处理文件出错 {file_path}: {str(e)}", OutputType.ERROR)
|
|
@@ -375,7 +375,7 @@ class KimiModel(BasePlatform):
|
|
|
375
375
|
self.reset()
|
|
376
376
|
return True
|
|
377
377
|
else:
|
|
378
|
-
PrettyOutput.print(f"删除会话失败: HTTP {response.status_code}", OutputType.
|
|
378
|
+
PrettyOutput.print(f"删除会话失败: HTTP {response.status_code}", OutputType.WARNING)
|
|
379
379
|
return False
|
|
380
380
|
except Exception as e:
|
|
381
381
|
PrettyOutput.print(f"删除会话时发生错误: {str(e)}", OutputType.ERROR)
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/oyi.py
RENAMED
|
@@ -83,10 +83,10 @@ class OyiModel(BasePlatform):
|
|
|
83
83
|
self.conversation = data
|
|
84
84
|
return True
|
|
85
85
|
else:
|
|
86
|
-
PrettyOutput.print(f"创建会话失败: {data['message']}", OutputType.
|
|
86
|
+
PrettyOutput.print(f"创建会话失败: {data['message']}", OutputType.WARNING)
|
|
87
87
|
return False
|
|
88
88
|
else:
|
|
89
|
-
PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.
|
|
89
|
+
PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.WARNING)
|
|
90
90
|
return False
|
|
91
91
|
|
|
92
92
|
except Exception as e:
|
|
@@ -157,13 +157,13 @@ class OyiModel(BasePlatform):
|
|
|
157
157
|
|
|
158
158
|
if response.status_code != 200:
|
|
159
159
|
error_msg = f"聊天请求失败: {response.status_code}"
|
|
160
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
160
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
161
161
|
raise Exception(error_msg)
|
|
162
162
|
|
|
163
163
|
data = response.json()
|
|
164
164
|
if data['code'] != 200 or data['type'] != 'success':
|
|
165
165
|
error_msg = f"聊天失败: {data.get('message', '未知错误')}"
|
|
166
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
166
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
167
167
|
raise Exception(error_msg)
|
|
168
168
|
|
|
169
169
|
message_id = data['result'][-1]
|
|
@@ -196,7 +196,7 @@ class OyiModel(BasePlatform):
|
|
|
196
196
|
return full_response
|
|
197
197
|
else:
|
|
198
198
|
error_msg = f"获取响应失败: {response.status_code}"
|
|
199
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
199
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
200
200
|
raise Exception(error_msg)
|
|
201
201
|
except Exception as e:
|
|
202
202
|
PrettyOutput.print(f"聊天失败: {str(e)}", OutputType.ERROR)
|
|
@@ -241,11 +241,11 @@ class OyiModel(BasePlatform):
|
|
|
241
241
|
return True
|
|
242
242
|
else:
|
|
243
243
|
error_msg = f"删除会话失败: {data.get('message', '未知错误')}"
|
|
244
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
244
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
245
245
|
return False
|
|
246
246
|
else:
|
|
247
247
|
error_msg = f"删除会话请求失败: {response.status_code}"
|
|
248
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
248
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
249
249
|
return False
|
|
250
250
|
|
|
251
251
|
except Exception as e:
|
|
@@ -281,7 +281,7 @@ class OyiModel(BasePlatform):
|
|
|
281
281
|
# 检查文件类型
|
|
282
282
|
file_type = mimetypes.guess_type(file_path)[0]
|
|
283
283
|
if not file_type or not file_type.startswith(('image/', 'text/', 'application/')):
|
|
284
|
-
PrettyOutput.print(f"文件类型 {file_type} 不支持", OutputType.
|
|
284
|
+
PrettyOutput.print(f"文件类型 {file_type} 不支持", OutputType.WARNING)
|
|
285
285
|
continue
|
|
286
286
|
|
|
287
287
|
with open(file_path, 'rb') as f:
|
|
@@ -300,10 +300,10 @@ class OyiModel(BasePlatform):
|
|
|
300
300
|
if data.get('code') == 200:
|
|
301
301
|
self.files.append(data)
|
|
302
302
|
else:
|
|
303
|
-
PrettyOutput.print(f"文件上传失败: {data.get('message')}", OutputType.
|
|
303
|
+
PrettyOutput.print(f"文件上传失败: {data.get('message')}", OutputType.WARNING)
|
|
304
304
|
return []
|
|
305
305
|
else:
|
|
306
|
-
PrettyOutput.print(f"文件上传失败: {response.status_code}", OutputType.
|
|
306
|
+
PrettyOutput.print(f"文件上传失败: {response.status_code}", OutputType.WARNING)
|
|
307
307
|
return []
|
|
308
308
|
|
|
309
309
|
return self.files
|
|
@@ -335,7 +335,7 @@ class OyiModel(BasePlatform):
|
|
|
335
335
|
)
|
|
336
336
|
|
|
337
337
|
if response.status_code != 200:
|
|
338
|
-
PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.
|
|
338
|
+
PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.WARNING)
|
|
339
339
|
return []
|
|
340
340
|
|
|
341
341
|
data = response.json()
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/registry.py
RENAMED
|
@@ -72,7 +72,7 @@ class PlatformRegistry:
|
|
|
72
72
|
if missing_methods:
|
|
73
73
|
PrettyOutput.print(
|
|
74
74
|
f"平台 {platform_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
|
|
75
|
-
OutputType.
|
|
75
|
+
OutputType.WARNING
|
|
76
76
|
)
|
|
77
77
|
return False
|
|
78
78
|
|
|
@@ -92,7 +92,7 @@ class PlatformRegistry:
|
|
|
92
92
|
|
|
93
93
|
# 确保目录存在
|
|
94
94
|
if not os.path.exists(directory):
|
|
95
|
-
PrettyOutput.print(f"平台目录不存在: {directory}", OutputType.
|
|
95
|
+
PrettyOutput.print(f"平台目录不存在: {directory}", OutputType.WARNING)
|
|
96
96
|
return platforms
|
|
97
97
|
|
|
98
98
|
# 获取目录的包名
|
|
@@ -201,7 +201,7 @@ class PlatformRegistry:
|
|
|
201
201
|
BasePlatform: Platform instance
|
|
202
202
|
"""
|
|
203
203
|
if name not in self.platforms:
|
|
204
|
-
PrettyOutput.print(f"未找到平台: {name}", OutputType.
|
|
204
|
+
PrettyOutput.print(f"未找到平台: {name}", OutputType.WARNING)
|
|
205
205
|
return None
|
|
206
206
|
|
|
207
207
|
try:
|
|
@@ -55,7 +55,7 @@ def chat_with_model(platform_name: str, model_name: str):
|
|
|
55
55
|
# Create platform instance
|
|
56
56
|
platform = registry.create_platform(platform_name)
|
|
57
57
|
if not platform:
|
|
58
|
-
PrettyOutput.print(f"创建平台 {platform_name} 失败", OutputType.
|
|
58
|
+
PrettyOutput.print(f"创建平台 {platform_name} 失败", OutputType.WARNING)
|
|
59
59
|
return
|
|
60
60
|
|
|
61
61
|
try:
|
|
@@ -108,7 +108,7 @@ def chat_with_model(platform_name: str, model_name: str):
|
|
|
108
108
|
# Helper function for platform and model validation
|
|
109
109
|
def validate_platform_model(args):
|
|
110
110
|
if not args.platform or not args.model:
|
|
111
|
-
PrettyOutput.print("请指定平台和模型。使用 'jarvis info' 查看可用平台和模型。", OutputType.
|
|
111
|
+
PrettyOutput.print("请指定平台和模型。使用 'jarvis info' 查看可用平台和模型。", OutputType.WARNING)
|
|
112
112
|
return False
|
|
113
113
|
return True
|
|
114
114
|
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/ask_codebase.py
RENAMED
|
@@ -89,7 +89,7 @@ def main():
|
|
|
89
89
|
if result["success"]:
|
|
90
90
|
PrettyOutput.print(result["stdout"], OutputType.INFO, lang="markdown")
|
|
91
91
|
else:
|
|
92
|
-
PrettyOutput.print(result["stderr"], OutputType.
|
|
92
|
+
PrettyOutput.print(result["stderr"], OutputType.WARNING)
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
if __name__ == "__main__":
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/code_review.py
RENAMED
|
@@ -241,7 +241,7 @@ def main():
|
|
|
241
241
|
PrettyOutput.print(report, OutputType.SUCCESS, lang="yaml")
|
|
242
242
|
|
|
243
243
|
else:
|
|
244
|
-
PrettyOutput.print(result["stderr"], OutputType.
|
|
244
|
+
PrettyOutput.print(result["stderr"], OutputType.WARNING)
|
|
245
245
|
|
|
246
246
|
if __name__ == "__main__":
|
|
247
247
|
main()
|
|
@@ -109,7 +109,7 @@ def main():
|
|
|
109
109
|
if result["success"]:
|
|
110
110
|
PrettyOutput.print(result["stdout"], OutputType.SUCCESS)
|
|
111
111
|
else:
|
|
112
|
-
PrettyOutput.print(result["stderr"], OutputType.
|
|
112
|
+
PrettyOutput.print(result["stderr"], OutputType.WARNING)
|
|
113
113
|
|
|
114
114
|
if __name__ == "__main__":
|
|
115
115
|
main()
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/git_commiter.py
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
3
|
import shlex
|
|
4
|
+
import subprocess
|
|
4
5
|
from typing import Dict, Any
|
|
5
6
|
import tempfile
|
|
6
|
-
|
|
7
7
|
import yaml
|
|
8
8
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
9
9
|
from jarvis.jarvis_utils import OutputType, PrettyOutput, has_uncommitted_changes, init_env
|
|
@@ -27,7 +27,13 @@ class GitCommitTool:
|
|
|
27
27
|
return "<<FORMAT VIOLATION>> Invalid commit message structure"
|
|
28
28
|
|
|
29
29
|
def _get_last_commit_hash(self):
|
|
30
|
-
|
|
30
|
+
process = subprocess.Popen(
|
|
31
|
+
["git", "log", "-1", "--pretty=%H"],
|
|
32
|
+
stdout=subprocess.PIPE,
|
|
33
|
+
stderr=subprocess.PIPE
|
|
34
|
+
)
|
|
35
|
+
stdout, _ = process.communicate()
|
|
36
|
+
return stdout.decode().strip()
|
|
31
37
|
|
|
32
38
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
33
39
|
"""Execute automatic commit process with support for multi-line messages and special characters"""
|
|
@@ -37,10 +43,19 @@ class GitCommitTool:
|
|
|
37
43
|
return {"success": True, "stdout": "No changes to commit", "stderr": ""}
|
|
38
44
|
|
|
39
45
|
PrettyOutput.print("准备添加文件到提交...", OutputType.SYSTEM)
|
|
40
|
-
|
|
46
|
+
subprocess.Popen(
|
|
47
|
+
["git", "add", "."],
|
|
48
|
+
stdout=subprocess.DEVNULL,
|
|
49
|
+
stderr=subprocess.DEVNULL
|
|
50
|
+
).wait()
|
|
41
51
|
|
|
42
52
|
PrettyOutput.print("获取差异...", OutputType.SYSTEM)
|
|
43
|
-
|
|
53
|
+
process = subprocess.Popen(
|
|
54
|
+
["git", "diff", "--cached", "--exit-code"],
|
|
55
|
+
stdout=subprocess.PIPE,
|
|
56
|
+
stderr=subprocess.PIPE
|
|
57
|
+
)
|
|
58
|
+
diff = process.communicate()[0].decode()
|
|
44
59
|
PrettyOutput.print(diff, OutputType.CODE, lang="diff")
|
|
45
60
|
|
|
46
61
|
prompt = f'''Generate commit message with the paranoia of someone who's lost production data:
|
|
@@ -69,7 +84,7 @@ YOU MUST USE EXACTLY THIS FORMAT:
|
|
|
69
84
|
|
|
70
85
|
PrettyOutput.print("生成提交消息...", OutputType.SYSTEM)
|
|
71
86
|
platform = PlatformRegistry().get_codegen_platform()
|
|
72
|
-
|
|
87
|
+
platform.set_suppress_output(True)
|
|
73
88
|
commit_message = platform.chat_until_success(prompt)
|
|
74
89
|
commit_message = self._extract_commit_message(commit_message)
|
|
75
90
|
|
|
@@ -77,9 +92,13 @@ YOU MUST USE EXACTLY THIS FORMAT:
|
|
|
77
92
|
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
|
|
78
93
|
tmp_file.write(commit_message)
|
|
79
94
|
tmp_file.flush() # 确保内容写入文件
|
|
80
|
-
commit_cmd =
|
|
95
|
+
commit_cmd = ["git", "commit", "-F", tmp_file.name]
|
|
81
96
|
PrettyOutput.print("提交...", OutputType.INFO)
|
|
82
|
-
|
|
97
|
+
subprocess.Popen(
|
|
98
|
+
commit_cmd,
|
|
99
|
+
stdout=subprocess.DEVNULL,
|
|
100
|
+
stderr=subprocess.DEVNULL
|
|
101
|
+
).wait()
|
|
83
102
|
|
|
84
103
|
commit_hash = self._get_last_commit_hash()
|
|
85
104
|
PrettyOutput.print(f"提交哈希: {commit_hash}\n提交消息: {commit_message}", OutputType.SUCCESS)
|
|
@@ -135,7 +135,7 @@ def main():
|
|
|
135
135
|
if result["success"]:
|
|
136
136
|
PrettyOutput.print(f"{result['stdout']}", OutputType.INFO, lang="markdown")
|
|
137
137
|
else:
|
|
138
|
-
PrettyOutput.print(result["stderr"], OutputType.
|
|
138
|
+
PrettyOutput.print(result["stderr"], OutputType.WARNING)
|
|
139
139
|
|
|
140
140
|
if __name__ == "__main__":
|
|
141
141
|
main()
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_utils/__init__.py
RENAMED
|
@@ -23,9 +23,11 @@ import psutil
|
|
|
23
23
|
from rich.console import Console
|
|
24
24
|
from rich.theme import Theme
|
|
25
25
|
from rich.panel import Panel
|
|
26
|
+
from rich.box import HEAVY
|
|
26
27
|
from rich.text import Text
|
|
27
28
|
from rich.traceback import install as install_rich_traceback
|
|
28
29
|
from rich.syntax import Syntax
|
|
30
|
+
from rich.style import Style as RichStyle
|
|
29
31
|
|
|
30
32
|
from prompt_toolkit.completion import Completer, Completion, PathCompleter
|
|
31
33
|
from prompt_toolkit.document import Document
|
|
@@ -45,18 +47,18 @@ install_rich_traceback()
|
|
|
45
47
|
|
|
46
48
|
# Create console with custom theme
|
|
47
49
|
custom_theme = Theme({
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
50
|
+
"INFO": "yellow",
|
|
51
|
+
"WARNING": "yellow",
|
|
52
|
+
"ERROR": "red",
|
|
53
|
+
"SUCCESS": "green",
|
|
54
|
+
"SYSTEM": "cyan",
|
|
55
|
+
"CODE": "green",
|
|
56
|
+
"RESULT": "blue",
|
|
57
|
+
"PLANNING": "magenta",
|
|
58
|
+
"PROGRESS": "white",
|
|
59
|
+
"DEBUG": "blue",
|
|
60
|
+
"USER": "green",
|
|
61
|
+
"TOOL": "yellow",
|
|
60
62
|
})
|
|
61
63
|
|
|
62
64
|
console = Console(theme=custom_theme)
|
|
@@ -76,7 +78,7 @@ def set_agent(agent_name: str, agent: Any):
|
|
|
76
78
|
current_agent_name = agent_name
|
|
77
79
|
|
|
78
80
|
def get_agent_list():
|
|
79
|
-
return "[" + str(len(global_agents)) + "]" + current_agent_name if global_agents else "
|
|
81
|
+
return "[" + str(len(global_agents)) + "]" + current_agent_name if global_agents else ""
|
|
80
82
|
|
|
81
83
|
def delete_agent(agent_name: str):
|
|
82
84
|
if agent_name in global_agents:
|
|
@@ -85,18 +87,18 @@ def delete_agent(agent_name: str):
|
|
|
85
87
|
current_agent_name = ""
|
|
86
88
|
|
|
87
89
|
class OutputType(Enum):
|
|
88
|
-
SYSTEM = "
|
|
89
|
-
CODE = "
|
|
90
|
-
RESULT = "
|
|
91
|
-
ERROR = "
|
|
92
|
-
INFO = "
|
|
93
|
-
PLANNING = "
|
|
94
|
-
PROGRESS = "
|
|
95
|
-
SUCCESS = "
|
|
96
|
-
WARNING = "
|
|
97
|
-
DEBUG = "
|
|
98
|
-
USER = "
|
|
99
|
-
TOOL = "
|
|
90
|
+
SYSTEM = "SYSTEM" # AI assistant message
|
|
91
|
+
CODE = "CODE" # Code related
|
|
92
|
+
RESULT = "RESULT" # Tool execution result
|
|
93
|
+
ERROR = "ERROR" # Error information
|
|
94
|
+
INFO = "INFO" # System prompt
|
|
95
|
+
PLANNING = "PLANNING" # Task planning
|
|
96
|
+
PROGRESS = "PROGRESS" # Execution progress
|
|
97
|
+
SUCCESS = "SUCCESS" # Success information
|
|
98
|
+
WARNING = "WARNING" # Warning information
|
|
99
|
+
DEBUG = "DEBUG" # Debug information
|
|
100
|
+
USER = "USER" # User input
|
|
101
|
+
TOOL = "TOOL" # Tool call
|
|
100
102
|
|
|
101
103
|
class PrettyOutput:
|
|
102
104
|
"""Pretty output using rich"""
|
|
@@ -164,18 +166,18 @@ class PrettyOutput:
|
|
|
164
166
|
return default_lang
|
|
165
167
|
|
|
166
168
|
@staticmethod
|
|
167
|
-
def _format(
|
|
169
|
+
def _format(output_type: OutputType, timestamp: bool = True) -> Text:
|
|
168
170
|
"""Format output text using rich Text"""
|
|
169
171
|
# Create rich Text object
|
|
170
172
|
formatted = Text()
|
|
171
173
|
|
|
172
174
|
# Add timestamp and agent info
|
|
173
175
|
if timestamp:
|
|
174
|
-
formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}]
|
|
175
|
-
formatted.append(f"{get_agent_list()}", style="blue")
|
|
176
|
+
formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}][{output_type.value}]", style=output_type.value)
|
|
177
|
+
formatted.append(f"[{get_agent_list()}]", style="blue")
|
|
176
178
|
# Add icon
|
|
177
179
|
icon = PrettyOutput._ICONS.get(output_type, "")
|
|
178
|
-
formatted.append(f"{icon} ", style=output_type.value)
|
|
180
|
+
formatted.append(f" {icon} ", style=output_type.value)
|
|
179
181
|
|
|
180
182
|
return formatted
|
|
181
183
|
|
|
@@ -190,27 +192,88 @@ class PrettyOutput:
|
|
|
190
192
|
lang: Language for syntax highlighting
|
|
191
193
|
traceback: Whether to show traceback for errors
|
|
192
194
|
"""
|
|
193
|
-
|
|
195
|
+
|
|
194
196
|
|
|
195
197
|
# Define styles for different output types
|
|
196
198
|
styles = {
|
|
197
|
-
OutputType.SYSTEM: RichStyle(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
OutputType.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
OutputType.
|
|
199
|
+
OutputType.SYSTEM: RichStyle(
|
|
200
|
+
color="bright_cyan",
|
|
201
|
+
italic=True,
|
|
202
|
+
bold=True,
|
|
203
|
+
),
|
|
204
|
+
OutputType.CODE: RichStyle(
|
|
205
|
+
color="green",
|
|
206
|
+
italic=True,
|
|
207
|
+
bgcolor="#1a1a1a",
|
|
208
|
+
frame=True
|
|
209
|
+
),
|
|
210
|
+
OutputType.RESULT: RichStyle(
|
|
211
|
+
color="bright_blue",
|
|
212
|
+
bold=True,
|
|
213
|
+
italic=True,
|
|
214
|
+
overline=True,
|
|
215
|
+
bgcolor="navy_blue"
|
|
216
|
+
),
|
|
217
|
+
OutputType.ERROR: RichStyle(
|
|
218
|
+
color="red",
|
|
219
|
+
bold=True,
|
|
220
|
+
italic=True,
|
|
221
|
+
blink=True,
|
|
222
|
+
bgcolor="dark_red",
|
|
223
|
+
),
|
|
224
|
+
OutputType.INFO: RichStyle(
|
|
225
|
+
color="gold1",
|
|
226
|
+
dim=True,
|
|
227
|
+
bgcolor="grey11",
|
|
228
|
+
italic=True
|
|
229
|
+
),
|
|
230
|
+
OutputType.PLANNING: RichStyle(
|
|
231
|
+
color="purple",
|
|
232
|
+
italic=True,
|
|
233
|
+
bold=True,
|
|
234
|
+
),
|
|
235
|
+
OutputType.PROGRESS: RichStyle(
|
|
236
|
+
color="white",
|
|
237
|
+
encircle=True,
|
|
238
|
+
italic=True,
|
|
239
|
+
),
|
|
240
|
+
OutputType.SUCCESS: RichStyle(
|
|
241
|
+
color="bright_green",
|
|
242
|
+
bold=True,
|
|
243
|
+
strike=False,
|
|
244
|
+
meta={"icon": "✓"},
|
|
245
|
+
italic=True
|
|
246
|
+
),
|
|
247
|
+
OutputType.WARNING: RichStyle(
|
|
248
|
+
color="yellow",
|
|
249
|
+
bold=True,
|
|
250
|
+
blink2=True,
|
|
251
|
+
bgcolor="dark_orange",
|
|
252
|
+
italic=True
|
|
253
|
+
),
|
|
254
|
+
OutputType.DEBUG: RichStyle(
|
|
255
|
+
color="grey58",
|
|
256
|
+
dim=True,
|
|
257
|
+
italic=True,
|
|
258
|
+
conceal=True
|
|
259
|
+
),
|
|
260
|
+
OutputType.USER: RichStyle(
|
|
261
|
+
color="spring_green2",
|
|
262
|
+
reverse=True,
|
|
263
|
+
frame=True,
|
|
264
|
+
italic=True
|
|
265
|
+
),
|
|
266
|
+
OutputType.TOOL: RichStyle(
|
|
267
|
+
color="dark_sea_green4",
|
|
268
|
+
italic=True,
|
|
269
|
+
bgcolor="grey19",
|
|
270
|
+
overline=True
|
|
271
|
+
)
|
|
209
272
|
}
|
|
210
273
|
|
|
211
274
|
# Get formatted header
|
|
212
275
|
lang = lang if lang is not None else PrettyOutput._detect_language(text, default_lang='markdown')
|
|
213
|
-
header = PrettyOutput._format(
|
|
276
|
+
header = PrettyOutput._format(output_type, timestamp)
|
|
214
277
|
|
|
215
278
|
# Create syntax highlighted content
|
|
216
279
|
content = Syntax(
|
|
@@ -218,7 +281,6 @@ class PrettyOutput:
|
|
|
218
281
|
lang,
|
|
219
282
|
theme="monokai",
|
|
220
283
|
word_wrap=True,
|
|
221
|
-
background_color="default"
|
|
222
284
|
)
|
|
223
285
|
|
|
224
286
|
# Create panel with styling
|
|
@@ -229,7 +291,8 @@ class PrettyOutput:
|
|
|
229
291
|
title=header,
|
|
230
292
|
title_align="left",
|
|
231
293
|
padding=(0, 0),
|
|
232
|
-
highlight=True
|
|
294
|
+
highlight=True,
|
|
295
|
+
box=HEAVY,
|
|
233
296
|
)
|
|
234
297
|
|
|
235
298
|
# Print panel
|
|
@@ -253,12 +316,22 @@ class PrettyOutput:
|
|
|
253
316
|
@staticmethod
|
|
254
317
|
def print_stream(text: str):
|
|
255
318
|
"""Print stream output without line break"""
|
|
256
|
-
|
|
319
|
+
# 使用进度类型样式
|
|
320
|
+
style = PrettyOutput._get_style(OutputType.SYSTEM)
|
|
321
|
+
console.print(text, style=style, end="")
|
|
257
322
|
|
|
258
323
|
@staticmethod
|
|
259
324
|
def print_stream_end():
|
|
260
325
|
"""End stream output with line break"""
|
|
261
|
-
|
|
326
|
+
# 结束符样式
|
|
327
|
+
end_style = PrettyOutput._get_style(OutputType.SUCCESS)
|
|
328
|
+
console.print("\n", style=end_style)
|
|
329
|
+
console.file.flush()
|
|
330
|
+
|
|
331
|
+
@staticmethod
|
|
332
|
+
def _get_style(output_type: OutputType) -> RichStyle:
|
|
333
|
+
"""Get pre-defined RichStyle for output type"""
|
|
334
|
+
return console.get_style(output_type.value)
|
|
262
335
|
|
|
263
336
|
def get_single_line_input(tip: str) -> str:
|
|
264
337
|
"""Get single line input, support direction key, history function, etc."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_code_agent/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_codebase/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/__init__.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/ollama.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_platform/openai.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_rag/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_smart_shell/main.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/__init__.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/ask_user.py
RENAMED
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/chdir.py
RENAMED
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/execute_shell.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/methodology.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/read_code.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/read_webpage.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/registry.py
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.119 → jarvis_ai_assistant-0.1.121}/src/jarvis/jarvis_tools/search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|