jarvis-ai-assistant 0.1.46__py3-none-any.whl → 0.1.47__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
jarvis/models/kimi.py CHANGED
@@ -8,46 +8,31 @@ from jarvis.models.base import BasePlatform
8
8
  from jarvis.utils import PrettyOutput, OutputType
9
9
  from jarvis.utils import while_success
10
10
 
11
-
12
11
  class KimiModel(BasePlatform):
13
12
  """Kimi模型实现"""
14
13
 
15
14
  platform_name = "kimi"
16
-
15
+
17
16
  def __init__(self):
18
17
  """
19
18
  初始化Kimi模型
20
19
  """
21
20
  self.api_key = os.getenv("KIMI_API_KEY")
22
21
  if not self.api_key:
23
- PrettyOutput.print(
24
- "\n需要设置 KIMI_API_KEY 才能使用 Jarvis。请按以下步骤操作:",
25
- OutputType.INFO)
22
+ PrettyOutput.print("\n需要设置 KIMI_API_KEY 才能使用 Jarvis。请按以下步骤操作:", OutputType.INFO)
26
23
  PrettyOutput.print("\n1. 获取 Kimi API Key:", OutputType.INFO)
27
- PrettyOutput.print(
28
- " • 访问 Kimi AI 平台: https://kimi.moonshot.cn",
29
- OutputType.INFO)
24
+ PrettyOutput.print(" • 访问 Kimi AI 平台: https://kimi.moonshot.cn", OutputType.INFO)
30
25
  PrettyOutput.print(" • 登录您的账号", OutputType.INFO)
31
- PrettyOutput.print(
32
- " • 打开浏览器开发者工具 (F12 或右键 -> 检查)",
33
- OutputType.INFO)
26
+ PrettyOutput.print(" • 打开浏览器开发者工具 (F12 或右键 -> 检查)", OutputType.INFO)
34
27
  PrettyOutput.print(" • 切换到 Network 标签页", OutputType.INFO)
35
28
  PrettyOutput.print(" • 发送任意消息", OutputType.INFO)
36
29
  PrettyOutput.print(" • 在请求中找到 Authorization 头部", OutputType.INFO)
37
- PrettyOutput.print(
38
- " • 复制 token 值(去掉 'Bearer ' 前缀)",
39
- OutputType.INFO)
30
+ PrettyOutput.print(" • 复制 token 值(去掉 'Bearer ' 前缀)", OutputType.INFO)
40
31
  PrettyOutput.print("\n2. 设置环境变量:", OutputType.INFO)
41
- PrettyOutput.print(
42
- " 方法 1: 创建或编辑 ~/.jarvis_env 文件:",
43
- OutputType.INFO)
44
- PrettyOutput.print(
45
- " echo 'KIMI_API_KEY=your_key_here' > ~/.jarvis_env",
46
- OutputType.INFO)
32
+ PrettyOutput.print(" 方法 1: 创建或编辑 ~/.jarvis_env 文件:", OutputType.INFO)
33
+ PrettyOutput.print(" echo 'KIMI_API_KEY=your_key_here' > ~/.jarvis_env", OutputType.INFO)
47
34
  PrettyOutput.print("\n 方法 2: 直接设置环境变量:", OutputType.INFO)
48
- PrettyOutput.print(
49
- " export KIMI_API_KEY=your_key_here",
50
- OutputType.INFO)
35
+ PrettyOutput.print(" export KIMI_API_KEY=your_key_here", OutputType.INFO)
51
36
  PrettyOutput.print("\n设置完成后重新运行 Jarvis。", OutputType.INFO)
52
37
  raise Exception("KIMI_API_KEY is not set")
53
38
  self.auth_header = f"Bearer {self.api_key}"
@@ -77,41 +62,30 @@ class KimiModel(BasePlatform):
77
62
  'Content-Type': 'application/json'
78
63
  }
79
64
  try:
