Skip to content

Commit a53a1ca

Browse files
JasonOA888Soulter
andauthored
fix(provider): handle MiniMax ThinkingBlock when max_tokens reached (AstrBotDevs#5913)
* fix(provider): handle MiniMax ThinkingBlock when max_tokens reached Fixes AstrBotDevs#5912 Problem: MiniMax API returns ThinkingBlock when stop_reason='max_tokens', but AstrBot throws 'completion 无法解析' exception because both completion_text and tools_call_args are empty. Root cause: The validation logic didn't consider ThinkingBlock (reasoning_content) as valid content. Fix: When completion_text and tools_call_args are empty but reasoning_content is present, treat it as valid instead of throwing exception. This happens when the model thinks but runs out of tokens before generating the actual response. Impact: MiniMax models now work correctly when responses are truncated due to max_tokens limit. * refactor: address review feedback 1. Use getattr for safe stop_reason access (prevent AttributeError) 2. Use ValueError instead of generic Exception for better error handling Thanks @gemini-code-assist and @sourcery-ai for the review! * refactor: flatten nested if/else with guard clause Address Gemini Code Assist feedback: - Use guard clause for early return - Flattened nested conditional for better readability Logic unchanged, just cleaner code structure. * fix(provider): improve logging for ThinkingBlock completions in ProviderAnthropic --------- Co-authored-by: Soulter <905617992@qq.com>
1 parent 3fd6c4c commit a53a1ca

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

astrbot/core/provider/sources/anthropic_source.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,24 @@ async def _query(self, payloads: dict, tools: ToolSet | None) -> LLMResponse:
276276
llm_response.id = completion.id
277277
llm_response.usage = self._extract_usage(completion.usage)
278278

279-
# TODO(Soulter): 处理 end_turn 情况
279+
# Handle cases where completion only contains ThinkingBlock (e.g., MiniMax max_tokens)
280+
# When stop_reason='max_tokens', the model may return only thinking content
281+
# This is valid and should not raise an exception
280282
if not llm_response.completion_text and not llm_response.tools_call_args:
281-
raise Exception(f"Anthropic API 返回的 completion 无法解析:{completion}。")
283+
# Guard clause: raise early if no valid content at all
284+
if not llm_response.reasoning_content:
285+
raise ValueError(
286+
f"Anthropic API returned unparsable completion: "
287+
f"no text, tool_use, or thinking content found. "
288+
f"Completion: {completion}"
289+
)
290+
291+
# We have reasoning content (ThinkingBlock) - this is valid
292+
stop_reason = getattr(completion, "stop_reason", "unknown")
293+
logger.debug(
294+
f"Completion contains only ThinkingBlock (stop_reason={stop_reason})"
295+
)
296+
llm_response.completion_text = "" # Ensure empty string, not None
282297

283298
return llm_response
284299

0 commit comments

Comments
 (0)