jarvis-ai-assistant 0.1.44__py3-none-any.whl → 0.1.46__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.
Files changed (58) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +47 -32
  3. jarvis/main.py +52 -30
  4. jarvis/models/__init__.py +1 -1
  5. jarvis/models/ai8.py +88 -58
  6. jarvis/models/base.py +6 -6
  7. jarvis/models/kimi.py +171 -80
  8. jarvis/models/openai.py +43 -23
  9. jarvis/models/oyi.py +93 -65
  10. jarvis/models/registry.py +63 -44
  11. jarvis/tools/__init__.py +1 -1
  12. jarvis/tools/base.py +2 -2
  13. jarvis/tools/file_ops.py +19 -15
  14. jarvis/tools/generator.py +15 -12
  15. jarvis/tools/methodology.py +20 -20
  16. jarvis/tools/registry.py +44 -30
  17. jarvis/tools/shell.py +12 -11
  18. jarvis/tools/sub_agent.py +1 -2
  19. jarvis/utils.py +47 -27
  20. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/METADATA +1 -1
  21. jarvis_ai_assistant-0.1.46.dist-info/RECORD +25 -0
  22. jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
  23. jarvis/__pycache__/agent.cpython-313.pyc +0 -0
  24. jarvis/__pycache__/main.cpython-313.pyc +0 -0
  25. jarvis/__pycache__/models.cpython-313.pyc +0 -0
  26. jarvis/__pycache__/tools.cpython-313.pyc +0 -0
  27. jarvis/__pycache__/utils.cpython-313.pyc +0 -0
  28. jarvis/__pycache__/zte_llm.cpython-313.pyc +0 -0
  29. jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
  30. jarvis/models/__pycache__/ai8.cpython-313.pyc +0 -0
  31. jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
  32. jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
  33. jarvis/models/__pycache__/openai.cpython-313.pyc +0 -0
  34. jarvis/models/__pycache__/oyi.cpython-313.pyc +0 -0
  35. jarvis/models/__pycache__/registry.cpython-313.pyc +0 -0
  36. jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  37. jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
  38. jarvis/tools/__pycache__/bing_search.cpython-313.pyc +0 -0
  39. jarvis/tools/__pycache__/calculator.cpython-313.pyc +0 -0
  40. jarvis/tools/__pycache__/calculator_tool.cpython-313.pyc +0 -0
  41. jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
  42. jarvis/tools/__pycache__/generator.cpython-313.pyc +0 -0
  43. jarvis/tools/__pycache__/methodology.cpython-313.pyc +0 -0
  44. jarvis/tools/__pycache__/python_script.cpython-313.pyc +0 -0
  45. jarvis/tools/__pycache__/rag.cpython-313.pyc +0 -0
  46. jarvis/tools/__pycache__/registry.cpython-313.pyc +0 -0
  47. jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
  48. jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
  49. jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
  50. jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc +0 -0
  51. jarvis/tools/__pycache__/user_input.cpython-313.pyc +0 -0
  52. jarvis/tools/__pycache__/user_interaction.cpython-313.pyc +0 -0
  53. jarvis/tools/__pycache__/webpage.cpython-313.pyc +0 -0
  54. jarvis_ai_assistant-0.1.44.dist-info/RECORD +0 -57
  55. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/LICENSE +0 -0
  56. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/WHEEL +0 -0
  57. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/entry_points.txt +0 -0
  58. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/top_level.txt +0 -0
jarvis/models/ai8.py CHANGED
@@ -6,12 +6,13 @@ import requests
6
6
  import json
7
7
  import base64
8
8
 
9
+
9
10
  class AI8Model(BasePlatform):
10
11
  """AI8 model implementation"""
11
-
12
+
12
13
  platform_name = "ai8"
13
14
  BASE_URL = "https://ai8.rcouyi.com"
14
-
15
+
15
16
  def __init__(self):
16
17
  """Initialize model"""
17
18
  self.system_message = ""
@@ -21,23 +22,23 @@ class AI8Model(BasePlatform):
21
22
 
22
23
  # 获取可用模型列表
23
24
  available_models = self.get_available_models()
24
-
25
+
25
26
  if available_models:
26
27
  PrettyOutput.section("支持的模型", OutputType.SUCCESS)
27
28
  for model in self.models.values():
28
29
  # 格式化显示模型信息
29
30
  model_str = f"{model['value']:<30}"
