From fdf64b2c46c8e1ed324203518b430a5f6a0e1a9b Mon Sep 17 00:00:00 2001 From: Juan Dominguez Date: Fri, 28 Nov 2025 13:07:46 -0300 Subject: [PATCH 1/3] feat(genai): add tool samples --- .../Tools/ToolsCodeExecWithTxtTest.cs | 38 ++++++ .../Tools/ToolsFuncDescWithTxtTest.cs | 41 ++++++ .../Tools/ToolsGoogleSearchWithTxtTest.cs | 40 ++++++ .../Tools/ToolsUrlContextWithTxtTest.cs | 40 ++++++ .../Tools/ToolsCodeExecWithTxt.cs | 96 ++++++++++++++ .../Tools/ToolsFuncDescWithTxt.cs | 123 ++++++++++++++++++ .../Tools/ToolsGoogleSearchWithTxt.cs | 57 ++++++++ .../Tools/ToolsUrlContextWithTxt.cs | 66 ++++++++++ 8 files changed, 501 insertions(+) create mode 100644 genai/api/GenAI.Samples.Tests/Tools/ToolsCodeExecWithTxtTest.cs create mode 100644 genai/api/GenAI.Samples.Tests/Tools/ToolsFuncDescWithTxtTest.cs create mode 100644 genai/api/GenAI.Samples.Tests/Tools/ToolsGoogleSearchWithTxtTest.cs create mode 100644 genai/api/GenAI.Samples.Tests/Tools/ToolsUrlContextWithTxtTest.cs create mode 100644 genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs create mode 100644 genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs create mode 100644 genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs create mode 100644 genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs diff --git a/genai/api/GenAI.Samples.Tests/Tools/ToolsCodeExecWithTxtTest.cs b/genai/api/GenAI.Samples.Tests/Tools/ToolsCodeExecWithTxtTest.cs new file mode 100644 index 00000000000..168afe51692 --- /dev/null +++ b/genai/api/GenAI.Samples.Tests/Tools/ToolsCodeExecWithTxtTest.cs @@ -0,0 +1,38 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(GenAIFixture))] +public class ToolsCodeExecWithTxtTest +{ + private readonly GenAIFixture _fixture; + private readonly ToolsCodeExecWithTxt _sample; + + public ToolsCodeExecWithTxtTest(GenAIFixture fixture) + { + _fixture = fixture; + _sample = new ToolsCodeExecWithTxt(); + } + + [Fact] + public async Task TestToolsCodeExecWithTxt() + { + var response = await _sample.GenerateContent(_fixture.ProjectId); + Assert.NotEmpty(response); + } +} diff --git a/genai/api/GenAI.Samples.Tests/Tools/ToolsFuncDescWithTxtTest.cs b/genai/api/GenAI.Samples.Tests/Tools/ToolsFuncDescWithTxtTest.cs new file mode 100644 index 00000000000..d4de7feacfd --- /dev/null +++ b/genai/api/GenAI.Samples.Tests/Tools/ToolsFuncDescWithTxtTest.cs @@ -0,0 +1,41 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Google.GenAI.Types; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(GenAIFixture))] +public class ToolsFuncDescWithTxtTest +{ + private readonly GenAIFixture _fixture; + private readonly ToolsFuncDescWithTxt _sample; + + public ToolsFuncDescWithTxtTest(GenAIFixture fixture) + { + _fixture = fixture; + _sample = new ToolsFuncDescWithTxt(); + } + + [Fact] + public async Task TestToolsFuncDescWithTxt() + { + FunctionCall response = await _sample.GenerateContent(_fixture.ProjectId); + Assert.NotNull(response); + Assert.NotEmpty(response.Name); + Assert.NotEmpty(response.Args); + } +} diff --git a/genai/api/GenAI.Samples.Tests/Tools/ToolsGoogleSearchWithTxtTest.cs b/genai/api/GenAI.Samples.Tests/Tools/ToolsGoogleSearchWithTxtTest.cs new file mode 100644 index 00000000000..188a65d092e --- /dev/null +++ b/genai/api/GenAI.Samples.Tests/Tools/ToolsGoogleSearchWithTxtTest.cs @@ -0,0 +1,40 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Google.GenAI.Types; +using System; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(GenAIFixture))] +public class ToolsGoogleSearchWithTxtTest +{ + private readonly GenAIFixture _fixture; + private readonly ToolsGoogleSearchWithTxt _sample; + + public ToolsGoogleSearchWithTxtTest(GenAIFixture fixture) + { + _fixture = fixture; + _sample = new ToolsGoogleSearchWithTxt(); + } + + [Fact] + public async Task TestToolsGoogleSearchWithTxt() + { + var response = await _sample.GenerateContent(_fixture.ProjectId); + Assert.NotEmpty(response); + } +} diff --git a/genai/api/GenAI.Samples.Tests/Tools/ToolsUrlContextWithTxtTest.cs b/genai/api/GenAI.Samples.Tests/Tools/ToolsUrlContextWithTxtTest.cs new file mode 100644 index 00000000000..b97ff3f1263 --- /dev/null +++ b/genai/api/GenAI.Samples.Tests/Tools/ToolsUrlContextWithTxtTest.cs @@ -0,0 +1,40 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Google.GenAI.Types; +using System; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(GenAIFixture))] +public class ToolsUrlContextWithTxtTest +{ + private readonly GenAIFixture _fixture; + private readonly ToolsUrlContextWithTxt _sample; + + public ToolsUrlContextWithTxtTest(GenAIFixture fixture) + { + _fixture = fixture; + _sample = new ToolsUrlContextWithTxt(); + } + + [Fact] + public async Task TestToolsUrlContextWithTxt() + { + var response = await _sample.GenerateContent(_fixture.ProjectId); + Assert.NotEmpty(response); + } +} diff --git a/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs new file mode 100644 index 00000000000..8a6d0ba6853 --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs @@ -0,0 +1,96 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// [START googlegenaisdk_tools_code_exec_with_txt] + +using Google.GenAI; +using Google.GenAI.Types; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +public class ToolsCodeExecWithTxt +{ + public async Task GenerateContent( + string projectId = "your-project-id", + string location = "global", + string model = "gemini-2.5-flash") + { + await using var client = new Client( + project: projectId, + location: location, + vertexAI: true, + httpOptions: new HttpOptions { ApiVersion = "v1" }); + + GenerateContentResponse response = await client.Models.GenerateContentAsync( + model: model, + contents: "Calculate 20th fibonacci number. Then find the nearest palindrome to it.", + config: new GenerateContentConfig + { + Tools = new List { new Tool { CodeExecution = new ToolCodeExecution() } }, + Temperature = 0 + }); + + List parts = response.Candidates?[0]?.Content?.Parts ?? new List(); + StringBuilder responseText = new StringBuilder(); + + foreach (Part part in parts) + { + if (part.Text != null) + { + Console.WriteLine($"Text: \n{part.Text}"); + responseText.AppendLine(part.Text); + } + + if (part.ExecutableCode != null) + { + Console.WriteLine($"Code: \n{part.ExecutableCode}"); + } + + if (part.CodeExecutionResult != null) + { + Console.WriteLine($"Outcome: \n{part.CodeExecutionResult}"); + } + } + + // Example response: + // Text: + // o calculate the 20th Fibonacci number and find its nearest palindrome, I will perform the following steps: + // 1. * *Calculate the 20th Fibonacci number: **I will use a Python function to compute the Fibonacci sequence. + // ... + // Code: + // ExecutableCode { + // Code = def fibonacci(n): + // a, b = 0, 1 + // for _ in range(n): + // a, b = b, a + b + // return a + // fib_20 = fibonacci(20) + // print(f'{fib_20=}') + // , Language = PYTHON } + // + // Outcome: + // CodeExecutionResult { Outcome = OUTCOME_OK, Output = fib_20 = 6765 } + // + // Code: + // ExecutableCode { + // Code = def is_palindrome(n): + // ... + return responseText.ToString(); + } +} +// [END googlegenaisdk_tools_code_exec_with_txt] diff --git a/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs new file mode 100644 index 00000000000..2a5c023a6e2 --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs @@ -0,0 +1,123 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// [START googlegenaisdk_tools_func_desc_with_txt] + +using Google.GenAI; +using Google.GenAI.Types; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +public class ToolsFuncDescWithTxt +{ + public async Task GenerateContent( + string projectId = "your-project-id", + string location = "global", + string model = "gemini-2.5-flash") + { + await using var client = new Client( + project: projectId, + location: location, + vertexAI: true, + httpOptions: new HttpOptions { ApiVersion = "v1" }); + + List getAlbumSales = new List + { + new FunctionDeclaration + { + Name = "get_album_sales", + Description = "Gets the number of albums sold", + Parameters = new Schema + { + Type = Google.GenAI.Types.Type.OBJECT, + Properties = new Dictionary + { + { + "albums", + new Schema + { + Type = Google.GenAI.Types.Type.ARRAY, + Description = "List of albums", + Items = new Schema + { + Type = Google.GenAI.Types.Type.OBJECT, + Description = "Album and its sales", + Properties = new Dictionary + { + { + "album_name", + new Schema + { + Type = Google.GenAI.Types.Type.STRING, + Description = "Name of the music album" + } + }, + { + "copies_sold", + new Schema + { + Type = Google.GenAI.Types.Type.INTEGER, + Description = "Number of copies sold" + } + } + } + } + } + } + } + } + } + }; + + string contents = "At Stellar Sounds, a music label, 2024 was a rollercoaster." + + " \"Echoes of the Night,\" a debut synth-pop album, surprisingly sold 350,000 copies," + + " while veteran rock band \"Crimson Tide\\'s\" latest, \"Reckless Hearts,\" lagged at 120,000." + + " Their up-and-coming indie artist, \"Luna Bloom\\'s\" EP, \"Whispers of Dawn,\" secured 75,000 sales." + + " The biggest disappointment was the highly-anticipated rap album \"Street Symphony\" only reaching 100,000" + + " units. Overall, Stellar Sounds moved over 645,000 units this year, revealing unexpected trends in music consumption."; + + GenerateContentResponse response = await client.Models.GenerateContentAsync( + model: model, + contents: contents, + config: new GenerateContentConfig + { + Temperature = 0, + Tools = new List + { + new Tool { FunctionDeclarations = getAlbumSales } + } + }); + + FunctionCall functionCall = response.Candidates[0].Content.Parts[0].FunctionCall; + + Console.WriteLine($"Name: {functionCall.Name}"); + + foreach (var parameter in functionCall.Args) + { + Console.WriteLine(parameter); + } + // Example output: + // Name: get_album_sales + // + // [albums, [{"album_name": "Echoes of the Night", "copies_sold": 350000}, + // {"album_name": "Reckless Hearts", "copies_sold": 120000}, + // {"copies_sold": 75000, "album_name": "Whispers of Dawn"}, + // {"album_name": "Street Symphony","copies_sold": 100000}]] + return functionCall; + } +} +// [END googlegenaisdk_tools_func_desc_with_txt] diff --git a/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs new file mode 100644 index 00000000000..b01f33a4f4d --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs @@ -0,0 +1,57 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// [START googlegenaisdk_tools_google_search_with_txt] + +using Google.GenAI; +using Google.GenAI.Types; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +public class ToolsGoogleSearchWithTxt +{ + public async Task GenerateContent( + string projectId = "your-project-id", + string location = "global", + string model = "gemini-2.5-flash") + { + await using var client = new Client( + project: projectId, + location: location, + vertexAI: true, + httpOptions: new HttpOptions { ApiVersion = "v1" }); + + GenerateContentResponse response = await client.Models.GenerateContentAsync( + model: model, + contents: "When is the next total solar eclipse in the United States?", + config: new GenerateContentConfig + { + Tools = new List + { + // Use Google Search Tool + new Tool { GoogleSearch = new GoogleSearch() } + } + }); + + string responseText = response.Candidates[0].Content.Parts[0].Text; + Console.WriteLine(responseText); + // Example response: + // The next total solar eclipse visible in the United States will occur on... + return responseText; + } +} +// [END googlegenaisdk_tools_google_search_with_txt] diff --git a/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs new file mode 100644 index 00000000000..fa331186452 --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs @@ -0,0 +1,66 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// [START googlegenaisdk_tools_urlcontext_with_txt] + +using Google.GenAI; +using Google.GenAI.Types; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +public class ToolsUrlContextWithTxt +{ + public async Task GenerateContent( + string projectId = "your-project-id", + string location = "global", + string model = "gemini-2.5-flash") + { + await using var client = new Client( + project: projectId, + location: location, + vertexAI: true, + httpOptions: new HttpOptions { ApiVersion = "v1" }); + + string url1 = "https://cloud.google.com/vertex-ai/generative-ai/docs"; + string url2 = "https://cloud.google.com/docs/overview"; + + GenerateContentResponse response = await client.Models.GenerateContentAsync( + model: model, + contents: $"Compare the content, purpose, and audiences of {url1} and {url2}.", + config: new GenerateContentConfig + { + Tools = new List + { + // Use Url Context Tool + new Tool { UrlContext = new UrlContext() } + }, + ResponseModalities = new List { "TEXT" } + }); + + string responseText = response.Candidates[0].Content.Parts[0].Text; + Console.WriteLine(responseText); + // Example response: + // The two Google Cloud documentation pages serve distinct purposes, cover different content scopes... + + // Url Context Metadata + response.Candidates[0].UrlContextMetadata.UrlMetadata.ForEach(Console.WriteLine); + // UrlMetadata { RetrievedUrl = https://cloud.google.com/docs/overview, UrlRetrievalStatus = URL_RETRIEVAL_STATUS_SUCCESS } + // UrlMetadata { RetrievedUrl = https://cloud.google.com/vertex-ai/generative-ai/docs, UrlRetrievalStatus = URL_RETRIEVAL_STATUS_SUCCESS } + return responseText; + } +} +// [END googlegenaisdk_tools_urlcontext_with_txt] From 32c2a6c439018832e523d22c6e29658d0e68f964 Mon Sep 17 00:00:00 2001 From: Juan Dominguez Date: Wed, 10 Dec 2025 13:00:02 -0300 Subject: [PATCH 2/3] refactor(genai): change parameter schema and comments --- .../Tools/ToolsCodeExecWithTxt.cs | 3 ++ .../Tools/ToolsFuncDescWithTxt.cs | 51 ++++++++++--------- .../Tools/ToolsGoogleSearchWithTxt.cs | 1 - .../Tools/ToolsUrlContextWithTxt.cs | 1 - 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs index 8a6d0ba6853..3d68f444b22 100644 --- a/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs +++ b/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs @@ -42,6 +42,9 @@ public async Task GenerateContent( config: new GenerateContentConfig { Tools = new List { new Tool { CodeExecution = new ToolCodeExecution() } }, + // The temperature controls the randomness of the output, ranging from 0.0 to 2.0. + // A temperature of 0 is more deterministic, meaning that the model can generate more focused and predictable responses. + // Higher temperatures can lead to less predictable and more creative responses. Temperature = 0 }); diff --git a/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs index 2a5c023a6e2..1439eebab81 100644 --- a/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs +++ b/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs @@ -41,37 +41,40 @@ public async Task GenerateContent( { Name = "get_album_sales", Description = "Gets the number of albums sold", - Parameters = new Schema + ParametersJsonSchema = new Dictionary { - Type = Google.GenAI.Types.Type.OBJECT, - Properties = new Dictionary + { "type", "object" }, { + "properties", new Dictionary { - "albums", - new Schema { - Type = Google.GenAI.Types.Type.ARRAY, - Description = "List of albums", - Items = new Schema + "albums", new Dictionary { - Type = Google.GenAI.Types.Type.OBJECT, - Description = "Album and its sales", - Properties = new Dictionary + { "type", "array" }, + { "description", "List of albums" }, { + "items", new Dictionary { - "album_name", - new Schema + { "type", "object" }, + { "description", "Album and its sales" }, { - Type = Google.GenAI.Types.Type.STRING, - Description = "Name of the music album" - } - }, - { - "copies_sold", - new Schema - { - Type = Google.GenAI.Types.Type.INTEGER, - Description = "Number of copies sold" + "properties", new Dictionary + { + { + "album_name", new Dictionary + { + { "type", "string" }, + { "description", "Name of the music album" } + } + }, + { + "copies_sold", new Dictionary + { + { "type", "integer" }, + { "description", "Number of copies sold" } + } + } + } } } } @@ -115,7 +118,7 @@ public async Task GenerateContent( // // [albums, [{"album_name": "Echoes of the Night", "copies_sold": 350000}, // {"album_name": "Reckless Hearts", "copies_sold": 120000}, - // {"copies_sold": 75000, "album_name": "Whispers of Dawn"}, + // {"album_name": "Whispers of Dawn", "copies_sold": 75000}, // {"album_name": "Street Symphony","copies_sold": 100000}]] return functionCall; } diff --git a/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs index b01f33a4f4d..9ddb624749a 100644 --- a/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs +++ b/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs @@ -42,7 +42,6 @@ public async Task GenerateContent( { Tools = new List { - // Use Google Search Tool new Tool { GoogleSearch = new GoogleSearch() } } }); diff --git a/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs index fa331186452..f95db4bdfe4 100644 --- a/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs +++ b/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs @@ -45,7 +45,6 @@ public async Task GenerateContent( { Tools = new List { - // Use Url Context Tool new Tool { UrlContext = new UrlContext() } }, ResponseModalities = new List { "TEXT" } From 8a2b404d2ed8065c7c32fb8e691b2d933e747358 Mon Sep 17 00:00:00 2001 From: Juan Dominguez Date: Wed, 10 Dec 2025 18:10:17 -0300 Subject: [PATCH 3/3] refactor(genai): update function calling to use ResponseJsonSchema --- .../Tools/ToolsFuncDescWithTxt.cs | 87 +++++++++++++------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs b/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs index 1439eebab81..d6c07b60bd2 100644 --- a/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs +++ b/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs @@ -35,45 +35,37 @@ public async Task GenerateContent( vertexAI: true, httpOptions: new HttpOptions { ApiVersion = "v1" }); - List getAlbumSales = new List + var parametersJsonSchema = new Dictionary { - new FunctionDeclaration + { "type", "object" }, { - Name = "get_album_sales", - Description = "Gets the number of albums sold", - ParametersJsonSchema = new Dictionary + "properties", new Dictionary { - { "type", "object" }, { - "properties", new Dictionary + "albums", new Dictionary { + { "type", "array" }, + { "description", "List of albums" }, { - "albums", new Dictionary + "items", new Dictionary { - { "type", "array" }, - { "description", "List of albums" }, + { "type", "object" }, + { "description", "Album and its sales" }, { - "items", new Dictionary + "properties", new Dictionary { - { "type", "object" }, - { "description", "Album and its sales" }, { - "properties", new Dictionary + "album_name", new Dictionary + { + { "type", "string" }, + { "description", "Name of the music album" } + } + }, + { + "copies_sold", new Dictionary { - { - "album_name", new Dictionary - { - { "type", "string" }, - { "description", "Name of the music album" } - } - }, - { - "copies_sold", new Dictionary - { - { "type", "integer" }, - { "description", "Number of copies sold" } - } - } + { "type", "integer" }, + { "description", "Number of copies sold" } } } } @@ -86,6 +78,45 @@ public async Task GenerateContent( } }; + var responseJsonSchema = new Dictionary + { + { "type", "array" }, + { + "items", new Dictionary + { + { "type", "object" }, + { + "properties", new Dictionary + { + { + "album_name", new Dictionary + { + { "type", "string" } + } + }, + { + "copies_sold", new Dictionary + { + { "type", "integer" } + } + } + } + } + } + } + }; + + List getAlbumSales = new List + { + new FunctionDeclaration + { + Name = "get_album_sales", + Description = "Gets the number of albums sold", + ParametersJsonSchema = parametersJsonSchema, + ResponseJsonSchema = responseJsonSchema + } + }; + string contents = "At Stellar Sounds, a music label, 2024 was a rollercoaster." + " \"Echoes of the Night,\" a debut synth-pop album, surprisingly sold 350,000 copies," + " while veteran rock band \"Crimson Tide\\'s\" latest, \"Reckless Hearts,\" lagged at 120,000." +