26#include "CoreMinimal.h"
29#include "Types/AllTypesHeader.h"
30#include "FuncLib/OpenAIFuncLib.h"
31#include "FuncLib/JsonFuncLib.h"
32#include "Provider/JsonParsers/ChatParser.h"
33#include "JsonObjectConverter.h"
34#include "OpenAIProvider.generated.h"
51 void SetAPI(
const TSharedPtr<OpenAI::IAPI>& API);
64 void RetrieveModel(
const FString& ModelName,
const FOpenAIAuth& Auth);
70 void DeleteFineTunedModel(
const FString& ModelID,
const FOpenAIAuth& Auth);
144 void DeleteFile(
const FString& FileID,
const FOpenAIAuth& Auth);
150 void RetrieveFile(
const FString& FileID,
const FOpenAIAuth& Auth);
156 void RetrieveFileContent(
const FString& FileID,
const FOpenAIAuth& Auth);
181 void ListFineTuningEvents(
188 void ListFineTuningCheckpoints(
195 void RetrieveFineTuningJob(
const FString& FineTuningJobID,
const FOpenAIAuth& Auth);
201 void CancelFineTuningJob(
const FString& FineTuneID,
const FOpenAIAuth& Auth);
214 void RetrieveBatch(
const FString& BatchId,
const FOpenAIAuth& Auth);
223 void CancelBatch(
const FString& BatchId,
const FOpenAIAuth& Auth);
257 void CancelUpload(
const FString& UploadId,
const FOpenAIAuth& Auth);
275 void RetrieveAssistant(
const FString& AssistantId,
const FOpenAIAuth& Auth);
287 void DeleteAssistant(
const FString& AssistantId,
const FOpenAIAuth& Auth);
294#define DEFINE_EVENT_GETTER(Name) \
296 FOn##Name& On##Name() { return Name; } \
302 FOnRequestError& OnRequestError() {
return RequestError; };
303 DEFINE_EVENT_GETTER(ListModelsCompleted)
304 DEFINE_EVENT_GETTER(RetrieveModelCompleted)
305 DEFINE_EVENT_GETTER(CreateCompletionCompleted)
306 DEFINE_EVENT_GETTER(CreateCompletionStreamCompleted)
307 DEFINE_EVENT_GETTER(CreateCompletionStreamProgresses)
308 DEFINE_EVENT_GETTER(CreateChatCompletionCompleted)
309 DEFINE_EVENT_GETTER(CreateChatCompletionStreamCompleted)
310 DEFINE_EVENT_GETTER(CreateChatCompletionStreamProgresses)
311 DEFINE_EVENT_GETTER(CreateImageCompleted)
312 DEFINE_EVENT_GETTER(CreateImageEditCompleted)
313 DEFINE_EVENT_GETTER(CreateImageVariationCompleted)
314 DEFINE_EVENT_GETTER(CreateEmbeddingsCompleted)
315 DEFINE_EVENT_GETTER(CreateSpeechCompleted)
316 DEFINE_EVENT_GETTER(CreateAudioTranscriptionCompleted)
317 DEFINE_EVENT_GETTER(CreateAudioTranscriptionVerboseCompleted)
318 DEFINE_EVENT_GETTER(CreateAudioTranslationCompleted)
319 DEFINE_EVENT_GETTER(ListFilesCompleted)
320 DEFINE_EVENT_GETTER(UploadFileCompleted)
321 DEFINE_EVENT_GETTER(DeleteFileCompleted)
322 DEFINE_EVENT_GETTER(RetrieveFileCompleted)
323 DEFINE_EVENT_GETTER(RetrieveFileContentCompleted)
324 DEFINE_EVENT_GETTER(CreateFineTuningJobCompleted)
325 DEFINE_EVENT_GETTER(ListFineTuningJobsCompleted)
326 DEFINE_EVENT_GETTER(ListFineTuningEventsCompleted)
327 DEFINE_EVENT_GETTER(ListFineTuningCheckpointsCompleted)
328 DEFINE_EVENT_GETTER(DeleteFineTunedModelCompleted)
329 DEFINE_EVENT_GETTER(CreateModerationsCompleted)
330 DEFINE_EVENT_GETTER(RetrieveFineTuningJobCompleted)
331 DEFINE_EVENT_GETTER(CancelFineTuningJobCompleted)
332 DEFINE_EVENT_GETTER(ListBatchCompleted)
333 DEFINE_EVENT_GETTER(CreateBatchCompleted)
334 DEFINE_EVENT_GETTER(RetrieveBatchCompleted)
335 DEFINE_EVENT_GETTER(CancelBatchCompleted)
336 DEFINE_EVENT_GETTER(CreateUploadCompleted)
337 DEFINE_EVENT_GETTER(AddUploadPartCompleted)
338 DEFINE_EVENT_GETTER(CompleteUploadCompleted)
339 DEFINE_EVENT_GETTER(CancelUploadCompleted)
340 DEFINE_EVENT_GETTER(CreateAssistantCompleted)
341 DEFINE_EVENT_GETTER(ListAssistantsCompleted)
342 DEFINE_EVENT_GETTER(RetrieveAssistantCompleted)
343 DEFINE_EVENT_GETTER(ModifyAssistantCompleted)
344 DEFINE_EVENT_GETTER(DeleteAssistantCompleted)
347 TSharedPtr<OpenAI::IAPI> API;
348 bool bLogEnabled{
true};
349 FOnRequestError RequestError;
351#define DECLARE_HTTP_CALLBACK(Callback) virtual void Callback(FHttpRequestPtr Request, FHttpResponsePtr Response, bool WasSuccessful);
352#define DECLARE_HTTP_CALLBACK_PROGRESS(Callback) virtual void Callback(FHttpRequestPtr Request, uint64 BytesSent, uint64 BytesReceived);
354 DECLARE_HTTP_CALLBACK(OnListModelsCompleted)
355 DECLARE_HTTP_CALLBACK(OnRetrieveModelCompleted)
356 DECLARE_HTTP_CALLBACK(OnCreateCompletionCompleted)
357 DECLARE_HTTP_CALLBACK(OnCreateCompletionStreamCompleted)
358 DECLARE_HTTP_CALLBACK_PROGRESS(OnCreateCompletionStreamProgress)
359 DECLARE_HTTP_CALLBACK(OnCreateChatCompletionCompleted)
360 DECLARE_HTTP_CALLBACK(OnCreateChatCompletionStreamCompleted)
361 DECLARE_HTTP_CALLBACK_PROGRESS(OnCreateChatCompletionStreamProgress)
362 DECLARE_HTTP_CALLBACK(OnCreateImageCompleted)
363 DECLARE_HTTP_CALLBACK(OnCreateImageEditCompleted)
364 DECLARE_HTTP_CALLBACK(OnCreateImageVariationCompleted)
365 DECLARE_HTTP_CALLBACK(OnCreateEmbeddingsCompleted)
366 DECLARE_HTTP_CALLBACK(OnCreateSpeechCompleted)
367 DECLARE_HTTP_CALLBACK(OnCreateAudioTranscriptionCompleted)
368 DECLARE_HTTP_CALLBACK(OnCreateAudioTranslationCompleted)
369 DECLARE_HTTP_CALLBACK(OnListFilesCompleted)
370 DECLARE_HTTP_CALLBACK(OnUploadFileCompleted)
371 DECLARE_HTTP_CALLBACK(OnDeleteFileCompleted)
372 DECLARE_HTTP_CALLBACK(OnRetrieveFileCompleted)
373 DECLARE_HTTP_CALLBACK(OnRetrieveFileContentCompleted)
374 DECLARE_HTTP_CALLBACK(OnDeleteFineTunedModelCompleted)
375 DECLARE_HTTP_CALLBACK(OnCreateModerationsCompleted)
376 DECLARE_HTTP_CALLBACK(OnCreateFineTuningJobCompleted)
377 DECLARE_HTTP_CALLBACK(OnListFineTuningJobsCompleted)
378 DECLARE_HTTP_CALLBACK(OnListFineTuningEventsCompleted)
379 DECLARE_HTTP_CALLBACK(OnListFineTuningCheckpointsCompleted)
380 DECLARE_HTTP_CALLBACK(OnRetrieveFineTuningJobCompleted)
381 DECLARE_HTTP_CALLBACK(OnCancelFineTuningJobCompleted)
382 DECLARE_HTTP_CALLBACK(OnCreateBatchCompleted)
383 DECLARE_HTTP_CALLBACK(OnRetrieveBatchCompleted)
384 DECLARE_HTTP_CALLBACK(OnCancelBatchCompleted)
385 DECLARE_HTTP_CALLBACK(OnListBatchCompleted)
386 DECLARE_HTTP_CALLBACK(OnCreateUploadCompleted)
387 DECLARE_HTTP_CALLBACK(OnAddUploadPartCompleted)
388 DECLARE_HTTP_CALLBACK(OnCompleteUploadCompleted)
389 DECLARE_HTTP_CALLBACK(OnCancelUploadCompleted)
390 DECLARE_HTTP_CALLBACK(OnCreateAssistantCompleted)
391 DECLARE_HTTP_CALLBACK(OnListAssistantsCompleted)
392 DECLARE_HTTP_CALLBACK(OnRetrieveAssistantCompleted)
393 DECLARE_HTTP_CALLBACK(OnModifyAssistantCompleted)
394 DECLARE_HTTP_CALLBACK(OnDeleteAssistantCompleted)
396 void ProcessRequest(FHttpRequestRef HttpRequest);
398 bool Success(FHttpResponsePtr Response,
bool WasSuccessful);
399 void Log(
const FString& Info)
const;
400 void LogResponse(FHttpResponsePtr Response)
const;
401 void LogError(
const FString& ErrorText)
const;
403 template <
typename OutStructType>
404 FString SerializeRequest(
const OutStructType& OutStruct)
const
406 TSharedPtr<FJsonObject> Json = FJsonObjectConverter::UStructToJsonObject(OutStruct);
407 UJsonFuncLib::RemoveEmptyArrays(Json);
408 FString RequestBodyStr;
409 UJsonFuncLib::JsonToString(Json, RequestBodyStr);
410 return RequestBodyStr;
413 FHttpRequestRef MakeRequestHeaders(
const FOpenAIAuth& Auth)
const;
416 template <
typename OutStructType>
417 FHttpRequestRef MakeRequest(
const OutStructType& OutStruct,
const FString& URL,
const FString& Method,
const FOpenAIAuth& Auth)
const
419 auto HttpRequest = MakeRequestHeaders(Auth);
420 HttpRequest->SetURL(URL);
421 HttpRequest->SetVerb(Method);
423 const FString Content = SerializeRequest(OutStruct);
424 Log(FString(
"Content: ").Append(Content));
426 const FString PostprocessedContent = UJsonFuncLib::RemoveOptionalValuesThatNotSet(Content);
427 Log(FString(
"Postprocessed content was set as: ").Append(PostprocessedContent));
429 HttpRequest->SetContentAsString(PostprocessedContent);
433 FHttpRequestRef MakeRequest(
const FString& URL,
const FString& Method,
const FOpenAIAuth& Auth)
const;
434 FHttpRequestRef MakeRequest(
437 template <
typename ParsedResponseType,
typename DelegateType>
438 void HandleResponse(FHttpResponsePtr Response,
bool WasSuccessful, DelegateType& Delegate)
440 if (!Success(Response, WasSuccessful))
return;
442 const FString Content = Response.IsValid() ? Response->GetContentAsString() : FString{};
443 const FString ResponseURL = Response.IsValid() ? Response->GetURL() : FString{};
445 ParsedResponseType ParsedResponse;
446 if (UJsonFuncLib::ParseJSONToStruct(Content, &ParsedResponse))
448 Delegate.Broadcast(ParsedResponse, GetResponseHeaders(Response));
452 LogError(
"JSON deserialization error");
453 RequestError.Broadcast(ResponseURL, Content);
457 virtual TSharedRef<IHttpRequest, ESPMode::ThreadSafe> CreateRequest()
const {
return FHttpModule::Get().CreateRequest(); }
460 void SetOptional(TSharedPtr<FJsonObject> RequestBody,
const TOptional<FString>& Param,
const FString& ParamName);
461 void SetOptional(TSharedPtr<FJsonObject> RequestBody,
const TOptional<bool>& Param,
const FString& ParamName);
462 void SetOptional(TSharedPtr<FJsonObject> RequestBody,
const TOptional<TArray<float>>& Param,
const FString& ParamName);
464 template <
typename NumberType>
465 void SetOptional(TSharedPtr<FJsonObject> RequestBody,
const TOptional<NumberType>& Param,
const FString& ParamName)
467 if (!Param.IsSet())
return;
468 RequestBody->SetNumberField(ParamName, Param.GetValue());
472 TTuple<FString, FString> GetErrorData(FHttpRequestPtr Request, FHttpResponsePtr Response)
const;
474 template <
typename ResponseType>
475 bool ParseStreamRequest(FHttpResponsePtr Response, TArray<ResponseType>& Responses)
477 if (!Response.IsValid())
return false;
479 TArray<FString> StringArray;
480 Response->GetContentAsString().ParseIntoArrayLines(StringArray);
482 for (
auto& String : StringArray)
484 bool LastString{
false};
485 if (OpenAI::ChatParser::CleanChunkResponseString(String, LastString))
491 ResponseType ParsedResponse;
492 if (!UJsonFuncLib::ParseJSONToStruct(String, &ParsedResponse))
continue;
494 Responses.Add(ParsedResponse);
500 template <
typename ResponseType,
typename DelegateType>
501 void OnStreamProgress(FHttpRequestPtr Request, uint64 BytesSent, uint64 BytesReceived, DelegateType& Delegate)
503 const auto& Response = Request->GetResponse();
504 TArray<ResponseType> ParsedResponses;
506 if (ParseStreamRequest(Response, ParsedResponses))
508 LogResponse(Response);
509 Delegate.Broadcast(ParsedResponses, GetResponseHeaders(Response));
511 else if (Response.IsValid())
513 LogError(Response->GetContentAsString());
516 else if (BytesReceived == 0)
524 LogError(FString::Format(TEXT(
"JSON deserialization error BytesSent:{0} BytesReceived:{1}"), {BytesSent, BytesReceived}));
528 template <
typename ResponseType,
typename DelegateType>
529 void OnStreamCompleted(FHttpRequestPtr Request, FHttpResponsePtr Response,
bool WasSuccessful, DelegateType& Delegate)
533 const auto& [URL, Content] = GetErrorData(Request, Response);
535 RequestError.Broadcast(URL, Content);
539 TArray<ResponseType> ParsedResponses;
540 if (ParseStreamRequest(Response, ParsedResponses))
542 LogResponse(Response);
543 Delegate.Broadcast(ParsedResponses, GetResponseHeaders(Response));
547 const FString Content = Response.IsValid() ? Response->GetContentAsString() : FString{};
548 const FString ResponseURL = Response.IsValid() ? Response->GetURL() : FString{};
550 LogError(
"JSON deserialization error");
552 RequestError.Broadcast(ResponseURL, Content);
Definition: OpenAI.Build.cs:6
Definition: OpenAIProvider.h:45
void SetLogEnabled(bool LogEnabled)
Definition: OpenAIProvider.h:292
Definition: UploadTypes.h:58
Definition: AudioTypes.h:103
Definition: AudioTypes.h:127
Definition: ChatCommonTypes.h:159
Definition: UploadTypes.h:70
Definition: CompletionTypes.h:16
Definition: AssistantTypes.h:42
Definition: BatchTypes.h:29
Definition: UploadTypes.h:24
Definition: EmbeddingTypes.h:22
Definition: FineTuneTypes.h:103
Definition: FineTuneTypes.h:168
Definition: AssistantTypes.h:123
Definition: BatchTypes.h:68
Definition: ModerationTypes.h:21
Definition: AssistantTypes.h:179
Definition: CommonTypes.h:11
Definition: ImageTypes.h:124
Definition: ImageTypes.h:61
Definition: ImageTypes.h:183
Definition: AudioTypes.h:133
Definition: FileTypes.h:28