80
- response = while_success(
81
- lambda: requests.request(
82
- "POST",
83
- url,
84
- headers=headers,
85
- data=payload),
86
- sleep_time=5)
65
+ response = while_success(lambda: requests.request("POST", url, headers=headers, data=payload), sleep_time=5)
87
66
  self.chat_id = response.json()["id"]
88
67
  return True
89
68
  except Exception as e:
90
- PrettyOutput.print(
91
- f"Error: Failed to create chat: {e}",
92
- OutputType.ERROR)
69
+ PrettyOutput.print(f"Error: Failed to create chat: {e}", OutputType.ERROR)
93
70
  return False
94
71
 
95
72
  def _get_presigned_url(self, filename: str, action: str) -> Dict:
96
73
  """获取预签名上传URL"""
97
74
  url = "https://kimi.moonshot.cn/api/pre-sign-url"
98
-
75
+
76
+
77
+
99
78
  payload = json.dumps({
100
79
  "action": action,
101
80
  "name": os.path.basename(filename)
102
81
  }, ensure_ascii=False)
103
-
82
+
104
83
  headers = {
105
84
  'Authorization': self.auth_header,
106
85
  'Content-Type': 'application/json'
107
86
  }
108
-
109
- response = while_success(
110
- lambda: requests.post(
111
- url,
112
- headers=headers,
113
- data=payload),
114
- sleep_time=5)
87
+
88
+ response = while_success(lambda: requests.post(url, headers=headers, data=payload), sleep_time=5)
115
89
  return response.json()
116
90
 
117
91
  def _upload_file(self, file_path: str, presigned_url: str) -> bool:
@@ -119,20 +93,13 @@ class KimiModel(BasePlatform):
119
93
  try:
120
94
  with open(file_path, 'rb') as f:
121
95
  content = f.read()
122
- response = while_success(
123
- lambda: requests.put(
124
- presigned_url,
125
- data=content),
126
- sleep_time=5)
96
+ response = while_success(lambda: requests.put(presigned_url, data=content), sleep_time=5)
127
97
  return response.status_code == 200
128
98
  except Exception as e:
129
- PrettyOutput.print(
130
- f"Error: Failed to upload file: {e}",
131
- OutputType.ERROR)
99
+ PrettyOutput.print(f"Error: Failed to upload file: {e}", OutputType.ERROR)
132
100
  return False
133
101
 
134
- def _get_file_info(self, file_data: Dict, name: str,
135
- file_type: str) -> Dict:
102
+ def _get_file_info(self, file_data: Dict, name: str, file_type: str) -> Dict:
136
103
  """获取文件信息"""
137
104
  url = "https://kimi.moonshot.cn/api/file"
138
105
  payload = json.dumps({
@@ -142,18 +109,13 @@ class KimiModel(BasePlatform):
142
109
  "chat_id": self.chat_id,
143
110
  "file_id": file_data.get("file_id", "")
144
111
  }, ensure_ascii=False)
145
-
112
+
146
113
  headers = {
147
114
  'Authorization': self.auth_header,
148
115
  'Content-Type': 'application/json'
149
116
  }
150
-
151
- response = while_success(
152
- lambda: requests.post(
153
- url,
154
- headers=headers,
155
- data=payload),
156
- sleep_time=5)
117
+
118
+ response = while_success(lambda: requests.post(url, headers=headers, data=payload), sleep_time=5)
157
119
  return response.json()
158
120
 
159
121
  def _wait_for_parse(self, file_id: str) -> bool:
@@ -163,28 +125,22 @@ class KimiModel(BasePlatform):
163
125
  'Authorization': self.auth_header,
164
126
  'Content-Type': 'application/json'
165
127
  }
166
-
128
+
167
129
  max_retries = 30
168
130
  retry_count = 0
169
-
131
+
170
132
  while retry_count < max_retries:
171
133
  payload = json.dumps({"ids": [file_id]}, ensure_ascii=False)
