From 7bd3075d532cdfd28a414c18d1dfb45c4a2ebcc3 Mon Sep 17 00:00:00 2001 From: Aero Date: Wed, 21 Jan 2026 18:08:59 +0800 Subject: [PATCH] open_ai: Support reasoning content (#43662) Support for Kimi K2 Thinking Release Notes: - Added support for thinking traces when using OpenAI-API-compatible AI providers --------- Co-authored-by: Bennet Bo Fenner --- .../language_models/src/provider/open_ai.rs | 21 +++++++++++++++++-- crates/open_ai/src/open_ai.rs | 2 ++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/crates/language_models/src/provider/open_ai.rs b/crates/language_models/src/provider/open_ai.rs index fde221f86f270cd5955adccc4588ea5811e02ad8..f421da7a975e7e155bf7ffef1897026078d5ec4c 100644 --- a/crates/language_models/src/provider/open_ai.rs +++ b/crates/language_models/src/provider/open_ai.rs @@ -426,7 +426,14 @@ pub fn into_open_ai( for content in message.content { match content { MessageContent::Text(text) | MessageContent::Thinking { text, .. } => { - if !text.trim().is_empty() { + let should_add = if message.role == Role::User { + // Including whitespace-only user messages can cause error with OpenAI compatible APIs + // See https://github.com/zed-industries/zed/issues/40097 + !text.trim().is_empty() + } else { + !text.is_empty() + }; + if should_add { add_message_content_part( open_ai::MessagePart::Text { text }, message.role, @@ -792,8 +799,18 @@ impl OpenAiEventMapper { }; if let Some(delta) = choice.delta.as_ref() { + if let Some(reasoning_content) = delta.reasoning_content.clone() { + if !reasoning_content.is_empty() { + events.push(Ok(LanguageModelCompletionEvent::Thinking { + text: reasoning_content, + signature: None, + })); + } + } if let Some(content) = delta.content.clone() { - events.push(Ok(LanguageModelCompletionEvent::Text(content))); + if !content.is_empty() { + events.push(Ok(LanguageModelCompletionEvent::Text(content))); + } } if let Some(tool_calls) = delta.tool_calls.as_ref() { diff --git a/crates/open_ai/src/open_ai.rs b/crates/open_ai/src/open_ai.rs index 0f88aaddc608d8c794d6d7e867cbac6c042d53df..e05865e079cbf71add94b790b1659b09a8e8fa22 100644 --- a/crates/open_ai/src/open_ai.rs +++ b/crates/open_ai/src/open_ai.rs @@ -463,6 +463,8 @@ pub struct ResponseMessageDelta { pub content: Option, #[serde(default, skip_serializing_if = "is_none_or_empty")] pub tool_calls: Option>, + #[serde(default, skip_serializing_if = "is_none_or_empty")] + pub reasoning_content: Option, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]