30
-
31
+
31
32
  # 添加标签
32
33
  model_str += f"{model['label']}"
33
-
34
+
34
35
  # 添加标签和积分信息
35
36
  attrs = []
36
37
  if model['attr'].get('tag'):
37
38
  attrs.append(model['attr']['tag'])
38
39
  if model['attr'].get('integral'):
39
40
  attrs.append(model['attr']['integral'])
40
-
41
+
41
42
  # 添加特性标记
42
43
  features = []
43
44
  if model['attr'].get('multimodal'):
@@ -48,11 +49,11 @@ class AI8Model(BasePlatform):
48
49
  features.append("图像支持")
49
50
  if features:
50
51
  model_str += f" [{'|'.join(features)}]"
51
-
52
+
52
53
  # 添加备注
53
54
  if model['attr'].get('note'):
54
55
  model_str += f" - {model['attr']['note']}"
55
-
56
+
56
57
  PrettyOutput.print(model_str, OutputType.INFO)
57
58
  else:
58
59
  PrettyOutput.print("获取模型列表失败", OutputType.WARNING)
@@ -60,19 +61,22 @@ class AI8Model(BasePlatform):
60
61
  self.token = os.getenv("AI8_API_KEY")
61
62
  if not self.token:
62
63
  raise Exception("AI8_API_KEY is not set")
63
-
64
+
64
65
  PrettyOutput.print("使用AI8_MODEL环境变量配置模型", OutputType.SUCCESS)
65
-
66
+
66
67
  self.model_name = os.getenv("AI8_MODEL") or "deepseek-chat"
67
68
  if self.model_name not in self.models:
68
- PrettyOutput.print(f"警告: 当前选择的模型 {self.model_name} 不在可用列表中", OutputType.WARNING)
69
-
69
+ PrettyOutput.print(
70
+ f"警告: 当前选择的模型 {
71
+ self.model_name} 不在可用列表中",
72
+ OutputType.WARNING)
73
+
70
74
  PrettyOutput.print(f"当前使用模型: {self.model_name}", OutputType.SYSTEM)
71
75
 
72
76
  def set_model_name(self, model_name: str):
73
77
  """设置模型名称"""
74
78
  self.model_name = model_name
75
-
79
+
76
80
  def create_conversation(self) -> bool:
77
81
  """Create a new conversation"""
78
82
  try:
@@ -85,25 +89,36 @@ class AI8Model(BasePlatform):
85
89
  'Origin': self.BASE_URL,
86
90
  'Referer': f'{self.BASE_URL}/chat?_userMenuKey=chat'
87
91
  }
88
-
92
+
89
93
  # 1. 创建会话
90
94
  response = requests.post(
91
95
  f"{self.BASE_URL}/api/chat/session",
92
96
  headers=headers
93
97
  )
94
-
98
+
95
99
  if response.status_code != 200:
96
- PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.ERROR)
100
+ PrettyOutput.print(
101
+ f"创建会话失败: {
102
+ response.status_code}",
103
+ OutputType.ERROR)
97
104
  return False
98
-
105
+
99
106
  data = response.json()
100
107
  if data['code'] != 0:
101
- PrettyOutput.print(f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
108
+ PrettyOutput.print(
109
+ f"创建会话失败: {
110
+ data.get(
111
+ 'msg',
112
+ '未知错误')}",
113
+ OutputType.ERROR)
102
114
  return False
103
-
115
+
104
116
  self.conversation = data['data']
105
- PrettyOutput.print(f"创建会话成功: {data['data']['id']}", OutputType.SUCCESS)
106
-
117
+ PrettyOutput.print(
118
+ f"创建会话成功: {
119
+ data['data']['id']}",
120
+ OutputType.SUCCESS)
121
+
107
122
  # 2. 更新会话设置
108
123
  session_data = {
109
124
  **self.conversation,
@@ -114,13 +129,13 @@ class AI8Model(BasePlatform):
114
129
  "localPlugins": None,
115
130
  "useAppId": 0
116
131
  }
117
-
132
+
118
133
  response = requests.put(
119
134
  f"{self.BASE_URL}/api/chat/session/{self.conversation['id']}",
120
135
  headers=headers,
121
136
  json=session_data
122
137
  )
123
-
138
+
124
139
  if response.status_code == 200:
125
140
  data = response.json()
126
141
  if data['code'] == 0:
