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..3d68f444b22 --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsCodeExecWithTxt.cs @@ -0,0 +1,99 @@ +/* + * 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() } }, + // 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 + }); + + 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..d6c07b60bd2 --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsFuncDescWithTxt.cs @@ -0,0 +1,157 @@ +/* + * 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" }); + + var parametersJsonSchema = new Dictionary + { + { "type", "object" }, + { + "properties", new Dictionary + { + { + "albums", new Dictionary + { + { "type", "array" }, + { "description", "List of albums" }, + { + "items", 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 + { + { "type", "integer" }, + { "description", "Number of copies sold" } + } + } + } + } + } + } + } + } + } + } + }; + + 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." + + " 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}, + // {"album_name": "Whispers of Dawn", "copies_sold": 75000}, + // {"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..9ddb624749a --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsGoogleSearchWithTxt.cs @@ -0,0 +1,56 @@ +/* + * 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 + { + 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..f95db4bdfe4 --- /dev/null +++ b/genai/api/GenAI.Samples/Tools/ToolsUrlContextWithTxt.cs @@ -0,0 +1,65 @@ +/* + * 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 + { + 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]