jarvis-ai-assistant 0.1.178__py3-none-any.whl → 0.1.179__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (65) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +130 -79
  3. jarvis/jarvis_agent/builtin_input_handler.py +1 -1
  4. jarvis/jarvis_agent/jarvis.py +9 -13
  5. jarvis/jarvis_agent/main.py +4 -2
  6. jarvis/jarvis_code_agent/code_agent.py +34 -23
  7. jarvis/jarvis_code_agent/lint.py +164 -0
  8. jarvis/jarvis_code_analysis/checklists/loader.py +6 -20
  9. jarvis/jarvis_code_analysis/code_review.py +8 -6
  10. jarvis/jarvis_dev/main.py +1 -8
  11. jarvis/jarvis_git_details/main.py +1 -1
  12. jarvis/jarvis_git_squash/main.py +5 -3
  13. jarvis/jarvis_git_utils/git_commiter.py +24 -23
  14. jarvis/jarvis_mcp/sse_mcp_client.py +6 -4
  15. jarvis/jarvis_mcp/stdio_mcp_client.py +5 -4
  16. jarvis/jarvis_mcp/streamable_mcp_client.py +404 -0
  17. jarvis/jarvis_methodology/main.py +10 -9
  18. jarvis/jarvis_multi_agent/main.py +3 -1
  19. jarvis/jarvis_platform/base.py +14 -8
  20. jarvis/jarvis_platform/human.py +3 -1
  21. jarvis/jarvis_platform/kimi.py +10 -7
  22. jarvis/jarvis_platform/openai.py +4 -1
  23. jarvis/jarvis_platform/registry.py +6 -2
  24. jarvis/jarvis_platform/yuanbao.py +13 -10
  25. jarvis/jarvis_platform_manager/main.py +11 -9
  26. jarvis/jarvis_smart_shell/main.py +1 -0
  27. jarvis/jarvis_tools/ask_codebase.py +4 -3
  28. jarvis/jarvis_tools/ask_user.py +2 -1
  29. jarvis/jarvis_tools/base.py +3 -1
  30. jarvis/jarvis_tools/chdir.py +2 -1
  31. jarvis/jarvis_tools/cli/main.py +1 -0
  32. jarvis/jarvis_tools/code_plan.py +5 -3
  33. jarvis/jarvis_tools/create_code_agent.py +5 -2
  34. jarvis/jarvis_tools/create_sub_agent.py +1 -3
  35. jarvis/jarvis_tools/edit_file.py +3 -3
  36. jarvis/jarvis_tools/execute_script.py +1 -1
  37. jarvis/jarvis_tools/file_analyzer.py +5 -3
  38. jarvis/jarvis_tools/file_operation.py +4 -7
  39. jarvis/jarvis_tools/find_methodology.py +4 -2
  40. jarvis/jarvis_tools/generate_new_tool.py +2 -1
  41. jarvis/jarvis_tools/methodology.py +3 -4
  42. jarvis/jarvis_tools/read_code.py +2 -1
  43. jarvis/jarvis_tools/read_webpage.py +3 -1
  44. jarvis/jarvis_tools/registry.py +22 -13
  45. jarvis/jarvis_tools/rewrite_file.py +2 -1
  46. jarvis/jarvis_tools/search_web.py +1 -0
  47. jarvis/jarvis_tools/virtual_tty.py +5 -4
  48. jarvis/jarvis_utils/__init__.py +2 -0
  49. jarvis/jarvis_utils/builtin_replace_map.py +1 -1
  50. jarvis/jarvis_utils/config.py +31 -1
  51. jarvis/jarvis_utils/embedding.py +4 -3
  52. jarvis/jarvis_utils/file_processors.py +1 -0
  53. jarvis/jarvis_utils/git_utils.py +55 -25
  54. jarvis/jarvis_utils/globals.py +4 -2
  55. jarvis/jarvis_utils/input.py +14 -7
  56. jarvis/jarvis_utils/methodology.py +6 -4
  57. jarvis/jarvis_utils/output.py +10 -6
  58. jarvis/jarvis_utils/utils.py +89 -13
  59. {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/METADATA +45 -33
  60. jarvis_ai_assistant-0.1.179.dist-info/RECORD +98 -0
  61. jarvis_ai_assistant-0.1.178.dist-info/RECORD +0 -96
  62. {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/WHEEL +0 -0
  63. {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/entry_points.txt +0 -0
  64. {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/licenses/LICENSE +0 -0
  65. {jarvis_ai_assistant-0.1.178.dist-info → jarvis_ai_assistant-0.1.179.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,404 @@
1
+ # -*- coding: utf-8 -*-
2
+ import json
3
+ import threading
4
+ from typing import Any, Callable, Dict, List
5
+ from urllib.parse import urljoin
6
+
7
+ import requests
8
+
9
+ from jarvis.jarvis_mcp import McpClient
10
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
11
+
12
+
13
+ class StreamableMcpClient(McpClient):
14
+ """Streamable HTTP MCP客户端实现
15
+
16
+ 参数:
17
+ config: 配置字典,包含以下字段:
18
+ - base_url: str - MCP服务器的基础URL
19
+ - auth_token: str - 认证令牌(可选)
20
+ - headers: Dict[str, str] - 额外的HTTP头(可选)
21
+ """
22
+ def __init__(self, config: Dict[str, Any]):
23
+ self.config = config
24
+ self.base_url = config.get('base_url', '')
25
+ if not self.base_url:
26
+ raise ValueError('No base_url specified in config')
27
+
28
+ # 设置HTTP客户端
29
+ self.session = requests.Session()
30
+ self.session.headers.update({
31
+ 'Content-Type': 'application/json',
32
+ 'Accept': 'application/json',
33
+ })
34
+
35
+ # 添加认证令牌(如果提供)
36
+ auth_token = config.get('auth_token')
37
+ if auth_token:
38
+ self.session.headers['Authorization'] = f'Bearer {auth_token}'
39
+
40
+ # 添加额外的HTTP头
41
+ extra_headers = config.get('headers', {})
42
+ self.session.headers.update(extra_headers)
43
+
44
+ # 请求相关属性
45
+ self.pending_requests = {} # 存储等待响应的请求 {id: Event}
46
+ self.request_results = {} # 存储请求结果 {id: result}
47
+ self.notification_handlers = {}
48
+ self.event_lock = threading.Lock()
49
+ self.request_id_counter = 0
50
+
51
+ # 初始化连接
52
+ self._initialize()
53
+
54
+ def _initialize(self) -> None:
55
+ """初始化MCP连接"""
56
+ try:
57
+ # 发送初始化请求
58
+ response = self._send_request('initialize', {
59
+ 'processId': None, # 远程客户端不需要进程ID
60
+ 'clientInfo': {
61
+ 'name': 'jarvis',
62
+ 'version': '1.0.0'
63
+ },
64
+ 'capabilities': {},
65
+ 'protocolVersion': "2025-03-26"
66
+ })
67
+
68
+ # 验证服务器响应
69
+ if 'result' not in response:
70
+ raise RuntimeError(f"初始化失败: {response.get('error', 'Unknown error')}")
71
+
72
+ # 发送initialized通知
73
+ self._send_notification('notifications/initialized', {})
74
+
75
+ except Exception as e:
76
+ PrettyOutput.print(f"MCP初始化失败: {str(e)}", OutputType.ERROR)
77
+ raise
78
+
79
+ def register_notification_handler(self, method: str, handler: Callable) -> None:
80
+ """注册通知处理器
81
+
82
+ 参数:
83
+ method: 通知方法名
84
+ handler: 处理通知的回调函数,接收params参数
85
+ """
86
+ with self.event_lock:
87
+ if method not in self.notification_handlers:
88
+ self.notification_handlers[method] = []
89
+ self.notification_handlers[method].append(handler)
90
+
91
+ def unregister_notification_handler(self, method: str, handler: Callable) -> None:
92
+ """注销通知处理器
93
+
94
+ 参数:
95
+ method: 通知方法名
96
+ handler: 要注销的处理器函数
97
+ """
98
+ with self.event_lock:
99
+ if method in self.notification_handlers:
100
+ if handler in self.notification_handlers[method]:
101
+ self.notification_handlers[method].remove(handler)
102
+ if not self.notification_handlers[method]:
103
+ del self.notification_handlers[method]
104
+
105
+ def _get_next_request_id(self) -> str:
106
+ """获取下一个请求ID"""
107
+ with self.event_lock:
108
+ self.request_id_counter += 1
109
+ return str(self.request_id_counter)
110
+
111
+ def _send_request(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
112
+ """发送请求到MCP服务器
113
+
114
+ 参数:
115
+ method: 请求方法
116
+ params: 请求参数
117
+
118
+ 返回:
119
+ Dict[str, Any]: 响应结果
120
+ """
121
+ # 生成唯一请求ID
122
+ req_id = self._get_next_request_id()
123
+
124
+ # 创建事件标志,用于等待响应
125
+ event = threading.Event()
126
+
127
+ with self.event_lock:
128
+ self.pending_requests[req_id] = event
129
+
130
+ try:
131
+ # 构建请求
132
+ request = {
133
+ 'jsonrpc': '2.0',
134
+ 'method': method,
135
+ 'params': params,
136
+ 'id': req_id
137
+ }
138
+
139
+ # 发送请求到Streamable HTTP端点
140
+ mcp_url = urljoin(self.base_url, 'mcp')
141
+ response = self.session.post(
142
+ mcp_url,
143
+ json=request,
144
+ stream=True # 启用流式传输
145
+ )
146
+ response.raise_for_status()
147
+
148
+ # 处理流式响应
149
+ result = None
150
+ for line in response.iter_lines(decode_unicode=True):
151
+ if line:
152
+ try:
153
+ data = json.loads(line)
154
+ if 'id' in data and data['id'] == req_id:
155
+ # 这是我们的请求响应
156
+ result = data
157
+ break
158
+ elif 'method' in data:
159
+ # 这是一个通知
160
+ method = data.get('method', '')
161
+ params = data.get('params', {})
162
+ if method in self.notification_handlers:
163
+ for handler in self.notification_handlers[method]:
164
+ try:
165
+ handler(params)
166
+ except Exception as e:
167
+ PrettyOutput.print(
168
+ f"处理通知时出错 ({method}): {e}",
169
+ OutputType.ERROR
170
+ )
171
+ except json.JSONDecodeError:
172
+ PrettyOutput.print(f"无法解析响应: {line}", OutputType.WARNING)
173
+ continue
174
+
175
+ if result is None:
176
+ raise RuntimeError(f"未收到响应: {method}")
177
+
178
+ return result
179
+
180
+ except Exception as e:
181
+ PrettyOutput.print(f"发送请求失败: {str(e)}", OutputType.ERROR)
182
+ raise
183
+ finally:
184
+ # 清理请求状态
185
+ with self.event_lock:
186
+ self.pending_requests.pop(req_id, None)
187
+ self.request_results.pop(req_id, None)
188
+
189
+ def _send_notification(self, method: str, params: Dict[str, Any]) -> None:
190
+ """发送通知到MCP服务器(不需要响应)
191
+
192
+ 参数:
193
+ method: 通知方法
194
+ params: 通知参数
195
+ """
196
+ try:
197
+ # 构建通知
198
+ notification = {
199
+ 'jsonrpc': '2.0',
200
+ 'method': method,
201
+ 'params': params
202
+ }
203
+
204
+ # 发送通知到Streamable HTTP端点
205
+ mcp_url = urljoin(self.base_url, 'mcp')
206
+ response = self.session.post(
207
+ mcp_url,
208
+ json=notification
209
+ )
210
+ response.raise_for_status()
211
+
212
+ except Exception as e:
213
+ PrettyOutput.print(f"发送通知失败: {str(e)}", OutputType.ERROR)
214
+ raise
215
+
216
+ def get_tool_list(self) -> List[Dict[str, Any]]:
217
+ """获取工具列表
218
+
219
+ 返回:
220
+ List[Dict[str, Any]]: 工具列表,每个工具包含以下字段:
221
+ - name: str - 工具名称
222
+ - description: str - 工具描述
223
+ - parameters: Dict - 工具参数
224
+ """
225
+ try:
226
+ response = self._send_request('tools/list', {})
227
+ if 'result' in response and 'tools' in response['result']:
228
+ # 注意这里: 响应结构是 response['result']['tools']
229
+ tools = response['result']['tools']
230
+ # 将MCP协议字段转换为内部格式
231
+ formatted_tools = []
232
+ for tool in tools:
233
+ # 从inputSchema中提取参数定义
234
+ input_schema = tool.get('inputSchema', {})
235
+ parameters = {}
236
+ if 'properties' in input_schema:
237
+ parameters = input_schema['properties']
238
+
239
+ formatted_tools.append({
240
+ 'name': tool.get('name', ''),
241
+ 'description': tool.get('description', ''),
242
+ 'parameters': parameters
243
+ })
244
+ return formatted_tools
245
+ else:
246
+ error_msg = "获取工具列表失败"
247
+ if 'error' in response:
248
+ error_msg += f": {response['error']}"
249
+ elif 'result' in response:
250
+ error_msg += f": 响应格式不正确 - {response['result']}"
251
+ else:
252
+ error_msg += ": 未知错误"
253
+
254
+ PrettyOutput.print(error_msg, OutputType.ERROR)
255
+ return []
256
+ except Exception as e:
257
+ PrettyOutput.print(f"获取工具列表失败: {str(e)}", OutputType.ERROR)
258
+ return []
259
+
260
+ def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
261
+ """执行工具
262
+
263
+ 参数:
264
+ tool_name: 工具名称
265
+ arguments: 参数字典,包含工具执行所需的参数
266
+
267
+ 返回:
268
+ Dict[str, Any]: 执行结果,包含以下字段:
269
+ - success: bool - 是否执行成功
270
+ - stdout: str - 标准输出
271
+ - stderr: str - 标准错误
272
+ """
273
+ try:
274
+ response = self._send_request('tools/call', {
275
+ 'name': tool_name,
276
+ 'arguments': arguments
277
+ })
278
+ if 'result' in response:
279
+ result = response['result']
280
+ # 从content中提取输出信息
281
+ stdout = ''
282
+ stderr = ''
283
+ for content in result.get('content', []):
284
+ if content.get('type') == 'text':
285
+ stdout += content.get('text', '')
286
+ elif content.get('type') == 'error':
287
+ stderr += content.get('text', '')
288
+
289
+ return {
290
+ 'success': True,
291
+ 'stdout': stdout,
292
+ 'stderr': stderr
293
+ }
294
+ else:
295
+ return {
296
+ 'success': False,
297
+ 'stdout': '',
298
+ 'stderr': response.get('error', 'Unknown error')
299
+ }
300
+ except Exception as e:
301
+ PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
302
+ return {
303
+ 'success': False,
304
+ 'stdout': '',
305
+ 'stderr': str(e)
306
+ }
307
+
308
+ def get_resource_list(self) -> List[Dict[str, Any]]:
309
+ """获取资源列表
310
+
311
+ 返回:
312
+ List[Dict[str, Any]]: 资源列表,每个资源包含以下字段:
313
+ - uri: str - 资源的唯一标识符
314
+ - name: str - 资源的名称
315
+ - description: str - 资源的描述(可选)
316
+ - mimeType: str - 资源的MIME类型(可选)
317
+ """
318
+ try:
319
+ response = self._send_request('resources/list', {})
320
+ if 'result' in response and 'resources' in response['result']:
321
+ return response['result']['resources']
322
+ else:
323
+ error_msg = "获取资源列表失败"
324
+ if 'error' in response:
325
+ error_msg += f": {response['error']}"
326
+ else:
327
+ error_msg += ": 未知错误"
328
+ PrettyOutput.print(error_msg, OutputType.ERROR)
329
+ return []
330
+ except Exception as e:
331
+ PrettyOutput.print(f"获取资源列表失败: {str(e)}", OutputType.ERROR)
332
+ return []
333
+
334
+ def get_resource(self, uri: str) -> Dict[str, Any]:
335
+ """获取指定资源的内容
336
+
337
+ 参数:
338
+ uri: str - 资源的URI标识符
339
+
340
+ 返回:
341
+ Dict[str, Any]: 执行结果,包含以下字段:
342
+ - success: bool - 是否执行成功
343
+ - stdout: str - 资源内容(文本或base64编码的二进制内容)
344
+ - stderr: str - 错误信息
345
+ """
346
+ try:
347
+ response = self._send_request('resources/read', {
348
+ 'uri': uri
349
+ })
350
+ if 'result' in response and 'contents' in response['result']:
351
+ contents = response['result']['contents']
352
+ if contents:
353
+ content = contents[0] # 获取第一个资源内容
354
+ # 根据资源类型返回内容
355
+ if 'text' in content:
356
+ return {
357
+ 'success': True,
358
+ 'stdout': content['text'],
359
+ 'stderr': ''
360
+ }
361
+ elif 'blob' in content:
362
+ return {
363
+ 'success': True,
364
+ 'stdout': content['blob'],
365
+ 'stderr': ''
366
+ }
367
+ return {
368
+ 'success': False,
369
+ 'stdout': '',
370
+ 'stderr': '资源内容为空'
371
+ }
372
+ else:
373
+ error_msg = "获取资源内容失败"
374
+ if 'error' in response:
375
+ error_msg += f": {response['error']}"
376
+ else:
377
+ error_msg += ": 未知错误"
378
+ PrettyOutput.print(error_msg, OutputType.ERROR)
379
+ return {
380
+ 'success': False,
381
+ 'stdout': '',
382
+ 'stderr': error_msg
383
+ }
384
+ except Exception as e:
385
+ error_msg = f"获取资源内容失败: {str(e)}"
386
+ PrettyOutput.print(error_msg, OutputType.ERROR)
387
+ return {
388
+ 'success': False,
389
+ 'stdout': '',
390
+ 'stderr': error_msg
391
+ }
392
+
393
+ def __del__(self):
394
+ """清理资源"""
395
+ # 清理请求状态
396
+ with self.event_lock:
397
+ for event in self.pending_requests.values():
398
+ event.set() # 释放所有等待的请求
399
+ self.pending_requests.clear()
400
+ self.request_results.clear()
401
+
402
+ # 关闭HTTP会话
403
+ if self.session:
404
+ self.session.close()
@@ -8,18 +8,19 @@
8
8
  - 列出所有方法论
9
9
  """
10
10
 
11
+ import argparse
11
12
  import hashlib
12
- import os
13
13
  import json
14
- import argparse
15
- import yaml # type: ignore
16
- from jarvis.jarvis_utils.methodology import (
17
- _get_methodology_directory,
18
- _load_all_methodologies
19
- )
14
+ import os
15
+
16
+ import yaml # type: ignore
17
+ from yaspin import yaspin # type: ignore
18
+
20
19
  from jarvis.jarvis_platform.registry import PlatformRegistry
21
- from jarvis.jarvis_utils.output import PrettyOutput, OutputType
22
- from yaspin import yaspin # type: ignore
20
+ from jarvis.jarvis_utils.methodology import (_get_methodology_directory,
21
+ _load_all_methodologies)
22
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
23
+
23
24
 
24
25
  def import_methodology(input_file):
25
26
  """导入方法论文件(合并策略)"""
@@ -1,8 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import yaml
3
+
3
4
  from jarvis.jarvis_multi_agent import MultiAgent
4
- from jarvis.jarvis_utils.utils import init_env
5
5
  from jarvis.jarvis_utils.input import get_multiline_input
6
+ from jarvis.jarvis_utils.utils import init_env
7
+
6
8
 
7
9
  def main():
8
10
  """从YAML配置文件初始化并运行多智能体系统
@@ -1,19 +1,23 @@
1
1
  # -*- coding: utf-8 -*-
2
- from abc import ABC, abstractmethod
3
2
  import re
3
+ from abc import ABC, abstractmethod
4
4
  from typing import Generator, List, Tuple
5
5
 
6
+ from rich import box
7
+ from rich.live import Live
8
+ from rich.panel import Panel
9
+ from rich.text import Text
6
10
  from yaspin import yaspin
7
11
 
8
- from jarvis.jarvis_utils.config import get_max_input_token_count, get_pretty_output
12
+ from jarvis.jarvis_utils.config import (get_max_input_token_count,
13
+ get_pretty_output, is_print_prompt)
9
14
  from jarvis.jarvis_utils.embedding import split_text_into_chunks
10
15
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
11
- from jarvis.jarvis_utils.utils import get_context_token_count, is_context_overflow, while_success, while_true
12
- from jarvis.jarvis_utils.tag import ot, ct
13
- from rich.live import Live
14
- from rich.text import Text
15
- from rich.panel import Panel
16
- from rich import box
16
+ from jarvis.jarvis_utils.tag import ct, ot
17
+ from jarvis.jarvis_utils.utils import (get_context_token_count,
18
+ is_context_overflow, while_success,
19
+ while_true)
20
+
17
21
 
18
22
  class BasePlatform(ABC):
19
23
  """Base class for large language models"""
@@ -122,6 +126,8 @@ class BasePlatform(ABC):
122
126
  return response
123
127
 
124
128
  def chat_until_success(self, message: str) -> str:
129
+ if is_print_prompt():
130
+ PrettyOutput.print(f"{message}", OutputType.USER)
125
131
  return while_true(lambda: while_success(lambda: self._chat(message), 5), 5)
126
132
 
127
133
  @abstractmethod
@@ -1,11 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
- from typing import Generator, List, Tuple
3
2
  import random
4
3
  import string
4
+ from typing import Generator, List, Tuple
5
+
5
6
  from jarvis.jarvis_platform.base import BasePlatform
6
7
  from jarvis.jarvis_utils.input import get_multiline_input
7
8
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
8
9
 
10
+
9
11
  class HumanPlatform(BasePlatform):
10
12
  """人类交互平台实现,模拟大模型但实际上与人交互"""
11
13
 
@@ -1,18 +1,21 @@
1
1
  # -*- coding: utf-8 -*-
2
- from typing import Dict, Generator, List, Tuple
3
- import requests # type: ignore
4
2
  import json
5
- import os
6
3
  import mimetypes
4
+ import os
7
5
  import time
6
+ from typing import Dict, Generator, List, Tuple
7
+
8
+ import requests # type: ignore
9
+ from rich import box
8
10
  from rich.live import Live
9
- from rich.text import Text
10
11
  from rich.panel import Panel
11
- from rich import box
12
+ from rich.text import Text
13
+
12
14
  from jarvis.jarvis_platform.base import BasePlatform
15
+ from jarvis.jarvis_utils.config import get_data_dir
13
16
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
14
17
  from jarvis.jarvis_utils.utils import while_success
15
- from jarvis.jarvis_utils.config import get_data_dir
18
+
16
19
 
17
20
  class KimiModel(BasePlatform):
18
21
  """Kimi model implementation"""
@@ -183,7 +186,7 @@ class KimiModel(BasePlatform):
183
186
  if not file_list:
184
187
  return True
185
188
 
186
- from yaspin import yaspin # type: ignore
189
+ from yaspin import yaspin # type: ignore
187
190
 
188
191
  if not self.chat_id:
189
192
  with yaspin(text="创建聊天会话...", color="yellow") as spinner:
@@ -1,10 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
- from typing import Dict, Generator, List, Tuple
3
2
  import os
3
+ from typing import Dict, Generator, List, Tuple
4
+
4
5
  from openai import OpenAI
6
+
5
7
  from jarvis.jarvis_platform.base import BasePlatform
6
8
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
9
 
10
+
8
11
  class OpenAIModel(BasePlatform):
9
12
  platform_name = "openai"
10
13
 
@@ -3,9 +3,13 @@ import importlib
3
3
  import inspect
4
4
  import os
5
5
  import sys
6
- from typing import Dict, Type, Optional, List
6
+ from typing import Dict, List, Optional, Type
7
+
7
8
  from jarvis.jarvis_platform.base import BasePlatform
8
- from jarvis.jarvis_utils.config import get_normal_model_name, get_normal_platform_name, get_thinking_model_name, get_thinking_platform_name, get_data_dir
9
+ from jarvis.jarvis_utils.config import (get_data_dir, get_normal_model_name,
10
+ get_normal_platform_name,
11
+ get_thinking_model_name,
12
+ get_thinking_platform_name)
9
13
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
10
14
 
11
15
  REQUIRED_METHODS = [
@@ -1,24 +1,27 @@
1
1
  # -*- coding: utf-8 -*-
2
- from typing import Dict, Generator, List, Tuple
3
- import requests
2
+ import hashlib
3
+ import hmac
4
4
  import json
5
5
  import os
6
- import hmac
7
- import hashlib
8
6
  import time
9
7
  import urllib.parse
8
+ from typing import Dict, Generator, List, Tuple
9
+
10
+ import requests
10
11
  from PIL import Image
11
- from yaspin import yaspin
12
- from yaspin.spinners import Spinners
13
- from yaspin.api import Yaspin
12
+ from rich import box
14
13
  from rich.live import Live
15
- from rich.text import Text
16
14
  from rich.panel import Panel
17
- from rich import box
15
+ from rich.text import Text
16
+ from yaspin import yaspin
17
+ from yaspin.api import Yaspin
18
+ from yaspin.spinners import Spinners
19
+
18
20
  from jarvis.jarvis_platform.base import BasePlatform
21
+ from jarvis.jarvis_utils.config import get_data_dir
19
22
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
20
23
  from jarvis.jarvis_utils.utils import while_success
21
- from jarvis.jarvis_utils.config import get_data_dir
24
+
22
25
 
23
26
  class YuanbaoPlatform(BasePlatform):
24
27
  """Hunyuan模型实现"""
@@ -1,18 +1,20 @@
1
1
  # -*- coding: utf-8 -*-
2
- import os
3
- from jarvis.jarvis_platform.registry import PlatformRegistry
4
2
  import asyncio
3
+ import os
4
+ from typing import Any, Dict, List, Optional
5
+
6
+ import uvicorn
5
7
  from fastapi import FastAPI, HTTPException
8
+ from fastapi.middleware.cors import CORSMiddleware
6
9
  from fastapi.responses import StreamingResponse
7
10
  from pydantic import BaseModel, Field
8
- from typing import List, Dict, Any, Optional
9
- import uvicorn
10
- from fastapi.middleware.cors import CORSMiddleware
11
11
 
12
+ from jarvis.jarvis_platform.registry import PlatformRegistry
12
13
  from jarvis.jarvis_utils.input import get_multiline_input
13
14
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
14
15
  from jarvis.jarvis_utils.utils import init_env
15
16
 
17
+
16
18
  def list_platforms():
17
19
  """List all supported platforms and models"""
18
20
  registry = PlatformRegistry.get_global_platform_registry()
@@ -248,10 +250,10 @@ class ChatCompletionResponse(BaseModel):
248
250
 
249
251
  def service_command(args):
250
252
  """Process service subcommand - start OpenAI-compatible API server"""
251
- import time
252
- import uuid
253
253
  import json
254
254
  import os
255
+ import time
256
+ import uuid
255
257
  from datetime import datetime
256
258
 
257
259
  host = args.host
@@ -451,11 +453,11 @@ def service_command(args):
451
453
 
452
454
  async def stream_chat_response(platform, message, model_name):
453
455
  """Stream chat response in OpenAI-compatible format"""
454
- import time
455
456
  import json
457
+ import os
458
+ import time
456
459
  import uuid
457
460
  from datetime import datetime
458
- import os
459
461
 
460
462
  completion_id = f"chatcmpl-{str(uuid.uuid4())}"
461
463
  created_time = int(time.time())
@@ -12,6 +12,7 @@ from jarvis.jarvis_utils.config import get_shell_name
12
12
  from jarvis.jarvis_utils.input import get_multiline_input
13
13
  from jarvis.jarvis_utils.utils import init_env
14
14
 
15
+
15
16
  def execute_command(command: str, should_run: bool) -> None:
16
17
  """Print command without execution"""
17
18
  print(command)