jarvis-ai-assistant 0.1.131__py3-none-any.whl → 0.1.134__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/jarvis_agent/__init__.py +165 -285
- jarvis/jarvis_agent/jarvis.py +143 -0
- jarvis/jarvis_agent/main.py +0 -2
- jarvis/jarvis_agent/patch.py +70 -48
- jarvis/jarvis_agent/shell_input_handler.py +1 -1
- jarvis/jarvis_code_agent/code_agent.py +169 -117
- jarvis/jarvis_dev/main.py +327 -626
- jarvis/jarvis_git_squash/main.py +10 -31
- jarvis/jarvis_lsp/base.py +0 -42
- jarvis/jarvis_lsp/cpp.py +0 -15
- jarvis/jarvis_lsp/go.py +0 -15
- jarvis/jarvis_lsp/python.py +0 -19
- jarvis/jarvis_lsp/registry.py +0 -62
- jarvis/jarvis_lsp/rust.py +0 -15
- jarvis/jarvis_multi_agent/__init__.py +19 -69
- jarvis/jarvis_multi_agent/main.py +43 -0
- jarvis/jarvis_platform/ai8.py +7 -32
- jarvis/jarvis_platform/base.py +2 -7
- jarvis/jarvis_platform/kimi.py +3 -144
- jarvis/jarvis_platform/ollama.py +54 -68
- jarvis/jarvis_platform/openai.py +0 -4
- jarvis/jarvis_platform/oyi.py +0 -75
- jarvis/jarvis_platform/registry.py +2 -16
- jarvis/jarvis_platform/yuanbao.py +264 -0
- jarvis/jarvis_rag/file_processors.py +138 -0
- jarvis/jarvis_rag/main.py +1305 -425
- jarvis/jarvis_tools/ask_codebase.py +216 -43
- jarvis/jarvis_tools/code_review.py +158 -113
- jarvis/jarvis_tools/create_sub_agent.py +0 -1
- jarvis/jarvis_tools/execute_python_script.py +58 -0
- jarvis/jarvis_tools/execute_shell.py +13 -26
- jarvis/jarvis_tools/execute_shell_script.py +1 -1
- jarvis/jarvis_tools/file_analyzer.py +282 -0
- jarvis/jarvis_tools/file_operation.py +1 -1
- jarvis/jarvis_tools/find_caller.py +278 -0
- jarvis/jarvis_tools/find_symbol.py +295 -0
- jarvis/jarvis_tools/function_analyzer.py +331 -0
- jarvis/jarvis_tools/git_commiter.py +5 -5
- jarvis/jarvis_tools/methodology.py +88 -53
- jarvis/jarvis_tools/project_analyzer.py +308 -0
- jarvis/jarvis_tools/rag.py +0 -5
- jarvis/jarvis_tools/read_code.py +24 -3
- jarvis/jarvis_tools/read_webpage.py +195 -81
- jarvis/jarvis_tools/registry.py +132 -11
- jarvis/jarvis_tools/search_web.py +22 -307
- jarvis/jarvis_tools/tool_generator.py +8 -10
- jarvis/jarvis_utils/__init__.py +1 -0
- jarvis/jarvis_utils/config.py +80 -76
- jarvis/jarvis_utils/embedding.py +344 -45
- jarvis/jarvis_utils/git_utils.py +9 -1
- jarvis/jarvis_utils/input.py +7 -6
- jarvis/jarvis_utils/methodology.py +384 -15
- jarvis/jarvis_utils/output.py +5 -3
- jarvis/jarvis_utils/utils.py +60 -8
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/METADATA +8 -16
- jarvis_ai_assistant-0.1.134.dist-info/RECORD +82 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/entry_points.txt +4 -3
- jarvis/jarvis_codebase/__init__.py +0 -0
- jarvis/jarvis_codebase/main.py +0 -1011
- jarvis/jarvis_tools/lsp_find_definition.py +0 -150
- jarvis/jarvis_tools/lsp_find_references.py +0 -127
- jarvis/jarvis_tools/treesitter_analyzer.py +0 -331
- jarvis/jarvis_treesitter/README.md +0 -104
- jarvis/jarvis_treesitter/__init__.py +0 -20
- jarvis/jarvis_treesitter/database.py +0 -258
- jarvis/jarvis_treesitter/example.py +0 -115
- jarvis/jarvis_treesitter/grammar_builder.py +0 -182
- jarvis/jarvis_treesitter/language.py +0 -117
- jarvis/jarvis_treesitter/symbol.py +0 -31
- jarvis/jarvis_treesitter/tools_usage.md +0 -121
- jarvis_ai_assistant-0.1.131.dist-info/RECORD +0 -85
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/top_level.txt +0 -0
jarvis/jarvis_platform/kimi.py
CHANGED
|
@@ -45,7 +45,6 @@ class KimiModel(BasePlatform):
|
|
|
45
45
|
PrettyOutput.print("KIMI_API_KEY 未设置", OutputType.WARNING)
|
|
46
46
|
self.auth_header = f"Bearer {self.api_key}"
|
|
47
47
|
self.chat_id = ""
|
|
48
|
-
self.uploaded_files = [] # 存储已上传文件的信息
|
|
49
48
|
self.first_chat = True # 添加标记,用于判断是否是第一次对话
|
|
50
49
|
self.system_message = ""
|
|
51
50
|
|
|
@@ -77,138 +76,6 @@ class KimiModel(BasePlatform):
|
|
|
77
76
|
PrettyOutput.print(f"错误:创建会话失败:{e}", OutputType.ERROR)
|
|
78
77
|
return False
|
|
79
78
|
|
|
80
|
-
def _get_presigned_url(self, filename: str, action: str) -> Dict:
|
|
81
|
-
"""Get presigned upload URL"""
|
|
82
|
-
url = "https://kimi.moonshot.cn/api/pre-sign-url"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
payload = json.dumps({
|
|
87
|
-
"action": action,
|
|
88
|
-
"name": os.path.basename(filename)
|
|
89
|
-
}, ensure_ascii=False)
|
|
90
|
-
|
|
91
|
-
headers = {
|
|
92
|
-
'Authorization': self.auth_header,
|
|
93
|
-
'Content-Type': 'application/json'
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
response = while_success(lambda: requests.post(url, headers=headers, data=payload), sleep_time=5)
|
|
97
|
-
return response.json()
|
|
98
|
-
|
|
99
|
-
def _upload_file(self, file_path: str, presigned_url: str) -> bool:
|
|
100
|
-
"""Upload file to presigned URL"""
|
|
101
|
-
try:
|
|
102
|
-
with open(file_path, 'rb') as f:
|
|
103
|
-
content = f.read()
|
|
104
|
-
response = while_success(lambda: requests.put(presigned_url, data=content), sleep_time=5)
|
|
105
|
-
return response.status_code == 200
|
|
106
|
-
except Exception as e:
|
|
107
|
-
PrettyOutput.print(f"错误:上传文件失败:{e}", OutputType.ERROR)
|
|
108
|
-
return False
|
|
109
|
-
|
|
110
|
-
def _get_file_info(self, file_data: Dict, name: str, file_type: str) -> Dict:
|
|
111
|
-
"""Get file information"""
|
|
112
|
-
url = "https://kimi.moonshot.cn/api/file"
|
|
113
|
-
payload = json.dumps({
|
|
114
|
-
"type": file_type,
|
|
115
|
-
"name": name,
|
|
116
|
-
"object_name": file_data["object_name"],
|
|
117
|
-
"chat_id": self.chat_id,
|
|
118
|
-
"file_id": file_data.get("file_id", "")
|
|
119
|
-
}, ensure_ascii=False)
|
|
120
|
-
|
|
121
|
-
headers = {
|
|
122
|
-
'Authorization': self.auth_header,
|
|
123
|
-
'Content-Type': 'application/json'
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
response = while_success(lambda: requests.post(url, headers=headers, data=payload), sleep_time=5)
|
|
127
|
-
return response.json()
|
|
128
|
-
|
|
129
|
-
def _wait_for_parse(self, file_id: str) -> bool:
|
|
130
|
-
"""Wait for file parsing to complete"""
|
|
131
|
-
url = "https://kimi.moonshot.cn/api/file/parse_process"
|
|
132
|
-
headers = {
|
|
133
|
-
'Authorization': self.auth_header,
|
|
134
|
-
'Content-Type': 'application/json'
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
max_retries = 30
|
|
138
|
-
retry_count = 0
|
|
139
|
-
|
|
140
|
-
while retry_count < max_retries:
|
|
141
|
-
payload = json.dumps({"ids": [file_id]}, ensure_ascii=False)
|
|
142
|
-
response = while_success(lambda: requests.post(url, headers=headers, data=payload, stream=True), sleep_time=5)
|
|
143
|
-
|
|
144
|
-
for line in response.iter_lines():
|
|
145
|
-
if not line:
|
|
146
|
-
continue
|
|
147
|
-
|
|
148
|
-
line = line.decode('utf-8')
|
|
149
|
-
if not line.startswith("data: "):
|
|
150
|
-
continue
|
|
151
|
-
|
|
152
|
-
try:
|
|
153
|
-
data = json.loads(line[6:])
|
|
154
|
-
if data.get("event") == "resp":
|
|
155
|
-
status = data.get("file_info", {}).get("status")
|
|
156
|
-
if status == "parsed":
|
|
157
|
-
return True
|
|
158
|
-
elif status == "failed":
|
|
159
|
-
return False
|
|
160
|
-
except json.JSONDecodeError:
|
|
161
|
-
continue
|
|
162
|
-
|
|
163
|
-
retry_count += 1
|
|
164
|
-
time.sleep(1)
|
|
165
|
-
|
|
166
|
-
return False
|
|
167
|
-
def upload_files(self, file_list: List[str]) -> List[Dict]:
|
|
168
|
-
"""Upload file list and return file information"""
|
|
169
|
-
if not file_list:
|
|
170
|
-
return []
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if not self.chat_id:
|
|
174
|
-
if not self._create_chat():
|
|
175
|
-
raise Exception("Failed to create chat session")
|
|
176
|
-
|
|
177
|
-
uploaded_files = []
|
|
178
|
-
for index, file_path in enumerate(file_list, 1):
|
|
179
|
-
try:
|
|
180
|
-
PrettyOutput.print(f"处理文件 [{index}/{len(file_list)}]: {file_path}", OutputType.PROGRESS)
|
|
181
|
-
|
|
182
|
-
mime_type, _ = mimetypes.guess_type(file_path)
|
|
183
|
-
action = "image" if mime_type and mime_type.startswith('image/') else "file"
|
|
184
|
-
|
|
185
|
-
# 获取预签名URL
|
|
186
|
-
presigned_data = self._get_presigned_url(file_path, action)
|
|
187
|
-
|
|
188
|
-
# 上传文件
|
|
189
|
-
if self._upload_file(file_path, presigned_data["url"]):
|
|
190
|
-
# 获取文件信息
|
|
191
|
-
file_info = self._get_file_info(presigned_data, os.path.basename(file_path), action)
|
|
192
|
-
file_info = self._get_file_info(presigned_data, os.path.basename(file_path), action)
|
|
193
|
-
# 等待文件解析
|
|
194
|
-
|
|
195
|
-
# 只有文件需要解析
|
|
196
|
-
if action == "file":
|
|
197
|
-
if self._wait_for_parse(file_info["id"]):
|
|
198
|
-
uploaded_files.append(file_info)
|
|
199
|
-
else:
|
|
200
|
-
PrettyOutput.print(f"✗ 文件解析失败: {file_path}", OutputType.WARNING)
|
|
201
|
-
else:
|
|
202
|
-
uploaded_files.append(file_info)
|
|
203
|
-
else:
|
|
204
|
-
PrettyOutput.print(f"错误:文件上传失败: {file_path}", OutputType.WARNING)
|
|
205
|
-
|
|
206
|
-
except Exception as e:
|
|
207
|
-
PrettyOutput.print(f"✗ 处理文件出错 {file_path}: {str(e)}", OutputType.ERROR)
|
|
208
|
-
continue
|
|
209
|
-
|
|
210
|
-
self.uploaded_files = uploaded_files
|
|
211
|
-
return uploaded_files
|
|
212
79
|
|
|
213
80
|
def chat(self, message: str) -> str:
|
|
214
81
|
"""Send message and get response"""
|
|
@@ -218,15 +85,7 @@ class KimiModel(BasePlatform):
|
|
|
218
85
|
|
|
219
86
|
url = f"https://kimi.moonshot.cn/api/chat/{self.chat_id}/completion/stream"
|
|
220
87
|
|
|
221
|
-
|
|
222
|
-
refs = []
|
|
223
|
-
refs_file = []
|
|
224
|
-
if self.first_chat:
|
|
225
|
-
if self.uploaded_files:
|
|
226
|
-
refs = [f["id"] for f in self.uploaded_files]
|
|
227
|
-
refs_file = self.uploaded_files
|
|
228
|
-
message = self.system_message + "\n" + message
|
|
229
|
-
self.first_chat = False
|
|
88
|
+
|
|
230
89
|
|
|
231
90
|
payload = {
|
|
232
91
|
"messages": [{"role": "user", "content": message}],
|
|
@@ -235,8 +94,8 @@ class KimiModel(BasePlatform):
|
|
|
235
94
|
"kimiplus_id": "kimi",
|
|
236
95
|
"use_research": False,
|
|
237
96
|
"use_math": False,
|
|
238
|
-
"refs":
|
|
239
|
-
"refs_file":
|
|
97
|
+
"refs": [],
|
|
98
|
+
"refs_file": []
|
|
240
99
|
}
|
|
241
100
|
|
|
242
101
|
headers = {
|
jarvis/jarvis_platform/ollama.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import requests
|
|
2
1
|
from typing import List, Dict, Tuple
|
|
3
2
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
4
3
|
import os
|
|
5
|
-
import json
|
|
6
4
|
|
|
7
|
-
from jarvis.jarvis_utils.input import get_single_line_input
|
|
8
5
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
9
6
|
|
|
7
|
+
|
|
8
|
+
import ollama
|
|
9
|
+
|
|
10
10
|
class OllamaPlatform(BasePlatform):
|
|
11
11
|
"""Ollama platform implementation"""
|
|
12
12
|
|
|
@@ -20,11 +20,13 @@ class OllamaPlatform(BasePlatform):
|
|
|
20
20
|
self.api_base = os.getenv("OLLAMA_API_BASE", "http://localhost:11434")
|
|
21
21
|
self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-r1:1.5b"
|
|
22
22
|
|
|
23
|
+
# Setup client based on availability
|
|
24
|
+
self.client = None
|
|
25
|
+
self.client = ollama.Client(host=self.api_base)
|
|
26
|
+
|
|
23
27
|
# Check if Ollama service is available
|
|
24
28
|
try:
|
|
25
|
-
|
|
26
|
-
response.raise_for_status()
|
|
27
|
-
available_models = [model["name"] for model in response.json().get("models", [])]
|
|
29
|
+
available_models = self._get_available_models()
|
|
28
30
|
|
|
29
31
|
if not available_models:
|
|
30
32
|
message = (
|
|
@@ -36,9 +38,9 @@ class OllamaPlatform(BasePlatform):
|
|
|
36
38
|
PrettyOutput.print(message, OutputType.INFO)
|
|
37
39
|
PrettyOutput.print("Ollama 没有可用的模型", OutputType.WARNING)
|
|
38
40
|
|
|
39
|
-
except
|
|
41
|
+
except Exception as e:
|
|
40
42
|
message = (
|
|
41
|
-
"Ollama
|
|
43
|
+
f"Ollama 服务未启动或无法连接: {str(e)}\n"
|
|
42
44
|
"请确保您已:\n"
|
|
43
45
|
"1. 安装 Ollama: https://ollama.ai\n"
|
|
44
46
|
"2. 启动 Ollama 服务\n"
|
|
@@ -50,11 +52,19 @@ class OllamaPlatform(BasePlatform):
|
|
|
50
52
|
self.messages = []
|
|
51
53
|
self.system_message = ""
|
|
52
54
|
|
|
55
|
+
def _get_available_models(self) -> List[str]:
|
|
56
|
+
"""Get list of available models using appropriate method"""
|
|
57
|
+
models_response = self.client.list() # type: ignore
|
|
58
|
+
return [model["model"] for model in models_response.get("models", [])]
|
|
59
|
+
|
|
53
60
|
def get_model_list(self) -> List[Tuple[str, str]]:
|
|
54
61
|
"""Get model list"""
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
try:
|
|
63
|
+
models = self._get_available_models()
|
|
64
|
+
return [(model, "") for model in models]
|
|
65
|
+
except Exception as e:
|
|
66
|
+
PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.ERROR)
|
|
67
|
+
return []
|
|
58
68
|
|
|
59
69
|
def set_model_name(self, model_name: str):
|
|
60
70
|
"""Set model name"""
|
|
@@ -69,54 +79,44 @@ class OllamaPlatform(BasePlatform):
|
|
|
69
79
|
messages.append({"role": "system", "content": self.system_message})
|
|
70
80
|
messages.extend(self.messages)
|
|
71
81
|
messages.append({"role": "user", "content": message})
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
data = {
|
|
75
|
-
"model": self.model_name,
|
|
76
|
-
"messages": messages,
|
|
77
|
-
"stream": True # 启用流式输出
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
# 发送请求
|
|
81
|
-
response = requests.post(
|
|
82
|
-
f"{self.api_base}/api/chat",
|
|
83
|
-
json=data,
|
|
84
|
-
stream=True
|
|
85
|
-
)
|
|
86
|
-
response.raise_for_status()
|
|
87
|
-
|
|
88
|
-
# 处理流式响应
|
|
89
|
-
full_response = ""
|
|
90
|
-
for line in response.iter_lines():
|
|
91
|
-
if line:
|
|
92
|
-
chunk = line.decode()
|
|
93
|
-
try:
|
|
94
|
-
result = json.loads(chunk)
|
|
95
|
-
if "message" in result and "content" in result["message"]:
|
|
96
|
-
text = result["message"]["content"]
|
|
97
|
-
if not self.suppress_output:
|
|
98
|
-
PrettyOutput.print_stream(text)
|
|
99
|
-
full_response += text
|
|
100
|
-
except json.JSONDecodeError:
|
|
101
|
-
continue
|
|
102
|
-
|
|
103
|
-
if not self.suppress_output:
|
|
104
|
-
PrettyOutput.print_stream_end()
|
|
105
|
-
|
|
106
|
-
# 更新消息历史
|
|
107
|
-
self.messages.append({"role": "user", "content": message})
|
|
108
|
-
self.messages.append({"role": "assistant", "content": full_response})
|
|
109
|
-
|
|
110
|
-
return full_response
|
|
82
|
+
|
|
83
|
+
return self._chat_with_package(messages)
|
|
111
84
|
|
|
112
85
|
except Exception as e:
|
|
113
86
|
PrettyOutput.print(f"对话失败: {str(e)}", OutputType.ERROR)
|
|
114
87
|
raise Exception(f"Chat failed: {str(e)}")
|
|
115
88
|
|
|
116
|
-
def
|
|
117
|
-
"""
|
|
118
|
-
|
|
119
|
-
|
|
89
|
+
def _chat_with_package(self, messages: List[Dict]) -> str:
|
|
90
|
+
"""Chat using the ollama package"""
|
|
91
|
+
# The client should not be None here due to the check in the chat method
|
|
92
|
+
if not self.client:
|
|
93
|
+
raise ValueError("Ollama client is not initialized")
|
|
94
|
+
|
|
95
|
+
# Use ollama-python's streaming API
|
|
96
|
+
stream = self.client.chat(
|
|
97
|
+
model=self.model_name,
|
|
98
|
+
messages=messages,
|
|
99
|
+
stream=True
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Process the streaming response
|
|
103
|
+
full_response = ""
|
|
104
|
+
for chunk in stream:
|
|
105
|
+
if "message" in chunk and "content" in chunk["message"]:
|
|
106
|
+
text = chunk["message"]["content"]
|
|
107
|
+
if not self.suppress_output:
|
|
108
|
+
PrettyOutput.print_stream(text)
|
|
109
|
+
full_response += text
|
|
110
|
+
|
|
111
|
+
if not self.suppress_output:
|
|
112
|
+
PrettyOutput.print_stream_end()
|
|
113
|
+
|
|
114
|
+
# Update message history
|
|
115
|
+
self.messages.append({"role": "user", "content": messages[-1]["content"]})
|
|
116
|
+
self.messages.append({"role": "assistant", "content": full_response})
|
|
117
|
+
|
|
118
|
+
return full_response
|
|
119
|
+
|
|
120
120
|
|
|
121
121
|
def reset(self):
|
|
122
122
|
"""Reset model state"""
|
|
@@ -137,17 +137,3 @@ class OllamaPlatform(BasePlatform):
|
|
|
137
137
|
"""Set system message"""
|
|
138
138
|
self.system_message = message
|
|
139
139
|
self.reset() # 重置会话以应用新的系统消息
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if __name__ == "__main__":
|
|
143
|
-
try:
|
|
144
|
-
ollama = OllamaPlatform()
|
|
145
|
-
while True:
|
|
146
|
-
try:
|
|
147
|
-
message = get_single_line_input("输入问题 (Ctrl+C 退出)")
|
|
148
|
-
ollama.chat_until_success(message)
|
|
149
|
-
except KeyboardInterrupt:
|
|
150
|
-
print("再见!")
|
|
151
|
-
break
|
|
152
|
-
except Exception as e:
|
|
153
|
-
PrettyOutput.print(f"程序异常退出: {str(e)}", OutputType.ERROR)
|
jarvis/jarvis_platform/openai.py
CHANGED
|
@@ -7,10 +7,6 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
|
7
7
|
class OpenAIModel(BasePlatform):
|
|
8
8
|
platform_name = "openai"
|
|
9
9
|
|
|
10
|
-
def upload_files(self, file_list: List[str]):
|
|
11
|
-
"""Upload files"""
|
|
12
|
-
PrettyOutput.print("OpenAI does not support file upload", OutputType.WARNING)
|
|
13
|
-
|
|
14
10
|
def __init__(self):
|
|
15
11
|
"""
|
|
16
12
|
Initialize OpenAI model
|
jarvis/jarvis_platform/oyi.py
CHANGED
|
@@ -25,7 +25,6 @@ class OyiModel(BasePlatform):
|
|
|
25
25
|
self.messages = []
|
|
26
26
|
self.system_message = ""
|
|
27
27
|
self.conversation = None
|
|
28
|
-
self.files = []
|
|
29
28
|
self.first_chat = True
|
|
30
29
|
|
|
31
30
|
self.token = os.getenv("OYI_API_KEY")
|
|
@@ -132,17 +131,6 @@ class OyiModel(BasePlatform):
|
|
|
132
131
|
|
|
133
132
|
# 如果有上传的文件,添加到请求中
|
|
134
133
|
if self.first_chat:
|
|
135
|
-
if self.files:
|
|
136
|
-
for file_data in self.files:
|
|
137
|
-
file_info = {
|
|
138
|
-
"contentType": 1, # 1 表示图片
|
|
139
|
-
"fileUrl": file_data['result']['url'],
|
|
140
|
-
"fileId": file_data['result']['id'],
|
|
141
|
-
"fileName": file_data['result']['fileName']
|
|
142
|
-
}
|
|
143
|
-
payload["contentFiles"].append(file_info)
|
|
144
|
-
# 清空已使用的文件列表
|
|
145
|
-
self.files = []
|
|
146
134
|
message = self.system_message + "\n" + message
|
|
147
135
|
payload["content"] = message
|
|
148
136
|
self.first_chat = False
|
|
@@ -211,7 +199,6 @@ class OyiModel(BasePlatform):
|
|
|
211
199
|
"""Reset model state"""
|
|
212
200
|
self.messages = []
|
|
213
201
|
self.conversation = None
|
|
214
|
-
self.files = []
|
|
215
202
|
self.first_chat = True
|
|
216
203
|
|
|
217
204
|
def delete_chat(self) -> bool:
|
|
@@ -252,65 +239,6 @@ class OyiModel(BasePlatform):
|
|
|
252
239
|
except Exception as e:
|
|
253
240
|
PrettyOutput.print(f"删除会话失败: {str(e)}", OutputType.ERROR)
|
|
254
241
|
return False
|
|
255
|
-
|
|
256
|
-
def upload_files(self, file_list: List[str]) -> List[Dict]:
|
|
257
|
-
"""Upload a file to OYI API
|
|
258
|
-
|
|
259
|
-
Args:
|
|
260
|
-
file_path: Path to the file to upload
|
|
261
|
-
|
|
262
|
-
Returns:
|
|
263
|
-
Dict: Upload response data
|
|
264
|
-
"""
|
|
265
|
-
try:
|
|
266
|
-
# 检查当前模型是否支持文件上传
|
|
267
|
-
model_info = self.models.get(self.model_name)
|
|
268
|
-
if not model_info or not model_info.get('uploadFile', False):
|
|
269
|
-
PrettyOutput.print(f"当前模型 {self.model_name} 不支持文件上传", OutputType.WARNING)
|
|
270
|
-
return []
|
|
271
|
-
|
|
272
|
-
headers = {
|
|
273
|
-
'Authorization': f'Bearer {self.token}',
|
|
274
|
-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
275
|
-
'Accept': '*/*',
|
|
276
|
-
'DNT': '1',
|
|
277
|
-
'Origin': 'https://ai.rcouyi.com',
|
|
278
|
-
'Referer': 'https://ai.rcouyi.com/'
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
for file_path in file_list:
|
|
282
|
-
# 检查文件类型
|
|
283
|
-
file_type = mimetypes.guess_type(file_path)[0]
|
|
284
|
-
if not file_type or not file_type.startswith(('image/', 'text/', 'application/')):
|
|
285
|
-
PrettyOutput.print(f"文件类型 {file_type} 不支持", OutputType.WARNING)
|
|
286
|
-
continue
|
|
287
|
-
|
|
288
|
-
with open(file_path, 'rb') as f:
|
|
289
|
-
files = {
|
|
290
|
-
'file': (os.path.basename(file_path), f, file_type)
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
response = requests.post(
|
|
294
|
-
f"{self.BASE_URL}/chatapi/m_file/uploadfile",
|
|
295
|
-
headers=headers,
|
|
296
|
-
files=files
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
if response.status_code == 200:
|
|
300
|
-
data = response.json()
|
|
301
|
-
if data.get('code') == 200:
|
|
302
|
-
self.files.append(data)
|
|
303
|
-
else:
|
|
304
|
-
PrettyOutput.print(f"文件上传失败: {data.get('message')}", OutputType.WARNING)
|
|
305
|
-
return []
|
|
306
|
-
else:
|
|
307
|
-
PrettyOutput.print(f"文件上传失败: {response.status_code}", OutputType.WARNING)
|
|
308
|
-
return []
|
|
309
|
-
|
|
310
|
-
return self.files
|
|
311
|
-
except Exception as e:
|
|
312
|
-
PrettyOutput.print(f"文件上传失败: {str(e)}", OutputType.ERROR)
|
|
313
|
-
return []
|
|
314
242
|
|
|
315
243
|
def get_available_models(self) -> List[str]:
|
|
316
244
|
"""Get available model list
|
|
@@ -371,9 +299,6 @@ class OyiModel(BasePlatform):
|
|
|
371
299
|
if info:
|
|
372
300
|
model_str += f" - {info}"
|
|
373
301
|
|
|
374
|
-
# 添加文件上传支持标记
|
|
375
|
-
if model.get('uploadFile'):
|
|
376
|
-
model_str += " [Support file upload]"
|
|
377
302
|
model['desc'] = model_str
|
|
378
303
|
models.append(model_name)
|
|
379
304
|
|
|
@@ -4,7 +4,7 @@ import os
|
|
|
4
4
|
import sys
|
|
5
5
|
from typing import Dict, Type, Optional, List
|
|
6
6
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
7
|
-
from jarvis.jarvis_utils.config import
|
|
7
|
+
from jarvis.jarvis_utils.config import get_normal_model_name, get_normal_platform_name, get_thinking_model_name, get_thinking_platform_name
|
|
8
8
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
9
9
|
|
|
10
10
|
REQUIRED_METHODS = [
|
|
@@ -21,7 +21,7 @@ REQUIRED_METHODS = [
|
|
|
21
21
|
class PlatformRegistry:
|
|
22
22
|
"""Platform registry"""
|
|
23
23
|
|
|
24
|
-
global_platform_name = "
|
|
24
|
+
global_platform_name = "yuanbao"
|
|
25
25
|
global_platform_registry = None
|
|
26
26
|
|
|
27
27
|
@staticmethod
|
|
@@ -161,20 +161,6 @@ class PlatformRegistry:
|
|
|
161
161
|
platform.set_model_name(model_name) # type: ignore
|
|
162
162
|
return platform # type: ignore
|
|
163
163
|
|
|
164
|
-
def get_codegen_platform(self) -> BasePlatform:
|
|
165
|
-
platform_name = get_codegen_platform_name()
|
|
166
|
-
model_name = get_codegen_model_name()
|
|
167
|
-
platform = self.create_platform(platform_name)
|
|
168
|
-
platform.set_model_name(model_name) # type: ignore
|
|
169
|
-
return platform # type: ignore
|
|
170
|
-
|
|
171
|
-
def get_cheap_platform(self) -> BasePlatform:
|
|
172
|
-
platform_name = get_cheap_platform_name()
|
|
173
|
-
model_name = get_cheap_model_name()
|
|
174
|
-
platform = self.create_platform(platform_name)
|
|
175
|
-
platform.set_model_name(model_name) # type: ignore
|
|
176
|
-
return platform # type: ignore
|
|
177
|
-
|
|
178
164
|
def get_thinking_platform(self) -> BasePlatform:
|
|
179
165
|
platform_name = get_thinking_platform_name()
|
|
180
166
|
model_name = get_thinking_model_name()
|