1+ using System ;
2+ using System . IO ;
13using UnityEngine ;
24using System . Text ;
35using Newtonsoft . Json ;
6+ using System . Threading ;
47using System . Globalization ;
58using System . Threading . Tasks ;
69using UnityEngine . Networking ;
710using System . Collections . Generic ;
8- using System . IO ;
911using Newtonsoft . Json . Serialization ;
12+ using System . Linq ;
1013
1114namespace OpenAI
1215{
@@ -87,6 +90,61 @@ private async Task<T> DispatchRequest<T>(string path, string method, byte[] payl
8790
8891 return data ;
8992 }
93+
94+ /// <summary>
95+ /// Dispatches an HTTP request to the specified path with the specified method and optional payload.
96+ /// </summary>
97+ /// <param name="path">The path to send the request to.</param>
98+ /// <param name="method">The HTTP method to use for the request.</param>
99+ /// <param name="onResponse">A callback function to be called when a response is updated.</param>
100+ /// <param name="onComplete">A callback function to be called when the request is complete.</param>
101+ /// <param name="token">A cancellation token to cancel the request.</param>
102+ /// <param name="payload">An optional byte array of json payload to include in the request.</param>
103+ private async void DispatchRequest < T > ( string path , string method , Action < List < T > > onResponse , Action onComplete , CancellationTokenSource token , byte [ ] payload = null ) where T : IResponse
104+ {
105+ using ( var request = UnityWebRequest . Put ( path , payload ) )
106+ {
107+ request . method = method ;
108+ request . SetHeaders ( Configuration , ContentType . ApplicationJson ) ;
109+
110+ var asyncOperation = request . SendWebRequest ( ) ;
111+
112+ do
113+ {
114+ List < T > dataList = new List < T > ( ) ;
115+ string [ ] lines = request . downloadHandler . text . Split ( '\n ' ) . Where ( line => line != "" ) . ToArray ( ) ;
116+
117+ foreach ( string line in lines )
118+ {
119+ var value = line . Replace ( "data: " , "" ) ;
120+
121+ if ( value . Contains ( "[DONE]" ) )
122+ {
123+ onComplete ? . Invoke ( ) ;
124+ break ;
125+ }
126+
127+ var data = JsonConvert . DeserializeObject < T > ( value , jsonSerializerSettings ) ;
128+
129+ if ( data ? . Error != null )
130+ {
131+ ApiError error = data . Error ;
132+ Debug . LogError ( $ "Error Message: { error . Message } \n Error Type: { error . Type } \n ") ;
133+ }
134+ else
135+ {
136+ dataList . Add ( data ) ;
137+ }
138+ }
139+ onResponse ? . Invoke ( dataList ) ;
140+
141+ await Task . Yield ( ) ;
142+ }
143+ while ( ! asyncOperation . isDone && ! token . IsCancellationRequested ) ;
144+
145+ onComplete ? . Invoke ( ) ;
146+ }
147+ }
90148
91149 /// <summary>
92150 /// Dispatches an HTTP request to the specified path with a multi-part data form.
@@ -167,6 +225,22 @@ public async Task<CreateCompletionResponse> CreateCompletion(CreateCompletionReq
167225 return await DispatchRequest < CreateCompletionResponse > ( path , UnityWebRequest . kHttpVerbPOST , payload ) ;
168226 }
169227
228+ /// <summary>
229+ /// Creates a chat completion request as in ChatGPT.
230+ /// </summary>
231+ /// <param name="request">See <see cref="CreateChatCompletionRequest"/></param>
232+ /// <param name="onResponse">Callback function that will be called when stream response is updated.</param>
233+ /// <param name="onComplete">Callback function that will be called when stream response is completed.</param>
234+ /// <param name="token">Cancellation token to cancel the request.</param>
235+ public void CreateCompletionAsync ( CreateCompletionRequest request , Action < List < CreateCompletionResponse > > onResponse , Action onComplete , CancellationTokenSource token )
236+ {
237+ request . Stream = true ;
238+ var path = $ "{ BASE_PATH } /completions";
239+ var payload = CreatePayload ( request ) ;
240+
241+ DispatchRequest ( path , UnityWebRequest . kHttpVerbPOST , onResponse , onComplete , token , payload ) ;
242+ }
243+
170244 /// <summary>
171245 /// Creates a chat completion request as in ChatGPT.
172246 /// </summary>
@@ -176,9 +250,26 @@ public async Task<CreateChatCompletionResponse> CreateChatCompletion(CreateChatC
176250 {
177251 var path = $ "{ BASE_PATH } /chat/completions";
178252 var payload = CreatePayload ( request ) ;
253+
179254 return await DispatchRequest < CreateChatCompletionResponse > ( path , UnityWebRequest . kHttpVerbPOST , payload ) ;
180255 }
181256
257+ /// <summary>
258+ /// Creates a chat completion request as in ChatGPT.
259+ /// </summary>
260+ /// <param name="request">See <see cref="CreateChatCompletionRequest"/></param>
261+ /// <param name="onResponse">Callback function that will be called when stream response is updated.</param>
262+ /// <param name="onComplete">Callback function that will be called when stream response is completed.</param>
263+ /// <param name="token">Cancellation token to cancel the request.</param>
264+ public void CreateChatCompletionAsync ( CreateChatCompletionRequest request , Action < List < CreateChatCompletionResponse > > onResponse , Action onComplete , CancellationTokenSource token )
265+ {
266+ request . Stream = true ;
267+ var path = $ "{ BASE_PATH } /chat/completions";
268+ var payload = CreatePayload ( request ) ;
269+
270+ DispatchRequest ( path , UnityWebRequest . kHttpVerbPOST , onResponse , onComplete , token , payload ) ;
271+ }
272+
182273 /// <summary>
183274 /// Creates a new edit for the provided input, instruction, and parameters.
184275 /// </summary>
0 commit comments