|
3 | 3 | import json |
4 | 4 | import time |
5 | 5 | from collections.abc import AsyncIterator |
6 | | -from typing import Any, Literal, cast, overload |
| 6 | +from typing import Any, Literal, Optional, cast, overload |
7 | 7 |
|
8 | 8 | from openai.types.responses.response_usage import InputTokensDetails, OutputTokensDetails |
9 | 9 |
|
|
45 | 45 | from ...usage import Usage |
46 | 46 |
|
47 | 47 |
|
| 48 | +class InternalChatCompletionMessage(ChatCompletionMessage): |
| 49 | + """ |
| 50 | + An internal subclass to carry reasoning_content without modifying the original model. |
| 51 | + """ |
| 52 | + |
| 53 | + reasoning_content: Optional[str] = None |
| 54 | + |
| 55 | + |
48 | 56 | class LitellmModel(Model): |
49 | 57 | """This class enables using any model via LiteLLM. LiteLLM allows you to acess OpenAPI, |
50 | 58 | Anthropic, Gemini, Mistral, and many other models. |
@@ -364,13 +372,18 @@ def convert_message_to_openai( |
364 | 372 | provider_specific_fields.get("refusal", None) if provider_specific_fields else None |
365 | 373 | ) |
366 | 374 |
|
367 | | - return ChatCompletionMessage( |
| 375 | + reasoning_content = "" |
| 376 | + if hasattr(message, "reasoning_content") and message.reasoning_content: |
| 377 | + reasoning_content = message.reasoning_content |
| 378 | + |
| 379 | + return InternalChatCompletionMessage( |
368 | 380 | content=message.content, |
369 | 381 | refusal=refusal, |
370 | 382 | role="assistant", |
371 | 383 | annotations=cls.convert_annotations_to_openai(message), |
372 | 384 | audio=message.get("audio", None), # litellm deletes audio if not present |
373 | 385 | tool_calls=tool_calls, |
| 386 | + reasoning_content=reasoning_content, |
374 | 387 | ) |
375 | 388 |
|
376 | 389 | @classmethod |
|
0 commit comments