Skip to content

Commit 64e0183

Browse files
fix: drop Groq reasoning_content from assistant history (#6065)
Co-authored-by: Stable Genius <259448942+stablegenius49@users.noreply.github.com>
1 parent 420d82d commit 64e0183

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

astrbot/core/provider/sources/groq_source.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,11 @@ def __init__(
1313
) -> None:
1414
super().__init__(provider_config, provider_settings)
1515
self.reasoning_key = "reasoning"
16+
17+
def _finally_convert_payload(self, payloads: dict) -> None:
18+
"""Groq rejects assistant history items that include reasoning_content."""
19+
super()._finally_convert_payload(payloads)
20+
for message in payloads.get("messages", []):
21+
if message.get("role") == "assistant":
22+
message.pop("reasoning_content", None)
23+
message.pop("reasoning", None)

tests/test_openai_source.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44

5+
from astrbot.core.provider.sources.groq_source import ProviderGroq
56
from astrbot.core.provider.sources.openai_source import ProviderOpenAIOfficial
67

78

@@ -32,6 +33,21 @@ def _make_provider(overrides: dict | None = None) -> ProviderOpenAIOfficial:
3233
)
3334

3435

36+
def _make_groq_provider(overrides: dict | None = None) -> ProviderGroq:
37+
provider_config = {
38+
"id": "test-groq",
39+
"type": "groq_chat_completion",
40+
"model": "qwen/qwen3-32b",
41+
"key": ["test-key"],
42+
}
43+
if overrides:
44+
provider_config.update(overrides)
45+
return ProviderGroq(
46+
provider_config=provider_config,
47+
provider_settings={},
48+
)
49+
50+
3551
@pytest.mark.asyncio
3652
async def test_handle_api_error_content_moderated_removes_images():
3753
provider = _make_provider(
@@ -198,6 +214,57 @@ def test_extract_error_text_candidates_truncates_long_response_text():
198214
)
199215

200216

217+
@pytest.mark.asyncio
218+
async def test_openai_payload_keeps_reasoning_content_in_assistant_history():
219+
provider = _make_provider()
220+
try:
221+
payloads = {
222+
"messages": [
223+
{
224+
"role": "assistant",
225+
"content": [
226+
{"type": "think", "think": "step 1"},
227+
{"type": "text", "text": "final answer"},
228+
],
229+
}
230+
]
231+
}
232+
233+
provider._finally_convert_payload(payloads)
234+
235+
assistant_message = payloads["messages"][0]
236+
assert assistant_message["content"] == [{"type": "text", "text": "final answer"}]
237+
assert assistant_message["reasoning_content"] == "step 1"
238+
finally:
239+
await provider.terminate()
240+
241+
242+
@pytest.mark.asyncio
243+
async def test_groq_payload_drops_reasoning_content_from_assistant_history():
244+
provider = _make_groq_provider()
245+
try:
246+
payloads = {
247+
"messages": [
248+
{
249+
"role": "assistant",
250+
"content": [
251+
{"type": "think", "think": "step 1"},
252+
{"type": "text", "text": "final answer"},
253+
],
254+
}
255+
]
256+
}
257+
258+
provider._finally_convert_payload(payloads)
259+
260+
assistant_message = payloads["messages"][0]
261+
assert assistant_message["content"] == [{"type": "text", "text": "final answer"}]
262+
assert "reasoning_content" not in assistant_message
263+
assert "reasoning" not in assistant_message
264+
finally:
265+
await provider.terminate()
266+
267+
201268
@pytest.mark.asyncio
202269
async def test_handle_api_error_content_moderated_without_images_raises():
203270
provider = _make_provider(

0 commit comments

Comments
 (0)