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

@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.150
3
+ Version: 0.1.152
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -42,7 +42,7 @@ Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
43
  Requires-Dist: requests==2.32.3
44
44
  Requires-Dist: colorama==0.4.6
45
- Requires-Dist: prompt-toolkit==3.0.50
45
+ Requires-Dist: prompt_toolkit==3.0.50
46
46
  Requires-Dist: yaspin==2.4.0
47
47
  Requires-Dist: pygments==2.19.1
48
48
  Requires-Dist: fuzzywuzzy==0.18.0
@@ -54,11 +54,16 @@ Requires-Dist: transformers==4.46.3
54
54
  Requires-Dist: torch==2.4.1
55
55
  Requires-Dist: python-Levenshtein==0.25.1
56
56
  Requires-Dist: sseclient==0.0.27
57
+ Requires-Dist: pillow==10.2.1
57
58
  Provides-Extra: dev
58
59
  Requires-Dist: pytest; extra == "dev"
59
60
  Requires-Dist: black; extra == "dev"
60
61
  Requires-Dist: isort; extra == "dev"
61
62
  Requires-Dist: mypy; extra == "dev"
63
+ Dynamic: author
64
+ Dynamic: home-page
65
+ Dynamic: license-file
66
+ Dynamic: requires-python
62
67
 
63
68
  # 🤖 Jarvis AI 助手
64
69
  <p align="center">
@@ -276,6 +281,30 @@ class CustomTool:
276
281
  ```
277
282
 
278
283
 
284
+ ### 添加MCP
285
+ MCP(模型上下文协议)。在`~/.jarvis/tools/mcp/`中创建YAML配置文件:
286
+
287
+ #### 本地MCP配置(`stdio`模式)
288
+ ```yaml
289
+ type: local
290
+ name: MCP名称
291
+ command: 可执行命令
292
+ args: [参数列表] # 可选
293
+ env: # 可选环境变量
294
+ KEY: VALUE
295
+ ```
296
+
297
+ #### 远程MCP配置(`sse`模式)
298
+ ```yaml
299
+ type: remote
300
+ name: MCP名称
301
+ base_url: http://example.com/api
302
+ auth_token: 认证令牌 # 可选
303
+ headers: # 可选HTTP头
304
+ X-Custom-Header: value
305
+ ```
306
+
307
+
279
308
  ### 添加新大模型平台
280
309
  在 `~/.jarvis/platforms/` 中创建新的 Python 文件:
281
310
  ```python
@@ -1,5 +1,5 @@
1
- jarvis/__init__.py,sha256=LAXd2PqzX1hdAOiMxEwjP0kqPkpnlGGCzmHQH7bDoXI,50
2
- jarvis/jarvis_agent/__init__.py,sha256=QtWu2kh6o5IB_XtGLoxHi5K9lA1t8XoqNUXtX-OqujY,23796
1
+ jarvis/__init__.py,sha256=tsvFvhy5rydxyl_d92GGD4EZIoZ_0NHYhtgTGOJ2GZk,50
2
+ jarvis/jarvis_agent/__init__.py,sha256=LeFNTT1Mzc-PH_bNQ7KRbvBowfQifEQc-Moiun85_9Q,24000
3
3
  jarvis/jarvis_agent/builtin_input_handler.py,sha256=0SjlBYnBWKNi3eVdZ7c2NuP82tQej7DEWLAqG6bY1Rc,4357
4
4
  jarvis/jarvis_agent/file_input_handler.py,sha256=6R68cSjLBnSJjTKJrSO2IqziRDFnxazU_Jq2t1W1ndo,3695
5
5
  jarvis/jarvis_agent/jarvis.py,sha256=-Q-h1M4dgElFnoA2B9H3r0LmnQdoPfiy2JPXzNNihBQ,5155
@@ -35,16 +35,16 @@ jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
35
35
  jarvis/jarvis_git_details/main.py,sha256=YowncVxYyJ3y2EvGrZhAJeR4yizXp6aB3dqvoYTepFY,6117
36
36
  jarvis/jarvis_git_squash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  jarvis/jarvis_git_squash/main.py,sha256=xBNkAl7_8_pQC-C6RcUImA1mEU4KTqhjtA57rG_mMJ8,2179
