ElevenLabs: client-provided API key via SaveGame
The API key is no longer stored in project settings / DefaultEngine.ini (it was committed and baked into shipped builds). It is now provided per-install by the client at runtime and persisted in a SaveGame slot. - Add UPS_AI_ConvAgent_SaveGame_ElevenLabs (slot PS_AI_ConvAgent_ElevenLabs) - BlueprintLibrary is the single owner of the key: Set/Get/Has/Clear + in-memory cache backed by the SaveGame - Add async BP node 'Test ElevenLabs API Key' (GET /v1/models) - Remove API_Key UPROPERTY from UPS_AI_ConvAgent_Settings_ElevenLabs and the key logic from the module - Route all consumers (WebSocket auth, region probe, editor sync customizations) through GetElevenLabsAPIKey() Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -181,6 +181,9 @@ bUseManualIPAddress=False
|
||||
ManualIPAddress=
|
||||
|
||||
[/Script/PS_AI_ConvAgent.PS_AI_ConvAgent_Settings_ElevenLabs]
|
||||
API_Key=7b73c4244ccbec394cc010aaab01b0ec59ce0b11fc636ce4828354f675ca14a5
|
||||
; NOTE: there is intentionally no API_Key here. The ElevenLabs key is provided
|
||||
; per-install by the client at runtime (BlueprintLibrary "Set ElevenLabs API Key")
|
||||
; and stored in a SaveGame slot (Saved/SaveGames/PS_AI_ConvAgent_ElevenLabs.sav),
|
||||
; so it is never committed or baked into a shipped build.
|
||||
ServerRegion=Global
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ void FPS_AI_ConvAgentModule::StartupModule()
|
||||
Settings = NewObject<UPS_AI_ConvAgent_Settings_ElevenLabs>(GetTransientPackage(), "PS_AI_ConvAgent_Settings_ElevenLabs", RF_Standalone);
|
||||
Settings->AddToRoot();
|
||||
|
||||
// NOTE: the client-provided API key (if any) is loaded lazily on the first
|
||||
// GetSettings() call rather than here — see GetSettings(). Loading at module
|
||||
// startup would be too early: the SaveGame system may not be ready yet.
|
||||
|
||||
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
|
||||
{
|
||||
SettingsModule->RegisterSettings(
|
||||
|
||||
@@ -1,7 +1,34 @@
|
||||
// Copyright ASTERION. All Rights Reserved.
|
||||
|
||||
#include "PS_AI_ConvAgent_BlueprintLibrary.h"
|
||||
#include "PS_AI_ConvAgent.h"
|
||||
#include "PS_AI_ConvAgent_SaveGame_ElevenLabs.h"
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// In-memory cache of the client API key. This BlueprintLibrary is the single
|
||||
// owner of the key — every consumer (WebSocket auth, region probe, editor sync
|
||||
// tools) reads it via GetElevenLabsAPIKey(). The SaveGame on disk is the
|
||||
// persistent backing store; this cache avoids a disk read on every access.
|
||||
// All access is on the game thread, so no synchronization is needed.
|
||||
bool GElevenLabsKeyLoaded = false;
|
||||
FString GElevenLabsKeyCache;
|
||||
|
||||
/** Load the API-key SaveGame from its slot, or null if none exists yet. */
|
||||
UPS_AI_ConvAgent_SaveGame_ElevenLabs* LoadElevenLabsKeySaveGame()
|
||||
{
|
||||
const TCHAR* Slot = UPS_AI_ConvAgent_SaveGame_ElevenLabs::GetSlotName();
|
||||
const int32 UserIndex = UPS_AI_ConvAgent_SaveGame_ElevenLabs::GetUserIndex();
|
||||
if (UGameplayStatics::DoesSaveGameExist(Slot, UserIndex))
|
||||
{
|
||||
return Cast<UPS_AI_ConvAgent_SaveGame_ElevenLabs>(
|
||||
UGameplayStatics::LoadGameFromSlot(Slot, UserIndex));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void UPS_AI_ConvAgent_BlueprintLibrary::SetPostProcessAnimBlueprint(
|
||||
USkeletalMeshComponent* SkelMeshComp,
|
||||
@@ -15,3 +42,71 @@ void UPS_AI_ConvAgent_BlueprintLibrary::SetPostProcessAnimBlueprint(
|
||||
|
||||
SkelMeshComp->SetOverridePostProcessAnimBP(AnimBPClass);
|
||||
}
|
||||
|
||||
// ── ElevenLabs API key (per-user, client-provided) ──────────────────────────
|
||||
|
||||
void UPS_AI_ConvAgent_BlueprintLibrary::SetElevenLabsAPIKey(const FString& Key)
|
||||
{
|
||||
// 1) Persist to the SaveGame slot (writes to disk immediately).
|
||||
UPS_AI_ConvAgent_SaveGame_ElevenLabs* Save = LoadElevenLabsKeySaveGame();
|
||||
if (!Save)
|
||||
{
|
||||
Save = Cast<UPS_AI_ConvAgent_SaveGame_ElevenLabs>(
|
||||
UGameplayStatics::CreateSaveGameObject(UPS_AI_ConvAgent_SaveGame_ElevenLabs::StaticClass()));
|
||||
}
|
||||
if (!Save)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("[PS_AI_ConvAgent] SetElevenLabsAPIKey: failed to create SaveGame object."));
|
||||
return;
|
||||
}
|
||||
|
||||
Save->API_Key = Key;
|
||||
const bool bSaved = UGameplayStatics::SaveGameToSlot(
|
||||
Save,
|
||||
UPS_AI_ConvAgent_SaveGame_ElevenLabs::GetSlotName(),
|
||||
UPS_AI_ConvAgent_SaveGame_ElevenLabs::GetUserIndex());
|
||||
|
||||
if (!bSaved)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("[PS_AI_ConvAgent] SetElevenLabsAPIKey: SaveGameToSlot failed "
|
||||
"(check write permissions at the install location)."));
|
||||
}
|
||||
|
||||
// 2) Update the in-memory cache so the new key takes effect immediately
|
||||
// (next conversation / region probe / editor sync) without a restart.
|
||||
GElevenLabsKeyCache = Key;
|
||||
GElevenLabsKeyLoaded = true;
|
||||
}
|
||||
|
||||
FString UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey()
|
||||
{
|
||||
// Lazy-load once from the SaveGame, then serve from the in-memory cache.
|
||||
if (!GElevenLabsKeyLoaded)
|
||||
{
|
||||
GElevenLabsKeyLoaded = true;
|
||||
if (const UPS_AI_ConvAgent_SaveGame_ElevenLabs* Save = LoadElevenLabsKeySaveGame())
|
||||
{
|
||||
GElevenLabsKeyCache = Save->API_Key;
|
||||
}
|
||||
}
|
||||
return GElevenLabsKeyCache;
|
||||
}
|
||||
|
||||
bool UPS_AI_ConvAgent_BlueprintLibrary::HasElevenLabsAPIKey()
|
||||
{
|
||||
return !GetElevenLabsAPIKey().IsEmpty();
|
||||
}
|
||||
|
||||
void UPS_AI_ConvAgent_BlueprintLibrary::ClearElevenLabsAPIKey()
|
||||
{
|
||||
const TCHAR* Slot = UPS_AI_ConvAgent_SaveGame_ElevenLabs::GetSlotName();
|
||||
const int32 UserIndex = UPS_AI_ConvAgent_SaveGame_ElevenLabs::GetUserIndex();
|
||||
if (UGameplayStatics::DoesSaveGameExist(Slot, UserIndex))
|
||||
{
|
||||
UGameplayStatics::DeleteGameInSlot(Slot, UserIndex);
|
||||
}
|
||||
|
||||
// Clear the cache too so the running session stops using the old key.
|
||||
GElevenLabsKeyCache.Empty();
|
||||
GElevenLabsKeyLoaded = true;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "PS_AI_ConvAgent_InteractionSubsystem.h"
|
||||
#include "PS_AI_ConvAgent_InteractionComponent.h"
|
||||
#include "PS_AI_ConvAgent.h"
|
||||
#include "PS_AI_ConvAgent_BlueprintLibrary.h"
|
||||
|
||||
#include "Components/AudioComponent.h"
|
||||
#include "Sound/SoundAttenuation.h"
|
||||
@@ -2822,12 +2823,13 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::DrawDebugHUD() const
|
||||
void UPS_AI_ConvAgent_ElevenLabsComponent::FetchServerRegion()
|
||||
{
|
||||
const UPS_AI_ConvAgent_Settings_ElevenLabs* Settings = FPS_AI_ConvAgentModule::Get().GetSettings();
|
||||
if (!Settings || Settings->API_Key.IsEmpty()) return;
|
||||
const FString APIKey = UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey();
|
||||
if (!Settings || APIKey.IsEmpty()) return;
|
||||
|
||||
auto Request = FHttpModule::Get().CreateRequest();
|
||||
Request->SetURL(Settings->GetAPIBaseURL() + TEXT("/v1/models"));
|
||||
Request->SetVerb(TEXT("GET"));
|
||||
Request->SetHeader(TEXT("xi-api-key"), Settings->API_Key);
|
||||
Request->SetHeader(TEXT("xi-api-key"), APIKey);
|
||||
|
||||
TWeakObjectPtr<UPS_AI_ConvAgent_ElevenLabsComponent> WeakThis(this);
|
||||
Request->OnProcessRequestComplete().BindLambda(
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright ASTERION. All Rights Reserved.
|
||||
|
||||
#include "PS_AI_ConvAgent_TestAPIKey_AsyncAction.h"
|
||||
#include "PS_AI_ConvAgent.h"
|
||||
#include "HttpModule.h"
|
||||
#include "Interfaces/IHttpRequest.h"
|
||||
#include "Interfaces/IHttpResponse.h"
|
||||
|
||||
UPS_AI_ConvAgent_TestAPIKey_AsyncAction* UPS_AI_ConvAgent_TestAPIKey_AsyncAction::TestElevenLabsAPIKey(const FString& Key)
|
||||
{
|
||||
UPS_AI_ConvAgent_TestAPIKey_AsyncAction* Action = NewObject<UPS_AI_ConvAgent_TestAPIKey_AsyncAction>();
|
||||
Action->KeyToTest = Key;
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UPS_AI_ConvAgent_TestAPIKey_AsyncAction::Activate()
|
||||
{
|
||||
// Keep this action alive across the async HTTP round-trip. Removed right
|
||||
// before SetReadyToDestroy() once a result has been broadcast.
|
||||
AddToRoot();
|
||||
|
||||
if (KeyToTest.IsEmpty())
|
||||
{
|
||||
OnInvalid.Broadcast(TEXT("API key is empty."));
|
||||
RemoveFromRoot();
|
||||
SetReadyToDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
// Respect the configured server region for the probe URL; fall back to global.
|
||||
FString BaseURL = TEXT("https://api.elevenlabs.io");
|
||||
if (FPS_AI_ConvAgentModule::IsAvailable())
|
||||
{
|
||||
if (const UPS_AI_ConvAgent_Settings_ElevenLabs* Settings = FPS_AI_ConvAgentModule::Get().GetSettings())
|
||||
{
|
||||
BaseURL = Settings->GetAPIBaseURL();
|
||||
}
|
||||
}
|
||||
|
||||
const TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
|
||||
Request->SetURL(BaseURL + TEXT("/v1/models"));
|
||||
Request->SetVerb(TEXT("GET"));
|
||||
Request->SetHeader(TEXT("xi-api-key"), KeyToTest);
|
||||
|
||||
TWeakObjectPtr<UPS_AI_ConvAgent_TestAPIKey_AsyncAction> WeakThis(this);
|
||||
Request->OnProcessRequestComplete().BindLambda(
|
||||
[WeakThis](FHttpRequestPtr /*Req*/, FHttpResponsePtr Resp, bool bSuccess)
|
||||
{
|
||||
if (!WeakThis.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
UPS_AI_ConvAgent_TestAPIKey_AsyncAction* Self = WeakThis.Get();
|
||||
|
||||
const int32 Code = Resp.IsValid() ? Resp->GetResponseCode() : 0;
|
||||
if (bSuccess && Code == 200)
|
||||
{
|
||||
Self->OnValid.Broadcast(TEXT("API key is valid."));
|
||||
}
|
||||
else if (Code == 401 || Code == 403)
|
||||
{
|
||||
Self->OnInvalid.Broadcast(FString::Printf(TEXT("Invalid API key (HTTP %d)."), Code));
|
||||
}
|
||||
else if (Code == 0)
|
||||
{
|
||||
Self->OnInvalid.Broadcast(TEXT("Could not reach ElevenLabs (network error)."));
|
||||
}
|
||||
else
|
||||
{
|
||||
Self->OnInvalid.Broadcast(FString::Printf(TEXT("Key test failed (HTTP %d)."), Code));
|
||||
}
|
||||
|
||||
Self->RemoveFromRoot();
|
||||
Self->SetReadyToDestroy();
|
||||
});
|
||||
|
||||
Request->ProcessRequest();
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "PS_AI_ConvAgent_WebSocket_ElevenLabsProxy.h"
|
||||
#include "PS_AI_ConvAgent.h"
|
||||
#include "PS_AI_ConvAgent_BlueprintLibrary.h"
|
||||
|
||||
#include "WebSocketsModule.h"
|
||||
#include "IWebSocket.h"
|
||||
@@ -43,9 +44,12 @@ void UPS_AI_ConvAgent_WebSocket_ElevenLabsProxy::Connect(const FString& AgentIDO
|
||||
|
||||
// Headers: the ElevenLabs Conversational AI WS endpoint accepts the
|
||||
// xi-api-key header on the initial HTTP upgrade request.
|
||||
// The key comes from the client-provided SaveGame (via the BlueprintLibrary);
|
||||
// an explicit override passed to Connect() still takes precedence.
|
||||
TMap<FString, FString> UpgradeHeaders;
|
||||
const UPS_AI_ConvAgent_Settings_ElevenLabs* Settings = FPS_AI_ConvAgentModule::Get().GetSettings();
|
||||
const FString ResolvedKey = APIKeyOverride.IsEmpty() ? Settings->API_Key : APIKeyOverride;
|
||||
const FString ResolvedKey = APIKeyOverride.IsEmpty()
|
||||
? UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey()
|
||||
: APIKeyOverride;
|
||||
if (!ResolvedKey.IsEmpty())
|
||||
{
|
||||
UpgradeHeaders.Add(TEXT("xi-api-key"), ResolvedKey);
|
||||
|
||||
@@ -31,13 +31,12 @@ class PS_AI_CONVAGENT_API UPS_AI_ConvAgent_Settings_ElevenLabs : public UObject
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* ElevenLabs API key.
|
||||
* Obtain from https://elevenlabs.io – used to authenticate WebSocket connections.
|
||||
* Keep this secret; do not ship with the key hard-coded in a shipping build.
|
||||
*/
|
||||
UPROPERTY(Config, EditAnywhere, Category = "ASTERION|PS_AI_ConvAgent|ElevenLabs API")
|
||||
FString API_Key;
|
||||
// NOTE: The ElevenLabs API key is NOT stored here on purpose.
|
||||
// It is provided per-install by the client at runtime and persisted in a
|
||||
// SaveGame slot (see UPS_AI_ConvAgent_SaveGame_ElevenLabs). Read/write it via
|
||||
// UPS_AI_ConvAgent_BlueprintLibrary::Get/SetElevenLabsAPIKey(). This keeps the
|
||||
// key out of Project Settings / DefaultEngine.ini so it can never be committed
|
||||
// or baked into a shipped build.
|
||||
|
||||
/**
|
||||
* Server region for ElevenLabs API.
|
||||
@@ -119,7 +118,8 @@ public:
|
||||
return FModuleManager::Get().IsModuleLoaded("PS_AI_ConvAgent");
|
||||
}
|
||||
|
||||
/** Access the settings object at runtime */
|
||||
/** Access the settings object at runtime (region, custom URL, logging, global
|
||||
* prompt). The API key is NOT here — see UPS_AI_ConvAgent_BlueprintLibrary. */
|
||||
UPS_AI_ConvAgent_Settings_ElevenLabs* GetSettings() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -28,4 +28,30 @@ public:
|
||||
meta = (DisplayName = "Set Post Process Anim Blueprint"))
|
||||
static void SetPostProcessAnimBlueprint(USkeletalMeshComponent* SkelMeshComp,
|
||||
TSubclassOf<UAnimInstance> AnimBPClass);
|
||||
|
||||
// ── ElevenLabs API key (per-user, client-provided) ────────────────────────
|
||||
|
||||
/** Store the client's ElevenLabs API key. Persists it per-user in
|
||||
* Saved/Config/.../Game.ini AND applies it immediately to the running plugin
|
||||
* (no restart needed). Call this from your settings UI once the user has
|
||||
* entered — and ideally validated via "Test ElevenLabs API Key" — their key. */
|
||||
UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_AI_ConvAgent|ElevenLabs API Key",
|
||||
meta = (DisplayName = "Set ElevenLabs API Key"))
|
||||
static void SetElevenLabsAPIKey(const FString& Key);
|
||||
|
||||
/** Return the currently stored client ElevenLabs API key (empty if none). */
|
||||
UFUNCTION(BlueprintPure, Category = "ASTERION|PS_AI_ConvAgent|ElevenLabs API Key",
|
||||
meta = (DisplayName = "Get ElevenLabs API Key"))
|
||||
static FString GetElevenLabsAPIKey();
|
||||
|
||||
/** True if a non-empty client ElevenLabs API key has been stored.
|
||||
* Use this on startup to decide whether to force the user to the key entry screen. */
|
||||
UFUNCTION(BlueprintPure, Category = "ASTERION|PS_AI_ConvAgent|ElevenLabs API Key",
|
||||
meta = (DisplayName = "Has ElevenLabs API Key"))
|
||||
static bool HasElevenLabsAPIKey();
|
||||
|
||||
/** Clear the stored client ElevenLabs API key (both on disk and in memory). */
|
||||
UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_AI_ConvAgent|ElevenLabs API Key",
|
||||
meta = (DisplayName = "Clear ElevenLabs API Key"))
|
||||
static void ClearElevenLabsAPIKey();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright ASTERION. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/SaveGame.h"
|
||||
#include "PS_AI_ConvAgent_SaveGame_ElevenLabs.generated.h"
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// UPS_AI_ConvAgent_SaveGame_ElevenLabs
|
||||
//
|
||||
// Per-install persistence for the CLIENT's own ElevenLabs API key. Written via
|
||||
// UGameplayStatics::SaveGameToSlot to:
|
||||
// - Editor/PIE : <Project>/Saved/SaveGames/PS_AI_ConvAgent_ElevenLabs.sav
|
||||
// - Packaged : <Build>/<Project>/Saved/SaveGames/PS_AI_ConvAgent_ElevenLabs.sav
|
||||
//
|
||||
// Binary file → the key is never stored in plaintext, never committed, never
|
||||
// baked into the shipped config. The key is entered once at runtime via the
|
||||
// settings UI (BlueprintLibrary "Set ElevenLabs API Key").
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
UCLASS()
|
||||
class PS_AI_CONVAGENT_API UPS_AI_ConvAgent_SaveGame_ElevenLabs : public USaveGame
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Client-provided ElevenLabs API key. Empty until the user enters one. */
|
||||
UPROPERTY()
|
||||
FString API_Key;
|
||||
|
||||
/** Fixed save slot name used for the key. */
|
||||
static const TCHAR* GetSlotName() { return TEXT("PS_AI_ConvAgent_ElevenLabs"); }
|
||||
|
||||
/** Fixed user index used for the key slot. */
|
||||
static constexpr int32 GetUserIndex() { return 0; }
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright ASTERION. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintAsyncActionBase.h"
|
||||
#include "PS_AI_ConvAgent_TestAPIKey_AsyncAction.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPS_AI_ConvAgent_TestAPIKeyResult, const FString&, Message);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// UPS_AI_ConvAgent_TestAPIKey_AsyncAction
|
||||
//
|
||||
// Latent Blueprint node that validates an ElevenLabs API key by issuing a
|
||||
// lightweight GET /v1/models request with the key as the xi-api-key header.
|
||||
// - HTTP 200 → OnValid (key works)
|
||||
// - HTTP 401 / other → OnInvalid (bad key, or network/server error)
|
||||
//
|
||||
// Designed for a settings UI: let the user type their key, run this node, and
|
||||
// only call "Set ElevenLabs API Key" on the OnValid branch.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
UCLASS()
|
||||
class PS_AI_CONVAGENT_API UPS_AI_ConvAgent_TestAPIKey_AsyncAction : public UBlueprintAsyncActionBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Test an ElevenLabs API key. Pass the key the user just entered in your settings UI. */
|
||||
UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_AI_ConvAgent|ElevenLabs API Key",
|
||||
meta = (BlueprintInternalUseOnly = "true", DisplayName = "Test ElevenLabs API Key"))
|
||||
static UPS_AI_ConvAgent_TestAPIKey_AsyncAction* TestElevenLabsAPIKey(const FString& Key);
|
||||
|
||||
/** Fired when the key is valid (HTTP 200). The Message contains a human-readable status. */
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FPS_AI_ConvAgent_TestAPIKeyResult OnValid;
|
||||
|
||||
/** Fired when the key is invalid or the request failed. The Message explains why. */
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FPS_AI_ConvAgent_TestAPIKeyResult OnInvalid;
|
||||
|
||||
//~ Begin UBlueprintAsyncActionBase interface
|
||||
virtual void Activate() override;
|
||||
//~ End UBlueprintAsyncActionBase interface
|
||||
|
||||
private:
|
||||
FString KeyToTest;
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "PS_AI_ConvAgent_ActionSetCustomization_ElevenLabs.h"
|
||||
#include "PS_AI_ConvAgent_ActionSet_ElevenLabs.h"
|
||||
#include "PS_AI_ConvAgent.h"
|
||||
#include "PS_AI_ConvAgent_BlueprintLibrary.h"
|
||||
|
||||
#include "DetailLayoutBuilder.h"
|
||||
#include "DetailCategoryBuilder.h"
|
||||
@@ -65,14 +66,8 @@ void FPS_AI_ConvAgent_ActionSetCustomization_ElevenLabs::OnUpdateAllAgentsClicke
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
FString FPS_AI_ConvAgent_ActionSetCustomization_ElevenLabs::GetAPIKey() const
|
||||
{
|
||||
if (FPS_AI_ConvAgentModule::IsAvailable())
|
||||
{
|
||||
if (const UPS_AI_ConvAgent_Settings_ElevenLabs* Settings = FPS_AI_ConvAgentModule::Get().GetSettings())
|
||||
{
|
||||
return Settings->API_Key;
|
||||
}
|
||||
}
|
||||
return FString();
|
||||
// Key is client-provided and stored in a SaveGame slot (see BlueprintLibrary).
|
||||
return UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey();
|
||||
}
|
||||
|
||||
UPS_AI_ConvAgent_ActionSet_ElevenLabs* FPS_AI_ConvAgent_ActionSetCustomization_ElevenLabs::GetEditedAsset() const
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "PS_AI_ConvAgent_AgentConfig_ElevenLabs.h"
|
||||
#include "PS_AI_ConvAgent_Tool_ElevenLabs.h"
|
||||
#include "PS_AI_ConvAgent.h"
|
||||
#include "PS_AI_ConvAgent_BlueprintLibrary.h"
|
||||
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
|
||||
@@ -1508,14 +1509,8 @@ void FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::OnFetchAgentClicked()
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
FString FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::GetAPIKey() const
|
||||
{
|
||||
if (FPS_AI_ConvAgentModule::IsAvailable())
|
||||
{
|
||||
if (const UPS_AI_ConvAgent_Settings_ElevenLabs* Settings = FPS_AI_ConvAgentModule::Get().GetSettings())
|
||||
{
|
||||
return Settings->API_Key;
|
||||
}
|
||||
}
|
||||
return FString();
|
||||
// Key is client-provided and stored in a SaveGame slot (see BlueprintLibrary).
|
||||
return UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey();
|
||||
}
|
||||
|
||||
UPS_AI_ConvAgent_AgentConfig_ElevenLabs* FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::GetEditedAsset() const
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "PS_AI_ConvAgent_AgentConfig_ElevenLabs.h"
|
||||
#include "PS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs.h"
|
||||
#include "PS_AI_ConvAgent.h"
|
||||
#include "PS_AI_ConvAgent_BlueprintLibrary.h"
|
||||
|
||||
#include "DetailLayoutBuilder.h"
|
||||
#include "DetailCategoryBuilder.h"
|
||||
@@ -820,15 +821,8 @@ void FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::OnUpdateAllAgentsClicked()
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
FString FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::GetAPIKey() const
|
||||
{
|
||||
if (FPS_AI_ConvAgentModule::IsAvailable())
|
||||
{
|
||||
if (const UPS_AI_ConvAgent_Settings_ElevenLabs* Settings =
|
||||
FPS_AI_ConvAgentModule::Get().GetSettings())
|
||||
{
|
||||
return Settings->API_Key;
|
||||
}
|
||||
}
|
||||
return FString();
|
||||
// Key is client-provided and stored in a SaveGame slot (see BlueprintLibrary).
|
||||
return UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey();
|
||||
}
|
||||
|
||||
UPS_AI_ConvAgent_Tool_ElevenLabs* FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::GetEditedAsset() const
|
||||
|
||||
Reference in New Issue
Block a user