Skip to content

Commit 1db529f

Browse files
committed
finish openrouter thinking part
1 parent b325816 commit 1db529f

File tree

1 file changed

+10
-29
lines changed

1 file changed

+10
-29
lines changed

pydantic_ai_slim/pydantic_ai/models/openrouter.py

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from dataclasses import dataclass
1+
from dataclasses import asdict, dataclass
22
from typing import Literal, cast
33

44
from openai import AsyncOpenAI
55
from openai.types.chat import ChatCompletion, ChatCompletionMessage, ChatCompletionMessageParam
66
from openai.types.chat.chat_completion import Choice
7-
from pydantic import BaseModel
7+
from pydantic import AliasChoices, BaseModel, Field, TypeAdapter
88
from typing_extensions import TypedDict
99

1010
from .. import _utils
@@ -253,21 +253,21 @@ class ReasoningSummary(BaseReasoningDetail):
253253
"""Represents a high-level summary of the reasoning process."""
254254

255255
type: Literal['reasoning.summary']
256-
summary: str
256+
summary: str = Field(validation_alias=AliasChoices('summary', 'content'))
257257

258258

259259
class ReasoningEncrypted(BaseReasoningDetail):
260260
"""Represents encrypted reasoning data."""
261261

262262
type: Literal['reasoning.encrypted']
263-
data: str
263+
data: str = Field(validation_alias=AliasChoices('data', 'signature'))
264264

265265

266266
class ReasoningText(BaseReasoningDetail):
267267
"""Represents raw text reasoning."""
268268

269269
type: Literal['reasoning.text']
270-
text: str
270+
text: str = Field(validation_alias=AliasChoices('text', 'content'))
271271
signature: str | None = None
272272

273273

@@ -276,7 +276,7 @@ class ReasoningText(BaseReasoningDetail):
276276

277277
@dataclass(repr=False)
278278
class OpenRouterThinkingPart(ThinkingPart):
279-
"""filler."""
279+
"""A special ThinkingPart that includes reasoning attributes specific to OpenRouter."""
280280

281281
type: Literal['reasoning.summary', 'reasoning.encrypted', 'reasoning.text']
282282
index: int
@@ -317,22 +317,7 @@ def from_reasoning_detail(cls, reasoning: OpenRouterReasoningDetail, provider_na
317317
)
318318

319319
def into_reasoning_detail(self):
320-
reasoning_detail = {
321-
'type': self.type,
322-
'id': self.id,
323-
'format': self.format,
324-
'index': self.index,
325-
}
326-
327-
if self.type == 'reasoning.summary':
328-
reasoning_detail['summary'] = self.content
329-
elif self.type == 'reasoning.text':
330-
reasoning_detail['text'] = self.content
331-
reasoning_detail['signature'] = self.signature
332-
elif self.type == 'reasoning.encrypted':
333-
reasoning_detail['data'] = self.signature
334-
335-
return reasoning_detail
320+
return TypeAdapter(OpenRouterReasoningDetail).validate_python(asdict(self)).model_dump()
336321

337322

338323
class OpenRouterCompletionMessage(ChatCompletionMessage):
@@ -475,12 +460,8 @@ async def _map_messages(self, messages: list[ModelMessage]) -> list[ChatCompleti
475460

476461
for message, openai_message in zip(messages, openai_messages):
477462
if isinstance(message, ModelResponse):
478-
reasoning_details = []
479-
480-
for part in message.parts:
481-
if isinstance(part, OpenRouterThinkingPart):
482-
reasoning_details.append(part.into_reasoning_detail())
483-
484-
openai_message['reasoning_details'] = reasoning_details
463+
openai_message['reasoning_details'] = [
464+
part.into_reasoning_detail() for part in message.parts if isinstance(part, OpenRouterThinkingPart)
465+
]
485466

486467
return openai_messages

0 commit comments

Comments
 (0)