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/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