From 79e559d2968523dbfd9e5582df733a7ba4678321 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 15:55:32 +0000 Subject: [PATCH] style(responses): drop inline comments from #34754 fix --- litellm/responses/response_construction.py | 32 +++++-------------- .../responses/test_response_construction.py | 13 +++----- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/litellm/responses/response_construction.py b/litellm/responses/response_construction.py index d1487c5b7bc..492431c038c 100644 --- a/litellm/responses/response_construction.py +++ b/litellm/responses/response_construction.py @@ -1,17 +1,12 @@ """ Best-effort construction of Responses API objects from raw provider payloads. -Providers deviate from the OpenAI Responses spec often enough that strict -pydantic validation fails (missing ``output``, a ``usage`` block with unexpected -fields, ...). Callers used to fall back to ``model_construct``, which skips -validation *and* nested model coercion, so ``response.usage`` stayed a plain -dict and ``response.output`` could be missing entirely. Everything downstream -reads those attributes as declared (``ResponsesAPIResponse.usage`` is a -``ResponseAPIUsage``, ``.output`` is a list), so the fallback produced objects -that violate their own type and blew up with ``AttributeError`` mid-stream. - -These helpers keep the declared shape intact even when validation fails, so the -fallback stays a degraded-data path instead of a crash path. +When a provider payload fails strict validation, callers fall back to +``model_construct``, which skips nested model coercion and leaves ``usage`` as a +plain dict and ``output`` missing. Downstream code reads those attributes as +declared, so such objects raise ``AttributeError`` mid-stream. These helpers keep +the declared shape intact so the fallback stays a degraded-data path rather than +a crash path """ from collections.abc import Callable, Mapping @@ -26,11 +21,7 @@ _FIELD_MAPPING_ADAPTER = TypeAdapter(dict[str, object]) def construct_responses_api_response(payload: Mapping[str, object]) -> ResponsesAPIResponse: - """Build a ``ResponsesAPIResponse``, validating when possible. - - On validation failure, fields required by the model are defaulted and - ``usage`` is coerced, so attribute access on the result behaves as declared. - """ + """Validate a raw response payload, coercing ``output`` and ``usage`` when validation fails""" try: return ResponsesAPIResponse.model_validate(dict(payload)) except ValidationError: @@ -54,12 +45,7 @@ def construct_responses_api_stream_event( event_model: type[BaseLiteLLMOpenAIResponseObject], payload: Mapping[str, object], ) -> BaseLiteLLMOpenAIResponseObject: - """Build a Responses API streaming event without validation. - - Terminal events (``response.completed`` / ``.failed`` / ``.incomplete``) - declare a ``ResponsesAPIResponse``; ``model_construct`` alone would leave it - as the raw dict, so construct that nested object explicitly. - """ + """Build a streaming event without validation, keeping its nested ``response`` typed""" construct: Callable[..., BaseLiteLLMOpenAIResponseObject] = event_model.model_construct response_payload = _as_field_mapping(payload.get("response")) if response_payload is None: @@ -68,7 +54,6 @@ def construct_responses_api_stream_event( def _construct_usage(usage: object) -> ResponseAPIUsage | None: - """Coerce a raw ``usage`` payload into ``ResponseAPIUsage``, or drop it.""" if usage is None or isinstance(usage, ResponseAPIUsage): return usage usage_fields = _as_field_mapping(usage) @@ -92,7 +77,6 @@ def _construct_usage(usage: object) -> ResponseAPIUsage | None: def _as_field_mapping(value: object) -> Mapping[str, object] | None: - """Validate an untyped payload into a string-keyed field mapping.""" try: return _FIELD_MAPPING_ADAPTER.validate_python(value) except ValidationError: diff --git a/tests/test_litellm/responses/test_response_construction.py b/tests/test_litellm/responses/test_response_construction.py index 6d54f9d1a20..565803a25f6 100644 --- a/tests/test_litellm/responses/test_response_construction.py +++ b/tests/test_litellm/responses/test_response_construction.py @@ -1,11 +1,10 @@ """ Regression tests for GitHub issue #34754. -Providers whose Responses API payloads fail strict validation used to be built -with bare ``model_construct``, leaving ``event.response`` as a raw dict and -``response.usage`` unparsed. Consumers read those as declared, so streaming -requests died with ``AttributeError: 'dict' object has no attribute 'usage'`` -(HTTP 500 mid-stream) or silently dropped the SpendLogs entry. +Providers whose Responses API payloads fail strict validation used to be built with bare +``model_construct``, leaving ``event.response`` as a raw dict and ``response.usage`` unparsed. Consumers +read those as declared, so streaming requests died with ``AttributeError: 'dict' object has no attribute +'usage'`` (HTTP 500 mid-stream) or silently dropped the SpendLogs entry """ import datetime @@ -22,8 +21,6 @@ from litellm.types.llms.openai import ( ResponsesAPIResponse, ) -# `response.completed` payload that fails validation: `output` is required by -# ResponsesAPIResponse but plenty of providers omit it. DICT_FORMAT_COMPLETED_CHUNK = { "type": "response.completed", "response": { @@ -87,7 +84,7 @@ def test_valid_payload_is_validated_not_constructed(): ) assert isinstance(response.usage, ResponseAPIUsage) - assert response.model_fields_set # validated instance, not a bare model_construct + assert response.model_fields_set def test_streaming_event_response_is_not_a_dict():