language_models: Add thinking support to DeepSeek provider (#32338)

Umesh Yadav created

For DeepSeek provider thinking is returned as reasoning_content and we
don't have to send the reasoning_content back in the request.

Release Notes:

- Add thinking support to DeepSeek provider

Change summary

crates/language_models/src/provider/deepseek.rs | 25 ++++++++++++------
1 file changed, 16 insertions(+), 9 deletions(-)

Detailed changes

crates/language_models/src/provider/deepseek.rs 🔗

@@ -372,15 +372,15 @@ pub fn into_deepseek(
     for message in request.messages {
         for content in message.content {
             match content {
-                MessageContent::Text(text) | MessageContent::Thinking { text, .. } => messages
-                    .push(match message.role {
-                        Role::User => deepseek::RequestMessage::User { content: text },
-                        Role::Assistant => deepseek::RequestMessage::Assistant {
-                            content: Some(text),
-                            tool_calls: Vec::new(),
-                        },
-                        Role::System => deepseek::RequestMessage::System { content: text },
-                    }),
+                MessageContent::Text(text) => messages.push(match message.role {
+                    Role::User => deepseek::RequestMessage::User { content: text },
+                    Role::Assistant => deepseek::RequestMessage::Assistant {
+                        content: Some(text),
+                        tool_calls: Vec::new(),
+                    },
+                    Role::System => deepseek::RequestMessage::System { content: text },
+                }),
+                MessageContent::Thinking { .. } => {}
                 MessageContent::RedactedThinking(_) => {}
                 MessageContent::Image(_) => {}
                 MessageContent::ToolUse(tool_use) => {
@@ -485,6 +485,13 @@ impl DeepSeekEventMapper {
             events.push(Ok(LanguageModelCompletionEvent::Text(content)));
         }
 
+        if let Some(reasoning_content) = choice.delta.reasoning_content.clone() {
+            events.push(Ok(LanguageModelCompletionEvent::Thinking {
+                text: reasoning_content,
+                signature: None,
+            }));
+        }
+
         if let Some(tool_calls) = choice.delta.tool_calls.as_ref() {
             for tool_call in tool_calls {
                 let entry = self.tool_calls_by_index.entry(tool_call.index).or_default();