fix: preserve bridge iterator hidden params

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yassin 2026-09-02 15:48:31 +00:00
parent 575161a786
commit 32e43221b9
2 changed files with 21 additions and 25 deletions

View file

@ -89,10 +89,9 @@ class LiteLLMCompletionStreamingIterator(ResponsesAPIStreamingIterator):
self.request_input: str | ResponseInputParam = request_input
self.responses_api_request: ResponsesAPIOptionalRequestParams = responses_api_request
self.custom_llm_provider: str | None = custom_llm_provider
self.litellm_metadata = litellm_metadata or {}
self.completed_response: Any | None = None
_wrapper_hidden_params = getattr(litellm_custom_stream_wrapper, "_hidden_params", None)
self._hidden_params: dict[str, Any] = (
self.litellm_metadata: dict | None = litellm_metadata or {}
_wrapper_hidden_params: Final = getattr(litellm_custom_stream_wrapper, "_hidden_params", None)
self._hidden_params: dict[str, object] = (
dict(_wrapper_hidden_params) if isinstance(_wrapper_hidden_params, dict) else {}
)
# Store lightweight dict snapshots for stream_chunk_builder to reduce

View file

@ -10,12 +10,12 @@ Targets the four helpers introduced on Router:
- _aresponses_streaming_iterator
"""
from typing import Any, AsyncIterator, List
from collections.abc import AsyncIterator
from typing import Any
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from litellm import Router
from litellm.types.llms.openai import (
ResponseAPIUsage,
@ -46,9 +46,7 @@ def _make_router() -> Router:
)
def _make_completed_event(
input_tokens: int, output_tokens: int, total_tokens: int
) -> ResponseCompletedEvent:
def _make_completed_event(input_tokens: int, output_tokens: int, total_tokens: int) -> ResponseCompletedEvent:
response = ResponsesAPIResponse.model_construct(
usage=ResponseAPIUsage(
input_tokens=input_tokens,
@ -145,9 +143,7 @@ def test_combine_responses_fallback_usage_passthrough_for_unknown_event():
def test_build_responses_continuation_input_from_string():
out = Router._build_responses_continuation_input(
"Hello world", "partial assistant text"
)
out = Router._build_responses_continuation_input("Hello world", "partial assistant text")
assert len(out) == 3
assert out[0]["role"] == "user"
assert out[0]["content"][0]["text"] == "Hello world"
@ -157,7 +153,7 @@ def test_build_responses_continuation_input_from_string():
def test_build_responses_continuation_input_from_list_preserves_items():
existing: List[Any] = [
existing: list[Any] = [
{
"type": "message",
"role": "user",
@ -227,9 +223,7 @@ async def test_aresponses_streaming_iterator_passthrough():
router = _make_router()
source = _FakeSource()
wrapper = await router._aresponses_streaming_iterator(
source, initial_kwargs={"model": "primary"}
)
wrapper = await router._aresponses_streaming_iterator(source, initial_kwargs={"model": "primary"})
assert isinstance(wrapper, BaseResponsesAPIStreamingIterator)
collected = [ev async for ev in wrapper]
@ -276,15 +270,18 @@ async def test_aresponses_with_streaming_fallbacks_wraps_streaming_iterator():
async def fake_original(**_kwargs):
return streaming_iter
with patch.object(
router,
"_ageneric_api_call_with_fallbacks",
new=AsyncMock(return_value=streaming_iter),
), patch.object(
router,
"_aresponses_streaming_iterator",
new=AsyncMock(return_value=wrapped),
) as mock_wrap:
with (
patch.object(
router,
"_ageneric_api_call_with_fallbacks",
new=AsyncMock(return_value=streaming_iter),
),
patch.object(
router,
"_aresponses_streaming_iterator",
new=AsyncMock(return_value=wrapped),
) as mock_wrap,
):
out = await router._aresponses_with_streaming_fallbacks(
original_function=fake_original,
model="primary",