@@ -128,16 +143,24 @@ class AI8Model(BasePlatform):
128
143
  PrettyOutput.print("会话设置更新成功", OutputType.SUCCESS)
129
144
  return True
130
145
  else:
131
- PrettyOutput.print(f"更新会话设置失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
146
+ PrettyOutput.print(
147
+ f"更新会话设置失败: {
148
+ data.get(
149
+ 'msg',
150
+ '未知错误')}",
151
+ OutputType.ERROR)
132
152
  return False
133
153
  else:
134
- PrettyOutput.print(f"更新会话设置失败: {response.status_code}", OutputType.ERROR)
154
+ PrettyOutput.print(
155
+ f"更新会话设置失败: {
156
+ response.status_code}",
157
+ OutputType.ERROR)
135
158
  return False
136
-
159
+
137
160
  except Exception as e:
138
161
  PrettyOutput.print(f"创建会话异常: {str(e)}", OutputType.ERROR)
139
162
  return False
140
-
163
+
141
164
  def upload_files(self, file_list: List[str]) -> List[Dict]:
142
165
  for file_path in file_list:
143
166
  name = os.path.basename(file_path)
@@ -149,17 +172,17 @@ class AI8Model(BasePlatform):
149
172
  "data": f"data:image/png;base64,{base64_data}"
150
173
  })
151
174
  PrettyOutput.print(f"文件 {name} 已准备好发送", OutputType.SUCCESS)
152
-
175
+
153
176
  def set_system_message(self, message: str):
154
177
  """Set system message"""
155
178
  self.system_message = message
156
-
179
+
157
180
  def chat(self, message: str) -> str:
158
181
  """Execute chat with the model
159
-
182
+
160
183
  Args:
161
184
  message: User input message
162
-
185
+
163
186
  Returns:
164
187
  str: Model response
165
188
  """
@@ -168,7 +191,7 @@ class AI8Model(BasePlatform):
168
191
  if not self.conversation:
169
192
  if not self.create_conversation():
170
193
  raise Exception("Failed to create conversation")
171
-
194
+
172
195
  headers = {
173
196
  'Authorization': self.token,
174
197
  'Content-Type': 'application/json',
@@ -178,13 +201,13 @@ class AI8Model(BasePlatform):
178
201
  'Origin': self.BASE_URL,
179
202
  'Referer': f'{self.BASE_URL}/chat?_userMenuKey=chat'
180
203
  }
181
-
204
+
182
205
  payload = {
183
206
  "text": message,
184
207
  "sessionId": self.conversation['id'],
185
208
  "files": []
186
209
  }
187
-
210
+
188
211
  # 如果有文件需要发送
189
212
  if self.files:
190
213
  for file_data in self.files:
@@ -193,19 +216,19 @@ class AI8Model(BasePlatform):
193
216
  "data": file_data["data"]
194
217
  })
195
218
  self.files = [] # 清空已使用的文件
196
-
219
+
197
220
  response = requests.post(
198
221
  f"{self.BASE_URL}/api/chat/completions",
199
222
  headers=headers,
200
223
  json=payload,
201
224
  stream=True
202
225
  )
203
-
226
+
204
227
  if response.status_code != 200:
205
228
  error_msg = f"聊天请求失败: {response.status_code}"
206
229
  PrettyOutput.print(error_msg, OutputType.ERROR)
207
230
  raise Exception(error_msg)
208
-
231
+
209
232
  # 处理流式响应
210
233
  full_response = ""
211
234
  for line in response.iter_lines():
@@ -222,30 +245,30 @@ class AI8Model(BasePlatform):
222
245
 
223
246
  except json.JSONDecodeError:
224
247
  continue
225
-
248
+
226
249
  PrettyOutput.print_stream_end()
227
250
 
228
251
  return full_response
229
-
252
+
230
253
  except Exception as e:
231
254
  PrettyOutput.print(f"聊天异常: {str(e)}", OutputType.ERROR)
232
255
  raise e
233
-
256
+
234
257
  def name(self) -> str:
235
258
  """Return model name"""
236
259
  return self.model_name
237
-
260
+
238
261
  def reset(self):
239
262
  """Reset model state"""
240
263
  self.conversation = None
241
264
  self.files = [] # 清空文件列表
242
-
265
+
243
266
  def delete_chat(self) -> bool:
244
267
  """Delete current chat session"""
245
268
  try:
