From 0d478826da133b6bd1cd6bb58e1fb665b49dc9d6 Mon Sep 17 00:00:00 2001 From: giulio-leone Date: Mon, 2 Mar 2026 04:22:31 +0100 Subject: [PATCH 1/5] fix(types): make logprobs Optional in response event types Non-OpenAI providers (litellm, Anthropic proxies) may not include logprobs in streaming delta events. Making it Optional with a default of None prevents ValidationError when parsing proxy responses. Fixes #2489 --- .../responses/response_text_delta_event.py | 2 +- .../responses/response_text_done_event.py | 2 +- tests/test_response_event_logprobs.py | 67 +++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tests/test_response_event_logprobs.py diff --git a/src/openai/types/responses/response_text_delta_event.py b/src/openai/types/responses/response_text_delta_event.py index 4f802abfd2..9dab3c6b84 100644 --- a/src/openai/types/responses/response_text_delta_event.py +++ b/src/openai/types/responses/response_text_delta_event.py @@ -45,7 +45,7 @@ class ResponseTextDeltaEvent(BaseModel): item_id: str """The ID of the output item that the text delta was added to.""" - logprobs: List[Logprob] + logprobs: Optional[List[Logprob]] = None """The log probabilities of the tokens in the delta.""" output_index: int diff --git a/src/openai/types/responses/response_text_done_event.py b/src/openai/types/responses/response_text_done_event.py index 75bd479870..b4f57b8f6b 100644 --- a/src/openai/types/responses/response_text_done_event.py +++ b/src/openai/types/responses/response_text_done_event.py @@ -42,7 +42,7 @@ class ResponseTextDoneEvent(BaseModel): item_id: str """The ID of the output item that the text content is finalized.""" - logprobs: List[Logprob] + logprobs: Optional[List[Logprob]] = None """The log probabilities of the tokens in the delta.""" output_index: int diff --git a/tests/test_response_event_logprobs.py b/tests/test_response_event_logprobs.py new file mode 100644 index 0000000000..6d55ea9630 --- /dev/null +++ b/tests/test_response_event_logprobs.py @@ -0,0 +1,67 @@ +"""Tests for optional logprobs in response event types. + +Regression tests for https://github.com/openai/openai-python/issues/2489 +Non-OpenAI providers may not include logprobs in streaming responses. +""" + +import pytest + +from openai.types.responses.response_text_delta_event import ResponseTextDeltaEvent, Logprob +from openai.types.responses.response_text_done_event import ResponseTextDoneEvent + + +_DELTA_BASE = { + "content_index": 0, + "delta": "Hello", + "item_id": "item_1", + "output_index": 0, + "sequence_number": 1, + "type": "response.output_text.delta", +} + +_DONE_BASE = { + "content_index": 0, + "item_id": "item_1", + "output_index": 0, + "sequence_number": 2, + "text": "Hello world", + "type": "response.output_text.done", +} + +_SAMPLE_LOGPROBS = [{"token": "Hello", "logprob": -0.1, "top_logprobs": None}] + + +class TestResponseTextDeltaEventLogprobs: + def test_without_logprobs(self) -> None: + event = ResponseTextDeltaEvent.model_validate(_DELTA_BASE) + assert event.logprobs is None + + def test_with_logprobs(self) -> None: + data = {**_DELTA_BASE, "logprobs": _SAMPLE_LOGPROBS} + event = ResponseTextDeltaEvent.model_validate(data) + assert event.logprobs is not None + assert len(event.logprobs) == 1 + assert event.logprobs[0].token == "Hello" + + def test_with_empty_logprobs(self) -> None: + data = {**_DELTA_BASE, "logprobs": []} + event = ResponseTextDeltaEvent.model_validate(data) + assert event.logprobs == [] + + +class TestResponseTextDoneEventLogprobs: + def test_without_logprobs(self) -> None: + event = ResponseTextDoneEvent.model_validate(_DONE_BASE) + assert event.logprobs is None + + def test_with_logprobs(self) -> None: + data = {**_DONE_BASE, "logprobs": _SAMPLE_LOGPROBS} + event = ResponseTextDoneEvent.model_validate(data) + assert event.logprobs is not None + assert len(event.logprobs) == 1 + assert event.logprobs[0].token == "Hello" + + def test_with_empty_logprobs(self) -> None: + data = {**_DONE_BASE, "logprobs": []} + event = ResponseTextDoneEvent.model_validate(data) + assert event.logprobs == [] From 799afa66eb0249513caefb793747409528bc3f16 Mon Sep 17 00:00:00 2001 From: giulio-leone Date: Mon, 2 Mar 2026 05:19:41 +0100 Subject: [PATCH 2/5] fix: remove unused imports from test file --- tests/test_response_event_logprobs.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_response_event_logprobs.py b/tests/test_response_event_logprobs.py index 6d55ea9630..a91fa0ce6f 100644 --- a/tests/test_response_event_logprobs.py +++ b/tests/test_response_event_logprobs.py @@ -4,9 +4,7 @@ Non-OpenAI providers may not include logprobs in streaming responses. """ -import pytest - -from openai.types.responses.response_text_delta_event import ResponseTextDeltaEvent, Logprob +from openai.types.responses.response_text_delta_event import ResponseTextDeltaEvent from openai.types.responses.response_text_done_event import ResponseTextDoneEvent From 0571026d78fbe94579385253ec17d5577453e2c2 Mon Sep 17 00:00:00 2001 From: giulio-leone Date: Mon, 2 Mar 2026 17:26:48 +0100 Subject: [PATCH 3/5] fix(review): add manual override comments to auto-generated type files Note that logprobs fields were manually changed to Optional in the auto-generated files, referencing issue #2489. Also fix import sorting in the test file. Refs: #2914 --- src/openai/types/responses/response_text_delta_event.py | 2 ++ src/openai/types/responses/response_text_done_event.py | 2 ++ tests/test_response_event_logprobs.py | 3 +-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/openai/types/responses/response_text_delta_event.py b/src/openai/types/responses/response_text_delta_event.py index 9dab3c6b84..2cae46d188 100644 --- a/src/openai/types/responses/response_text_delta_event.py +++ b/src/openai/types/responses/response_text_delta_event.py @@ -1,4 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +# NOTE: logprobs field manually changed to Optional to support non-OpenAI providers +# that may not include logprobs in streaming responses. See #2489. from typing import List, Optional from typing_extensions import Literal diff --git a/src/openai/types/responses/response_text_done_event.py b/src/openai/types/responses/response_text_done_event.py index b4f57b8f6b..ab89dbc65c 100644 --- a/src/openai/types/responses/response_text_done_event.py +++ b/src/openai/types/responses/response_text_done_event.py @@ -1,4 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +# NOTE: logprobs field manually changed to Optional to support non-OpenAI providers +# that may not include logprobs in streaming responses. See #2489. from typing import List, Optional from typing_extensions import Literal diff --git a/tests/test_response_event_logprobs.py b/tests/test_response_event_logprobs.py index a91fa0ce6f..61e664559a 100644 --- a/tests/test_response_event_logprobs.py +++ b/tests/test_response_event_logprobs.py @@ -4,9 +4,8 @@ Non-OpenAI providers may not include logprobs in streaming responses. """ -from openai.types.responses.response_text_delta_event import ResponseTextDeltaEvent from openai.types.responses.response_text_done_event import ResponseTextDoneEvent - +from openai.types.responses.response_text_delta_event import ResponseTextDeltaEvent _DELTA_BASE = { "content_index": 0, From ae4a07e09c0354df7c7fdd4bf8b8d9d49bebca82 Mon Sep 17 00:00:00 2001 From: giulio-leone Date: Mon, 2 Mar 2026 17:45:49 +0100 Subject: [PATCH 4/5] fix: apply code review suggestions Apply reviewer code suggestions from PR review. --- src/openai/types/responses/response_text_delta_event.py | 2 +- src/openai/types/responses/response_text_done_event.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openai/types/responses/response_text_delta_event.py b/src/openai/types/responses/response_text_delta_event.py index 2cae46d188..c90716897c 100644 --- a/src/openai/types/responses/response_text_delta_event.py +++ b/src/openai/types/responses/response_text_delta_event.py @@ -45,7 +45,7 @@ class ResponseTextDeltaEvent(BaseModel): """The text delta that was added.""" item_id: str - """The ID of the output item that the text delta was added to.""" + logprobs: List[Logprob] logprobs: Optional[List[Logprob]] = None """The log probabilities of the tokens in the delta.""" diff --git a/src/openai/types/responses/response_text_done_event.py b/src/openai/types/responses/response_text_done_event.py index ab89dbc65c..cbfa3085b1 100644 --- a/src/openai/types/responses/response_text_done_event.py +++ b/src/openai/types/responses/response_text_done_event.py @@ -42,7 +42,7 @@ class ResponseTextDoneEvent(BaseModel): """The index of the content part that the text content is finalized.""" item_id: str - """The ID of the output item that the text content is finalized.""" + logprobs: List[Logprob] logprobs: Optional[List[Logprob]] = None """The log probabilities of the tokens in the delta.""" From ea170bbdad703fd4c6925b3dcc60fc401c2a6a5b Mon Sep 17 00:00:00 2001 From: g97iulio1609 Date: Mon, 2 Mar 2026 18:28:20 +0100 Subject: [PATCH 5/5] fix: apply code review suggestions Refs: #2914 --- src/openai/types/responses/response_text_delta_event.py | 2 -- src/openai/types/responses/response_text_done_event.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/openai/types/responses/response_text_delta_event.py b/src/openai/types/responses/response_text_delta_event.py index c90716897c..ba54349950 100644 --- a/src/openai/types/responses/response_text_delta_event.py +++ b/src/openai/types/responses/response_text_delta_event.py @@ -46,8 +46,6 @@ class ResponseTextDeltaEvent(BaseModel): item_id: str logprobs: List[Logprob] - - logprobs: Optional[List[Logprob]] = None """The log probabilities of the tokens in the delta.""" output_index: int diff --git a/src/openai/types/responses/response_text_done_event.py b/src/openai/types/responses/response_text_done_event.py index cbfa3085b1..9a85b1e623 100644 --- a/src/openai/types/responses/response_text_done_event.py +++ b/src/openai/types/responses/response_text_done_event.py @@ -43,8 +43,6 @@ class ResponseTextDoneEvent(BaseModel): item_id: str logprobs: List[Logprob] - - logprobs: Optional[List[Logprob]] = None """The log probabilities of the tokens in the delta.""" output_index: int