fix(openai): Adapt content format for third-party LLM like MindIE#9337
fix(openai): Adapt content format for third-party LLM like MindIE#9337dourylee wants to merge 2 commits into
Conversation
Fix 422 Input Validation Error when connecting MindIE and other third-party LLM services: 1. Convert messages.content array format to plain text string 2. Fill empty content with placeholder to avoid input check failure Adapt for MindIE LLM inference framework and Qwen3-30B-A3B-w8a8 model.
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The content normalization logic is duplicated in both
_queryand_query_stream; consider extracting it into a shared helper to keep behavior consistent and easier to maintain. - Currently all models go through the MindIE-oriented content flattening and placeholder logic; you might want to gate this behavior based on model/provider configuration to avoid altering content for providers that support the array format.
- Using a single space as a placeholder for empty content is a bit opaque; consider defining a named constant or configurable placeholder so the intent is clearer and easier to adjust if MindIE’s validation rules change.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The content normalization logic is duplicated in both `_query` and `_query_stream`; consider extracting it into a shared helper to keep behavior consistent and easier to maintain.
- Currently all models go through the MindIE-oriented content flattening and placeholder logic; you might want to gate this behavior based on model/provider configuration to avoid altering content for providers that support the array format.
- Using a single space as a placeholder for empty content is a bit opaque; consider defining a named constant or configurable placeholder so the intent is clearer and easier to adjust if MindIE’s validation rules change.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request introduces payload adaptation logic in both the _query and _query_stream methods of openai_source.py to handle third-party LLM services (such as MindIE) that do not support content arrays or empty content. The review feedback highlights that this implementation introduces duplicated code and lacks defensive type checking. It is recommended to refactor this logic into a shared helper method and add type checks to prevent potential runtime errors.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| # 修复第三方LLM服务(MindIE等)不支持content数组、空content导致422校验失败 | ||
| for msg in payloads.get("messages", []): | ||
| if isinstance(msg.get("content"), list): | ||
| # 拼接数组内所有文本内容 | ||
| texts = [block.get("text", "") for block in msg["content"] if block.get("type") == "text"] | ||
| msg["content"] = " ".join(texts) if texts else " " | ||
| # 空内容填充占位符,避免输入校验失败 | ||
| if not msg.get("content"): | ||
| msg["content"] = " " |
There was a problem hiding this comment.
问题与改进建议
-
代码重复 (Code Duplication):
在_query和_query_stream中,完全相同的消息格式适配逻辑被重复编写了两次。根据通用规则,应当将此类相似逻辑重构为共享的辅助函数/方法,以提高代码的可维护性并避免重复。 -
防御性编程 (Defensive Programming):
当前代码直接调用了msg.get("content")和block.get("text"),但没有预先校验msg或block是否为字典类型(dict)。如果messages列表中包含非字典类型的元素,或者content列表内包含非字典类型的元素,程序将会抛出AttributeError异常。
重构方案
建议在 ProviderOpenAIOfficial 类中添加一个私有辅助方法 _adapt_messages_for_third_party,并在 _query 和 _query_stream 中调用它。
请在类中添加如下辅助方法:
def _adapt_messages_for_third_party(self, payloads: dict) -> None:
# 修复第三方LLM服务(MindIE等)不支持content数组、空content导致422校验失败
for msg in payloads.get("messages", []):
if not isinstance(msg, dict):
continue
content = msg.get("content")
if isinstance(content, list):
# 拼接数组内所有文本内容
texts = [
block.get("text", "")
for block in content
if isinstance(block, dict) and block.get("type") == "text"
]
msg["content"] = " ".join(texts) if texts else " "
# 空内容填充占位符,避免输入校验失败
if not msg.get("content"):
msg["content"] = " "| # 修复第三方LLM服务(MindIE等)不支持content数组、空content导致422校验失败 | |
| for msg in payloads.get("messages", []): | |
| if isinstance(msg.get("content"), list): | |
| # 拼接数组内所有文本内容 | |
| texts = [block.get("text", "") for block in msg["content"] if block.get("type") == "text"] | |
| msg["content"] = " ".join(texts) if texts else " " | |
| # 空内容填充占位符,避免输入校验失败 | |
| if not msg.get("content"): | |
| msg["content"] = " " | |
| self._adapt_messages_for_third_party(payloads) |
References
- When implementing similar functionality for different cases, refactor the logic into a shared helper function to avoid code duplication.
| # 修复第三方LLM服务(MindIE等)不支持content数组、空content导致422校验失败 | ||
| for msg in payloads.get("messages", []): | ||
| if isinstance(msg.get("content"), list): | ||
| # 拼接数组内所有文本内容 | ||
| texts = [block.get("text", "") for block in msg["content"] if block.get("type") == "text"] | ||
| msg["content"] = " ".join(texts) if texts else " " | ||
| # 空内容填充占位符,避免输入校验失败 | ||
| if not msg.get("content"): | ||
| msg["content"] = " " |
There was a problem hiding this comment.
代码重复与重构建议
此处的逻辑与 _query 中的消息适配逻辑完全相同。建议将其重构为共享的辅助方法 _adapt_messages_for_third_party,以消除重复代码并增强防御性校验。具体重构方案和辅助方法实现请参考 _query 方法中的评审意见。
| # 修复第三方LLM服务(MindIE等)不支持content数组、空content导致422校验失败 | |
| for msg in payloads.get("messages", []): | |
| if isinstance(msg.get("content"), list): | |
| # 拼接数组内所有文本内容 | |
| texts = [block.get("text", "") for block in msg["content"] if block.get("type") == "text"] | |
| msg["content"] = " ".join(texts) if texts else " " | |
| # 空内容填充占位符,避免输入校验失败 | |
| if not msg.get("content"): | |
| msg["content"] = " " | |
| self._adapt_messages_for_third_party(payloads) |
References
- When implementing similar functionality for different cases, refactor the logic into a shared helper function to avoid code duplication.
…tional enable 1 Extract duplicated content convert logic into _adapt_messages_for_third_party shared method 2 Add full isinstance type check to avoid AttributeError 3 Define EMPTY_CONTENT_PLACEHOLDER constant instead magic space 4 Only enable format adapt for non-official OpenAI endpoints, keep native multi-modal support Fix MindIE 422 validation error without breaking original OpenAI functionality
|
Refactored as requested: |
Fix 422 Input Validation Error when connecting MindIE and other third-party LLM services:
问题描述
When connecting AstrBot to third-party LLM services based on MindIE framework (e.g. Qwen3-30B-A3B-w8a8 model),
the interface returns 422 Input Validation Error.
Root cause:
messages.contentas array format, but MindIE only supports string content.contentwill trigger input text check failure on MindIE.修复方案
contentarray to plain text string by extracting alltextblocks.测试情况
Tested with MindIE + Qwen3-30B-A3B-w8a8 model:
Summary by Sourcery
Bug Fixes: