jarvis-ai-assistant 0.1.111__py3-none-any.whl → 0.1.113__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.
- jarvis/__init__.py +1 -1
- jarvis/agent.py +72 -41
- jarvis/jarvis_code_agent/code_agent.py +23 -5
- jarvis/jarvis_code_agent/file_select.py +16 -16
- jarvis/jarvis_code_agent/patch.py +17 -11
- jarvis/jarvis_code_agent/relevant_files.py +33 -40
- jarvis/jarvis_codebase/main.py +57 -48
- jarvis/jarvis_lsp/cpp.py +1 -1
- jarvis/jarvis_lsp/go.py +1 -1
- jarvis/jarvis_lsp/python.py +0 -2
- jarvis/jarvis_lsp/registry.py +13 -13
- jarvis/jarvis_lsp/rust.py +1 -1
- jarvis/jarvis_platform/ai8.py +14 -14
- jarvis/jarvis_platform/base.py +1 -1
- jarvis/jarvis_platform/kimi.py +17 -17
- jarvis/jarvis_platform/ollama.py +14 -14
- jarvis/jarvis_platform/openai.py +8 -8
- jarvis/jarvis_platform/oyi.py +19 -19
- jarvis/jarvis_platform/registry.py +6 -6
- jarvis/jarvis_platform_manager/main.py +17 -17
- jarvis/jarvis_rag/main.py +25 -25
- jarvis/jarvis_smart_shell/main.py +6 -6
- jarvis/jarvis_tools/ask_codebase.py +3 -3
- jarvis/jarvis_tools/ask_user.py +2 -2
- jarvis/jarvis_tools/create_code_agent.py +8 -8
- jarvis/jarvis_tools/create_sub_agent.py +2 -2
- jarvis/jarvis_tools/execute_shell.py +2 -2
- jarvis/jarvis_tools/file_operation.py +1 -1
- jarvis/jarvis_tools/git_commiter.py +8 -5
- jarvis/jarvis_tools/methodology.py +3 -3
- jarvis/jarvis_tools/rag.py +3 -3
- jarvis/jarvis_tools/read_code.py +1 -1
- jarvis/jarvis_tools/read_webpage.py +19 -6
- jarvis/jarvis_tools/registry.py +11 -11
- jarvis/jarvis_tools/search.py +88 -27
- jarvis/jarvis_tools/select_code_files.py +1 -1
- jarvis/jarvis_tools/tool_generator.py +182 -0
- jarvis/utils.py +69 -28
- jarvis_ai_assistant-0.1.113.dist-info/METADATA +460 -0
- jarvis_ai_assistant-0.1.113.dist-info/RECORD +64 -0
- jarvis_ai_assistant-0.1.111.dist-info/METADATA +0 -461
- jarvis_ai_assistant-0.1.111.dist-info/RECORD +0 -63
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/top_level.txt +0 -0
jarvis/jarvis_platform/ai8.py
CHANGED
|
@@ -27,12 +27,12 @@ class AI8Model(BasePlatform):
|
|
|
27
27
|
|
|
28
28
|
self.token = os.getenv("AI8_API_KEY")
|
|
29
29
|
if not self.token:
|
|
30
|
-
PrettyOutput.print("AI8_API_KEY
|
|
30
|
+
PrettyOutput.print("未设置 AI8_API_KEY", OutputType.WARNING)
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-chat"
|
|
34
34
|
if self.model_name not in self.get_available_models():
|
|
35
|
-
PrettyOutput.print(f"
|
|
35
|
+
PrettyOutput.print(f"警告: 选择的模型 {self.model_name} 不在可用列表中", OutputType.WARNING)
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def set_model_name(self, model_name: str):
|
|
@@ -60,12 +60,12 @@ class AI8Model(BasePlatform):
|
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
if response.status_code != 200:
|
|
63
|
-
PrettyOutput.print(f"
|
|
63
|
+
PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.ERROR)
|
|
64
64
|
return False
|
|
65
65
|
|
|
66
66
|
data = response.json()
|
|
67
67
|
if data['code'] != 0:
|
|
68
|
-
PrettyOutput.print(f"
|
|
68
|
+
PrettyOutput.print(f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
|
|
69
69
|
return False
|
|
70
70
|
|
|
71
71
|
self.conversation = data['data']
|
|
@@ -93,14 +93,14 @@ class AI8Model(BasePlatform):
|
|
|
93
93
|
self.conversation = data['data']
|
|
94
94
|
return True
|
|
95
95
|
else:
|
|
96
|
-
PrettyOutput.print(f"
|
|
96
|
+
PrettyOutput.print(f"更新会话设置失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
|
|
97
97
|
return False
|
|
98
98
|
else:
|
|
99
|
-
PrettyOutput.print(f"
|
|
99
|
+
PrettyOutput.print(f"更新会话设置失败: {response.status_code}", OutputType.ERROR)
|
|
100
100
|
return False
|
|
101
101
|
|
|
102
102
|
except Exception as e:
|
|
103
|
-
PrettyOutput.print(f"
|
|
103
|
+
PrettyOutput.print(f"创建会话失败: {str(e)}", OutputType.ERROR)
|
|
104
104
|
return False
|
|
105
105
|
|
|
106
106
|
def upload_files(self, file_list: List[str]) -> List[Dict]:
|
|
@@ -189,7 +189,7 @@ class AI8Model(BasePlatform):
|
|
|
189
189
|
return full_response
|
|
190
190
|
|
|
191
191
|
except Exception as e:
|
|
192
|
-
PrettyOutput.print(f"
|
|
192
|
+
PrettyOutput.print(f"对话异常: {str(e)}", OutputType.ERROR)
|
|
193
193
|
raise e
|
|
194
194
|
|
|
195
195
|
def name(self) -> str:
|
|
@@ -228,16 +228,16 @@ class AI8Model(BasePlatform):
|
|
|
228
228
|
self.reset()
|
|
229
229
|
return True
|
|
230
230
|
else:
|
|
231
|
-
error_msg = f"
|
|
231
|
+
error_msg = f"删除会话失败: {data.get('msg', '未知错误')}"
|
|
232
232
|
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
233
233
|
return False
|
|
234
234
|
else:
|
|
235
|
-
error_msg = f"
|
|
235
|
+
error_msg = f"删除会话请求失败: {response.status_code}"
|
|
236
236
|
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
237
237
|
return False
|
|
238
238
|
|
|
239
239
|
except Exception as e:
|
|
240
|
-
PrettyOutput.print(f"
|
|
240
|
+
PrettyOutput.print(f"删除会话失败: {str(e)}", OutputType.ERROR)
|
|
241
241
|
return False
|
|
242
242
|
|
|
243
243
|
def get_available_models(self) -> List[str]:
|
|
@@ -265,12 +265,12 @@ class AI8Model(BasePlatform):
|
|
|
265
265
|
)
|
|
266
266
|
|
|
267
267
|
if response.status_code != 200:
|
|
268
|
-
PrettyOutput.print(f"
|
|
268
|
+
PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.ERROR)
|
|
269
269
|
return []
|
|
270
270
|
|
|
271
271
|
data = response.json()
|
|
272
272
|
if data['code'] != 0:
|
|
273
|
-
PrettyOutput.print(f"
|
|
273
|
+
PrettyOutput.print(f"获取模型列表失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
|
|
274
274
|
return []
|
|
275
275
|
|
|
276
276
|
# 保存模型信息
|
|
@@ -309,6 +309,6 @@ class AI8Model(BasePlatform):
|
|
|
309
309
|
return list(self.models.keys())
|
|
310
310
|
|
|
311
311
|
except Exception as e:
|
|
312
|
-
PrettyOutput.print(f"
|
|
312
|
+
PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.WARNING)
|
|
313
313
|
return []
|
|
314
314
|
|
jarvis/jarvis_platform/base.py
CHANGED
jarvis/jarvis_platform/kimi.py
CHANGED
|
@@ -26,24 +26,24 @@ class KimiModel(BasePlatform):
|
|
|
26
26
|
self.api_key = os.getenv("KIMI_API_KEY")
|
|
27
27
|
if not self.api_key:
|
|
28
28
|
message = (
|
|
29
|
-
"
|
|
30
|
-
"1.
|
|
31
|
-
" •
|
|
32
|
-
" •
|
|
33
|
-
" •
|
|
34
|
-
" •
|
|
35
|
-
" •
|
|
36
|
-
" •
|
|
37
|
-
" •
|
|
38
|
-
"2.
|
|
39
|
-
" •
|
|
29
|
+
"需要设置 KIMI_API_KEY 才能使用 Jarvis。请按照以下步骤操作:\n"
|
|
30
|
+
"1. 获取 Kimi API Key:\n"
|
|
31
|
+
" • 访问 Kimi AI 平台: https://kimi.moonshot.cn\n"
|
|
32
|
+
" • 登录您的账户\n"
|
|
33
|
+
" • 打开浏览器开发者工具 (F12 或右键 -> 检查)\n"
|
|
34
|
+
" • 切换到网络标签\n"
|
|
35
|
+
" • 发送任意消息\n"
|
|
36
|
+
" • 在请求中找到 Authorization 头\n"
|
|
37
|
+
" • 复制 token 值(去掉 'Bearer ' 前缀)\n"
|
|
38
|
+
"2. 设置环境变量:\n"
|
|
39
|
+
" • 方法 1: 创建或编辑 ~/.jarvis/env 文件:\n"
|
|
40
40
|
" echo 'KIMI_API_KEY=your_key_here' > ~/.jarvis/env\n"
|
|
41
|
-
" •
|
|
41
|
+
" • 方法 2: 直接设置环境变量:\n"
|
|
42
42
|
" export KIMI_API_KEY=your_key_here\n"
|
|
43
|
-
"
|
|
43
|
+
"设置后,重新运行 Jarvis。"
|
|
44
44
|
)
|
|
45
45
|
PrettyOutput.print(message, OutputType.INFO)
|
|
46
|
-
PrettyOutput.print("KIMI_API_KEY
|
|
46
|
+
PrettyOutput.print("KIMI_API_KEY 未设置", OutputType.WARNING)
|
|
47
47
|
self.auth_header = f"Bearer {self.api_key}"
|
|
48
48
|
self.chat_id = ""
|
|
49
49
|
self.uploaded_files = [] # 存储已上传文件的信息
|
|
@@ -75,7 +75,7 @@ class KimiModel(BasePlatform):
|
|
|
75
75
|
self.chat_id = response.json()["id"]
|
|
76
76
|
return True
|
|
77
77
|
except Exception as e:
|
|
78
|
-
PrettyOutput.print(f"
|
|
78
|
+
PrettyOutput.print(f"错误:创建会话失败:{e}", OutputType.ERROR)
|
|
79
79
|
return False
|
|
80
80
|
|
|
81
81
|
def _get_presigned_url(self, filename: str, action: str) -> Dict:
|
|
@@ -105,7 +105,7 @@ class KimiModel(BasePlatform):
|
|
|
105
105
|
response = while_success(lambda: requests.put(presigned_url, data=content), sleep_time=5)
|
|
106
106
|
return response.status_code == 200
|
|
107
107
|
except Exception as e:
|
|
108
|
-
PrettyOutput.print(f"
|
|
108
|
+
PrettyOutput.print(f"错误:上传文件失败:{e}", OutputType.ERROR)
|
|
109
109
|
return False
|
|
110
110
|
|
|
111
111
|
def _get_file_info(self, file_data: Dict, name: str, file_type: str) -> Dict:
|
|
@@ -202,7 +202,7 @@ class KimiModel(BasePlatform):
|
|
|
202
202
|
else:
|
|
203
203
|
uploaded_files.append(file_info)
|
|
204
204
|
else:
|
|
205
|
-
PrettyOutput.print(f"
|
|
205
|
+
PrettyOutput.print(f"错误:文件上传失败: {file_path}", OutputType.ERROR)
|
|
206
206
|
|
|
207
207
|
except Exception as e:
|
|
208
208
|
PrettyOutput.print(f"✗ 处理文件出错 {file_path}: {str(e)}", OutputType.ERROR)
|
jarvis/jarvis_platform/ollama.py
CHANGED
|
@@ -26,21 +26,21 @@ class OllamaPlatform(BasePlatform):
|
|
|
26
26
|
|
|
27
27
|
if not available_models:
|
|
28
28
|
message = (
|
|
29
|
-
"
|
|
30
|
-
"1.
|
|
31
|
-
"2.
|
|
29
|
+
"需要先下载 Ollama 模型才能使用:\n"
|
|
30
|
+
"1. 安装 Ollama: https://ollama.ai\n"
|
|
31
|
+
"2. 下载模型:\n"
|
|
32
32
|
f" ollama pull {self.model_name}"
|
|
33
33
|
)
|
|
34
34
|
PrettyOutput.print(message, OutputType.INFO)
|
|
35
|
-
PrettyOutput.print("Ollama
|
|
35
|
+
PrettyOutput.print("Ollama 没有可用的模型", OutputType.WARNING)
|
|
36
36
|
|
|
37
37
|
except requests.exceptions.ConnectionError:
|
|
38
38
|
message = (
|
|
39
|
-
"Ollama
|
|
40
|
-
"
|
|
41
|
-
"1.
|
|
42
|
-
"2.
|
|
43
|
-
"3.
|
|
39
|
+
"Ollama 服务未启动或无法连接\n"
|
|
40
|
+
"请确保您已:\n"
|
|
41
|
+
"1. 安装 Ollama: https://ollama.ai\n"
|
|
42
|
+
"2. 启动 Ollama 服务\n"
|
|
43
|
+
"3. 正确配置服务地址 (默认: http://localhost:11434)"
|
|
44
44
|
)
|
|
45
45
|
PrettyOutput.print(message, OutputType.WARNING)
|
|
46
46
|
|
|
@@ -108,12 +108,12 @@ class OllamaPlatform(BasePlatform):
|
|
|
108
108
|
return full_response
|
|
109
109
|
|
|
110
110
|
except Exception as e:
|
|
111
|
-
PrettyOutput.print(f"
|
|
111
|
+
PrettyOutput.print(f"对话失败: {str(e)}", OutputType.ERROR)
|
|
112
112
|
raise Exception(f"Chat failed: {str(e)}")
|
|
113
113
|
|
|
114
114
|
def upload_files(self, file_list: List[str]) -> List[Dict]:
|
|
115
115
|
"""Upload files (Ollama does not support file upload)"""
|
|
116
|
-
PrettyOutput.print("Ollama
|
|
116
|
+
PrettyOutput.print("Ollama 不支持文件上传", output_type=OutputType.WARNING)
|
|
117
117
|
return []
|
|
118
118
|
|
|
119
119
|
def reset(self):
|
|
@@ -142,10 +142,10 @@ if __name__ == "__main__":
|
|
|
142
142
|
ollama = OllamaPlatform()
|
|
143
143
|
while True:
|
|
144
144
|
try:
|
|
145
|
-
message = get_single_line_input("
|
|
145
|
+
message = get_single_line_input("输入问题 (Ctrl+C 退出)")
|
|
146
146
|
ollama.chat_until_success(message)
|
|
147
147
|
except KeyboardInterrupt:
|
|
148
|
-
print("
|
|
148
|
+
print("再见!")
|
|
149
149
|
break
|
|
150
150
|
except Exception as e:
|
|
151
|
-
PrettyOutput.print(f"
|
|
151
|
+
PrettyOutput.print(f"程序异常退出: {str(e)}", OutputType.ERROR)
|
jarvis/jarvis_platform/openai.py
CHANGED
|
@@ -20,21 +20,21 @@ class OpenAIModel(BasePlatform):
|
|
|
20
20
|
self.api_key = os.getenv("OPENAI_API_KEY")
|
|
21
21
|
if not self.api_key:
|
|
22
22
|
message = (
|
|
23
|
-
"
|
|
24
|
-
" • OPENAI_API_KEY: API
|
|
25
|
-
" • OPENAI_API_BASE: (
|
|
26
|
-
"
|
|
27
|
-
"1.
|
|
23
|
+
"需要设置以下环境变量才能使用 OpenAI 模型:\n"
|
|
24
|
+
" • OPENAI_API_KEY: API 密钥\n"
|
|
25
|
+
" • OPENAI_API_BASE: (可选) API 基础地址, 默认使用 https://api.openai.com/v1\n"
|
|
26
|
+
"您可以通过以下方式设置它们:\n"
|
|
27
|
+
"1. 创建或编辑 ~/.jarvis/env 文件:\n"
|
|
28
28
|
" OPENAI_API_KEY=your_api_key\n"
|
|
29
29
|
" OPENAI_API_BASE=your_api_base\n"
|
|
30
30
|
" OPENAI_MODEL_NAME=your_model_name\n"
|
|
31
|
-
"2.
|
|
31
|
+
"2. 直接设置环境变量:\n"
|
|
32
32
|
" export OPENAI_API_KEY=your_api_key\n"
|
|
33
33
|
" export OPENAI_API_BASE=your_api_base\n"
|
|
34
34
|
" export OPENAI_MODEL_NAME=your_model_name"
|
|
35
35
|
)
|
|
36
36
|
PrettyOutput.print(message, OutputType.INFO)
|
|
37
|
-
PrettyOutput.print("OPENAI_API_KEY
|
|
37
|
+
PrettyOutput.print("OPENAI_API_KEY 未设置", OutputType.WARNING)
|
|
38
38
|
|
|
39
39
|
self.base_url = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1")
|
|
40
40
|
self.model_name = os.getenv("JARVIS_MODEL") or "gpt-4o"
|
|
@@ -92,7 +92,7 @@ class OpenAIModel(BasePlatform):
|
|
|
92
92
|
return full_response
|
|
93
93
|
|
|
94
94
|
except Exception as e:
|
|
95
|
-
PrettyOutput.print(f"
|
|
95
|
+
PrettyOutput.print(f"对话失败:{str(e)}", OutputType.ERROR)
|
|
96
96
|
raise Exception(f"Chat failed: {str(e)}")
|
|
97
97
|
|
|
98
98
|
def name(self) -> str:
|
jarvis/jarvis_platform/oyi.py
CHANGED
|
@@ -29,11 +29,11 @@ class OyiModel(BasePlatform):
|
|
|
29
29
|
|
|
30
30
|
self.token = os.getenv("OYI_API_KEY")
|
|
31
31
|
if not self.token:
|
|
32
|
-
PrettyOutput.print("OYI_API_KEY
|
|
32
|
+
PrettyOutput.print("OYI_API_KEY 未设置", OutputType.WARNING)
|
|
33
33
|
|
|
34
34
|
self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-chat"
|
|
35
35
|
if self.model_name not in [m.split()[0] for m in self.get_available_models()]:
|
|
36
|
-
PrettyOutput.print(f"
|
|
36
|
+
PrettyOutput.print(f"警告: 选择的模型 {self.model_name} 不在可用列表中", OutputType.WARNING)
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def set_model_name(self, model_name: str):
|
|
@@ -83,14 +83,14 @@ class OyiModel(BasePlatform):
|
|
|
83
83
|
self.conversation = data
|
|
84
84
|
return True
|
|
85
85
|
else:
|
|
86
|
-
PrettyOutput.print(f"
|
|
86
|
+
PrettyOutput.print(f"创建会话失败: {data['message']}", OutputType.ERROR)
|
|
87
87
|
return False
|
|
88
88
|
else:
|
|
89
|
-
PrettyOutput.print(f"
|
|
89
|
+
PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.ERROR)
|
|
90
90
|
return False
|
|
91
91
|
|
|
92
92
|
except Exception as e:
|
|
93
|
-
PrettyOutput.print(f"
|
|
93
|
+
PrettyOutput.print(f"创建会话失败: {str(e)}", OutputType.ERROR)
|
|
94
94
|
return False
|
|
95
95
|
|
|
96
96
|
def set_system_message(self, message: str):
|
|
@@ -156,13 +156,13 @@ class OyiModel(BasePlatform):
|
|
|
156
156
|
)
|
|
157
157
|
|
|
158
158
|
if response.status_code != 200:
|
|
159
|
-
error_msg = f"
|
|
159
|
+
error_msg = f"聊天请求失败: {response.status_code}"
|
|
160
160
|
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
161
161
|
raise Exception(error_msg)
|
|
162
162
|
|
|
163
163
|
data = response.json()
|
|
164
164
|
if data['code'] != 200 or data['type'] != 'success':
|
|
165
|
-
error_msg = f"
|
|
165
|
+
error_msg = f"聊天失败: {data.get('message', '未知错误')}"
|
|
166
166
|
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
167
167
|
raise Exception(error_msg)
|
|
168
168
|
|
|
@@ -195,11 +195,11 @@ class OyiModel(BasePlatform):
|
|
|
195
195
|
self.messages.append({"role": "assistant", "content": full_response})
|
|
196
196
|
return full_response
|
|
197
197
|
else:
|
|
198
|
-
error_msg = f"
|
|
198
|
+
error_msg = f"获取响应失败: {response.status_code}"
|
|
199
199
|
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
200
200
|
raise Exception(error_msg)
|
|
201
201
|
except Exception as e:
|
|
202
|
-
PrettyOutput.print(f"
|
|
202
|
+
PrettyOutput.print(f"聊天失败: {str(e)}", OutputType.ERROR)
|
|
203
203
|
raise e
|
|
204
204
|
|
|
205
205
|
def name(self) -> str:
|
|
@@ -240,16 +240,16 @@ class OyiModel(BasePlatform):
|
|
|
240
240
|
self.reset()
|
|
241
241
|
return True
|
|
242
242
|
else:
|
|
243
|
-
error_msg = f"
|
|
243
|
+
error_msg = f"删除会话失败: {data.get('message', '未知错误')}"
|
|
244
244
|
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
245
245
|
return False
|
|
246
246
|
else:
|
|
247
|
-
error_msg = f"
|
|
247
|
+
error_msg = f"删除会话请求失败: {response.status_code}"
|
|
248
248
|
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
249
249
|
return False
|
|
250
250
|
|
|
251
251
|
except Exception as e:
|
|
252
|
-
PrettyOutput.print(f"
|
|
252
|
+
PrettyOutput.print(f"删除会话失败: {str(e)}", OutputType.ERROR)
|
|
253
253
|
return False
|
|
254
254
|
|
|
255
255
|
def upload_files(self, file_list: List[str]) -> List[Dict]:
|
|
@@ -265,7 +265,7 @@ class OyiModel(BasePlatform):
|
|
|
265
265
|
# 检查当前模型是否支持文件上传
|
|
266
266
|
model_info = self.models.get(self.model_name)
|
|
267
267
|
if not model_info or not model_info.get('uploadFile', False):
|
|
268
|
-
PrettyOutput.print(f"
|
|
268
|
+
PrettyOutput.print(f"当前模型 {self.model_name} 不支持文件上传", OutputType.WARNING)
|
|
269
269
|
return []
|
|
270
270
|
|
|
271
271
|
headers = {
|
|
@@ -281,7 +281,7 @@ class OyiModel(BasePlatform):
|
|
|
281
281
|
# 检查文件类型
|
|
282
282
|
file_type = mimetypes.guess_type(file_path)[0]
|
|
283
283
|
if not file_type or not file_type.startswith(('image/', 'text/', 'application/')):
|
|
284
|
-
PrettyOutput.print(f"
|
|
284
|
+
PrettyOutput.print(f"文件类型 {file_type} 不支持", OutputType.ERROR)
|
|
285
285
|
continue
|
|
286
286
|
|
|
287
287
|
with open(file_path, 'rb') as f:
|
|
@@ -300,15 +300,15 @@ class OyiModel(BasePlatform):
|
|
|
300
300
|
if data.get('code') == 200:
|
|
301
301
|
self.files.append(data)
|
|
302
302
|
else:
|
|
303
|
-
PrettyOutput.print(f"
|
|
303
|
+
PrettyOutput.print(f"文件上传失败: {data.get('message')}", OutputType.ERROR)
|
|
304
304
|
return []
|
|
305
305
|
else:
|
|
306
|
-
PrettyOutput.print(f"
|
|
306
|
+
PrettyOutput.print(f"文件上传失败: {response.status_code}", OutputType.ERROR)
|
|
307
307
|
return []
|
|
308
308
|
|
|
309
309
|
return self.files
|
|
310
310
|
except Exception as e:
|
|
311
|
-
PrettyOutput.print(f"
|
|
311
|
+
PrettyOutput.print(f"文件上传失败: {str(e)}", OutputType.ERROR)
|
|
312
312
|
return []
|
|
313
313
|
|
|
314
314
|
def get_available_models(self) -> List[str]:
|
|
@@ -335,7 +335,7 @@ class OyiModel(BasePlatform):
|
|
|
335
335
|
)
|
|
336
336
|
|
|
337
337
|
if response.status_code != 200:
|
|
338
|
-
PrettyOutput.print(f"
|
|
338
|
+
PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.ERROR)
|
|
339
339
|
return []
|
|
340
340
|
|
|
341
341
|
data = response.json()
|
|
@@ -379,5 +379,5 @@ class OyiModel(BasePlatform):
|
|
|
379
379
|
return sorted(models)
|
|
380
380
|
|
|
381
381
|
except Exception as e:
|
|
382
|
-
PrettyOutput.print(f"
|
|
382
|
+
PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.WARNING)
|
|
383
383
|
return []
|
|
@@ -36,7 +36,7 @@ class PlatformRegistry:
|
|
|
36
36
|
|
|
37
37
|
pass
|
|
38
38
|
except Exception as e:
|
|
39
|
-
PrettyOutput.print(f"
|
|
39
|
+
PrettyOutput.print(f"创建平台目录失败: {str(e)}", OutputType.ERROR)
|
|
40
40
|
return ""
|
|
41
41
|
return user_platform_dir
|
|
42
42
|
|
|
@@ -71,7 +71,7 @@ class PlatformRegistry:
|
|
|
71
71
|
|
|
72
72
|
if missing_methods:
|
|
73
73
|
PrettyOutput.print(
|
|
74
|
-
f"
|
|
74
|
+
f"平台 {platform_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
|
|
75
75
|
OutputType.ERROR
|
|
76
76
|
)
|
|
77
77
|
return False
|
|
@@ -92,7 +92,7 @@ class PlatformRegistry:
|
|
|
92
92
|
|
|
93
93
|
# 确保目录存在
|
|
94
94
|
if not os.path.exists(directory):
|
|
95
|
-
PrettyOutput.print(f"
|
|
95
|
+
PrettyOutput.print(f"平台目录不存在: {directory}", OutputType.ERROR)
|
|
96
96
|
return platforms
|
|
97
97
|
|
|
98
98
|
# 获取目录的包名
|
|
@@ -128,7 +128,7 @@ class PlatformRegistry:
|
|
|
128
128
|
platforms[obj.platform_name] = obj # type: ignore
|
|
129
129
|
break
|
|
130
130
|
except Exception as e:
|
|
131
|
-
PrettyOutput.print(f"
|
|
131
|
+
PrettyOutput.print(f"加载平台 {module_name} 失败: {str(e)}", OutputType.ERROR)
|
|
132
132
|
|
|
133
133
|
return platforms
|
|
134
134
|
|
|
@@ -201,7 +201,7 @@ class PlatformRegistry:
|
|
|
201
201
|
BasePlatform: Platform instance
|
|
202
202
|
"""
|
|
203
203
|
if name not in self.platforms:
|
|
204
|
-
PrettyOutput.print(f"
|
|
204
|
+
PrettyOutput.print(f"未找到平台: {name}", OutputType.ERROR)
|
|
205
205
|
return None
|
|
206
206
|
|
|
207
207
|
try:
|
|
@@ -209,7 +209,7 @@ class PlatformRegistry:
|
|
|
209
209
|
platform = self.platforms[name]()
|
|
210
210
|
return platform
|
|
211
211
|
except Exception as e:
|
|
212
|
-
PrettyOutput.print(f"
|
|
212
|
+
PrettyOutput.print(f"创建平台失败: {str(e)}", OutputType.ERROR)
|
|
213
213
|
return None
|
|
214
214
|
|
|
215
215
|
def get_available_platforms(self) -> List[str]:
|
|
@@ -31,10 +31,10 @@ def list_platforms():
|
|
|
31
31
|
output += f" • {model_name}\n"
|
|
32
32
|
PrettyOutput.print(output, OutputType.SUCCESS, lang="markdown")
|
|
33
33
|
else:
|
|
34
|
-
PrettyOutput.print(" •
|
|
34
|
+
PrettyOutput.print(" • 没有可用的模型信息", OutputType.WARNING)
|
|
35
35
|
|
|
36
36
|
except Exception as e:
|
|
37
|
-
PrettyOutput.print(f"
|
|
37
|
+
PrettyOutput.print(f"获取 {platform_name} 的模型列表失败: {str(e)}", OutputType.WARNING)
|
|
38
38
|
|
|
39
39
|
def chat_with_model(platform_name: str, model_name: str):
|
|
40
40
|
"""Chat with specified platform and model"""
|
|
@@ -43,13 +43,13 @@ def chat_with_model(platform_name: str, model_name: str):
|
|
|
43
43
|
# Create platform instance
|
|
44
44
|
platform = registry.create_platform(platform_name)
|
|
45
45
|
if not platform:
|
|
46
|
-
PrettyOutput.print(f"
|
|
46
|
+
PrettyOutput.print(f"创建平台 {platform_name} 失败", OutputType.ERROR)
|
|
47
47
|
return
|
|
48
48
|
|
|
49
49
|
try:
|
|
50
50
|
# Set model
|
|
51
51
|
platform.set_model_name(model_name)
|
|
52
|
-
PrettyOutput.print(f"
|
|
52
|
+
PrettyOutput.print(f"连接到 {platform_name} 平台 {model_name} 模型", OutputType.SUCCESS)
|
|
53
53
|
|
|
54
54
|
# Start conversation loop
|
|
55
55
|
while True:
|
|
@@ -58,7 +58,7 @@ def chat_with_model(platform_name: str, model_name: str):
|
|
|
58
58
|
|
|
59
59
|
# Check if input is cancelled
|
|
60
60
|
if user_input.strip() == "/bye":
|
|
61
|
-
PrettyOutput.print("
|
|
61
|
+
PrettyOutput.print("再见!", OutputType.SUCCESS)
|
|
62
62
|
break
|
|
63
63
|
|
|
64
64
|
# Check if input is empty
|
|
@@ -70,22 +70,22 @@ def chat_with_model(platform_name: str, model_name: str):
|
|
|
70
70
|
try:
|
|
71
71
|
platform.delete_chat()
|
|
72
72
|
platform.set_model_name(model_name) # Reinitialize session
|
|
73
|
-
PrettyOutput.print("
|
|
73
|
+
PrettyOutput.print("会话已清除", OutputType.SUCCESS)
|
|
74
74
|
except Exception as e:
|
|
75
|
-
PrettyOutput.print(f"
|
|
75
|
+
PrettyOutput.print(f"清除会话失败: {str(e)}", OutputType.ERROR)
|
|
76
76
|
continue
|
|
77
77
|
|
|
78
78
|
try:
|
|
79
79
|
# Send to model and get reply
|
|
80
80
|
response = platform.chat_until_success(user_input)
|
|
81
81
|
if not response:
|
|
82
|
-
PrettyOutput.print("
|
|
82
|
+
PrettyOutput.print("没有有效的回复", OutputType.WARNING)
|
|
83
83
|
|
|
84
84
|
except Exception as e:
|
|
85
|
-
PrettyOutput.print(f"
|
|
85
|
+
PrettyOutput.print(f"聊天失败: {str(e)}", OutputType.ERROR)
|
|
86
86
|
|
|
87
87
|
except Exception as e:
|
|
88
|
-
PrettyOutput.print(f"
|
|
88
|
+
PrettyOutput.print(f"初始化会话失败: {str(e)}", OutputType.ERROR)
|
|
89
89
|
finally:
|
|
90
90
|
# Clean up resources
|
|
91
91
|
try:
|
|
@@ -100,7 +100,7 @@ def info_command(args):
|
|
|
100
100
|
def chat_command(args):
|
|
101
101
|
"""Process chat subcommand"""
|
|
102
102
|
if not args.platform or not args.model:
|
|
103
|
-
PrettyOutput.print("
|
|
103
|
+
PrettyOutput.print("请指定平台和模型。使用 'jarvis info' 查看可用平台和模型。", OutputType.ERROR)
|
|
104
104
|
return
|
|
105
105
|
chat_with_model(args.platform, args.model)
|
|
106
106
|
|
|
@@ -110,16 +110,16 @@ def main():
|
|
|
110
110
|
|
|
111
111
|
init_env()
|
|
112
112
|
|
|
113
|
-
parser = argparse.ArgumentParser(description='Jarvis AI
|
|
114
|
-
subparsers = parser.add_subparsers(dest='command', help='
|
|
113
|
+
parser = argparse.ArgumentParser(description='Jarvis AI 平台')
|
|
114
|
+
subparsers = parser.add_subparsers(dest='command', help='可用子命令')
|
|
115
115
|
|
|
116
116
|
# info subcommand
|
|
117
|
-
info_parser = subparsers.add_parser('info', help='
|
|
117
|
+
info_parser = subparsers.add_parser('info', help='显示支持的平台和模型信息')
|
|
118
118
|
|
|
119
119
|
# chat subcommand
|
|
120
|
-
chat_parser = subparsers.add_parser('chat', help='
|
|
121
|
-
chat_parser.add_argument('--platform', '-p', help='
|
|
122
|
-
chat_parser.add_argument('--model', '-m', help='
|
|
120
|
+
chat_parser = subparsers.add_parser('chat', help='与指定平台和模型聊天')
|
|
121
|
+
chat_parser.add_argument('--platform', '-p', help='指定要使用的平台')
|
|
122
|
+
chat_parser.add_argument('--model', '-m', help='指定要使用的模型')
|
|
123
123
|
|
|
124
124
|
args = parser.parse_args()
|
|
125
125
|
|