From 40258d2648ceddd03d00cbaddf45c8e4348fa7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B7=A9=E6=97=AD=E7=BA=A2?= <2250244225@qq.com> Date: Wed, 31 Dec 2025 12:38:42 +0800 Subject: [PATCH] Add reasoningContent for model chat --- Sources/OpenAI/Public/Models/ChatQuery.swift | 10 ++++++-- Tests/OpenAITests/ChatQueryCodingTests.swift | 25 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Sources/OpenAI/Public/Models/ChatQuery.swift b/Sources/OpenAI/Public/Models/ChatQuery.swift index 4ada9282..bb7e2907 100644 --- a/Sources/OpenAI/Public/Models/ChatQuery.swift +++ b/Sources/OpenAI/Public/Models/ChatQuery.swift @@ -292,6 +292,7 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { public init?( role: Role, content: String? = nil, + reasoningContent: String? = nil, imageData: Data? = nil, name: String? = nil, toolCalls: [Self.AssistantMessageParam.ToolCallParam]? = nil, @@ -318,9 +319,9 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { } case .assistant: if let content { - self = .assistant(.init(content: .textContent(content), name: name, toolCalls: toolCalls)) + self = .assistant(.init(content: .textContent(content), reasoningContent: reasoningContent, name: name, toolCalls: toolCalls)) } else { - self = .assistant(.init(content: nil, name: name, toolCalls: toolCalls)) + self = .assistant(.init(content: nil, reasoningContent: reasoningContent, name: name, toolCalls: toolCalls)) } case .tool: if let content, let toolCallId { @@ -783,6 +784,8 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { public let role: Self.Role = .assistant /// The contents of the assistant message. Required unless `tool_calls` is specified. public let content: TextOrRefusalContent? + /// The reasoning content of the assistant message. + public let reasoningContent: String? /// Data about a previous audio response from the model. public let audio: Audio? /// The name of the author of this message. `name` is required if role is `function`, and it should be the name of the function whose response is in the `content`. May contain a-z, A-Z, 0-9, and underscores, with a maximum length of 64 characters. @@ -792,11 +795,13 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { public init( content: TextOrRefusalContent? = nil, + reasoningContent: String? = nil, audio: Audio? = nil, name: String? = nil, toolCalls: [Self.ToolCallParam]? = nil ) { self.content = content + self.reasoningContent = reasoningContent self.audio = audio self.name = name self.toolCalls = toolCalls @@ -806,6 +811,7 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { case name case role case content + case reasoningContent = "reasoning_content" case audio case toolCalls = "tool_calls" } diff --git a/Tests/OpenAITests/ChatQueryCodingTests.swift b/Tests/OpenAITests/ChatQueryCodingTests.swift index 012aca12..a6c713ea 100644 --- a/Tests/OpenAITests/ChatQueryCodingTests.swift +++ b/Tests/OpenAITests/ChatQueryCodingTests.swift @@ -94,6 +94,31 @@ struct ChatQueryCodingTests { #expect(try equal(query, expected)) } + @Test func encodeReasoningContent() throws { + let query = ChatQuery( + messages: [ + .assistant(.init(content: .textContent("Content"), reasoningContent: "Reasoning")) + ], + model: .gpt4_o + ) + + let expected = """ + { + "model": "gpt-4o", + "messages": [ + { + "role": "assistant", + "content": "Content", + "reasoning_content": "Reasoning" + } + ], + "stream": false + } + """ + + #expect(try equal(query, expected)) + } + @Test func encodeWebSearchOptions() throws { let query = ChatQuery( messages: [],