Skip to content

Commit d500f1b

Browse files
committed
fix(provider): forward extra user content in streams
1 parent 296427c commit d500f1b

3 files changed

Lines changed: 42 additions & 2 deletions

File tree

astrbot/core/provider/sources/openai_source.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,6 @@ def _apply_provider_specific_extra_body_overrides(
517517

518518
def _requires_tool_call_reasoning_content(
519519
self,
520-
payloads: dict,
521520
extra_body: dict[str, Any],
522521
) -> bool:
523522
thinking = extra_body.get("thinking")
@@ -534,7 +533,7 @@ def _ensure_tool_call_reasoning_content(
534533
payloads: dict,
535534
extra_body: dict[str, Any],
536535
) -> None:
537-
if not self._requires_tool_call_reasoning_content(payloads, extra_body):
536+
if not self._requires_tool_call_reasoning_content(extra_body):
538537
return
539538

540539
messages = payloads.get("messages")
@@ -1280,6 +1279,7 @@ async def text_chat_stream(
12801279
system_prompt=None,
12811280
tool_calls_result=None,
12821281
model=None,
1282+
extra_user_content_parts=None,
12831283
tool_choice: Literal["auto", "required"] = "auto",
12841284
**kwargs,
12851285
) -> AsyncGenerator[LLMResponse, None]:
@@ -1292,6 +1292,7 @@ async def text_chat_stream(
12921292
system_prompt,
12931293
tool_calls_result,
12941294
model=model,
1295+
extra_user_content_parts=extra_user_content_parts,
12951296
**kwargs,
12961297
)
12971298
if func_tool and not func_tool.empty():

astrbot/core/provider/sources/opencode_go_source.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ async def text_chat_stream(
132132
system_prompt: str | None = None,
133133
tool_calls_result: ToolCallsResult | list[ToolCallsResult] | None = None,
134134
model: str | None = None,
135+
extra_user_content_parts: list[ContentPart] | None = None,
135136
tool_choice: Literal["auto", "required"] = "auto",
136137
**kwargs,
137138
) -> AsyncGenerator[LLMResponse, None]:
@@ -145,6 +146,7 @@ async def text_chat_stream(
145146
system_prompt=system_prompt,
146147
tool_calls_result=tool_calls_result,
147148
model=self._resolve_model(model),
149+
extra_user_content_parts=extra_user_content_parts,
148150
tool_choice=tool_choice,
149151
**kwargs,
150152
):

tests/test_openai_source.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from PIL import Image as PILImage
99

1010
import astrbot.core.provider.sources.openai_source as openai_source_module
11+
from astrbot.core.agent.message import ContentPart, TextPart
1112
from astrbot.core.exceptions import EmptyModelOutputError
1213
from astrbot.core.provider.sources.groq_source import ProviderGroq
1314
from astrbot.core.provider.sources.openai_source import ProviderOpenAIOfficial
@@ -34,6 +35,15 @@ async def get_models(self) -> list[str]:
3435
return self._models
3536

3637

38+
class _OpenCodeGoDelegateStub:
39+
def __init__(self):
40+
self.stream_kwargs: dict[str, object] | None = None
41+
42+
async def text_chat_stream(self, **kwargs):
43+
self.stream_kwargs = kwargs
44+
yield SimpleNamespace(role="assistant")
45+
46+
3747
class _OpenCodeGoUnitProvider(ProviderOpenCodeGo):
3848
openai_provider: _ModelsProviderStub
3949

@@ -42,6 +52,14 @@ def __init__(self, models: list[str]):
4252
self.model_name = "kimi-k2.6"
4353

4454

55+
class _OpenCodeGoStreamUnitProvider(ProviderOpenCodeGo):
56+
openai_provider: _OpenCodeGoDelegateStub
57+
58+
def __init__(self, delegate: _OpenCodeGoDelegateStub):
59+
self.openai_provider = delegate
60+
self.model_name = "kimi-k2.6"
61+
62+
4563
def _make_provider(overrides: dict | None = None) -> ProviderOpenAIOfficial:
4664
provider_config = {
4765
"id": "test-openai",
@@ -481,6 +499,25 @@ def test_opencode_go_delegate_config_defaults_force_reasoning_content_only_when_
481499
assert config["force_tool_call_reasoning_content"] is False
482500

483501

502+
@pytest.mark.asyncio
503+
async def test_opencode_go_text_chat_stream_forwards_extra_user_content_parts():
504+
delegate = _OpenCodeGoDelegateStub()
505+
provider = _OpenCodeGoStreamUnitProvider(delegate)
506+
extra_parts: list[ContentPart] = [TextPart(text="extra context")]
507+
508+
responses = [
509+
response
510+
async for response in provider.text_chat_stream(
511+
prompt="hello",
512+
extra_user_content_parts=extra_parts,
513+
)
514+
]
515+
516+
assert responses
517+
assert delegate.stream_kwargs is not None
518+
assert delegate.stream_kwargs["extra_user_content_parts"] is extra_parts
519+
520+
484521
@pytest.mark.asyncio
485522
async def test_handle_api_error_content_moderated_without_images_raises():
486523
provider = _make_provider(

0 commit comments

Comments
 (0)