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

Commit

Permalink
HttpGPT v1.5.4: Add chat history persistence to editor tool
Browse files Browse the repository at this point in the history
  • Loading branch information
lucoiso authored Aug 14, 2023
2 parents e49ef63 + 3c31589 commit 45947b4
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 17 deletions.
4 changes: 2 additions & 2 deletions HttpGPT.uplugin
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 16,
"VersionName": "1.5.3",
"Version": 17,
"VersionName": "1.5.4",
"FriendlyName": "HttpGPT - GPT Integration",
"Description": "HttpGPT is an Unreal Engine plugin that facilitates integration with OpenAI's GPT based services (ChatGPT and DALL-E) through asynchronous REST requests, making it easy for developers to communicate with these services. HttpGPT also includes new Editor Tools to integrate Chat GPT and DALL-E image generation directly in the Engine.",
"Category": "Game Features",
Expand Down
8 changes: 4 additions & 4 deletions Source/HttpGPTChatModule/Private/Tasks/HttpGPTChatRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ FString UHttpGPTChatRequest::SetRequestContent()

UE_LOG(LogHttpGPT_Internal, Display, TEXT("%s (%d): Mounting content"), *FString(__func__), GetUniqueID());

const TSharedPtr<FJsonObject> JsonRequest = MakeShareable(new FJsonObject);
const TSharedPtr<FJsonObject> JsonRequest = MakeShared<FJsonObject>();
JsonRequest->SetStringField("model", UHttpGPTHelper::ModelToName(GetChatOptions().Model).ToString().ToLower());
JsonRequest->SetNumberField("max_tokens", GetChatOptions().MaxTokens);
JsonRequest->SetNumberField("temperature", GetChatOptions().Temperature);
Expand All @@ -125,15 +125,15 @@ FString UHttpGPTChatRequest::SetRequestContent()
TArray<TSharedPtr<FJsonValue>> StopJson;
for (const FName& Iterator : GetChatOptions().Stop)
{
StopJson.Add(MakeShareable(new FJsonValueString(Iterator.ToString())));
StopJson.Add(MakeShared<FJsonValueString>(Iterator.ToString()));
}

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

if (!HttpGPT::Internal::HasEmptyParam(GetChatOptions().LogitBias))
{
TSharedPtr<FJsonObject> LogitBiasJson = MakeShareable(new FJsonObject());
TSharedPtr<FJsonObject> LogitBiasJson = MakeShared<FJsonObject>();
for (const TPair<int32, float>& Iterator : GetChatOptions().LogitBias)
{
LogitBiasJson->SetNumberField(FString::FromInt(Iterator.Key), Iterator.Value);
Expand Down Expand Up @@ -314,7 +314,7 @@ void UHttpGPTChatRequest::DeserializeSingleResponse(const FString& Content)
}

const TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Content);
TSharedPtr<FJsonObject> JsonResponse = MakeShareable(new FJsonObject);
TSharedPtr<FJsonObject> JsonResponse = MakeShared<FJsonObject>();
FJsonSerializer::Deserialize(Reader, JsonResponse);

if (CheckError(JsonResponse, Response.Error))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ FHttpGPTChatMessage::FHttpGPTChatMessage(const FName& Role, const FString& Conte

TSharedPtr<FJsonValue> FHttpGPTChatMessage::GetMessage() const
{
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
TSharedPtr<FJsonObject> JsonObject = MakeShared<FJsonObject>();
JsonObject->SetStringField("role", UHttpGPTHelper::RoleToName(Role).ToString().ToLower());
JsonObject->SetStringField("content", Content);

return MakeShareable(new FJsonValueObject(JsonObject));
return MakeShared<FJsonValueObject>(JsonObject);
}

FHttpGPTChatOptions::FHttpGPTChatOptions()
Expand Down
3 changes: 2 additions & 1 deletion Source/HttpGPTEditorModule/HttpGPTEditorModule.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public HttpGPTEditorModule(ReadOnlyTargetRules Target) : base(Target)
"AssetRegistry",
"HttpGPTCommonModule",
"HttpGPTChatModule",
"HttpGPTImageModule"
"HttpGPTImageModule",
"Json"
});
}
}
88 changes: 86 additions & 2 deletions Source/HttpGPTEditorModule/Private/SHttpGPTChatView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
#include <Utils/HttpGPTHelper.h>
#include <HttpGPTInternalFuncs.h>
#include <Interfaces/IPluginManager.h>
#include <Dom/JsonObject.h>
#include <Serialization/JsonWriter.h>
#include <Serialization/JsonReader.h>
#include <Serialization/JsonSerializer.h>
#include <Misc/FileHelper.h>