246
269
  if not self.conversation:
247
270
  return True
248
-
271
+
249
272
  headers = {
250
273
  'Authorization': self.token,
251
274
  'Content-Type': 'application/json',
@@ -255,12 +278,12 @@ class AI8Model(BasePlatform):
255
278
  'Origin': self.BASE_URL,
256
279
  'Referer': f'{self.BASE_URL}/chat?_userMenuKey=chat'
257
280
  }
258
-
281
+
259
282
  response = requests.delete(
260
283
  f"{self.BASE_URL}/api/chat/session/{self.conversation['id']}",
261
284
  headers=headers
262
285
  )
263
-
286
+
264
287
  if response.status_code == 200:
265
288
  data = response.json()
266
289
  if data['code'] == 0:
@@ -275,14 +298,14 @@ class AI8Model(BasePlatform):
275
298
  error_msg = f"删除会话请求失败: {response.status_code}"
276
299
  PrettyOutput.print(error_msg, OutputType.ERROR)
277
300
  return False
278
-
301
+
279
302
  except Exception as e:
280
303
  PrettyOutput.print(f"删除会话异常: {str(e)}", OutputType.ERROR)
281
304
  return False
282
-
305
+
283
306
  def get_available_models(self) -> List[str]:
284
307
  """获取可用的模型列表
285
-
308
+
286
309
  Returns:
287
310
  List[str]: 可用模型名称列表
288
311
  """
@@ -295,30 +318,37 @@ class AI8Model(BasePlatform):
295
318
  'Origin': self.BASE_URL,
296
319
  'Referer': f'{self.BASE_URL}/chat?_userMenuKey=chat'
297
320
  }
298
-
321
+
299
322
  response = requests.get(
300
323
  f"{self.BASE_URL}/api/chat/template",
301
324
  headers=headers
302
325
  )
303
-
326
+
304
327
  if response.status_code != 200:
305
- PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.ERROR)
328
+ PrettyOutput.print(
329
+ f"获取模型列表失败: {
330
+ response.status_code}",
331
+ OutputType.ERROR)
306
332
  return []
307
-
333
+
308
334
  data = response.json()
309
335
  if data['code'] != 0:
310
- PrettyOutput.print(f"获取模型列表失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
336
+ PrettyOutput.print(
337
+ f"获取模型列表失败: {
338
+ data.get(
339
+ 'msg',
340
+ '未知错误')}",
341
+ OutputType.ERROR)
311
342
  return []
312
-
343
+
313
344
  # 保存模型信息
314
345
  self.models = {
315
- model['value']: model
346
+ model['value']: model
316
347
  for model in data['data']['models']
317
348
  }
318
-
349
+
319
350
  return list(self.models.keys())
320
-
351
+
321
352
  except Exception as e:
322
353
  PrettyOutput.print(f"获取模型列表异常: {str(e)}", OutputType.ERROR)
323
354
  return []
324
-
jarvis/models/base.py CHANGED
@@ -4,7 +4,7 @@ from typing import Dict, List
4
4
 
5
5
  class BasePlatform(ABC):
6
6
  """大语言模型基类"""
7
-
7
+
8
8
  def __init__(self):
9
9
  """初始化模型"""
10
10
  pass
@@ -12,7 +12,7 @@ class BasePlatform(ABC):
12
12
  def set_model_name(self, model_name: str):
13
13
  """设置模型名称"""
14
14
  raise NotImplementedError("set_model_name is not implemented")
15
-
15
+
16
16
  @abstractmethod
17
17
  def chat(self, message: str) -> str:
18
18
  """执行对话"""
@@ -25,17 +25,17 @@ class BasePlatform(ABC):
25
25
  def reset(self):
26
26
  """重置模型"""
27
27
  raise NotImplementedError("reset is not implemented")
28
-
28
+
29
29
  @abstractmethod
30
30
  def name(self) -> str:
31
31
  """模型名称"""
32
32
  raise NotImplementedError("name is not implemented")
33
-
33
+
34
34
  @abstractmethod
35
- def delete_chat(self)->bool:
35
+ def delete_chat(self) -> bool:
36
36
  """删除对话"""
37
37
  raise NotImplementedError("delete_chat is not implemented")
38
-
38
+
39
39
  def set_system_message(self, message: str):
40
40
  """设置系统消息"""
41
41
  raise NotImplementedError("set_system_message is not implemented")