diff --git a/LLama.Unittest/LLama.Unittest.csproj b/LLama.Unittest/LLama.Unittest.csproj
index 0532244d..bcd5feef 100644
--- a/LLama.Unittest/LLama.Unittest.csproj
+++ b/LLama.Unittest/LLama.Unittest.csproj
@@ -30,6 +30,7 @@
+
diff --git a/LLama.Unittest/SemanticKernel/ChatRequestSettingsConverterTests.cs b/LLama.Unittest/SemanticKernel/ChatRequestSettingsConverterTests.cs
new file mode 100644
index 00000000..4190e852
--- /dev/null
+++ b/LLama.Unittest/SemanticKernel/ChatRequestSettingsConverterTests.cs
@@ -0,0 +1,107 @@
+using LLamaSharp.SemanticKernel.ChatCompletion;
+using System.Text.Json;
+
+namespace LLama.Unittest.SemanticKernel
+{
+ public class ChatRequestSettingsConverterTests
+ {
+ [Fact]
+ public void ChatRequestSettingsConverter_DeserializeWithDefaults()
+ {
+ // Arrange
+ var options = new JsonSerializerOptions();
+ options.Converters.Add(new ChatRequestSettingsConverter());
+ var json = "{}";
+
+ // Act
+ var requestSettings = JsonSerializer.Deserialize(json, options);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(0, requestSettings.FrequencyPenalty);
+ Assert.Null(requestSettings.MaxTokens);
+ Assert.Equal(0, requestSettings.PresencePenalty);
+ Assert.Equal(1, requestSettings.ResultsPerPrompt);
+ Assert.NotNull(requestSettings.StopSequences);
+ Assert.Empty(requestSettings.StopSequences);
+ Assert.Equal(0, requestSettings.Temperature);
+ Assert.NotNull(requestSettings.TokenSelectionBiases);
+ Assert.Empty(requestSettings.TokenSelectionBiases);
+ Assert.Equal(0, requestSettings.TopP);
+ }
+
+ [Fact]
+ public void ChatRequestSettingsConverter_DeserializeWithSnakeCase()
+ {
+ // Arrange
+ var options = new JsonSerializerOptions();
+ options.AllowTrailingCommas = true;
+ options.Converters.Add(new ChatRequestSettingsConverter());
+ var json = @"{
+ ""frequency_penalty"": 0.5,
+ ""max_tokens"": 250,
+ ""presence_penalty"": 0.5,
+ ""results_per_prompt"": -1,
+ ""stop_sequences"": [ ""foo"", ""bar"" ],
+ ""temperature"": 0.5,
+ ""token_selection_biases"": { ""1"": 2, ""3"": 4 },
+ ""top_p"": 0.5,
+}";
+
+ // Act
+ var requestSettings = JsonSerializer.Deserialize(json, options);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(0.5, requestSettings.FrequencyPenalty);
+ Assert.Equal(250, requestSettings.MaxTokens);
+ Assert.Equal(0.5, requestSettings.PresencePenalty);
+ Assert.Equal(-1, requestSettings.ResultsPerPrompt);
+ Assert.NotNull(requestSettings.StopSequences);
+ Assert.Contains("foo", requestSettings.StopSequences);
+ Assert.Contains("bar", requestSettings.StopSequences);
+ Assert.Equal(0.5, requestSettings.Temperature);
+ Assert.NotNull(requestSettings.TokenSelectionBiases);
+ Assert.Equal(2, requestSettings.TokenSelectionBiases[1]);
+ Assert.Equal(4, requestSettings.TokenSelectionBiases[3]);
+ Assert.Equal(0.5, requestSettings.TopP);
+ }
+
+ [Fact]
+ public void ChatRequestSettingsConverter_DeserializeWithPascalCase()
+ {
+ // Arrange
+ var options = new JsonSerializerOptions();
+ options.AllowTrailingCommas = true;
+ options.Converters.Add(new ChatRequestSettingsConverter());
+ var json = @"{
+ ""FrequencyPenalty"": 0.5,
+ ""MaxTokens"": 250,
+ ""PresencePenalty"": 0.5,
+ ""ResultsPerPrompt"": -1,
+ ""StopSequences"": [ ""foo"", ""bar"" ],
+ ""Temperature"": 0.5,
+ ""TokenSelectionBiases"": { ""1"": 2, ""3"": 4 },
+ ""TopP"": 0.5,
+}";
+
+ // Act
+ var requestSettings = JsonSerializer.Deserialize(json, options);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(0.5, requestSettings.FrequencyPenalty);
+ Assert.Equal(250, requestSettings.MaxTokens);
+ Assert.Equal(0.5, requestSettings.PresencePenalty);
+ Assert.Equal(-1, requestSettings.ResultsPerPrompt);
+ Assert.NotNull(requestSettings.StopSequences);
+ Assert.Contains("foo", requestSettings.StopSequences);
+ Assert.Contains("bar", requestSettings.StopSequences);
+ Assert.Equal(0.5, requestSettings.Temperature);
+ Assert.NotNull(requestSettings.TokenSelectionBiases);
+ Assert.Equal(2, requestSettings.TokenSelectionBiases[1]);
+ Assert.Equal(4, requestSettings.TokenSelectionBiases[3]);
+ Assert.Equal(0.5, requestSettings.TopP);
+ }
+ }
+}
diff --git a/LLama.Unittest/SemanticKernel/ChatRequestSettingsTests.cs b/LLama.Unittest/SemanticKernel/ChatRequestSettingsTests.cs
new file mode 100644
index 00000000..99881b57
--- /dev/null
+++ b/LLama.Unittest/SemanticKernel/ChatRequestSettingsTests.cs
@@ -0,0 +1,169 @@
+using LLamaSharp.SemanticKernel.ChatCompletion;
+using Microsoft.SemanticKernel.AI;
+
+namespace LLama.Unittest.SemanticKernel
+{
+ public class ChatRequestSettingsTests
+ {
+ [Fact]
+ public void ChatRequestSettings_FromRequestSettingsNull()
+ {
+ // Arrange
+ // Act
+ var requestSettings = ChatRequestSettings.FromRequestSettings(null, null);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(0, requestSettings.FrequencyPenalty);
+ Assert.Null(requestSettings.MaxTokens);
+ Assert.Equal(0, requestSettings.PresencePenalty);
+ Assert.Equal(1, requestSettings.ResultsPerPrompt);
+ Assert.NotNull(requestSettings.StopSequences);
+ Assert.Empty(requestSettings.StopSequences);
+ Assert.Equal(0, requestSettings.Temperature);
+ Assert.NotNull(requestSettings.TokenSelectionBiases);
+ Assert.Empty(requestSettings.TokenSelectionBiases);
+ Assert.Equal(0, requestSettings.TopP);
+ }
+
+ [Fact]
+ public void ChatRequestSettings_FromRequestSettingsNullWithMaxTokens()
+ {
+ // Arrange
+ // Act
+ var requestSettings = ChatRequestSettings.FromRequestSettings(null, 200);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(0, requestSettings.FrequencyPenalty);
+ Assert.Equal(200, requestSettings.MaxTokens);
+ Assert.Equal(0, requestSettings.PresencePenalty);
+ Assert.Equal(1, requestSettings.ResultsPerPrompt);
+ Assert.NotNull(requestSettings.StopSequences);
+ Assert.Empty(requestSettings.StopSequences);
+ Assert.Equal(0, requestSettings.Temperature);
+ Assert.NotNull(requestSettings.TokenSelectionBiases);
+ Assert.Empty(requestSettings.TokenSelectionBiases);
+ Assert.Equal(0, requestSettings.TopP);
+ }
+
+ [Fact]
+ public void ChatRequestSettings_FromExistingRequestSettings()
+ {
+ // Arrange
+ var originalRequestSettings = new ChatRequestSettings()
+ {
+ FrequencyPenalty = 0.5,
+ MaxTokens = 100,
+ PresencePenalty = 0.5,
+ ResultsPerPrompt = -1,
+ StopSequences = new[] { "foo", "bar" },
+ Temperature = 0.5,
+ TokenSelectionBiases = new Dictionary() { { 1, 2 }, { 3, 4 } },
+ TopP = 0.5,
+ };
+
+ // Act
+ var requestSettings = ChatRequestSettings.FromRequestSettings(originalRequestSettings);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(originalRequestSettings, requestSettings);
+ }
+
+ [Fact]
+ public void ChatRequestSettings_FromAIRequestSettings()
+ {
+ // Arrange
+ var originalRequestSettings = new AIRequestSettings()
+ {
+ ServiceId = "test",
+ };
+
+ // Act
+ var requestSettings = ChatRequestSettings.FromRequestSettings(originalRequestSettings);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(originalRequestSettings.ServiceId, requestSettings.ServiceId);
+ }
+
+ [Fact]
+ public void ChatRequestSettings_FromAIRequestSettingsWithExtraPropertiesInSnakeCase()
+ {
+ // Arrange
+ var originalRequestSettings = new AIRequestSettings()
+ {
+ ServiceId = "test",
+ ExtensionData = new Dictionary
+ {
+ { "frequency_penalty", 0.5 },
+ { "max_tokens", 250 },
+ { "presence_penalty", 0.5 },
+ { "results_per_prompt", -1 },
+ { "stop_sequences", new [] { "foo", "bar" } },
+ { "temperature", 0.5 },
+ { "token_selection_biases", new Dictionary() { { 1, 2 }, { 3, 4 } } },
+ { "top_p", 0.5 },
+ }
+ };
+
+ // Act
+ var requestSettings = ChatRequestSettings.FromRequestSettings(originalRequestSettings);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(0.5, requestSettings.FrequencyPenalty);
+ Assert.Equal(250, requestSettings.MaxTokens);
+ Assert.Equal(0.5, requestSettings.PresencePenalty);
+ Assert.Equal(-1, requestSettings.ResultsPerPrompt);
+ Assert.NotNull(requestSettings.StopSequences);
+ Assert.Contains("foo", requestSettings.StopSequences);
+ Assert.Contains("bar", requestSettings.StopSequences);
+ Assert.Equal(0.5, requestSettings.Temperature);
+ Assert.NotNull(requestSettings.TokenSelectionBiases);
+ Assert.Equal(2, requestSettings.TokenSelectionBiases[1]);
+ Assert.Equal(4, requestSettings.TokenSelectionBiases[3]);
+ Assert.Equal(0.5, requestSettings.TopP);
+ }
+
+ [Fact]
+ public void ChatRequestSettings_FromAIRequestSettingsWithExtraPropertiesInPascalCase()
+ {
+ // Arrange
+ var originalRequestSettings = new AIRequestSettings()
+ {
+ ServiceId = "test",
+ ExtensionData = new Dictionary
+ {
+ { "FrequencyPenalty", 0.5 },
+ { "MaxTokens", 250 },
+ { "PresencePenalty", 0.5 },
+ { "ResultsPerPrompt", -1 },
+ { "StopSequences", new [] { "foo", "bar" } },
+ { "Temperature", 0.5 },
+ { "TokenSelectionBiases", new Dictionary() { { 1, 2 }, { 3, 4 } } },
+ { "TopP", 0.5 },
+ }
+ };
+
+ // Act
+ var requestSettings = ChatRequestSettings.FromRequestSettings(originalRequestSettings);
+
+ // Assert
+ Assert.NotNull(requestSettings);
+ Assert.Equal(0.5, requestSettings.FrequencyPenalty);
+ Assert.Equal(250, requestSettings.MaxTokens);
+ Assert.Equal(0.5, requestSettings.PresencePenalty);
+ Assert.Equal(-1, requestSettings.ResultsPerPrompt);
+ Assert.NotNull(requestSettings.StopSequences);
+ Assert.Contains("foo", requestSettings.StopSequences);
+ Assert.Contains("bar", requestSettings.StopSequences);
+ Assert.Equal(0.5, requestSettings.Temperature);
+ Assert.NotNull(requestSettings.TokenSelectionBiases);
+ Assert.Equal(2, requestSettings.TokenSelectionBiases[1]);
+ Assert.Equal(4, requestSettings.TokenSelectionBiases[3]);
+ Assert.Equal(0.5, requestSettings.TopP);
+ }
+ }
+}