1
+ using System ;
2
+ using System . IO ;
1
3
using UnityEngine ;
2
4
using System . Text ;
3
5
using Newtonsoft . Json ;
6
+ using System . Threading ;
4
7
using System . Globalization ;
5
8
using System . Threading . Tasks ;
6
9
using UnityEngine . Networking ;
7
10
using System . Collections . Generic ;
8
- using System . IO ;
9
11
using Newtonsoft . Json . Serialization ;
12
+ using System . Linq ;
10
13
11
14
namespace OpenAI
12
15
{
@@ -87,6 +90,61 @@ private async Task<T> DispatchRequest<T>(string path, string method, byte[] payl
87
90
88
91
return data ;
89
92
}
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
+ }
90
148
91
149
/// <summary>
92
150
/// Dispatches an HTTP request to the specified path with a multi-part data form.
@@ -167,6 +225,22 @@ public async Task<CreateCompletionResponse> CreateCompletion(CreateCompletionReq
167
225
return await DispatchRequest < CreateCompletionResponse > ( path , UnityWebRequest . kHttpVerbPOST , payload ) ;
168
226
}
169
227
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
+
170
244
/// <summary>
171
245
/// Creates a chat completion request as in ChatGPT.
172
246
/// </summary>
@@ -176,9 +250,26 @@ public async Task<CreateChatCompletionResponse> CreateChatCompletion(CreateChatC
176
250
{
177
251
var path = $ "{ BASE_PATH } /chat/completions";
178
252
var payload = CreatePayload ( request ) ;
253
+
179
254
return await DispatchRequest < CreateChatCompletionResponse > ( path , UnityWebRequest . kHttpVerbPOST , payload ) ;
180
255
}
181
256
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
+
182
273
/// <summary>
183
274
/// Creates a new edit for the provided input, instruction, and parameters.
184
275
/// </summary>
0 commit comments