diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index d8c85853..e4465f27 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -77,6 +77,11 @@ public partial class RoutingService message.CurrentAgentId = agent.Id; message.IsStreaming = response.IsStreaming; message.MessageLabel = response.MessageLabel; + // Preserve the LLM's chain-of-thought (DeepSeek `reasoning_content`) so it is not + // dropped on the final assistant message. `RoleDialogModel.From(...)` rebuilds the + // dialog from the sender and would otherwise lose `response.ReasoningContent`, which + // the w4c-chatapi relies on for its Reasoning viewer. + message.ReasoningContent = response.ReasoningContent; dialogs.Add(message); Context.AddDialogs([message]); } diff --git a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs index dbaeb82d..c7651e83 100644 --- a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs @@ -254,10 +254,26 @@ public class ChatCompletionProvider : IChatCompletion // DeepSeek thinking mode streams the chain-of-thought in `reasoning_content` // (delta level). OpenAI SDK 2.12 keeps it as an unknown property in the JsonPatch. + // Each delta is forwarded as a stream message carrying `ReasoningContent` (empty + // `Content`) so the host (w4c-chatapi) can surface the live reasoning to the UI — + // the same `OnReceiveLlmStreamMessage` event the consumer already subscribes to. var reasoningDelta = ReadStreamingReasoningContent(choice); if (!string.IsNullOrEmpty(reasoningDelta)) { reasoningContentBuilder.Append(reasoningDelta); + + var reasoning = new RoleDialogModel(AgentRole.Assistant, string.Empty) + { + CurrentAgentId = agent.Id, + MessageId = messageId, + ReasoningContent = reasoningDelta + }; + hub.Push(new() + { + EventName = ChatEvent.OnReceiveLlmStreamMessage, + RefId = conv.ConversationId, + Data = reasoning + }); } if (!choice.ContentUpdate.IsNullOrEmpty())