172
- response = while_success(
173
- lambda: requests.post(
174
- url,
175
- headers=headers,
176
- data=payload,
177
- stream=True),
178
- sleep_time=5)
179
-
134
+ response = while_success(lambda: requests.post(url, headers=headers, data=payload, stream=True), sleep_time=5)
135
+
180
136
  for line in response.iter_lines():
181
137
  if not line:
182
138
  continue
183
-
139
+
184
140
  line = line.decode('utf-8')
185
141
  if not line.startswith("data: "):
186
142
  continue
187
-
143
+
188
144
  try:
189
145
  data = json.loads(line[6:])
190
146
  if data.get("event") == "resp":
@@ -195,19 +151,18 @@ class KimiModel(BasePlatform):
195
151
  return False
196
152
  except json.JSONDecodeError:
197
153
  continue
198
-
154
+
199
155
  retry_count += 1
200
156
  time.sleep(1)
201
-
157
+
202
158
  return False
203
-
204
159
  def upload_files(self, file_list: List[str]) -> List[Dict]:
205
160
  """上传文件列表并返回文件信息"""
206
161
  if not file_list:
207
162
  return []
208
163
 
209
164
  PrettyOutput.print("Progress: 开始处理文件上传...", OutputType.PROGRESS)
210
-
165
+
211
166
  if not self.chat_id:
212
167
  PrettyOutput.print("创建新的对话会话...", OutputType.PROGRESS)
213
168
  if not self._create_chat():
@@ -216,24 +171,21 @@ class KimiModel(BasePlatform):
216
171
  uploaded_files = []
217
172
  for index, file_path in enumerate(file_list, 1):
218
173
  try:
219
- PrettyOutput.print(
220
- f"处理文件 [{index}/{len(file_list)}]: {file_path}", OutputType.PROGRESS)
174
+ PrettyOutput.print(f"处理文件 [{index}/{len(file_list)}]: {file_path}", OutputType.PROGRESS)
221
175
 
222
176
  mime_type, _ = mimetypes.guess_type(file_path)
223
- action = "image" if mime_type and mime_type.startswith(
224
- 'image/') else "file"
225
-
177
+ action = "image" if mime_type and mime_type.startswith('image/') else "file"
178
+
226
179
  # 获取预签名URL
227
180
  PrettyOutput.print("获取上传URL...", OutputType.PROGRESS)
228
181
  presigned_data = self._get_presigned_url(file_path, action)
229
-
182
+
230
183
  # 上传文件
231
184
  PrettyOutput.print("上传文件内容...", OutputType.PROGRESS)
232
185
  if self._upload_file(file_path, presigned_data["url"]):
233
186
  # 获取文件信息
234
187
  PrettyOutput.print("获取文件信息...", OutputType.PROGRESS)
235
- file_info = self._get_file_info(
236
- presigned_data, os.path.basename(file_path), action)
188
+ file_info = self._get_file_info(presigned_data, os.path.basename(file_path), action)
237
189
  # 等待文件解析
238
190
  PrettyOutput.print("等待文件解析完成...", OutputType.PROGRESS)
239
191
 
@@ -241,31 +193,24 @@ class KimiModel(BasePlatform):
241
193
  if action == "file":
242
194
  if self._wait_for_parse(file_info["id"]):
243
195
  uploaded_files.append(file_info)
244
- PrettyOutput.print(
245
- f"Success: 文件处理成功: {file_path}", OutputType.SUCCESS)
196
+ PrettyOutput.print(f"Success: 文件处理成功: {file_path}", OutputType.SUCCESS)
246
197
  else:
247
- PrettyOutput.print(
248
- f"✗ 文件解析失败: {file_path}", OutputType.ERROR)
198
+ PrettyOutput.print(f"✗ 文件解析失败: {file_path}", OutputType.ERROR)
249
199
  else:
250
200
  uploaded_files.append(file_info)
251
- PrettyOutput.print(
252
- f"Success: 文件处理成功: {file_path}", OutputType.SUCCESS)
201
+ PrettyOutput.print(f"Success: 文件处理成功: {file_path}", OutputType.SUCCESS)
253
202
  else:
