Skip to content

Commit 80e9160

Browse files
authored
Correctly handle partial JSON at the end of the chunk
1 parent c45f332 commit 80e9160

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

Sources/OpenAI/Private/StreamingSession.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ final class StreamingSession<ResultType: Codable>: NSObject, Identifiable, URLSe
2828
return session
2929
}()
3030

31+
private var prevChunkBuffer = ""
32+
3133
init(urlRequest: URLRequest) {
3234
self.urlRequest = urlRequest
3335
}
@@ -47,14 +49,16 @@ final class StreamingSession<ResultType: Codable>: NSObject, Identifiable, URLSe
4749
onProcessingError?(self, StreamingError.unknownContent)
4850
return
4951
}
50-
let jsonObjects = stringContent
52+
let jsonObjects = "\(prevChunkBuffer)\(stringContent)"
5153
.components(separatedBy: "data:")
5254
.filter { $0.isEmpty == false }
5355
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
56+
prevChunkBuffer = ""
57+
5458
guard jsonObjects.isEmpty == false, jsonObjects.first != streamingCompletionMarker else {
5559
return
5660
}
57-
jsonObjects.forEach { jsonContent in
61+
jsonObjects.enumerated().forEach { (index, jsonContent) in
5862
guard jsonContent != streamingCompletionMarker else {
5963
return
6064
}
@@ -77,7 +81,12 @@ final class StreamingSession<ResultType: Codable>: NSObject, Identifiable, URLSe
7781
let decoded = try JSONDecoder().decode(APIErrorResponse.self, from: jsonData)
7882
onProcessingError?(self, decoded)
7983
} catch {
80-
onProcessingError?(self, apiError)
84+
if index == jsonObjects.count - 1 {
85+
// Chunk ends in a partial JSON
86+
prevChunkBuffer = "data: \(jsonContent)"
87+
} else {
88+
onProcessingError?(self, apiError)
89+
}
8190
}
8291
}
8392
}

0 commit comments

Comments
 (0)