From 08c38388e1b3dbc5fbaaed1969e93859af427cab Mon Sep 17 00:00:00 2001 From: Oleksii Date: Thu, 25 Sep 2025 18:49:40 +0300 Subject: [PATCH] Make index of ChoiceDeltaToolCall required But only in strict mode. 0 would be used in relaxed mode if not found --- .../KeyedDecodingContainer+ParsingOptions.swift | 4 ++++ Sources/OpenAI/Public/Models/ChatStreamResult.swift | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Sources/OpenAI/Private/KeyedDecodingContainer+ParsingOptions.swift b/Sources/OpenAI/Private/KeyedDecodingContainer+ParsingOptions.swift index e4b409a5..784c626d 100644 --- a/Sources/OpenAI/Private/KeyedDecodingContainer+ParsingOptions.swift +++ b/Sources/OpenAI/Private/KeyedDecodingContainer+ParsingOptions.swift @@ -16,6 +16,10 @@ extension KeyedDecodingContainer { try self.decode(TimeInterval.self, forKey: key, parsingOptions: parsingOptions, defaultValue: 0) } + func decodeInt(forKey key: KeyedDecodingContainer.Key, parsingOptions: ParsingOptions) throws -> Int { + try self.decode(Int.self, forKey: key, parsingOptions: parsingOptions, defaultValue: 0) + } + func decode(_ type: T.Type, forKey key: KeyedDecodingContainer.Key, parsingOptions: ParsingOptions, defaultValue: T) throws -> T { do { return try decode(T.self, forKey: key) diff --git a/Sources/OpenAI/Public/Models/ChatStreamResult.swift b/Sources/OpenAI/Public/Models/ChatStreamResult.swift index c1f30216..1ff6b787 100644 --- a/Sources/OpenAI/Public/Models/ChatStreamResult.swift +++ b/Sources/OpenAI/Public/Models/ChatStreamResult.swift @@ -71,7 +71,7 @@ public struct ChatStreamResult: Codable, Equatable, Sendable { public struct ChoiceDeltaToolCall: Codable, Equatable, Sendable { - public let index: Int? + public let index: Int /// The ID of the tool call. public let id: String? /// The function that the model called. @@ -89,6 +89,15 @@ public struct ChatStreamResult: Codable, Equatable, Sendable { self.function = function self.type = "function" } + + public init(from decoder: any Decoder) throws { + let container: KeyedDecodingContainer = try decoder.container(keyedBy: ChoiceDeltaToolCall.CodingKeys.self) + let parsingOptions = decoder.userInfo[.parsingOptions] as? ParsingOptions ?? [] + self.index = try container.decodeInt(forKey: ChoiceDeltaToolCall.CodingKeys.index, parsingOptions: parsingOptions) + self.id = try container.decodeIfPresent(String.self, forKey: ChoiceDeltaToolCall.CodingKeys.id) + self.function = try container.decodeIfPresent(ChoiceDeltaToolCallFunction.self, forKey: ChoiceDeltaToolCall.CodingKeys.function) + self.type = try container.decodeIfPresent(String.self, forKey: ChoiceDeltaToolCall.CodingKeys.type) + } public struct ChoiceDeltaToolCallFunction: Codable, Equatable, Sendable {