diff --git a/README.md b/README.md index 2ee1ceac..12576326 100644 --- a/README.md +++ b/README.md @@ -1159,11 +1159,14 @@ Models are represented as a typealias `typealias Model = String`. ```swift public extension Model { + static let gpt5_1 = "gpt-5.1" + static let gpt5_1_chat_latest = "gpt-5.1-chat-latest" + static let gpt5 = "gpt-5" static let gpt5_mini = "gpt-5-mini" static let gpt5_nano = "gpt-5-nano" static let gpt5_chat = "gpt-5-chat" - + static let gpt4_1 = "gpt-4.1" static let gpt4_1_mini = "gpt-4.1-mini" static let gpt4_1_nano = "gpt-4.1-nano" diff --git a/Sources/OpenAI/Public/Models/ChatQuery.swift b/Sources/OpenAI/Public/Models/ChatQuery.swift index 612bf632..4ada9282 100644 --- a/Sources/OpenAI/Public/Models/ChatQuery.swift +++ b/Sources/OpenAI/Public/Models/ChatQuery.swift @@ -15,7 +15,7 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { public let messages: [Self.ChatCompletionMessageParam] /// Model ID used to generate the response, like `gpt-4o` or `o3`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. public let model: Model - /// Constrains effort on reasoning for [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently supported values are minimal, low, medium, and high. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response. + /// Constrains effort on reasoning for [reasoning models](https://platform.openai.com/docs/guides/reasoning). Currently supported values are none, minimal, low, medium, and high. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response. /// /// - Note: o-series models only public let reasoningEffort: ReasoningEffort? @@ -922,6 +922,7 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { } public enum ReasoningEffort: Codable, Equatable, Sendable { + case none case minimal case low case medium @@ -935,6 +936,8 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { public func encode(to encoder: any Encoder) throws { var container = encoder.singleValueContainer() switch self { + case .none: + try container.encode("none") case .minimal: try container.encode("minimal") case .low: @@ -952,6 +955,8 @@ public struct ChatQuery: Equatable, Codable, Streamable, Sendable { let container = try decoder.singleValueContainer() let rawValue = try container.decode(String.self) switch rawValue { + case "none": + self = .none case "minimal": self = .minimal case "low": diff --git a/Sources/OpenAI/Public/Models/Models/Models.swift b/Sources/OpenAI/Public/Models/Models/Models.swift index 24c245ba..3b1fa197 100644 --- a/Sources/OpenAI/Public/Models/Models/Models.swift +++ b/Sources/OpenAI/Public/Models/Models/Models.swift @@ -53,6 +53,14 @@ public extension Model { @available(*, deprecated, message: "On April 14th, 2025, developers were notified that the gpt-4.5-preview model is deprecated and will be removed from the API in the coming months. Recommended replacement: gpt-4.1") static let gpt4_5_preview = "gpt-4.5-preview" + // GPT-5.1 + + /// `gpt-5.1` Enhanced version of GPT-5 with improved reasoning and performance + static let gpt5_1 = "gpt-5.1" + + /// `gpt-5.1-chat-latest` Latest GPT-5.1 model optimized for chat interactions + static let gpt5_1_chat_latest = "gpt-5.1-chat-latest" + // GPT-5 /// `gpt-5` OpenAI's best AI system with significant leap in intelligence, designed for logic and multi-step tasks with deep reasoning @@ -261,7 +269,7 @@ public extension Model { // reasoning .o4_mini, o3, o3_mini, .o1, // flagship - .gpt5, .gpt5_mini, .gpt5_nano, .gpt5_chat, .gpt4_1, .gpt4_o, .gpt_4o_audio_preview, chatgpt_4o_latest, + .gpt5, .gpt5_mini, .gpt5_nano, .gpt5_chat, .gpt5_1, .gpt5_1_chat_latest, .gpt4_1, .gpt4_o, .gpt_4o_audio_preview, chatgpt_4o_latest, // cost-optimized .gpt4_1_mini, .gpt4_1_nano, .gpt4_o_mini, .gpt_4o_mini_audio_preview, // tool-specific @@ -274,7 +282,7 @@ public extension Model { // reasoning .o4_mini, .o3, .o3_mini, .o1, .o1_pro, // flagship - .gpt5, .gpt5_mini, .gpt5_nano, .gpt5_chat, .gpt4_1, .gpt4_o, .chatgpt_4o_latest, + .gpt5, .gpt5_mini, .gpt5_nano, .gpt5_chat, .gpt5_1, .gpt5_1_chat_latest, .gpt4_1, .gpt4_o, .chatgpt_4o_latest, // cost-optimized .gpt4_1_mini, .gpt4_1_nano, .gpt4_o_mini, .gpt4_turbo, .gpt4, .gpt3_5Turbo, diff --git a/Sources/OpenAI/Public/Schemas/Generated/Components.swift b/Sources/OpenAI/Public/Schemas/Generated/Components.swift index b3bbe334..8f7dce6d 100644 --- a/Sources/OpenAI/Public/Schemas/Generated/Components.swift +++ b/Sources/OpenAI/Public/Schemas/Generated/Components.swift @@ -4861,13 +4861,14 @@ public enum Components { /// /// Constrains effort on reasoning for /// [reasoning models](https://platform.openai.com/docs/guides/reasoning). - /// Currently supported values are `minimal`, `low`, `medium`, and `high`. Reducing + /// Currently supported values are `none`, `minimal`, `low`, `medium`, and `high`. Reducing /// reasoning effort can result in faster responses and fewer tokens used /// on reasoning in a response. /// /// /// - Remark: Generated from `#/components/schemas/ReasoningEffort`. @frozen public enum ReasoningEffort: String, Codable, Hashable, Sendable, CaseIterable { + case none = "none" case minimal = "minimal" case low = "low" case medium = "medium" diff --git a/Tests/OpenAITests/OpenAITestsDecoder.swift b/Tests/OpenAITests/OpenAITestsDecoder.swift index 9c66c017..bdb55591 100644 --- a/Tests/OpenAITests/OpenAITestsDecoder.swift +++ b/Tests/OpenAITests/OpenAITestsDecoder.swift @@ -383,7 +383,44 @@ class OpenAITestsDecoder: XCTestCase { let decoded = try JSONDecoder().decode(Components.Schemas.Reasoning.self, from: data) XCTAssertEqual(decoded.effort, .minimal) } - + + func testChatQueryWithReasoningEffortNone() throws { + let chatQuery = ChatQuery( + messages: [ + .init(role: .user, content: "Who are you?")! + ], + model: .gpt5_1, + reasoningEffort: ChatQuery.ReasoningEffort.none + ) + let expectedValue = """ + { + "model": "gpt-5.1", + "messages": [ + { + "role": "user", + "content": "Who are you?" + } + ], + "reasoning_effort": "none", + "stream": false + } + """ + + let chatQueryAsDict = try jsonDataAsNSDictionary(JSONEncoder().encode(chatQuery)) + let expectedValueAsDict = try jsonDataAsNSDictionary(expectedValue.data(using: .utf8)!) + + XCTAssertEqual(chatQueryAsDict, expectedValueAsDict) + } + + func testReasoningEffortDecodingNone() throws { + let json = """ + { "effort": "none" } + """ + let data = json.data(using: .utf8)! + let decoded = try JSONDecoder().decode(Components.Schemas.Reasoning.self, from: data) + XCTAssertEqual(decoded.effort, Components.Schemas.ReasoningEffort.none) + } + func testEmbeddings() async throws { let data = """ {