1+ import AIModel
12import AsyncAlgorithms
23import Foundation
34import Preferences
4- import AIModel
55
66typealias CompletionStreamAPIBuilder = ( String , ChatModel , URL , CompletionRequestBody )
7- -> CompletionStreamAPI
7+ -> any CompletionStreamAPI
88
99protocol CompletionStreamAPI {
10- func callAsFunction( ) async throws -> (
11- trunkStream: AsyncThrowingStream < CompletionStreamDataTrunk , Error > ,
12- cancel: Cancellable
13- )
10+ func callAsFunction( ) async throws -> AsyncThrowingStream < CompletionStreamDataChunk , Error >
1411}
1512
1613public enum FunctionCallStrategy : Codable , Equatable {
@@ -128,7 +125,7 @@ struct CompletionRequestBody: Codable, Equatable {
128125 }
129126}
130127
131- struct CompletionStreamDataTrunk : Codable {
128+ struct CompletionStreamDataChunk : Codable {
132129 var id : String ?
133130 var object : String ?
134131 var model : String ?
@@ -171,10 +168,7 @@ struct OpenAICompletionStreamAPI: CompletionStreamAPI {
171168 self . model = model
172169 }
173170
174- func callAsFunction( ) async throws -> (
175- trunkStream: AsyncThrowingStream < CompletionStreamDataTrunk , Error > ,
176- cancel: Cancellable
177- ) {
171+ func callAsFunction( ) async throws -> AsyncThrowingStream < CompletionStreamDataChunk , Error > {
178172 var request = URLRequest ( url: endpoint)
179173 request. httpMethod = " POST "
180174 let encoder = JSONEncoder ( )
@@ -187,7 +181,7 @@ struct OpenAICompletionStreamAPI: CompletionStreamAPI {
187181 case . azureOpenAI:
188182 request. setValue ( apiKey, forHTTPHeaderField: " api-key " )
189183 case . googleAI:
190- assert ( false , " Unsupported " )
184+ assertionFailure ( " Unsupported " )
191185 }
192186 }
193187
@@ -207,35 +201,31 @@ struct OpenAICompletionStreamAPI: CompletionStreamAPI {
207201 throw error ?? ChatGPTServiceError . responseInvalid
208202 }
209203
210- var receivingDataTask : Task < Void , Error > ?
211-
212- let stream = AsyncThrowingStream < CompletionStreamDataTrunk , Error > { continuation in
213- receivingDataTask = Task {
204+ let stream = AsyncThrowingStream < CompletionStreamDataChunk , Error > { continuation in
205+ let task = Task {
214206 do {
215207 for try await line in result. lines {
216208 if Task . isCancelled { break }
217209 let prefix = " data: "
218210 guard line. hasPrefix ( prefix) ,
219211 let content = line. dropFirst ( prefix. count) . data ( using: . utf8) ,
220- let trunk = try ? JSONDecoder ( )
221- . decode ( CompletionStreamDataTrunk . self, from: content)
212+ let chunk = try ? JSONDecoder ( )
213+ . decode ( CompletionStreamDataChunk . self, from: content)
222214 else { continue }
223- continuation. yield ( trunk )
215+ continuation. yield ( chunk )
224216 }
225217 continuation. finish ( )
226218 } catch {
227219 continuation. finish ( throwing: error)
228220 }
229221 }
230- }
231-
232- return (
233- stream,
234- Cancellable {
222+ continuation. onTermination = { _ in
223+ task. cancel ( )
235224 result. task. cancel ( )
236- receivingDataTask? . cancel ( )
237225 }
238- )
226+ }
227+
228+ return stream
239229 }
240230}
241231
0 commit comments