Skip to content

Commit 245dff4

Browse files
authored
Support OpenAI Responses API returning encrypted reasoning content without summary (#2866)
1 parent e97b93a commit 245dff4

File tree

5 files changed

+4
-9
lines changed

5 files changed

+4
-9
lines changed

pydantic_ai_slim/pydantic_ai/_parts_manager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,16 +198,16 @@ def handle_thinking_delta(
198198
existing_thinking_part_and_index = existing_part, part_index
199199

200200
if existing_thinking_part_and_index is None:
201-
if content is not None:
201+
if content is not None or signature is not None:
202202
# There is no existing thinking part that should be updated, so create a new one
203203
new_part_index = len(self._parts)
204-
part = ThinkingPart(content=content, id=id, signature=signature, provider_name=provider_name)
204+
part = ThinkingPart(content=content or '', id=id, signature=signature, provider_name=provider_name)
205205
if vendor_part_id is not None: # pragma: no branch
206206
self._vendor_id_to_part_index[vendor_part_id] = new_part_index
207207
self._parts.append(part)
208208
return PartStartEvent(index=new_part_index, part=part)
209209
else:
210-
raise UnexpectedModelBehavior('Cannot create a ThinkingPart with no content')
210+
raise UnexpectedModelBehavior('Cannot create a ThinkingPart with no content or signature')
211211
else:
212212
if content is not None or signature is not None:
213213
# Update the existing ThinkingPart with the new content and/or signature delta

pydantic_ai_slim/pydantic_ai/models/anthropic.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,6 @@ async def _get_event_iterator(self) -> AsyncIterator[ModelResponseStreamEvent]:
641641
yield self._parts_manager.handle_thinking_delta(
642642
vendor_part_id=event.index,
643643
id='redacted_thinking',
644-
content='',
645644
signature=current_block.data,
646645
provider_name=self.provider_name,
647646
)

pydantic_ai_slim/pydantic_ai/models/bedrock.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,6 @@ async def _get_event_iterator(self) -> AsyncIterator[ModelResponseStreamEvent]:
681681
yield self._parts_manager.handle_thinking_delta(
682682
vendor_part_id=index,
683683
id='redacted_content',
684-
content='',
685684
signature=redacted_content.decode('utf-8'),
686685
provider_name=self.provider_name,
687686
)

pydantic_ai_slim/pydantic_ai/models/google.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,6 @@ async def _get_event_iterator(self) -> AsyncIterator[ModelResponseStreamEvent]:
596596
signature = base64.b64encode(part.thought_signature).decode('utf-8')
597597
yield self._parts_manager.handle_thinking_delta(
598598
vendor_part_id='thinking',
599-
content='', # A thought signature may occur without a preceding thinking part, so we add an empty delta so that a new part can be created
600599
signature=signature,
601600
provider_name=self.provider_name,
602601
)

tests/models/test_google.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,9 +1226,7 @@ def dummy() -> None: ... # pragma: no cover
12261226
PartDeltaEvent(index=0, delta=ThinkingPartDelta(content_delta=IsStr())),
12271227
PartDeltaEvent(index=0, delta=ThinkingPartDelta(content_delta=IsStr())),
12281228
PartDeltaEvent(index=0, delta=ThinkingPartDelta(content_delta=IsStr())),
1229-
PartDeltaEvent(
1230-
index=0, delta=ThinkingPartDelta(content_delta='', signature_delta=IsStr(), provider_name='google-gla')
1231-
),
1229+
PartDeltaEvent(index=0, delta=ThinkingPartDelta(signature_delta=IsStr(), provider_name='google-gla')),
12321230
PartStartEvent(index=1, part=TextPart(content=IsStr())),
12331231
FinalResultEvent(tool_name=None, tool_call_id=None),
12341232
PartDeltaEvent(index=1, delta=TextPartDelta(content_delta=IsStr())),

0 commit comments

Comments
 (0)