@@ -95,30 +95,28 @@ public class ChatGPTService: ChatGPTServiceType {
9595 return AsyncThrowingStream < String , Error > { continuation in
9696 Task ( priority: . userInitiated) {
9797 do {
98- let stream = try await sendMemory ( )
9998 var functionCall : ChatMessage . FunctionCall ?
100- var functionCallMessageID = uuidGenerator ( )
101- for try await content in stream {
102- switch content {
103- case let . text( text) :
104- continuation. yield ( text)
105- case let . functionCall( call) :
106- functionCall = call
107- await prepareFunctionCall ( call, messageId: functionCallMessageID)
99+ var functionCallMessageID = " "
100+ var isInitialCall = true
101+ while functionCall != nil || isInitialCall {
102+ isInitialCall = false
103+ if let call = functionCall {
104+ functionCall = nil
105+ await runFunctionCall ( call, messageId: functionCallMessageID)
108106 }
109- }
110-
111- while let call = functionCall {
112- functionCall = nil
113- await runFunctionCall ( call)
114- functionCallMessageID = uuidGenerator ( )
115- let nextStream = try await sendMemory ( )
116- for try await content in nextStream {
107+ let stream = try await sendMemory ( )
108+ for try await content in stream {
117109 switch content {
118110 case let . text( text) :
119111 continuation. yield ( text)
120112 case let . functionCall( call) :
121- functionCall = call
113+ if functionCall == nil {
114+ functionCallMessageID = uuidGenerator ( )
115+ functionCall = call
116+ } else {
117+ functionCall? . name. append ( call. name)
118+ functionCall? . arguments. append ( call. arguments)
119+ }
122120 await prepareFunctionCall ( call, messageId: functionCallMessageID)
123121 }
124122 }
@@ -180,7 +178,14 @@ extension ChatGPTService {
180178 else { throw ChatGPTServiceError . endpointIncorrect }
181179
182180 let messages = await memory. messages. map {
183- CompletionRequestBody . Message ( role: $0. role, content: $0. content)
181+ CompletionRequestBody . Message (
182+ role: $0. role,
183+ content: $0. content ?? " " ,
184+ name: $0. name,
185+ function_call: $0. functionCall. map {
186+ . init( name: $0. name, arguments: $0. arguments)
187+ }
188+ )
184189 }
185190 let remainingTokens = await memory. remainingTokens
186191
@@ -195,7 +200,13 @@ extension ChatGPTService {
195200 remainingTokens: remainingTokens
196201 ) ,
197202 function_call: nil ,
198- functions: functionProvider. functionSchemas
203+ functions: functionProvider. functions. map {
204+ ChatGPTFunctionSchema (
205+ name: $0. name,
206+ description: $0. description,
207+ parameters: $0. argumentSchema
208+ )
209+ }
199210 )
200211
201212 let api = buildCompletionStreamAPI (
@@ -213,13 +224,15 @@ extension ChatGPTService {
213224 for try await trunk in trunks {
214225 guard let delta = trunk. choices. first? . delta else { continue }
215226
216- // The api will always return a function call with correct JSON format .
227+ // The api will always return a function call with JSON object .
217228 // The first round will contain the function name and an empty argument.
218229 // e.g. {"name":"weather","arguments":""}
219- let functionCall : ChatMessage . FunctionCall ? = delta. function_call. flatMap {
220- guard let data = $0. data ( using: . utf8) else { return nil }
221- return try ? JSONDecoder ( )
222- . decode ( ChatMessage . FunctionCall. self, from: data)
230+ // The other rounds will contain part of the arguments.
231+ let functionCall = delta. function_call. map {
232+ ChatMessage . FunctionCall (
233+ name: $0. name ?? " " ,
234+ arguments: $0. arguments ?? " "
235+ )
223236 }
224237
225238 await memory. streamMessage (
@@ -264,11 +277,10 @@ extension ChatGPTService {
264277 let messages = await memory. messages. map {
265278 CompletionRequestBody . Message (
266279 role: $0. role,
267- content: $0. content,
280+ content: $0. content ?? " " ,
268281 name: $0. name,
269282 function_call: $0. functionCall. map {
270- CompletionRequestBody
271- . MessageFunctionCall ( name: $0. name, arguments: $0. arguments)
283+ . init( name: $0. name, arguments: $0. arguments)
272284 }
273285 )
274286 }
@@ -285,7 +297,13 @@ extension ChatGPTService {
285297 remainingTokens: remainingTokens
286298 ) ,
287299 function_call: nil ,
288- functions: functionProvider. functionSchemas
300+ functions: functionProvider. functions. map {
301+ ChatGPTFunctionSchema (
302+ name: $0. name,
303+ description: $0. description,
304+ parameters: $0. argumentSchema
305+ )
306+ }
289307 )
290308
291309 let api = buildCompletionAPI (
@@ -303,13 +321,13 @@ extension ChatGPTService {
303321 content: choice. message. content,
304322 name: choice. message. name,
305323 functionCall: choice. message. function_call. map {
306- ChatMessage . FunctionCall ( name: $0. name, arguments: $0. arguments)
324+ ChatMessage . FunctionCall ( name: $0. name, arguments: $0. arguments ?? " " )
307325 }
308326 )
309327 await memory. appendMessage ( message)
310328 return message
311329 }
312-
330+
313331 /// When a function call is detected, but arguments are not yet ready, we can call this
314332 /// to insert a message placeholder in memory.
315333 func prepareFunctionCall( _ call: ChatMessage . FunctionCall , messageId: String ) async {
@@ -318,6 +336,7 @@ extension ChatGPTService {
318336 id: messageId,
319337 role: . function,
320338 content: nil ,
339+ name: call. name,
321340 summary: function. message ( at: . detected)
322341 )
323342 await memory. appendMessage ( responseMessage)
@@ -348,32 +367,32 @@ extension ChatGPTService {
348367 id: messageId,
349368 role: . function,
350369 content: nil ,
351- summary : function
352- . message ( at: . processing( argumentsJsonString: call. arguments ?? " " ) )
370+ name : call . name ,
371+ summary : function . message ( at: . processing( argumentsJsonString: call. arguments) )
353372 )
354373 await memory. appendMessage ( responseMessage)
355374
356375 do {
357376 // Run the function
358- let response = try await function
359- . call ( argumentsJsonString: call. arguments ?? " " )
377+ let result = try await function
378+ . call ( argumentsJsonString: call. arguments)
360379
361380 // Update the message to display the finish state of the function.
362381 await memory. updateMessage ( id: messageId) { message in
363- message. content = response
382+ message. content = result . botReadableContent
364383 message. summary = function. message ( at: . ended(
365- argumentsJsonString: call. arguments ?? " " ,
366- result: response
384+ argumentsJsonString: call. arguments,
385+ result: result
367386 ) )
368387 }
369- return response
388+ return result . botReadableContent
370389 } catch {
371390 // For errors, use the error message as the result.
372391 let content = " Error: \( error. localizedDescription) "
373392 await memory. updateMessage ( id: messageId) { message in
374393 message. content = content
375394 message. summary = function. message ( at: . error(
376- argumentsJsonString: call. arguments ?? " " ,
395+ argumentsJsonString: call. arguments,
377396 result: error
378397 ) )
379398 }
0 commit comments