diff --git a/pkgs/sdk/server-ai/src/LdAiClient.cs b/pkgs/sdk/server-ai/src/LdAiClient.cs index 423fa67c..ea227e75 100644 --- a/pkgs/sdk/server-ai/src/LdAiClient.cs +++ b/pkgs/sdk/server-ai/src/LdAiClient.cs @@ -73,10 +73,28 @@ public ILdAiConfigTracker ModelConfig(string key, Context context, LdAiConfig de } - var prompt = - parsed.Prompt?.Select(m => new LdAiConfig.Message(InterpolateTemplate(m.Content, mergedVariables), m.Role)); + var prompt = new List(); + + if (parsed.Prompt != null) + { + for (var i = 0; i < parsed.Prompt.Count; i++) + { + try + { + var content = InterpolateTemplate(parsed.Prompt[i].Content, mergedVariables); + prompt.Add(new LdAiConfig.Message(content, parsed.Prompt[i].Role)); + } + catch (Exception ex) + { + _logger.Error( + $"AI model config prompt has malformed message at index {i}: {ex.Message} (returning default config, which will not contain interpolated prompt messages)"); + return new LdAiConfigTracker(_client, key, defaultValue, context); + } + } + } return new LdAiConfigTracker(_client, key, new LdAiConfig(parsed.Meta?.Enabled ?? false, prompt, parsed.Meta, parsed.Model), context); + } /// @@ -137,7 +155,8 @@ private AiConfig ParseConfig(LdValue value, string key) } catch (JsonException e) { - _logger.Error("Unable to parse AI model config for key {0}: {1}", key, e.Message); + _logger.Error( + $"Unable to parse AI model config for key {key}: {e.Message} (returning default config, which will not contain interpolated prompt messages)"); return null; } } diff --git a/pkgs/sdk/server-ai/test/InterpolationTests.cs b/pkgs/sdk/server-ai/test/InterpolationTests.cs index d6256e9d..d7ddf163 100644 --- a/pkgs/sdk/server-ai/test/InterpolationTests.cs +++ b/pkgs/sdk/server-ai/test/InterpolationTests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; @@ -117,6 +118,37 @@ public void TestInterpolationWithArraySectionWorks() Assert.Equal("hello world ! ", result); } + [Fact] + public void TestInterpolationMalformed() + { + var mockClient = new Mock(); + var mockLogger = new Mock(); + + const string configJson = """ + { + "_ldMeta": {"versionKey": "1", "enabled": true}, + "model": {}, + "prompt": [ + { + "content": "This is a {{ malformed }]} prompt", + "role": "System" + } + ] + } + """; + + + mockClient.Setup(x => + x.JsonVariation("foo", It.IsAny(), It.IsAny())).Returns(LdValue.Parse(configJson)); + + mockClient.Setup(x => x.GetLogger()).Returns(mockLogger.Object); + + mockLogger.Setup(x => x.Error(It.IsAny())); + + var client = new LdAiClient(mockClient.Object); + var tracker = client.ModelConfig("foo", Context.New("key"), LdAiConfig.Disabled); + Assert.False(tracker.Config.Enabled); + } [Fact] public void TestInterpolationWithBasicContext()