Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/openai/types/responses/response_text_delta_event.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -43,8 +45,6 @@ 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]
"""The log probabilities of the tokens in the delta."""

Expand Down
4 changes: 2 additions & 2 deletions src/openai/types/responses/response_text_done_event.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -40,8 +42,6 @@ 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]
"""The log probabilities of the tokens in the delta."""

Expand Down
64 changes: 64 additions & 0 deletions tests/test_response_event_logprobs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""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.
"""

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,
"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 == []