@@ -88,6 +88,7 @@ public actor ChatGPTService: ChatGPTServiceType {
8888 var uuidGenerator : ( ) -> String = { UUID ( ) . uuidString }
8989 var cancelTask : Cancellable ?
9090 var buildCompletionStreamAPI : CompletionStreamAPIBuilder = OpenAICompletionStreamAPI . init
91+ var buildCompletionAPI : CompletionAPIBuilder = OpenAICompletionAPI . init
9192
9293 public init (
9394 systemPrompt: String = " " ,
@@ -121,72 +122,99 @@ public actor ChatGPTService: ChatGPTServiceType {
121122
122123 isReceivingMessage = true
123124
124- do {
125- let api = buildCompletionStreamAPI ( apiKey, url, requestBody)
125+ let api = buildCompletionStreamAPI ( apiKey, url, requestBody)
126126
127- return AsyncThrowingStream < String , Error > { continuation in
128- Task {
129- do {
130- let ( trunks, cancel) = try await api ( )
131- guard isReceivingMessage else {
132- continuation. finish ( )
133- return
134- }
135- cancelTask = cancel
136- for try await trunk in trunks {
137- guard let delta = trunk. choices. first? . delta else { continue }
138-
139- if history. last? . id == trunk. id {
140- if let role = delta. role {
141- history [ history. endIndex - 1 ] . role = role
142- }
143- if let content = delta. content {
144- history [ history. endIndex - 1 ] . content. append ( content)
145- }
146- } else {
147- history. append ( . init(
148- id: trunk. id,
149- role: delta. role ?? . assistant,
150- content: delta. content ?? " "
151- ) )
152- }
127+ return AsyncThrowingStream < String , Error > { continuation in
128+ Task {
129+ do {
130+ let ( trunks, cancel) = try await api ( )
131+ guard isReceivingMessage else {
132+ continuation. finish ( )
133+ return
134+ }
135+ cancelTask = cancel
136+ for try await trunk in trunks {
137+ guard let delta = trunk. choices. first? . delta else { continue }
153138
139+ if history. last? . id == trunk. id {
140+ if let role = delta. role {
141+ history [ history. endIndex - 1 ] . role = role
142+ }
154143 if let content = delta. content {
155- continuation . yield ( content)
144+ history [ history . endIndex - 1 ] . content . append ( content)
156145 }
146+ } else {
147+ history. append ( . init(
148+ id: trunk. id,
149+ role: delta. role ?? . assistant,
150+ content: delta. content ?? " "
151+ ) )
157152 }
158153
159- continuation. finish ( )
160- isReceivingMessage = false
161- } catch let error as CancellationError {
162- isReceivingMessage = false
163- continuation. finish ( throwing: error)
164- } catch let error as NSError where error. code == NSURLErrorCancelled {
165- isReceivingMessage = false
166- continuation. finish ( throwing: error)
167- } catch {
168- history. append ( . init(
169- role: . assistant,
170- content: error. localizedDescription
171- ) )
172- isReceivingMessage = false
173- continuation. finish ( throwing: error)
154+ if let content = delta. content {
155+ continuation. yield ( content)
156+ }
174157 }
158+
159+ continuation. finish ( )
160+ isReceivingMessage = false
161+ } catch let error as CancellationError {
162+ isReceivingMessage = false
163+ continuation. finish ( throwing: error)
164+ } catch let error as NSError where error. code == NSURLErrorCancelled {
165+ isReceivingMessage = false
166+ continuation. finish ( throwing: error)
167+ } catch {
168+ history. append ( . init(
169+ role: . assistant,
170+ content: error. localizedDescription
171+ ) )
172+ isReceivingMessage = false
173+ continuation. finish ( throwing: error)
175174 }
176175 }
177176 }
178177 }
179-
178+
180179 public func sendAndWait(
181180 content: String ,
182181 summary: String ? = nil
183- ) async throws -> String {
184- let stream = try await send ( content: content, summary: summary)
185- var content = " "
186- for try await fragment in stream {
187- content. append ( fragment)
182+ ) async throws -> String ? {
183+ guard !isReceivingMessage else { throw CancellationError ( ) }
184+ guard let url = URL ( string: endpoint) else { throw ChatGPTServiceError . endpointIncorrect }
185+ let newMessage = ChatMessage (
186+ id: uuidGenerator ( ) ,
187+ role: . user,
188+ content: content,
189+ summary: summary
190+ )
191+ history. append ( newMessage)
192+
193+ let requestBody = CompletionRequestBody (
194+ model: model,
195+ messages: combineHistoryWithSystemPrompt ( ) ,
196+ temperature: temperature,
197+ stream: true ,
198+ max_tokens: maxToken
199+ )
200+
201+ isReceivingMessage = true
202+ defer { isReceivingMessage = false }
203+
204+ let api = buildCompletionAPI ( apiKey, url, requestBody)
205+ let response = try await api ( )
206+
207+ if let choice = response. choices. first {
208+ history. append ( . init(
209+ id: response. id,
210+ role: choice. message. role,
211+ content: choice. message. content
212+ ) )
213+
214+ return choice. message. content
188215 }
189- return content
216+
217+ return nil
190218 }
191219
192220 public func stopReceivingMessage( ) {
@@ -231,7 +259,7 @@ extension ChatGPTService {
231259 all. append ( . init( role: message. role, content: message. content) )
232260 count += 1
233261 }
234-
262+
235263 all. append ( . init( role: . system, content: systemPrompt) )
236264 return all. reversed ( )
237265 }
0 commit comments