Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions astrbot/core/provider/sources/openai_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,28 @@
)
class ProviderOpenAIOfficial(Provider):
_ERROR_TEXT_CANDIDATE_MAX_CHARS = 4096
# 空内容占位常量,方便统一修改
EMPTY_CONTENT_PLACEHOLDER = " "

# 新增:统一转换消息格式,带完整类型防御
def _adapt_messages_for_third_party(self, payloads: dict) -> None:
messages = payloads.get("messages", [])
for msg in messages:
# 过滤非字典消息,防止 .get 报错
if not isinstance(msg, dict):
continue
content = msg.get("content")
# 处理多模态数组content
if isinstance(content, list):
text_parts = []
for block in content:
# 仅处理标准text块,跳过图片/音频等
if isinstance(block, dict) and block.get("type") == "text":
text_parts.append(block.get("text", ""))
msg["content"] = " ".join(text_parts) if text_parts else self.EMPTY_CONTENT_PLACEHOLDER
# 空内容填充占位符
if not content:
msg["content"] = self.EMPTY_CONTENT_PLACEHOLDER

@classmethod
def _truncate_error_text_candidate(cls, text: str) -> str:
Expand Down Expand Up @@ -535,6 +557,11 @@ async def _query(
*,
request_max_retries: int | None = None,
) -> LLMResponse:
# 仅非原生OpenAI服务执行格式适配(MindIE、国产推理等)
base_url = self.client.base_url.host or ""
if "openai.com" not in base_url:
self._adapt_messages_for_third_party(payloads)

if tools:
model = payloads.get("model", "").lower()
omit_empty_param_field = "gemini" in model
Expand Down Expand Up @@ -593,6 +620,11 @@ async def _query_stream(
*,
request_max_retries: int | None = None,
) -> AsyncGenerator[LLMResponse, None]:
# 仅非原生OpenAI服务执行格式适配(MindIE、国产推理等)
base_url = self.client.base_url.host or ""
if "openai.com" not in base_url:
self._adapt_messages_for_third_party(payloads)

"""流式查询API,逐步返回结果"""
if tools:
model = payloads.get("model", "").lower()
Expand Down