Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
Support for UE4.27 & UE5.0 (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucoiso authored Mar 22, 2023
1 parent 674a8ea commit 4d9e7fe
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 39 deletions.
8 changes: 1 addition & 7 deletions Config/FilterPlugin.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,2 @@
[FilterPlugin]
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
;
; Examples:
; /README.txt
; /Extras/...
; /Binaries/ThirdParty/*.dll
Config/DefaultHttpGPT.ini
9 changes: 4 additions & 5 deletions HttpGPT.uplugin
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"FileVersion": 3,
"Version": 7,
"VersionName": "1.4.2",
"EngineVersion": "5.1.0",
"Version": 8,
"VersionName": "1.4.3",
"FriendlyName": "HttpGPT - ChatGPT integrated in the Engine",
"Description": "HttpGPT is an Unreal Engine plugin that facilitates integration with Chat GPT through asynchronous REST requests, making it easy for developers to communicate with the chatbot. HttpGPT also includes a new Editor Tool to integrate Chat GPT directly in the Engine.",
"Category": "Messaging",
Expand All @@ -20,7 +19,7 @@
"Name": "HttpGPT",
"Type": "Runtime",
"LoadingPhase": "Default",
"PlatformAllowList": [
"WhitelistPlatforms": [
"Win64",
"Mac",
"Linux",
Expand All @@ -31,7 +30,7 @@
{
"Name": "HttpGPTEditor",
"Type": "Editor",
"PlatformAllowList": [
"WhitelistPlatforms": [
"Win64",
"Mac",
"Linux"
Expand Down
3 changes: 2 additions & 1 deletion Source/HttpGPT/Private/HttpGPTHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Repo: https://github.com/lucoiso/UEHttpGPT

#include "HttpGPTHelper.h"
#include <HttpGPTInternalFuncs.h>

#ifdef UE_INLINE_GENERATED_CPP_BY_NAME
#include UE_INLINE_GENERATED_CPP_BY_NAME(HttpGPTHelper)
Expand Down Expand Up @@ -77,7 +78,7 @@ const TArray<FName> UHttpGPTHelper::GetAvailableGPTModels()

for (uint8 Iterator = static_cast<uint8>(EHttpGPTModel::gpt4); Iterator <= static_cast<uint8>(EHttpGPTModel::codedavinci002); ++Iterator)
{
if (const FName ModelName = ModelToName(static_cast<EHttpGPTModel>(Iterator)); !ModelName.IsNone())
if (const FName ModelName = ModelToName(static_cast<EHttpGPTModel>(Iterator)); !HttpGPT::Internal::HasEmptyParam(ModelName))
{
Output.Add(ModelName);
}
Expand Down
25 changes: 13 additions & 12 deletions Source/HttpGPT/Private/HttpGPTRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "HttpGPTRequest.h"
#include "HttpGPTSettings.h"
#include "HttpGPTHelper.h"
#include "HttpGPTInternalFuncs.h"
#include "LogHttpGPT.h"
#include <HttpModule.h>
#include <Interfaces/IHttpRequest.h>
Expand Down Expand Up @@ -92,7 +93,7 @@ void UHttpGPTRequest::Activate()

bIsActive = true;

if (Messages.IsEmpty() || TaskOptions.APIKey.IsNone())
if (HttpGPT::Internal::HasEmptyParam(Messages) || HttpGPT::Internal::HasEmptyParam(TaskOptions.APIKey))
{
UE_LOG(LogHttpGPT, Error, TEXT("%s (%d): Failed to activate task: Request not sent due to invalid params"), *FString(__func__), GetUniqueID());
RequestFailed.Broadcast();
Expand Down Expand Up @@ -222,23 +223,23 @@ void UHttpGPTRequest::SetRequestContent()
JsonRequest->SetNumberField("presence_penalty", TaskOptions.PresencePenalty);
JsonRequest->SetNumberField("frequency_penalty", TaskOptions.FrequencyPenalty);

if (!TaskOptions.User.IsNone())
if (!HttpGPT::Internal::HasEmptyParam(TaskOptions.User))
{
JsonRequest->SetStringField("user", TaskOptions.User.ToString());
}

if (!TaskOptions.Stop.IsEmpty())
if (!HttpGPT::Internal::HasEmptyParam(TaskOptions.Stop))
{
TArray<TSharedPtr<FJsonValue>> StopJson;
for (const FName& Iterator : TaskOptions.Stop)
{
StopJson.Add(MakeShareable(new FJsonValueString(Iterator.ToString())));
}
for (const FName& Iterator : TaskOptions.Stop)
{
StopJson.Add(MakeShareable(new FJsonValueString(Iterator.ToString())));
}

JsonRequest->SetArrayField("stop", StopJson);
}

if (!TaskOptions.LogitBias.IsEmpty())
if (!HttpGPT::Internal::HasEmptyParam(TaskOptions.LogitBias))
{
TSharedPtr<FJsonObject> LogitBiasJson = MakeShareable(new FJsonObject());
for (auto Iterator = TaskOptions.LogitBias.CreateConstIterator(); Iterator; ++Iterator)
Expand Down Expand Up @@ -321,7 +322,7 @@ void UHttpGPTRequest::OnProgressUpdated(const FString& Content, int32 BytesSent,
{
FScopeLock Lock(&Mutex);

if (Content.IsEmpty())
if (HttpGPT::Internal::HasEmptyParam(Content))
{
return;
}
Expand Down Expand Up @@ -364,7 +365,7 @@ void UHttpGPTRequest::OnProgressCompleted(const FString& Content, const bool bWa
{
FScopeLock Lock(&Mutex);

if (!bWasSuccessful || Content.IsEmpty())
if (!bWasSuccessful || HttpGPT::Internal::HasEmptyParam(Content))
{
UE_LOG(LogHttpGPT, Error, TEXT("%s (%d): Request failed"), *FString(__func__), GetUniqueID());
AsyncTask(ENamedThreads::GameThread,
Expand Down Expand Up @@ -429,7 +430,7 @@ TArray<FString> UHttpGPTRequest::GetDeltasFromContent(const FString& Content) co
Deltas.Pop();
}

if (Deltas.IsEmpty())
if (HttpGPT::Internal::HasEmptyParam(Deltas))
{
Deltas.Add(Content);
}
Expand All @@ -452,7 +453,7 @@ void UHttpGPTRequest::DeserializeSingleResponse(const FString& Content)
{
FScopeLock Lock(&Mutex);

if (Content.IsEmpty())
if (HttpGPT::Internal::HasEmptyParam(Content))
{
return;
}
Expand Down
53 changes: 53 additions & 0 deletions Source/HttpGPT/Public/HttpGPTInternalFuncs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Author: Lucas Vilas-Boas
// Year: 2023
// Repo: https://github.com/lucoiso/UEHttpGPT

#pragma once

#include <CoreMinimal.h>
#include <Runtime/Launch/Resources/Version.h>
#include <string>
/**
*
*/

namespace HttpGPT
{
namespace Internal
{
template<typename Ty>
constexpr const bool HasEmptyParam(const Ty& Arg1)
{
if constexpr (std::is_base_of<FString, Ty>())
{
return Arg1.IsEmpty();
}
else if constexpr (std::is_base_of<FName, Ty>())
{
return Arg1.IsNone();
}
else if constexpr (std::is_base_of<FText, Ty>())
{
return Arg1.IsEmptyOrWhitespace();
}
else if constexpr (std::is_base_of<std::string, Ty>())
{
return Arg1.empty();
}
else
{
#if ENGINE_MAJOR_VERSION >= 5
return Arg1.IsEmpty();
#else
return Arg1.Num() == 0;
#endif
}
}

template<typename Ty, typename ...Args>
constexpr const bool HasEmptyParam(const Ty& Arg1, Args&& ...args)
{
return HasEmptyParam(Arg1) || HasEmptyParam(std::forward<Args>(args)...);
}
}
}
2 changes: 1 addition & 1 deletion Source/HttpGPT/Public/HttpGPTRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class HTTPGPT_API UHttpGPTRequest : public UBlueprintAsyncActionBase
void DeserializeSingleResponse(const FString& Content);

private:
TSharedPtr<IHttpRequest> HttpRequest;
TSharedPtr<IHttpRequest, ESPMode::ThreadSafe> HttpRequest;
FHttpGPTResponse Response;

bool bInitialized = false;
Expand Down
1 change: 0 additions & 1 deletion Source/HttpGPTEditor/HttpGPTEditor.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public HttpGPTEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
CppStandard = CppStandardVersion.Cpp17;
bEnableExceptions = true;

PublicDependencyModuleNames.AddRange(new[]
{
Expand Down
22 changes: 16 additions & 6 deletions Source/HttpGPTEditor/Private/SHttpGPTChatView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "SHttpGPTChatView.h"
#include <HttpGPTHelper.h>
#include <HttpGPTInternalFuncs.h>
#include <Interfaces/IPluginManager.h>

#ifdef UE_INLINE_GENERATED_CPP_BY_NAME
Expand Down Expand Up @@ -40,7 +41,7 @@ void UHttpGPTMessagingHandler::ProcessCompleted(const FHttpGPTResponse& Response

void UHttpGPTMessagingHandler::ProcessResponse(const FHttpGPTResponse& Response)
{
if (Response.Choices.IsEmpty())
if (HttpGPT::Internal::HasEmptyParam(Response.Choices))
{
return;
}
Expand Down Expand Up @@ -218,7 +219,7 @@ FReply SHttpGPTChatView::HandleSendMessageButton()

bool SHttpGPTChatView::IsSendMessageEnabled() const
{
return (!IsValid(RequestReference) || !RequestReference->IsTaskActive()) && !InputTextBox->GetText().IsEmptyOrWhitespace();
return (!IsValid(RequestReference) || !RequestReference->IsTaskActive()) && !HttpGPT::Internal::HasEmptyParam(InputTextBox->GetText());
}

FReply SHttpGPTChatView::HandleClearChatButton()
Expand All @@ -236,7 +237,7 @@ FReply SHttpGPTChatView::HandleClearChatButton()

bool SHttpGPTChatView::IsClearChatEnabled() const
{
return !ChatItems.IsEmpty();
return !HttpGPT::Internal::HasEmptyParam(ChatItems);
}

TArray<FHttpGPTMessage> SHttpGPTChatView::GetChatHistory() const
Expand All @@ -256,18 +257,27 @@ TArray<FHttpGPTMessage> SHttpGPTChatView::GetChatHistory() const

FString SHttpGPTChatView::GetSystemContext() const
{
FString SupportedModels;
for (const TSharedPtr<FString>& Model : AvailableModels)
{
SupportedModels.Append(*Model.Get() + ", ");
}

SupportedModels.RemoveFromEnd(", ");

const TSharedPtr<IPlugin> PluginInterface = IPluginManager::Get().FindPlugin("HttpGPT");

const FStringFormatOrderedArguments Arguments {
FString::Printf(TEXT("%d.%d"), ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION),
"HttpGPT",
FString("HttpGPT"),
PluginInterface->GetDescriptor().VersionName,
PluginInterface->GetDescriptor().CreatedBy,
PluginInterface->GetDescriptor().DocsURL,
PluginInterface->GetDescriptor().SupportURL
PluginInterface->GetDescriptor().SupportURL,
SupportedModels
};

return FString::Format(TEXT("You are in the Unreal Engine {0} plugin {1} version {2}, which was developed by {3}. You can find the documentation at {4} and support at {5}. You are an assistant that will help with the development of projects in Unreal Engine in general."), Arguments);
return FString::Format(TEXT("You are in the Unreal Engine {0} plugin {1} version {2}, which was developed by {3}. You can find the documentation at {4} and support at {5}. You are an assistant that will help with the development of projects in Unreal Engine in general. HttpGPT supports all these models provided by OpenAI: {6}."), Arguments);
}

void SHttpGPTChatView::InitializeModelsOptions()
Expand Down
12 changes: 6 additions & 6 deletions Source/HttpGPTEditor/Private/SHttpGPTChatView.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class UHttpGPTMessagingHandler : public UObject

FHttpGPTMessage Message;

TSharedPtr<SScrollBox, ESPMode::ThreadSafe> ScrollBoxReference;
TSharedPtr<SScrollBox> ScrollBoxReference;

private:
void ProcessResponse(const FHttpGPTResponse& Response);
Expand All @@ -58,10 +58,10 @@ class SHttpGPTChatItem final : public SCompoundWidget
UHttpGPTMessagingHandlerPtr MessagingHandlerObject;

private:
TSharedPtr<STextBlock, ESPMode::ThreadSafe> MessageBox;
TSharedPtr<STextBlock> MessageBox;
};

typedef TSharedPtr<SHttpGPTChatItem, ESPMode::ThreadSafe> SHttpGPTChatItemPtr;
typedef TSharedPtr<SHttpGPTChatItem> SHttpGPTChatItemPtr;

class SHttpGPTChatView final : public SCompoundWidget
{
Expand Down Expand Up @@ -89,10 +89,10 @@ class SHttpGPTChatView final : public SCompoundWidget
TSharedPtr<SVerticalBox> ChatBox;
TArray<SHttpGPTChatItemPtr> ChatItems;

TSharedPtr<SScrollBox, ESPMode::ThreadSafe> ChatScrollBox;
TSharedPtr<SScrollBox> ChatScrollBox;

TSharedPtr<SEditableTextBox, ESPMode::ThreadSafe> InputTextBox;
TSharedPtr<STextComboBox, ESPMode::ThreadSafe> ModelsComboBox;
TSharedPtr<SEditableTextBox> InputTextBox;
TSharedPtr<STextComboBox> ModelsComboBox;

TArray<TSharedPtr<FString>> AvailableModels;

Expand Down

0 comments on commit 4d9e7fe

Please sign in to comment.