Skip to content

Commit 8a0b121

Browse files
committed
Support reasoning content from DeepSeek
1 parent 4298221 commit 8a0b121

5 files changed

Lines changed: 23 additions & 0 deletions

File tree

Core/Sources/ChatService/AllPlugins.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ final class LegacyChatPluginWrapper<Plugin: ChatPlugin>: LegacyChatPlugin {
9494
break
9595
case .startNewMessage:
9696
break
97+
case .reasoning:
98+
break
9799
}
98100

99101
await chatGPTService.memory.mutateHistory { history in

Tool/Sources/ChatBasic/ChatAgent.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public enum ChatAgentResponse {
2424
case references([ChatMessage.Reference])
2525
/// End the current message. The next contents will be sent as a new message.
2626
case startNewMessage
27+
/// Reasoning
28+
case reasoning(String)
2729
}
2830

2931
public struct ChatAgentRequest {

Tool/Sources/OpenAIService/APIs/ChatCompletionsAPIDefinition.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ struct ChatCompletionsStreamDataChunk {
209209

210210
var role: ChatCompletionsRequestBody.Message.Role?
211211
var content: String?
212+
var reasoningContent: String?
212213
var toolCalls: [ToolCall]?
213214
}
214215

@@ -243,6 +244,8 @@ struct ChatCompletionResponseBody: Equatable {
243244
var role: Role
244245
/// The content of the message.
245246
var content: String?
247+
/// The reasoning content of the message.
248+
var reasoningContent: String?
246249
/// When we want to reply to a function call with the result, we have to provide the
247250
/// name of the function call, and include the result in `content`.
248251
///

Tool/Sources/OpenAIService/APIs/OpenAIChatCompletionsService.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ actor OpenAIChatCompletionsService: ChatCompletionsStreamAPI, ChatCompletionsAPI
100100
struct Delta: Codable {
101101
var role: MessageRole?
102102
var content: String?
103+
var reasoning_content: String?
104+
var reasoning: String?
103105
var function_call: RequestBody.MessageFunctionCall?
104106
var tool_calls: [RequestBody.MessageToolCall]?
105107
}
@@ -112,6 +114,8 @@ actor OpenAIChatCompletionsService: ChatCompletionsStreamAPI, ChatCompletionsAPI
112114
var role: MessageRole
113115
/// The content of the message.
114116
var content: String?
117+
var reasoning_content: String?
118+
var reasoning: String?
115119
/// When we want to reply to a function call with the result, we have to provide the
116120
/// name of the function call, and include the result in `content`.
117121
///
@@ -482,6 +486,7 @@ extension OpenAIChatCompletionsService.ResponseBody {
482486
.init(
483487
role: message.role.formalized,
484488
content: message.content ?? "",
489+
reasoningContent: message.reasoning_content ?? message.reasoning ?? "",
485490
toolCalls: {
486491
if let toolCalls = message.tool_calls {
487492
return toolCalls.map { toolCall in
@@ -553,6 +558,8 @@ extension OpenAIChatCompletionsService.StreamDataChunk {
553558
return .init(
554559
role: choice.delta?.role?.formalized,
555560
content: choice.delta?.content,
561+
reasoningContent: choice.delta?.reasoning_content
562+
?? choice.delta?.reasoning,
556563
toolCalls: {
557564
if let toolCalls = choice.delta?.tool_calls {
558565
return toolCalls.map {

Tool/Sources/OpenAIService/ChatGPTService.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public struct ChatGPTError: Error, Codable, LocalizedError {
6666
public enum ChatGPTResponse: Equatable {
6767
case status([String])
6868
case partialText(String)
69+
case partialReasoning(String)
6970
case toolCalls([ChatMessage.ToolCall])
7071
}
7172

@@ -195,6 +196,9 @@ public class ChatGPTService: ChatGPTServiceType {
195196
switch content {
196197
case let .partialText(text):
197198
continuation.yield(ChatGPTResponse.partialText(text))
199+
200+
case let .partialReasoning(text):
201+
continuation.yield(ChatGPTResponse.partialReasoning(text))
198202

199203
case let .partialToolCalls(toolCalls):
200204
guard configuration.runFunctionsAutomatically else { break }
@@ -250,6 +254,7 @@ public class ChatGPTService: ChatGPTServiceType {
250254

251255
extension ChatGPTService {
252256
enum StreamContent {
257+
case partialReasoning(String)
253258
case partialText(String)
254259
case partialToolCalls([Int: ChatMessage.ToolCall])
255260
}
@@ -340,6 +345,10 @@ extension ChatGPTService {
340345
if let content = delta.content {
341346
continuation.yield(.partialText(content))
342347
}
348+
349+
if let reasoning = delta.reasoningContent {
350+
continuation.yield(.partialReasoning(reasoning))
351+
}
343352
}
344353

345354
Logger.service.info("ChatGPT usage: \(usage)")

0 commit comments

Comments
 (0)