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
20 changes: 11 additions & 9 deletions python/packages/core/agent_framework/openai/_responses_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ def _openai_chat_message_parser(
case FunctionCallContent():
function_call = self._openai_content_parser(message.role, content, call_id_to_id)
all_messages.append(function_call) # type: ignore
case FunctionApprovalResponseContent() | FunctionApprovalRequestContent():
case FunctionApprovalResponseContent() | FunctionApprovalRequestContent() | TextReasoningContent():
all_messages.append(self._openai_content_parser(message.role, content, call_id_to_id)) # type: ignore
case _:
if "content" not in args:
Expand All @@ -427,10 +427,12 @@ def _openai_content_parser(
case TextReasoningContent():
ret: dict[str, Any] = {
"type": "reasoning",
"summary": {
"type": "summary_text",
"text": content.text,
},
"summary": [
{
"type": "summary_text",
"text": content.text,
}
],
}
if content.additional_properties is not None:
if status := content.additional_properties.get("status"):
Expand Down Expand Up @@ -838,14 +840,14 @@ def _create_streaming_response_content(
contents.append(TextReasoningContent(text=event.delta, raw_representation=event))
metadata.update(self._get_metadata_from_response(event))
case "response.reasoning_text.done":
contents.append(TextReasoningContent(text=event.text, raw_representation=event))
metadata.update(self._get_metadata_from_response(event))
# Skip .done event - contains complete text already streamed via .delta events
pass
case "response.reasoning_summary_text.delta":
contents.append(TextReasoningContent(text=event.delta, raw_representation=event))
metadata.update(self._get_metadata_from_response(event))
case "response.reasoning_summary_text.done":
contents.append(TextReasoningContent(text=event.text, raw_representation=event))
metadata.update(self._get_metadata_from_response(event))
# Skip .done event - contains complete text already streamed via .delta events
pass
case "response.completed":
conversation_id = event.response.id if chat_options.store is True else None
model = event.response.model
Expand Down
23 changes: 8 additions & 15 deletions python/packages/core/tests/openai/test_openai_responses_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,8 @@ def test_openai_content_parser_text_reasoning_comprehensive() -> None:
)
result = client._openai_content_parser(Role.ASSISTANT, comprehensive_reasoning, {}) # type: ignore
assert result["type"] == "reasoning"
assert result["summary"]["text"] == "Comprehensive reasoning summary"
assert len(result["summary"]) == 1
assert result["summary"][0]["text"] == "Comprehensive reasoning summary"
assert result["status"] == "in_progress"
assert result["content"]["type"] == "reasoning_text"
assert result["content"]["text"] == "Step-by-step analysis"
Expand Down Expand Up @@ -1823,15 +1824,11 @@ def test_streaming_reasoning_text_done_event() -> None:
text="complete reasoning",
)

with patch.object(client, "_get_metadata_from_response", return_value={"test": "data"}) as mock_metadata:
with patch.object(client, "_get_metadata_from_response", return_value={"test": "data"}):
response = client._create_streaming_response_content(event, chat_options, function_call_ids) # type: ignore

assert len(response.contents) == 1
assert isinstance(response.contents[0], TextReasoningContent)
assert response.contents[0].text == "complete reasoning"
assert response.contents[0].raw_representation == event
mock_metadata.assert_called_once_with(event)
assert response.additional_properties == {"test": "data"}
# Event should be ignored - no content added
assert len(response.contents) == 0


def test_streaming_reasoning_summary_text_delta_event() -> None:
Expand Down Expand Up @@ -1874,15 +1871,11 @@ def test_streaming_reasoning_summary_text_done_event() -> None:
text="complete summary",
)

with patch.object(client, "_get_metadata_from_response", return_value={"custom": "meta"}) as mock_metadata:
with patch.object(client, "_get_metadata_from_response", return_value={"custom": "meta"}):
response = client._create_streaming_response_content(event, chat_options, function_call_ids) # type: ignore

assert len(response.contents) == 1
assert isinstance(response.contents[0], TextReasoningContent)
assert response.contents[0].text == "complete summary"
assert response.contents[0].raw_representation == event
mock_metadata.assert_called_once_with(event)
assert response.additional_properties == {"custom": "meta"}
# Event should be ignored - no content added
assert len(response.contents) == 0


def test_streaming_reasoning_events_preserve_metadata() -> None:
Expand Down