38
- jarvis/jarvis_git_utils/git_commiter.py,sha256=dozU5vmodhb-uiLJBHGRPzUMU1er4xqvjClG3sqNwTA,10780
38
+ jarvis/jarvis_git_utils/git_commiter.py,sha256=pnUiX-KkAMLDBRMXot93T9zTdoYsIJpqVMozMwQo6R0,11096
39
39
  jarvis/jarvis_lsp/base.py,sha256=f-76xgNijfQ4G3Q0t8IfOGtCu-q2TSQ7a_in6XwDb_8,2030
40
40
  jarvis/jarvis_lsp/cpp.py,sha256=ekci2M9_UtkCSEe9__72h26Gat93r9_knL2VmFr8X5M,3141
41
41
  jarvis/jarvis_lsp/go.py,sha256=sSypuQSP5X2YtrVMC8XCc5nXkgfG93SO7sC89lHzoR8,3458
42
42
  jarvis/jarvis_lsp/python.py,sha256=OJuYHLHI1aYNNWcAFayy_5GxogwyMC3A7KOYGjxN1yg,1843
43
43
  jarvis/jarvis_lsp/registry.py,sha256=-b7lAfZ6SNp3O0ifRiFSLxH0xJlPQhkq4DATDDjJb1U,6491
44
44
  jarvis/jarvis_lsp/rust.py,sha256=ICmQs5UVdMZwn5KjaF1YRXBCLUMtGF8Z9IwE5rqWkrU,3686
45
- jarvis/jarvis_mcp/__init__.py,sha256=gVPImIkjVSYdc9hJykceEiHnO19oX-rHAUuVR3Ztczg,1044
46
- jarvis/jarvis_mcp/local_mcp_client.py,sha256=cTOVtrMSZCyPsDNvC5egUus11YWSrZYyR7XKBkIIfgo,8404
47
- jarvis/jarvis_mcp/remote_mcp_client.py,sha256=ji7wO0VxM3I9lDV7eQ1TBTCX9VL6EAVwAVOXnxGxVo4,8112
45
+ jarvis/jarvis_mcp/__init__.py,sha256=gi74_Yz5nsEFhrAyCg1Ovxsj-hLweLjMGoOaceL2yx4,2090
46
+ jarvis/jarvis_mcp/sse_mcp_client.py,sha256=PfhVzJLLb9OAHyxn8wcU2yFRN-EH0_wZiHU_JC8xhvI,23475
47
+ jarvis/jarvis_mcp/stdio_mcp_client.py,sha256=1II-dRWVXXZXZCDfqJNxhmF5kpLt9RHSERe-zZ8iOJ0,11790
48
48
  jarvis/jarvis_methodology/main.py,sha256=IBv87UOmdCailgooMtWEcqZcQHmNLhZD-kkGw5jOcVg,3375
49
49
  jarvis/jarvis_multi_agent/__init__.py,sha256=SX8lBErhltKyYRM-rymrMz3sJ0Zl3hBXrpsPdFgzkQc,4399
50
50
  jarvis/jarvis_multi_agent/main.py,sha256=aGuUC3YQmahabqwDwZXJjfQLYsZ3KIZdf8DZDlVNMe4,1543
@@ -58,7 +58,7 @@ jarvis/jarvis_platform_manager/main.py,sha256=o7UDrcCkLf9dTh2LOO-_bQVHjWf2X6RuSY
58
58
  jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  jarvis/jarvis_smart_shell/main.py,sha256=slP_8CwpfMjWFZis0At1ANRlPb3gx1KteAg1B7R7dl4,4546
60
60
  jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- jarvis/jarvis_tools/ask_codebase.py,sha256=xQTcuDl7cbH6uVkWlkA1HXJAo4_3r09-3SboUkBEBDU,10062
61
+ jarvis/jarvis_tools/ask_codebase.py,sha256=S6NArvKZyK8WEbsEgeGCljjg4D9mteWrq9m352V58jU,9635
62
62
  jarvis/jarvis_tools/ask_user.py,sha256=NjxTCHGKo4nthbEQD-isvPCW4PQhTcekEferjnukX70,2143
63
63
  jarvis/jarvis_tools/base.py,sha256=vskI4czVdlhbo38ODuF9rFrnWBYQIhJSPAqAkLVcyTs,1165