#ifdef UE_INLINE_GENERATED_CPP_BY_NAME
#include UE_INLINE_GENERATED_CPP_BY_NAME(SHttpGPTChatView)
Expand Down Expand Up @@ -249,6 +254,13 @@ void SHttpGPTChatView::Construct([[maybe_unused]] const FArguments&)
]
]
];

LoadChatHistory();
}

SHttpGPTChatView::~SHttpGPTChatView()
{
SaveChatHistory();
}

FReply SHttpGPTChatView::HandleSendMessageButton()
Expand Down Expand Up @@ -319,9 +331,11 @@ TArray<FHttpGPTChatMessage> SHttpGPTChatView::GetChatHistory() const
FHttpGPTChatMessage(EHttpGPTChatRole::System, GetSystemContext())
};

for (const auto& Item : ChatItems)
for (const SHttpGPTChatItemPtr& Item : ChatItems)
{
Output.Add(FHttpGPTChatMessage(*Item->GetRoleText(), Item->GetMessageText()));
FString RoleText = Item->GetRoleText();
RoleText.RemoveFromEnd(TEXT(":"));
Output.Add(FHttpGPTChatMessage(*RoleText, Item->GetMessageText()));
}

return Output;
Expand Down Expand Up @@ -390,6 +404,76 @@ FString SHttpGPTChatView::GetSystemContext() const
return FString::Format(TEXT("You are an assistant that will help with the development of projects in Unreal Engine in general.\n{0}\n{1}\n{2}\n{3}\n{4}\n{5}"), Arguments_SystemContext);
}

void SHttpGPTChatView::LoadChatHistory()
{
if (const FString LoadPath = GetHistoryPath(); FPaths::FileExists(LoadPath))
{
FString FileContent;
if (!FFileHelper::LoadFileToString(FileContent, *LoadPath))
{
return;
}

TSharedPtr<FJsonObject> JsonParsed;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(FileContent);
if (FJsonSerializer::Deserialize(Reader, JsonParsed))
{
const TArray<TSharedPtr<FJsonValue>> Data = JsonParsed->GetArrayField("Data");
for (const TSharedPtr<FJsonValue>& Item : Data)
{
if (const TSharedPtr<FJsonObject> MessageItObj = Item->AsObject())
{
const FString RoleString = MessageItObj->GetStringField("role");
const EHttpGPTChatRole Role = UHttpGPTHelper::NameToRole(*RoleString);
if (Role == EHttpGPTChatRole::System)
{
continue;
}

const FString Message = MessageItObj->GetStringField("content");

ChatItems.Add(
SNew(SHttpGPTChatItem)
.MessageRole(Role)
.InputText(Message)
);
}
}
}
}

for (const SHttpGPTChatItemPtr& Item : ChatItems)
{
ChatBox->AddSlot().AutoHeight()[Item.ToSharedRef()];
}
}

void SHttpGPTChatView::SaveChatHistory() const
{
const TSharedPtr<FJsonObject> JsonRequest = MakeShared<FJsonObject>();

TArray<TSharedPtr<FJsonValue>> Data;
for (const FHttpGPTChatMessage& Item : GetChatHistory())
{
Data.Add(Item.GetMessage());
}

JsonRequest->SetArrayField("Data", Data);

FString RequestContentString;
const TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&RequestContentString);

