From a6bd5bbc0d5d6f89297130179de7f7407b024552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20Kirst=C3=A4tter?= <7329802+jochenkirstaetter@users.noreply.github.com> Date: Fri, 12 Apr 2024 09:22:39 +0400 Subject: [PATCH] system instruction is an instance of content --- src/Mscc.GenerativeAI/CHANGELOG.md | 7 ++++++ src/Mscc.GenerativeAI/GenerativeModel.cs | 6 ++--- src/Mscc.GenerativeAI/GoogleAI.cs | 2 +- src/Mscc.GenerativeAI/IGenerativeAI.cs | 2 +- .../Types/GenerateContentRequest.cs | 10 ++++---- src/Mscc.GenerativeAI/VertexAI.cs | 2 +- .../GoogleAi_Gemini15Pro_Should.cs | 23 ++++--------------- .../VertexAi_Gemini15Pro_Should.cs | 12 +++------- 8 files changed, 26 insertions(+), 38 deletions(-) diff --git a/src/Mscc.GenerativeAI/CHANGELOG.md b/src/Mscc.GenerativeAI/CHANGELOG.md index 526c9f5..603dbd8 100644 --- a/src/Mscc.GenerativeAI/CHANGELOG.md +++ b/src/Mscc.GenerativeAI/CHANGELOG.md @@ -14,12 +14,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - implement Automatic Function Call (AFC) - implement Server-Sent Events (SSE) +### Changed +### Fixed + +## 1.1.3 + ### Changed - improve Grounding for Google Search and Vertex AI Search ### Fixed +- system instruction is an instance of content, not a list of same. + ## 1.1.2 ### Added diff --git a/src/Mscc.GenerativeAI/GenerativeModel.cs b/src/Mscc.GenerativeAI/GenerativeModel.cs index c9ebcbc..72ea920 100644 --- a/src/Mscc.GenerativeAI/GenerativeModel.cs +++ b/src/Mscc.GenerativeAI/GenerativeModel.cs @@ -39,7 +39,7 @@ public class GenerativeModel private List? _safetySettings; private GenerationConfig? _generationConfig; private List? _tools; - private List? _systemInstruction; + private Content? _systemInstruction; #if NET472_OR_GREATER || NETSTANDARD2_0 private static readonly Version _httpVersion = HttpVersion.Version11; @@ -236,7 +236,7 @@ internal GenerativeModel(string? apiKey = null, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) : this() + Content? systemInstruction = null) : this() { ApiKey = apiKey ?? _apiKey; Model = model ?? _model; @@ -261,7 +261,7 @@ internal GenerativeModel(string? projectId = null, string? region = null, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) : this() + Content? systemInstruction = null) : this() { _useVertexAi = true; AccessToken = Environment.GetEnvironmentVariable("GOOGLE_ACCESS_TOKEN") ?? diff --git a/src/Mscc.GenerativeAI/GoogleAI.cs b/src/Mscc.GenerativeAI/GoogleAI.cs index 075596f..8817efe 100644 --- a/src/Mscc.GenerativeAI/GoogleAI.cs +++ b/src/Mscc.GenerativeAI/GoogleAI.cs @@ -64,7 +64,7 @@ public GenerativeModel GenerativeModel(string model = Model.Gemini10Pro, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) + Content? systemInstruction = null) { if (_apiKey is null && _accessToken is null) throw new ArgumentNullException("apiKey or accessToken", diff --git a/src/Mscc.GenerativeAI/IGenerativeAI.cs b/src/Mscc.GenerativeAI/IGenerativeAI.cs index 74a9264..cf83803 100644 --- a/src/Mscc.GenerativeAI/IGenerativeAI.cs +++ b/src/Mscc.GenerativeAI/IGenerativeAI.cs @@ -24,7 +24,7 @@ public GenerativeModel GenerativeModel(string model = Model.Gemini10Pro, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null); + Content? systemInstruction = null); /// /// Gets information about a specific Model. diff --git a/src/Mscc.GenerativeAI/Types/GenerateContentRequest.cs b/src/Mscc.GenerativeAI/Types/GenerateContentRequest.cs index 7fa510d..51a2cce 100644 --- a/src/Mscc.GenerativeAI/Types/GenerateContentRequest.cs +++ b/src/Mscc.GenerativeAI/Types/GenerateContentRequest.cs @@ -38,7 +38,7 @@ public class GenerateContentRequest /// The text strings count toward the token limit. /// The role field of systemInstruction is ignored and doesn't affect the performance of the model. /// - public List? SystemInstruction { get; set; } + public Content? SystemInstruction { get; set; } /// /// Initializes a new instance of the class. @@ -58,7 +58,7 @@ public GenerateContentRequest(string prompt, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) : this() + Content? systemInstruction = null) : this() { if (prompt == null) throw new ArgumentNullException(nameof(prompt)); @@ -89,7 +89,7 @@ public GenerateContentRequest(List parts, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) : this() + Content? systemInstruction = null) : this() { if (parts == null) throw new ArgumentNullException(nameof(parts)); @@ -117,7 +117,7 @@ public GenerateContentRequest(FileResource file, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) : this() + Content? systemInstruction = null) : this() { if (file == null) throw new ArgumentNullException(nameof(file)); @@ -145,7 +145,7 @@ public GenerateContentRequest(List parts, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) : this() + Content? systemInstruction = null) : this() { if (parts == null) throw new ArgumentNullException(nameof(parts)); diff --git a/src/Mscc.GenerativeAI/VertexAI.cs b/src/Mscc.GenerativeAI/VertexAI.cs index 90478f2..3378a77 100644 --- a/src/Mscc.GenerativeAI/VertexAI.cs +++ b/src/Mscc.GenerativeAI/VertexAI.cs @@ -67,7 +67,7 @@ public GenerativeModel GenerativeModel(string model = Model.Gemini10Pro, GenerationConfig? generationConfig = null, List? safetySettings = null, List? tools = null, - List? systemInstruction = null) + Content? systemInstruction = null) { if (_projectId is null) throw new ArgumentNullException("projectId"); if (_region is null) throw new ArgumentNullException("region"); diff --git a/tests/Mscc.GenerativeAI/GoogleAi_Gemini15Pro_Should.cs b/tests/Mscc.GenerativeAI/GoogleAi_Gemini15Pro_Should.cs index 9ebb490..62ae3da 100644 --- a/tests/Mscc.GenerativeAI/GoogleAi_Gemini15Pro_Should.cs +++ b/tests/Mscc.GenerativeAI/GoogleAi_Gemini15Pro_Should.cs @@ -568,15 +568,10 @@ public async void Generate_Content_SystemInstruction() { // Arrange var prompt = "Good morning! How are you?"; - var parts = new List + var systemInstruction = new Content { - new TextData { Text = "You are a cat. Your name is Neko." } + Parts = new() { new TextData { Text = "You are a friendly pirate. Speak like one." }} }; - var systemInstruction = new List { new Content - { - Role = Role.System, - Parts = parts - }}; IGenerativeAI genAi = new GoogleAI(_fixture.ApiKey); var model = genAi.GenerativeModel(_model, systemInstruction: systemInstruction); var request = new GenerateContentRequest(prompt); @@ -597,15 +592,10 @@ public async void Generate_Content_SystemInstruction_WithSafetySettings() // Arrange var prompt = @"User input: I like bagels. Answer:"; - var parts = new List + var systemInstruction = new Content { - new TextData { Text = "You are a helpful language translator. Your mission is to translate text in English to French." } + Parts = new() { new TextData { Text = "You are a helpful language translator. Your mission is to translate text in English to French." }} }; - var systemInstruction = new List { new Content - { - Role = Role.System, - Parts = parts - }}; var generationConfig = new GenerationConfig() { Temperature = 0.9f, @@ -632,10 +622,7 @@ public async void Generate_Content_SystemInstruction_WithSafetySettings() response.Should().NotBeNull(); response.Candidates.Should().NotBeNull().And.HaveCount(1); response.Text.Should().NotBeNull(); - _output.WriteLine($"Answer:\n{response?.Text}"); - _output.WriteLine($"Usage metadata: {response.UsageMetadata.TotalTokenCount}"); - _output.WriteLine($"Finish reason: {response.Candidates[0].FinishReason}"); - _output.WriteLine($"Safety settings: {response.Candidates[0].SafetyRatings}"); + _output.WriteLine($"{prompt} {response?.Text}"); } [Fact(Skip = "URL scheme not supported")] diff --git a/tests/Mscc.GenerativeAI/VertexAi_Gemini15Pro_Should.cs b/tests/Mscc.GenerativeAI/VertexAi_Gemini15Pro_Should.cs index b36558c..7c429c2 100644 --- a/tests/Mscc.GenerativeAI/VertexAi_Gemini15Pro_Should.cs +++ b/tests/Mscc.GenerativeAI/VertexAi_Gemini15Pro_Should.cs @@ -245,16 +245,10 @@ public async void Generate_Content_SystemInstruction() // Arrange var prompt = @"User input: I like bagels. Answer:"; - var parts = new List + var systemInstruction = new Content { - new TextData { Text = "You are a helpful language translator." }, - new TextData { Text = "Your mission is to translate text in English to French." } + Parts = new() { new TextData { Text = "You are a friendly pirate. Speak like one. Your mission is to translate text in English to French." }} }; - var systemInstruction = new List { new Content - { - Role = Role.System, - Parts = parts - }}; var generationConfig = new GenerationConfig() { Temperature = 0.9f, @@ -282,7 +276,7 @@ public async void Generate_Content_SystemInstruction() response.Should().NotBeNull(); response.Candidates.Should().NotBeNull().And.HaveCount(1); response.Text.Should().NotBeNull(); - _output.WriteLine($"Answer:\n{response?.Text}"); + _output.WriteLine($"{prompt} {response?.Text}"); _output.WriteLine($"Usage metadata: {response.UsageMetadata.TotalTokenCount}"); _output.WriteLine($"Finish reason: {response.Candidates[0].FinishReason}"); _output.WriteLine($"Safety settings: {response.Candidates[0].SafetyRatings}");