64
64
  jarvis/jarvis_tools/chdir.py,sha256=do_OdtabiH3lZcT_ynjSAX66XgH2gPl9mYiS7dMMDa8,2682
@@ -73,22 +73,22 @@ jarvis/jarvis_tools/lsp_get_diagnostics.py,sha256=IYqv8jQwSK71sZpDBRolSDnYii8t0M
73
73
  jarvis/jarvis_tools/methodology.py,sha256=gnlJojY4Dg5v9AAB5xcpKqpPIHs0tOYVtzTHkwOrWk0,5214
74
74
  jarvis/jarvis_tools/read_code.py,sha256=_X6D3AIgRD9YplSDnFhXOm8wQAZMA3pkkXy31SG33l0,6041
75
75
  jarvis/jarvis_tools/read_webpage.py,sha256=syduSZK4kXRRTPzeZ2W9Q6YH5umKiMJZyjA0cCpSF4g,2198
76
- jarvis/jarvis_tools/registry.py,sha256=-wzv1Xfzvzu8-A22xTvPnGhgYamuFU_PVmpr_sgoxA8,23083
76
+ jarvis/jarvis_tools/registry.py,sha256=qw9uxfosqjFM1H-i6L4kpgkwK_wNlQjUHmVSP8XxUMU,24821
77
77
  jarvis/jarvis_tools/search_web.py,sha256=kWW9K2QUR2AxPq6gcyx4Bgy-0Y4gzcdErq1DNT1EYM4,1333
78
78
  jarvis/jarvis_tools/virtual_tty.py,sha256=Rpn9VXUG17LQsY87F_O6UCjN_opXB05mpwozxYf-xVI,16372
79
79
  jarvis/jarvis_utils/__init__.py,sha256=KMg-KY5rZIhGTeOD5e2Xo5CU7DX1DUz4ULWAaTQ-ZNw,825
80
- jarvis/jarvis_utils/config.py,sha256=1OKG64hK740C1RzGk4Kov-6MgpODupMLhuma_OO5vxs,3317
80
+ jarvis/jarvis_utils/config.py,sha256=UXIwt1TknkYIuNW15TNiyZ1HJFdjjAzmt_D7_cd6xxQ,3317
81
81
  jarvis/jarvis_utils/embedding.py,sha256=_Q-VurYHQZSsyISClTFjadDaNqNPBMqJe58lMM6bsVs,6991
82
82
  jarvis/jarvis_utils/file_processors.py,sha256=oNtVlz2JHcQ60NS6sgI-VsvYXOnsQgFUEVenznCXHC4,2952
83
83
  jarvis/jarvis_utils/git_utils.py,sha256=j_Jw6h7JD91XhMf0WD3MAH4URkLUBrrYCLnuLm1GeN4,5630
84
84
  jarvis/jarvis_utils/globals.py,sha256=Ed2d6diWXCgI74HVV_tI4qW7yXxLpNvQKN2yG0IH9hc,3388
85
85
  jarvis/jarvis_utils/input.py,sha256=QhqZEF4BpOGDgNEBrTBabA5n8DnlU0GaHqbKUEZ13Ls,6953
86
- jarvis/jarvis_utils/methodology.py,sha256=dVk_1GmVFlZnj1EPR_3wilP2-vyOygAIH56w_8PC8Sw,6281
86
+ jarvis/jarvis_utils/methodology.py,sha256=Q2ldjarnZLU9dBY-i2hOP1WL0SOa8VX_uxNEwE422TY,6400
87
87
  jarvis/jarvis_utils/output.py,sha256=BmWdB1bmizv0xfU4Z___9p_xQodorriIcEgADVq9fk0,8416
88
88
  jarvis/jarvis_utils/utils.py,sha256=j-YZap58avAzSb9ZuB2I71trVqVxIpFxxZDoh8_7a_o,4653
