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