fix: 数字人 text 通道剥离 think 标签内容

__send_digital_human_message 在 say() 中先于 think 状态机被调用,导致 <think>...</think>
原样泄露到 10002 端口的 text 通道;audio 通道虽被状态机拦截但 text 不对称。
新增 __remove_think_tags 处理完整/未闭合/孤立闭合三种流式分片场景,使 prestart
与 think 在数字人接口上保持对称剥离。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
guo zebin
2026-04-10 17:47:35 +08:00
parent 4e4682c190
commit 3638c7b4b6
+27 -1
View File
@@ -2568,6 +2568,30 @@ class FeiFei:
return cleaned.strip()
def __remove_think_tags(self, text):
"""
移除文本中的 think 标签及其内容(含未闭合的流式分片)
:param text: 原始文本
:return: 移除 think 标签后的文本
"""
if not text:
return text
# 1. 先剥离完整的 <think>...</think>
cleaned = re.sub(r'<think[^>]*>[\s\S]*?</think>', '', text, flags=re.IGNORECASE)
# 2. 处理流式分片中孤立的 </think> —— 取最后一个 </think> 之后的内容
if re.search(r'</think>', cleaned, flags=re.IGNORECASE):
cleaned = re.split(r'</think>', cleaned, flags=re.IGNORECASE)[-1]
# 3. 处理流式分片中未闭合的 <think>... —— 截断该位置之后的内容
if re.search(r'<think[^>]*>', cleaned, flags=re.IGNORECASE):
cleaned = re.split(r'<think[^>]*>', cleaned, flags=re.IGNORECASE)[0]
return cleaned.strip()
def __has_prestart(self, text):
@@ -2901,11 +2925,13 @@ class FeiFei:
# 从原始文本中提取 markdown 图片 URL(在清理前提取)
image_urls = re.findall(r'!\[.*?\]\((https?://[^\s\)]+)\)', text or "")
# 移除 prestart 标签内容,不发送给数字人
# 移除 prestart 与 think 标签内容,不发送给数字人
cleaned_text = self.__remove_prestart_tags(text) if text else ""
cleaned_text = self.__remove_think_tags(cleaned_text) if cleaned_text else ""
full_text = self.__remove_emojis(cleaned_text.replace("*", "")) if cleaned_text else ""