254
- PrettyOutput.print(
255
- f"Error: 文件上传失败: {file_path}", OutputType.ERROR)
256
-
203
+ PrettyOutput.print(f"Error: 文件上传失败: {file_path}", OutputType.ERROR)
204
+
257
205
  except Exception as e:
258
- PrettyOutput.print(
259
- f"✗ 处理文件出错 {file_path}: {
260
- str(e)}", OutputType.ERROR)
206
+ PrettyOutput.print(f"✗ 处理文件出错 {file_path}: {str(e)}", OutputType.ERROR)
261
207
  continue
262
-
208
+
263
209
  if uploaded_files:
264
- PrettyOutput.print(
265
- f"成功处理 {len(uploaded_files)}/{len(file_list)} 个文件", OutputType.SUCCESS)
210
+ PrettyOutput.print(f"成功处理 {len(uploaded_files)}/{len(file_list)} 个文件", OutputType.SUCCESS)
266
211
  else:
267
212
  PrettyOutput.print("没有文件成功处理", OutputType.ERROR)
268
-
213
+
269
214
  self.uploaded_files = uploaded_files
270
215
  return uploaded_files
271
216
 
@@ -276,21 +221,19 @@ class KimiModel(BasePlatform):
276
221
  if not self._create_chat():
277
222
  raise Exception("Failed to create chat session")
278
223
 
279
- url = f"https://kimi.moonshot.cn/api/chat/{
280
- self.chat_id}/completion/stream"
281
-
224
+ url = f"https://kimi.moonshot.cn/api/chat/{self.chat_id}/completion/stream"
225
+
282
226
  # 只在第一次对话时带上文件引用
283
227
  refs = []
284
228
  refs_file = []
285
229
  if self.first_chat:
286
230
  if self.uploaded_files:
287
- PrettyOutput.print(
288
- f"首次对话,引用 {len(self.uploaded_files)} 个文件...", OutputType.PROGRESS)
231
+ PrettyOutput.print(f"首次对话,引用 {len(self.uploaded_files)} 个文件...", OutputType.PROGRESS)
289
232
  refs = [f["id"] for f in self.uploaded_files]
290
233
  refs_file = self.uploaded_files
291
234
  message = self.system_message + "\n" + message
292
235
  self.first_chat = False
293
-
236
+
294
237
  PrettyOutput.print("发送请求...", OutputType.PROGRESS)
295
238
  payload = {
296
239
  "messages": [{"role": "user", "content": message}],
@@ -309,39 +252,33 @@ class KimiModel(BasePlatform):
309
252
  }
310
253
 
311
254
  try:
312
- response = while_success(
313
- lambda: requests.post(
314
- url,
315
- headers=headers,
316
- json=payload,
317
- stream=True),
318
- sleep_time=5)
255
+ response = while_success(lambda: requests.post(url, headers=headers, json=payload, stream=True), sleep_time=5)
319
256
  full_response = ""
320
-
257
+
321
258
  # 收集搜索和引用结果
322
259
  search_results = []
323
260
  ref_sources = []
324
-
261
+
325
262
  PrettyOutput.print("接收响应...", OutputType.PROGRESS)
326
263
  for line in response.iter_lines():
327
264
  if not line:
328
265
  continue
329
-
266
+
330
267
  line = line.decode('utf-8')
331
268
  if not line.startswith("data: "):
332
269
  continue
333
-
270
+
334
271
  try:
335
272
  data = json.loads(line[6:])
336
273
  event = data.get("event")
337
-
274
+
338
275
  if event == "cmpl":
339
276
  # 处理补全文本
340
277
  text = data.get("text", "")
341
278
  if text:
342
279
  PrettyOutput.print_stream(text)
343
280
  full_response += text
344
-
281
+
345
282
  elif event == "search_plus":
346
283
  # 收集搜索结果
347
284
  msg = data.get("msg", {})
