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.
- jarvis/__init__.py +1 -1
- jarvis/agent.py +47 -32
- jarvis/main.py +52 -30
- jarvis/models/__init__.py +1 -1
- jarvis/models/ai8.py +88 -58
- jarvis/models/base.py +6 -6
- jarvis/models/kimi.py +171 -80
- jarvis/models/openai.py +43 -23
- jarvis/models/oyi.py +93 -65
- jarvis/models/registry.py +63 -44
- jarvis/tools/__init__.py +1 -1
- jarvis/tools/base.py +2 -2
- jarvis/tools/file_ops.py +19 -15
- jarvis/tools/generator.py +15 -12
- jarvis/tools/methodology.py +20 -20
- jarvis/tools/registry.py +44 -30
- jarvis/tools/shell.py +12 -11
- jarvis/tools/sub_agent.py +1 -2
- jarvis/utils.py +47 -27
- {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/METADATA +1 -1
- jarvis_ai_assistant-0.1.46.dist-info/RECORD +25 -0
- jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/__pycache__/agent.cpython-313.pyc +0 -0
- jarvis/__pycache__/main.cpython-313.pyc +0 -0
- jarvis/__pycache__/models.cpython-313.pyc +0 -0
- jarvis/__pycache__/tools.cpython-313.pyc +0 -0
- jarvis/__pycache__/utils.cpython-313.pyc +0 -0
- jarvis/__pycache__/zte_llm.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/ai8.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/openai.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/oyi.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/registry.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/bing_search.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/calculator.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/calculator_tool.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/generator.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/methodology.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/python_script.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/rag.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/registry.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/user_input.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/user_interaction.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/webpage.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.44.dist-info/RECORD +0 -57
- {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/entry_points.txt +0 -0
- {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(
|
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(
|
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(
|
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(
|
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(
|
146
|
+
PrettyOutput.print(
|
147
|
+
f"更新会话设置失败: {
|
148
|
+
data.get(
|
149
|
+
'msg',
|
150
|
+
'未知错误')}",
|
151
|
+
OutputType.ERROR)
|
132
152
|
return False
|
133
153
|
else:
|
134
|
-
PrettyOutput.print(
|
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(
|
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(
|
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")
|