diff --git a/sdk/openai/Azure.AI.OpenAI/tests/Azure.AI.OpenAI.Tests.csproj b/sdk/openai/Azure.AI.OpenAI/tests/Azure.AI.OpenAI.Tests.csproj index 6dbf8cd62f87..87752b6df9ae 100644 --- a/sdk/openai/Azure.AI.OpenAI/tests/Azure.AI.OpenAI.Tests.csproj +++ b/sdk/openai/Azure.AI.OpenAI/tests/Azure.AI.OpenAI.Tests.csproj @@ -81,4 +81,11 @@ + + + Always + Resources/batman.wav + + + diff --git a/sdk/openai/Azure.AI.OpenAI/tests/ResponsesTests.cs b/sdk/openai/Azure.AI.OpenAI/tests/ResponsesTests.cs index db5a0bb29ee9..1dadddb7648a 100644 --- a/sdk/openai/Azure.AI.OpenAI/tests/ResponsesTests.cs +++ b/sdk/openai/Azure.AI.OpenAI/tests/ResponsesTests.cs @@ -90,6 +90,37 @@ public async Task FileSearch(string deploymentName) } } + [TestCase(Gpt4oMiniDeployment)] + public async Task ResponseImageInput(string deploymentName) + { + OpenAIClient topLevelClient = GetTestTopLevelClient(DefaultResponsesConfig); + OpenAIFileClient fileClient = topLevelClient.GetOpenAIFileClient(); + VectorStoreClient vectorStoreClient = topLevelClient.GetVectorStoreClient(); + OpenAIResponseClient client = topLevelClient.GetOpenAIResponseClient(deploymentName); + + Uri imageUri = new("https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Microsoft_logo.svg/512px-Microsoft_logo.svg.png"); + ResponseContentPart imagePart = ResponseContentPart.CreateInputImagePart(imageUri); + ResponseContentPart textPart = ResponseContentPart.CreateInputTextPart("Describe this image"); + + List contentParts = [imagePart, textPart]; + + OpenAIResponse response = client.CreateResponse( + inputItems: + [ + ResponseItem.CreateSystemMessageItem("You are a helpful assistant that describes images"), + ResponseItem.CreateUserMessageItem(contentParts) + ]); + + Assert.That(response.OutputItems?.Count, Is.EqualTo(1)); + MessageResponseItem? message = response?.OutputItems?[0] as MessageResponseItem; + Assert.That(message, Is.Not.Null); + + await foreach (ResponseItem inputItem in client.GetResponseInputItemsAsync(response?.Id)) + { + Console.WriteLine(ModelReaderWriter.Write(inputItem).ToString()); + } + } + [RecordedTest] public async Task ComputerToolWithScreenshotRoundTrip() { @@ -953,4 +984,45 @@ private static void AssertSerializationRoundTrip( } """), false); + + [TestCase(Gpt4oMiniDeployment)] + public void ChatbotTellsJokes(string deploymentName) + { + OpenAIResponseClient client = GetResponseTestClientForDeployment(deploymentName); + + OpenAIResponse response = client.CreateResponse( + inputItems: [ + ResponseItem.CreateSystemMessageItem("You are a humorous assistant who tells jokes"), + ResponseItem.CreateUserMessageItem("Please tell me 3 jokes about trains") + ]); + + string output = ((MessageResponseItem)response.OutputItems[0]).Content[0].Text; + + Assert.That(output, Is.Not.Null.And.Not.Empty); + } + + [TestCase(Gpt4oMiniDeployment)] + public void ChatbotSummarizeTextTest(string deploymentName) + { + OpenAIResponseClient client = GetResponseTestClientForDeployment(deploymentName); + + OpenAIResponse response = client.CreateResponse( + inputItems: [ + ResponseItem.CreateSystemMessageItem("You are a helpful assistant that summarizes texts"), + ResponseItem.CreateAssistantMessageItem("Please summarize the following text in one sentence"), + ResponseItem.CreateUserMessageItem(GetSummarizationPromt()) + ]); + + string output = ((MessageResponseItem)response.OutputItems[0]).Content[0].Text; + Assert.That(output, Is.Not.Null.And.Not.Empty); + } + private static string GetSummarizationPromt() + { + String textToSummarize = "On July 20, 1969, Apollo 11 successfully landed the first humans on the Moon. " + + "Astronauts Neil Armstrong and Buzz Aldrin spent over two hours collecting samples and conducting experiments, " + + "while Michael Collins remained in orbit aboard the command module. " + + "The mission marked a significant achievement in space exploration, fulfilling President John F. Kennedy's goal of landing a man on the Moon and returning him safely to Earth. " + + "The lunar samples brought back provided invaluable insights into the Moon's composition and history."; + return "Summarize the following text.%n" + "Text:%n" + textToSummarize + "%n Summary:%n"; + } } diff --git a/sdk/openai/Azure.AI.OpenAI/tests/Samples/01_Chat.cs b/sdk/openai/Azure.AI.OpenAI/tests/Samples/01_Chat.cs index a6371324812b..b482ccbde246 100644 --- a/sdk/openai/Azure.AI.OpenAI/tests/Samples/01_Chat.cs +++ b/sdk/openai/Azure.AI.OpenAI/tests/Samples/01_Chat.cs @@ -12,6 +12,7 @@ using System.Diagnostics; using System.Text; using System.Text.Json; +using System.Threading.Tasks; namespace Azure.AI.OpenAI.Samples; @@ -40,6 +41,80 @@ public void BasicChat() #endregion } + public void ConversationChat() + { + #region Snippet:ConversationResponse + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + ChatClient chatClient = azureClient.GetChatClient("my-gpt-35-turbo-deployment"); + + var messages = new List + { + new UserChatMessage("Tell me a story about building the best SDK!") + }; + + for (int i = 0; i < 4; i++) + { + ChatCompletion completion = chatClient.CompleteChat(messages, new() + { + MaxOutputTokenCount = 2048 + }); + + Console.WriteLine($"\n--- Response {i + 1} ---\n"); + + foreach (var choice in completion.Content) + { + Console.WriteLine(choice.Text); + messages.Add(new AssistantChatMessage(choice.Text)); + } + + string exclamations = new('!', i); + string questions = new('?', i); + + messages.Add(new SystemChatMessage($"Be as snarky as possible when replying!{exclamations}")); + messages.Add(new UserChatMessage($"But why?{questions}")); + } + #endregion + } + + public async Task ConversationChatAsync() + { + #region Snippet:ConversationChatAsync + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + ChatClient chatClient = azureClient.GetChatClient("my-gpt-35-turbo-deployment"); + + var messages = new List + { + new UserChatMessage("Tell me a story about building the best SDK!") + }; + + for (int i = 0; i < 4; i++) + { + ChatCompletion completion = await chatClient.CompleteChatAsync(messages, new() + { + MaxOutputTokenCount = 2048 + }); + + Console.WriteLine($"\n--- Response {i + 1} ---\n"); + + foreach (var choice in completion.Content) + { + Console.WriteLine(choice.Text); + messages.Add(new AssistantChatMessage(choice.Text)); + } + + string exclamations = new('!', i); + string questions = new('?', i); + + messages.Add(new SystemChatMessage($"Be as snarky as possible when replying!{exclamations}")); + messages.Add(new UserChatMessage($"But why?{questions}")); + } + #endregion + } + public void StreamingChat() { #region Snippet:StreamChatMessages @@ -66,6 +141,96 @@ public void StreamingChat() #endregion } + public void StructuredOutputs() + { + #region Snippet:StructuredOutputs + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + ChatClient client = azureClient.GetChatClient("my-gpt-35-turbo-deployment"); + + IEnumerable messages = + [ + new UserChatMessage("What's heavier, a pound of feathers or sixteen ounces of steel?") + ]; + ChatCompletionOptions options = new ChatCompletionOptions() + { + ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat( + "test_schema", + BinaryData.FromString(""" + { + "type": "object", + "properties": { + "answer": { + "type": "string" + }, + "steps": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "answer", + "steps" + ], + "additionalProperties": false + } + """), + "a single final answer with a supporting collection of steps", + jsonSchemaIsStrict: true) + }; + ChatCompletion completion = client.CompleteChat(messages, options)!; + Console.WriteLine(completion!.Content![0].Text); + #endregion + } + + public async Task StructuredOutputsAsync() + { + #region Snippet:StructuredOutputsAsync + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + ChatClient client = azureClient.GetChatClient("my-gpt-35-turbo-deployment"); + + IEnumerable messages = + [ + new UserChatMessage("What's heavier, a pound of feathers or sixteen ounces of steel?") + ]; + ChatCompletionOptions options = new ChatCompletionOptions() + { + ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat( + "test_schema", + BinaryData.FromString(""" + { + "type": "object", + "properties": { + "answer": { + "type": "string" + }, + "steps": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "answer", + "steps" + ], + "additionalProperties": false + } + """), + "a single final answer with a supporting collection of steps", + jsonSchemaIsStrict: true) + }; + ChatCompletion completion = await client.CompleteChatAsync(messages, options)!; + Console.WriteLine(completion!.Content![0].Text); + #endregion + } + public void ChatWithTools() { #region Snippet:ChatTools:DefineTool diff --git a/sdk/openai/Azure.AI.OpenAI/tests/Samples/04_Responses.cs b/sdk/openai/Azure.AI.OpenAI/tests/Samples/04_Responses.cs new file mode 100644 index 000000000000..0e78a2f23154 --- /dev/null +++ b/sdk/openai/Azure.AI.OpenAI/tests/Samples/04_Responses.cs @@ -0,0 +1,165 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable disable + +using OpenAI.Responses; +using Azure.Identity; +using System.Collections.Generic; +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Threading.Tasks; + +namespace Azure.AI.OpenAI.Samples; + +public partial class AzureOpenAISamples +{ + public void ResponseImage() + { + #region Snippet:ResponseInputImage + + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + // Replace with your deployment name + OpenAIResponseClient client = azureClient.GetOpenAIResponseClient("my-gpt-35-turbo-deployment"); + + Uri imageUri = new("https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Microsoft_logo.svg/512px-Microsoft_logo.svg.png"); + ResponseContentPart imagePart = ResponseContentPart.CreateInputImagePart(imageUri); + ResponseContentPart textPart = ResponseContentPart.CreateInputTextPart("Describe this image"); + + List contentParts = [imagePart, textPart]; + + OpenAIResponse response = client.CreateResponse( + inputItems: + [ + ResponseItem.CreateSystemMessageItem("You are a helpful assistant that describes images"), + ResponseItem.CreateUserMessageItem(contentParts) + ]); + + Console.WriteLine($"{response.Id}: {((MessageResponseItem)response.OutputItems[0]).Content[0].Text}"); + + #endregion + + } + + public void ResponseChatbot() + { + #region Snippet:ResponseBasicChatbot + + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + // Replace with your deployment name + OpenAIResponseClient client = azureClient.GetOpenAIResponseClient("my-gpt-35-turbo-deployment"); + + OpenAIResponse response = client.CreateResponse( + inputItems: [ + ResponseItem.CreateSystemMessageItem("You are a humorous assistant who tells jokes"), + ResponseItem.CreateUserMessageItem("Please tell me 3 jokes about trains") + ]); + + Console.WriteLine($"{response.Id}: {((MessageResponseItem)response.OutputItems[0]).Content[0].Text}"); + + OpenAIResponse getResponse = client.GetResponse(response.Id); + Console.WriteLine($"Get response from id {response.Id}...: {((MessageResponseItem)response.OutputItems[0]).Content[0].Text}"); + + ResponseDeletionResult deleteResponse = client.DeleteResponse(response.Id); + Console.WriteLine($"Deleting response from id... \nResponse deleted: {deleteResponse.Deleted}"); + + try + { + OpenAIResponse getDeletedResponse = client.GetResponse(response.Id); + Console.WriteLine($"Response not deleted properly: {((MessageResponseItem)getDeletedResponse.OutputItems[0]).Content[0].Text}"); + } + catch (ClientResultException ex) + { + if (!ex.Message.Contains("404")) + { + throw; + } + Console.WriteLine($"Response was not found as expected: {ex.Message}"); + } + + #endregion + } + + public void ResponseSummarizeText() + { + #region Snippet:ResponseSummarizeText + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + OpenAIResponseClient client = azureClient.GetOpenAIResponseClient("my-gpt-35-turbo-deployment"); + + string summaryPrompt = GetSummarizationPromt(); + + OpenAIResponse response = client.CreateResponse( + inputItems: [ + ResponseItem.CreateSystemMessageItem("You are a helpful assistant that summarizes texts"), + ResponseItem.CreateAssistantMessageItem("Please summarize the following text in one sentence"), + ResponseItem.CreateUserMessageItem(summaryPrompt) + ] + ); + Console.WriteLine($"Get response from id {response.Id}...: {((MessageResponseItem)response.OutputItems[0]).Content[0].Text}"); + } + + private static string GetSummarizationPromt() + { + String textToSummarize = "On July 20, 1969, Apollo 11 successfully landed the first humans on the Moon. " + + "Astronauts Neil Armstrong and Buzz Aldrin spent over two hours collecting samples and conducting experiments, " + + "while Michael Collins remained in orbit aboard the command module. " + + "The mission marked a significant achievement in space exploration, fulfilling President John F. Kennedy's goal of landing a man on the Moon and returning him safely to Earth. " + + "The lunar samples brought back provided invaluable insights into the Moon's composition and history."; + return "Summarize the following text.%n" + "Text:%n" + textToSummarize + "%n Summary:%n"; + #endregion + } + + public void ResponseStreaming() + { + #region Snippet:ResponseStreaming + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + // Replace with your deployment name + OpenAIResponseClient client = azureClient.GetOpenAIResponseClient("my-gpt-35-turbo-deployment"); + + ResponseCreationOptions options = new(); + ResponseContentPart contentPart = ResponseContentPart.CreateInputTextPart("Tell me a 20-word story about building the best SDK!"); + ResponseItem inputItem = ResponseItem.CreateUserMessageItem([contentPart]); + + foreach (StreamingResponseUpdate update + in client.CreateResponseStreaming([inputItem], options)) + { + Console.WriteLine(ModelReaderWriter.Write(update)); + } + #endregion + } + + public async Task ResponseStreamingAsync() + { + #region Snippet:ResponseStreamingAsync + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + // Replace with your deployment name + OpenAIResponseClient client = azureClient.GetOpenAIResponseClient("my-gpt-35-turbo-deployment"); + + ResponseCreationOptions options = new(); + ResponseContentPart contentPart = ResponseContentPart.CreateInputTextPart("Tell me a 20-word story about building the best SDK!"); + ResponseItem inputItem = ResponseItem.CreateUserMessageItem([contentPart]); + + await foreach (StreamingResponseUpdate update + in client.CreateResponseStreamingAsync([inputItem], options)) + { + Console.WriteLine(ModelReaderWriter.Write(update)); + } + #endregion + } +} diff --git a/sdk/openai/Azure.AI.OpenAI/tests/Samples/05_Audio.cs b/sdk/openai/Azure.AI.OpenAI/tests/Samples/05_Audio.cs new file mode 100644 index 000000000000..3979bf13b320 --- /dev/null +++ b/sdk/openai/Azure.AI.OpenAI/tests/Samples/05_Audio.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Azure.Identity; +using OpenAI.Audio; + +namespace Azure.AI.OpenAI.Tests.Samples +{ + public partial class AzureOpenAISamples + { + public void TranscribeAudio() + { + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + AudioClient chatClient = azureClient.GetAudioClient("whisper"); + + string fileName = "batman.wav"; + string audioFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", fileName); + var transcriptionResult = chatClient.TranscribeAudio(audioFilePath); + Console.WriteLine(transcriptionResult.Value.Text.ToString()); + } + public async Task TranscribeAudioAsync() + { + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + AudioClient chatClient = azureClient.GetAudioClient("whisper"); + AudioTranscriptionOptions transcriptionOptions = new AudioTranscriptionOptions + { + Language = "en", // Specify the language if needed + ResponseFormat = AudioTranscriptionFormat.Simple, // Specify the response format + Temperature = 0.1f // Set temperature for transcription + }; + + string fileName = "batman.wav"; + string audioFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", fileName); + var transcriptionResult = await chatClient.TranscribeAudioAsync(audioFilePath, transcriptionOptions); + Console.WriteLine(transcriptionResult.Value.Text.ToString()); + } + } +} diff --git a/sdk/openai/Azure.AI.OpenAI/tests/Samples/06_Embeddings.cs b/sdk/openai/Azure.AI.OpenAI/tests/Samples/06_Embeddings.cs new file mode 100644 index 000000000000..f0abcc126802 --- /dev/null +++ b/sdk/openai/Azure.AI.OpenAI/tests/Samples/06_Embeddings.cs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable disable + +using System; +using System.ClientModel; +using System.Threading.Tasks; +using Azure.Identity; +using OpenAI.Embeddings; + +namespace Azure.AI.OpenAI.Samples; + +public partial class AzureOpenAISamples +{ + public void EmbeddingBasic() + { + #region Snippet:EmbeddingBasic + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + // Replace with your deployment name + EmbeddingClient client = azureClient.GetEmbeddingClient("my-gpt-35-turbo-deployment"); + + ClientResult embeddingResult = client.GenerateEmbedding("The quick brown fox jumped over the lazy dog"); + + if (embeddingResult?.Value != null) + { + float[] embedding = embeddingResult.Value.ToFloats().ToArray(); + + Console.WriteLine($"Embedding Length: {embedding.Length}"); + Console.WriteLine("Embedding Values:"); + foreach (float value in embedding) + { + Console.Write($"{value}, "); + } + } + else + { + Console.WriteLine("Failed to generate embedding or received null value."); + } + #endregion + } + + public async Task EmbeddingBasicAsync() + { + #region Snippet:EmbeddingBasicAsync + AzureOpenAIClient azureClient = new( + new Uri("https://your-azure-openai-resource.com"), + new DefaultAzureCredential()); + + // Replace with your deployment name + EmbeddingClient client = azureClient.GetEmbeddingClient("my-gpt-35-turbo-deployment"); + + ClientResult embeddingResult = await client.GenerateEmbeddingAsync("The quick brown fox jumped over the lazy dog"); + + if (embeddingResult?.Value != null) + { + float[] embedding = embeddingResult.Value.ToFloats().ToArray(); + + Console.WriteLine($"Embedding Length: {embedding.Length}"); + Console.WriteLine("Embedding Values:"); + foreach (float value in embedding) + { + Console.Write($"{value}, "); + } + } + else + { + Console.WriteLine("Failed to generate embedding or received null value."); + } + #endregion + } +} diff --git a/sdk/openai/Azure.AI.OpenAI/tests/Samples/Resources/batman.wav b/sdk/openai/Azure.AI.OpenAI/tests/Samples/Resources/batman.wav new file mode 100644 index 000000000000..4c0b7248a39c Binary files /dev/null and b/sdk/openai/Azure.AI.OpenAI/tests/Samples/Resources/batman.wav differ