coo7 commited on
Commit
fec88c0
·
verified ·
1 Parent(s): cea506d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -12
app.py CHANGED
@@ -489,7 +489,7 @@ def list_models():
489
  app.logger.info("[list_models] 用户请求 /v1/models")
490
  models_list = [
491
  {
492
- "id": "DeepSeek-R1",
493
  "object": "model",
494
  "created": 1677610602,
495
  "owned_by": "deepseek",
@@ -503,14 +503,14 @@ def list_models():
503
  "permission": []
504
  },
505
  {
506
- "id": "DeepSeek-V3",
507
  "object": "model",
508
  "created": 1677610602,
509
  "owned_by": "deepseek",
510
  "permission": []
511
  },
512
  {
513
- "id": "deepseek-chat",
514
  "object": "model",
515
  "created": 1677610602,
516
  "owned_by": "deepseek",
@@ -525,8 +525,8 @@ def list_models():
525
  # ----------------------------------------------------------------------
526
  def messages_prepare(messages: list) -> str:
527
  """处理消息列表,合并连续相同角色的消息,并添加角色标签:
528
- - 对于 assistant 消息,加上 <|Assistant|> 前缀及 <|end▁of▁sentence|> 结束标签;
529
- - 对于 user/system 消息(除第一条外)加上 <|User|> 前缀;
530
  - 如果消息 content 为数组,则提取其中 type 为 "text" 的部分;
531
  - 最后移除 markdown 图片格式的内容。
532
  """
@@ -555,10 +555,10 @@ def messages_prepare(messages: list) -> str:
555
  role = block["role"]
556
  text = block["text"]
557
  if role == "assistant":
558
- parts.append(f"<|Assistant|>{text}<|end▁of▁sentence|>")
559
  elif role in ("user", "system"):
560
  if idx > 0:
561
- parts.append(f"<|User|>{text}")
562
  else:
563
  parts.append(text)
564
  else:
@@ -601,14 +601,23 @@ def chat_completions():
601
  if not model or not messages:
602
  return jsonify({"error": "Request must include 'model' and 'messages'."}), 400
603
 
604
- # 判断是否启用“思考”功能(这里根据模型名称判断)
605
  model_lower = model.lower()
606
  if model_lower in ["deepseek-v3", "deepseek-chat"]:
607
  thinking_enabled = False
 
608
  elif model_lower in ["deepseek-r1", "deepseek-reasoner"]:
609
  thinking_enabled = True
 
 
 
 
 
 
 
610
  else:
611
- return jsonify({"error": f"Model '{model}' is not available."}), 503
 
612
 
613
  # 使用 messages_prepare 函数构造最终 prompt
614
  final_prompt = messages_prepare(messages)
@@ -633,7 +642,7 @@ def chat_completions():
633
  "prompt": final_prompt,
634
  "ref_file_ids": [],
635
  "thinking_enabled": thinking_enabled,
636
- "search_enabled": False
637
  }
638
  app.logger.debug(f"[chat_completions] -> {DEEPSEEK_COMPLETION_URL}, payload={payload}")
639
 
@@ -657,6 +666,7 @@ def chat_completions():
657
  final_text = ""
658
  final_thinking = ""
659
  first_chunk_sent = False
 
660
  for raw_line in deepseek_resp.iter_lines(chunk_size=512):
661
  try:
662
  line = raw_line.decode("utf-8")
@@ -691,6 +701,12 @@ def chat_completions():
691
  try:
692
  chunk = json.loads(data_str)
693
  app.logger.debug(f"[sse_stream] 解析到 chunk: {chunk}")
 
 
 
 
 
 
694
  except Exception as e:
695
  app.logger.warning(f"[sse_stream] 无法解析: {data_str}, 错误: {e}")
696
  continue
@@ -699,6 +715,8 @@ def chat_completions():
699
  delta = choice.get("delta", {})
700
  ctype = delta.get("type")
701
  ctext = delta.get("content", "")
 
 
702
  if ctype == "thinking":
703
  if thinking_enabled:
704
  final_thinking += ctext
@@ -735,6 +753,7 @@ def chat_completions():
735
  # 非流式响应处理
736
  think_list = []
737
  text_list = []
 
738
  try:
739
  for raw_line in deepseek_resp.iter_lines(chunk_size=512):
740
  try:
@@ -751,16 +770,25 @@ def chat_completions():
751
  try:
752
  chunk = json.loads(data_str)
753
  app.logger.debug(f"[chat_completions] 非流式 chunk: {chunk}")
 
 
 
 
 
 
754
  except Exception as e:
755
  app.logger.warning(f"[chat_completions] 无法解析: {data_str}, 错误: {e}")
756
  continue
757
  for choice in chunk.get("choices", []):
758
  delta = choice.get("delta", {})
759
  ctype = delta.get("type")
 
 
 
760
  if ctype == "thinking" and thinking_enabled:
761
- think_list.append(delta.get("content", ""))
762
  elif ctype == "text":
763
- text_list.append(delta.get("content", ""))
764
  finally:
765
  deepseek_resp.close()
766
  final_reasoning = "".join(think_list)
 
489
  app.logger.info("[list_models] 用户请求 /v1/models")
490
  models_list = [
491
  {
492
+ "id": "deepseek-chat",
493
  "object": "model",
494
  "created": 1677610602,
495
  "owned_by": "deepseek",
 
503
  "permission": []
504
  },
505
  {
506
+ "id": "deepseek-chat-search",
507
  "object": "model",
508
  "created": 1677610602,
509
  "owned_by": "deepseek",
510
  "permission": []
511
  },
512
  {
513
+ "id": "deepseek-reasoner-search",
514
  "object": "model",
515
  "created": 1677610602,
516
  "owned_by": "deepseek",
 
525
  # ----------------------------------------------------------------------
526
  def messages_prepare(messages: list) -> str:
527
  """处理消息列表,合并连续相同角色的消息,并添加角色标签:
528
+ - 对于 assistant 消息,加上 <|Assistant|> 前缀及 结束标签;
529
+ - 对于 user/system 消息(除第一条外)加上 结束标签;
530
  - 如果消息 content 为数组,则提取其中 type 为 "text" 的部分;
531
  - 最后移除 markdown 图片格式的内容。
532
  """
 
555
  role = block["role"]
556
  text = block["text"]
557
  if role == "assistant":
558
+ parts.append(f"<|Assistant|>{text}")
559
  elif role in ("user", "system"):
560
  if idx > 0:
561
+ parts.append(f"结束标签")
562
  else:
563
  parts.append(text)
564
  else:
 
601
  if not model or not messages:
602
  return jsonify({"error": "Request must include 'model' and 'messages'."}), 400
603
 
604
+ # 判断是否启用"思考"功能(这里根据模型名称判断)
605
  model_lower = model.lower()
606
  if model_lower in ["deepseek-v3", "deepseek-chat"]:
607
  thinking_enabled = False
608
+ search_enabled = False
609
  elif model_lower in ["deepseek-r1", "deepseek-reasoner"]:
610
  thinking_enabled = True
611
+ search_enabled = False
612
+ elif model_lower in ["deepseek-v3-search", "deepseek-chat-search"]:
613
+ thinking_enabled = False
614
+ search_enabled = True
615
+ elif model_lower in ["deepseek-r1-search", "deepseek-reasoner-search"]:
616
+ thinking_enabled = True
617
+ search_enabled = True
618
  else:
619
+ return Response(json.dumps({"error": f"Model '{model}' is not available."}),
620
+ status=503, mimetype="application/json")
621
 
622
  # 使用 messages_prepare 函数构造最终 prompt
623
  final_prompt = messages_prepare(messages)
 
642
  "prompt": final_prompt,
643
  "ref_file_ids": [],
644
  "thinking_enabled": thinking_enabled,
645
+ "search_enabled": search_enabled
646
  }
647
  app.logger.debug(f"[chat_completions] -> {DEEPSEEK_COMPLETION_URL}, payload={payload}")
648
 
 
666
  final_text = ""
667
  final_thinking = ""
668
  first_chunk_sent = False
669
+ citation_map = {} # 用于存储引用链接的字典
670
  for raw_line in deepseek_resp.iter_lines(chunk_size=512):
671
  try:
672
  line = raw_line.decode("utf-8")
 
701
  try:
702
  chunk = json.loads(data_str)
703
  app.logger.debug(f"[sse_stream] 解析到 chunk: {chunk}")
704
+ # 处理搜索索引数据
705
+ if chunk.get("choices", [{}])[0].get("delta", {}).get("type") == "search_index":
706
+ search_indexes = chunk["choices"][0]["delta"].get("search_indexes", [])
707
+ for idx in search_indexes:
708
+ citation_map[str(idx.get("cite_index"))] = idx.get("url", "")
709
+ continue
710
  except Exception as e:
711
  app.logger.warning(f"[sse_stream] 无法解析: {data_str}, 错误: {e}")
712
  continue
 
715
  delta = choice.get("delta", {})
716
  ctype = delta.get("type")
717
  ctext = delta.get("content", "")
718
+ if search_enabled and ctext.startswith("[citation:"):
719
+ ctext = ""
720
  if ctype == "thinking":
721
  if thinking_enabled:
722
  final_thinking += ctext
 
753
  # 非流式响应处理
754
  think_list = []
755
  text_list = []
756
+ citation_map = {} # 用于存储引用链接的字典
757
  try:
758
  for raw_line in deepseek_resp.iter_lines(chunk_size=512):
759
  try:
 
770
  try:
771
  chunk = json.loads(data_str)
772
  app.logger.debug(f"[chat_completions] 非流式 chunk: {chunk}")
773
+ # 处理搜索索引数据
774
+ if chunk.get("choices", [{}])[0].get("delta", {}).get("type") == "search_index":
775
+ search_indexes = chunk["choices"][0]["delta"].get("search_indexes", [])
776
+ for idx in search_indexes:
777
+ citation_map[str(idx.get("cite_index"))] = idx.get("url", "")
778
+ continue
779
  except Exception as e:
780
  app.logger.warning(f"[chat_completions] 无法解析: {data_str}, 错误: {e}")
781
  continue
782
  for choice in chunk.get("choices", []):
783
  delta = choice.get("delta", {})
784
  ctype = delta.get("type")
785
+ ctext = delta.get("content", "")
786
+ if search_enabled and ctext.startswith("[citation:"):
787
+ ctext = ""
788
  if ctype == "thinking" and thinking_enabled:
789
+ think_list.append(ctext)
790
  elif ctype == "text":
791
+ text_list.append(ctext)
792
  finally:
793
  deepseek_resp.close()
794
  final_reasoning = "".join(think_list)