jarvis-ai-assistant 0.1.178__py3-none-any.whl → 0.1.180__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +130 -79
- jarvis/jarvis_agent/builtin_input_handler.py +1 -1
- jarvis/jarvis_agent/jarvis.py +9 -13
- jarvis/jarvis_agent/main.py +4 -2
- jarvis/jarvis_code_agent/code_agent.py +34 -23
- jarvis/jarvis_code_agent/lint.py +164 -0
- jarvis/jarvis_code_analysis/checklists/loader.py +6 -20
- jarvis/jarvis_code_analysis/code_review.py +8 -6
- jarvis/jarvis_data/config_schema.json +260 -0
- jarvis/jarvis_dev/main.py +1 -8
- jarvis/jarvis_git_details/main.py +1 -1
- jarvis/jarvis_git_squash/main.py +5 -3
- jarvis/jarvis_git_utils/git_commiter.py +25 -24
- jarvis/jarvis_mcp/sse_mcp_client.py +6 -4
- jarvis/jarvis_mcp/stdio_mcp_client.py +5 -4
- jarvis/jarvis_mcp/streamable_mcp_client.py +404 -0
- jarvis/jarvis_methodology/main.py +10 -9
- jarvis/jarvis_multi_agent/main.py +3 -1
- jarvis/jarvis_platform/base.py +14 -8
- jarvis/jarvis_platform/human.py +3 -1
- jarvis/jarvis_platform/kimi.py +8 -27
- jarvis/jarvis_platform/openai.py +4 -16
- jarvis/jarvis_platform/registry.py +6 -2
- jarvis/jarvis_platform/yuanbao.py +9 -29
- jarvis/jarvis_platform_manager/main.py +11 -9
- jarvis/jarvis_smart_shell/main.py +7 -3
- jarvis/jarvis_tools/ask_codebase.py +4 -3
- jarvis/jarvis_tools/ask_user.py +2 -1
- jarvis/jarvis_tools/base.py +3 -1
- jarvis/jarvis_tools/chdir.py +2 -1
- jarvis/jarvis_tools/cli/main.py +1 -0
- jarvis/jarvis_tools/code_plan.py +5 -3
- jarvis/jarvis_tools/create_code_agent.py +5 -2
- jarvis/jarvis_tools/create_sub_agent.py +1 -3
- jarvis/jarvis_tools/edit_file.py +4 -4
- jarvis/jarvis_tools/execute_script.py +1 -1
- jarvis/jarvis_tools/file_analyzer.py +5 -3
- jarvis/jarvis_tools/file_operation.py +4 -7
- jarvis/jarvis_tools/find_methodology.py +4 -2
- jarvis/jarvis_tools/generate_new_tool.py +2 -1
- jarvis/jarvis_tools/methodology.py +3 -4
- jarvis/jarvis_tools/read_code.py +2 -1
- jarvis/jarvis_tools/read_webpage.py +3 -1
- jarvis/jarvis_tools/registry.py +60 -45
- jarvis/jarvis_tools/rewrite_file.py +2 -1
- jarvis/jarvis_tools/search_web.py +1 -0
- jarvis/jarvis_tools/virtual_tty.py +5 -4
- jarvis/jarvis_utils/__init__.py +2 -0
- jarvis/jarvis_utils/builtin_replace_map.py +1 -1
- jarvis/jarvis_utils/config.py +88 -17
- jarvis/jarvis_utils/embedding.py +4 -3
- jarvis/jarvis_utils/file_processors.py +1 -0
- jarvis/jarvis_utils/git_utils.py +83 -40
- jarvis/jarvis_utils/globals.py +4 -2
- jarvis/jarvis_utils/input.py +14 -7
- jarvis/jarvis_utils/methodology.py +6 -4
- jarvis/jarvis_utils/output.py +10 -6
- jarvis/jarvis_utils/utils.py +140 -24
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.180.dist-info}/METADATA +66 -59
- jarvis_ai_assistant-0.1.180.dist-info/RECORD +99 -0
- jarvis_ai_assistant-0.1.178.dist-info/RECORD +0 -96
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.180.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.180.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.180.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.180.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
2
|
+
import fcntl
|
|
3
3
|
import os
|
|
4
|
-
import time
|
|
5
4
|
import pty
|
|
6
|
-
import fcntl
|
|
7
|
-
import signal
|
|
8
5
|
import select
|
|
6
|
+
import signal
|
|
7
|
+
import time
|
|
8
|
+
from typing import Any, Dict
|
|
9
|
+
|
|
9
10
|
|
|
10
11
|
class VirtualTTYTool:
|
|
11
12
|
name = "virtual_tty"
|
jarvis/jarvis_utils/__init__.py
CHANGED
jarvis/jarvis_utils/config.py
CHANGED
|
@@ -1,14 +1,46 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import os
|
|
3
3
|
from functools import lru_cache
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, List
|
|
6
|
+
|
|
7
|
+
|
|
4
8
|
import yaml
|
|
9
|
+
|
|
10
|
+
|
|
5
11
|
from jarvis.jarvis_utils.builtin_replace_map import BUILTIN_REPLACE_MAP
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 全局环境变量存储
|
|
15
|
+
|
|
16
|
+
GLOBAL_CONFIG_DATA: Dict[str, Any] = {}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def set_global_env_data(env_data: Dict[str, Any]) -> None:
|
|
20
|
+
"""设置全局环境变量数据"""
|
|
21
|
+
global GLOBAL_CONFIG_DATA
|
|
22
|
+
GLOBAL_CONFIG_DATA = env_data
|
|
23
|
+
|
|
24
|
+
def set_config(key: str, value: Any) -> None:
|
|
25
|
+
"""设置配置"""
|
|
26
|
+
GLOBAL_CONFIG_DATA[key] = value
|
|
27
|
+
|
|
28
|
+
|
|
6
29
|
"""配置管理模块。
|
|
7
30
|
|
|
8
31
|
该模块提供了获取Jarvis系统各种配置设置的函数。
|
|
9
32
|
所有配置都从环境变量中读取,带有回退默认值。
|
|
10
33
|
"""
|
|
11
34
|
|
|
35
|
+
def get_git_commit_prompt() -> str:
|
|
36
|
+
"""
|
|
37
|
+
获取Git提交提示模板
|
|
38
|
+
|
|
39
|
+
返回:
|
|
40
|
+
str: Git提交信息生成提示模板,如果未配置则返回空字符串
|
|
41
|
+
"""
|
|
42
|
+
return GLOBAL_CONFIG_DATA.get("JARVIS_GIT_COMMIT_PROMPT", "")
|
|
43
|
+
|
|
12
44
|
# 输出窗口预留大小
|
|
13
45
|
INPUT_WINDOW_REVERSE_SIZE = 2048
|
|
14
46
|
|
|
@@ -17,16 +49,27 @@ def get_replace_map() -> dict:
|
|
|
17
49
|
"""
|
|
18
50
|
获取替换映射表。
|
|
19
51
|
|
|
20
|
-
|
|
52
|
+
优先使用GLOBAL_CONFIG_DATA['JARVIS_REPLACE_MAP']的配置,
|
|
53
|
+
如果没有则从数据目录下的replace_map.yaml文件中读取替换映射表,
|
|
21
54
|
如果文件不存在则返回内置替换映射表。
|
|
22
55
|
|
|
23
56
|
返回:
|
|
24
57
|
dict: 合并后的替换映射表字典(内置+文件中的映射表)
|
|
25
58
|
"""
|
|
59
|
+
if 'JARVIS_REPLACE_MAP' in GLOBAL_CONFIG_DATA:
|
|
60
|
+
return {**BUILTIN_REPLACE_MAP, **GLOBAL_CONFIG_DATA['JARVIS_REPLACE_MAP']}
|
|
61
|
+
|
|
26
62
|
replace_map_path = os.path.join(get_data_dir(), 'replace_map.yaml')
|
|
27
63
|
if not os.path.exists(replace_map_path):
|
|
28
64
|
return BUILTIN_REPLACE_MAP.copy()
|
|
29
65
|
|
|
66
|
+
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
67
|
+
PrettyOutput.print(
|
|
68
|
+
"警告:使用replace_map.yaml进行配置的方式已被弃用,将在未来版本中移除。"
|
|
69
|
+
"请迁移到使用GLOBAL_CONFIG_DATA中的JARVIS_REPLACE_MAP配置。",
|
|
70
|
+
output_type=OutputType.WARNING
|
|
71
|
+
)
|
|
72
|
+
|
|
30
73
|
with open(replace_map_path, 'r', encoding='utf-8', errors='ignore') as file:
|
|
31
74
|
file_map = yaml.safe_load(file) or {}
|
|
32
75
|
return {**BUILTIN_REPLACE_MAP, **file_map}
|
|
@@ -38,7 +81,7 @@ def get_max_token_count() -> int:
|
|
|
38
81
|
返回:
|
|
39
82
|
int: 模型能处理的最大token数量。
|
|
40
83
|
"""
|
|
41
|
-
return int(
|
|
84
|
+
return int(GLOBAL_CONFIG_DATA.get('JARVIS_MAX_TOKEN_COUNT', '960000'))
|
|
42
85
|
|
|
43
86
|
def get_max_input_token_count() -> int:
|
|
44
87
|
"""
|
|
@@ -47,7 +90,7 @@ def get_max_input_token_count() -> int:
|
|
|
47
90
|
返回:
|
|
48
91
|
int: 模型能处理的最大输入token数量。
|
|
49
92
|
"""
|
|
50
|
-
return int(
|
|
93
|
+
return int(GLOBAL_CONFIG_DATA.get('JARVIS_MAX_INPUT_TOKEN_COUNT', '32000'))
|
|
51
94
|
|
|
52
95
|
|
|
53
96
|
def is_auto_complete() -> bool:
|
|
@@ -57,7 +100,7 @@ def is_auto_complete() -> bool:
|
|
|
57
100
|
返回:
|
|
58
101
|
bool: 如果启用了自动补全则返回True,默认为False
|
|
59
102
|
"""
|
|
60
|
-
return
|
|
103
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_AUTO_COMPLETE', 'false') == 'true'
|
|
61
104
|
|
|
62
105
|
|
|
63
106
|
def get_shell_name() -> str:
|
|
@@ -67,7 +110,7 @@ def get_shell_name() -> str:
|
|
|
67
110
|
返回:
|
|
68
111
|
str: Shell名称(例如bash, zsh),默认为bash
|
|
69
112
|
"""
|
|
70
|
-
shell_path =
|
|
113
|
+
shell_path = GLOBAL_CONFIG_DATA.get('SHELL', '/bin/bash')
|
|
71
114
|
return os.path.basename(shell_path)
|
|
72
115
|
def get_normal_platform_name() -> str:
|
|
73
116
|
"""
|
|
@@ -76,7 +119,7 @@ def get_normal_platform_name() -> str:
|
|
|
76
119
|
返回:
|
|
77
120
|
str: 平台名称,默认为'yuanbao'
|
|
78
121
|
"""
|
|
79
|
-
return
|
|
122
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_PLATFORM', 'yuanbao')
|
|
80
123
|
def get_normal_model_name() -> str:
|
|
81
124
|
"""
|
|
82
125
|
获取正常操作的模型名称。
|
|
@@ -84,7 +127,7 @@ def get_normal_model_name() -> str:
|
|
|
84
127
|
返回:
|
|
85
128
|
str: 模型名称,默认为'deep_seek'
|
|
86
129
|
"""
|
|
87
|
-
return
|
|
130
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_MODEL', 'deep_seek_v3')
|
|
88
131
|
|
|
89
132
|
|
|
90
133
|
def get_thinking_platform_name() -> str:
|
|
@@ -94,7 +137,7 @@ def get_thinking_platform_name() -> str:
|
|
|
94
137
|
返回:
|
|
95
138
|
str: 平台名称,默认为'yuanbao'
|
|
96
139
|
"""
|
|
97
|
-
return
|
|
140
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_THINKING_PLATFORM', GLOBAL_CONFIG_DATA.get('JARVIS_PLATFORM', 'yuanbao'))
|
|
98
141
|
def get_thinking_model_name() -> str:
|
|
99
142
|
"""
|
|
100
143
|
获取思考操作的模型名称。
|
|
@@ -102,7 +145,7 @@ def get_thinking_model_name() -> str:
|
|
|
102
145
|
返回:
|
|
103
146
|
str: 模型名称,默认为'deep_seek'
|
|
104
147
|
"""
|
|
105
|
-
return
|
|
148
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_THINKING_MODEL', GLOBAL_CONFIG_DATA.get('JARVIS_MODEL', 'deep_seek'))
|
|
106
149
|
|
|
107
150
|
def is_execute_tool_confirm() -> bool:
|
|
108
151
|
"""
|
|
@@ -111,7 +154,7 @@ def is_execute_tool_confirm() -> bool:
|
|
|
111
154
|
返回:
|
|
112
155
|
bool: 如果需要确认则返回True,默认为False
|
|
113
156
|
"""
|
|
114
|
-
return
|
|
157
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_EXECUTE_TOOL_CONFIRM', 'false') == 'true'
|
|
115
158
|
def is_confirm_before_apply_patch() -> bool:
|
|
116
159
|
"""
|
|
117
160
|
检查应用补丁前是否需要确认。
|
|
@@ -119,7 +162,7 @@ def is_confirm_before_apply_patch() -> bool:
|
|
|
119
162
|
返回:
|
|
120
163
|
bool: 如果需要确认则返回True,默认为False
|
|
121
164
|
"""
|
|
122
|
-
return
|
|
165
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_CONFIRM_BEFORE_APPLY_PATCH', 'true') == 'true'
|
|
123
166
|
|
|
124
167
|
def get_max_tool_call_count() -> int:
|
|
125
168
|
"""
|
|
@@ -128,7 +171,7 @@ def get_max_tool_call_count() -> int:
|
|
|
128
171
|
返回:
|
|
129
172
|
int: 最大连续工具调用次数,默认为20
|
|
130
173
|
"""
|
|
131
|
-
return int(
|
|
174
|
+
return int(GLOBAL_CONFIG_DATA.get('JARVIS_MAX_TOOL_CALL_COUNT', '20'))
|
|
132
175
|
|
|
133
176
|
|
|
134
177
|
def get_data_dir() -> str:
|
|
@@ -139,7 +182,7 @@ def get_data_dir() -> str:
|
|
|
139
182
|
str: 数据目录路径,优先从JARVIS_DATA_PATH环境变量获取,
|
|
140
183
|
如果未设置或为空,则使用~/.jarvis作为默认值
|
|
141
184
|
"""
|
|
142
|
-
data_path =
|
|
185
|
+
data_path = GLOBAL_CONFIG_DATA.get('JARVIS_DATA_PATH', '').strip()
|
|
143
186
|
if not data_path:
|
|
144
187
|
return os.path.expanduser('~/.jarvis')
|
|
145
188
|
return data_path
|
|
@@ -151,7 +194,7 @@ def get_auto_update() -> bool:
|
|
|
151
194
|
返回:
|
|
152
195
|
bool: 如果需要自动更新则返回True,默认为True
|
|
153
196
|
"""
|
|
154
|
-
return
|
|
197
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_AUTO_UPDATE', 'true') == 'true'
|
|
155
198
|
|
|
156
199
|
def get_max_big_content_size() -> int:
|
|
157
200
|
"""
|
|
@@ -160,7 +203,7 @@ def get_max_big_content_size() -> int:
|
|
|
160
203
|
返回:
|
|
161
204
|
int: 最大大内容大小
|
|
162
205
|
"""
|
|
163
|
-
return int(
|
|
206
|
+
return int(GLOBAL_CONFIG_DATA.get('JARVIS_MAX_BIG_CONTENT_SIZE', '1024000'))
|
|
164
207
|
|
|
165
208
|
def get_pretty_output() -> bool:
|
|
166
209
|
"""
|
|
@@ -169,7 +212,7 @@ def get_pretty_output() -> bool:
|
|
|
169
212
|
返回:
|
|
170
213
|
bool: 如果启用PrettyOutput则返回True,默认为True
|
|
171
214
|
"""
|
|
172
|
-
return
|
|
215
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_PRETTY_OUTPUT', 'false') == 'true'
|
|
173
216
|
|
|
174
217
|
def is_use_methodology() -> bool:
|
|
175
218
|
"""
|
|
@@ -178,4 +221,32 @@ def is_use_methodology() -> bool:
|
|
|
178
221
|
返回:
|
|
179
222
|
bool: 如果启用方法论则返回True,默认为True
|
|
180
223
|
"""
|
|
181
|
-
return
|
|
224
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_USE_METHODOLOGY', 'false') == 'true'
|
|
225
|
+
|
|
226
|
+
def is_use_analysis() -> bool:
|
|
227
|
+
"""
|
|
228
|
+
获取是否启用任务分析。
|
|
229
|
+
|
|
230
|
+
返回:
|
|
231
|
+
bool: 如果启用任务分析则返回True,默认为True
|
|
232
|
+
"""
|
|
233
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_USE_ANALYSIS', 'false') == 'true'
|
|
234
|
+
|
|
235
|
+
def is_print_prompt() -> bool:
|
|
236
|
+
"""
|
|
237
|
+
获取是否打印提示。
|
|
238
|
+
|
|
239
|
+
返回:
|
|
240
|
+
bool: 如果打印提示则返回True,默认为True
|
|
241
|
+
"""
|
|
242
|
+
return GLOBAL_CONFIG_DATA.get('JARVIS_PRINT_PROMPT', 'false') == 'true'
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def get_mcp_config() -> List[Dict[str, Any]]:
|
|
246
|
+
"""
|
|
247
|
+
获取MCP配置列表。
|
|
248
|
+
|
|
249
|
+
返回:
|
|
250
|
+
List[Dict[str, Any]]: MCP配置项列表,如果未配置则返回空列表
|
|
251
|
+
"""
|
|
252
|
+
return GLOBAL_CONFIG_DATA.get("JARVIS_MCP", [])
|
jarvis/jarvis_utils/embedding.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
import functools
|
|
2
3
|
import os
|
|
3
|
-
from transformers import AutoTokenizer
|
|
4
4
|
from typing import List
|
|
5
|
-
import functools
|
|
6
5
|
|
|
7
|
-
from
|
|
6
|
+
from transformers import AutoTokenizer
|
|
7
|
+
|
|
8
8
|
from jarvis.jarvis_utils.config import get_data_dir
|
|
9
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
9
10
|
|
|
10
11
|
# 全局缓存,避免重复加载模型
|
|
11
12
|
_global_tokenizers = {}
|
jarvis/jarvis_utils/git_utils.py
CHANGED
|
@@ -12,10 +12,14 @@ Git工具模块
|
|
|
12
12
|
import os
|
|
13
13
|
import re
|
|
14
14
|
import subprocess
|
|
15
|
-
from typing import List, Tuple
|
|
16
|
-
|
|
17
|
-
from jarvis.jarvis_utils.
|
|
15
|
+
from typing import Dict, List, Tuple
|
|
16
|
+
|
|
17
|
+
from jarvis.jarvis_utils.config import (get_auto_update,
|
|
18
|
+
is_confirm_before_apply_patch)
|
|
19
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
18
20
|
from jarvis.jarvis_utils.utils import user_confirm
|
|
21
|
+
|
|
22
|
+
|
|
19
23
|
def find_git_root(start_dir: str = ".") -> str:
|
|
20
24
|
"""
|
|
21
25
|
切换到给定路径的Git根目录,如果不是Git仓库则初始化。
|
|
@@ -101,49 +105,41 @@ def get_commits_between(start_hash: str, end_hash: str) -> List[Tuple[str, str]]
|
|
|
101
105
|
|
|
102
106
|
|
|
103
107
|
def get_diff() -> str:
|
|
104
|
-
"""使用git
|
|
105
|
-
import subprocess
|
|
106
|
-
|
|
107
|
-
# 初始化状态
|
|
108
|
-
need_reset = False
|
|
108
|
+
"""使用git获取工作区差异,包括修改和新增的文件内容
|
|
109
109
|
|
|
110
|
+
返回:
|
|
111
|
+
str: 差异内容或错误信息
|
|
112
|
+
"""
|
|
110
113
|
try:
|
|
111
|
-
#
|
|
112
|
-
subprocess.run(['git', 'add', '.'], check=True)
|
|
113
|
-
need_reset = True
|
|
114
|
+
# 暂存新增文件
|
|
115
|
+
subprocess.run(['git', 'add', '-N', '.'], check=True)
|
|
114
116
|
|
|
115
|
-
#
|
|
117
|
+
# 获取所有差异(包括新增文件)
|
|
116
118
|
result = subprocess.run(
|
|
117
|
-
['git', 'diff', '
|
|
119
|
+
['git', 'diff', 'HEAD'],
|
|
118
120
|
capture_output=True,
|
|
119
121
|
text=False,
|
|
120
122
|
check=True
|
|
121
123
|
)
|
|
122
124
|
|
|
123
|
-
# 解码输出
|
|
124
|
-
try:
|
|
125
|
-
ret = result.stdout.decode('utf-8')
|
|
126
|
-
except UnicodeDecodeError:
|
|
127
|
-
ret = result.stdout.decode('utf-8', errors='replace')
|
|
128
|
-
|
|
129
125
|
# 重置暂存区
|
|
130
|
-
subprocess.run(['git',
|
|
131
|
-
return ret
|
|
126
|
+
subprocess.run(['git', 'reset'], check=True)
|
|
132
127
|
|
|
128
|
+
try:
|
|
129
|
+
return result.stdout.decode('utf-8')
|
|
130
|
+
except UnicodeDecodeError:
|
|
131
|
+
return result.stdout.decode('utf-8', errors='replace')
|
|
132
|
+
|
|
133
133
|
except subprocess.CalledProcessError as e:
|
|
134
|
-
if need_reset:
|
|
135
|
-
subprocess.run(['git', "reset", "--mixed"], check=False)
|
|
136
134
|
return f"获取差异失败: {str(e)}"
|
|
137
135
|
except Exception as e:
|
|
138
|
-
if need_reset:
|
|
139
|
-
subprocess.run(['git', "reset", "--mixed"], check=False)
|
|
140
136
|
return f"发生意外错误: {str(e)}"
|
|
141
137
|
|
|
142
138
|
|
|
143
139
|
|
|
144
140
|
|
|
145
141
|
|
|
146
|
-
def revert_file(filepath: str):
|
|
142
|
+
def revert_file(filepath: str) -> None:
|
|
147
143
|
"""增强版git恢复,处理新文件"""
|
|
148
144
|
import subprocess
|
|
149
145
|
try:
|
|
@@ -166,7 +162,7 @@ def revert_file(filepath: str):
|
|
|
166
162
|
# 修改后的恢复函数
|
|
167
163
|
|
|
168
164
|
|
|
169
|
-
def revert_change():
|
|
165
|
+
def revert_change() -> None:
|
|
170
166
|
"""恢复所有未提交的修改到HEAD状态"""
|
|
171
167
|
import subprocess
|
|
172
168
|
try:
|
|
@@ -180,7 +176,7 @@ def revert_change():
|
|
|
180
176
|
subprocess.run(['git', 'reset', '--hard', 'HEAD'], check=True)
|
|
181
177
|
subprocess.run(['git', 'clean', '-fd'], check=True)
|
|
182
178
|
except subprocess.CalledProcessError as e:
|
|
183
|
-
|
|
179
|
+
PrettyOutput.print(f"恢复更改失败: {str(e)}", OutputType.ERROR)
|
|
184
180
|
|
|
185
181
|
|
|
186
182
|
def handle_commit_workflow() -> bool:
|
|
@@ -196,15 +192,15 @@ def handle_commit_workflow() -> bool:
|
|
|
196
192
|
import subprocess
|
|
197
193
|
try:
|
|
198
194
|
# 获取当前分支的提交总数
|
|
199
|
-
|
|
195
|
+
commit_result = subprocess.run(
|
|
200
196
|
['git', 'rev-list', '--count', 'HEAD'],
|
|
201
197
|
capture_output=True,
|
|
202
198
|
text=True
|
|
203
199
|
)
|
|
204
|
-
if
|
|
200
|
+
if commit_result.returncode != 0:
|
|
205
201
|
return False
|
|
206
202
|
|
|
207
|
-
commit_count = int(
|
|
203
|
+
commit_count = int(commit_result.stdout.strip())
|
|
208
204
|
|
|
209
205
|
# 暂存所有修改
|
|
210
206
|
subprocess.run(['git', 'add', '.'], check=True)
|
|
@@ -317,15 +313,28 @@ def check_and_update_git_repo(repo_path: str) -> bool:
|
|
|
317
313
|
if has_uncommitted_changes():
|
|
318
314
|
return False
|
|
319
315
|
|
|
320
|
-
#
|
|
321
|
-
subprocess.run(["git", "fetch"], cwd=git_root, check=True)
|
|
322
|
-
#
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
316
|
+
# 获取远程tag更新
|
|
317
|
+
subprocess.run(["git", "fetch", "--tags"], cwd=git_root, check=True)
|
|
318
|
+
# 获取最新本地tag
|
|
319
|
+
local_tag_result = subprocess.run(["git", "describe", "--tags", "--abbrev=0"],
|
|
320
|
+
cwd=git_root, capture_output=True, text=True)
|
|
321
|
+
# 获取最新远程tag
|
|
322
|
+
remote_tag_result = subprocess.run(
|
|
323
|
+
["git", "ls-remote", "--tags", "--refs", "origin"],
|
|
324
|
+
cwd=git_root, capture_output=True, text=True
|
|
325
|
+
)
|
|
326
|
+
if remote_tag_result.returncode == 0:
|
|
327
|
+
# 提取最新的tag名称
|
|
328
|
+
tags = [ref.split("/")[-1] for ref in remote_tag_result.stdout.splitlines()]
|
|
329
|
+
tags = sorted(tags, key=lambda x: [int(i) if i.isdigit() else i for i in re.split(r'([0-9]+)', x)])
|
|
330
|
+
remote_tag = tags[-1] if tags else ""
|
|
331
|
+
remote_tag_result.stdout = remote_tag
|
|
332
|
+
|
|
333
|
+
if (local_tag_result.returncode == 0 and remote_tag_result.returncode == 0 and
|
|
334
|
+
local_tag_result.stdout.strip() != remote_tag_result.stdout.strip()):
|
|
335
|
+
PrettyOutput.print(f"检测到新版本tag {remote_tag_result.stdout.strip()},正在更新Jarvis...", OutputType.INFO)
|
|
336
|
+
subprocess.run(["git", "checkout", remote_tag_result.stdout.strip()], cwd=git_root, check=True)
|
|
337
|
+
PrettyOutput.print(f"Jarvis已更新到tag {remote_tag_result.stdout.strip()}", OutputType.SUCCESS)
|
|
329
338
|
return True
|
|
330
339
|
return False
|
|
331
340
|
except Exception as e:
|
|
@@ -333,3 +342,37 @@ def check_and_update_git_repo(repo_path: str) -> bool:
|
|
|
333
342
|
return False
|
|
334
343
|
finally:
|
|
335
344
|
os.chdir(curr_dir)
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def get_diff_file_list() -> List[str]:
|
|
348
|
+
"""获取HEAD到当前变更的文件列表,包括修改和新增的文件
|
|
349
|
+
|
|
350
|
+
返回:
|
|
351
|
+
List[str]: 修改和新增的文件路径列表
|
|
352
|
+
"""
|
|
353
|
+
try:
|
|
354
|
+
# 暂存新增文件
|
|
355
|
+
subprocess.run(['git', 'add', '-N', '.'], check=True)
|
|
356
|
+
|
|
357
|
+
# 获取所有差异文件(包括新增文件)
|
|
358
|
+
result = subprocess.run(
|
|
359
|
+
['git', 'diff', '--name-only', 'HEAD'],
|
|
360
|
+
capture_output=True,
|
|
361
|
+
text=True
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
# 重置暂存区
|
|
365
|
+
subprocess.run(['git', 'reset'], check=True)
|
|
366
|
+
|
|
367
|
+
if result.returncode != 0:
|
|
368
|
+
PrettyOutput.print(f"获取差异文件列表失败: {result.stderr}", OutputType.ERROR)
|
|
369
|
+
return []
|
|
370
|
+
|
|
371
|
+
return [f for f in result.stdout.splitlines() if f]
|
|
372
|
+
|
|
373
|
+
except subprocess.CalledProcessError as e:
|
|
374
|
+
PrettyOutput.print(f"获取差异文件列表失败: {str(e)}", OutputType.ERROR)
|
|
375
|
+
return []
|
|
376
|
+
except Exception as e:
|
|
377
|
+
PrettyOutput.print(f"获取差异文件列表异常: {str(e)}", OutputType.ERROR)
|
|
378
|
+
return []
|
jarvis/jarvis_utils/globals.py
CHANGED
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
- 带有自定义主题的控制台配置
|
|
8
8
|
- 环境初始化
|
|
9
9
|
"""
|
|
10
|
-
from typing import Any, Set, Dict
|
|
11
|
-
import colorama
|
|
12
10
|
import os
|
|
11
|
+
from typing import Any, Dict, Set
|
|
12
|
+
|
|
13
|
+
import colorama
|
|
13
14
|
from rich.console import Console
|
|
14
15
|
from rich.theme import Theme
|
|
16
|
+
|
|
15
17
|
# 初始化colorama以支持跨平台的彩色文本
|
|
16
18
|
colorama.init()
|
|
17
19
|
# 禁用tokenizers并行以避免多进程问题
|
jarvis/jarvis_utils/input.py
CHANGED
|
@@ -8,17 +8,21 @@
|
|
|
8
8
|
- 带有模糊匹配的文件路径补全
|
|
9
9
|
- 用于输入控制的自定义键绑定
|
|
10
10
|
"""
|
|
11
|
+
from colorama import Fore
|
|
12
|
+
from colorama import Style as ColoramaStyle
|
|
13
|
+
from fuzzywuzzy import process
|
|
11
14
|
from prompt_toolkit import PromptSession
|
|
12
|
-
from prompt_toolkit.styles import Style as PromptStyle
|
|
13
|
-
from prompt_toolkit.formatted_text import FormattedText
|
|
14
15
|
from prompt_toolkit.completion import Completer, Completion, PathCompleter
|
|
15
16
|
from prompt_toolkit.document import Document
|
|
17
|
+
from prompt_toolkit.formatted_text import FormattedText
|
|
16
18
|
from prompt_toolkit.key_binding import KeyBindings
|
|
17
|
-
from
|
|
18
|
-
|
|
19
|
-
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
20
|
-
from jarvis.jarvis_utils.tag import ot
|
|
19
|
+
from prompt_toolkit.styles import Style as PromptStyle
|
|
20
|
+
|
|
21
21
|
from jarvis.jarvis_utils.config import get_replace_map
|
|
22
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
23
|
+
from jarvis.jarvis_utils.tag import ot
|
|
24
|
+
|
|
25
|
+
|
|
22
26
|
def get_single_line_input(tip: str) -> str:
|
|
23
27
|
"""
|
|
24
28
|
获取支持历史记录的单行输入。
|
|
@@ -176,9 +180,12 @@ def get_multiline_input(tip: str) -> str:
|
|
|
176
180
|
'prompt': 'ansicyan',
|
|
177
181
|
})
|
|
178
182
|
try:
|
|
183
|
+
import os
|
|
184
|
+
|
|
179
185
|
from prompt_toolkit.history import FileHistory
|
|
186
|
+
|
|
180
187
|
from jarvis.jarvis_utils.config import get_data_dir
|
|
181
|
-
|
|
188
|
+
|
|
182
189
|
# 获取数据目录路径
|
|
183
190
|
history_dir = get_data_dir()
|
|
184
191
|
# 初始化带历史记录的会话
|
|
@@ -7,17 +7,18 @@
|
|
|
7
7
|
- 生成方法论临时文件
|
|
8
8
|
- 上传方法论文件到大模型
|
|
9
9
|
"""
|
|
10
|
-
import os
|
|
11
10
|
import json
|
|
11
|
+
import os
|
|
12
12
|
import tempfile
|
|
13
13
|
from typing import Any, Dict, Optional
|
|
14
14
|
|
|
15
15
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
16
|
-
from jarvis.jarvis_utils.config import get_data_dir
|
|
17
|
-
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
18
16
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
17
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
|
18
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
19
19
|
from jarvis.jarvis_utils.utils import is_context_overflow
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
def _get_methodology_directory() -> str:
|
|
22
23
|
"""
|
|
23
24
|
获取方法论目录路径,如果不存在则创建
|
|
@@ -139,7 +140,8 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
|
139
140
|
返回:
|
|
140
141
|
str: 相关的方法论提示,如果未找到方法论则返回空字符串
|
|
141
142
|
"""
|
|
142
|
-
from yaspin import yaspin
|
|
143
|
+
from yaspin import yaspin # type: ignore
|
|
144
|
+
|
|
143
145
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
144
146
|
|
|
145
147
|
prompt = tool_registery.prompt() if tool_registery else ""
|
jarvis/jarvis_utils/output.py
CHANGED
|
@@ -8,18 +8,22 @@
|
|
|
8
8
|
- 多种编程语言的语法高亮支持
|
|
9
9
|
- 结构化输出的面板显示
|
|
10
10
|
"""
|
|
11
|
-
from enum import Enum
|
|
12
11
|
from datetime import datetime
|
|
12
|
+
from enum import Enum
|
|
13
13
|
from typing import Optional, Tuple
|
|
14
|
-
|
|
15
|
-
from rich.text import Text
|
|
16
|
-
from rich.syntax import Syntax
|
|
17
|
-
from rich.style import Style as RichStyle
|
|
14
|
+
|
|
18
15
|
from pygments.lexers import guess_lexer
|
|
19
16
|
from pygments.util import ClassNotFound
|
|
17
|
+
from rich.box import SIMPLE
|
|
18
|
+
from rich.panel import Panel
|
|
19
|
+
from rich.style import Style as RichStyle
|
|
20
|
+
from rich.syntax import Syntax
|
|
21
|
+
from rich.text import Text
|
|
22
|
+
|
|
20
23
|
from jarvis.jarvis_utils.config import get_pretty_output
|
|
21
24
|
from jarvis.jarvis_utils.globals import console, get_agent_list
|
|
22
|
-
|
|
25
|
+
|
|
26
|
+
|
|
23
27
|
class OutputType(Enum):
|
|
24
28
|
"""
|
|
25
29
|
输出类型枚举,用于分类和样式化不同类型的消息。
|