From 847f7a4814fae2790c371f856f6b536a2872f7df Mon Sep 17 00:00:00 2001 From: Tin Chi Lo Date: Mon, 3 Aug 2026 20:01:08 -0700 Subject: [PATCH] test(bedrock): stop the streaming closure test depending on the model cost map The new integration test keyed its fake rejection on `strict`, but whether `strict` reaches the wire is decided by `bedrock_converse_supports_strict_tools`, which reads the model cost map. That made the test pass locally and fail on CI: with the flag resolving the other way there was no `strict` in the payload, so the retry found nothing to drop, returned None, and re-raised. The rejection now names `description`, which `BedrockToolSpec` emits unconditionally. Which field the provider dislikes is irrelevant to what this test covers, which is that the closure retries and resends. Verified to pass with the gate forced both True and False. --- ...test_converse_rejected_tool_field_retry.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/test_litellm/llms/bedrock/chat/test_converse_rejected_tool_field_retry.py b/tests/test_litellm/llms/bedrock/chat/test_converse_rejected_tool_field_retry.py index 456a44d3181..369d4519046 100644 --- a/tests/test_litellm/llms/bedrock/chat/test_converse_rejected_tool_field_retry.py +++ b/tests/test_litellm/llms/bedrock/chat/test_converse_rejected_tool_field_retry.py @@ -247,11 +247,24 @@ _CONVERSE_OK = { } +_DESCRIPTION_REJECTION = ( + '{"message":"The model returned the following errors: ' + 'tools.0.custom.description: Extra inputs are not permitted"}' +) + + class _RejectThenAcceptClient: """Fake transport: rejects the first body the way Bedrock does, accepts the second. Drives the real ``_send``/``_send_stream`` closures inside the handler rather than calling the retry wrapper directly, so the wiring at each call site is covered too. + + The rejection names ``description`` rather than ``strict`` on purpose. Whether + ``strict`` reaches the wire depends on ``bedrock_converse_supports_strict_tools``, + which reads the model cost map, so keying this test on it would couple the wiring + under test to global pricing state that another test can change. ``description`` is + emitted by ``BedrockToolSpec`` unconditionally. Which field the provider dislikes is + irrelevant here; what is under test is that the closure retries and resends. """ def __init__(self) -> None: @@ -262,7 +275,7 @@ class _RejectThenAcceptClient: if len(self.posts) == 1: request = httpx.Request("POST", "https://bedrock-runtime.us-east-1.amazonaws.com/x") raise httpx.HTTPStatusError( - "400", request=request, response=httpx.Response(400, text=_STRICT_REJECTION, request=request) + "400", request=request, response=httpx.Response(400, text=_DESCRIPTION_REJECTION, request=request) ) return httpx.Response(200, json=_CONVERSE_OK) @@ -327,6 +340,6 @@ async def test_async_streaming_closure_retries_and_resends_without_the_field() - await BedrockConverseLLM().async_streaming(**_converse_kwargs(async_client)) assert len(async_client.posts) == 2 - assert '"strict"' in async_client.posts[0] - assert '"strict"' not in async_client.posts[1] + assert '"description"' in async_client.posts[0] + assert '"description"' not in async_client.posts[1] assert '"get_weather"' in async_client.posts[1]