if (FJsonSerializer::Serialize(JsonRequest.ToSharedRef(), Writer))
{
FFileHelper::SaveStringToFile(RequestContentString, *GetHistoryPath());
}
}

FString SHttpGPTChatView::GetHistoryPath() const
{
return FPaths::Combine(FPaths::ProjectSavedDir(), "HttpGPT", "HttpGPTChatHistory.json");
}

void SHttpGPTChatView::InitializeModelsOptions()
{
for (const FName& ModelName : UHttpGPTHelper::GetAvailableGPTModels())
Expand Down
6 changes: 6 additions & 0 deletions Source/HttpGPTEditorModule/Private/SHttpGPTChatView.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class SHttpGPTChatView final : public SCompoundWidget
SLATE_END_ARGS()

void Construct(const FArguments& InArgs);
~SHttpGPTChatView();

FReply HandleSendMessageButton();
bool IsSendMessageEnabled() const;
Expand All @@ -89,6 +90,11 @@ class SHttpGPTChatView final : public SCompoundWidget
TArray<FHttpGPTChatMessage> GetChatHistory() const;
FString GetSystemContext() const;

void LoadChatHistory();
void SaveChatHistory() const;

FString GetHistoryPath() const;

void InitializeModelsOptions();

private:
Expand Down
8 changes: 4 additions & 4 deletions Source/HttpGPTEditorModule/Private/SHttpGPTImageGenView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,13 +397,13 @@ void SHttpGPTImageGenView::InitializeImageNumOptions()
constexpr uint8 MaxNum = 10u;
for (uint8 Iterator = 1u; Iterator <= MaxNum; ++Iterator)
{
ImageNum.Add(MakeShareable(new FString(FString::FromInt(Iterator))));
ImageNum.Add(MakeShared<FString>(FString::FromInt(Iterator)));
}
}

void SHttpGPTImageGenView::InitializeImageSizeOptions()
{
ImageSize.Add(MakeShareable(new FString(UHttpGPTHelper::SizeToName(EHttpGPTImageSize::x256).ToString())));
ImageSize.Add(MakeShareable(new FString(UHttpGPTHelper::SizeToName(EHttpGPTImageSize::x512).ToString())));
ImageSize.Add(MakeShareable(new FString(UHttpGPTHelper::SizeToName(EHttpGPTImageSize::x1024).ToString())));
ImageSize.Add(MakeShared<FString>(UHttpGPTHelper::SizeToName(EHttpGPTImageSize::x256).ToString()));
ImageSize.Add(MakeShared<FString>(UHttpGPTHelper::SizeToName(EHttpGPTImageSize::x512).ToString()));
ImageSize.Add(MakeShared<FString>(UHttpGPTHelper::SizeToName(EHttpGPTImageSize::x1024).ToString()));
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ FString UHttpGPTImageRequest::SetRequestContent()

UE_LOG(LogHttpGPT_Internal, Display, TEXT("%s (%d): Mounting content"), *FString(__func__), GetUniqueID());

const TSharedPtr<FJsonObject> JsonRequest = MakeShareable(new FJsonObject);
const TSharedPtr<FJsonObject> JsonRequest = MakeShared<FJsonObject>();
JsonRequest->SetStringField("prompt", Prompt);
JsonRequest->SetNumberField("n", GetImageOptions().ImagesNum);
JsonRequest->SetStringField("size", UHttpGPTHelper::SizeToName(GetImageOptions().Size).ToString());
Expand Down Expand Up @@ -178,7 +178,7 @@ void UHttpGPTImageRequest::DeserializeResponse(const FString& Content)
}

const TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Content);
TSharedPtr<FJsonObject> JsonResponse = MakeShareable(new FJsonObject);
TSharedPtr<FJsonObject> JsonResponse = MakeShared<FJsonObject>();
FJsonSerializer::Deserialize(Reader, JsonResponse);

if (CheckError(JsonResponse, Response.Error))
Expand Down

0 comments on commit 45947b4

Please sign in to comment.