diff --git a/Source/Private/Core/N2CSerializer.cpp b/Source/Private/Core/N2CSerializer.cpp index 02f56b7..3f1e759 100644 --- a/Source/Private/Core/N2CSerializer.cpp +++ b/Source/Private/Core/N2CSerializer.cpp @@ -751,7 +751,7 @@ bool FN2CSerializer::ParseFlowsFromJson(const TSharedPtr& JsonObjec { if (DataFlow.Value->Type == EJson::String) { - OutFlows.Data.Add(DataFlow.Key, DataFlow.Value->AsString()); + OutFlows.Data.Add(FString(DataFlow.Key.ToView()), DataFlow.Value->AsString()); } } @@ -921,4 +921,4 @@ bool FN2CSerializer::ParseEnumFromJson(const TSharedPtr& JsonObject } return true; -} +} \ No newline at end of file diff --git a/Source/Private/Core/N2CSettings.cpp b/Source/Private/Core/N2CSettings.cpp index c89f014..50a4634 100644 --- a/Source/Private/Core/N2CSettings.cpp +++ b/Source/Private/Core/N2CSettings.cpp @@ -44,6 +44,7 @@ UN2CSettings::UN2CSettings() Anthropic_API_Key_UI = UserSecrets->Anthropic_API_Key; Gemini_API_Key_UI = UserSecrets->Gemini_API_Key; DeepSeek_API_Key_UI = UserSecrets->DeepSeek_API_Key; + OllamaConfig.ApiKey = UserSecrets->Ollama_API_Key; // Initialize token estimate EstimatedReferenceTokens = GetReferenceFilesTokenEstimate(); @@ -80,6 +81,8 @@ FString UN2CSettings::GetActiveApiKey() const return UserSecrets->Gemini_API_Key; case EN2CLLMProvider::DeepSeek: return UserSecrets->DeepSeek_API_Key; + case EN2CLLMProvider::Ollama: + return UserSecrets->Ollama_API_Key; case EN2CLLMProvider::LMStudio: return "lm-studio"; // LM Studio just requires a dummy API key for its OpenAI endpoint default: @@ -269,6 +272,17 @@ void UN2CSettings::PostEditChangeProperty(FPropertyChangedEvent& PropertyChanged UserSecrets->SaveSecrets(); return; } + if (PropertyName == GET_MEMBER_NAME_CHECKED(FN2COllamaConfig, ApiKey)) + { + if (!UserSecrets) + { + UserSecrets = NewObject(); + UserSecrets->LoadSecrets(); + } + UserSecrets->Ollama_API_Key = OllamaConfig.ApiKey; + UserSecrets->SaveSecrets(); + return; + } // Update logger severity when MinSeverity changes if (PropertyName == GET_MEMBER_NAME_CHECKED(UN2CSettings, MinSeverity)) diff --git a/Source/Private/Core/N2CUserSecrets.cpp b/Source/Private/Core/N2CUserSecrets.cpp index 593b83a..1674e00 100644 --- a/Source/Private/Core/N2CUserSecrets.cpp +++ b/Source/Private/Core/N2CUserSecrets.cpp @@ -71,6 +71,7 @@ void UN2CUserSecrets::LoadSecrets() Anthropic_API_Key = JsonObject->GetStringField(TEXT("Anthropic_API_Key")); Gemini_API_Key = JsonObject->GetStringField(TEXT("Gemini_API_Key")); DeepSeek_API_Key = JsonObject->GetStringField(TEXT("DeepSeek_API_Key")); + JsonObject->TryGetStringField(TEXT("Ollama_API_Key"), Ollama_API_Key); FN2CLogger::Get().Log( FString::Printf(TEXT("Successfully loaded secrets from: %s"), *SecretsFilePath), @@ -88,6 +89,7 @@ void UN2CUserSecrets::SaveSecrets() JsonObject->SetStringField(TEXT("Anthropic_API_Key"), Anthropic_API_Key); JsonObject->SetStringField(TEXT("Gemini_API_Key"), Gemini_API_Key); JsonObject->SetStringField(TEXT("DeepSeek_API_Key"), DeepSeek_API_Key); + JsonObject->SetStringField(TEXT("Ollama_API_Key"), Ollama_API_Key); // Serialize to string FString JsonString; diff --git a/Source/Public/Core/N2CUserSecrets.h b/Source/Public/Core/N2CUserSecrets.h index 0c007ca..033cde2 100644 --- a/Source/Public/Core/N2CUserSecrets.h +++ b/Source/Public/Core/N2CUserSecrets.h @@ -44,6 +44,10 @@ class NODETOCODE_API UN2CUserSecrets : public UObject /** DeepSeek API Key */ UPROPERTY(EditAnywhere, Category = "Node to Code | API Keys") FString DeepSeek_API_Key; + + /** Ollama API Key */ + UPROPERTY(EditAnywhere, Category = "Node to Code | API Keys") + FString Ollama_API_Key; private: /** Ensure the secrets directory exists */ diff --git a/Source/Public/LLM/N2COllamaConfig.h b/Source/Public/LLM/N2COllamaConfig.h index c469603..6960771 100644 --- a/Source/Public/LLM/N2COllamaConfig.h +++ b/Source/Public/LLM/N2COllamaConfig.h @@ -20,6 +20,12 @@ struct FN2COllamaConfig ToolTip="The base endpoint to use for the Ollama API. Defaults to http:localhost:11434")) FString OllamaEndpoint = "http://localhost:11434"; + /** Optional API key for authenticated Ollama endpoints such as Ollama Cloud. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient, Category = "Cloud", + meta=(DisplayName="API Key", PasswordField=true, + ToolTip="API key for authenticated Ollama endpoints such as Ollama Cloud. Leave empty for local Ollama servers.")) + FString ApiKey; + /** Whether to use system prompts with Ollama models */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General", meta=(DisplayName="Use System Prompts",