@@ -354,7 +291,7 @@ class KimiModel(BasePlatform):
354
291
  "type": msg.get("type", ""),
355
292
  "url": msg.get("url", "")
356
293
  })
357
-
294
+
358
295
  elif event == "ref_docs":
359
296
  # 收集引用来源
360
297
  ref_cards = data.get("ref_cards", [])
@@ -370,75 +307,52 @@ class KimiModel(BasePlatform):
370
307
  "rag_segments": card.get("rag_segments", []),
371
308
  "origin": card.get("origin", {})
372
309
  })
373
-
310
+
374
311
  except json.JSONDecodeError:
375
312
  continue
376
-
313
+
377
314
  PrettyOutput.print_stream_end()
315
+
378
316
 
379
317
  # 显示搜索结果摘要
380
318
  if search_results:
381
319
  PrettyOutput.print("\n搜索结果:", OutputType.PROGRESS)
382
320
  for result in search_results:
383
- PrettyOutput.print(
384
- f"- {result['title']}", OutputType.PROGRESS)
321
+ PrettyOutput.print(f"- {result['title']}", OutputType.PROGRESS)
385
322
  if result['date']:
386
- PrettyOutput.print(
387
- f" 日期: {
388
- result['date']}",
389
- OutputType.PROGRESS)
390
- PrettyOutput.print(
391
- f" 来源: {
392
- result['site_name']}",
393
- OutputType.PROGRESS)
323
+ PrettyOutput.print(f" 日期: {result['date']}", OutputType.PROGRESS)
324
+ PrettyOutput.print(f" 来源: {result['site_name']}", OutputType.PROGRESS)
394
325
  if result['snippet']:
395
- PrettyOutput.print(
396
- f" 摘要: {
397
- result['snippet']}",
398
- OutputType.PROGRESS)
399
- PrettyOutput.print(
400
- f" 链接: {
401
- result['url']}",
402
- OutputType.PROGRESS)
326
+ PrettyOutput.print(f" 摘要: {result['snippet']}", OutputType.PROGRESS)
327
+ PrettyOutput.print(f" 链接: {result['url']}", OutputType.PROGRESS)
403
328
  PrettyOutput.print("", OutputType.PROGRESS)
404
-
329
+
405
330
  # 显示引用来源
406
331
  if ref_sources:
407
332
  PrettyOutput.print("\n引用来源:", OutputType.PROGRESS)
408
333
  for source in ref_sources:
409
- PrettyOutput.print(
410
- f"- [{source['ref_id']}] {source['title']} ({source['source']})", OutputType.PROGRESS)
411
- PrettyOutput.print(
412
- f" 链接: {
413
- source['url']}",
414
- OutputType.PROGRESS)
334
+ PrettyOutput.print(f"- [{source['ref_id']}] {source['title']} ({source['source']})", OutputType.PROGRESS)
335
+ PrettyOutput.print(f" 链接: {source['url']}", OutputType.PROGRESS)
415
336
  if source['abstract']:
416
- PrettyOutput.print(
417
- f" 摘要: {
418
- source['abstract']}",
419
- OutputType.PROGRESS)
420
-
337
+ PrettyOutput.print(f" 摘要: {source['abstract']}", OutputType.PROGRESS)
338
+
421
339
  # 显示相关段落
422
340
  if source['rag_segments']:
423
341
  PrettyOutput.print(" 相关段落:", OutputType.PROGRESS)
424
342
  for segment in source['rag_segments']:
425
- text = segment.get(
426
- 'text', '').replace(
427
- '\n', ' ').strip()
343
+ text = segment.get('text', '').replace('\n', ' ').strip()
428
344
  if text:
429
- PrettyOutput.print(
430
- f" - {text}", OutputType.PROGRESS)
431
-
345
+ PrettyOutput.print(f" - {text}", OutputType.PROGRESS)
346
+
432
347
  # 显示原文引用
433
348
  origin = source['origin']
434
349
  if origin:
435
350
  text = origin.get('text', '')
436
351
  if text:
437
- PrettyOutput.print(
438
- f" 原文: {text}", OutputType.PROGRESS)
439
-
352
+ PrettyOutput.print(f" 原文: {text}", OutputType.PROGRESS)
353
+
440
354
  PrettyOutput.print("", OutputType.PROGRESS)
441
-
355
+
442
356
  return full_response
443
357
 
444
358
  except Exception as e:
@@ -448,26 +362,21 @@ class KimiModel(BasePlatform):
448
362
  """删除当前会话"""
449
363
  if not self.chat_id:
450
364
  return True # 如果没有会话ID,视为删除成功
451
-
365
+
452
366
  url = f"https://kimi.moonshot.cn/api/chat/{self.chat_id}"
453
367
  headers = {
454
368
  'Authorization': self.auth_header,
455
369
  'Content-Type': 'application/json'
456
370
  }
457
-
371
+
458
372
  try:
459
- response = while_success(
460
- lambda: requests.delete(
461
- url, headers=headers), sleep_time=5)
373
+ response = while_success(lambda: requests.delete(url, headers=headers), sleep_time=5)
462
374
  if response.status_code == 200:
463
375
  PrettyOutput.print("会话已删除", OutputType.SUCCESS)
464
376
  self.reset()
465
377
  return True
466
378
  else:
467
- PrettyOutput.print(
468
- f"删除会话失败: HTTP {
469
- response.status_code}",
470
- OutputType.ERROR)
379
+ PrettyOutput.print(f"删除会话失败: HTTP {response.status_code}", OutputType.ERROR)
471
380
  return False
472
381
  except Exception as e:
473
382
  PrettyOutput.print(f"删除会话时发生错误: {str(e)}", OutputType.ERROR)
jarvis/models/openai.py CHANGED
@@ -4,12 +4,11 @@ from openai import OpenAI
4
4
  from jarvis.models.base import BasePlatform
5
5
  from jarvis.utils import PrettyOutput, OutputType
6
6
 
7
-
8
7
  class OpenAIModel(BasePlatform):
9
8
  """DeepSeek模型实现"""
10
9
 
11
10
  platform_name = "openai"
12
-
11
+
13
12
  def __init__(self):
