From b30cb12133963edd0c527c4dc8773e8591ccd17b Mon Sep 17 00:00:00 2001 From: NayukiMeko Date: Fri, 20 Feb 2026 13:48:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(provider):=20=E4=BF=AE=E5=A4=8D=20dict=20?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=20content=20=E5=AF=BC=E8=87=B4=E7=9A=84=20JS?= =?UTF-8?q?ON=20=E6=AE=8B=E7=95=99=E9=97=AE=E9=A2=98=20(#5250)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(provider): 修复 dict 格式 content 导致的 JSON 残留问题 修复 _normalize_content 函数未处理 dict 类型 content 的问题。 当 LLM 返回 {"type": "text", "text": "..."} 格式的 content 时, 现在会正确提取 text 字段而非直接转为字符串。 同时改进 fallback 行为,对 None 值返回空字符串。 Fixes #5244 * Update warning message for unexpected dict format --------- Co-authored-by: Soulter <37870767+Soulter@users.noreply.github.com> --- astrbot/core/provider/sources/openai_source.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/astrbot/core/provider/sources/openai_source.py b/astrbot/core/provider/sources/openai_source.py index 5378385e5..adee24073 100644 --- a/astrbot/core/provider/sources/openai_source.py +++ b/astrbot/core/provider/sources/openai_source.py @@ -381,13 +381,22 @@ class ProviderOpenAIOfficial(Provider): plain string. This method handles both formats. Args: - raw_content: The raw content from LLM response, can be str, list, or other. + raw_content: The raw content from LLM response, can be str, list, dict, or other. strip: Whether to strip whitespace from the result. Set to False for streaming chunks to preserve spaces between words. Returns: Normalized plain text string. """ + # Handle dict format (e.g., {"type": "text", "text": "..."}) + if isinstance(raw_content, dict): + if "text" in raw_content: + text_val = raw_content.get("text", "") + return str(text_val) if text_val is not None else "" + # For other dict formats, return empty string and log + logger.warning(f"Unexpected dict format content: {raw_content}") + return "" + if isinstance(raw_content, list): # Check if this looks like OpenAI content-part format # Only process if at least one item has {'type': 'text', 'text': ...} structure @@ -450,7 +459,8 @@ class ProviderOpenAIOfficial(Provider): return "".join(text_parts) return content - return str(raw_content) + # Fallback for other types (int, float, etc.) + return str(raw_content) if raw_content is not None else "" async def _parse_openai_completion( self, completion: ChatCompletion, tools: ToolSet | None