// Copyright (c) Microsoft. All rights reserved. using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using Resources; namespace ChatCompletion; /// /// This sample shows how to use Google's Gemini Chat Completion model with vision using VertexAI and GoogleAI APIs. /// public sealed class Google_GeminiVision(ITestOutputHelper output) : BaseTest(output) { [Fact] public async Task GoogleAIChatCompletionWithVision() { Console.WriteLine("============= Google AI - Gemini Chat Completion with vision ============="); string geminiApiKey = TestConfiguration.GoogleAI.ApiKey; string geminiModelId = TestConfiguration.GoogleAI.Gemini.ModelId; if (geminiApiKey is null) { Console.WriteLine("Gemini credentials not found. Skipping example."); return; } Kernel kernel = Kernel.CreateBuilder() .AddGoogleAIGeminiChatCompletion( modelId: geminiModelId, apiKey: geminiApiKey) .Build(); var chatHistory = new ChatHistory("Your job is describing images."); var chatCompletionService = kernel.GetRequiredService(); // Load the image from the resources await using var stream = EmbeddedResource.ReadStream("sample_image.jpg")!; using var binaryReader = new BinaryReader(stream); var bytes = binaryReader.ReadBytes((int)stream.Length); chatHistory.AddUserMessage( [ new TextContent("What’s in this image?"), // Google AI Gemini API requires the image to be in base64 format, doesn't support URI // You have to always provide the mimeType for the image new ImageContent(bytes, "image/jpeg"), ]); var reply = await chatCompletionService.GetChatMessageContentAsync(chatHistory); Console.WriteLine(reply.Content); } [Fact] public async Task VertexAIChatCompletionWithVision() { Console.WriteLine("============= Vertex AI - Gemini Chat Completion with vision ============="); Assert.NotNull(TestConfiguration.VertexAI.BearerKey); Assert.NotNull(TestConfiguration.VertexAI.Location); Assert.NotNull(TestConfiguration.VertexAI.ProjectId); Assert.NotNull(TestConfiguration.VertexAI.Gemini.ModelId); Kernel kernel = Kernel.CreateBuilder() .AddVertexAIGeminiChatCompletion( modelId: TestConfiguration.VertexAI.Gemini.ModelId, bearerKey: TestConfiguration.VertexAI.BearerKey, location: TestConfiguration.VertexAI.Location, projectId: TestConfiguration.VertexAI.ProjectId) .Build(); // To generate bearer key, you need installed google sdk or use google web console with command: // // gcloud auth print-access-token // // Above code pass bearer key as string, it is not recommended way in production code, // especially if IChatCompletionService will be long lived, tokens generated by google sdk lives for 1 hour. // You should use bearer key provider, which will be used to generate token on demand: // // Example: // // Kernel kernel = Kernel.CreateBuilder() // .AddVertexAIGeminiChatCompletion( // modelId: TestConfiguration.VertexAI.Gemini.ModelId, // bearerKeyProvider: () => // { // // This is just example, in production we recommend using Google SDK to generate your BearerKey token. // // This delegate will be called on every request, // // when providing the token consider using caching strategy and refresh token logic when it is expired or close to expiration. // return GetBearerKey(); // }, // location: TestConfiguration.VertexAI.Location, // projectId: TestConfiguration.VertexAI.ProjectId); var chatHistory = new ChatHistory("Your job is describing images."); var chatCompletionService = kernel.GetRequiredService(); // Load the image from the resources await using var stream = EmbeddedResource.ReadStream("sample_image.jpg")!; using var binaryReader = new BinaryReader(stream); var bytes = binaryReader.ReadBytes((int)stream.Length); chatHistory.AddUserMessage( [ new TextContent("What’s in this image?"), // Vertex AI Gemini API supports both base64 and URI format // You have to always provide the mimeType for the image new ImageContent(bytes, "image/jpeg"), // The Cloud Storage URI of the image to include in the prompt. // The bucket that stores the file must be in the same Google Cloud project that's sending the request. // new ImageContent(new Uri("gs://generativeai-downloads/images/scones.jpg"), // metadata: new Dictionary { { "mimeType", "image/jpeg" } }) ]); var reply = await chatCompletionService.GetChatMessageContentAsync(chatHistory); Console.WriteLine(reply.Content); } }