14
13
  """
15
14
  初始化DeepSeek模型
@@ -18,39 +17,23 @@ class OpenAIModel(BasePlatform):
18
17
  if not self.api_key:
19
18
  PrettyOutput.print("\n需要设置以下环境变量才能使用 OpenAI 模型:", OutputType.INFO)
20
19
  PrettyOutput.print(" • OPENAI_API_KEY: API 密钥", OutputType.INFO)
21
- PrettyOutput.print(
22
- " • OPENAI_API_BASE: (可选) API 基础地址,默认使用 https://api.deepseek.com",
23
- OutputType.INFO)
20
+ PrettyOutput.print(" • OPENAI_API_BASE: (可选) API 基础地址,默认使用 https://api.deepseek.com", OutputType.INFO)
24
21
  PrettyOutput.print("\n可以通过以下方式设置:", OutputType.INFO)
25
22
  PrettyOutput.print("1. 创建或编辑 ~/.jarvis_env 文件:", OutputType.INFO)
26
- PrettyOutput.print(
27
- " OPENAI_API_KEY=your_api_key",
28
- OutputType.INFO)
29
- PrettyOutput.print(
30
- " OPENAI_API_BASE=your_api_base",
31
- OutputType.INFO)
32
- PrettyOutput.print(
33
- " OPENAI_MODEL_NAME=your_model_name",
34
- OutputType.INFO)
23
+ PrettyOutput.print(" OPENAI_API_KEY=your_api_key", OutputType.INFO)
24
+ PrettyOutput.print(" OPENAI_API_BASE=your_api_base", OutputType.INFO)
25
+ PrettyOutput.print(" OPENAI_MODEL_NAME=your_model_name", OutputType.INFO)
35
26
  PrettyOutput.print("\n2. 或者直接设置环境变量:", OutputType.INFO)
36
- PrettyOutput.print(
37
- " export OPENAI_API_KEY=your_api_key",
38
- OutputType.INFO)
39
- PrettyOutput.print(
40
- " export OPENAI_API_BASE=your_api_base",
41
- OutputType.INFO)
42
- PrettyOutput.print(
43
- " export OPENAI_MODEL_NAME=your_model_name",
44
- OutputType.INFO)
27
+ PrettyOutput.print(" export OPENAI_API_KEY=your_api_key", OutputType.INFO)
28
+ PrettyOutput.print(" export OPENAI_API_BASE=your_api_base", OutputType.INFO)
29
+ PrettyOutput.print(" export OPENAI_MODEL_NAME=your_model_name", OutputType.INFO)
45
30
  raise Exception("OPENAI_API_KEY is not set")
46
-
47
- self.base_url = os.getenv(
48
- "OPENAI_API_BASE",
49
- "https://api.deepseek.com")
31
+
32
+ self.base_url = os.getenv("OPENAI_API_BASE", "https://api.deepseek.com")
50
33
  self.model_name = os.getenv("OPENAI_MODEL_NAME", "deepseek-chat")
51
34
 
52
35
  PrettyOutput.print(f"当前使用模型: {self.model_name}", OutputType.SYSTEM)
53
-
36
+
54
37
  self.client = OpenAI(
55
38
  api_key=self.api_key,
56
39
  base_url=self.base_url
@@ -65,40 +48,38 @@ class OpenAIModel(BasePlatform):
65
48
  def set_system_message(self, message: str):
66
49
  """设置系统消息"""
67
50
  self.system_message = message
68
- self.messages.append(
69
- {"role": "system", "content": self.system_message})
51
+ self.messages.append({"role": "system", "content": self.system_message})
70
52
 
71
53
  def chat(self, message: str) -> str:
72
54
  """执行对话"""
73
55
  try:
74
56
  PrettyOutput.print("发送请求...", OutputType.PROGRESS)
75
-
57
+
76
58
  # 添加用户消息到历史记录
77
59
  self.messages.append({"role": "user", "content": message})
78
-
60
+
79
61
  response = self.client.chat.completions.create(
80
62
  model=self.model_name, # 使用配置的模型名称
81
63
  messages=self.messages,
82
64
  stream=True
83
65
  )
84
-
66
+
85
67
  PrettyOutput.print("接收响应...", OutputType.PROGRESS)
86
68
  full_response = ""
87
-
69
+
88
70
  for chunk in response:
89
71
  if chunk.choices[0].delta.content:
90
72
  text = chunk.choices[0].delta.content
91
73
  PrettyOutput.print_stream(text)
92
74
  full_response += text
93
-
75
+
94
76
  PrettyOutput.print_stream_end()
95
-
77
+
96
78
  # 添加助手回复到历史记录
97
- self.messages.append(
98
- {"role": "assistant", "content": full_response})
99
-
79
+ self.messages.append({"role": "assistant", "content": full_response})
80
+
100
81
  return full_response
101
-
82
+
102
83
  except Exception as e:
103
84
  PrettyOutput.print(f"对话失败: {str(e)}", OutputType.ERROR)
104
85
  raise Exception(f"Chat failed: {str(e)}")
@@ -111,12 +92,11 @@ class OpenAIModel(BasePlatform):
111
92
  """重置模型状态"""
112
93
  # 清空对话历史,只保留system message
113
94
  if self.system_message:
114
- self.messages = [
115
- {"role": "system", "content": self.system_message}]
95
+ self.messages = [{"role": "system", "content": self.system_message}]
116
96
  else:
117
97
  self.messages = []
118
98
 
119
- def delete_chat(self) -> bool:
99
+ def delete_chat(self)->bool:
120
100
  """删除对话"""
121
101
  self.reset()
122
102
  return True