From e7a78dad4423acc97d5a825b24f0a74753b1d6bb Mon Sep 17 00:00:00 2001 From: Dmitrii Medvedev Date: Mon, 29 Sep 2025 12:01:09 +0300 Subject: [PATCH 1/4] Add status code handling on performSpeechRequest --- Sources/OpenAI/Private/Client/CombineClient.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/OpenAI/Private/Client/CombineClient.swift b/Sources/OpenAI/Private/Client/CombineClient.swift index 58a268a4..e343bde7 100644 --- a/Sources/OpenAI/Private/Client/CombineClient.swift +++ b/Sources/OpenAI/Private/Client/CombineClient.swift @@ -52,6 +52,8 @@ final class CombineClient: Sendable { return session .dataTaskPublisher(for: interceptedRequest) .tryMap { (data, response) in + guard let response = response as? HTTPURLResponse else { return .init(audio: Data()) } + guard 200...299 ~= response.statusCode else { throw OpenAIError.statusError(response: response, statusCode: response.statusCode) } let finalData: Data = try self.responseHandler.interceptAndDecodeRaw(response: response, urlRequest: urlRequest, responseData: data) return .init(audio: finalData) }.eraseToAnyPublisher() From 3c051cc96a6516d692c6264591995292bde61a70 Mon Sep 17 00:00:00 2001 From: Dmitrii Medvedev Date: Fri, 12 Dec 2025 11:10:11 +0200 Subject: [PATCH 2/4] Add annotation property to ChatStreamResult.Choice.ChoiceDelta --- Sources/OpenAI/Public/Models/Annotation.swift | 29 +++++++++++++++++++ Sources/OpenAI/Public/Models/ChatResult.swift | 28 ------------------ .../Public/Models/ChatStreamResult.swift | 4 +++ 3 files changed, 33 insertions(+), 28 deletions(-) create mode 100644 Sources/OpenAI/Public/Models/Annotation.swift diff --git a/Sources/OpenAI/Public/Models/Annotation.swift b/Sources/OpenAI/Public/Models/Annotation.swift new file mode 100644 index 00000000..269cc361 --- /dev/null +++ b/Sources/OpenAI/Public/Models/Annotation.swift @@ -0,0 +1,29 @@ +import Foundation + +public struct Annotation: Codable, Equatable, Sendable { + /// The type of the URL citation. Always `url_citation`. + let type: String + /// A URL citation when using web search. + let urlCitation: URLCitation + + public enum CodingKeys: String, CodingKey { + case type, urlCitation = "url_citation" + } + + public struct URLCitation: Codable, Equatable, Sendable { + /// The index of the last character of the URL citation in the message. + let endIndex: Int + /// The index of the first character of the URL citation in the message. + let startIndex: Int + /// The title of the web resource. + let title: String + /// The URL of the web resource. + let url: String + + public enum CodingKeys: String, CodingKey { + case endIndex = "end_index" + case startIndex = "start_index" + case title, url + } + } +} diff --git a/Sources/OpenAI/Public/Models/ChatResult.swift b/Sources/OpenAI/Public/Models/ChatResult.swift index 52b5773f..c6ed4eed 100644 --- a/Sources/OpenAI/Public/Models/ChatResult.swift +++ b/Sources/OpenAI/Public/Models/ChatResult.swift @@ -156,34 +156,6 @@ public struct ChatResult: Codable, Equatable, Sendable { case _reasoningContent = "reasoning_content" } - public struct Annotation: Codable, Equatable, Sendable { - /// The type of the URL citation. Always `url_citation`. - let type: String - /// A URL citation when using web search. - let urlCitation: URLCitation - - public enum CodingKeys: String, CodingKey { - case type, urlCitation = "url_citation" - } - - public struct URLCitation: Codable, Equatable, Sendable { - /// The index of the last character of the URL citation in the message. - let endIndex: Int - /// The index of the first character of the URL citation in the message. - let startIndex: Int - /// The title of the web resource. - let title: String - /// The URL of the web resource. - let url: String - - public enum CodingKeys: String, CodingKey { - case endIndex = "end_index" - case startIndex = "start_index" - case title, url - } - } - } - public struct Audio: Codable, Equatable, Sendable { /// Base64 encoded audio bytes generated by the model, in the format specified in the request. public let data: String diff --git a/Sources/OpenAI/Public/Models/ChatStreamResult.swift b/Sources/OpenAI/Public/Models/ChatStreamResult.swift index c1f30216..9e6cd54d 100644 --- a/Sources/OpenAI/Public/Models/ChatStreamResult.swift +++ b/Sources/OpenAI/Public/Models/ChatStreamResult.swift @@ -25,6 +25,9 @@ public struct ChatStreamResult: Codable, Equatable, Sendable { /// The role of the author of this message. public let role: Self.Role? public let toolCalls: [Self.ChoiceDeltaToolCall]? + /// Annotations for the message, when applicable, as when using the web search tool. + /// Web search tool: https://platform.openai.com/docs/guides/tools-web-search?api-mode=chat + public let annotations: [Annotation]? /// Value for `reasoning` field in response. /// @@ -111,6 +114,7 @@ public struct ChatStreamResult: Codable, Equatable, Sendable { case content case audio case role + case annotations case toolCalls = "tool_calls" case _reasoning = "reasoning" case _reasoningContent = "reasoning_content" From c696c734febeac88260cbad04a586fc03da25561 Mon Sep 17 00:00:00 2001 From: Dmitrii Medvedev Date: Fri, 12 Dec 2025 11:12:16 +0200 Subject: [PATCH 3/4] Revert "Add status code handling on performSpeechRequest" This reverts commit e7a78dad4423acc97d5a825b24f0a74753b1d6bb. --- Sources/OpenAI/Private/Client/CombineClient.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sources/OpenAI/Private/Client/CombineClient.swift b/Sources/OpenAI/Private/Client/CombineClient.swift index e343bde7..58a268a4 100644 --- a/Sources/OpenAI/Private/Client/CombineClient.swift +++ b/Sources/OpenAI/Private/Client/CombineClient.swift @@ -52,8 +52,6 @@ final class CombineClient: Sendable { return session .dataTaskPublisher(for: interceptedRequest) .tryMap { (data, response) in - guard let response = response as? HTTPURLResponse else { return .init(audio: Data()) } - guard 200...299 ~= response.statusCode else { throw OpenAIError.statusError(response: response, statusCode: response.statusCode) } let finalData: Data = try self.responseHandler.interceptAndDecodeRaw(response: response, urlRequest: urlRequest, responseData: data) return .init(audio: finalData) }.eraseToAnyPublisher() From bbc4792000c628ed6181baacef461c8ae3b283a4 Mon Sep 17 00:00:00 2001 From: Dmitrii Medvedev Date: Fri, 12 Dec 2025 11:16:21 +0200 Subject: [PATCH 4/4] Make Annotation properties - public --- Sources/OpenAI/Public/Models/Annotation.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/OpenAI/Public/Models/Annotation.swift b/Sources/OpenAI/Public/Models/Annotation.swift index 269cc361..7191a3d7 100644 --- a/Sources/OpenAI/Public/Models/Annotation.swift +++ b/Sources/OpenAI/Public/Models/Annotation.swift @@ -2,9 +2,9 @@ import Foundation public struct Annotation: Codable, Equatable, Sendable { /// The type of the URL citation. Always `url_citation`. - let type: String + public let type: String /// A URL citation when using web search. - let urlCitation: URLCitation + public let urlCitation: URLCitation public enum CodingKeys: String, CodingKey { case type, urlCitation = "url_citation" @@ -12,13 +12,13 @@ public struct Annotation: Codable, Equatable, Sendable { public struct URLCitation: Codable, Equatable, Sendable { /// The index of the last character of the URL citation in the message. - let endIndex: Int + public let endIndex: Int /// The index of the first character of the URL citation in the message. - let startIndex: Int + public let startIndex: Int /// The title of the web resource. - let title: String + public let title: String /// The URL of the web resource. - let url: String + public let url: String public enum CodingKeys: String, CodingKey { case endIndex = "end_index"