diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/PS_AI_ConvAgentEditor.Build.cs b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/PS_AI_ConvAgentEditor.Build.cs index d57728e..2d76be9 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/PS_AI_ConvAgentEditor.Build.cs +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/PS_AI_ConvAgentEditor.Build.cs @@ -35,6 +35,8 @@ public class PS_AI_ConvAgentEditor : ModuleRules "JsonUtilities", // Asset Registry for scanning AgentConfig assets (batch update) "AssetRegistry", + // UDeveloperSettings base class for editor-only API key settings + "DeveloperSettings", }); } } diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ActionSetCustomization_ElevenLabs.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ActionSetCustomization_ElevenLabs.cpp index 0fab1ac..43f169f 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ActionSetCustomization_ElevenLabs.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ActionSetCustomization_ElevenLabs.cpp @@ -4,6 +4,7 @@ #include "PS_AI_ConvAgent_ActionSet_ElevenLabs.h" #include "PS_AI_ConvAgent.h" #include "PS_AI_ConvAgent_BlueprintLibrary.h" +#include "PS_AI_ConvAgent_EditorSettings_ElevenLabs.h" #include "DetailLayoutBuilder.h" #include "DetailCategoryBuilder.h" @@ -66,8 +67,9 @@ void FPS_AI_ConvAgent_ActionSetCustomization_ElevenLabs::OnUpdateAllAgentsClicke // ───────────────────────────────────────────────────────────────────────────── FString FPS_AI_ConvAgent_ActionSetCustomization_ElevenLabs::GetAPIKey() const { - // Key is client-provided and stored in a SaveGame slot (see BlueprintLibrary). - return UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey(); + // Editor-only authoring key (Project Settings → Editor, or ELEVENLABS_API_KEY env). + // Never committed by a build, never packaged — see UPS_AI_ConvAgent_EditorSettings_ElevenLabs. + return UPS_AI_ConvAgent_EditorSettings_ElevenLabs::ResolveEditorApiKey(); } UPS_AI_ConvAgent_ActionSet_ElevenLabs* FPS_AI_ConvAgent_ActionSetCustomization_ElevenLabs::GetEditedAsset() const diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs.cpp index 860f31b..36ef82d 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs.cpp @@ -5,6 +5,7 @@ #include "PS_AI_ConvAgent_Tool_ElevenLabs.h" #include "PS_AI_ConvAgent.h" #include "PS_AI_ConvAgent_BlueprintLibrary.h" +#include "PS_AI_ConvAgent_EditorSettings_ElevenLabs.h" #include "AssetRegistry/AssetRegistryModule.h" @@ -426,7 +427,7 @@ void FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::OnFetchVoicesClicked( const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings > PS AI ConvAgent - ElevenLabs.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -632,7 +633,7 @@ void FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::OnFetchLLMsClicked() const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings > PS AI ConvAgent - ElevenLabs.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -918,7 +919,7 @@ void FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::OnCreateAgentClicked( const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -1020,7 +1021,7 @@ void FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::OnUpdateAgentClicked( const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -1108,7 +1109,7 @@ void FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::OnFetchAgentClicked() const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -1509,8 +1510,9 @@ void FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::OnFetchAgentClicked() // ───────────────────────────────────────────────────────────────────────────── FString FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::GetAPIKey() const { - // Key is client-provided and stored in a SaveGame slot (see BlueprintLibrary). - return UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey(); + // Editor-only authoring key (Project Settings → Editor, or ELEVENLABS_API_KEY env). + // Never committed by a build, never packaged — see UPS_AI_ConvAgent_EditorSettings_ElevenLabs. + return UPS_AI_ConvAgent_EditorSettings_ElevenLabs::ResolveEditorApiKey(); } UPS_AI_ConvAgent_AgentConfig_ElevenLabs* FPS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs::GetEditedAsset() const diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_EditorSettings_ElevenLabs.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_EditorSettings_ElevenLabs.cpp new file mode 100644 index 0000000..0f0e351 --- /dev/null +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_EditorSettings_ElevenLabs.cpp @@ -0,0 +1,27 @@ +// Copyright ASTERION. All Rights Reserved. + +#include "PS_AI_ConvAgent_EditorSettings_ElevenLabs.h" +#include "PS_AI_ConvAgent_BlueprintLibrary.h" +#include "HAL/PlatformMisc.h" + +FString UPS_AI_ConvAgent_EditorSettings_ElevenLabs::ResolveEditorApiKey() +{ + // 1) Explicit editor setting (Project Settings → Editor). + if (const UPS_AI_ConvAgent_EditorSettings_ElevenLabs* Settings = GetDefault()) + { + if (!Settings->EditorApiKey.IsEmpty()) + { + return Settings->EditorApiKey; + } + } + + // 2) Environment variable (CI / shared machines). + const FString EnvKey = FPlatformMisc::GetEnvironmentVariable(TEXT("ELEVENLABS_API_KEY")); + if (!EnvKey.IsEmpty()) + { + return EnvKey; + } + + // 3) Runtime client key from the SaveGame, if one was set on this machine. + return UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey(); +} diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_EditorSettings_ElevenLabs.h b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_EditorSettings_ElevenLabs.h new file mode 100644 index 0000000..350ddff --- /dev/null +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_EditorSettings_ElevenLabs.h @@ -0,0 +1,57 @@ +// Copyright ASTERION. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Engine/DeveloperSettings.h" +#include "PS_AI_ConvAgent_EditorSettings_ElevenLabs.generated.h" + +/** + * Editor-only settings for ElevenLabs agent authoring. + * + * The API key entered here is used EXCLUSIVELY by the editor (voice/model/LLM + * fetch, agent create/sync, tool & action-set sync). It is: + * - declared in the EDITOR module → never compiled into a packaged game, + * - stored with config = EditorPerProjectUserSettings → written to + * Saved/Config/.../EditorPerProjectUserSettings.ini, which is never cooked + * into a build. + * → The key therefore can never end up in a shipped package. + * + * The shipped game does NOT use this key. The final client provides their own + * key at runtime, persisted in a SaveGame slot (see UPS_AI_ConvAgent_BlueprintLibrary). + * + * Exposed in Project Settings → Editor → "PS AI ConvAgent - ElevenLabs (Editor)". + */ +UCLASS(config = EditorPerProjectUserSettings, defaultconfig, + meta = (DisplayName = "PS AI ConvAgent - ElevenLabs (Editor)")) +class UPS_AI_ConvAgent_EditorSettings_ElevenLabs : public UDeveloperSettings +{ + GENERATED_BODY() + +public: + /** + * ElevenLabs API key used by the editor to author and sync agents. + * Editor-only — never committed by a build, never packaged. + * Leave empty and set the ELEVENLABS_API_KEY environment variable instead + * if you prefer (useful for CI / shared machines). + */ + UPROPERTY(config, EditAnywhere, Category = "ElevenLabs API", + meta = (DisplayName = "Editor API Key", + ToolTip = "ElevenLabs API key used ONLY by the editor for authoring/syncing agents.\n" + "Stored per-user under Saved/Config — never committed by a build, never packaged.\n" + "The shipped game uses the client-provided runtime key instead.\n" + "Alternatively, leave empty and set the ELEVENLABS_API_KEY environment variable.")) + FString EditorApiKey; + + /** Show under the "Editor" section of Project Settings (not "Game"/"Plugins"). */ + virtual FName GetCategoryName() const override { return FName(TEXT("Editor")); } + + /** + * Resolve the API key used by editor authoring, in priority order: + * 1) the EditorApiKey above, + * 2) the ELEVENLABS_API_KEY environment variable (CI / shared machines), + * 3) the runtime client key from the SaveGame, if one happens to exist locally. + * Returns an empty string if none is set. + */ + static FString ResolveEditorApiKey(); +}; diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ToolCustomization_ElevenLabs.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ToolCustomization_ElevenLabs.cpp index 17defa4..bd89256 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ToolCustomization_ElevenLabs.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgentEditor/Private/PS_AI_ConvAgent_ToolCustomization_ElevenLabs.cpp @@ -6,6 +6,7 @@ #include "PS_AI_ConvAgent_AgentConfigCustomization_ElevenLabs.h" #include "PS_AI_ConvAgent.h" #include "PS_AI_ConvAgent_BlueprintLibrary.h" +#include "PS_AI_ConvAgent_EditorSettings_ElevenLabs.h" #include "DetailLayoutBuilder.h" #include "DetailCategoryBuilder.h" @@ -243,7 +244,7 @@ void FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::OnCreateToolClicked() const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -354,7 +355,7 @@ void FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::OnUpdateToolClicked() const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -444,7 +445,7 @@ void FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::OnFetchToolClicked() const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -661,7 +662,7 @@ void FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::OnUpdateAllAgentsClicked() const FString APIKey = GetAPIKey(); if (APIKey.IsEmpty()) { - SetStatusError(TEXT("API Key not set in Project Settings > PS AI ConvAgent - ElevenLabs.")); + SetStatusError(TEXT("ElevenLabs API Key not set. Set it in Project Settings > Editor > 'PS AI ConvAgent - ElevenLabs (Editor)' (or the ELEVENLABS_API_KEY env var).")); return; } @@ -821,8 +822,9 @@ void FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::OnUpdateAllAgentsClicked() // ───────────────────────────────────────────────────────────────────────────── FString FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::GetAPIKey() const { - // Key is client-provided and stored in a SaveGame slot (see BlueprintLibrary). - return UPS_AI_ConvAgent_BlueprintLibrary::GetElevenLabsAPIKey(); + // Editor-only authoring key (Project Settings → Editor, or ELEVENLABS_API_KEY env). + // Never committed by a build, never packaged — see UPS_AI_ConvAgent_EditorSettings_ElevenLabs. + return UPS_AI_ConvAgent_EditorSettings_ElevenLabs::ResolveEditorApiKey(); } UPS_AI_ConvAgent_Tool_ElevenLabs* FPS_AI_ConvAgent_ToolCustomization_ElevenLabs::GetEditedAsset() const