89
- jarvis_ai_assistant-0.1.150.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
90
- jarvis_ai_assistant-0.1.150.dist-info/METADATA,sha256=7qCut4ZuAw6wrI-H61ZzAYaeeljHvPen4W2fDTr0Zrk,10975
91
- jarvis_ai_assistant-0.1.150.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
92
- jarvis_ai_assistant-0.1.150.dist-info/entry_points.txt,sha256=4ZS8kq6jahnmfDyXFSx39HRi-Tkbp0uFc6cTXt3QIHA,929
93
- jarvis_ai_assistant-0.1.150.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
94
- jarvis_ai_assistant-0.1.150.dist-info/RECORD,,
89
+ jarvis_ai_assistant-0.1.152.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
90
+ jarvis_ai_assistant-0.1.152.dist-info/METADATA,sha256=px1hZu22QjDeJXmG5oKS2quEvDgShgOhUAWL8kybgnM,11562
91
+ jarvis_ai_assistant-0.1.152.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
92
+ jarvis_ai_assistant-0.1.152.dist-info/entry_points.txt,sha256=4ZS8kq6jahnmfDyXFSx39HRi-Tkbp0uFc6cTXt3QIHA,929
93
+ jarvis_ai_assistant-0.1.152.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
94
+ jarvis_ai_assistant-0.1.152.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.2)
2
+ Generator: setuptools (79.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,230 +0,0 @@
1
- from typing import Any, Dict, List
2
- import requests
3
- import sseclient
4
- from urllib.parse import urljoin
5
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
- from . import McpClient
7
-
8
-
9
- class RemoteMcpClient(McpClient):
10
- """远程MCP客户端实现
11
-
12
- 参数:
13
- config: 配置字典,包含以下字段:
14
- - base_url: str - MCP服务器的基础URL
15
- - auth_token: str - 认证令牌(可选)
16
- - headers: Dict[str, str] - 额外的HTTP头(可选)
17
- """
18
- def __init__(self, config: Dict[str, Any]):
19
- self.config = config
20
- self.base_url = config.get('base_url', '')
21
- if not self.base_url:
22
- raise ValueError('No base_url specified in config')
23
-
24
- # 设置HTTP客户端
25
- self.session = requests.Session()
26
- self.session.headers.update({
27
- 'Content-Type': 'application/json',
28
- 'Accept': 'application/json',
29
- })
30
-
31
- # 添加认证令牌(如果提供)
32
- auth_token = config.get('auth_token')
33
- if auth_token:
34
- self.session.headers['Authorization'] = f'Bearer {auth_token}'
35
-
36
- # 添加额外的HTTP头
37
- extra_headers = config.get('headers', {})
38
- self.session.headers.update(extra_headers)
39
-
40
- # 初始化SSE连接
41
- self.sse_client = None
42
- self._initialize()
43
-
44
- def _initialize(self) -> None:
45
- """初始化MCP连接"""
46
- try:
47
- # 发送初始化请求
48
- response = self._send_request('initialize', {
49
- 'processId': None, # 远程客户端不需要进程ID
50
- 'clientInfo': {
51
- 'name': 'jarvis',
52
- 'version': '1.0.0'
53
- },
54
- 'capabilities': {},
55
- 'protocolVersion': "2025-03-26"
56
- })
57
-
58
- # 验证服务器响应
59
- if 'result' not in response:
60
- raise RuntimeError(f"初始化失败: {response.get('error', 'Unknown error')}")
61
-
62
- result = response['result']
63
-
64
- # 发送initialized通知 - 使用正确的方法名格式
65
- self._send_notification('notifications/initialized', {})
66
-
67
- # 建立SSE连接
68
- sse_url = urljoin(self.base_url, 'events')
69
- response = self.session.get(sse_url, stream=True)
70
- self.sse_client = sseclient.SSEClient(response)
71
-
72
- except Exception as e:
73
- PrettyOutput.print(f"MCP初始化失败: {str(e)}", OutputType.ERROR)
74
- raise
75
-
76
- def _send_request(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
77
- """发送请求到MCP服务器
78
-
79
- 参数:
80
- method: 请求方法
81
- params: 请求参数
82
-
83
- 返回:
84
- Dict[str, Any]: 响应结果
85
- """
86
- try:
87
- # 构建请求
88
- request = {
89
- 'jsonrpc': '2.0',
90
- 'method': method,
91
- 'params': params,
92
- 'id': 1
93
- }
94
-
95
- # 发送请求
96
- response = self.session.post(
97
- urljoin(self.base_url, 'rpc'),
98
- json=request
99
- )
100
- response.raise_for_status()
101
- return response.json()
102
-
103
- except Exception as e:
104
- PrettyOutput.print(f"发送请求失败: {str(e)}", OutputType.ERROR)
105
- raise
106
-
107
- def _send_notification(self, method: str, params: Dict[str, Any]) -> None:
108
- """发送通知到MCP服务器(不需要响应)
109
-
110
- 参数:
111
- method: 通知方法
112
- params: 通知参数
113
- """
114
- try:
115
- # 构建通知
116
- notification = {
117
- 'jsonrpc': '2.0',
118
- 'method': method,
119
- 'params': params
120
- }
121
-
122
- # 发送通知
123
- response = self.session.post(
124
- urljoin(self.base_url, 'rpc'),
125
- json=notification
126
- )
127
- response.raise_for_status()
128
-
129
- except Exception as e:
130
- PrettyOutput.print(f"发送通知失败: {str(e)}", OutputType.ERROR)
131
- raise
132
-
133
- def get_tool_list(self) -> List[Dict[str, Any]]:
134
- """获取工具列表
135
-
136
- 返回:
137
- List[Dict[str, Any]]: 工具列表,每个工具包含以下字段:
138
- - name: str - 工具名称
139
- - description: str - 工具描述
140
- - parameters: Dict - 工具参数
141
- """
142
- try:
143
- response = self._send_request('tools/list', {})
144
- if 'result' in response and 'tools' in response['result']:
145
- # 注意这里: 响应结构是 response['result']['tools']
146
- tools = response['result']['tools']
147
- # 将MCP协议字段转换为内部格式
148
- formatted_tools = []
149
- for tool in tools:
150
- # 从inputSchema中提取参数定义
151
- input_schema = tool.get('inputSchema', {})
152
- parameters = {}
153
- if 'properties' in input_schema:
154
- parameters = input_schema['properties']
155
-
156
- formatted_tools.append({
157
- 'name': tool.get('name', ''),
158
- 'description': tool.get('description', ''),
159
- 'parameters': parameters
160
- })
161
- return formatted_tools
162
- else:
163
- error_msg = "获取工具列表失败"
164
- if 'error' in response:
165
- error_msg += f": {response['error']}"
166
- elif 'result' in response:
167
- error_msg += f": 响应格式不正确 - {response['result']}"
168
- else:
169
- error_msg += ": 未知错误"
170
-
171
- PrettyOutput.print(error_msg, OutputType.ERROR)
172
- return []
173
- except Exception as e:
174
- PrettyOutput.print(f"获取工具列表失败: {str(e)}", OutputType.ERROR)
175
- return []
176
-
177
- def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
178
- """执行工具
179
-
180
- 参数:
181
- tool_name: 工具名称
182
- arguments: 参数字典,包含工具执行所需的参数
183
-
184
- 返回:
185
- Dict[str, Any]: 执行结果,包含以下字段:
186
- - success: bool - 是否执行成功
187
- - stdout: str - 标准输出
188
- - stderr: str - 标准错误
189
- """
190
- try:
191
- response = self._send_request('tools/call', {
192
- 'name': tool_name,
193
- 'arguments': arguments
194
- })
195
- if 'result' in response:
196
- result = response['result']
197
- # 从content中提取输出信息
198
- stdout = ''
199
- stderr = ''
200
- for content in result.get('content', []):
201
- if content.get('type') == 'text':
202
- stdout += content.get('text', '')
203
- elif content.get('type') == 'error':
204
- stderr += content.get('text', '')
205
-
206
- return {
207
- 'success': True,
208
- 'stdout': stdout,
209
- 'stderr': stderr
210
- }
211
- else:
212
- return {
213
- 'success': False,
214
- 'stdout': '',
215
- 'stderr': response.get('error', 'Unknown error')
216
- }
217
- except Exception as e:
218
- PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
219
- return {
220
- 'success': False,
221
- 'stdout': '',
222
- 'stderr': str(e)
223
- }
224
-
225
- def __del__(self):
226
- """清理资源"""
227
- if self.sse_client and hasattr(self.sse_client, 'resp'):
228
- self.sse_client.resp.close()
229
- if self.session:
230
- self.session.close()