diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cb8983895cfe..953efb46402d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -898,6 +898,12 @@ # ServiceLabel: %VideoAnalyzer # ServiceOwners: @giakas +# PRLabel: %VoiceLive +/sdk/ai/Azure.AI.VoiceLive/ @rhurey + +# ServiceLabel: %VoiceLive +# ServiceOwners: @rhurey + # ServiceLabel: %Web Apps # ServiceOwners: @AzureAppServiceCLI @antcp diff --git a/sdk/ai/Azure.AI.VoiceLive/Azure.AI.VoiceLive.sln b/sdk/ai/Azure.AI.VoiceLive/Azure.AI.VoiceLive.sln new file mode 100644 index 000000000000..852040ccbe22 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/Azure.AI.VoiceLive.sln @@ -0,0 +1,54 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36301.6 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.TestFramework", "..\..\core\Azure.Core.TestFramework\src\Azure.Core.TestFramework.csproj", "{ECC730C1-4AEA-420C-916A-66B19B79E4DC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.AI.VoiceLive", "src\Azure.AI.VoiceLive.csproj", "{28FF4005-4467-4E36-92E7-DEA27DEB1519}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.AI.VoiceLive.Tests", "tests\Azure.AI.VoiceLive.Tests.csproj", "{1F1CD1D4-9932-4B73-99D8-C252A67D4B46}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicVoiceAssistant", "samples\BasicVoiceAssistant\BasicVoiceAssistant.csproj", "{4F423188-2AE3-CB57-5BE2-808B33B8B5AB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomerServiceBot", "samples\CustomerServiceBot\CustomerServiceBot.csproj", "{0821FA24-C459-5CC2-DB1B-2F755A9B3148}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.AI.VoiceLive.Snippets", "samples\snippets\Azure.AI.VoiceLive.Snippets.csproj", "{1694BF5F-7AE7-9D41-44E7-A50680B5CA40}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ECC730C1-4AEA-420C-916A-66B19B79E4DC}.Release|Any CPU.Build.0 = Release|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28FF4005-4467-4E36-92E7-DEA27DEB1519}.Release|Any CPU.Build.0 = Release|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F1CD1D4-9932-4B73-99D8-C252A67D4B46}.Release|Any CPU.Build.0 = Release|Any CPU + {4F423188-2AE3-CB57-5BE2-808B33B8B5AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F423188-2AE3-CB57-5BE2-808B33B8B5AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F423188-2AE3-CB57-5BE2-808B33B8B5AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F423188-2AE3-CB57-5BE2-808B33B8B5AB}.Release|Any CPU.Build.0 = Release|Any CPU + {0821FA24-C459-5CC2-DB1B-2F755A9B3148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0821FA24-C459-5CC2-DB1B-2F755A9B3148}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0821FA24-C459-5CC2-DB1B-2F755A9B3148}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0821FA24-C459-5CC2-DB1B-2F755A9B3148}.Release|Any CPU.Build.0 = Release|Any CPU + {1694BF5F-7AE7-9D41-44E7-A50680B5CA40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1694BF5F-7AE7-9D41-44E7-A50680B5CA40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1694BF5F-7AE7-9D41-44E7-A50680B5CA40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1694BF5F-7AE7-9D41-44E7-A50680B5CA40}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A97F4B90-2591-4689-B1F8-5F21FE6D6CAE} + EndGlobalSection +EndGlobal diff --git a/sdk/ai/Azure.AI.VoiceLive/CHANGELOG.md b/sdk/ai/Azure.AI.VoiceLive/CHANGELOG.md new file mode 100644 index 000000000000..d309e9bab1b7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/CHANGELOG.md @@ -0,0 +1,12 @@ +# Release History + +## 1.0.0-beta.1 (Unreleased) + +### Features Added +Initial Addition of VoiceLiveClient and associated classes. + +### Breaking Changes + +### Bugs Fixed + +### Other Changes \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/Directory.Build.props b/sdk/ai/Azure.AI.VoiceLive/Directory.Build.props new file mode 100644 index 000000000000..a4e7b88bc67a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/Directory.Build.props @@ -0,0 +1,11 @@ + + + + true + true + + + + diff --git a/sdk/ai/Azure.AI.VoiceLive/README.md b/sdk/ai/Azure.AI.VoiceLive/README.md new file mode 100644 index 000000000000..dd64655a984c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/README.md @@ -0,0 +1,318 @@ +# Azure VoiceLive client library for .NET + +Azure VoiceLive is a managed service that enables low-latency, high-quality speech-to-speech interactions for voice agents. The API consolidates speech recognition, generative AI, and text-to-speech functionalities into a single, unified interface, providing an end-to-end solution for creating seamless voice-driven experiences. + +Use the client library to: + +* Create real-time voice assistants and conversational agents +* Build speech-to-speech applications with minimal latency +* Integrate advanced conversational features like noise suppression and echo cancellation +* Leverage multiple AI models (GPT-4o, GPT-4o-mini, Phi) for different use cases +* Implement function calling and tool integration for dynamic responses +* Create avatar-enabled voice interactions with visual components + +[Source code][source_root] | [Package (NuGet)][package] | [API reference documentation][reference_docs] | [Product documentation][voicelive_docs] | [Samples][source_samples] + +## Getting started + +This section includes everything a developer needs to install the package and create their first VoiceLive client connection. + +### Install the package + +Install the client library for .NET with [NuGet](https://www.nuget.org/): + +```dotnetcli +dotnet add package Azure.AI.VoiceLive --prerelease +``` + +### Prerequisites + +You must have an [Azure subscription](https://azure.microsoft.com/free/dotnet/) and an [Azure AI Foundry resource](https://docs.microsoft.com/azure/ai-services/openai/how-to/create-resource) to use this service. + +The client library targets .NET Standard 2.0 and .NET 8.0, providing compatibility with a wide range of .NET implementations. To use the async streaming features demonstrated in the examples, you'll need .NET 6.0 or later. + +### Authenticate the client + +The Azure.AI.VoiceLive client supports two authentication methods: + +1. **Microsoft Entra ID (recommended)**: Use token-based authentication +2. **API Key**: Use your resource's API key + +#### Authentication with Microsoft Entra ID + +```C# Snippet:CreateVoiceLiveClientWithTokenCredential +Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); +DefaultAzureCredential credential = new DefaultAzureCredential(); +VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); +``` + +#### Authentication with API Key + +```C# Snippet:CreateVoiceLiveClientWithApiKey +Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); +AzureKeyCredential credential = new AzureKeyCredential("your-api-key"); +VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); +``` + +For the recommended keyless authentication with Microsoft Entra ID, you need to: + +1. Assign the `Cognitive Services User` role to your user account or managed identity in the Azure portal under Access control (IAM) > Add role assignment +2. Use a `TokenCredential` implementation - the SDK automatically handles token acquisition and refresh with the appropriate scope + +### Service API versions + +The client library targets the latest service API version by default. You can optionally specify the API version when creating a client instance. + +#### Select a service API version + +You have the flexibility to explicitly select a supported service API version when instantiating a client by configuring its associated options: + +```C# Snippet:CreateVoiceLiveClientForSpecificApiVersion +Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); +DefaultAzureCredential credential = new DefaultAzureCredential(); +VoiceLiveClientOptions options = new VoiceLiveClientOptions(VoiceLiveClientOptions.ServiceVersion.V2025_05_01_Preview); +VoiceLiveClient client = new VoiceLiveClient(endpoint, credential, options); +``` + +## Key concepts + +The Azure.AI.VoiceLive client library provides several key classes for real-time voice interactions: + +### VoiceLiveClient + +The primary entry point for the Azure.AI.VoiceLive service. Use this client to establish sessions and configure authentication. + +### VoiceLiveSession + +Represents an active WebSocket connection to the VoiceLive service. This class handles bidirectional communication, allowing you to send audio input and receive audio output, text transcriptions, and other events in real-time. + +### Session Configuration + +The service uses session configuration to control various aspects of the voice interaction: + +- **Turn Detection**: Configure how the service detects when users start and stop speaking +- **Audio Processing**: Enable noise suppression and echo cancellation +- **Voice Selection**: Choose from standard Azure voices, high-definition voices, or custom voices +- **Model Selection**: Select the AI model (GPT-4o, GPT-4o-mini, Phi variants) that best fits your needs + +### Models and Capabilities + +The VoiceLive API supports multiple AI models with different capabilities: + +| Model | Description | Use Case | +|-------|-------------|----------| +| `gpt-4o-realtime-preview` | GPT-4o with real-time audio processing | High-quality conversational AI | +| `gpt-4o-mini-realtime-preview` | Lightweight GPT-4o variant | Fast, efficient interactions | +| `phi4-mm-realtime` | Phi model with multimodal support | Cost-effective voice applications | + +### Conversational Enhancements + +The VoiceLive API provides Azure-specific enhancements: + +- **Azure Semantic VAD**: Advanced voice activity detection that removes filler words +- **Noise Suppression**: Reduces environmental background noise +- **Echo Cancellation**: Removes echo from the model's own voice +- **End-of-Turn Detection**: Allows natural pauses without premature interruption + +### Thread safety + +We guarantee that all client instance methods are thread-safe and independent of each other ([guideline](https://azure.github.io/azure-sdk/dotnet_introduction.html#dotnet-service-methods-thread-safety)). This ensures that the recommendation of reusing client instances is always safe, even across threads. + +### Additional concepts + +[Client options](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#configuring-service-clients-using-clientoptions) | +[Accessing the response](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#accessing-http-response-details-using-responset) | +[Long-running operations](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#consuming-long-running-operations-using-operationt) | +[Handling failures](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#reporting-errors-requestfailedexception) | +[Diagnostics](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/samples/Diagnostics.md) | +[Mocking](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#mocking) | +[Client lifetime](https://devblogs.microsoft.com/azure-sdk/lifetime-management-and-thread-safety-guarantees-of-azure-sdk-net-clients/) + + +## Examples + +You can familiarize yourself with different APIs using [Samples](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.VoiceLive/samples). + +### Basic voice assistant + +```C# Snippet:BasicVoiceAssistantExample +// Create the VoiceLive client +Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); +DefaultAzureCredential credential = new DefaultAzureCredential(); +VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); + +// Start a new session +VoiceLiveSession session = await client.StartSessionAsync().ConfigureAwait(false); + +// Configure session for voice conversation +SessionOptions sessionOptions = new SessionOptions() +{ + Model = "gpt-4o-mini-realtime-preview", + Instructions = "You are a helpful AI assistant. Respond naturally and conversationally.", + Voice = new AzureStandardVoice("en-US-AvaNeural", AzureStandardVoiceType.AzureStandard), + TurnDetection = new ServerVad() + { + Threshold = 0.5f, + PrefixPaddingMs = 300, + SilenceDurationMs = 500 + }, + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16 +}; + +// Ensure modalities include audio +sessionOptions.Modalities.Clear(); +sessionOptions.Modalities.Add(InputModality.Text); +sessionOptions.Modalities.Add(InputModality.Audio); + +await session.ConfigureConversationSessionAsync(sessionOptions).ConfigureAwait(false); + +// Process events from the session +await foreach (ServerEvent serverEvent in session.GetUpdatesAsync().ConfigureAwait(false)) +{ + if (serverEvent is ServerEventResponseAudioDelta audioDelta) + { + // Play audio response + byte[] audioData = audioDelta.Delta.ToArray(); + // ... audio playback logic + } + else if (serverEvent is ServerEventResponseTextDelta textDelta) + { + // Display text response + Console.Write(textDelta.Delta); + } +} +``` + +### Configuring custom voice and advanced features + +```C# Snippet:AdvancedVoiceConfiguration +SessionOptions sessionOptions = new SessionOptions() +{ + Model = "gpt-4o-realtime-preview", + Instructions = "You are a customer service representative. Be helpful and professional.", + Voice = new AzureCustomVoice("your-custom-voice-name", "your-custom-voice-endpoint-id", AzureCustomVoiceType.AzureCustom) + { + Temperature = 0.8f + }, + TurnDetection = new AzureSemanticVad() + { + NegThreshold = 0.3f, + WindowSize = 300, + RemoveFillerWords = true + }, + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16 +}; + +// Ensure modalities include audio +sessionOptions.Modalities.Clear(); +sessionOptions.Modalities.Add(InputModality.Text); +sessionOptions.Modalities.Add(InputModality.Audio); + +await session.ConfigureConversationSessionAsync(sessionOptions).ConfigureAwait(false); +``` + +### Function calling example + +```C# Snippet:FunctionCallingExample +// Define a function for the assistant to call +var getCurrentWeatherFunction = new FunctionTool("get_current_weather") +{ + Description = "Get the current weather for a given location", + Parameters = BinaryData.FromString(""" + { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state or country" + } + }, + "required": ["location"] + } + """) +}; + +SessionOptions sessionOptions = new SessionOptions() +{ + Model = "gpt-4o-mini-realtime-preview", + Instructions = "You are a weather assistant. Use the get_current_weather function to help users with weather information.", + Voice = new AzureStandardVoice("en-US-AvaNeural", AzureStandardVoiceType.AzureStandard), + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16 +}; + +// Add the function tool +sessionOptions.Tools.Add(getCurrentWeatherFunction); + +// Ensure modalities include audio +sessionOptions.Modalities.Clear(); +sessionOptions.Modalities.Add(InputModality.Text); +sessionOptions.Modalities.Add(InputModality.Audio); + +await session.ConfigureConversationSessionAsync(sessionOptions).ConfigureAwait(false); +``` + +## Troubleshooting + +### Common errors and exceptions + +**Authentication Errors**: If you receive authentication errors, verify that: +- Your Azure AI Foundry resource is correctly configured +- Your API key or credential has the necessary permissions +- The endpoint URL is correct and accessible + +**WebSocket Connection Issues**: VoiceLive uses WebSocket connections. Ensure that: +- Your network allows WebSocket connections +- Firewall rules permit connections to `*.cognitiveservices.azure.com` +- The service is available in your selected region + +**Audio Processing Errors**: For audio-related issues: +- Verify audio input format is supported (16kHz or 24kHz PCM) +- Check that audio devices are accessible and functioning +- Ensure proper audio codec configuration + +### Logging and diagnostics + +Enable logging to help diagnose issues: + +```csharp +using Azure.Core.Diagnostics; + +// Enable logging for Azure SDK +using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger(); +``` + +### Rate limiting and throttling + +The VoiceLive service implements rate limiting based on: +- Concurrent connections per resource +- Token consumption rates +- Model-specific limits + +Implement appropriate retry logic and connection management to handle throttling gracefully. + +## Next steps + +* Explore the comprehensive [samples](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.VoiceLive/samples) including basic voice assistants and customer service bots +* Learn about [voice customization](https://learn.microsoft.com/azure/ai-services/speech-service/custom-neural-voice) to create unique brand voices +* Understand [avatar integration](https://learn.microsoft.com/azure/ai-services/speech-service/text-to-speech-avatar/what-is-text-to-speech-avatar) for visual voice experiences +* Review the [VoiceLive API documentation](https://docs.microsoft.com/azure/ai-services/) for advanced configuration options + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. + +When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + + +[source_root]: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.VoiceLive/src +[source_samples]: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.VoiceLive/samples +[package]: https://www.nuget.org/ +[reference_docs]: https://azure.github.io/azure-sdk-for-net/ +[voicelive_docs]: https://docs.microsoft.com/azure/ai-services/ +[style-guide-msft]: https://docs.microsoft.com/style-guide/capitalization +[style-guide-cloud]: https://aka.ms/azsdk/cloud-style-guide diff --git a/sdk/ai/Azure.AI.VoiceLive/cspell.json b/sdk/ai/Azure.AI.VoiceLive/cspell.json new file mode 100644 index 000000000000..61c03bda4518 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/cspell.json @@ -0,0 +1,6 @@ +{ + // Version of the setting file. Always 0.2 + "version": "0.2", + // words - list of words to be always considered correct + "words": ["Viseme", "logprobs", "Alaw", "Ulaw"] +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/.gitignore b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/.gitignore new file mode 100644 index 000000000000..09ee35a7a9c2 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/.gitignore @@ -0,0 +1,323 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +*.userprefs +launchsettings.json + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio 2015/2017/2019/2022 cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these files may be visible. +*.azurePubxml + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment the next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +CrystalReportsBackup*/ + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# Sensitive configuration +appsettings.Development.json +appsettings.Production.json \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/AudioProcessor.cs b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/AudioProcessor.cs new file mode 100644 index 000000000000..5d6713b1e484 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/AudioProcessor.cs @@ -0,0 +1,386 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Channels; +using NAudio.Wave; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive.Samples; + +/// +/// Handles real-time audio capture and playback for the voice assistant. +/// +/// This processor demonstrates some of the new VoiceLive SDK convenience methods: +/// - Uses existing SendInputAudioAsync() method for audio streaming +/// - Shows how convenience methods simplify audio operations +/// +/// Additional convenience methods available in the SDK: +/// - StartAudioTurnAsync() / AppendAudioToTurnAsync() / EndAudioTurnAsync() - Audio turn management +/// - ClearStreamingAudioAsync() - Clear all streaming audio +/// - ConnectAvatarAsync() - Avatar connection with SDP +/// +/// Threading Architecture: +/// - Main thread: Event loop and UI +/// - Capture thread: NAudio input stream reading +/// - Send thread: Async audio data transmission to VoiceLive +/// - Playback thread: NAudio output stream writing +/// +public class AudioProcessor : IDisposable +{ + private readonly VoiceLiveSession _session; + private readonly ILogger _logger; + + // Audio configuration - PCM16, 24kHz, mono as specified + private const int SampleRate = 24000; + private const int Channels = 1; + private const int BitsPerSample = 16; + + // NAudio components + private WaveInEvent? _waveIn; + private WaveOutEvent? _waveOut; + private BufferedWaveProvider? _playbackBuffer; + + // Audio capture and playback state + private bool _isCapturing; + private bool _isPlaying; + + // Audio streaming channels + private readonly Channel _audioSendChannel; + private readonly Channel _audioPlaybackChannel; + private readonly ChannelWriter _audioSendWriter; + private readonly ChannelReader _audioSendReader; + private readonly ChannelWriter _audioPlaybackWriter; + private readonly ChannelReader _audioPlaybackReader; + + // Background tasks + private Task? _audioSendTask; + private Task? _audioPlaybackTask; + private readonly CancellationTokenSource _cancellationTokenSource; + private CancellationTokenSource _playbackCancellationTokenSource; + + /// + /// Initializes a new instance of the AudioProcessor class. + /// + /// The VoiceLive session for audio communication. + /// Logger for diagnostic information. + public AudioProcessor(VoiceLiveSession session, ILogger logger) + { + _session = session ?? throw new ArgumentNullException(nameof(session)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + // Create unbounded channels for audio data + _audioSendChannel = Channel.CreateUnbounded(); + _audioSendWriter = _audioSendChannel.Writer; + _audioSendReader = _audioSendChannel.Reader; + + _audioPlaybackChannel = Channel.CreateUnbounded(); + _audioPlaybackWriter = _audioPlaybackChannel.Writer; + _audioPlaybackReader = _audioPlaybackChannel.Reader; + + _cancellationTokenSource = new CancellationTokenSource(); + _playbackCancellationTokenSource = new CancellationTokenSource(); + + _logger.LogInformation("AudioProcessor initialized with {SampleRate}Hz PCM16 mono audio", SampleRate); + } + + /// + /// Start capturing audio from microphone. + /// + public Task StartCaptureAsync() + { + if (_isCapturing) + return Task.CompletedTask; + + _isCapturing = true; + + try + { + _waveIn = new WaveInEvent + { + WaveFormat = new WaveFormat(SampleRate, BitsPerSample, Channels), + BufferMilliseconds = 50 // 50ms buffer for low latency + }; + + _waveIn.DataAvailable += OnAudioDataAvailable; + _waveIn.RecordingStopped += OnRecordingStopped; + + _waveIn.DeviceNumber = 0; + + _waveIn.StartRecording(); + + // Start audio send task + _audioSendTask = ProcessAudioSendAsync(_cancellationTokenSource.Token); + + _logger.LogInformation("Started audio capture"); + return Task.CompletedTask; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to start audio capture"); + _isCapturing = false; + throw; + } + } + + /// + /// Stop capturing audio. + /// + public async Task StopCaptureAsync() + { + if (!_isCapturing) + return; + + _isCapturing = false; + + if (_waveIn != null) + { + _waveIn.StopRecording(); + _waveIn.DataAvailable -= OnAudioDataAvailable; + _waveIn.RecordingStopped -= OnRecordingStopped; + _waveIn.Dispose(); + _waveIn = null; + } + + // Complete the send channel and wait for the send task + _audioSendWriter.TryComplete(); + if (_audioSendTask != null) + { + await _audioSendTask.ConfigureAwait(false); + _audioSendTask = null; + } + + _logger.LogInformation("Stopped audio capture"); + } + + /// + /// Initialize audio playback system. + /// + public Task StartPlaybackAsync() + { + if (_isPlaying) + return Task.CompletedTask; + + _isPlaying = true; + + try + { + _waveOut = new WaveOutEvent + { + DesiredLatency = 100 // 100ms latency + }; + + _playbackBuffer = new BufferedWaveProvider(new WaveFormat(SampleRate, BitsPerSample, Channels)) + { + BufferDuration = TimeSpan.FromMinutes(5), // 5 second buffer + DiscardOnBufferOverflow = true + }; + + _waveOut.Init(_playbackBuffer); + _waveOut.Play(); + + _playbackCancellationTokenSource = new CancellationTokenSource(); + + // Start audio playback task + _audioPlaybackTask = ProcessAudioPlaybackAsync(); + + _logger.LogInformation("Audio playback system ready"); + return Task.CompletedTask; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to initialize audio playback"); + _isPlaying = false; + throw; + } + } + + /// + /// Stop audio playback and clear buffer. + /// + public async Task StopPlaybackAsync() + { + if (!_isPlaying) + return; + + _isPlaying = false; + + // Clear the playback channel + while (_audioPlaybackReader.TryRead(out _)) + { } + + if (_playbackBuffer != null) + { + _playbackBuffer.ClearBuffer(); + } + + if (_waveOut != null) + { + _waveOut.Stop(); + _waveOut.Dispose(); + _waveOut = null; + } + + _playbackBuffer = null; + + // Complete the playback channel and wait for the playback task + _playbackCancellationTokenSource.Cancel(); + + if (_audioPlaybackTask != null) + { + await _audioPlaybackTask.ConfigureAwait(false); + _audioPlaybackTask = null; + } + + _logger.LogInformation("Stopped audio playback"); + } + + /// + /// Queue audio data for playback. + /// + /// The audio data to queue. + public async Task QueueAudioAsync(byte[] audioData) + { + if (_isPlaying && audioData.Length > 0) + { + await _audioPlaybackWriter.WriteAsync(audioData).ConfigureAwait(false); + } + } + + /// + /// Event handler for audio data available from microphone. + /// + private void OnAudioDataAvailable(object? sender, WaveInEventArgs e) + { + if (_isCapturing && e.BytesRecorded > 0) + { + byte[] audioData = new byte[e.BytesRecorded]; + Array.Copy(e.Buffer, 0, audioData, 0, e.BytesRecorded); + + // Queue audio data for sending (non-blocking) + if (!_audioSendWriter.TryWrite(audioData)) + { + _logger.LogWarning("Failed to queue audio data for sending - channel may be full"); + } + } + } + + /// + /// Event handler for recording stopped. + /// + private void OnRecordingStopped(object? sender, StoppedEventArgs e) + { + if (e.Exception != null) + { + _logger.LogError(e.Exception, "Audio recording stopped due to error"); + } + } + + /// + /// Background task to process audio data and send to VoiceLive service. + /// + private async Task ProcessAudioSendAsync(CancellationToken cancellationToken) + { + try + { + await foreach (byte[] audioData in _audioSendReader.ReadAllAsync(cancellationToken).ConfigureAwait(false)) + { + if (cancellationToken.IsCancellationRequested) + break; + + try + { + // Send audio data directly to the session using the convenience method + // This demonstrates the existing SendInputAudioAsync convenience method + // Other available methods: StartAudioTurnAsync, AppendAudioToTurnAsync, EndAudioTurnAsync + await _session.SendInputAudioAsync(audioData, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error sending audio data to VoiceLive"); + // Continue processing other audio data + } + } + } + catch (OperationCanceledException) + { + // Expected when cancellation is requested + } + catch (Exception ex) + { + _logger.LogError(ex, "Error in audio send processing"); + } + } + + /// + /// Background task to process audio playback. + /// + private async Task ProcessAudioPlaybackAsync() + { + try + { + CancellationTokenSource combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_playbackCancellationTokenSource.Token, _cancellationTokenSource.Token); + var cancellationToken = combinedTokenSource.Token; + + await foreach (byte[] audioData in _audioPlaybackReader.ReadAllAsync(cancellationToken).ConfigureAwait(false)) + { + if (cancellationToken.IsCancellationRequested) + break; + + try + { + if (_playbackBuffer != null && _isPlaying) + { + _playbackBuffer.AddSamples(audioData, 0, audioData.Length); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error in audio playback"); + // Continue processing other audio data + } + } + } + catch (OperationCanceledException) + { + // Expected when cancellation is requested + } + catch (Exception ex) + { + _logger.LogError(ex, "Error in audio playback processing"); + } + } + + /// + /// Clean up audio resources. + /// + public async Task CleanupAsync() + { + await StopCaptureAsync().ConfigureAwait(false); + await StopPlaybackAsync().ConfigureAwait(false); + + _cancellationTokenSource.Cancel(); + + // Wait for background tasks to complete + var tasks = new List(); + if (_audioSendTask != null) + tasks.Add(_audioSendTask); + if (_audioPlaybackTask != null) + tasks.Add(_audioPlaybackTask); + + if (tasks.Count > 0) + { + await Task.WhenAll(tasks).ConfigureAwait(false); + } + + _logger.LogInformation("Audio processor cleaned up"); + } + + /// + /// Dispose of resources. + /// + public void Dispose() + { + CleanupAsync().Wait(); + _cancellationTokenSource.Dispose(); + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.cs b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.cs new file mode 100644 index 000000000000..4b55460f2061 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.cs @@ -0,0 +1,305 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.AI.VoiceLive; + +namespace Azure.AI.VoiceLive.Samples; + +/// +/// Basic voice assistant implementing the VoiceLive SDK patterns. +/// +/// +/// This sample now demonstrates some of the new convenience methods added to the VoiceLive SDK: +/// - ClearStreamingAudioAsync() - Clears all input audio currently being streamed +/// - CancelResponseAsync() - Cancels the current response generation (existing method) +/// - ConfigureConversationSessionAsync() - Configures session options (existing method) +/// +/// Additional convenience methods available but not shown in this sample: +/// - StartAudioTurnAsync() / EndAudioTurnAsync() / CancelAudioTurnAsync() - Audio turn management +/// - AppendAudioToTurnAsync() - Append audio data to an ongoing turn +/// - ConnectAvatarAsync() - Connect avatar with SDP for media negotiation +/// +/// These methods provide a more developer-friendly API similar to the OpenAI SDK, +/// eliminating the need to manually construct and populate ClientEvent classes. +/// +public class BasicVoiceAssistant : IDisposable +{ + private readonly VoiceLiveClient _client; + private readonly string _model; + private readonly string _voice; + private readonly string _instructions; + private readonly ILogger _logger; + private readonly ILoggerFactory _loggerFactory; + + private VoiceLiveSession? _session; + private AudioProcessor? _audioProcessor; + private bool _disposed; + + /// + /// Initializes a new instance of the BasicVoiceAssistant class. + /// + /// The VoiceLive client. + /// The model to use. + /// The voice to use. + /// The system instructions. + /// Logger factory for creating loggers. + public BasicVoiceAssistant( + VoiceLiveClient client, + string model, + string voice, + string instructions, + ILoggerFactory loggerFactory) + { + _client = client ?? throw new ArgumentNullException(nameof(client)); + _model = model ?? throw new ArgumentNullException(nameof(model)); + _voice = voice ?? throw new ArgumentNullException(nameof(voice)); + _instructions = instructions ?? throw new ArgumentNullException(nameof(instructions)); + _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + _logger = loggerFactory.CreateLogger(); + } + + /// + /// Start the voice assistant session. + /// + /// Cancellation token for stopping the session. + public async Task StartAsync(CancellationToken cancellationToken = default) + { + try + { + _logger.LogInformation("Connecting to VoiceLive API with model {Model}", _model); + + // Start VoiceLive session + _session = await _client.StartSessionAsync(_model, cancellationToken).ConfigureAwait(false); + + // Initialize audio processor + _audioProcessor = new AudioProcessor(_session, _loggerFactory.CreateLogger()); + + // Configure session for voice conversation + await SetupSessionAsync(cancellationToken).ConfigureAwait(false); + + // Start audio systems + await _audioProcessor.StartPlaybackAsync().ConfigureAwait(false); + await _audioProcessor.StartCaptureAsync().ConfigureAwait(false); + + _logger.LogInformation("Voice assistant ready! Start speaking..."); + Console.WriteLine(); + Console.WriteLine("=" + new string('=', 59)); + Console.WriteLine("🎤 VOICE ASSISTANT READY"); + Console.WriteLine("Start speaking to begin conversation"); + Console.WriteLine("Press Ctrl+C to exit"); + Console.WriteLine("=" + new string('=', 59)); + Console.WriteLine(); + + // Process events + await ProcessEventsAsync(cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + _logger.LogInformation("Received cancellation signal, shutting down..."); + } + catch (Exception ex) + { + _logger.LogError(ex, "Connection error"); + throw; + } + finally + { + // Cleanup + if (_audioProcessor != null) + { + await _audioProcessor.CleanupAsync().ConfigureAwait(false); + } + } + } + + /// + /// Configure the VoiceLive session for audio conversation. + /// + private async Task SetupSessionAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Setting up voice conversation session..."); + + // Azure voice + var azureVoice = new AzureStandardVoice(_voice, AzureStandardVoiceType.AzureStandard); + + // Create strongly typed turn detection configuration + var turnDetectionConfig = new ServerVad + { + Threshold = 0.5f, + PrefixPaddingMs = 300, + SilenceDurationMs = 500 + }; + + // Create conversation session options + var sessionOptions = new SessionOptions + { + EchoCancellation = new AudioEchoCancellation(), + Model = _model, + Instructions = _instructions, + Voice = azureVoice, + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16, + TurnDetection = turnDetectionConfig + }; + + // Ensure modalities include audio + sessionOptions.Modalities.Clear(); + sessionOptions.Modalities.Add(InputModality.Text); + sessionOptions.Modalities.Add(InputModality.Audio); + + await _session!.ConfigureConversationSessionAsync(sessionOptions, cancellationToken).ConfigureAwait(false); + + _logger.LogInformation("Session configuration sent"); + } + + /// + /// Process events from the VoiceLive session. + /// + private async Task ProcessEventsAsync(CancellationToken cancellationToken) + { + try + { + await foreach (ServerEvent serverEvent in _session!.GetUpdatesAsync(cancellationToken).ConfigureAwait(false)) + { + await HandleServerEventAsync(serverEvent, cancellationToken).ConfigureAwait(false); + } + } + catch (OperationCanceledException) + { + _logger.LogInformation("Event processing cancelled"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error processing events"); + throw; + } + } + + /// + /// Handle different types of server events from VoiceLive. + /// + private async Task HandleServerEventAsync(ServerEvent serverEvent, CancellationToken cancellationToken) + { + _logger.LogDebug("Received event: {EventType}", serverEvent.GetType().Name); + + switch (serverEvent) + { + case ServerEventSessionCreated sessionCreated: + await HandleSessionCreatedAsync(sessionCreated, cancellationToken).ConfigureAwait(false); + break; + + case ServerEventSessionUpdated sessionUpdated: + _logger.LogInformation("Session updated successfully"); + + // Start audio capture once session is ready + if (_audioProcessor != null) + { + await _audioProcessor.StartCaptureAsync().ConfigureAwait(false); + } + break; + + case ServerEventInputAudioBufferSpeechStarted speechStarted: + _logger.LogInformation("🎤 User started speaking - stopping playback"); + Console.WriteLine("🎤 Listening..."); + + // Stop current assistant audio playback (interruption handling) + if (_audioProcessor != null) + { + await _audioProcessor.StopPlaybackAsync().ConfigureAwait(false); + } + + // Cancel any ongoing response + try + { + await _session!.CancelResponseAsync(cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.LogDebug(ex, "No response to cancel"); + } + + // Demonstrate the new ClearStreamingAudio convenience method + try + { + await _session!.ClearStreamingAudioAsync(cancellationToken).ConfigureAwait(false); + _logger.LogInformation("✨ Used ClearStreamingAudioAsync convenience method"); + } + catch (Exception ex) + { + _logger.LogDebug(ex, "ClearStreamingAudio call failed (may not be supported in all scenarios)"); + } + break; + + case ServerEventInputAudioBufferSpeechStopped speechStopped: + _logger.LogInformation("🎤 User stopped speaking"); + Console.WriteLine("🤔 Processing..."); + + // Restart playback system for response + if (_audioProcessor != null) + { + await _audioProcessor.StartPlaybackAsync().ConfigureAwait(false); + } + break; + + case ServerEventResponseCreated responseCreated: + _logger.LogInformation("🤖 Assistant response created"); + break; + + case ServerEventResponseAudioDelta audioDelta: + // Stream audio response to speakers + _logger.LogDebug("Received audio delta"); + + if (audioDelta.Delta != null && _audioProcessor != null) + { + byte[] audioData = audioDelta.Delta.ToArray(); + await _audioProcessor.QueueAudioAsync(audioData).ConfigureAwait(false); + } + break; + + case ServerEventResponseAudioDone audioDone: + _logger.LogInformation("🤖 Assistant finished speaking"); + Console.WriteLine("🎤 Ready for next input..."); + break; + + case ServerEventResponseDone responseDone: + _logger.LogInformation("✅ Response complete"); + break; + + case ServerEventError errorEvent: + _logger.LogError("❌ VoiceLive error: {ErrorMessage}", errorEvent.Error?.Message); + Console.WriteLine($"Error: {errorEvent.Error?.Message}"); + break; + + default: + _logger.LogDebug("Unhandled event type: {EventType}", serverEvent.GetType().Name); + break; + } + } + + /// + /// Handle session created event. + /// + private async Task HandleSessionCreatedAsync(ServerEventSessionCreated sessionCreated, CancellationToken cancellationToken) + { + _logger.LogInformation("Session ready: {SessionId}", sessionCreated.Session?.Id); + + // Start audio capture once session is ready + if (_audioProcessor != null) + { + await _audioProcessor.StartCaptureAsync().ConfigureAwait(false); + } + } + + /// + /// Dispose of resources. + /// + public void Dispose() + { + if (_disposed) + return; + + _audioProcessor?.Dispose(); + _session?.Dispose(); + _disposed = true; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.csproj b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.csproj new file mode 100644 index 000000000000..b4fcec9b4aec --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.csproj @@ -0,0 +1,43 @@ + + + + Exe + net8.0 + enable + enable + BasicVoiceAssistant + Azure.AI.VoiceLive.Samples + true + false + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.sln b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.sln new file mode 100644 index 000000000000..4ceacdfde460 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/BasicVoiceAssistant.sln @@ -0,0 +1,18 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicVoiceAssistant", "BasicVoiceAssistant.csproj", "{A1B2C3D4-E5F6-7890-1234-567890ABCDEF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1B2C3D4-E5F6-7890-1234-567890ABCDEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1B2C3D4-E5F6-7890-1234-567890ABCDEF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1B2C3D4-E5F6-7890-1234-567890ABCDEF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1B2C3D4-E5F6-7890-1234-567890ABCDEF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/GlobalUsings.cs b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/GlobalUsings.cs new file mode 100644 index 000000000000..2487c6297d6c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/GlobalUsings.cs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +global using System; +global using System.Threading; +global using System.Threading.Tasks; +global using Azure.AI.VoiceLive; +global using Microsoft.Extensions.Logging; \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/README.md b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/README.md new file mode 100644 index 000000000000..dcdef5f6a866 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/README.md @@ -0,0 +1,248 @@ +# Basic Voice Assistant Sample + +This sample demonstrates the fundamental capabilities of the Azure VoiceLive SDK by creating a basic voice assistant that can engage in natural conversation with proper interruption handling. This serves as the foundational example that showcases the core value proposition of unified speech-to-speech interaction. + +## New VoiceLive SDK Convenience Methods + +This sample now demonstrates some of the new convenience methods added to the VoiceLive SDK for better developer experience: + +**Used in this sample:** +- `ClearStreamingAudioAsync()` - Clears all input audio currently being streamed +- `ConfigureConversationSessionAsync()` - Configures conversation session options +- `CancelResponseAsync()` - Cancels the current response generation +- `SendInputAudioAsync()` - Sends audio data to the service + +**Additional convenience methods available:** +- `StartAudioTurnAsync()` / `EndAudioTurnAsync()` / `CancelAudioTurnAsync()` - Audio turn management +- `AppendAudioToTurnAsync()` - Append audio data to an ongoing turn +- `ConnectAvatarAsync()` - Connect avatar with SDP for media negotiation +- `CommitInputAudioAsync()` / `ClearInputAudioAsync()` - Audio buffer operations + +These methods eliminate the need to manually construct and populate `ClientEvent` classes, providing a more developer-friendly API similar to the OpenAI SDK. + +## Features + +- **Real-time voice conversation**: Seamless bidirectional audio streaming +- **Interruption handling**: Graceful handling of user interruptions during assistant responses +- **Multiple voice options**: Support for both OpenAI and Azure voices +- **Cross-platform audio**: Uses NAudio for reliable audio capture and playback +- **Robust error handling**: Automatic reconnection and error recovery +- **Configurable settings**: Command line options and configuration file support + +## Prerequisites + +- .NET 8.0 or later +- Azure VoiceLive API key or Azure credential +- Microphone and speakers/headphones +- Audio drivers properly installed + +## Setup + +1. **Install dependencies**: + ```bash + dotnet restore + ``` + +2. **Configure credentials**: + + Option 1: Environment variables + ```bash + export AZURE_VOICELIVE_API_KEY="your-api-key" + export AZURE_VOICELIVE_ENDPOINT="wss://api.voicelive.com/v1" + ``` + + Option 2: Update `appsettings.json` + ```json + { + "VoiceLive": { + "ApiKey": "your-api-key", + "Endpoint": "wss://api.voicelive.com/v1", + "Model": "gpt-4o-realtime-preview", + "Voice": "en-US-AvaNeural", + "Instructions": "You are a helpful AI assistant. Respond naturally and conversationally." + } + } + ``` + +3. **Test audio system**: + ```bash + dotnet run -- --verbose + ``` + +## Usage + +### Basic Usage +```bash +dotnet run +``` + +### Command Line Options +```bash +dotnet run -- --help +``` + +Available options: +- `--api-key `: Azure VoiceLive API key +- `--endpoint `: VoiceLive service endpoint +- `--model `: Model to use (default: gpt-4o-realtime-preview) +- `--voice `: Voice for the assistant (default: en-US-AvaNeural) +- `--instructions `: System instructions for the AI +- `--use-token-credential`: Use Azure authentication instead of API key +- `--verbose`: Enable detailed logging + +### Example Commands + +**Using a different voice**: +```bash +dotnet run -- --voice "en-US-JennyNeural" +``` + +**Using OpenAI voice**: +```bash +dotnet run -- --voice "alloy" +``` + +**Custom instructions**: +```bash +dotnet run -- --instructions "You are a helpful coding assistant. Focus on programming questions and provide code examples." +``` + +**Azure authentication**: +```bash +dotnet run -- --use-token-credential +``` + +## Supported Voices + +### OpenAI Voices +- `alloy` +- `echo` +- `fable` +- `onyx` +- `nova` +- `shimmer` + +### Azure Voices +- `en-US-AvaNeural` +- `en-US-JennyNeural` +- `en-US-GuyNeural` + +## How It Works + +### Architecture +The sample uses a multi-threaded architecture for optimal performance: + +1. **Main Thread**: UI and event processing +2. **Audio Capture**: NAudio input stream processing +3. **Audio Send**: Async transmission to VoiceLive service +4. **Audio Playback**: NAudio output stream processing + +### Key Components + +#### VoiceLiveClient +- Manages authentication and connection to the service +- Provides WebSocket-based real-time communication + +#### VoiceLiveSession +- Handles bidirectional message streaming +- Manages session lifecycle and configuration + +#### AudioProcessor +- Captures audio from microphone (24kHz PCM16 mono) +- Streams audio to VoiceLive service in real-time +- Plays back assistant responses through speakers +- Handles interruption scenarios + +#### BasicVoiceAssistant +- Orchestrates the entire conversation flow +- Handles VoiceLive events and updates +- Manages session configuration and voice settings + +### Event Flow + +1. **Session Setup**: Configure audio format, voice, and turn detection +2. **Audio Capture**: Start capturing microphone input +3. **Speech Detection**: Service detects when user starts/stops speaking +4. **Response Generation**: AI generates audio response +5. **Audio Playback**: Stream response audio to speakers +6. **Interruption Handling**: Stop playback when user interrupts + +## Troubleshooting + +### Audio Issues + +**No microphone detected**: +- Ensure microphone is connected and recognized by Windows +- Check audio permissions for the application +- Try running with `--verbose` to see detailed audio device information + +**No sound output**: +- Check speaker/headphone connections +- Verify volume levels +- Ensure no other applications are exclusively using audio devices + +**Poor audio quality**: +- Check microphone positioning and levels +- Reduce background noise +- Ensure stable internet connection for real-time streaming + +### Connection Issues + +**Authentication failed**: +- Verify API key is correct and active +- Check endpoint URL format +- Try using `--use-token-credential` for Azure authentication + +**Connection timeouts**: +- Check internet connectivity +- Verify firewall allows WebSocket connections +- Try different endpoint if available + +### Performance Issues + +**High latency**: +- Close other bandwidth-intensive applications +- Use wired internet connection instead of WiFi +- Reduce audio buffer sizes (requires code modification) + +**Audio dropouts**: +- Check system resources (CPU, memory) +- Close unnecessary applications +- Update audio drivers + +## Advanced Configuration + +### Custom Audio Settings +Modify `AudioProcessor.cs` to adjust: +- Buffer sizes for latency vs. stability trade-offs +- Sample rates (requires service support) +- Audio formats and compression + +### Session Configuration +Modify `BasicVoiceAssistant.cs` to customize: +- Turn detection sensitivity +- Response modalities (text + audio vs. audio only) +- Conversation context and memory + +### Error Handling +The sample includes robust error handling for: +- Network connectivity issues +- Audio device problems +- Service-side errors +- Graceful shutdown scenarios + +## Next Steps + +This basic sample can be extended with: + +1. **Voice Selection UI**: Dynamic voice switching during conversation +2. **Conversation History**: Save and replay conversations +3. **Custom Instructions**: Runtime instruction updates +4. **Multi-Language Support**: Language detection and switching +5. **Audio Effects**: Voice modulation and audio processing +6. **Analytics**: Conversation metrics and usage tracking + +## References + +- [NAudio Documentation](https://github.com/naudio/NAudio) +- [System.CommandLine Documentation](https://docs.microsoft.com/dotnet/standard/commandline/) diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/SampleProgram.cs b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/SampleProgram.cs new file mode 100644 index 000000000000..fc1fc8c3380c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/SampleProgram.cs @@ -0,0 +1,263 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.CommandLine; +using Azure.AI.VoiceLive.Samples; +using Azure.Core; +using Azure.Core.Pipeline; +using Azure.Identity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NAudio.Wave; + +namespace Azure.AI.VoiceLive.Samples +{ + /// + /// FILE: Program.cs + /// + /// + /// DESCRIPTION: + /// This sample demonstrates the fundamental capabilities of the VoiceLive SDK by creating + /// a basic voice assistant that can engage in natural conversation with proper interruption + /// handling. This serves as the foundational example that showcases the core value + /// proposition of unified speech-to-speech interaction. + /// + /// USAGE: + /// dotnet run + /// + /// Set the environment variables with your own values before running the sample: + /// 1) AZURE_VOICELIVE_API_KEY - The Azure VoiceLive API key + /// 2) AZURE_VOICELIVE_ENDPOINT - The Azure VoiceLive endpoint + /// + /// Or update appsettings.json with your values. + /// + /// REQUIREMENTS: + /// - Azure.AI.VoiceLive + /// - Azure.Identity + /// - NAudio (for audio capture and playback) + /// - Microsoft.Extensions.Configuration + /// - System.CommandLine + /// + public class SampleProgram + { + /// + /// Main entry point for the Voice Assistant sample. + /// + /// + /// + public static async Task Main(string[] args) + { + // Create command line interface + var rootCommand = CreateRootCommand(); + return await rootCommand.InvokeAsync(args).ConfigureAwait(false); + } + + private static RootCommand CreateRootCommand() + { + var rootCommand = new RootCommand("Basic Voice Assistant using Azure VoiceLive SDK"); + + var apiKeyOption = new Option( + "--api-key", + "Azure VoiceLive API key. If not provided, will use AZURE_VOICELIVE_API_KEY environment variable."); + + var endpointOption = new Option( + "--endpoint", + () => "wss://api.voicelive.com/v1", + "Azure VoiceLive endpoint"); + + var modelOption = new Option( + "--model", + () => "gpt-4o", + "VoiceLive model to use"); + + var voiceOption = new Option( + "--voice", + () => "en-US-AvaNeural", + "Voice to use for the assistant"); + + var instructionsOption = new Option( + "--instructions", + () => "You are a helpful AI assistant. Respond naturally and conversationally. Keep your responses concise but engaging.", + "System instructions for the AI assistant"); + + var useTokenCredentialOption = new Option( + "--use-token-credential", + "Use Azure token credential instead of API key"); + + var verboseOption = new Option( + "--verbose", + "Enable verbose logging"); + + rootCommand.AddOption(apiKeyOption); + rootCommand.AddOption(endpointOption); + rootCommand.AddOption(modelOption); + rootCommand.AddOption(voiceOption); + rootCommand.AddOption(instructionsOption); + rootCommand.AddOption(useTokenCredentialOption); + rootCommand.AddOption(verboseOption); + + rootCommand.SetHandler(async ( + string? apiKey, + string endpoint, + string model, + string voice, + string instructions, + bool useTokenCredential, + bool verbose) => + { + await RunVoiceAssistantAsync(apiKey, endpoint, model, voice, instructions, useTokenCredential, verbose).ConfigureAwait(false); + }, + apiKeyOption, + endpointOption, + modelOption, + voiceOption, + instructionsOption, + useTokenCredentialOption, + verboseOption); + + return rootCommand; + } + + private static async Task RunVoiceAssistantAsync( + string? apiKey, + string endpoint, + string model, + string voice, + string instructions, + bool useTokenCredential, + bool verbose) + { + // Setup configuration + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", optional: true) + .AddEnvironmentVariables() + .Build(); + + // Override with command line values if provided + apiKey ??= configuration["VoiceLive:ApiKey"] ?? Environment.GetEnvironmentVariable("AZURE_VOICELIVE_API_KEY"); + endpoint = configuration["VoiceLive:Endpoint"] ?? endpoint; + model = configuration["VoiceLive:Model"] ?? model; + voice = configuration["VoiceLive:Voice"] ?? voice; + instructions = configuration["VoiceLive:Instructions"] ?? instructions; + + // Setup logging + using var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConsole(); + if (verbose) + { + builder.SetMinimumLevel(LogLevel.Debug); + } + else + { + builder.SetMinimumLevel(LogLevel.Information); + } + }); + + var logger = loggerFactory.CreateLogger(); + + // Validate credentials + if (string.IsNullOrEmpty(apiKey) && !useTokenCredential) + { + Console.WriteLine("❌ Error: No authentication provided"); + Console.WriteLine("Please provide an API key using --api-key or set AZURE_VOICELIVE_API_KEY environment variable,"); + Console.WriteLine("or use --use-token-credential for Azure authentication."); + return; + } + + // Check audio system before starting + if (!CheckAudioSystem(logger)) + { + return; + } + + try + { + // Create client with appropriate credential + VoiceLiveClient client; + if (useTokenCredential) + { + var tokenCredential = new DefaultAzureCredential(); + client = new VoiceLiveClient(new Uri(endpoint), tokenCredential, new VoiceLiveClientOptions()); + logger.LogInformation("Using Azure token credential"); + } + else + { + var keyCredential = new Azure.AzureKeyCredential(apiKey!); + client = new VoiceLiveClient(new Uri(endpoint), keyCredential, new VoiceLiveClientOptions()); + logger.LogInformation("Using API key credential"); + } + + // Create and start voice assistant + using var assistant = new BasicVoiceAssistant( + client, + model, + voice, + instructions, + loggerFactory); + + // Setup cancellation token for graceful shutdown + using var cancellationTokenSource = new CancellationTokenSource(); + Console.CancelKeyPress += (sender, e) => + { + e.Cancel = true; + logger.LogInformation("Received shutdown signal"); + cancellationTokenSource.Cancel(); + }; + + // Start the assistant + await assistant.StartAsync(cancellationTokenSource.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + Console.WriteLine("\n👋 Voice assistant shut down. Goodbye!"); + } + catch (Exception ex) + { + logger.LogError(ex, "Fatal error"); + Console.WriteLine($"❌ Error: {ex.Message}"); + } + } + + private static bool CheckAudioSystem(ILogger logger) + { + try + { + // Try input (default device) + using (var waveIn = new WaveInEvent + { + WaveFormat = new WaveFormat(24000, 16, 1), + BufferMilliseconds = 50 + }) + { + // Start/Stop to force initialization and surface any device errors + waveIn.DataAvailable += (_, __) => { }; + waveIn.StartRecording(); + waveIn.StopRecording(); + } + + // Try output (default device) + var buffer = new BufferedWaveProvider(new WaveFormat(24000, 16, 1)) + { + BufferDuration = TimeSpan.FromMilliseconds(200) + }; + + using (var waveOut = new WaveOutEvent { DesiredLatency = 100 }) + { + waveOut.Init(buffer); + // Playing isn’t strictly required to validate a device, but it’s safe + waveOut.Play(); + waveOut.Stop(); + } + + logger.LogInformation("Audio system check passed (default input/output initialized)."); + return true; + } + catch (Exception ex) + { + Console.WriteLine($"❌ Audio system check failed: {ex.Message}"); + return false; + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/appsettings.json b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/appsettings.json new file mode 100644 index 000000000000..f193a20b915a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/appsettings.json @@ -0,0 +1,6 @@ +{ + "VoiceLive": { + "Voice": "en-US-AvaNeural", + "Instructions": "You are a helpful AI assistant. Respond naturally and conversationally. Keep your responses concise but engaging." + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/appsettings.template.json b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/appsettings.template.json new file mode 100644 index 000000000000..778f63db265d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/BasicVoiceAssistant/appsettings.template.json @@ -0,0 +1,15 @@ +{ + "VoiceLive": { + "ApiKey": "your-api-key-here", + "Endpoint": "wss://api.voicelive.com/v1", + "Model": "gpt-4o-realtime-preview", + "Voice": "en-US-AvaNeural", + "Instructions": "You are a helpful AI assistant. Respond naturally and conversationally. Keep your responses concise but engaging." + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Azure.AI.VoiceLive": "Debug" + } + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/.gitignore b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/.gitignore new file mode 100644 index 000000000000..2945f93d5676 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/.gitignore @@ -0,0 +1,66 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates +launchsettings.json +appsettings.Development.json + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Configuration files with secrets +appsettings.json +!appsettings.template.json + +# IDE files +.vscode/ +.idea/ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/AudioProcessor.cs b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/AudioProcessor.cs new file mode 100644 index 000000000000..ba16ce05fbe4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/AudioProcessor.cs @@ -0,0 +1,384 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Threading.Channels; +using NAudio.Wave; + +namespace Azure.AI.VoiceLive.Samples; + +/// +/// Handles real-time audio capture and playback for the voice assistant. +/// +/// +/// Threading Architecture: +/// - Main thread: Event loop and UI +/// - Capture thread: NAudio input stream reading +/// - Send thread: Async audio data transmission to VoiceLive +/// - Playback thread: NAudio output stream writing +/// +public class AudioProcessor : IDisposable +{ + private readonly VoiceLiveSession _session; + private readonly ILogger _logger; + + // Audio configuration - PCM16, 24kHz, mono as specified + private const int SampleRate = 24000; + private const int Channels = 1; + private const int BitsPerSample = 16; + + // NAudio components + private WaveInEvent? _waveIn; + private WaveOutEvent? _waveOut; + private BufferedWaveProvider? _playbackBuffer; + + // Audio capture and playback state + private bool _isCapturing; + private bool _isPlaying; + + // Audio streaming channels + private readonly Channel _audioSendChannel; + private readonly Channel _audioPlaybackChannel; + private readonly ChannelWriter _audioSendWriter; + private readonly ChannelReader _audioSendReader; + private readonly ChannelWriter _audioPlaybackWriter; + private readonly ChannelReader _audioPlaybackReader; + + // Background tasks + private Task? _audioSendTask; + private Task? _audioPlaybackTask; + private readonly CancellationTokenSource _cancellationTokenSource; + private CancellationTokenSource _playbackCancellationTokenSource; + + /// + /// Initializes a new instance of the AudioProcessor class. + /// + /// The VoiceLive session for audio communication. + /// Logger for diagnostic information. + public AudioProcessor(VoiceLiveSession session, ILogger logger) + { + _session = session ?? throw new ArgumentNullException(nameof(session)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + // Create unbounded channels for audio data + _audioSendChannel = Channel.CreateUnbounded(); + _audioSendWriter = _audioSendChannel.Writer; + _audioSendReader = _audioSendChannel.Reader; + + _audioPlaybackChannel = Channel.CreateUnbounded(); + _audioPlaybackWriter = _audioPlaybackChannel.Writer; + _audioPlaybackReader = _audioPlaybackChannel.Reader; + + _cancellationTokenSource = new CancellationTokenSource(); + _playbackCancellationTokenSource = new CancellationTokenSource(); + + _logger.LogInformation("AudioProcessor initialized with {SampleRate}Hz PCM16 mono audio", SampleRate); + } + + /// + /// Start capturing audio from microphone. + /// + public Task StartCaptureAsync() + { + if (_isCapturing) + return Task.CompletedTask; + + _isCapturing = true; + + try + { + _waveIn = new WaveInEvent + { + WaveFormat = new WaveFormat(SampleRate, BitsPerSample, Channels), + BufferMilliseconds = 50 // 50ms buffer for low latency + }; + + _waveIn.DataAvailable += OnAudioDataAvailable; + _waveIn.RecordingStopped += OnRecordingStopped; + + /* + _logger.LogInformation($"There are {WaveIn.DeviceCount} devices available."); + for (int i = 0; i < WaveIn.DeviceCount; i++) + { + var deviceInfo = WaveIn.GetCapabilities(i); + + _logger.LogInformation($"{i}: {deviceInfo.ProductName}"); + } + */ + _waveIn.DeviceNumber = 0; // Default to first device + + _waveIn.StartRecording(); + + // Start audio send task + _audioSendTask = ProcessAudioSendAsync(_cancellationTokenSource.Token); + + _logger.LogInformation("Started audio capture"); + return Task.CompletedTask; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to start audio capture"); + _isCapturing = false; + throw; + } + } + + /// + /// Stop capturing audio. + /// + public async Task StopCaptureAsync() + { + if (!_isCapturing) + return; + + _isCapturing = false; + + if (_waveIn != null) + { + _waveIn.StopRecording(); + _waveIn.DataAvailable -= OnAudioDataAvailable; + _waveIn.RecordingStopped -= OnRecordingStopped; + _waveIn.Dispose(); + _waveIn = null; + } + + // Complete the send channel and wait for the send task + _audioSendWriter.TryComplete(); + if (_audioSendTask != null) + { + await _audioSendTask.ConfigureAwait(false); + _audioSendTask = null; + } + + _logger.LogInformation("Stopped audio capture"); + } + + /// + /// Initialize audio playback system. + /// + public Task StartPlaybackAsync() + { + if (_isPlaying) + return Task.CompletedTask; + + _isPlaying = true; + + try + { + _waveOut = new WaveOutEvent + { + DesiredLatency = 100 // 100ms latency + }; + + _playbackBuffer = new BufferedWaveProvider(new WaveFormat(SampleRate, BitsPerSample, Channels)) + { + BufferDuration = TimeSpan.FromMinutes(5), // 5 second buffer + DiscardOnBufferOverflow = true + }; + + _waveOut.Init(_playbackBuffer); + _waveOut.Play(); + + _playbackCancellationTokenSource = new CancellationTokenSource(); + + // Start audio playback task + _audioPlaybackTask = ProcessAudioPlaybackAsync(); + + _logger.LogInformation("Audio playback system ready"); + return Task.CompletedTask; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to initialize audio playback"); + _isPlaying = false; + throw; + } + } + + /// + /// Stop audio playback and clear buffer. + /// + public async Task StopPlaybackAsync() + { + if (!_isPlaying) + return; + + _isPlaying = false; + + // Clear the playback channel + while (_audioPlaybackReader.TryRead(out _)) + { } + + if (_playbackBuffer != null) + { + _playbackBuffer.ClearBuffer(); + } + + if (_waveOut != null) + { + _waveOut.Stop(); + _waveOut.Dispose(); + _waveOut = null; + } + + _playbackBuffer = null; + + // Complete the playback channel and wait for the playback task + _playbackCancellationTokenSource.Cancel(); + + if (_audioPlaybackTask != null) + { + await _audioPlaybackTask.ConfigureAwait(false); + _audioPlaybackTask = null; + } + + _logger.LogInformation("Stopped audio playback"); + } + + /// + /// Queue audio data for playback. + /// + /// The audio data to queue. + public async Task QueueAudioAsync(byte[] audioData) + { + if (_isPlaying && audioData.Length > 0) + { + await _audioPlaybackWriter.WriteAsync(audioData).ConfigureAwait(false); + } + } + + /// + /// Event handler for audio data available from microphone. + /// + private void OnAudioDataAvailable(object? sender, WaveInEventArgs e) + { + if (_isCapturing && e.BytesRecorded > 0) + { + byte[] audioData = new byte[e.BytesRecorded]; + Array.Copy(e.Buffer, 0, audioData, 0, e.BytesRecorded); + + // Queue audio data for sending (non-blocking) + if (!_audioSendWriter.TryWrite(audioData)) + { + _logger.LogWarning("Failed to queue audio data for sending - channel may be full"); + } + } + } + + /// + /// Event handler for recording stopped. + /// + private void OnRecordingStopped(object? sender, StoppedEventArgs e) + { + if (e.Exception != null) + { + _logger.LogError(e.Exception, "Audio recording stopped due to error"); + } + } + + /// + /// Background task to process audio data and send to VoiceLive service. + /// + private async Task ProcessAudioSendAsync(CancellationToken cancellationToken) + { + try + { + await foreach (byte[] audioData in _audioSendReader.ReadAllAsync(cancellationToken).ConfigureAwait(false)) + { + if (cancellationToken.IsCancellationRequested) + break; + + try + { + // Send audio data directly to the session + await _session.SendInputAudioAsync(audioData, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error sending audio data to VoiceLive"); + // Continue processing other audio data + } + } + } + catch (OperationCanceledException) + { + // Expected when cancellation is requested + } + catch (Exception ex) + { + _logger.LogError(ex, "Error in audio send processing"); + } + } + + /// + /// Background task to process audio playback. + /// + private async Task ProcessAudioPlaybackAsync() + { + try + { + CancellationTokenSource combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_playbackCancellationTokenSource.Token, _cancellationTokenSource.Token); + var cancellationToken = combinedTokenSource.Token; + + await foreach (byte[] audioData in _audioPlaybackReader.ReadAllAsync(cancellationToken).ConfigureAwait(false)) + { + if (cancellationToken.IsCancellationRequested) + break; + + try + { + if (_playbackBuffer != null && _isPlaying) + { + _playbackBuffer.AddSamples(audioData, 0, audioData.Length); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error in audio playback"); + // Continue processing other audio data + } + } + } + catch (OperationCanceledException) + { + // Expected when cancellation is requested + } + catch (Exception ex) + { + _logger.LogError(ex, "Error in audio playback processing"); + } + } + + /// + /// Clean up audio resources. + /// + public async Task CleanupAsync() + { + await StopCaptureAsync().ConfigureAwait(false); + await StopPlaybackAsync().ConfigureAwait(false); + + _cancellationTokenSource.Cancel(); + + // Wait for background tasks to complete + var tasks = new List(); + if (_audioSendTask != null) + tasks.Add(_audioSendTask); + if (_audioPlaybackTask != null) + tasks.Add(_audioPlaybackTask); + + if (tasks.Count > 0) + { + await Task.WhenAll(tasks).ConfigureAwait(false); + } + + _logger.LogInformation("Audio processor cleaned up"); + } + + /// + /// Dispose of resources. + /// + public void Dispose() + { + CleanupAsync().Wait(); + _cancellationTokenSource.Dispose(); + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.cs b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.cs new file mode 100644 index 000000000000..11938839c40d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.cs @@ -0,0 +1,602 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.AI.VoiceLive.Samples; + +/// +/// Customer service voice bot implementing function calling with the VoiceLive SDK. +/// +/// +/// This sample demonstrates how to build a sophisticated customer service bot that can: +/// - Check order status and track shipments +/// - Retrieve customer account information and history +/// - Schedule technical support calls +/// - Process returns and exchanges +/// - Update shipping addresses for pending orders +/// +/// The bot uses strongly-typed function definitions and provides real-time voice interaction +/// with proper interruption handling and error recovery. +/// +public class CustomerServiceBot : IDisposable +{ + private readonly VoiceLiveClient _client; + private readonly string _model; + private readonly string _voice; + private readonly string _instructions; + private readonly ICustomerServiceFunctions _functions; + private readonly ILogger _logger; + private readonly ILoggerFactory _loggerFactory; + + private readonly HashSet _assistantMessageItems = new HashSet(); + private readonly HashSet _assistantMessageResponses = new HashSet(); + + private VoiceLiveSession? _session; + private AudioProcessor? _audioProcessor; + private bool _disposed; + + /// + /// Initializes a new instance of the CustomerServiceBot class. + /// + /// The VoiceLive client. + /// The model to use. + /// The voice to use. + /// The system instructions. + /// The customer service functions implementation. + /// Logger factory for creating loggers. + public CustomerServiceBot( + VoiceLiveClient client, + string model, + string voice, + string instructions, + ICustomerServiceFunctions functions, + ILoggerFactory loggerFactory) + { + _client = client ?? throw new ArgumentNullException(nameof(client)); + _model = model ?? throw new ArgumentNullException(nameof(model)); + _voice = voice ?? throw new ArgumentNullException(nameof(voice)); + _instructions = instructions ?? throw new ArgumentNullException(nameof(instructions)); + _functions = functions ?? throw new ArgumentNullException(nameof(functions)); + _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + _logger = loggerFactory.CreateLogger(); + } + + /// + /// Start the customer service bot session. + /// + /// Cancellation token for stopping the session. + public async Task StartAsync(CancellationToken cancellationToken = default) + { + try + { + _logger.LogInformation("Connecting to VoiceLive API with model {Model}", _model); + + // Start VoiceLive session + _session = await _client.StartSessionAsync(_model, cancellationToken).ConfigureAwait(false); + + // Initialize audio processor + _audioProcessor = new AudioProcessor(_session, _loggerFactory.CreateLogger()); + + // Configure session for voice conversation with function calling + await SetupSessionAsync(cancellationToken).ConfigureAwait(false); + + // Start audio systems + await _audioProcessor.StartPlaybackAsync().ConfigureAwait(false); + await _audioProcessor.StartCaptureAsync().ConfigureAwait(false); + + _logger.LogInformation("Customer service bot ready! Start speaking..."); + Console.WriteLine(); + Console.WriteLine("=" + new string('=', 69)); + Console.WriteLine("🏢 CUSTOMER SERVICE BOT READY"); + Console.WriteLine("I can help you with orders, returns, account info, and scheduling support calls"); + Console.WriteLine("Start speaking to begin your customer service session"); + Console.WriteLine("Press Ctrl+C to exit"); + Console.WriteLine("=" + new string('=', 69)); + Console.WriteLine(); + + // Process events + await ProcessEventsAsync(cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + _logger.LogInformation("Received cancellation signal, shutting down..."); + } + catch (Exception ex) + { + _logger.LogError(ex, "Connection error"); + throw; + } + finally + { + // Cleanup + if (_audioProcessor != null) + { + await _audioProcessor.CleanupAsync().ConfigureAwait(false); + } + } + } + + /// + /// Configure the VoiceLive session for customer service with function calling. + /// + private async Task SetupSessionAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Setting up customer service session with function calling..."); + + // Azure voice configuration + var azureVoice = new AzureStandardVoice(_voice, AzureStandardVoiceType.AzureStandard); + + // Create strongly typed turn detection configuration + var turnDetectionConfig = new ServerVad + { + Threshold = 0.5f, + PrefixPaddingMs = 300, + SilenceDurationMs = 500 + }; + + // Create conversation session options with function tools + var sessionOptions = new SessionOptions + { + Model = _model, + Instructions = _instructions, + Voice = azureVoice, + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16, + TurnDetection = turnDetectionConfig + }; + + // Ensure modalities include audio + sessionOptions.Modalities.Clear(); + sessionOptions.Modalities.Add(InputModality.Text); + sessionOptions.Modalities.Add(InputModality.Audio); + + // Add function tools for customer service operations + sessionOptions.Tools.Add(CreateCheckOrderStatusTool()); + sessionOptions.Tools.Add(CreateGetCustomerInfoTool()); + sessionOptions.Tools.Add(CreateScheduleSupportCallTool()); + sessionOptions.Tools.Add(CreateInitiateReturnProcessTool()); + sessionOptions.Tools.Add(CreateUpdateShippingAddressTool()); + + + await _session!.ConfigureConversationSessionAsync(sessionOptions, cancellationToken).ConfigureAwait(false); + + _logger.LogInformation("Session configuration sent with {ToolCount} customer service tools", sessionOptions.Tools.Count); + } + + /// + /// Create the check order status function tool. + /// + private FunctionTool CreateCheckOrderStatusTool() + { + var parameters = new + { + type = "object", + properties = new + { + order_number = new + { + type = "string", + description = "The customer's order number (required)" + }, + email = new + { + type = "string", + description = "Customer's email address if order number is not available" + } + }, + required = new[] { "order_number" } + }; + + return new FunctionTool("check_order_status") + { + Description = "Check the status of a customer order by order number or email. Use this when customers ask about their order status, shipping, or delivery information.", + Parameters = BinaryData.FromObjectAsJson(parameters) + }; + } + + /// + /// Create the get customer info function tool. + /// + private FunctionTool CreateGetCustomerInfoTool() + { + var parameters = new + { + type = "object", + properties = new + { + customer_id = new + { + type = "string", + description = "Customer ID or email address to look up" + }, + include_history = new + { + type = "boolean", + description = "Whether to include recent purchase history in the response", + @default = false + } + }, + required = new[] { "customer_id" } + }; + + return new FunctionTool("get_customer_info") + { + Description = "Retrieve customer account information and optionally their purchase history. Use this when customers ask about their account details or past orders.", + Parameters = BinaryData.FromObjectAsJson(parameters) + }; + } + + /// + /// Create the schedule support call function tool. + /// + private FunctionTool CreateScheduleSupportCallTool() + { + var parameters = new + { + type = "object", + properties = new + { + customer_id = new + { + type = "string", + description = "Customer identifier (ID or email)" + }, + preferred_time = new + { + type = "string", + description = "Preferred call time in ISO format (optional)" + }, + issue_category = new + { + type = "string", + @enum = new[] { "technical", "billing", "warranty", "returns" }, + description = "Category of the support issue" + }, + urgency = new + { + type = "string", + @enum = new[] { "low", "medium", "high", "critical" }, + description = "Urgency level of the issue", + @default = "medium" + }, + description = new + { + type = "string", + description = "Brief description of the issue the customer needs help with" + } + }, + required = new[] { "customer_id", "issue_category", "description" } + }; + + return new FunctionTool("schedule_support_call") + { + Description = "Schedule a technical support call with a specialist. Use this when customers need to speak with a technical expert about complex issues.", + Parameters = BinaryData.FromObjectAsJson(parameters) + }; + } + + /// + /// Create the initiate return process function tool. + /// + private FunctionTool CreateInitiateReturnProcessTool() + { + var parameters = new + { + type = "object", + properties = new + { + order_number = new + { + type = "string", + description = "Original order number for the return" + }, + product_id = new + { + type = "string", + description = "Specific product ID to return from the order" + }, + reason = new + { + type = "string", + @enum = new[] { "defective", "wrong_item", "not_satisfied", "damaged_shipping" }, + description = "Reason for the return" + }, + return_type = new + { + type = "string", + @enum = new[] { "refund", "exchange", "store_credit" }, + description = "Type of return requested by the customer" + } + }, + required = new[] { "order_number", "product_id", "reason", "return_type" } + }; + + return new FunctionTool("initiate_return_process") + { + Description = "Start the return/exchange process for a product. Use this when customers want to return or exchange items they've purchased.", + Parameters = BinaryData.FromObjectAsJson(parameters) + }; + } + + /// + /// Create the update shipping address function tool. + /// + private FunctionTool CreateUpdateShippingAddressTool() + { + var parameters = new + { + type = "object", + properties = new + { + order_number = new + { + type = "string", + description = "Order number to update the shipping address for" + }, + new_address = new + { + type = "object", + properties = new + { + street = new { type = "string", description = "Street address" }, + city = new { type = "string", description = "City name" }, + state = new { type = "string", description = "State or province" }, + zip_code = new { type = "string", description = "ZIP or postal code" }, + country = new { type = "string", description = "Country code", @default = "US" } + }, + required = new[] { "street", "city", "state", "zip_code" }, + description = "New shipping address information" + } + }, + required = new[] { "order_number", "new_address" } + }; + + return new FunctionTool("update_shipping_address") + { + Description = "Update shipping address for pending orders. Use this when customers need to change where their order will be delivered.", + Parameters = BinaryData.FromObjectAsJson(parameters) + }; + } + + /// + /// Process events from the VoiceLive session. + /// + private async Task ProcessEventsAsync(CancellationToken cancellationToken) + { + try + { + await foreach (ServerEvent serverEvent in _session!.GetUpdatesAsync(cancellationToken).ConfigureAwait(false)) + { + await HandleServerEventAsync(serverEvent, cancellationToken).ConfigureAwait(false); + } + } + catch (OperationCanceledException) + { + _logger.LogInformation("Event processing cancelled"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error processing events"); + throw; + } + } + + /// + /// Handle different types of server events from VoiceLive. + /// + private async Task HandleServerEventAsync(ServerEvent serverEvent, CancellationToken cancellationToken) + { + _logger.LogDebug("Received event: {EventType}", serverEvent.GetType().Name); + + switch (serverEvent) + { + case ServerEventSessionCreated sessionCreated: + await HandleSessionCreatedAsync(sessionCreated, cancellationToken).ConfigureAwait(false); + break; + + case ServerEventSessionUpdated sessionUpdated: + _logger.LogInformation("Session updated successfully with function tools"); + + // Start audio capture once session is ready + if (_audioProcessor != null) + { + await _audioProcessor.StartCaptureAsync().ConfigureAwait(false); + } + break; + + case ServerEventInputAudioBufferSpeechStarted speechStarted: + _logger.LogInformation("🎤 Customer started speaking - stopping playback"); + Console.WriteLine("🎤 Listening..."); + + // Stop current assistant audio playback (interruption handling) + if (_audioProcessor != null) + { + await _audioProcessor.StopPlaybackAsync().ConfigureAwait(false); + } + + // Cancel any ongoing response + try + { + await _session!.CancelResponseAsync(cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.LogDebug(ex, "No response to cancel"); + } + break; + + case ServerEventInputAudioBufferSpeechStopped speechStopped: + _logger.LogInformation("🎤 Customer stopped speaking"); + Console.WriteLine("🤔 Processing..."); + + // Restart playback system for response + if (_audioProcessor != null) + { + await _audioProcessor.StartPlaybackAsync().ConfigureAwait(false); + } + break; + + case ServerEventResponseCreated responseCreated: + _logger.LogInformation("🤖 Assistant response created"); + break; + + case ServerEventResponseOutputItemAdded outputItemAdded: + await HandleResponseOutputItemAddedAsync(outputItemAdded, cancellationToken).ConfigureAwait(false); + break; + + case ServerEventResponseAudioDelta audioDelta: + // Stream audio response to speakers + _logger.LogDebug("Received audio delta"); + + if (audioDelta.Delta != null && _audioProcessor != null) + { + byte[] audioData = audioDelta.Delta.ToArray(); + await _audioProcessor.QueueAudioAsync(audioData).ConfigureAwait(false); + } + break; + + case ServerEventResponseAudioDone audioDone: + _logger.LogInformation("🤖 Assistant finished speaking"); + Console.WriteLine("🎤 Ready for next customer inquiry..."); + break; + + case ServerEventResponseContentPartAdded partAdded: + if (_assistantMessageItems.Contains(partAdded.ItemId)) + { + _assistantMessageResponses.Add(partAdded.ResponseId); + } + + break; + case ServerEventResponseDone responseDone: + _logger.LogInformation("✅ Response complete"); + break; + case ServerEventResponseFunctionCallArgumentsDone functionCallArgumentsDone: + _logger.LogInformation("🔧 Function call arguments done for call ID: {CallId}", functionCallArgumentsDone.CallId); + await HandleFunctionCallAsync(functionCallArgumentsDone.Name, functionCallArgumentsDone.CallId, functionCallArgumentsDone.Arguments, cancellationToken).ConfigureAwait(false); + break; + case ServerEventResponseAudioTranscriptDelta transcriptDelta: + // For now, only deal with the assistant responses. + if (_assistantMessageResponses.Contains(transcriptDelta.ResponseId)) + { + Console.Write($"{transcriptDelta.Delta}"); + } + break; + + case ServerEventResponseAudioTranscriptDone transcriptDone: + // For now, only deal with the assistant responses. + if (_assistantMessageResponses.Contains(transcriptDone.ResponseId)) + { + Console.WriteLine(); + } + break; + case ServerEventError errorEvent: + _logger.LogError("❌ VoiceLive error: {ErrorMessage}", errorEvent.Error?.Message); + Console.WriteLine($"Error: {errorEvent.Error?.Message}"); + break; + + default: + _logger.LogDebug("Unhandled event type: {EventType}", serverEvent.GetType().Name); + break; + } + } + + /// + /// Handle response output item added events, including function calls. + /// + private async Task HandleResponseOutputItemAddedAsync(ServerEventResponseOutputItemAdded outputItemAdded, CancellationToken cancellationToken) + { + if (outputItemAdded.Item is ConversationItemWithReference item && + item.Type == ConversationItemWithReferenceType.FunctionCall) + { + // This is a function call item, extract the details + var functionName = item.Name; + var callId = item.CallId; + var arguments = item.Arguments; + + if (!string.IsNullOrEmpty(functionName) && !string.IsNullOrEmpty(callId) && !string.IsNullOrEmpty(arguments)) + { + await HandleFunctionCallAsync(functionName, callId, arguments, cancellationToken).ConfigureAwait(false); + } + else + { + _logger.LogWarning("Function call item missing required properties: Name={Name}, CallId={CallId}, Arguments={Arguments}", + functionName, callId, arguments); + } + } + else if (outputItemAdded.Item is ConversationItemWithReference messageItem && + messageItem.Type == ConversationItemWithReferenceType.Message && + messageItem.Role == ConversationItemWithReferenceRole.Assistant) + { + // Keep track of the items that are from the assistant, so we know how to display the conversation. + _assistantMessageItems.Add(messageItem.Id); + } + } + + /// + /// Handle function call execution and send results back to the session. + /// + private async Task HandleFunctionCallAsync(string functionName, string callId, string arguments, CancellationToken cancellationToken) + { + _logger.LogInformation("🔧 Executing function: {FunctionName}", functionName); + Console.WriteLine($"🔧 Looking up {functionName.Replace("_", " ")}..."); + + try + { + // Execute the function through our business logic layer + var result = await _functions.ExecuteFunctionAsync(functionName, arguments, cancellationToken).ConfigureAwait(false); + + // Create function call output item using the model factory + var outputItem = new ConversationItemWithReference() + { + Type = ConversationItemWithReferenceType.FunctionCallOutput, + CallId = callId, + Output = JsonSerializer.Serialize(result) + }; + + // Add the result to the conversation + await _session!.AddItemAsync(outputItem, cancellationToken).ConfigureAwait(false); + await _session!.StartResponseAsync(cancellationToken).ConfigureAwait(false); + + _logger.LogInformation("✅ Function {FunctionName} completed successfully", functionName); + } + catch (Exception ex) + { + _logger.LogError(ex, "❌ Function {FunctionName} execution failed", functionName); + + // Send error response + var errorResult = new { success = false, error = "I'm sorry, I'm having trouble accessing that information right now. Please try again in a moment." }; + var outputItem = new ConversationItemWithReference(); + outputItem.Type = ConversationItemWithReferenceType.FunctionCallOutput; + outputItem.CallId = callId; + outputItem.Output = JsonSerializer.Serialize(errorResult); + + await _session!.AddItemAsync(outputItem, cancellationToken).ConfigureAwait(false); + } + } + + /// + /// Handle session created event. + /// + private async Task HandleSessionCreatedAsync(ServerEventSessionCreated sessionCreated, CancellationToken cancellationToken) + { + _logger.LogInformation("Session ready: {SessionId}", sessionCreated.Session?.Id); + + // Start audio capture once session is ready + if (_audioProcessor != null) + { + await _audioProcessor.StartCaptureAsync().ConfigureAwait(false); + } + } + + /// + /// Dispose of resources. + /// + public void Dispose() + { + if (_disposed) + return; + + _audioProcessor?.Dispose(); + _session?.Dispose(); + _disposed = true; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.csproj b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.csproj new file mode 100644 index 000000000000..a2a542fb77f5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.csproj @@ -0,0 +1,42 @@ + + + + Exe + net8.0 + enable + enable + CustomerServiceBot + Azure.AI.VoiceLive.Samples + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.sln b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.sln new file mode 100644 index 000000000000..817844e0fdfa --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceBot.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomerServiceBot", "CustomerServiceBot.csproj", "{12345678-1234-1234-1234-123456789012}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {12345678-1234-1234-1234-123456789012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12345678-1234-1234-1234-123456789012}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12345678-1234-1234-1234-123456789012}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12345678-1234-1234-1234-123456789012}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceFunctions.cs b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceFunctions.cs new file mode 100644 index 000000000000..4536930efd61 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/CustomerServiceFunctions.cs @@ -0,0 +1,464 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using static Azure.AI.VoiceLive.Samples.FunctionModels; +using static Azure.AI.VoiceLive.Samples.SampleData; + +namespace Azure.AI.VoiceLive.Samples; + +/// +/// Interface for customer service function execution. +/// +public interface ICustomerServiceFunctions +{ + /// + /// Executes a function by name with JSON arguments. + /// + /// + /// + /// + /// + Task ExecuteFunctionAsync(string functionName, string argumentsJson, CancellationToken cancellationToken = default); +} + +/// +/// Implementation of customer service functions with mock data for demonstration. +/// In a real implementation, these would connect to actual databases and services. +/// +public class CustomerServiceFunctions : ICustomerServiceFunctions +{ + private readonly ILogger _logger; + private readonly Dictionary _orders; + private readonly Dictionary _customers; + private readonly List _supportTickets; + + /// + /// Constructor for CustomerServiceFunctions. + /// + /// + /// + public CustomerServiceFunctions(ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + // Initialize sample data + _orders = InitializeSampleOrders(); + _customers = InitializeSampleCustomers(); + _supportTickets = new List(); + } + + /// + /// Execute a function by name with JSON arguments. + /// + public async Task ExecuteFunctionAsync(string functionName, string argumentsJson, CancellationToken cancellationToken = default) + { + try + { + _logger.LogInformation("Executing function: {FunctionName} with arguments: {Arguments}", functionName, argumentsJson); + + return functionName switch + { + "check_order_status" => await CheckOrderStatusAsync(argumentsJson, cancellationToken).ConfigureAwait(false), + "get_customer_info" => await GetCustomerInfoAsync(argumentsJson, cancellationToken).ConfigureAwait(false), + "schedule_support_call" => await ScheduleSupportCallAsync(argumentsJson, cancellationToken).ConfigureAwait(false), + "initiate_return_process" => await InitiateReturnProcessAsync(argumentsJson, cancellationToken).ConfigureAwait(false), + "update_shipping_address" => await UpdateShippingAddressAsync(argumentsJson, cancellationToken).ConfigureAwait(false), + _ => new { success = false, error = $"Unknown function: {functionName}" } + }; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error executing function {FunctionName}", functionName); + return new { success = false, error = "Internal error occurred while processing your request." }; + } + } + + private async Task CheckOrderStatusAsync(string argumentsJson, CancellationToken cancellationToken) + { + var args = JsonSerializer.Deserialize(argumentsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + if (args == null) + { + return new { success = false, message = "Invalid arguments provided." }; + } + + // Simulate async database lookup + await Task.Delay(100, cancellationToken).ConfigureAwait(false); + + if (!_orders.TryGetValue(args.order_number, out var order)) + { + return new + { + success = false, + message = "Order not found. Please verify the order number and try again." + }; + } + + return new + { + success = true, + order = new + { + number = order.OrderNumber, + status = order.Status, + total = order.TotalAmount, + items = order.Items.Select(item => new + { + name = item.ProductName, + quantity = item.Quantity, + status = item.Status, + price = item.Price + }), + estimated_delivery = order.EstimatedDelivery?.ToString("yyyy-MM-dd"), + tracking = order.TrackingNumber, + order_date = order.CreatedAt.ToString("yyyy-MM-dd") + } + }; + } + + private async Task GetCustomerInfoAsync(string argumentsJson, CancellationToken cancellationToken) + { + var args = JsonSerializer.Deserialize(argumentsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + if (args == null) + { + return new { success = false, message = "Invalid arguments provided." }; + } + + // Simulate async database lookup + await Task.Delay(150, cancellationToken).ConfigureAwait(false); + + var customer = _customers.Values.FirstOrDefault(c => + c.CustomerId == args.customer_id || + c.Email.Equals(args.customer_id, StringComparison.OrdinalIgnoreCase)); + + if (customer == null) + { + return new + { + success = false, + message = "Customer account not found. Please verify the customer ID or email address." + }; + } + + var result = new + { + success = true, + customer = new + { + id = customer.CustomerId, + name = customer.Name, + email = customer.Email, + phone = customer.Phone, + tier = customer.Tier, + joined_date = customer.CreatedAt.ToString("yyyy-MM-dd") + } + }; + + if (args.include_history) + { + var customerOrders = _orders.Values + .Where(o => o.CustomerId == customer.CustomerId) + .OrderByDescending(o => o.CreatedAt) + .Take(5) + .Select(order => new + { + number = order.OrderNumber, + date = order.CreatedAt.ToString("yyyy-MM-dd"), + total = order.TotalAmount, + status = order.Status + }); + + return new + { + result.success, + customer = new + { + result.customer.id, + result.customer.name, + result.customer.email, + result.customer.phone, + result.customer.tier, + result.customer.joined_date, + recent_orders = customerOrders + } + }; + } + + return result; + } + + private async Task ScheduleSupportCallAsync(string argumentsJson, CancellationToken cancellationToken) + { + var args = JsonSerializer.Deserialize(argumentsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + if (args == null) + { + return new { success = false, message = "Invalid arguments provided." }; + } + + // Validate customer exists + var customer = _customers.Values.FirstOrDefault(c => + c.CustomerId == args.customer_id || + c.Email.Equals(args.customer_id, StringComparison.OrdinalIgnoreCase)); + + if (customer == null) + { + return new + { + success = false, + message = "Customer not found. Please verify the customer ID." + }; + } + + // Simulate async scheduling system + await Task.Delay(200, cancellationToken).ConfigureAwait(false); + + // Parse preferred time or use default + DateTime scheduledTime; + if (!string.IsNullOrEmpty(args.preferred_time) && DateTime.TryParse(args.preferred_time, out scheduledTime)) + { + // Use provided time + } + else + { + // Default to next business day at 10 AM + scheduledTime = DateTime.Today.AddDays(1); + if (scheduledTime.DayOfWeek == DayOfWeek.Saturday) + scheduledTime = scheduledTime.AddDays(2); + if (scheduledTime.DayOfWeek == DayOfWeek.Sunday) + scheduledTime = scheduledTime.AddDays(1); + scheduledTime = scheduledTime.AddHours(10); + } + + var ticket = new SupportTicket + { + TicketId = $"TICKET-{DateTime.Now:yyyyMMdd}-{Random.Shared.Next(1000, 9999)}", + CustomerId = customer.CustomerId, + Category = args.issue_category, + Urgency = args.urgency, + Description = args.description, + ScheduledTime = scheduledTime, + Status = "Scheduled" + }; + + _supportTickets.Add(ticket); + + return new + { + success = true, + ticket = new + { + ticket_id = ticket.TicketId, + customer_name = customer.Name, + scheduled_time = ticket.ScheduledTime.ToString("yyyy-MM-dd HH:mm"), + category = ticket.Category, + urgency = ticket.Urgency, + description = ticket.Description, + status = ticket.Status + }, + message = $"Support call scheduled for {ticket.ScheduledTime:yyyy-MM-dd HH:mm}. You will receive a confirmation email shortly." + }; + } + + private async Task InitiateReturnProcessAsync(string argumentsJson, CancellationToken cancellationToken) + { + var args = JsonSerializer.Deserialize(argumentsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + if (args == null) + { + return new { success = false, message = "Invalid arguments provided." }; + } + + // Simulate async database lookup + await Task.Delay(150, cancellationToken).ConfigureAwait(false); + + if (!_orders.TryGetValue(args.order_number, out var order)) + { + return new + { + success = false, + message = "Order not found. Please verify the order number." + }; + } + + var item = order.Items.FirstOrDefault(i => i.ProductId == args.product_id); + if (item == null) + { + return new + { + success = false, + message = "Product not found in this order." + }; + } + + // Check if return is eligible (within 30 days and not already returned) + if (order.CreatedAt < DateTime.Now.AddDays(-30)) + { + return new + { + success = false, + message = "This order is outside the 30-day return window." + }; + } + + if (item.Status == "Returned") + { + return new + { + success = false, + message = "This item has already been returned." + }; + } + + var returnId = $"RTN-{DateTime.Now:yyyyMMdd}-{Random.Shared.Next(1000, 9999)}"; + + return new + { + success = true, + return_info = new + { + return_id = returnId, + order_number = order.OrderNumber, + product_name = item.ProductName, + return_type = args.return_type, + reason = args.reason, + refund_amount = args.return_type == "refund" ? item.Price : 0, + estimated_processing = "3-5 business days", + return_label_url = $"https://returns.techcorp.com/label/{returnId}" + }, + message = "Return request initiated successfully. You will receive a return shipping label via email within 24 hours." + }; + } + + private async Task UpdateShippingAddressAsync(string argumentsJson, CancellationToken cancellationToken) + { + var args = JsonSerializer.Deserialize(argumentsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + if (args == null) + { + return new { success = false, message = "Invalid arguments provided." }; + } + + // Simulate async database lookup + await Task.Delay(100, cancellationToken).ConfigureAwait(false); + + if (!_orders.TryGetValue(args.order_number, out var order)) + { + return new + { + success = false, + message = "Order not found. Please verify the order number." + }; + } + + // Check if order can be modified + if (order.Status == "Delivered" || order.Status == "Shipped") + { + return new + { + success = false, + message = $"Cannot update address for {order.Status.ToLower()} orders." + }; + } + + return new + { + success = true, + updated_order = new + { + order_number = order.OrderNumber, + status = order.Status, + new_shipping_address = new + { + args.new_address.street, + args.new_address.city, + args.new_address.state, + args.new_address.zip_code, + args.new_address.country + }, + estimated_delivery = order.EstimatedDelivery?.AddDays(1).ToString("yyyy-MM-dd") // Adjust delivery date + }, + message = "Shipping address updated successfully. Your estimated delivery date may have changed." + }; + } + + private Dictionary InitializeSampleOrders() + { + return new Dictionary + { + ["ORD-2024-001"] = new Order + { + OrderNumber = "ORD-2024-001", + Status = "Processing", + TotalAmount = 299.99m, + CustomerId = "CUST-001", + CreatedAt = DateTime.Now.AddDays(-2), + EstimatedDelivery = DateTime.Now.AddDays(3), + TrackingNumber = "1Z999AA1234567890", + Items = new List + { + new() { ProductId = "LAPTOP-001", ProductName = "TechCorp Laptop Pro", Quantity = 1, Status = "Processing", Price = 299.99m } + } + }, + ["ORD-2024-002"] = new Order + { + OrderNumber = "ORD-2024-002", + Status = "Shipped", + TotalAmount = 159.98m, + CustomerId = "CUST-002", + CreatedAt = DateTime.Now.AddDays(-5), + EstimatedDelivery = DateTime.Now.AddDays(1), + TrackingNumber = "1Z999AA1234567891", + Items = new List + { + new() { ProductId = "MOUSE-001", ProductName = "Wireless Gaming Mouse", Quantity = 1, Status = "Shipped", Price = 79.99m }, + new() { ProductId = "PAD-001", ProductName = "Gaming Mouse Pad", Quantity = 1, Status = "Shipped", Price = 79.99m } + } + }, + ["ORD-2024-003"] = new Order + { + OrderNumber = "ORD-2024-003", + Status = "Delivered", + TotalAmount = 499.99m, + CustomerId = "CUST-001", + CreatedAt = DateTime.Now.AddDays(-10), + EstimatedDelivery = DateTime.Now.AddDays(-3), + TrackingNumber = "1Z999AA1234567892", + Items = new List + { + new() { ProductId = "MONITOR-001", ProductName = "4K Gaming Monitor", Quantity = 1, Status = "Delivered", Price = 499.99m } + } + } + }; + } + + private Dictionary InitializeSampleCustomers() + { + return new Dictionary + { + ["CUST-001"] = new Customer + { + CustomerId = "CUST-001", + Name = "John Smith", + Email = "john.smith@email.com", + Phone = "+1-555-0123", + Tier = "Gold", + CreatedAt = DateTime.Now.AddMonths(-8) + }, + ["CUST-002"] = new Customer + { + CustomerId = "CUST-002", + Name = "Sarah Johnson", + Email = "sarah.johnson@email.com", + Phone = "+1-555-0124", + Tier = "Silver", + CreatedAt = DateTime.Now.AddMonths(-3) + }, + ["CUST-003"] = new Customer + { + CustomerId = "CUST-003", + Name = "Mike Davis", + Email = "mike.davis@email.com", + Phone = "+1-555-0125", + Tier = "Standard", + CreatedAt = DateTime.Now.AddMonths(-1) + } + }; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/FunctionModels.cs b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/FunctionModels.cs new file mode 100644 index 000000000000..304df865721a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/FunctionModels.cs @@ -0,0 +1,270 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.AI.VoiceLive.Samples; + +/// +/// Request models for customer service functions. +/// +public static class FunctionModels +{ + /// + /// Parameters for checking order status. + /// + public class CheckOrderStatusArgs + { + /// + /// The order number to check status for. + /// + public string order_number { get; set; } = string.Empty; + /// + /// Customer email. + /// + public string? email { get; set; } + } + + /// + /// Parameters for getting customer information. + /// + public class GetCustomerInfoArgs + { + /// + /// Customer ID to retrieve information for. + /// + public string customer_id { get; set; } = string.Empty; + /// + /// Whether to include order history in the response. + /// + public bool include_history { get; set; } = false; + } + + /// + /// Parameters for scheduling support calls. + /// + public class ScheduleSupportCallArgs + { + /// + /// The customer ID to schedule the call for. + /// + public string customer_id { get; set; } = string.Empty; + /// + /// The preferred time for the support call. + /// + public string? preferred_time { get; set; } + /// + /// The category of the support issue. + /// + public string issue_category { get; set; } = string.Empty; + /// + /// The urgency level of the support issue. + /// + public string urgency { get; set; } = "medium"; + /// + /// A brief description of the issue. + /// + public string description { get; set; } = string.Empty; + } + + /// + /// Parameters for initiating return process. + /// + public class InitiateReturnProcessArgs + { + /// + /// The order number for which the return is requested. + /// + public string order_number { get; set; } = string.Empty; + /// + /// The product ID to be returned. + /// + public string product_id { get; set; } = string.Empty; + /// + /// The reason for the return. + /// + public string reason { get; set; } = string.Empty; + /// + /// The return method preferred by the customer. + /// + public string return_type { get; set; } = string.Empty; + } + + /// + /// Address information for shipping updates. + /// + public class Address + { + /// + /// Street address for shipping. + /// + public string street { get; set; } = string.Empty; + /// + /// City for shipping address. + /// + public string city { get; set; } = string.Empty; + /// + /// state for shipping address. + /// + public string state { get; set; } = string.Empty; + /// + /// zip code for shipping address. + /// + public string zip_code { get; set; } = string.Empty; + /// + /// Country for shipping address. + /// + public string country { get; set; } = "US"; + } + + /// + /// Parameters for updating shipping address. + /// + public class UpdateShippingAddressArgs + { + /// + /// Order number for which the address needs to be updated. + /// + public string order_number { get; set; } = string.Empty; + /// + /// New shipping address. + /// + public Address new_address { get; set; } = new(); + } +} + +/// +/// Sample data models for demonstration purposes. +/// +public static class SampleData +{ + /// + /// Sample order information. + /// + public class Order + { + /// + /// The unique identifier for the order. + /// + public string OrderNumber { get; set; } = string.Empty; + /// + /// Status of the order. + /// + public string Status { get; set; } = string.Empty; + /// + /// Total amount for the order. + /// + public decimal TotalAmount { get; set; } + /// + /// The items included in the order. + /// + public List Items { get; set; } = new(); + /// + /// Estimated delivery date for the order. + /// + public DateTime? EstimatedDelivery { get; set; } + /// + /// Shipping tracking number, if available. + /// + public string? TrackingNumber { get; set; } + /// + /// Theustomer ID associated with the order. + /// + public string CustomerId { get; set; } = string.Empty; + /// + /// When the order was created. + /// + public DateTime CreatedAt { get; set; } + } + + /// + /// Sample order item information. + /// + public class OrderItem + { + /// + /// The unique identifier for the product. + /// + public string ProductId { get; set; } = string.Empty; + /// + /// Name of the product. + /// + public string ProductName { get; set; } = string.Empty; + /// + /// quantity of the product ordered. + /// + public int Quantity { get; set; } + /// + /// status of the order item. + /// + public string Status { get; set; } = string.Empty; + /// + /// price of the product. + /// + public decimal Price { get; set; } + } + + /// + /// Sample customer information. + /// + public class Customer + { + /// + /// customer ID. + /// + public string CustomerId { get; set; } = string.Empty; + /// + /// preferred name of the customer. + /// + public string Name { get; set; } = string.Empty; + /// + /// customer's email address. + /// + public string Email { get; set; } = string.Empty; + /// + /// phone number of the customer. + /// + public string? Phone { get; set; } + /// + /// customer's pricing tier. + /// + public string Tier { get; set; } = "Standard"; + /// + /// When the customer was created. + /// + public DateTime CreatedAt { get; set; } + } + + /// + /// Sample support ticket information. + /// + public class SupportTicket + { + /// + /// ID of the support ticket. + /// + public string TicketId { get; set; } = string.Empty; + /// + /// customer ID associated with the ticket. + /// + public string CustomerId { get; set; } = string.Empty; + /// + /// category of the support issue. + /// + public string Category { get; set; } = string.Empty; + /// + /// urgency level of the support issue. + /// + public string Urgency { get; set; } = string.Empty; + /// + /// brief description of the issue. + /// + public string Description { get; set; } = string.Empty; + /// + /// time when the ticket was created. + /// + public DateTime ScheduledTime { get; set; } + /// + /// current status of the support ticket. + /// + public string Status { get; set; } = "Scheduled"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/GlobalUsings.cs b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/GlobalUsings.cs new file mode 100644 index 000000000000..a1248f53e33c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/GlobalUsings.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +global using System; +global using System.Collections.Generic; +global using System.Linq; +global using System.Text.Json; +global using System.Threading; +global using System.Threading.Tasks; +global using Azure.AI.VoiceLive; +global using Microsoft.Extensions.Logging; diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/README.md b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/README.md new file mode 100644 index 000000000000..784f288fa8e9 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/README.md @@ -0,0 +1,393 @@ +# Customer Service Bot Sample + +This sample demonstrates how to build a sophisticated customer service voice bot using the Azure VoiceLive SDK with function calling capabilities. The bot provides real-time voice interaction for common customer service scenarios including order tracking, account management, returns processing, and technical support scheduling. + +## Features Demonstrated + +### Core Capabilities +- **Natural Voice Conversation**: Real-time speech-to-speech interaction with proper interruption handling +- **Function Calling**: Strongly-typed function definitions and execution using the VoiceLive SDK +- **Customer Service Operations**: Complete workflows for common support scenarios +- **Professional Voice Experience**: Optimized for customer-facing interactions + +### Supported Functions + +#### 1. Order Status Checking (`check_order_status`) +- Look up orders by order number +- Display order status, items, tracking, and delivery information +- Handle order not found scenarios gracefully + +#### 2. Customer Information Retrieval (`get_customer_info`) +- Retrieve customer account details by ID or email +- Optional inclusion of purchase history +- Customer tier and membership information + +#### 3. Support Call Scheduling (`schedule_support_call`) +- Schedule technical support calls with specialists +- Categorize issues (technical, billing, warranty, returns) +- Set urgency levels and preferred times +- Generate support tickets + +#### 4. Return Processing (`initiate_return_process`) +- Start return/exchange workflows +- Support multiple return reasons and types +- Generate return labels and tracking +- Validate return eligibility + +#### 5. Shipping Address Updates (`update_shipping_address`) +- Update shipping addresses for pending orders +- Validate order modification eligibility +- Adjust delivery estimates accordingly + +## Architecture + +### Clean Separation of Concerns +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ CustomerService │────│ VoiceLive SDK │────│ Business Logic │ +│ Bot │ │ Protocol │ │ Layer │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ │ + │ │ │ + ┌─────────┐ ┌─────────────┐ ┌─────────────┐ + │ Audio │ │ Function │ │ External │ + │ Handler │ │ Calling │ │ Services │ + └─────────┘ └─────────────┘ └─────────────┘ +``` + +### Key Components + +1. **CustomerServiceBot**: Main orchestrator handling VoiceLive session and event processing +2. **CustomerServiceFunctions**: Business logic implementation with mock data +3. **AudioProcessor**: Real-time audio capture and playback (shared with BasicVoiceAssistant) +4. **FunctionModels**: Strongly-typed request/response models + +## Getting Started + +### Prerequisites + +- .NET 8.0 or later +- Azure VoiceLive API key +- Audio input/output devices (microphone and speakers) + +### Setup + +1. **Configure API Key**: + ```bash + # Set environment variable + export AZURE_VOICELIVE_API_KEY="your_api_key_here" + + # Or update appsettings.json + cp appsettings.template.json appsettings.json + # Edit appsettings.json with your API key + ``` + +2. **Install Dependencies**: + ```bash + dotnet restore + ``` + +3. **Run the Sample**: + ```bash + dotnet run + ``` + +### Command Line Options + +```bash +dotnet run --help + +Customer Service Bot using Azure VoiceLive SDK with Function Calling + +Options: + --api-key Azure VoiceLive API key + --endpoint Azure VoiceLive endpoint [default: wss://api.voicelive.com/v1] + --model VoiceLive model to use [default: gpt-4o] + --voice Voice for the bot [default: en-US-JennyNeural] + --instructions System instructions for the bot + --use-token-credential Use Azure token credential instead of API key + --verbose Enable verbose logging + --help Show help message +``` + +## Sample Data + +The bot includes realistic sample data for demonstration: + +### Orders +- **ORD-2024-001**: Processing laptop order ($299.99) +- **ORD-2024-002**: Shipped gaming accessories ($159.98) +- **ORD-2024-003**: Delivered monitor ($499.99) + +### Customers +- **john.smith@email.com**: Gold tier customer with purchase history +- **sarah.johnson@email.com**: Silver tier customer +- **mike.davis@email.com**: Standard tier customer + +### Products +- **LAPTOP-001**: TechCorp Laptop Pro +- **MOUSE-001**: Wireless Gaming Mouse +- **MONITOR-001**: 4K Gaming Monitor + +## Usage Examples + +### Voice Interactions + +Try these sample phrases: + +1. **Order Status**: + - "What's the status of order ORD-2024-001?" + - "Can you track my order ORD-2024-002?" + +2. **Customer Info**: + - "Look up my account for john.smith@email.com" + - "Show me my account info and purchase history" + +3. **Returns**: + - "I need to return a defective laptop from order ORD-2024-001" + - "How do I exchange this monitor for a different size?" + +4. **Support Scheduling**: + - "I need to schedule a technical support call" + - "Can you book me a warranty call for tomorrow?" + +5. **Address Updates**: + - "I need to change the shipping address for order ORD-2024-001" + - "Update my delivery address to a new location" + +### Expected Responses + +The bot provides detailed, conversational responses: + +``` +🎤 "What's the status of order ORD-2024-001?" + +🔧 Looking up check order status... + +🤖 "I found your order ORD-2024-001. It's currently being processed + and contains one TechCorp Laptop Pro for $299.99. Your estimated + delivery date is January 15th, and the tracking number is + 1Z999AA1234567890. Is there anything else you'd like to know + about this order?" +``` + +## Implementation Details + +### Function Tool Definitions + +The bot uses strongly-typed function definitions with comprehensive parameter schemas: + +```csharp +private FunctionTool CreateCheckOrderStatusTool() +{ + var parameters = new + { + type = "object", + properties = new + { + order_number = new { + type = "string", + description = "The customer's order number (required)" + }, + email = new { + type = "string", + description = "Customer's email address if order number is not available" + } + }, + required = new[] { "order_number" } + }; + + return new FunctionTool("check_order_status") + { + Description = "Check the status of a customer order by order number or email...", + Parameters = BinaryData.FromObjectAsJson(parameters) + }; +} +``` + +### Event-Driven Architecture + +The bot handles VoiceLive events with proper pattern matching: + +```csharp +switch (serverEvent) +{ + case ServerEventResponseOutputItemAdded outputItemAdded: + await HandleResponseOutputItemAddedAsync(outputItemAdded, cancellationToken); + break; + + case ServerEventInputAudioBufferSpeechStarted: + // Handle interruption... + break; + + case ServerEventError errorEvent: + // Handle errors gracefully... + break; +} +``` + +### Function Execution Flow + +1. **Function Call Detection**: Monitor `ServerEventResponseOutputItemAdded` events +2. **Function Extraction**: Parse function name, call ID, and arguments +3. **Business Logic Execution**: Delegate to `CustomerServiceFunctions` +4. **Result Formatting**: Serialize response data +5. **Response Transmission**: Send results via `RequestFunctionCallOutputItem` + +### Error Handling + +The implementation includes comprehensive error handling: + +- **Network Issues**: Graceful degradation and retry logic +- **Invalid Parameters**: Clear user feedback and guidance +- **Function Failures**: Professional error messages +- **Audio Problems**: System checks and diagnostics + +## Configuration + +### Session Options + +```json +{ + "VoiceLive": { + "Model": "gpt-4o", + "Voice": "en-US-JennyNeural", + "Instructions": "You are a professional customer service representative...", + "InputAudioFormat": "Pcm16", + "OutputAudioFormat": "Pcm16", + "TurnDetection": { + "Type": "ServerVad", + "Threshold": 0.5, + "SilenceDurationMs": 500 + } + } +} +``` + +### Logging Configuration + +```json +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Azure.AI.VoiceLive": "Debug" + } + } +} +``` + +## Extending the Sample + +### Adding New Functions + +1. **Define Function Model**: + ```csharp + public class NewFunctionArgs + { + public string parameter1 { get; set; } = string.Empty; + public int parameter2 { get; set; } + } + ``` + +2. **Implement Business Logic**: + ```csharp + private async Task ExecuteNewFunctionAsync(string argumentsJson, CancellationToken cancellationToken) + { + var args = JsonSerializer.Deserialize(argumentsJson); + // Implementation here + return new { success = true, result = "..." }; + } + ``` + +3. **Register Function Tool**: + ```csharp + sessionOptions.Tools.Add(CreateNewFunctionTool()); + ``` + +### Integrating External Services + +Replace the mock implementations in `CustomerServiceFunctions` with actual service calls: + +```csharp +private async Task CheckOrderStatusAsync(string argumentsJson, CancellationToken cancellationToken) +{ + var args = JsonSerializer.Deserialize(argumentsJson); + + // Replace with actual service call + var order = await _orderService.GetOrderAsync(args.order_number, cancellationToken); + + return new { success = true, order = order }; +} +``` + +## Troubleshooting + +### Common Issues + +1. **No Audio Devices**: + - Ensure microphone and speakers are connected + - Check system audio settings + - Verify device permissions + +2. **API Key Issues**: + - Verify API key is correct + - Check environment variable or appsettings.json + - Ensure proper Azure subscription + +3. **Function Call Failures**: + - Check function parameter schemas + - Verify business logic implementation + - Review error logs for details + +4. **Session Configuration**: + - Ensure all required tools are properly registered + - Verify voice configuration is valid + - Check model availability + +### Debug Logging + +Enable verbose logging to troubleshoot issues: + +```bash +dotnet run --verbose +``` + +Or set logging level in appsettings.json: + +```json +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "Azure.AI.VoiceLive.Samples": "Trace" + } + } +} +``` + +## Performance Considerations + +- **Function Execution Time**: Keep business logic fast (< 2 seconds) +- **Audio Buffer Management**: Proper cleanup to prevent memory leaks +- **Concurrent Function Calls**: Handle parallel function execution +- **Error Recovery**: Implement retry logic for transient failures + +## Security Notes + +- **Data Validation**: Always validate function parameters +- **Input Sanitization**: Clean user inputs before processing +- **Error Information**: Don't expose sensitive data in error messages +- **Audit Logging**: Log all customer service interactions + +## Related Samples + +- **BasicVoiceAssistant**: Foundation for voice interaction patterns +- **TranscriptionSample**: Speech-to-text focused scenarios +- **ConversationAnalysis**: Advanced conversation insights + +## Learning Resources + +--- + +This sample demonstrates production-ready patterns for building sophisticated voice-enabled customer service applications using the Azure VoiceLive SDK. diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/SampleProgram.cs b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/SampleProgram.cs new file mode 100644 index 000000000000..b8549b2a44dc --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/SampleProgram.cs @@ -0,0 +1,300 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.CommandLine; +using Azure.AI.VoiceLive.Samples; +using Azure.Core; +using Azure.Core.Pipeline; +using Azure.Identity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NAudio.Wave; + +/// +/// FILE: SampleProgram.cs +/// +/// +/// DESCRIPTION: +/// This sample demonstrates sophisticated customer service capabilities using the VoiceLive SDK +/// with function calling. The bot can handle complex customer inquiries including order status, +/// account information, returns, and support scheduling through natural voice conversations. +/// +/// FEATURES DEMONSTRATED: +/// - Strongly-typed function calling using SDK's FunctionTool +/// - Real-time customer service operations with external system integration +/// - Professional voice configuration for customer-facing interactions +/// - Robust error handling and graceful degradation +/// - Clean separation between SDK protocol handling and business logic +/// +/// USAGE: +/// dotnet run +/// +/// Set the environment variables with your own values before running the sample: +/// 1) AZURE_VOICELIVE_API_KEY - The Azure VoiceLive API key +/// 2) AZURE_VOICELIVE_ENDPOINT - The Azure VoiceLive endpoint +/// +/// Or update appsettings.json with your values. +/// +/// REQUIREMENTS: +/// - Azure.AI.VoiceLive +/// - Azure.Identity +/// - NAudio (for audio capture and playback) +/// - Microsoft.Extensions.Configuration +/// - System.CommandLine +/// - System.Text.Json +/// +public class SampleProgram +{ + /// + /// Main entry point for the customer service bot sample. + /// + /// + /// + public static async Task Main(string[] args) + { + // Create command line interface + var rootCommand = CreateRootCommand(); + return await rootCommand.InvokeAsync(args).ConfigureAwait(false); + } + + private static RootCommand CreateRootCommand() + { + var rootCommand = new RootCommand("Customer Service Bot using Azure VoiceLive SDK with Function Calling"); + + var apiKeyOption = new Option( + "--api-key", + "Azure VoiceLive API key. If not provided, will use AZURE_VOICELIVE_API_KEY environment variable."); + + var endpointOption = new Option( + "--endpoint", + () => "wss://api.voicelive.com/v1", + "Azure VoiceLive endpoint"); + + var modelOption = new Option( + "--model", + () => "gpt-4o", + "VoiceLive model to use"); + + var voiceOption = new Option( + "--voice", + () => "en-US-JennyNeural", + "Voice to use for the customer service bot"); + + var instructionsOption = new Option( + "--instructions", + () => "You are a professional customer service representative for TechCorp. You have access to customer databases and order systems. Always be polite, helpful, and efficient. When customers ask about orders, accounts, or need to schedule service, use the available tools to provide accurate, real-time information. Keep your responses concise but thorough.", + "System instructions for the customer service bot"); + + var useTokenCredentialOption = new Option( + "--use-token-credential", + "Use Azure token credential instead of API key"); + + var verboseOption = new Option( + "--verbose", + "Enable verbose logging"); + + rootCommand.AddOption(apiKeyOption); + rootCommand.AddOption(endpointOption); + rootCommand.AddOption(modelOption); + rootCommand.AddOption(voiceOption); + rootCommand.AddOption(instructionsOption); + rootCommand.AddOption(useTokenCredentialOption); + rootCommand.AddOption(verboseOption); + + rootCommand.SetHandler(async ( + string? apiKey, + string endpoint, + string model, + string voice, + string instructions, + bool useTokenCredential, + bool verbose) => + { + await RunCustomerServiceBotAsync(apiKey, endpoint, model, voice, instructions, useTokenCredential, verbose).ConfigureAwait(false); + }, + apiKeyOption, + endpointOption, + modelOption, + voiceOption, + instructionsOption, + useTokenCredentialOption, + verboseOption); + + return rootCommand; + } + + private static async Task RunCustomerServiceBotAsync( + string? apiKey, + string endpoint, + string model, + string voice, + string instructions, + bool useTokenCredential, + bool verbose) + { + // Setup configuration + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", optional: true) + .AddEnvironmentVariables() + .Build(); + + // Override with command line values if provided + apiKey ??= configuration["VoiceLive:ApiKey"] ?? Environment.GetEnvironmentVariable("AZURE_VOICELIVE_API_KEY"); + endpoint = configuration["VoiceLive:Endpoint"] ?? endpoint; + model = configuration["VoiceLive:Model"] ?? model; + voice = configuration["VoiceLive:Voice"] ?? voice; + instructions = configuration["VoiceLive:Instructions"] ?? instructions; + + // Setup logging + using var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConsole(); + if (verbose) + { + builder.SetMinimumLevel(LogLevel.Debug); + } + else + { + builder.SetMinimumLevel(LogLevel.Information); + } + }); + + var logger = loggerFactory.CreateLogger(); + + // Validate credentials + if (string.IsNullOrEmpty(apiKey) && !useTokenCredential) + { + Console.WriteLine("❌ Error: No authentication provided"); + Console.WriteLine("Please provide an API key using --api-key or set AZURE_VOICELIVE_API_KEY environment variable,"); + Console.WriteLine("or use --use-token-credential for Azure authentication."); + return; + } + + // Check audio system before starting + if (!CheckAudioSystem(logger)) + { + return; + } + + try + { + // Create client with appropriate credential + VoiceLiveClient client; + if (useTokenCredential) + { + var tokenCredential = new DefaultAzureCredential(); + client = new VoiceLiveClient(new Uri(endpoint), tokenCredential, new VoiceLiveClientOptions()); + logger.LogInformation("Using Azure token credential"); + } + else + { + var keyCredential = new Azure.AzureKeyCredential(apiKey!); + client = new VoiceLiveClient(new Uri(endpoint), keyCredential, new VoiceLiveClientOptions()); + logger.LogInformation("Using API key credential"); + } + + // Create customer service functions implementation + var functions = new CustomerServiceFunctions(loggerFactory.CreateLogger()); + + // Create and start customer service bot + using var bot = new CustomerServiceBot( + client, + model, + voice, + instructions, + functions, + loggerFactory); + + // Setup cancellation token for graceful shutdown + using var cancellationTokenSource = new CancellationTokenSource(); + Console.CancelKeyPress += (sender, e) => + { + e.Cancel = true; + logger.LogInformation("Received shutdown signal"); + cancellationTokenSource.Cancel(); + }; + + // Display welcome message + DisplayWelcomeMessage(); + + // Start the customer service bot + await bot.StartAsync(cancellationTokenSource.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + Console.WriteLine("\n👋 Customer service bot shut down. Thank you for using TechCorp support!"); + } + catch (Exception ex) + { + logger.LogError(ex, "Fatal error"); + Console.WriteLine($"❌ Error: {ex.Message}"); + } + } + + private static void DisplayWelcomeMessage() + { + Console.WriteLine(); + Console.WriteLine("🏢 Welcome to TechCorp Customer Service"); + Console.WriteLine("======================================"); + Console.WriteLine(); + Console.WriteLine("I can help you with:"); + Console.WriteLine("• 📦 Order status and tracking"); + Console.WriteLine("• 👤 Account information and history"); + Console.WriteLine("• 🔄 Returns and exchanges"); + Console.WriteLine("• 📞 Scheduling technical support calls"); + Console.WriteLine("• 🚚 Updating shipping addresses"); + Console.WriteLine(); + Console.WriteLine("Sample data available:"); + Console.WriteLine("• Orders: ORD-2024-001, ORD-2024-002, ORD-2024-003"); + Console.WriteLine("• Customers: john.smith@email.com, sarah.johnson@email.com"); + Console.WriteLine("• Products: LAPTOP-001, MOUSE-001, MONITOR-001"); + Console.WriteLine(); + Console.WriteLine("Try saying things like:"); + Console.WriteLine("• \"What's the status of order ORD-2024-001?\""); + Console.WriteLine("• \"I need to return a defective laptop\""); + Console.WriteLine("• \"Can you look up my account info for john.smith@email.com?\""); + Console.WriteLine("• \"I need to schedule a technical support call\""); + Console.WriteLine(); + } + + private static bool CheckAudioSystem(ILogger logger) + { + try + { + // Try input (default device) + using (var waveIn = new WaveInEvent + { + WaveFormat = new WaveFormat(24000, 16, 1), + BufferMilliseconds = 50 + }) + { + // Start/Stop to force initialization and surface any device errors + waveIn.DataAvailable += (_, __) => { }; + waveIn.StartRecording(); + waveIn.StopRecording(); + } + + // Try output (default device) + var buffer = new BufferedWaveProvider(new WaveFormat(24000, 16, 1)) + { + BufferDuration = TimeSpan.FromMilliseconds(200) + }; + + using (var waveOut = new WaveOutEvent { DesiredLatency = 100 }) + { + waveOut.Init(buffer); + // Playing isn’t strictly required to validate a device, but it’s safe + waveOut.Play(); + waveOut.Stop(); + } + + logger.LogInformation("Audio system check passed (default input/output initialized)."); + return true; + } + catch (Exception ex) + { + Console.WriteLine($"❌ Audio system check failed: {ex.Message}"); + return false; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/appsettings.template.json b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/appsettings.template.json new file mode 100644 index 000000000000..db4f6b8f4897 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/CustomerServiceBot/appsettings.template.json @@ -0,0 +1,15 @@ +{ + "VoiceLive": { + "ApiKey": "YOUR_VOICELIVE_API_KEY", + "Endpoint": "wss://api.voicelive.com/v1", + "Model": "gpt-4o", + "Voice": "en-US-JennyNeural", + "Instructions": "You are a professional customer service representative for TechCorp. You have access to customer databases and order systems. Always be polite, helpful, and efficient. When customers ask about orders, accounts, or need to schedule service, use the available tools to provide accurate, real-time information. Keep your responses concise but thorough." + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Azure.AI.VoiceLive": "Debug" + } + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/Directory.Build.props b/sdk/ai/Azure.AI.VoiceLive/samples/Directory.Build.props new file mode 100644 index 000000000000..efd27f54e2d5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/Directory.Build.props @@ -0,0 +1,26 @@ + + + true + true + + false + false + + $(NoWarn); + NU5104; + + true + + + + + + + + + + $(DefineConstants);STRONGNAME_SIGNED + false + false + + diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/Directory.Build.targets b/sdk/ai/Azure.AI.VoiceLive/samples/Directory.Build.targets new file mode 100644 index 000000000000..2ce057016d6f --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/Directory.Build.targets @@ -0,0 +1,14 @@ + + + + $(TargetFramework) + + + + + + + + + diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/snippets/AuthenticationSnippets.cs b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/AuthenticationSnippets.cs new file mode 100644 index 000000000000..7f670066313a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/AuthenticationSnippets.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure.AI.VoiceLive; +using Azure.Core; +using Azure.Identity; + +namespace Azure.AI.VoiceLive.Samples.Snippets +{ + /// + /// Basic code snippets demonstrating how to authenticate and configure the VoiceLive client. + /// + public partial class AuthenticationSnippets + { + /// + /// Demonstrates creating a VoiceLive client with Microsoft Entra ID authentication. + /// + public void CreateVoiceLiveClientWithTokenCredential() + { + #region Snippet:CreateVoiceLiveClientWithTokenCredential + Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); + DefaultAzureCredential credential = new DefaultAzureCredential(); + VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); + #endregion + } + + /// + /// Demonstrates creating a VoiceLive client with API key authentication. + /// + public void CreateVoiceLiveClientWithApiKey() + { + #region Snippet:CreateVoiceLiveClientWithApiKey + Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); + AzureKeyCredential credential = new AzureKeyCredential("your-api-key"); + VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); + #endregion + } + + /// + /// Demonstrates creating a VoiceLive client for a specific API version. + /// + public void CreateVoiceLiveClientForSpecificApiVersion() + { + #region Snippet:CreateVoiceLiveClientForSpecificApiVersion + Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); + DefaultAzureCredential credential = new DefaultAzureCredential(); + VoiceLiveClientOptions options = new VoiceLiveClientOptions(VoiceLiveClientOptions.ServiceVersion.V2025_05_01_Preview); + VoiceLiveClient client = new VoiceLiveClient(endpoint, credential, options); + #endregion + } + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/snippets/Azure.AI.VoiceLive.Snippets.csproj b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/Azure.AI.VoiceLive.Snippets.csproj new file mode 100644 index 000000000000..fe145ab1b27e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/Azure.AI.VoiceLive.Snippets.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + enable + enable + Library + $(NoWarn);CS1998 + true + + + + + + + + + + + \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/snippets/BasicUsageSnippets.cs b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/BasicUsageSnippets.cs new file mode 100644 index 000000000000..ca1ebbfcbc64 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/BasicUsageSnippets.cs @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure.AI.VoiceLive; +using Azure.Core; +using Azure.Identity; + +namespace Azure.AI.VoiceLive.Samples.Snippets +{ + /// + /// Code snippets demonstrating basic usage patterns for the VoiceLive API. + /// + public partial class BasicUsageSnippets + { + /// + /// Demonstrates creating a basic voice assistant with the VoiceLive API. + /// + public async Task BasicVoiceAssistantExample() + { + #region Snippet:BasicVoiceAssistantExample + // Create the VoiceLive client + Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); + DefaultAzureCredential credential = new DefaultAzureCredential(); + VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); + + var model = "gpt-4o-mini-realtime-preview"; // Specify the model to use + // Start a new session + VoiceLiveSession session = await client.StartSessionAsync(model).ConfigureAwait(false); + + // Configure session for voice conversation + SessionOptions sessionOptions = new SessionOptions() + { + Model = model, + Instructions = "You are a helpful AI assistant. Respond naturally and conversationally.", + Voice = new AzureStandardVoice("en-US-AvaNeural", AzureStandardVoiceType.AzureStandard), + TurnDetection = new ServerVad() + { + Threshold = 0.5f, + PrefixPaddingMs = 300, + SilenceDurationMs = 500 + }, + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16 + }; + + // Ensure modalities include audio + sessionOptions.Modalities.Clear(); + sessionOptions.Modalities.Add(InputModality.Text); + sessionOptions.Modalities.Add(InputModality.Audio); + + await session.ConfigureConversationSessionAsync(sessionOptions).ConfigureAwait(false); + + // Process events from the session + await foreach (ServerEvent serverEvent in session.GetUpdatesAsync().ConfigureAwait(false)) + { + if (serverEvent is ServerEventResponseAudioDelta audioDelta) + { + // Play audio response + byte[] audioData = audioDelta.Delta.ToArray(); + // ... audio playback logic + } + else if (serverEvent is ServerEventResponseTextDelta textDelta) + { + // Display text response + Console.Write(textDelta.Delta); + } + } + #endregion + } + + /// + /// Demonstrates advanced voice configuration with custom voices and enhanced features. + /// + public async Task AdvancedVoiceConfiguration() + { + Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); + DefaultAzureCredential credential = new DefaultAzureCredential(); + VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); + + var model = "gpt-4o-realtime-preview"; // Specify the model to use + + VoiceLiveSession session = await client.StartSessionAsync(model).ConfigureAwait(false); + + #region Snippet:AdvancedVoiceConfiguration + SessionOptions sessionOptions = new SessionOptions() + { + Model = model, + Instructions = "You are a customer service representative. Be helpful and professional.", + Voice = new AzureCustomVoice("your-custom-voice-name", "your-custom-voice-endpoint-id", AzureCustomVoiceType.AzureCustom) + { + Temperature = 0.8f + }, + TurnDetection = new AzureSemanticVad() + { + NegThreshold = 0.3f, + WindowSize = 300, + RemoveFillerWords = true + }, + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16 + }; + + // Ensure modalities include audio + sessionOptions.Modalities.Clear(); + sessionOptions.Modalities.Add(InputModality.Text); + sessionOptions.Modalities.Add(InputModality.Audio); + + await session.ConfigureConversationSessionAsync(sessionOptions).ConfigureAwait(false); + #endregion + } + + /// + /// Demonstrates function calling capabilities. + /// + public async Task FunctionCallingExample() + { + Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); + DefaultAzureCredential credential = new DefaultAzureCredential(); + VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); + + var model = "gpt-4o-mini-realtime-preview"; // Specify the model to use + + VoiceLiveSession session = await client.StartSessionAsync(model).ConfigureAwait(false); + + #region Snippet:FunctionCallingExample + // Define a function for the assistant to call + var getCurrentWeatherFunction = new FunctionTool("get_current_weather") + { + Description = "Get the current weather for a given location", + Parameters = BinaryData.FromString(""" + { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state or country" + } + }, + "required": ["location"] + } + """) + }; + + SessionOptions sessionOptions = new SessionOptions() + { + Model = model, + Instructions = "You are a weather assistant. Use the get_current_weather function to help users with weather information.", + Voice = new AzureStandardVoice("en-US-AvaNeural", AzureStandardVoiceType.AzureStandard), + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16 + }; + + // Add the function tool + sessionOptions.Tools.Add(getCurrentWeatherFunction); + + // Ensure modalities include audio + sessionOptions.Modalities.Clear(); + sessionOptions.Modalities.Add(InputModality.Text); + sessionOptions.Modalities.Add(InputModality.Audio); + + await session.ConfigureConversationSessionAsync(sessionOptions).ConfigureAwait(false); + #endregion + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/samples/snippets/README.md b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/README.md new file mode 100644 index 000000000000..7797bbf56e1b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/samples/snippets/README.md @@ -0,0 +1,37 @@ +# Azure.AI.VoiceLive Snippets + +This directory contains code snippets used in the main README.md file and documentation. These snippets demonstrate the key functionality of the Azure.AI.VoiceLive client library. + +## Snippets Organization + +- **AuthenticationSnippets.cs**: Demonstrates different ways to authenticate with the VoiceLive service +- **BasicUsageSnippets.cs**: Shows basic usage patterns including voice assistants, custom voices, and function calling + +## Building the Snippets + +The snippets project references the main Azure.AI.VoiceLive project and can be built to verify that the code examples are syntactically correct: + +```bash +dotnet build Azure.AI.VoiceLive.Snippets.csproj +``` + +## Usage in Documentation + +The snippets use the `#region Snippet:Name` and `#endregion` syntax to allow them to be extracted and included in documentation and the README.md file. + +Example: +```csharp +#region Snippet:CreateVoiceLiveClientWithApiKey +Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); +AzureKeyCredential credential = new AzureKeyCredential("your-api-key"); +VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); +#endregion +``` + +These snippets are then referenced in the README using the syntax: +```markdown +```C# Snippet:CreateVoiceLiveClientWithApiKey +Uri endpoint = new Uri("https://your-resource.cognitiveservices.azure.com"); +AzureKeyCredential credential = new AzureKeyCredential("your-api-key"); +VoiceLiveClient client = new VoiceLiveClient(endpoint, credential); +``` \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Azure.AI.VoiceLive.csproj b/sdk/ai/Azure.AI.VoiceLive/src/Azure.AI.VoiceLive.csproj new file mode 100644 index 000000000000..70dadca3dd25 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Azure.AI.VoiceLive.csproj @@ -0,0 +1,24 @@ + + + This is the Azure.AI.VoiceLive client library for developing .NET applications with rich experience. + Azure SDK Code Generation Azure.AI.VoiceLive for Azure Data Plane + 1.0.0-beta.1 + Azure.AI.VoiceLive + $(RequiredTargetFrameworks) + true + + + + + + + + + + + + + + + + diff --git a/sdk/ai/Azure.AI.VoiceLive/src/AzureCustomVoice.cs b/sdk/ai/Azure.AI.VoiceLive/src/AzureCustomVoice.cs new file mode 100644 index 000000000000..79f27027646e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/AzureCustomVoice.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Data; +using System.IO; + +namespace Azure.AI.VoiceLive +{ + public partial class AzureCustomVoice : IVoiceType + { + /// + /// + /// + /// + public BinaryData ToBinaryData() => this.PersistableModelWriteCore(System.ClientModel.Primitives.ModelReaderWriterOptions.Json); + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/AzureStandardVoice.cs b/sdk/ai/Azure.AI.VoiceLive/src/AzureStandardVoice.cs new file mode 100644 index 000000000000..6ee4104f408b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/AzureStandardVoice.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.IO; + +namespace Azure.AI.VoiceLive +{ + public partial class AzureStandardVoice : IVoiceType + { + /// + /// + /// + /// + public BinaryData ToBinaryData() => this.PersistableModelWriteCore(System.ClientModel.Primitives.ModelReaderWriterOptions.Json); + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/ForceModelsRequest.cs b/sdk/ai/Azure.AI.VoiceLive/src/ForceModelsRequest.cs new file mode 100644 index 000000000000..15334fac61e6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/ForceModelsRequest.cs @@ -0,0 +1,119 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ForceModelsRequest. + internal partial class ForceModelsRequest + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + internal ForceModelsRequest(BinaryData @event) + { + Event = @event; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ForceModelsRequest(BinaryData @event, IDictionary additionalBinaryDataProperties) + { + Event = @event; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// + /// Gets the Event. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData Event { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOptions.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOptions.Serialization.cs new file mode 100644 index 000000000000..1e4c20e07b06 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOptions.Serialization.cs @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for animation outputs including blendshapes, visemes, and emotion metadata. + public partial class AnimationOptions : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AnimationOptions)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(ModelName)) + { + writer.WritePropertyName("model_name"u8); + writer.WriteStringValue(ModelName); + } + if (Optional.IsCollectionDefined(Outputs)) + { + writer.WritePropertyName("outputs"u8); + writer.WriteStartArray(); + foreach (AnimationOutputType item in Outputs) + { + writer.WriteStringValue(item.ToSerialString()); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(EmotionDetectionIntervalMs)) + { + writer.WritePropertyName("emotion_detection_interval_ms"u8); + writer.WriteNumberValue(EmotionDetectionIntervalMs.Value); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AnimationOptions IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AnimationOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AnimationOptions)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAnimationOptions(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AnimationOptions DeserializeAnimationOptions(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string modelName = default; + IList outputs = default; + int? emotionDetectionIntervalMs = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("model_name"u8)) + { + modelName = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("outputs"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(item.GetString().ToAnimationOutputType()); + } + outputs = array; + continue; + } + if (prop.NameEquals("emotion_detection_interval_ms"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + emotionDetectionIntervalMs = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AnimationOptions(modelName, outputs ?? new ChangeTrackingList(), emotionDetectionIntervalMs, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AnimationOptions)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AnimationOptions IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AnimationOptions PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAnimationOptions(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AnimationOptions)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOptions.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOptions.cs new file mode 100644 index 000000000000..053081c1e37c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOptions.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for animation outputs including blendshapes, visemes, and emotion metadata. + public partial class AnimationOptions + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public AnimationOptions() + { + Outputs = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// The name of the animation model to use. + /// Set of output data types requested from the animation system. + /// Interval for emotion detection in milliseconds. If not set, emotion detection is disabled. + /// Keeps track of any properties unknown to the library. + internal AnimationOptions(string modelName, IList outputs, int? emotionDetectionIntervalMs, IDictionary additionalBinaryDataProperties) + { + ModelName = modelName; + Outputs = outputs; + EmotionDetectionIntervalMs = emotionDetectionIntervalMs; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The name of the animation model to use. + public string ModelName { get; set; } + + /// Set of output data types requested from the animation system. + public IList Outputs { get; } + + /// Interval for emotion detection in milliseconds. If not set, emotion detection is disabled. + public int? EmotionDetectionIntervalMs { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOutputType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOutputType.Serialization.cs new file mode 100644 index 000000000000..58f297ae0a89 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOutputType.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class AnimationOutputTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this AnimationOutputType value) => value switch + { + AnimationOutputType.Blendshapes => "blendshapes", + AnimationOutputType.VisemeId => "viseme_id", + AnimationOutputType.Emotion => "emotion", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AnimationOutputType value.") + }; + + /// The value to deserialize. + public static AnimationOutputType ToAnimationOutputType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "blendshapes")) + { + return AnimationOutputType.Blendshapes; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "viseme_id")) + { + return AnimationOutputType.VisemeId; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "emotion")) + { + return AnimationOutputType.Emotion; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AnimationOutputType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOutputType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOutputType.cs new file mode 100644 index 000000000000..8bda37e13e3e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AnimationOutputType.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// Specifies the types of animation data to output. + public enum AnimationOutputType + { + /// Blendshapes. + Blendshapes, + /// VisemeId. + VisemeId, + /// Emotion. + Emotion + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioEchoCancellation.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioEchoCancellation.Serialization.cs new file mode 100644 index 000000000000..a5219d30b96d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioEchoCancellation.Serialization.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Echo cancellation configuration for server-side audio processing. + public partial class AudioEchoCancellation : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AudioEchoCancellation)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AudioEchoCancellation IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AudioEchoCancellation JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AudioEchoCancellation)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAudioEchoCancellation(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AudioEchoCancellation DeserializeAudioEchoCancellation(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AudioEchoCancellation(@type, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AudioEchoCancellation)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AudioEchoCancellation IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AudioEchoCancellation PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAudioEchoCancellation(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AudioEchoCancellation)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioEchoCancellation.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioEchoCancellation.cs new file mode 100644 index 000000000000..96247315053e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioEchoCancellation.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Echo cancellation configuration for server-side audio processing. + public partial class AudioEchoCancellation + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public AudioEchoCancellation() + { + } + + /// Initializes a new instance of . + /// The type of echo cancellation model to use. + /// Keeps track of any properties unknown to the library. + internal AudioEchoCancellation(string @type, IDictionary additionalBinaryDataProperties) + { + Type = @type; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The type of echo cancellation model to use. + public string Type { get; } = "server_echo_cancellation"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioFormat.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioFormat.cs new file mode 100644 index 000000000000..b80be462758b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioFormat.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// + public readonly partial struct AudioFormat : IEquatable + { + private readonly string _value; + private const string Pcm16Value = "pcm16"; + private const string G711UlawValue = "g711_ulaw"; + private const string G711AlawValue = "g711_alaw"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public AudioFormat(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the Pcm16. + public static AudioFormat Pcm16 { get; } = new AudioFormat(Pcm16Value); + + /// Gets the G711Ulaw. + public static AudioFormat G711Ulaw { get; } = new AudioFormat(G711UlawValue); + + /// Gets the G711Alaw. + public static AudioFormat G711Alaw { get; } = new AudioFormat(G711AlawValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(AudioFormat left, AudioFormat right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(AudioFormat left, AudioFormat right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator AudioFormat(string value) => new AudioFormat(value); + + /// Converts a string to a . + /// The value. + public static implicit operator AudioFormat?(string value) => value == null ? null : new AudioFormat(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is AudioFormat other && Equals(other); + + /// + public bool Equals(AudioFormat other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettings.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettings.Serialization.cs new file mode 100644 index 000000000000..aa73814a4f62 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettings.Serialization.cs @@ -0,0 +1,169 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for input audio transcription. + public partial class AudioInputTranscriptionSettings : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal AudioInputTranscriptionSettings() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AudioInputTranscriptionSettings)} does not support writing '{format}' format."); + } + writer.WritePropertyName("model"u8); + writer.WriteStringValue(Model.ToSerialString()); + if (Optional.IsDefined(Language)) + { + writer.WritePropertyName("language"u8); + writer.WriteStringValue(Language); + } + writer.WritePropertyName("enabled"u8); + writer.WriteBooleanValue(Enabled); + writer.WritePropertyName("custom_model"u8); + writer.WriteBooleanValue(CustomModel); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AudioInputTranscriptionSettings IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AudioInputTranscriptionSettings JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AudioInputTranscriptionSettings)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAudioInputTranscriptionSettings(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AudioInputTranscriptionSettings DeserializeAudioInputTranscriptionSettings(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + AudioInputTranscriptionSettingsModel model = default; + string language = default; + bool enabled = default; + bool customModel = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("model"u8)) + { + model = prop.Value.GetString().ToAudioInputTranscriptionSettingsModel(); + continue; + } + if (prop.NameEquals("language"u8)) + { + language = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("enabled"u8)) + { + enabled = prop.Value.GetBoolean(); + continue; + } + if (prop.NameEquals("custom_model"u8)) + { + customModel = prop.Value.GetBoolean(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AudioInputTranscriptionSettings(model, language, enabled, customModel, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AudioInputTranscriptionSettings)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AudioInputTranscriptionSettings IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AudioInputTranscriptionSettings PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAudioInputTranscriptionSettings(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AudioInputTranscriptionSettings)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettings.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettings.cs new file mode 100644 index 000000000000..6efc1f49e234 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettings.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for input audio transcription. + public partial class AudioInputTranscriptionSettings + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The model used for transcription. E.g., 'whisper-1', 'azure-fast-transcription', 's2s-ingraph'. + /// Whether transcription is enabled. + /// Whether a custom model is being used. + public AudioInputTranscriptionSettings(AudioInputTranscriptionSettingsModel model, bool enabled, bool customModel) + { + Model = model; + Enabled = enabled; + CustomModel = customModel; + } + + /// Initializes a new instance of . + /// The model used for transcription. E.g., 'whisper-1', 'azure-fast-transcription', 's2s-ingraph'. + /// The language code to use for transcription, if specified. + /// Whether transcription is enabled. + /// Whether a custom model is being used. + /// Keeps track of any properties unknown to the library. + internal AudioInputTranscriptionSettings(AudioInputTranscriptionSettingsModel model, string language, bool enabled, bool customModel, IDictionary additionalBinaryDataProperties) + { + Model = model; + Language = language; + Enabled = enabled; + CustomModel = customModel; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The model used for transcription. E.g., 'whisper-1', 'azure-fast-transcription', 's2s-ingraph'. + public AudioInputTranscriptionSettingsModel Model { get; set; } + + /// The language code to use for transcription, if specified. + public string Language { get; set; } + + /// Whether transcription is enabled. + public bool Enabled { get; set; } + + /// Whether a custom model is being used. + public bool CustomModel { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettingsModel.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettingsModel.Serialization.cs new file mode 100644 index 000000000000..6ac7c9adf05d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettingsModel.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class AudioInputTranscriptionSettingsModelExtensions + { + /// The value to serialize. + public static string ToSerialString(this AudioInputTranscriptionSettingsModel value) => value switch + { + AudioInputTranscriptionSettingsModel.Whisper1 => "whisper-1", + AudioInputTranscriptionSettingsModel.AzureFastTranscription => "azure-fast-transcription", + AudioInputTranscriptionSettingsModel.S2sIngraph => "s2s-ingraph", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AudioInputTranscriptionSettingsModel value.") + }; + + /// The value to deserialize. + public static AudioInputTranscriptionSettingsModel ToAudioInputTranscriptionSettingsModel(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "whisper-1")) + { + return AudioInputTranscriptionSettingsModel.Whisper1; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "azure-fast-transcription")) + { + return AudioInputTranscriptionSettingsModel.AzureFastTranscription; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "s2s-ingraph")) + { + return AudioInputTranscriptionSettingsModel.S2sIngraph; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AudioInputTranscriptionSettingsModel value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettingsModel.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettingsModel.cs new file mode 100644 index 000000000000..2f6c99eea0ed --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioInputTranscriptionSettingsModel.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum AudioInputTranscriptionSettingsModel + { + /// Whisper1. + Whisper1, + /// AzureFastTranscription. + AzureFastTranscription, + /// S2sIngraph. + S2sIngraph + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioNoiseReduction.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioNoiseReduction.Serialization.cs new file mode 100644 index 000000000000..5994c7efa998 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioNoiseReduction.Serialization.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for input audio noise reduction. + public partial class AudioNoiseReduction : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AudioNoiseReduction)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AudioNoiseReduction IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AudioNoiseReduction JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AudioNoiseReduction)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAudioNoiseReduction(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AudioNoiseReduction DeserializeAudioNoiseReduction(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AudioNoiseReduction(@type, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AudioNoiseReduction)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AudioNoiseReduction IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AudioNoiseReduction PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAudioNoiseReduction(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AudioNoiseReduction)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioNoiseReduction.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioNoiseReduction.cs new file mode 100644 index 000000000000..99edb1c44702 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioNoiseReduction.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for input audio noise reduction. + public partial class AudioNoiseReduction + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public AudioNoiseReduction() + { + } + + /// Initializes a new instance of . + /// The type of noise reduction model. + /// Keeps track of any properties unknown to the library. + internal AudioNoiseReduction(string @type, IDictionary additionalBinaryDataProperties) + { + Type = @type; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The type of noise reduction model. + public string Type { get; } = "azure_deep_noise_suppression"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioTimestampType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioTimestampType.cs new file mode 100644 index 000000000000..687eec23d0ad --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AudioTimestampType.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// Output timestamp types supported in audio response content. + public readonly partial struct AudioTimestampType : IEquatable + { + private readonly string _value; + /// Timestamps per word in the output audio. + private const string WordValue = "word"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public AudioTimestampType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Timestamps per word in the output audio. + public static AudioTimestampType Word { get; } = new AudioTimestampType(WordValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(AudioTimestampType left, AudioTimestampType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(AudioTimestampType left, AudioTimestampType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator AudioTimestampType(string value) => new AudioTimestampType(value); + + /// Converts a string to a . + /// The value. + public static implicit operator AudioTimestampType?(string value) => value == null ? null : new AudioTimestampType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is AudioTimestampType other && Equals(other); + + /// + public bool Equals(AudioTimestampType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AvatarConfig.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AvatarConfig.Serialization.cs new file mode 100644 index 000000000000..583e8c641c72 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AvatarConfig.Serialization.cs @@ -0,0 +1,207 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for avatar streaming and behavior during the session. + public partial class AvatarConfig : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal AvatarConfig() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AvatarConfig)} does not support writing '{format}' format."); + } + if (Optional.IsCollectionDefined(IceServers)) + { + writer.WritePropertyName("ice_servers"u8); + writer.WriteStartArray(); + foreach (IceServer item in IceServers) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + writer.WritePropertyName("character"u8); + writer.WriteStringValue(Character); + if (Optional.IsDefined(Style)) + { + writer.WritePropertyName("style"u8); + writer.WriteStringValue(Style); + } + writer.WritePropertyName("customized"u8); + writer.WriteBooleanValue(Customized); + if (Optional.IsDefined(Video)) + { + writer.WritePropertyName("video"u8); + writer.WriteObjectValue(Video, options); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AvatarConfig IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AvatarConfig JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AvatarConfig)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAvatarConfig(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AvatarConfig DeserializeAvatarConfig(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList iceServers = default; + string character = default; + string style = default; + bool customized = default; + VideoParams video = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("ice_servers"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(IceServer.DeserializeIceServer(item, options)); + } + iceServers = array; + continue; + } + if (prop.NameEquals("character"u8)) + { + character = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("style"u8)) + { + style = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("customized"u8)) + { + customized = prop.Value.GetBoolean(); + continue; + } + if (prop.NameEquals("video"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + video = VideoParams.DeserializeVideoParams(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AvatarConfig( + iceServers ?? new ChangeTrackingList(), + character, + style, + customized, + video, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AvatarConfig)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AvatarConfig IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AvatarConfig PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAvatarConfig(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AvatarConfig)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AvatarConfig.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AvatarConfig.cs new file mode 100644 index 000000000000..007b1f9d8b70 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AvatarConfig.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for avatar streaming and behavior during the session. + public partial class AvatarConfig + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The character name or ID used for the avatar. + /// Indicates whether the avatar is customized or not. + /// is null. + public AvatarConfig(string character, bool customized) + { + Argument.AssertNotNull(character, nameof(character)); + + IceServers = new ChangeTrackingList(); + Character = character; + Customized = customized; + } + + /// Initializes a new instance of . + /// Optional list of ICE servers to use for WebRTC connection establishment. + /// The character name or ID used for the avatar. + /// Optional avatar style, such as emotional tone or speaking style. + /// Indicates whether the avatar is customized or not. + /// Optional video configuration including resolution, bitrate, and codec. + /// Keeps track of any properties unknown to the library. + internal AvatarConfig(IList iceServers, string character, string style, bool customized, VideoParams video, IDictionary additionalBinaryDataProperties) + { + IceServers = iceServers; + Character = character; + Style = style; + Customized = customized; + Video = video; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Optional list of ICE servers to use for WebRTC connection establishment. + public IList IceServers { get; } + + /// The character name or ID used for the avatar. + public string Character { get; set; } + + /// Optional avatar style, such as emotional tone or speaking style. + public string Style { get; set; } + + /// Indicates whether the avatar is customized or not. + public bool Customized { get; set; } + + /// Optional video configuration including resolution, bitrate, and codec. + public VideoParams Video { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoice.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoice.Serialization.cs new file mode 100644 index 000000000000..69a830146479 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoice.Serialization.cs @@ -0,0 +1,232 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Voice configuration for Azure custom voice. + public partial class AzureCustomVoice : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal AzureCustomVoice() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzureCustomVoice)} does not support writing '{format}' format."); + } + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("endpoint_id"u8); + writer.WriteStringValue(EndpointId); + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToSerialString()); + if (Optional.IsDefined(Temperature)) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (Optional.IsDefined(CustomLexiconUri)) + { + writer.WritePropertyName("custom_lexicon_url"u8); + writer.WriteStringValue(CustomLexiconUri.AbsoluteUri); + } + if (Optional.IsCollectionDefined(PreferLocales)) + { + writer.WritePropertyName("prefer_locales"u8); + writer.WriteStartArray(); + foreach (string item in PreferLocales) + { + if (item == null) + { + writer.WriteNullValue(); + continue; + } + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AzureCustomVoice IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AzureCustomVoice JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzureCustomVoice)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAzureCustomVoice(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AzureCustomVoice DeserializeAzureCustomVoice(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string name = default; + string endpointId = default; + AzureCustomVoiceType @type = default; + float? temperature = default; + Uri customLexiconUri = default; + IList preferLocales = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("endpoint_id"u8)) + { + endpointId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString().ToAzureCustomVoiceType(); + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("custom_lexicon_url"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + customLexiconUri = new Uri(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("prefer_locales"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + if (item.ValueKind == JsonValueKind.Null) + { + array.Add(null); + } + else + { + array.Add(item.GetString()); + } + } + preferLocales = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AzureCustomVoice( + name, + endpointId, + @type, + temperature, + customLexiconUri, + preferLocales ?? new ChangeTrackingList(), + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AzureCustomVoice)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AzureCustomVoice IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AzureCustomVoice PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAzureCustomVoice(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AzureCustomVoice)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoice.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoice.cs new file mode 100644 index 000000000000..5dfea6d3a9f7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoice.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Voice configuration for Azure custom voice. + public partial class AzureCustomVoice + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// Name of the voice. + /// Custom endpoint ID. + /// Voice type identifier. + /// or is null. + public AzureCustomVoice(string name, string endpointId, AzureCustomVoiceType @type) + { + Argument.AssertNotNull(name, nameof(name)); + Argument.AssertNotNull(endpointId, nameof(endpointId)); + + Name = name; + EndpointId = endpointId; + Type = @type; + PreferLocales = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// Name of the voice. + /// Custom endpoint ID. + /// Voice type identifier. + /// Optional temperature for generation. + /// Optional custom lexicon URL. + /// Preferred locale list for voice rendering. + /// Keeps track of any properties unknown to the library. + internal AzureCustomVoice(string name, string endpointId, AzureCustomVoiceType @type, float? temperature, Uri customLexiconUri, IList preferLocales, IDictionary additionalBinaryDataProperties) + { + Name = name; + EndpointId = endpointId; + Type = @type; + Temperature = temperature; + CustomLexiconUri = customLexiconUri; + PreferLocales = preferLocales; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Name of the voice. + public string Name { get; set; } + + /// Custom endpoint ID. + public string EndpointId { get; set; } + + /// Voice type identifier. + public AzureCustomVoiceType Type { get; set; } + + /// Optional temperature for generation. + public float? Temperature { get; set; } + + /// Optional custom lexicon URL. + public Uri CustomLexiconUri { get; set; } + + /// Preferred locale list for voice rendering. + public IList PreferLocales { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoiceType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoiceType.Serialization.cs new file mode 100644 index 000000000000..10a3606d4320 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoiceType.Serialization.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class AzureCustomVoiceTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this AzureCustomVoiceType value) => value switch + { + AzureCustomVoiceType.AzureCustom => "azure-custom", + AzureCustomVoiceType.Custom => "custom", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzureCustomVoiceType value.") + }; + + /// The value to deserialize. + public static AzureCustomVoiceType ToAzureCustomVoiceType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "azure-custom")) + { + return AzureCustomVoiceType.AzureCustom; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "custom")) + { + return AzureCustomVoiceType.Custom; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzureCustomVoiceType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoiceType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoiceType.cs new file mode 100644 index 000000000000..f517dbcb1dfc --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureCustomVoiceType.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum AzureCustomVoiceType + { + /// AzureCustom. + AzureCustom, + /// Custom. + Custom + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoice.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoice.Serialization.cs new file mode 100644 index 000000000000..b37f93272b12 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoice.Serialization.cs @@ -0,0 +1,158 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Voice configuration for Azure personal voice. + public partial class AzurePersonalVoice : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal AzurePersonalVoice() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzurePersonalVoice)} does not support writing '{format}' format."); + } + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToSerialString()); + writer.WritePropertyName("model"u8); + writer.WriteStringValue(Model.ToSerialString()); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AzurePersonalVoice IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AzurePersonalVoice JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzurePersonalVoice)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAzurePersonalVoice(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AzurePersonalVoice DeserializeAzurePersonalVoice(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string name = default; + AzurePersonalVoiceType @type = default; + AzurePersonalVoiceModel model = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString().ToAzurePersonalVoiceType(); + continue; + } + if (prop.NameEquals("model"u8)) + { + model = prop.Value.GetString().ToAzurePersonalVoiceModel(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AzurePersonalVoice(name, @type, model, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AzurePersonalVoice)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AzurePersonalVoice IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AzurePersonalVoice PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAzurePersonalVoice(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AzurePersonalVoice)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoice.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoice.cs new file mode 100644 index 000000000000..6a1791e76886 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoice.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Voice configuration for Azure personal voice. + public partial class AzurePersonalVoice + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// Name of the voice. + /// Voice type identifier. + /// Personal voice model identifier. + /// is null. + public AzurePersonalVoice(string name, AzurePersonalVoiceType @type, AzurePersonalVoiceModel model) + { + Argument.AssertNotNull(name, nameof(name)); + + Name = name; + Type = @type; + Model = model; + } + + /// Initializes a new instance of . + /// Name of the voice. + /// Voice type identifier. + /// Personal voice model identifier. + /// Keeps track of any properties unknown to the library. + internal AzurePersonalVoice(string name, AzurePersonalVoiceType @type, AzurePersonalVoiceModel model, IDictionary additionalBinaryDataProperties) + { + Name = name; + Type = @type; + Model = model; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Name of the voice. + public string Name { get; set; } + + /// Voice type identifier. + public AzurePersonalVoiceType Type { get; set; } + + /// Personal voice model identifier. + public AzurePersonalVoiceModel Model { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceModel.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceModel.Serialization.cs new file mode 100644 index 000000000000..139bd52ce965 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceModel.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class AzurePersonalVoiceModelExtensions + { + /// The value to serialize. + public static string ToSerialString(this AzurePersonalVoiceModel value) => value switch + { + AzurePersonalVoiceModel.DragonLatestNeural => "DragonLatestNeural", + AzurePersonalVoiceModel.PhoenixLatestNeural => "PhoenixLatestNeural", + AzurePersonalVoiceModel.PhoenixV2Neural => "PhoenixV2Neural", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzurePersonalVoiceModel value.") + }; + + /// The value to deserialize. + public static AzurePersonalVoiceModel ToAzurePersonalVoiceModel(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "DragonLatestNeural")) + { + return AzurePersonalVoiceModel.DragonLatestNeural; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "PhoenixLatestNeural")) + { + return AzurePersonalVoiceModel.PhoenixLatestNeural; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "PhoenixV2Neural")) + { + return AzurePersonalVoiceModel.PhoenixV2Neural; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzurePersonalVoiceModel value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceModel.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceModel.cs new file mode 100644 index 000000000000..3a22b4501abe --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceModel.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum AzurePersonalVoiceModel + { + /// DragonLatestNeural. + DragonLatestNeural, + /// PhoenixLatestNeural. + PhoenixLatestNeural, + /// PhoenixV2Neural. + PhoenixV2Neural + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceType.Serialization.cs new file mode 100644 index 000000000000..4df691ea8917 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceType.Serialization.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class AzurePersonalVoiceTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this AzurePersonalVoiceType value) => value switch + { + AzurePersonalVoiceType.AzurePersonal => "azure-personal", + AzurePersonalVoiceType.Personal => "personal", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzurePersonalVoiceType value.") + }; + + /// The value to deserialize. + public static AzurePersonalVoiceType ToAzurePersonalVoiceType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "azure-personal")) + { + return AzurePersonalVoiceType.AzurePersonal; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "personal")) + { + return AzurePersonalVoiceType.Personal; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzurePersonalVoiceType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceType.cs new file mode 100644 index 000000000000..e9670cdb56a0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzurePersonalVoiceType.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum AzurePersonalVoiceType + { + /// AzurePersonal. + AzurePersonal, + /// Personal. + Personal + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureSemanticVad.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureSemanticVad.Serialization.cs new file mode 100644 index 000000000000..b3544416d356 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureSemanticVad.Serialization.cs @@ -0,0 +1,203 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Semantic VAD settings based on Azure SDK features. + public partial class AzureSemanticVad : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzureSemanticVad)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(NegThreshold)) + { + writer.WritePropertyName("neg_threshold"u8); + writer.WriteNumberValue(NegThreshold.Value); + } + if (Optional.IsDefined(WindowSize)) + { + writer.WritePropertyName("window_size"u8); + writer.WriteNumberValue(WindowSize.Value); + } + if (Optional.IsDefined(DistinctCiPhones)) + { + writer.WritePropertyName("distinct_ci_phones"u8); + writer.WriteNumberValue(DistinctCiPhones.Value); + } + if (Optional.IsDefined(RequireVowel)) + { + writer.WritePropertyName("require_vowel"u8); + writer.WriteBooleanValue(RequireVowel.Value); + } + if (Optional.IsDefined(RemoveFillerWords)) + { + writer.WritePropertyName("remove_filler_words"u8); + writer.WriteBooleanValue(RemoveFillerWords.Value); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AzureSemanticVad IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (AzureSemanticVad)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override TurnDetection JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzureSemanticVad)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAzureSemanticVad(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AzureSemanticVad DeserializeAzureSemanticVad(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + TurnDetectionType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + float? negThreshold = default; + int? windowSize = default; + int? distinctCiPhones = default; + bool? requireVowel = default; + bool? removeFillerWords = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString().ToTurnDetectionType(); + continue; + } + if (prop.NameEquals("neg_threshold"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + negThreshold = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("window_size"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + windowSize = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("distinct_ci_phones"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + distinctCiPhones = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("require_vowel"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + requireVowel = prop.Value.GetBoolean(); + continue; + } + if (prop.NameEquals("remove_filler_words"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + removeFillerWords = prop.Value.GetBoolean(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AzureSemanticVad( + @type, + additionalBinaryDataProperties, + negThreshold, + windowSize, + distinctCiPhones, + requireVowel, + removeFillerWords); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AzureSemanticVad)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AzureSemanticVad IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (AzureSemanticVad)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override TurnDetection PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAzureSemanticVad(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AzureSemanticVad)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureSemanticVad.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureSemanticVad.cs new file mode 100644 index 000000000000..5180e0451adc --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureSemanticVad.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Semantic VAD settings based on Azure SDK features. + public partial class AzureSemanticVad : TurnDetection + { + /// Initializes a new instance of . + public AzureSemanticVad() : base(TurnDetectionType.AzureSemanticVad) + { + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + /// + internal AzureSemanticVad(TurnDetectionType @type, IDictionary additionalBinaryDataProperties, float? negThreshold, int? windowSize, int? distinctCiPhones, bool? requireVowel, bool? removeFillerWords) : base(@type, additionalBinaryDataProperties) + { + NegThreshold = negThreshold; + WindowSize = windowSize; + DistinctCiPhones = distinctCiPhones; + RequireVowel = requireVowel; + RemoveFillerWords = removeFillerWords; + } + + /// Gets or sets the NegThreshold. + public float? NegThreshold { get; set; } + + /// Gets or sets the WindowSize. + public int? WindowSize { get; set; } + + /// Gets or sets the DistinctCiPhones. + public int? DistinctCiPhones { get; set; } + + /// Gets or sets the RequireVowel. + public bool? RequireVowel { get; set; } + + /// Gets or sets the RemoveFillerWords. + public bool? RemoveFillerWords { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoice.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoice.Serialization.cs new file mode 100644 index 000000000000..c859afc2a0d2 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoice.Serialization.cs @@ -0,0 +1,165 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Voice configuration for Azure standard or platform voices. + public partial class AzureStandardVoice : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal AzureStandardVoice() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzureStandardVoice)} does not support writing '{format}' format."); + } + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToSerialString()); + if (Optional.IsDefined(Temperature)) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + AzureStandardVoice IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual AzureStandardVoice JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(AzureStandardVoice)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeAzureStandardVoice(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static AzureStandardVoice DeserializeAzureStandardVoice(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string name = default; + AzureStandardVoiceType @type = default; + float? temperature = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString().ToAzureStandardVoiceType(); + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new AzureStandardVoice(name, @type, temperature, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(AzureStandardVoice)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + AzureStandardVoice IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual AzureStandardVoice PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeAzureStandardVoice(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(AzureStandardVoice)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoice.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoice.cs new file mode 100644 index 000000000000..8da27040ed07 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoice.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Voice configuration for Azure standard or platform voices. + public partial class AzureStandardVoice + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// Name of the voice. + /// Voice type identifier. + /// is null. + public AzureStandardVoice(string name, AzureStandardVoiceType @type) + { + Argument.AssertNotNull(name, nameof(name)); + + Name = name; + Type = @type; + } + + /// Initializes a new instance of . + /// Name of the voice. + /// Voice type identifier. + /// Optional temperature for generation. + /// Keeps track of any properties unknown to the library. + internal AzureStandardVoice(string name, AzureStandardVoiceType @type, float? temperature, IDictionary additionalBinaryDataProperties) + { + Name = name; + Type = @type; + Temperature = temperature; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Name of the voice. + public string Name { get; set; } + + /// Voice type identifier. + public AzureStandardVoiceType Type { get; set; } + + /// Optional temperature for generation. + public float? Temperature { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoiceType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoiceType.Serialization.cs new file mode 100644 index 000000000000..96a1d07aa3c7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoiceType.Serialization.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class AzureStandardVoiceTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this AzureStandardVoiceType value) => value switch + { + AzureStandardVoiceType.AzureStandard => "azure-standard", + AzureStandardVoiceType.AzurePlatform => "azure-platform", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzureStandardVoiceType value.") + }; + + /// The value to deserialize. + public static AzureStandardVoiceType ToAzureStandardVoiceType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "azure-standard")) + { + return AzureStandardVoiceType.AzureStandard; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "azure-platform")) + { + return AzureStandardVoiceType.AzurePlatform; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown AzureStandardVoiceType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoiceType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoiceType.cs new file mode 100644 index 000000000000..a9832ae23a1c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/AzureStandardVoiceType.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum AzureStandardVoiceType + { + /// AzureStandard. + AzureStandard, + /// AzurePlatform. + AzurePlatform + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEvent.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEvent.Serialization.cs new file mode 100644 index 000000000000..96c7c20d960b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEvent.Serialization.cs @@ -0,0 +1,170 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + [PersistableModelProxy(typeof(UnknownClientEvent))] + internal abstract partial class ClientEvent : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEvent() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEvent)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEvent IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEvent)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEvent(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEvent DeserializeClientEvent(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "session.update": + return ClientEventSessionUpdate.DeserializeClientEventSessionUpdate(element, options); + case "input_audio_buffer.append": + return ClientEventInputAudioBufferAppend.DeserializeClientEventInputAudioBufferAppend(element, options); + case "input_audio_buffer.commit": + return ClientEventInputAudioBufferCommit.DeserializeClientEventInputAudioBufferCommit(element, options); + case "input_audio_buffer.clear": + return ClientEventInputAudioBufferClear.DeserializeClientEventInputAudioBufferClear(element, options); + case "input_audio.turn.start": + return ClientEventInputAudioTurnStart.DeserializeClientEventInputAudioTurnStart(element, options); + case "input_audio.turn.append": + return ClientEventInputAudioTurnAppend.DeserializeClientEventInputAudioTurnAppend(element, options); + case "input_audio.turn.end": + return ClientEventInputAudioTurnEnd.DeserializeClientEventInputAudioTurnEnd(element, options); + case "input_audio.turn.cancel": + return ClientEventInputAudioTurnCancel.DeserializeClientEventInputAudioTurnCancel(element, options); + case "input_audio.clear": + return ClientEventInputAudioClear.DeserializeClientEventInputAudioClear(element, options); + case "conversation.item.create": + return ClientEventConversationItemCreate.DeserializeClientEventConversationItemCreate(element, options); + case "conversation.item.retrieve": + return ClientEventConversationItemRetrieve.DeserializeClientEventConversationItemRetrieve(element, options); + case "conversation.item.truncate": + return ClientEventConversationItemTruncate.DeserializeClientEventConversationItemTruncate(element, options); + case "conversation.item.delete": + return ClientEventConversationItemDelete.DeserializeClientEventConversationItemDelete(element, options); + case "response.create": + return ClientEventResponseCreate.DeserializeClientEventResponseCreate(element, options); + case "response.cancel": + return ClientEventResponseCancel.DeserializeClientEventResponseCancel(element, options); + case "session.avatar.connect": + return ClientEventSessionAvatarConnect.DeserializeClientEventSessionAvatarConnect(element, options); + } + } + return UnknownClientEvent.DeserializeUnknownClientEvent(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEvent)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEvent IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEvent(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEvent)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEvent.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEvent.cs new file mode 100644 index 000000000000..7fb0ee644f82 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEvent.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal abstract partial class ClientEvent + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The type of event. + private protected ClientEvent(ClientEventType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal ClientEvent(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties) + { + Type = @type; + EventId = eventId; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The type of event. + internal ClientEventType Type { get; set; } + + /// Gets or sets the EventId. + public virtual string EventId { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemCreate.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemCreate.Serialization.cs new file mode 100644 index 000000000000..5819104ac558 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemCreate.Serialization.cs @@ -0,0 +1,157 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemCreate : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemCreate)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + if (Optional.IsDefined(PreviousItemId)) + { + writer.WritePropertyName("previous_item_id"u8); + writer.WriteStringValue(PreviousItemId); + } + if (Optional.IsDefined(Item)) + { + writer.WritePropertyName("item"u8); + writer.WriteObjectValue(Item, options); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventConversationItemCreate IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventConversationItemCreate)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemCreate)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventConversationItemCreate(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventConversationItemCreate DeserializeClientEventConversationItemCreate(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string eventId = default; + string previousItemId = default; + ConversationItemWithReference item = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("previous_item_id"u8)) + { + previousItemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + item = ConversationItemWithReference.DeserializeConversationItemWithReference(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventConversationItemCreate(@type, additionalBinaryDataProperties, eventId, previousItemId, item); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemCreate)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventConversationItemCreate IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventConversationItemCreate)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventConversationItemCreate(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemCreate)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemCreate.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemCreate.cs new file mode 100644 index 000000000000..97d8dcbfea40 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemCreate.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemCreate : ClientEvent + { + /// Initializes a new instance of . + public ClientEventConversationItemCreate() : base(ClientEventType.ConversationItemCreate) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// Keeps track of any properties unknown to the library. + /// Optional client-generated ID used to identify this event. + /// + /// The ID of the preceding item after which the new item will be inserted. + /// If not set, the new item will be appended to the end of the conversation. + /// If set to `root`, the new item will be added to the beginning of the conversation. + /// If set to an existing ID, it allows an item to be inserted mid-conversation. If the + /// ID cannot be found, an error will be returned and the item will not be added. + /// + /// + internal ClientEventConversationItemCreate(ClientEventType @type, IDictionary additionalBinaryDataProperties, string eventId, string previousItemId, ConversationItemWithReference item) : base(@type, eventId, additionalBinaryDataProperties) + { + PreviousItemId = previousItemId; + Item = item; + } + + /// Optional client-generated ID used to identify this event. + public override string EventId { get; set; } + + /// + /// The ID of the preceding item after which the new item will be inserted. + /// If not set, the new item will be appended to the end of the conversation. + /// If set to `root`, the new item will be added to the beginning of the conversation. + /// If set to an existing ID, it allows an item to be inserted mid-conversation. If the + /// ID cannot be found, an error will be returned and the item will not be added. + /// + public string PreviousItemId { get; set; } + + /// Gets or sets the Item. + public ConversationItemWithReference Item { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemDelete.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemDelete.Serialization.cs new file mode 100644 index 000000000000..5393dc978b0f --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemDelete.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemDelete : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventConversationItemDelete() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemDelete)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventConversationItemDelete IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventConversationItemDelete)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemDelete)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventConversationItemDelete(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventConversationItemDelete DeserializeClientEventConversationItemDelete(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventConversationItemDelete(@type, eventId, additionalBinaryDataProperties, itemId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemDelete)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventConversationItemDelete IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventConversationItemDelete)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventConversationItemDelete(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemDelete)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemDelete.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemDelete.cs new file mode 100644 index 000000000000..c3aa2182be9a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemDelete.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemDelete : ClientEvent + { + /// Initializes a new instance of . + /// The ID of the item to delete. + /// is null. + public ClientEventConversationItemDelete(string itemId) : base(ClientEventType.ConversationItemDelete) + { + Argument.AssertNotNull(itemId, nameof(itemId)); + + ItemId = itemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the item to delete. + internal ClientEventConversationItemDelete(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string itemId) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + } + + /// The ID of the item to delete. + public string ItemId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemRetrieve.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemRetrieve.Serialization.cs new file mode 100644 index 000000000000..bb33973e875a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemRetrieve.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemRetrieve : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventConversationItemRetrieve() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemRetrieve)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventConversationItemRetrieve IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventConversationItemRetrieve)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemRetrieve)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventConversationItemRetrieve(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventConversationItemRetrieve DeserializeClientEventConversationItemRetrieve(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventConversationItemRetrieve(@type, eventId, additionalBinaryDataProperties, itemId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemRetrieve)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventConversationItemRetrieve IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventConversationItemRetrieve)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventConversationItemRetrieve(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemRetrieve)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemRetrieve.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemRetrieve.cs new file mode 100644 index 000000000000..1713957901db --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemRetrieve.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemRetrieve : ClientEvent + { + /// Initializes a new instance of . + /// The ID of the item to retrieve. + /// is null. + public ClientEventConversationItemRetrieve(string itemId) : base(ClientEventType.ConversationItemRetrieve) + { + Argument.AssertNotNull(itemId, nameof(itemId)); + + ItemId = itemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the item to retrieve. + internal ClientEventConversationItemRetrieve(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string itemId) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + } + + /// The ID of the item to retrieve. + public string ItemId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemTruncate.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemTruncate.Serialization.cs new file mode 100644 index 000000000000..f4c8d98d7816 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemTruncate.Serialization.cs @@ -0,0 +1,161 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemTruncate : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventConversationItemTruncate() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemTruncate)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("audio_end_ms"u8); + writer.WriteNumberValue(AudioEndMs); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventConversationItemTruncate IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventConversationItemTruncate)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventConversationItemTruncate)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventConversationItemTruncate(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventConversationItemTruncate DeserializeClientEventConversationItemTruncate(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + int contentIndex = default; + int audioEndMs = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_end_ms"u8)) + { + audioEndMs = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventConversationItemTruncate( + @type, + eventId, + additionalBinaryDataProperties, + itemId, + contentIndex, + audioEndMs); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemTruncate)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventConversationItemTruncate IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventConversationItemTruncate)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventConversationItemTruncate(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventConversationItemTruncate)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemTruncate.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemTruncate.cs new file mode 100644 index 000000000000..0190a9c0826d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventConversationItemTruncate.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventConversationItemTruncate : ClientEvent + { + /// Initializes a new instance of . + /// + /// The ID of the assistant message item to truncate. Only assistant message + /// items can be truncated. + /// + /// The index of the content part to truncate. Set this to 0. + /// + /// Inclusive duration up to which audio is truncated, in milliseconds. If + /// the audio_end_ms is greater than the actual audio duration, the server + /// will respond with an error. + /// + /// is null. + public ClientEventConversationItemTruncate(string itemId, int contentIndex, int audioEndMs) : base(ClientEventType.ConversationItemTruncate) + { + Argument.AssertNotNull(itemId, nameof(itemId)); + + ItemId = itemId; + ContentIndex = contentIndex; + AudioEndMs = audioEndMs; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// The ID of the assistant message item to truncate. Only assistant message + /// items can be truncated. + /// + /// The index of the content part to truncate. Set this to 0. + /// + /// Inclusive duration up to which audio is truncated, in milliseconds. If + /// the audio_end_ms is greater than the actual audio duration, the server + /// will respond with an error. + /// + internal ClientEventConversationItemTruncate(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string itemId, int contentIndex, int audioEndMs) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + ContentIndex = contentIndex; + AudioEndMs = audioEndMs; + } + + /// + /// The ID of the assistant message item to truncate. Only assistant message + /// items can be truncated. + /// + public string ItemId { get; } + + /// The index of the content part to truncate. Set this to 0. + public int ContentIndex { get; } + + /// + /// Inclusive duration up to which audio is truncated, in milliseconds. If + /// the audio_end_ms is greater than the actual audio duration, the server + /// will respond with an error. + /// + public int AudioEndMs { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferAppend.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferAppend.Serialization.cs new file mode 100644 index 000000000000..1dc209c0659b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferAppend.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioBufferAppend : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventInputAudioBufferAppend() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferAppend)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("audio"u8); + writer.WriteStringValue(Audio); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioBufferAppend IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioBufferAppend)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferAppend)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioBufferAppend(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioBufferAppend DeserializeClientEventInputAudioBufferAppend(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string audio = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("audio"u8)) + { + audio = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioBufferAppend(@type, eventId, additionalBinaryDataProperties, audio); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferAppend)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioBufferAppend IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioBufferAppend)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioBufferAppend(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferAppend)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferAppend.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferAppend.cs new file mode 100644 index 000000000000..fe17780dacb6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferAppend.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioBufferAppend : ClientEvent + { + /// Initializes a new instance of . + /// + /// Base64-encoded audio. This must be in the format specified by the + /// `input_audio_format` field in the session configuration. + /// + /// is null. + public ClientEventInputAudioBufferAppend(string audio) : base(ClientEventType.InputAudioBufferAppend) + { + Argument.AssertNotNull(audio, nameof(audio)); + + Audio = audio; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// Base64-encoded audio. This must be in the format specified by the + /// `input_audio_format` field in the session configuration. + /// + internal ClientEventInputAudioBufferAppend(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string audio) : base(@type, eventId, additionalBinaryDataProperties) + { + Audio = audio; + } + + /// + /// Base64-encoded audio. This must be in the format specified by the + /// `input_audio_format` field in the session configuration. + /// + public string Audio { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferClear.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferClear.Serialization.cs new file mode 100644 index 000000000000..455c3bea1267 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferClear.Serialization.cs @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioBufferClear : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferClear)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioBufferClear IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioBufferClear)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferClear)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioBufferClear(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioBufferClear DeserializeClientEventInputAudioBufferClear(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioBufferClear(@type, eventId, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferClear)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioBufferClear IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioBufferClear)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioBufferClear(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferClear)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferClear.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferClear.cs new file mode 100644 index 000000000000..3f225c9f929c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferClear.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioBufferClear : ClientEvent + { + /// Initializes a new instance of . + public ClientEventInputAudioBufferClear() : base(ClientEventType.InputAudioBufferClear) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal ClientEventInputAudioBufferClear(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties) : base(@type, eventId, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferCommit.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferCommit.Serialization.cs new file mode 100644 index 000000000000..b585048c4c39 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferCommit.Serialization.cs @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioBufferCommit : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferCommit)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioBufferCommit IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioBufferCommit)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferCommit)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioBufferCommit(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioBufferCommit DeserializeClientEventInputAudioBufferCommit(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioBufferCommit(@type, eventId, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferCommit)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioBufferCommit IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioBufferCommit)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioBufferCommit(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioBufferCommit)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferCommit.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferCommit.cs new file mode 100644 index 000000000000..d31a8d048e5a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioBufferCommit.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioBufferCommit : ClientEvent + { + /// Initializes a new instance of . + public ClientEventInputAudioBufferCommit() : base(ClientEventType.InputAudioBufferCommit) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal ClientEventInputAudioBufferCommit(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties) : base(@type, eventId, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioClear.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioClear.Serialization.cs new file mode 100644 index 000000000000..3ce42daa6d58 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioClear.Serialization.cs @@ -0,0 +1,126 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioClear : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioClear)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioClear IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioClear)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioClear)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioClear(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioClear DeserializeClientEventInputAudioClear(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioClear(@type, eventId, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioClear)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioClear IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioClear)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioClear(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioClear)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioClear.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioClear.cs new file mode 100644 index 000000000000..9604f380c021 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioClear.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioClear : ClientEvent + { + /// Initializes a new instance of . + public ClientEventInputAudioClear() : base(ClientEventType.InputAudioClear) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal ClientEventInputAudioClear(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties) : base(@type, eventId, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnAppend.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnAppend.Serialization.cs new file mode 100644 index 000000000000..ccf4aa88edc4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnAppend.Serialization.cs @@ -0,0 +1,147 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnAppend : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventInputAudioTurnAppend() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnAppend)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("turn_id"u8); + writer.WriteStringValue(TurnId); + writer.WritePropertyName("audio"u8); + writer.WriteStringValue(Audio); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioTurnAppend IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnAppend)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnAppend)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioTurnAppend(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioTurnAppend DeserializeClientEventInputAudioTurnAppend(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string turnId = default; + string audio = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("turn_id"u8)) + { + turnId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("audio"u8)) + { + audio = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioTurnAppend(@type, eventId, additionalBinaryDataProperties, turnId, audio); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnAppend)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioTurnAppend IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnAppend)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioTurnAppend(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnAppend)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnAppend.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnAppend.cs new file mode 100644 index 000000000000..3bd3d3b16476 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnAppend.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnAppend : ClientEvent + { + /// Initializes a new instance of . + /// The ID of the turn this audio is part of. + /// Base64-encoded audio chunk. + /// or is null. + public ClientEventInputAudioTurnAppend(string turnId, string audio) : base(ClientEventType.InputAudioTurnAppend) + { + Argument.AssertNotNull(turnId, nameof(turnId)); + Argument.AssertNotNull(audio, nameof(audio)); + + TurnId = turnId; + Audio = audio; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the turn this audio is part of. + /// Base64-encoded audio chunk. + internal ClientEventInputAudioTurnAppend(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string turnId, string audio) : base(@type, eventId, additionalBinaryDataProperties) + { + TurnId = turnId; + Audio = audio; + } + + /// The ID of the turn this audio is part of. + public string TurnId { get; } + + /// Base64-encoded audio chunk. + public string Audio { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnCancel.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnCancel.Serialization.cs new file mode 100644 index 000000000000..61c95d683ff6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnCancel.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnCancel : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventInputAudioTurnCancel() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnCancel)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("turn_id"u8); + writer.WriteStringValue(TurnId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioTurnCancel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnCancel)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnCancel)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioTurnCancel(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioTurnCancel DeserializeClientEventInputAudioTurnCancel(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string turnId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("turn_id"u8)) + { + turnId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioTurnCancel(@type, eventId, additionalBinaryDataProperties, turnId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnCancel)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioTurnCancel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnCancel)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioTurnCancel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnCancel)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnCancel.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnCancel.cs new file mode 100644 index 000000000000..e6d18e538bf1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnCancel.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnCancel : ClientEvent + { + /// Initializes a new instance of . + /// The ID of the turn to cancel. + /// is null. + public ClientEventInputAudioTurnCancel(string turnId) : base(ClientEventType.InputAudioTurnCancel) + { + Argument.AssertNotNull(turnId, nameof(turnId)); + + TurnId = turnId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the turn to cancel. + internal ClientEventInputAudioTurnCancel(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string turnId) : base(@type, eventId, additionalBinaryDataProperties) + { + TurnId = turnId; + } + + /// The ID of the turn to cancel. + public string TurnId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnEnd.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnEnd.Serialization.cs new file mode 100644 index 000000000000..2aa2c4bbb444 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnEnd.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnEnd : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventInputAudioTurnEnd() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnEnd)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("turn_id"u8); + writer.WriteStringValue(TurnId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioTurnEnd IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnEnd)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnEnd)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioTurnEnd(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioTurnEnd DeserializeClientEventInputAudioTurnEnd(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string turnId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("turn_id"u8)) + { + turnId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioTurnEnd(@type, eventId, additionalBinaryDataProperties, turnId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnEnd)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioTurnEnd IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnEnd)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioTurnEnd(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnEnd)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnEnd.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnEnd.cs new file mode 100644 index 000000000000..a72ae31a04a5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnEnd.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnEnd : ClientEvent + { + /// Initializes a new instance of . + /// The ID of the audio turn being ended. + /// is null. + public ClientEventInputAudioTurnEnd(string turnId) : base(ClientEventType.InputAudioTurnEnd) + { + Argument.AssertNotNull(turnId, nameof(turnId)); + + TurnId = turnId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the audio turn being ended. + internal ClientEventInputAudioTurnEnd(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string turnId) : base(@type, eventId, additionalBinaryDataProperties) + { + TurnId = turnId; + } + + /// The ID of the audio turn being ended. + public string TurnId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnStart.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnStart.Serialization.cs new file mode 100644 index 000000000000..8d909bfdcb02 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnStart.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnStart : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventInputAudioTurnStart() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnStart)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("turn_id"u8); + writer.WriteStringValue(TurnId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventInputAudioTurnStart IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnStart)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnStart)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventInputAudioTurnStart(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventInputAudioTurnStart DeserializeClientEventInputAudioTurnStart(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string turnId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("turn_id"u8)) + { + turnId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventInputAudioTurnStart(@type, eventId, additionalBinaryDataProperties, turnId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnStart)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventInputAudioTurnStart IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventInputAudioTurnStart)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventInputAudioTurnStart(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventInputAudioTurnStart)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnStart.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnStart.cs new file mode 100644 index 000000000000..6c7fb54565ae --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventInputAudioTurnStart.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventInputAudioTurnStart : ClientEvent + { + /// Initializes a new instance of . + /// Unique identifier for the input audio turn. + /// is null. + public ClientEventInputAudioTurnStart(string turnId) : base(ClientEventType.InputAudioTurnStart) + { + Argument.AssertNotNull(turnId, nameof(turnId)); + + TurnId = turnId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// Unique identifier for the input audio turn. + internal ClientEventInputAudioTurnStart(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string turnId) : base(@type, eventId, additionalBinaryDataProperties) + { + TurnId = turnId; + } + + /// Unique identifier for the input audio turn. + public string TurnId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCancel.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCancel.Serialization.cs new file mode 100644 index 000000000000..635cec5a406c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCancel.Serialization.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventResponseCancel : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventResponseCancel)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(ResponseId)) + { + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventResponseCancel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventResponseCancel)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventResponseCancel)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventResponseCancel(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventResponseCancel DeserializeClientEventResponseCancel(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventResponseCancel(@type, eventId, additionalBinaryDataProperties, responseId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventResponseCancel)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventResponseCancel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventResponseCancel)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventResponseCancel(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventResponseCancel)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCancel.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCancel.cs new file mode 100644 index 000000000000..116fc5fe9abc --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCancel.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventResponseCancel : ClientEvent + { + /// Initializes a new instance of . + public ClientEventResponseCancel() : base(ClientEventType.ResponseCancel) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// A specific response ID to cancel - if not provided, will cancel an + /// in-progress response in the default conversation. + /// + internal ClientEventResponseCancel(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + } + + /// + /// A specific response ID to cancel - if not provided, will cancel an + /// in-progress response in the default conversation. + /// + public string ResponseId { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCreate.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCreate.Serialization.cs new file mode 100644 index 000000000000..1aa8b69f8120 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCreate.Serialization.cs @@ -0,0 +1,152 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventResponseCreate : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventResponseCreate)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(Response)) + { + writer.WritePropertyName("response"u8); + writer.WriteObjectValue(Response, options); + } + if (Optional.IsDefined(AdditionalInstructions)) + { + writer.WritePropertyName("additional_instructions"u8); + writer.WriteStringValue(AdditionalInstructions); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventResponseCreate IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventResponseCreate)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventResponseCreate)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventResponseCreate(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventResponseCreate DeserializeClientEventResponseCreate(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + ResponseCreateParams response = default; + string additionalInstructions = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + response = ResponseCreateParams.DeserializeResponseCreateParams(prop.Value, options); + continue; + } + if (prop.NameEquals("additional_instructions"u8)) + { + additionalInstructions = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventResponseCreate(@type, eventId, additionalBinaryDataProperties, response, additionalInstructions); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventResponseCreate)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventResponseCreate IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventResponseCreate)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventResponseCreate(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventResponseCreate)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCreate.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCreate.cs new file mode 100644 index 000000000000..d0e6327f6eab --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventResponseCreate.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventResponseCreate : ClientEvent + { + /// Initializes a new instance of . + public ClientEventResponseCreate() : base(ClientEventType.ResponseCreate) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// additional instructions (system prompt) appended to the default instructions of the session. Only affects this response only. + internal ClientEventResponseCreate(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, ResponseCreateParams response, string additionalInstructions) : base(@type, eventId, additionalBinaryDataProperties) + { + Response = response; + AdditionalInstructions = additionalInstructions; + } + + /// Gets or sets the Response. + public ResponseCreateParams Response { get; set; } + + /// additional instructions (system prompt) appended to the default instructions of the session. Only affects this response only. + public string AdditionalInstructions { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionAvatarConnect.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionAvatarConnect.Serialization.cs new file mode 100644 index 000000000000..9496abb78120 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionAvatarConnect.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventSessionAvatarConnect : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventSessionAvatarConnect() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventSessionAvatarConnect)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("client_sdp"u8); + writer.WriteStringValue(ClientSdp); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventSessionAvatarConnect IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventSessionAvatarConnect)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventSessionAvatarConnect)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventSessionAvatarConnect(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventSessionAvatarConnect DeserializeClientEventSessionAvatarConnect(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string clientSdp = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("client_sdp"u8)) + { + clientSdp = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventSessionAvatarConnect(@type, eventId, additionalBinaryDataProperties, clientSdp); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventSessionAvatarConnect)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventSessionAvatarConnect IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventSessionAvatarConnect)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventSessionAvatarConnect(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventSessionAvatarConnect)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionAvatarConnect.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionAvatarConnect.cs new file mode 100644 index 000000000000..cd154bc3f47d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionAvatarConnect.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventSessionAvatarConnect : ClientEvent + { + /// Initializes a new instance of . + /// The client's SDP offer. + /// is null. + public ClientEventSessionAvatarConnect(string clientSdp) : base(ClientEventType.SessionAvatarConnect) + { + Argument.AssertNotNull(clientSdp, nameof(clientSdp)); + + ClientSdp = clientSdp; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The client's SDP offer. + internal ClientEventSessionAvatarConnect(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string clientSdp) : base(@type, eventId, additionalBinaryDataProperties) + { + ClientSdp = clientSdp; + } + + /// The client's SDP offer. + public string ClientSdp { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionUpdate.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionUpdate.Serialization.cs new file mode 100644 index 000000000000..9e95841be096 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionUpdate.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventSessionUpdate : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ClientEventSessionUpdate() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventSessionUpdate)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("session"u8); + writer.WriteObjectValue(Session, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEventSessionUpdate IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ClientEventSessionUpdate)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEventSessionUpdate)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEventSessionUpdate(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ClientEventSessionUpdate DeserializeClientEventSessionUpdate(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + RequestSession session = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("session"u8)) + { + session = RequestSession.DeserializeRequestSession(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ClientEventSessionUpdate(@type, eventId, additionalBinaryDataProperties, session); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEventSessionUpdate)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEventSessionUpdate IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ClientEventSessionUpdate)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEventSessionUpdate(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEventSessionUpdate)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionUpdate.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionUpdate.cs new file mode 100644 index 000000000000..3af0bfb6692a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventSessionUpdate.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ClientEventSessionUpdate : ClientEvent + { + /// Initializes a new instance of . + /// + /// is null. + public ClientEventSessionUpdate(RequestSession session) : base(ClientEventType.SessionUpdate) + { + Argument.AssertNotNull(session, nameof(session)); + + Session = session; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + internal ClientEventSessionUpdate(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties, RequestSession session) : base(@type, eventId, additionalBinaryDataProperties) + { + Session = session; + } + + /// Gets the Session. + public RequestSession Session { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventType.cs new file mode 100644 index 000000000000..684caa34c67a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ClientEventType.cs @@ -0,0 +1,124 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// Client event types used in VoiceLive protocol. + internal readonly partial struct ClientEventType : IEquatable + { + private readonly string _value; + private const string SessionUpdateValue = "session.update"; + private const string InputAudioBufferAppendValue = "input_audio_buffer.append"; + private const string InputAudioBufferCommitValue = "input_audio_buffer.commit"; + private const string InputAudioBufferClearValue = "input_audio_buffer.clear"; + private const string InputAudioTurnStartValue = "input_audio.turn.start"; + private const string InputAudioTurnAppendValue = "input_audio.turn.append"; + private const string InputAudioTurnEndValue = "input_audio.turn.end"; + private const string InputAudioTurnCancelValue = "input_audio.turn.cancel"; + private const string InputAudioClearValue = "input_audio.clear"; + private const string ConversationItemCreateValue = "conversation.item.create"; + private const string ConversationItemRetrieveValue = "conversation.item.retrieve"; + private const string ConversationItemTruncateValue = "conversation.item.truncate"; + private const string ConversationItemDeleteValue = "conversation.item.delete"; + private const string ResponseCreateValue = "response.create"; + private const string ResponseCancelValue = "response.cancel"; + private const string SessionAvatarConnectValue = "session.avatar.connect"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public ClientEventType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the SessionUpdate. + public static ClientEventType SessionUpdate { get; } = new ClientEventType(SessionUpdateValue); + + /// Gets the InputAudioBufferAppend. + public static ClientEventType InputAudioBufferAppend { get; } = new ClientEventType(InputAudioBufferAppendValue); + + /// Gets the InputAudioBufferCommit. + public static ClientEventType InputAudioBufferCommit { get; } = new ClientEventType(InputAudioBufferCommitValue); + + /// Gets the InputAudioBufferClear. + public static ClientEventType InputAudioBufferClear { get; } = new ClientEventType(InputAudioBufferClearValue); + + /// Gets the InputAudioTurnStart. + public static ClientEventType InputAudioTurnStart { get; } = new ClientEventType(InputAudioTurnStartValue); + + /// Gets the InputAudioTurnAppend. + public static ClientEventType InputAudioTurnAppend { get; } = new ClientEventType(InputAudioTurnAppendValue); + + /// Gets the InputAudioTurnEnd. + public static ClientEventType InputAudioTurnEnd { get; } = new ClientEventType(InputAudioTurnEndValue); + + /// Gets the InputAudioTurnCancel. + public static ClientEventType InputAudioTurnCancel { get; } = new ClientEventType(InputAudioTurnCancelValue); + + /// Gets the InputAudioClear. + public static ClientEventType InputAudioClear { get; } = new ClientEventType(InputAudioClearValue); + + /// Gets the ConversationItemCreate. + public static ClientEventType ConversationItemCreate { get; } = new ClientEventType(ConversationItemCreateValue); + + /// Gets the ConversationItemRetrieve. + public static ClientEventType ConversationItemRetrieve { get; } = new ClientEventType(ConversationItemRetrieveValue); + + /// Gets the ConversationItemTruncate. + public static ClientEventType ConversationItemTruncate { get; } = new ClientEventType(ConversationItemTruncateValue); + + /// Gets the ConversationItemDelete. + public static ClientEventType ConversationItemDelete { get; } = new ClientEventType(ConversationItemDeleteValue); + + /// Gets the ResponseCreate. + public static ClientEventType ResponseCreate { get; } = new ClientEventType(ResponseCreateValue); + + /// Gets the ResponseCancel. + public static ClientEventType ResponseCancel { get; } = new ClientEventType(ResponseCancelValue); + + /// Gets the SessionAvatarConnect. + public static ClientEventType SessionAvatarConnect { get; } = new ClientEventType(SessionAvatarConnectValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(ClientEventType left, ClientEventType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(ClientEventType left, ClientEventType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator ClientEventType(string value) => new ClientEventType(value); + + /// Converts a string to a . + /// The value. + public static implicit operator ClientEventType?(string value) => value == null ? null : new ClientEventType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ClientEventType other && Equals(other); + + /// + public bool Equals(ClientEventType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPart.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPart.Serialization.cs new file mode 100644 index 000000000000..a81c65052af0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPart.Serialization.cs @@ -0,0 +1,145 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// The ContentPart. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , , and . + /// + [PersistableModelProxy(typeof(UnknownContentPart))] + public abstract partial class ContentPart : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ContentPart() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ContentPart)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ContentPart IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ContentPart JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ContentPart)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeContentPart(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ContentPart DeserializeContentPart(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "input_text": + return RequestTextContentPart.DeserializeRequestTextContentPart(element, options); + case "input_audio": + return RequestAudioContentPart.DeserializeRequestAudioContentPart(element, options); + case "text": + return ResponseTextContentPart.DeserializeResponseTextContentPart(element, options); + case "audio": + return ResponseAudioContentPart.DeserializeResponseAudioContentPart(element, options); + } + } + return UnknownContentPart.DeserializeUnknownContentPart(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ContentPart)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ContentPart IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ContentPart PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeContentPart(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ContentPart)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPart.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPart.cs new file mode 100644 index 000000000000..48876be8d3da --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPart.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// The ContentPart. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , , and . + /// + public abstract partial class ContentPart + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + private protected ContentPart(ContentPartType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ContentPart(ContentPartType @type, IDictionary additionalBinaryDataProperties) + { + Type = @type; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets or sets the Type. + internal ContentPartType Type { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPartType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPartType.cs new file mode 100644 index 000000000000..b9f33a4fcda4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ContentPartType.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// + internal readonly partial struct ContentPartType : IEquatable + { + private readonly string _value; + private const string InputTextValue = "input_text"; + private const string InputAudioValue = "input_audio"; + private const string TextValue = "text"; + private const string AudioValue = "audio"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public ContentPartType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the InputText. + public static ContentPartType InputText { get; } = new ContentPartType(InputTextValue); + + /// Gets the InputAudio. + public static ContentPartType InputAudio { get; } = new ContentPartType(InputAudioValue); + + /// Gets the Text. + public static ContentPartType Text { get; } = new ContentPartType(TextValue); + + /// Gets the Audio. + public static ContentPartType Audio { get; } = new ContentPartType(AudioValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(ContentPartType left, ContentPartType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(ContentPartType left, ContentPartType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator ContentPartType(string value) => new ContentPartType(value); + + /// Converts a string to a . + /// The value. + public static implicit operator ContentPartType?(string value) => value == null ? null : new ContentPartType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ContentPartType other && Equals(other); + + /// + public bool Equals(ContentPartType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReference.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReference.Serialization.cs new file mode 100644 index 000000000000..1513ffa4b2ed --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReference.Serialization.cs @@ -0,0 +1,276 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The item to add to the conversation. + public partial class ConversationItemWithReference : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationItemWithReference)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.Value.ToSerialString()); + } + if (Optional.IsDefined(Object)) + { + writer.WritePropertyName("object"u8); + writer.WriteStringValue(Object); + } + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteStringValue(Status.Value.ToSerialString()); + } + if (Optional.IsDefined(Role)) + { + writer.WritePropertyName("role"u8); + writer.WriteStringValue(Role.Value.ToSerialString()); + } + if (Optional.IsCollectionDefined(Content)) + { + writer.WritePropertyName("content"u8); + writer.WriteStartArray(); + foreach (ConversationItemWithReferenceContent item in Content) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(CallId)) + { + writer.WritePropertyName("call_id"u8); + writer.WriteStringValue(CallId); + } + if (Optional.IsDefined(Name)) + { + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + if (Optional.IsDefined(Arguments)) + { + writer.WritePropertyName("arguments"u8); + writer.WriteStringValue(Arguments); + } + if (Optional.IsDefined(Output)) + { + writer.WritePropertyName("output"u8); + writer.WriteStringValue(Output); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ConversationItemWithReference IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ConversationItemWithReference JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationItemWithReference)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConversationItemWithReference(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ConversationItemWithReference DeserializeConversationItemWithReference(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string id = default; + ConversationItemWithReferenceType? @type = default; + string @object = default; + ConversationItemWithReferenceStatus? status = default; + ConversationItemWithReferenceRole? role = default; + IList content = default; + string callId = default; + string name = default; + string arguments = default; + string output = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @type = prop.Value.GetString().ToConversationItemWithReferenceType(); + continue; + } + if (prop.NameEquals("object"u8)) + { + @object = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("status"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = prop.Value.GetString().ToConversationItemWithReferenceStatus(); + continue; + } + if (prop.NameEquals("role"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + role = prop.Value.GetString().ToConversationItemWithReferenceRole(); + continue; + } + if (prop.NameEquals("content"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ConversationItemWithReferenceContent.DeserializeConversationItemWithReferenceContent(item, options)); + } + content = array; + continue; + } + if (prop.NameEquals("call_id"u8)) + { + callId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("arguments"u8)) + { + arguments = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output"u8)) + { + output = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ConversationItemWithReference( + id, + @type, + @object, + status, + role, + content ?? new ChangeTrackingList(), + callId, + name, + arguments, + output, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ConversationItemWithReference)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ConversationItemWithReference IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ConversationItemWithReference PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeConversationItemWithReference(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConversationItemWithReference)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReference.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReference.cs new file mode 100644 index 000000000000..bb6620cd9850 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReference.cs @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The item to add to the conversation. + public partial class ConversationItemWithReference + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public ConversationItemWithReference() + { + Content = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// + /// For an item of type (`message` | `function_call` | `function_call_output`) + /// this field allows the client to assign the unique ID of the item. It is + /// not required because the server will generate one if not provided. + /// + /// For an item of type `item_reference`, this field is required and is a + /// reference to any item that has previously existed in the conversation. + /// + /// The type of the item (`message`, `function_call`, `function_call_output`, `item_reference`). + /// Identifier for the API object being returned - always `realtime.item`. + /// + /// The status of the item (`completed`, `incomplete`). These have no effect + /// on the conversation, but are accepted for consistency with the + /// `conversation.item.created` event. + /// + /// + /// The role of the message sender (`user`, `assistant`, `system`), only + /// applicable for `message` items. + /// + /// + /// The content of the message, applicable for `message` items. + /// - Message items of role `system` support only `input_text` content + /// - Message items of role `user` support `input_text` and `input_audio` + /// content + /// - Message items of role `assistant` support `text` content. + /// + /// + /// The ID of the function call (for `function_call` and + /// `function_call_output` items). If passed on a `function_call_output` + /// item, the server will check that a `function_call` item with the same + /// ID exists in the conversation history. + /// + /// The name of the function being called (for `function_call` items). + /// The arguments of the function call (for `function_call` items). + /// The output of the function call (for `function_call_output` items). + /// Keeps track of any properties unknown to the library. + internal ConversationItemWithReference(string id, ConversationItemWithReferenceType? @type, string @object, ConversationItemWithReferenceStatus? status, ConversationItemWithReferenceRole? role, IList content, string callId, string name, string arguments, string output, IDictionary additionalBinaryDataProperties) + { + Id = id; + Type = @type; + Object = @object; + Status = status; + Role = role; + Content = content; + CallId = callId; + Name = name; + Arguments = arguments; + Output = output; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// + /// For an item of type (`message` | `function_call` | `function_call_output`) + /// this field allows the client to assign the unique ID of the item. It is + /// not required because the server will generate one if not provided. + /// + /// For an item of type `item_reference`, this field is required and is a + /// reference to any item that has previously existed in the conversation. + /// + public string Id { get; set; } + + /// The type of the item (`message`, `function_call`, `function_call_output`, `item_reference`). + public ConversationItemWithReferenceType? Type { get; set; } + + /// Identifier for the API object being returned - always `realtime.item`. + public string Object { get; set; } + + /// + /// The status of the item (`completed`, `incomplete`). These have no effect + /// on the conversation, but are accepted for consistency with the + /// `conversation.item.created` event. + /// + public ConversationItemWithReferenceStatus? Status { get; set; } + + /// + /// The role of the message sender (`user`, `assistant`, `system`), only + /// applicable for `message` items. + /// + public ConversationItemWithReferenceRole? Role { get; set; } + + /// + /// The content of the message, applicable for `message` items. + /// - Message items of role `system` support only `input_text` content + /// - Message items of role `user` support `input_text` and `input_audio` + /// content + /// - Message items of role `assistant` support `text` content. + /// + public IList Content { get; } + + /// + /// The ID of the function call (for `function_call` and + /// `function_call_output` items). If passed on a `function_call_output` + /// item, the server will check that a `function_call` item with the same + /// ID exists in the conversation history. + /// + public string CallId { get; set; } + + /// The name of the function being called (for `function_call` items). + public string Name { get; set; } + + /// The arguments of the function call (for `function_call` items). + public string Arguments { get; set; } + + /// The output of the function call (for `function_call_output` items). + public string Output { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContent.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContent.Serialization.cs new file mode 100644 index 000000000000..1ecfbd26aeca --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContent.Serialization.cs @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ConversationItemWithReferenceContent. + public partial class ConversationItemWithReferenceContent : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationItemWithReferenceContent)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.Value.ToSerialString()); + } + if (Optional.IsDefined(Text)) + { + writer.WritePropertyName("text"u8); + writer.WriteStringValue(Text); + } + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (Optional.IsDefined(Audio)) + { + writer.WritePropertyName("audio"u8); + writer.WriteStringValue(Audio); + } + if (Optional.IsDefined(Transcript)) + { + writer.WritePropertyName("transcript"u8); + writer.WriteStringValue(Transcript); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ConversationItemWithReferenceContent IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ConversationItemWithReferenceContent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationItemWithReferenceContent)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConversationItemWithReferenceContent(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ConversationItemWithReferenceContent DeserializeConversationItemWithReferenceContent(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ConversationItemWithReferenceContentType? @type = default; + string text = default; + string id = default; + string audio = default; + string transcript = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @type = prop.Value.GetString().ToConversationItemWithReferenceContentType(); + continue; + } + if (prop.NameEquals("text"u8)) + { + text = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("audio"u8)) + { + audio = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("transcript"u8)) + { + transcript = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ConversationItemWithReferenceContent( + @type, + text, + id, + audio, + transcript, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ConversationItemWithReferenceContent)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ConversationItemWithReferenceContent IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ConversationItemWithReferenceContent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeConversationItemWithReferenceContent(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConversationItemWithReferenceContent)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContent.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContent.cs new file mode 100644 index 000000000000..eb659bdfd147 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContent.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ConversationItemWithReferenceContent. + public partial class ConversationItemWithReferenceContent + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public ConversationItemWithReferenceContent() + { + } + + /// Initializes a new instance of . + /// The content type (`input_text`, `input_audio`, `item_reference`, `text`). + /// The text content, used for `input_text` and `text` content types. + /// + /// ID of a previous conversation item to reference (for `item_reference` + /// content types in `response.create` events). These can reference both + /// client and server created items. + /// + /// Base64-encoded audio bytes, used for `input_audio` content type. + /// The transcript of the audio, used for `input_audio` content type. + /// Keeps track of any properties unknown to the library. + internal ConversationItemWithReferenceContent(ConversationItemWithReferenceContentType? @type, string text, string id, string audio, string transcript, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Text = text; + Id = id; + Audio = audio; + Transcript = transcript; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The content type (`input_text`, `input_audio`, `item_reference`, `text`). + public ConversationItemWithReferenceContentType? Type { get; set; } + + /// The text content, used for `input_text` and `text` content types. + public string Text { get; set; } + + /// + /// ID of a previous conversation item to reference (for `item_reference` + /// content types in `response.create` events). These can reference both + /// client and server created items. + /// + public string Id { get; set; } + + /// Base64-encoded audio bytes, used for `input_audio` content type. + public string Audio { get; set; } + + /// The transcript of the audio, used for `input_audio` content type. + public string Transcript { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContentType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContentType.Serialization.cs new file mode 100644 index 000000000000..d4fb7a3b948b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContentType.Serialization.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ConversationItemWithReferenceContentTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this ConversationItemWithReferenceContentType value) => value switch + { + ConversationItemWithReferenceContentType.InputAudio => "input_audio", + ConversationItemWithReferenceContentType.InputText => "input_text", + ConversationItemWithReferenceContentType.ItemReference => "item_reference", + ConversationItemWithReferenceContentType.Text => "text", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceContentType value.") + }; + + /// The value to deserialize. + public static ConversationItemWithReferenceContentType ToConversationItemWithReferenceContentType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "input_audio")) + { + return ConversationItemWithReferenceContentType.InputAudio; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "input_text")) + { + return ConversationItemWithReferenceContentType.InputText; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "item_reference")) + { + return ConversationItemWithReferenceContentType.ItemReference; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "text")) + { + return ConversationItemWithReferenceContentType.Text; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceContentType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContentType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContentType.cs new file mode 100644 index 000000000000..2e08f4328e93 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceContentType.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ConversationItemWithReferenceContentType + { + /// InputAudio. + InputAudio, + /// InputText. + InputText, + /// ItemReference. + ItemReference, + /// Text. + Text + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceRole.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceRole.Serialization.cs new file mode 100644 index 000000000000..dccc496a614e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceRole.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ConversationItemWithReferenceRoleExtensions + { + /// The value to serialize. + public static string ToSerialString(this ConversationItemWithReferenceRole value) => value switch + { + ConversationItemWithReferenceRole.User => "user", + ConversationItemWithReferenceRole.Assistant => "assistant", + ConversationItemWithReferenceRole.System => "system", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceRole value.") + }; + + /// The value to deserialize. + public static ConversationItemWithReferenceRole ToConversationItemWithReferenceRole(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "user")) + { + return ConversationItemWithReferenceRole.User; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "assistant")) + { + return ConversationItemWithReferenceRole.Assistant; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "system")) + { + return ConversationItemWithReferenceRole.System; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceRole value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceRole.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceRole.cs new file mode 100644 index 000000000000..32a65118ab50 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceRole.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ConversationItemWithReferenceRole + { + /// User. + User, + /// Assistant. + Assistant, + /// System. + System + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceStatus.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceStatus.Serialization.cs new file mode 100644 index 000000000000..515c3af077b4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceStatus.Serialization.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ConversationItemWithReferenceStatusExtensions + { + /// The value to serialize. + public static string ToSerialString(this ConversationItemWithReferenceStatus value) => value switch + { + ConversationItemWithReferenceStatus.Completed => "completed", + ConversationItemWithReferenceStatus.Incomplete => "incomplete", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceStatus value.") + }; + + /// The value to deserialize. + public static ConversationItemWithReferenceStatus ToConversationItemWithReferenceStatus(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "completed")) + { + return ConversationItemWithReferenceStatus.Completed; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "incomplete")) + { + return ConversationItemWithReferenceStatus.Incomplete; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceStatus value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceStatus.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceStatus.cs new file mode 100644 index 000000000000..3c758d7ba4a2 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceStatus.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ConversationItemWithReferenceStatus + { + /// Completed. + Completed, + /// Incomplete. + Incomplete + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceType.Serialization.cs new file mode 100644 index 000000000000..e0632a4920ac --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceType.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ConversationItemWithReferenceTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this ConversationItemWithReferenceType value) => value switch + { + ConversationItemWithReferenceType.Message => "message", + ConversationItemWithReferenceType.FunctionCall => "function_call", + ConversationItemWithReferenceType.FunctionCallOutput => "function_call_output", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceType value.") + }; + + /// The value to deserialize. + public static ConversationItemWithReferenceType ToConversationItemWithReferenceType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "message")) + { + return ConversationItemWithReferenceType.Message; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "function_call")) + { + return ConversationItemWithReferenceType.FunctionCall; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "function_call_output")) + { + return ConversationItemWithReferenceType.FunctionCallOutput; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ConversationItemWithReferenceType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceType.cs new file mode 100644 index 000000000000..326cb20b7529 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationItemWithReferenceType.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ConversationItemWithReferenceType + { + /// Message. + Message, + /// FunctionCall. + FunctionCall, + /// FunctionCallOutput. + FunctionCallOutput + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationRequestItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationRequestItem.Serialization.cs new file mode 100644 index 000000000000..687a8dd17b5a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationRequestItem.Serialization.cs @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// The ConversationRequestItem. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + [PersistableModelProxy(typeof(UnknownConversationRequestItem))] + internal abstract partial class ConversationRequestItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ConversationRequestItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ConversationRequestItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConversationRequestItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ConversationRequestItem DeserializeConversationRequestItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "message": + return RequestMessageItem.DeserializeRequestMessageItem(element, options); + case "function_call": + return RequestFunctionCallItem.DeserializeRequestFunctionCallItem(element, options); + case "function_call_output": + return RequestFunctionCallOutputItem.DeserializeRequestFunctionCallOutputItem(element, options); + } + } + return UnknownConversationRequestItem.DeserializeUnknownConversationRequestItem(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ConversationRequestItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeConversationRequestItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationRequestItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationRequestItem.cs new file mode 100644 index 000000000000..7d62f2a93cc5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationRequestItem.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// The ConversationRequestItem. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + internal abstract partial class ConversationRequestItem + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + private protected ConversationRequestItem(ItemType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + internal ConversationRequestItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Id = id; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets or sets the Type. + internal ItemType Type { get; set; } + + /// Gets or sets the Id. + public string Id { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationResponseItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationResponseItem.Serialization.cs new file mode 100644 index 000000000000..232611143d14 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationResponseItem.Serialization.cs @@ -0,0 +1,153 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// The ConversationResponseItem. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + [PersistableModelProxy(typeof(UnknownConversationResponseItem))] + public abstract partial class ConversationResponseItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ConversationResponseItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Object)) + { + writer.WritePropertyName("object"u8); + writer.WriteStringValue(Object); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ConversationResponseItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConversationResponseItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ConversationResponseItem DeserializeConversationResponseItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "message": + return ResponseMessageItem.DeserializeResponseMessageItem(element, options); + case "function_call": + return ResponseFunctionCallItem.DeserializeResponseFunctionCallItem(element, options); + case "function_call_output": + return ResponseFunctionCallOutputItem.DeserializeResponseFunctionCallOutputItem(element, options); + } + } + return UnknownConversationResponseItem.DeserializeUnknownConversationResponseItem(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ConversationResponseItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeConversationResponseItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationResponseItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationResponseItem.cs new file mode 100644 index 000000000000..e6a72f931c51 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ConversationResponseItem.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// The ConversationResponseItem. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + public abstract partial class ConversationResponseItem + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + private protected ConversationResponseItem(ItemType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal ConversationResponseItem(string @object, ItemType @type, string id, IDictionary additionalBinaryDataProperties) + { + Object = @object; + Type = @type; + Id = id; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Object. + public string Object { get; } + + /// Gets or sets the Type. + internal ItemType Type { get; set; } + + /// Gets the Id. + public string Id { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/EmotionCandidate.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/EmotionCandidate.Serialization.cs new file mode 100644 index 000000000000..060b86f90ec9 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/EmotionCandidate.Serialization.cs @@ -0,0 +1,150 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The EmotionCandidate. + public partial class EmotionCandidate : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal EmotionCandidate() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(EmotionCandidate)} does not support writing '{format}' format."); + } + writer.WritePropertyName("emotion"u8); + writer.WriteStringValue(Emotion); + writer.WritePropertyName("confidence"u8); + writer.WriteNumberValue(Confidence); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + EmotionCandidate IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual EmotionCandidate JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(EmotionCandidate)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeEmotionCandidate(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static EmotionCandidate DeserializeEmotionCandidate(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string emotion = default; + float confidence = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("emotion"u8)) + { + emotion = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("confidence"u8)) + { + confidence = prop.Value.GetSingle(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new EmotionCandidate(emotion, confidence, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(EmotionCandidate)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + EmotionCandidate IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual EmotionCandidate PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeEmotionCandidate(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(EmotionCandidate)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/EmotionCandidate.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/EmotionCandidate.cs new file mode 100644 index 000000000000..bd8cc975738c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/EmotionCandidate.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The EmotionCandidate. + public partial class EmotionCandidate + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + /// + internal EmotionCandidate(string emotion, float confidence) + { + Emotion = emotion; + Confidence = confidence; + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + internal EmotionCandidate(string emotion, float confidence, IDictionary additionalBinaryDataProperties) + { + Emotion = emotion; + Confidence = confidence; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Emotion. + public string Emotion { get; } + + /// Gets the Confidence. + public float Confidence { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ForceModelsRequest.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ForceModelsRequest.Serialization.cs new file mode 100644 index 000000000000..8e56459d6d54 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ForceModelsRequest.Serialization.cs @@ -0,0 +1,162 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// The ForceModelsRequest. + internal partial class ForceModelsRequest : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ForceModelsRequest() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ForceModelsRequest)} does not support writing '{format}' format."); + } + writer.WritePropertyName("event"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Event); +#else + using (JsonDocument document = JsonDocument.Parse(Event)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ForceModelsRequest IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ForceModelsRequest JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ForceModelsRequest)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeForceModelsRequest(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ForceModelsRequest DeserializeForceModelsRequest(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + BinaryData @event = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("event"u8)) + { + @event = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ForceModelsRequest(@event, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ForceModelsRequest)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ForceModelsRequest IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ForceModelsRequest PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeForceModelsRequest(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ForceModelsRequest)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to serialize into . + public static implicit operator RequestContent(ForceModelsRequest forceModelsRequest) + { + if (forceModelsRequest == null) + { + return null; + } + Utf8JsonRequestContent content = new Utf8JsonRequestContent(); + content.JsonWriter.WriteObjectValue(forceModelsRequest, ModelSerializationExtensions.WireOptions); + return content; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/FunctionTool.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/FunctionTool.Serialization.cs new file mode 100644 index 000000000000..babce5274a29 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/FunctionTool.Serialization.cs @@ -0,0 +1,167 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The definition of a function tool as used by the voicelive endpoint. + public partial class FunctionTool : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal FunctionTool() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FunctionTool)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + if (Optional.IsDefined(Description)) + { + writer.WritePropertyName("description"u8); + writer.WriteStringValue(Description); + } + if (Optional.IsDefined(Parameters)) + { + writer.WritePropertyName("parameters"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Parameters); +#else + using (JsonDocument document = JsonDocument.Parse(Parameters)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + FunctionTool IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (FunctionTool)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ToolCall JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(FunctionTool)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeFunctionTool(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static FunctionTool DeserializeFunctionTool(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ToolType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string name = default; + string description = default; + BinaryData parameters = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ToolType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("description"u8)) + { + description = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("parameters"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + parameters = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new FunctionTool(@type, additionalBinaryDataProperties, name, description, parameters); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(FunctionTool)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + FunctionTool IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (FunctionTool)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ToolCall PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeFunctionTool(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(FunctionTool)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/FunctionTool.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/FunctionTool.cs new file mode 100644 index 000000000000..9ec43bc9f805 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/FunctionTool.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The definition of a function tool as used by the voicelive endpoint. + public partial class FunctionTool : ToolCall + { + /// Initializes a new instance of . + /// + /// is null. + public FunctionTool(string name) : base(ToolType.Function) + { + Argument.AssertNotNull(name, nameof(name)); + + Name = name; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + internal FunctionTool(ToolType @type, IDictionary additionalBinaryDataProperties, string name, string description, BinaryData parameters) : base(@type, additionalBinaryDataProperties) + { + Name = name; + Description = description; + Parameters = parameters; + } + + /// Gets or sets the Name. + public string Name { get; set; } + + /// Gets or sets the Description. + public string Description { get; set; } + + /// + /// Gets or sets the Parameters. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData Parameters { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/IceServer.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/IceServer.Serialization.cs new file mode 100644 index 000000000000..8f6df942f74e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/IceServer.Serialization.cs @@ -0,0 +1,186 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// ICE server configuration for WebRTC connection negotiation. + public partial class IceServer : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal IceServer() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IceServer)} does not support writing '{format}' format."); + } + writer.WritePropertyName("urls"u8); + writer.WriteStartArray(); + foreach (Uri item in Uris) + { + if (item == null) + { + writer.WriteNullValue(); + continue; + } + writer.WriteStringValue(item.AbsoluteUri); + } + writer.WriteEndArray(); + if (Optional.IsDefined(Username)) + { + writer.WritePropertyName("username"u8); + writer.WriteStringValue(Username); + } + if (Optional.IsDefined(Credential)) + { + writer.WritePropertyName("credential"u8); + writer.WriteStringValue(Credential); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + IceServer IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual IceServer JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(IceServer)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeIceServer(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static IceServer DeserializeIceServer(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList uris = default; + string username = default; + string credential = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("urls"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + if (item.ValueKind == JsonValueKind.Null) + { + array.Add(null); + } + else + { + array.Add(new Uri(item.GetString())); + } + } + uris = array; + continue; + } + if (prop.NameEquals("username"u8)) + { + username = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("credential"u8)) + { + credential = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new IceServer(uris, username, credential, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(IceServer)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + IceServer IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual IceServer PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeIceServer(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(IceServer)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/IceServer.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/IceServer.cs new file mode 100644 index 000000000000..edf78fc1ab4d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/IceServer.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// ICE server configuration for WebRTC connection negotiation. + public partial class IceServer + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// List of ICE server URLs (e.g., TURN or STUN endpoints). + /// is null. + public IceServer(IEnumerable uris) + { + Argument.AssertNotNull(uris, nameof(uris)); + + Uris = uris.ToList(); + } + + /// Initializes a new instance of . + /// List of ICE server URLs (e.g., TURN or STUN endpoints). + /// Optional username used for authentication with the ICE server. + /// Optional credential (e.g., password or token) used for authentication. + /// Keeps track of any properties unknown to the library. + internal IceServer(IList uris, string username, string credential, IDictionary additionalBinaryDataProperties) + { + Uris = uris; + Username = username; + Credential = credential; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// List of ICE server URLs (e.g., TURN or STUN endpoints). + public IList Uris { get; } + + /// Optional username used for authentication with the ICE server. + public string Username { get; set; } + + /// Optional credential (e.g., password or token) used for authentication. + public string Credential { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputAudio.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputAudio.Serialization.cs new file mode 100644 index 000000000000..2e18df471b8e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputAudio.Serialization.cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for client audio input. Used to specify the audio model and optional phrase list. + public partial class InputAudio : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputAudio)} does not support writing '{format}' format."); + } + writer.WritePropertyName("model"u8); + writer.WriteStringValue(Model); + if (Optional.IsCollectionDefined(PhraseList)) + { + writer.WritePropertyName("phrase_list"u8); + writer.WriteStartArray(); + foreach (string item in PhraseList) + { + if (item == null) + { + writer.WriteNullValue(); + continue; + } + writer.WriteStringValue(item); + } + writer.WriteEndArray(); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + InputAudio IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual InputAudio JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(InputAudio)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeInputAudio(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static InputAudio DeserializeInputAudio(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string model = default; + IList phraseList = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("model"u8)) + { + model = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("phrase_list"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + if (item.ValueKind == JsonValueKind.Null) + { + array.Add(null); + } + else + { + array.Add(item.GetString()); + } + } + phraseList = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new InputAudio(model, phraseList ?? new ChangeTrackingList(), additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(InputAudio)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + InputAudio IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual InputAudio PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeInputAudio(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(InputAudio)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputAudio.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputAudio.cs new file mode 100644 index 000000000000..3a2adf993df8 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputAudio.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Configuration for client audio input. Used to specify the audio model and optional phrase list. + public partial class InputAudio + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public InputAudio() + { + PhraseList = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// The name of the model to use for input audio (currently only 'azure-standard' is supported). + /// Optional list of phrases to bias the speech recognition engine. + /// Keeps track of any properties unknown to the library. + internal InputAudio(string model, IList phraseList, IDictionary additionalBinaryDataProperties) + { + Model = model; + PhraseList = phraseList; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The name of the model to use for input audio (currently only 'azure-standard' is supported). + public string Model { get; } = "azure-standard"; + + /// Optional list of phrases to bias the speech recognition engine. + public IList PhraseList { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputModality.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputModality.cs new file mode 100644 index 000000000000..e4879771f2ea --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/InputModality.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// + public readonly partial struct InputModality : IEquatable + { + private readonly string _value; + private const string TextValue = "text"; + private const string AudioValue = "audio"; + private const string AnimationValue = "animation"; + private const string AvatarValue = "avatar"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public InputModality(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the Text. + public static InputModality Text { get; } = new InputModality(TextValue); + + /// Gets the Audio. + public static InputModality Audio { get; } = new InputModality(AudioValue); + + /// Gets the Animation. + public static InputModality Animation { get; } = new InputModality(AnimationValue); + + /// Gets the Avatar. + public static InputModality Avatar { get; } = new InputModality(AvatarValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(InputModality left, InputModality right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(InputModality left, InputModality right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator InputModality(string value) => new InputModality(value); + + /// Converts a string to a . + /// The value. + public static implicit operator InputModality?(string value) => value == null ? null : new InputModality(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is InputModality other && Equals(other); + + /// + public bool Equals(InputModality other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Argument.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Argument.cs new file mode 100644 index 000000000000..5027a37eba00 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Argument.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal static partial class Argument + { + /// The value. + /// The name. + public static void AssertNotNull(T value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + } + + /// The value. + /// The name. + public static void AssertNotNull(T? value, string name) + where T : struct + { + if (!value.HasValue) + { + throw new ArgumentNullException(name); + } + } + + /// The value. + /// The name. + public static void AssertNotNullOrEmpty(IEnumerable value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + if (value is ICollection collectionOfT && collectionOfT.Count == 0) + { + throw new ArgumentException("Value cannot be an empty collection.", name); + } + if (value is ICollection collection && collection.Count == 0) + { + throw new ArgumentException("Value cannot be an empty collection.", name); + } + using IEnumerator e = value.GetEnumerator(); + if (!e.MoveNext()) + { + throw new ArgumentException("Value cannot be an empty collection.", name); + } + } + + /// The value. + /// The name. + public static void AssertNotNullOrEmpty(string value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + if (value.Length == 0) + { + throw new ArgumentException("Value cannot be an empty string.", name); + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ChangeTrackingDictionary.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ChangeTrackingDictionary.cs new file mode 100644 index 000000000000..afbdc641d219 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ChangeTrackingDictionary.cs @@ -0,0 +1,189 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class ChangeTrackingDictionary : IDictionary, IReadOnlyDictionary + where TKey : notnull + { + private IDictionary _innerDictionary; + + public ChangeTrackingDictionary() + { + } + + /// The inner dictionary. + public ChangeTrackingDictionary(IDictionary dictionary) + { + if (dictionary == null) + { + return; + } + _innerDictionary = new Dictionary(dictionary); + } + + /// The inner dictionary. + public ChangeTrackingDictionary(IReadOnlyDictionary dictionary) + { + if (dictionary == null) + { + return; + } + _innerDictionary = new Dictionary(); + foreach (var pair in dictionary) + { + _innerDictionary.Add(pair); + } + } + + /// Gets the IsUndefined. + public bool IsUndefined => _innerDictionary == null; + + /// Gets the Count. + public int Count => IsUndefined ? 0 : EnsureDictionary().Count; + + /// Gets the IsReadOnly. + public bool IsReadOnly => IsUndefined ? false : EnsureDictionary().IsReadOnly; + + /// Gets the Keys. + public ICollection Keys => IsUndefined ? Array.Empty() : EnsureDictionary().Keys; + + /// Gets the Values. + public ICollection Values => IsUndefined ? Array.Empty() : EnsureDictionary().Values; + + /// Gets or sets the value associated with the specified key. + public TValue this[TKey key] + { + get + { + if (IsUndefined) + { + throw new KeyNotFoundException(nameof(key)); + } + return EnsureDictionary()[key]; + } + set + { + EnsureDictionary()[key] = value; + } + } + + /// Gets the Keys. + IEnumerable IReadOnlyDictionary.Keys => Keys; + + /// Gets the Values. + IEnumerable IReadOnlyDictionary.Values => Values; + + public IEnumerator> GetEnumerator() + { + if (IsUndefined) + { + IEnumerator> enumerateEmpty() + { + yield break; + } + return enumerateEmpty(); + } + return EnsureDictionary().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// The item to add. + public void Add(KeyValuePair item) + { + EnsureDictionary().Add(item); + } + + public void Clear() + { + EnsureDictionary().Clear(); + } + + /// The item to search for. + public bool Contains(KeyValuePair item) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Contains(item); + } + + /// The array to copy. + /// The index. + public void CopyTo(KeyValuePair[] array, int index) + { + if (IsUndefined) + { + return; + } + EnsureDictionary().CopyTo(array, index); + } + + /// The item to remove. + public bool Remove(KeyValuePair item) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Remove(item); + } + + /// The key. + /// The value to add. + public void Add(TKey key, TValue value) + { + EnsureDictionary().Add(key, value); + } + + /// The key to search for. + public bool ContainsKey(TKey key) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().ContainsKey(key); + } + + /// The key. + public bool Remove(TKey key) + { + if (IsUndefined) + { + return false; + } + return EnsureDictionary().Remove(key); + } + + /// The key to search for. + /// The value. + public bool TryGetValue(TKey key, out TValue value) + { + if (IsUndefined) + { + value = default; + return false; + } + return EnsureDictionary().TryGetValue(key, out value); + } + + public IDictionary EnsureDictionary() + { + return _innerDictionary ??= new Dictionary(); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ChangeTrackingList.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ChangeTrackingList.cs new file mode 100644 index 000000000000..65b39d17f39b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ChangeTrackingList.cs @@ -0,0 +1,168 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + internal partial class ChangeTrackingList : IList, IReadOnlyList + { + private IList _innerList; + + public ChangeTrackingList() + { + } + + /// The inner list. + public ChangeTrackingList(IList innerList) + { + if (innerList != null) + { + _innerList = innerList; + } + } + + /// The inner list. + public ChangeTrackingList(IReadOnlyList innerList) + { + if (innerList != null) + { + _innerList = innerList.ToList(); + } + } + + /// Gets the IsUndefined. + public bool IsUndefined => _innerList == null; + + /// Gets the Count. + public int Count => IsUndefined ? 0 : EnsureList().Count; + + /// Gets the IsReadOnly. + public bool IsReadOnly => IsUndefined ? false : EnsureList().IsReadOnly; + + /// Gets or sets the value associated with the specified key. + public T this[int index] + { + get + { + if (IsUndefined) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + return EnsureList()[index]; + } + set + { + if (IsUndefined) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + EnsureList()[index] = value; + } + } + + public void Reset() + { + _innerList = null; + } + + public IEnumerator GetEnumerator() + { + if (IsUndefined) + { + IEnumerator enumerateEmpty() + { + yield break; + } + return enumerateEmpty(); + } + return EnsureList().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// The item to add. + public void Add(T item) + { + EnsureList().Add(item); + } + + public void Clear() + { + EnsureList().Clear(); + } + + /// The item. + public bool Contains(T item) + { + if (IsUndefined) + { + return false; + } + return EnsureList().Contains(item); + } + + /// The array to copy to. + /// The array index. + public void CopyTo(T[] array, int arrayIndex) + { + if (IsUndefined) + { + return; + } + EnsureList().CopyTo(array, arrayIndex); + } + + /// The item. + public bool Remove(T item) + { + if (IsUndefined) + { + return false; + } + return EnsureList().Remove(item); + } + + /// The item. + public int IndexOf(T item) + { + if (IsUndefined) + { + return -1; + } + return EnsureList().IndexOf(item); + } + + /// The inner list. + /// The item. + public void Insert(int index, T item) + { + EnsureList().Insert(index, item); + } + + /// The inner list. + public void RemoveAt(int index) + { + if (IsUndefined) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + EnsureList().RemoveAt(index); + } + + public IList EnsureList() + { + return _innerList ??= new List(); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ClientPipelineExtensions.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ClientPipelineExtensions.cs new file mode 100644 index 000000000000..d85dc928e30a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ClientPipelineExtensions.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ClientPipelineExtensions + { + public static async ValueTask ProcessMessageAsync(this HttpPipeline pipeline, HttpMessage message, RequestContext context) + { + (CancellationToken userCancellationToken, ErrorOptions statusOption) = context.Parse(); + await pipeline.SendAsync(message, userCancellationToken).ConfigureAwait(false); + + if (message.Response.IsError && (context?.ErrorOptions & ErrorOptions.NoThrow) != ErrorOptions.NoThrow) + { + throw new RequestFailedException(message.Response); + } + + return message.Response; + } + + public static Response ProcessMessage(this HttpPipeline pipeline, HttpMessage message, RequestContext context) + { + (CancellationToken userCancellationToken, ErrorOptions statusOption) = context.Parse(); + pipeline.Send(message, userCancellationToken); + + if (message.Response.IsError && (context?.ErrorOptions & ErrorOptions.NoThrow) != ErrorOptions.NoThrow) + { + throw new RequestFailedException(message.Response); + } + + return message.Response; + } + + public static async ValueTask> ProcessHeadAsBoolMessageAsync(this HttpPipeline pipeline, HttpMessage message, RequestContext context) + { + Response response = await pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false); + switch (response.Status) + { + case >= 200 and < 300: + return Response.FromValue(true, response); + case >= 400 and < 500: + return Response.FromValue(false, response); + default: + return new ErrorResult(response, new RequestFailedException(response)); + } + } + + public static Response ProcessHeadAsBoolMessage(this HttpPipeline pipeline, HttpMessage message, RequestContext context) + { + Response response = pipeline.ProcessMessage(message, context); + switch (response.Status) + { + case >= 200 and < 300: + return Response.FromValue(true, response); + case >= 400 and < 500: + return Response.FromValue(false, response); + default: + return new ErrorResult(response, new RequestFailedException(response)); + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenMemberAttribute.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenMemberAttribute.cs new file mode 100644 index 000000000000..bf5beb151a69 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenMemberAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + [AttributeUsage((AttributeTargets.Property | AttributeTargets.Field))] + internal partial class CodeGenMemberAttribute : CodeGenTypeAttribute + { + /// The original name of the member. + public CodeGenMemberAttribute(string originalName) : base(originalName) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenSerializationAttribute.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenSerializationAttribute.cs new file mode 100644 index 000000000000..6144cab5703f --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenSerializationAttribute.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + [AttributeUsage((AttributeTargets.Class | AttributeTargets.Struct), AllowMultiple = true, Inherited = true)] + internal partial class CodeGenSerializationAttribute : Attribute + { + /// The property name which these hooks apply to. + public CodeGenSerializationAttribute(string propertyName) + { + PropertyName = propertyName; + } + + /// The property name which these hooks apply to. + /// The serialization name of the property. + public CodeGenSerializationAttribute(string propertyName, string propertySerializationName) + { + PropertyName = propertyName; + PropertySerializationName = propertySerializationName; + } + + /// Gets or sets the property name which these hooks should apply to. + public string PropertyName { get; } + + /// Gets or sets the serialization name of the property. + public string PropertySerializationName { get; set; } + + /// + /// Gets or sets the method name to use when serializing the property value (property name excluded). + /// The signature of the serialization hook method must be or compatible with when invoking: private void SerializeHook(Utf8JsonWriter writer); + /// + public string SerializationValueHook { get; set; } + + /// + /// Gets or sets the method name to use when deserializing the property value from the JSON. + /// private static void DeserializationHook(JsonProperty property, ref TypeOfTheProperty propertyValue); // if the property is required + /// private static void DeserializationHook(JsonProperty property, ref Optional<TypeOfTheProperty> propertyValue); // if the property is optional + /// + public string DeserializationValueHook { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenSuppressAttribute.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenSuppressAttribute.cs new file mode 100644 index 000000000000..c8448235b482 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenSuppressAttribute.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + [AttributeUsage((AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct), AllowMultiple = true)] + internal partial class CodeGenSuppressAttribute : Attribute + { + /// The member to suppress. + /// The types of the parameters of the member. + public CodeGenSuppressAttribute(string member, params Type[] parameters) + { + Member = member; + Parameters = parameters; + } + + /// Gets the Member. + public string Member { get; } + + /// Gets the Parameters. + public Type[] Parameters { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenTypeAttribute.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenTypeAttribute.cs new file mode 100644 index 000000000000..0aa34aef6a85 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/CodeGenTypeAttribute.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + [AttributeUsage((AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct))] + internal partial class CodeGenTypeAttribute : Attribute + { + /// The original name of the type. + public CodeGenTypeAttribute(string originalName) + { + OriginalName = originalName; + } + + /// Gets the OriginalName. + public string OriginalName { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ErrorResult.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ErrorResult.cs new file mode 100644 index 000000000000..7aaf11e39c53 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ErrorResult.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using Azure; + +namespace Azure.AI.VoiceLive +{ + internal partial class ErrorResult : Response + { + private readonly Response _response; + private readonly RequestFailedException _exception; + + public ErrorResult(Response response, RequestFailedException exception) + { + _response = response; + _exception = exception; + } + + /// Gets the Value. + public override T Value => throw _exception; + + /// + public override Response GetRawResponse() + { + return _response; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ModelSerializationExtensions.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ModelSerializationExtensions.cs new file mode 100644 index 000000000000..c970b89de47b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/ModelSerializationExtensions.cs @@ -0,0 +1,258 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ModelSerializationExtensions + { + internal static readonly ModelReaderWriterOptions WireOptions = new ModelReaderWriterOptions("W"); + internal static readonly JsonDocumentOptions JsonDocumentOptions = new JsonDocumentOptions + { + MaxDepth = 256 + }; + + public static object GetObject(this JsonElement element) + { + switch (element.ValueKind) + { + case JsonValueKind.String: + return element.GetString(); + case JsonValueKind.Number: + if (element.TryGetInt32(out int intValue)) + { + return intValue; + } + if (element.TryGetInt64(out long longValue)) + { + return longValue; + } + return element.GetDouble(); + case JsonValueKind.True: + return true; + case JsonValueKind.False: + return false; + case JsonValueKind.Undefined: + case JsonValueKind.Null: + return null; + case JsonValueKind.Object: + Dictionary dictionary = new Dictionary(); + foreach (var jsonProperty in element.EnumerateObject()) + { + dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject()); + } + return dictionary; + case JsonValueKind.Array: + List list = new List(); + foreach (var item in element.EnumerateArray()) + { + list.Add(item.GetObject()); + } + return list.ToArray(); + default: + throw new NotSupportedException($"Not supported value kind {element.ValueKind}"); + } + } + + public static byte[] GetBytesFromBase64(this JsonElement element, string format) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + + return format switch + { + "U" => TypeFormatters.FromBase64UrlString(element.GetRequiredString()), + "D" => element.GetBytesFromBase64(), + _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) + }; + } + + public static DateTimeOffset GetDateTimeOffset(this JsonElement element, string format) => format switch + { + "U" when element.ValueKind == JsonValueKind.Number => DateTimeOffset.FromUnixTimeSeconds(element.GetInt64()), + _ => TypeFormatters.ParseDateTimeOffset(element.GetString(), format) + }; + + public static TimeSpan GetTimeSpan(this JsonElement element, string format) => TypeFormatters.ParseTimeSpan(element.GetString(), format); + + public static char GetChar(this JsonElement element) + { + if (element.ValueKind == JsonValueKind.String) + { + string text = element.GetString(); + if (text == null || text.Length != 1) + { + throw new NotSupportedException($"Cannot convert \"{text}\" to a char"); + } + return text[0]; + } + else + { + throw new NotSupportedException($"Cannot convert {element.ValueKind} to a char"); + } + } + + [Conditional("DEBUG")] + public static void ThrowNonNullablePropertyIsNull(this JsonProperty @property) + { + throw new JsonException($"A property '{@property.Name}' defined as non-nullable but received as null from the service. This exception only happens in DEBUG builds of the library and would be ignored in the release build"); + } + + public static string GetRequiredString(this JsonElement element) + { + string value = element.GetString(); + if (value == null) + { + throw new InvalidOperationException($"The requested operation requires an element of type 'String', but the target element has type '{element.ValueKind}'."); + } + return value; + } + + public static void WriteStringValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, DateTime value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, TimeSpan value, string format) + { + writer.WriteStringValue(TypeFormatters.ToString(value, format)); + } + + public static void WriteStringValue(this Utf8JsonWriter writer, char value) + { + writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture)); + } + + public static void WriteBase64StringValue(this Utf8JsonWriter writer, byte[] value, string format) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + switch (format) + { + case "U": + writer.WriteStringValue(TypeFormatters.ToBase64UrlString(value)); + break; + case "D": + writer.WriteBase64StringValue(value); + break; + default: + throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)); + } + } + + public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset value, string format) + { + if (format != "U") + { + throw new ArgumentOutOfRangeException(nameof(format), "Only 'U' format is supported when writing a DateTimeOffset as a Number."); + } + writer.WriteNumberValue(value.ToUnixTimeSeconds()); + } + + public static void WriteObjectValue(this Utf8JsonWriter writer, T value, ModelReaderWriterOptions options = null) + { + switch (value) + { + case null: + writer.WriteNullValue(); + break; + case IJsonModel jsonModel: + jsonModel.Write(writer, options ?? WireOptions); + break; + case byte[] bytes: + writer.WriteBase64StringValue(bytes); + break; + case BinaryData bytes0: + writer.WriteBase64StringValue(bytes0); + break; + case JsonElement json: + json.WriteTo(writer); + break; + case int i: + writer.WriteNumberValue(i); + break; + case decimal d: + writer.WriteNumberValue(d); + break; + case double d0: + if (double.IsNaN(d0)) + { + writer.WriteStringValue("NaN"); + } + else + { + writer.WriteNumberValue(d0); + } + break; + case float f: + writer.WriteNumberValue(f); + break; + case long l: + writer.WriteNumberValue(l); + break; + case string s: + writer.WriteStringValue(s); + break; + case bool b: + writer.WriteBooleanValue(b); + break; + case Guid g: + writer.WriteStringValue(g); + break; + case DateTimeOffset dateTimeOffset: + writer.WriteStringValue(dateTimeOffset, "O"); + break; + case DateTime dateTime: + writer.WriteStringValue(dateTime, "O"); + break; + case IEnumerable> enumerable: + writer.WriteStartObject(); + foreach (var pair in enumerable) + { + writer.WritePropertyName(pair.Key); + writer.WriteObjectValue(pair.Value, options); + } + writer.WriteEndObject(); + break; + case IEnumerable objectEnumerable: + writer.WriteStartArray(); + foreach (var item in objectEnumerable) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + break; + case TimeSpan timeSpan: + writer.WriteStringValue(timeSpan, "P"); + break; + default: + throw new NotSupportedException($"Not supported type {value.GetType()}"); + } + } + + public static void WriteObjectValue(this Utf8JsonWriter writer, object value, ModelReaderWriterOptions options = null) + { + writer.WriteObjectValue(value, options); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Optional.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Optional.cs new file mode 100644 index 000000000000..293a43131f53 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Optional.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal static partial class Optional + { + public static bool IsCollectionDefined(IEnumerable collection) + { + return !(collection is ChangeTrackingList changeTrackingList && changeTrackingList.IsUndefined); + } + + public static bool IsCollectionDefined(IDictionary collection) + { + return !(collection is ChangeTrackingDictionary changeTrackingDictionary && changeTrackingDictionary.IsUndefined); + } + + public static bool IsCollectionDefined(IReadOnlyDictionary collection) + { + return !(collection is ChangeTrackingDictionary changeTrackingDictionary && changeTrackingDictionary.IsUndefined); + } + + public static bool IsDefined(T? value) + where T : struct + { + return value.HasValue; + } + + public static bool IsDefined(object value) + { + return value != null; + } + + public static bool IsDefined(string value) + { + return value != null; + } + + public static bool IsDefined(JsonElement value) + { + return value.ValueKind != JsonValueKind.Undefined; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/RequestContextExtensions.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/RequestContextExtensions.cs new file mode 100644 index 000000000000..0782995f019d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/RequestContextExtensions.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Threading; +using Azure; + +namespace Azure.AI.VoiceLive +{ + internal static partial class RequestContextExtensions + { + /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + public static ValueTuple Parse(this RequestContext context) + { + if (context == null) + { + return (CancellationToken.None, ErrorOptions.Default); + } + return (context.CancellationToken, context.ErrorOptions); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/TypeFormatters.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/TypeFormatters.cs new file mode 100644 index 000000000000..6d10a623656b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/TypeFormatters.cs @@ -0,0 +1,152 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Azure.AI.VoiceLive +{ + internal static partial class TypeFormatters + { + private const string RoundtripZFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ"; + public const string DefaultNumberFormat = "G"; + + public static string ToString(bool value) => value ? "true" : "false"; + + public static string ToString(DateTime value, string format) => value.Kind switch + { + DateTimeKind.Utc => ToString((DateTimeOffset)value, format), + _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Generated clients require it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.") + }; + + public static string ToString(DateTimeOffset value, string format) => format switch + { + "D" => value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), + "U" => value.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture), + "O" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), + "o" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture), + "R" => value.ToString("r", CultureInfo.InvariantCulture), + _ => value.ToString(format, CultureInfo.InvariantCulture) + }; + + public static string ToString(TimeSpan value, string format) => format switch + { + "P" => System.Xml.XmlConvert.ToString(value), + _ => value.ToString(format, CultureInfo.InvariantCulture) + }; + + public static string ToString(byte[] value, string format) => format switch + { + "U" => ToBase64UrlString(value), + "D" => Convert.ToBase64String(value), + _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format)) + }; + + public static string ToBase64UrlString(byte[] value) + { + int numWholeOrPartialInputBlocks = checked (value.Length + 2) / 3; + int size = checked (numWholeOrPartialInputBlocks * 4); + char[] output = new char[size]; + + int numBase64Chars = Convert.ToBase64CharArray(value, 0, value.Length, output, 0); + + int i = 0; + for (; i < numBase64Chars; i++) + { + char ch = output[i]; + if (ch == '+') + { + output[i] = '-'; + } + else + { + if (ch == '/') + { + output[i] = '_'; + } + else + { + if (ch == '=') + { + break; + } + } + } + } + + return new string(output, 0, i); + } + + public static byte[] FromBase64UrlString(string value) + { + int paddingCharsToAdd = (value.Length % 4) switch + { + 0 => 0, + 2 => 2, + 3 => 1, + _ => throw new InvalidOperationException("Malformed input") + }; + char[] output = new char[(value.Length + paddingCharsToAdd)]; + int i = 0; + for (; i < value.Length; i++) + { + char ch = value[i]; + if (ch == '-') + { + output[i] = '+'; + } + else + { + if (ch == '_') + { + output[i] = '/'; + } + else + { + output[i] = ch; + } + } + } + + for (; i < output.Length; i++) + { + output[i] = '='; + } + + return Convert.FromBase64CharArray(output, 0, output.Length); + } + + public static DateTimeOffset ParseDateTimeOffset(string value, string format) => format switch + { + "U" => DateTimeOffset.FromUnixTimeSeconds(long.Parse(value, CultureInfo.InvariantCulture)), + _ => DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) + }; + + public static TimeSpan ParseTimeSpan(string value, string format) => format switch + { + "P" => System.Xml.XmlConvert.ToTimeSpan(value), + _ => TimeSpan.ParseExact(value, format, CultureInfo.InvariantCulture) + }; + + public static string ConvertToString(object value, string format = null) => value switch + { + null => "null", + string s => s, + bool b => ToString(b), + int or float or double or long or decimal => ((IFormattable)value).ToString(DefaultNumberFormat, CultureInfo.InvariantCulture), + byte[] b0 when format != null => ToString(b0, format), + IEnumerable s0 => string.Join(",", s0), + DateTimeOffset dateTime when format != null => ToString(dateTime, format), + TimeSpan timeSpan when format != null => ToString(timeSpan, format), + TimeSpan timeSpan0 => System.Xml.XmlConvert.ToString(timeSpan0), + Guid guid => guid.ToString(), + BinaryData binaryData => ConvertToString(binaryData.ToArray(), format), + _ => value.ToString() + }; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Utf8JsonRequestContent.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Utf8JsonRequestContent.cs new file mode 100644 index 000000000000..e996ca7e264c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Internal/Utf8JsonRequestContent.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.IO; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + internal partial class Utf8JsonRequestContent : RequestContent + { + private readonly MemoryStream _stream; + private readonly RequestContent _content; + + public Utf8JsonRequestContent() + { + _stream = new MemoryStream(); + _content = Create(_stream); + JsonWriter = new Utf8JsonWriter(_stream); + } + + /// Gets the JsonWriter. + public Utf8JsonWriter JsonWriter { get; } + + /// The stream containing the data to be written. + /// The cancellation token to use. + public override async Task WriteToAsync(Stream stream, CancellationToken cancellationToken = default) + { + await JsonWriter.FlushAsync().ConfigureAwait(false); + await _content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); + } + + /// The stream containing the data to be written. + /// The cancellation token to use. + public override void WriteTo(Stream stream, CancellationToken cancellationToken = default) + { + JsonWriter.Flush(); + _content.WriteTo(stream, cancellationToken); + } + + /// + public override bool TryComputeLength(out long length) + { + length = JsonWriter.BytesCommitted + JsonWriter.BytesPending; + return true; + } + + public override void Dispose() + { + JsonWriter.Dispose(); + _content.Dispose(); + _stream.Dispose(); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ItemStatus.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ItemStatus.cs new file mode 100644 index 000000000000..152d162766a9 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ItemStatus.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// + public readonly partial struct ItemStatus : IEquatable + { + private readonly string _value; + private const string InProgressValue = "in_progress"; + private const string CompletedValue = "completed"; + private const string IncompleteValue = "incomplete"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public ItemStatus(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the InProgress. + public static ItemStatus InProgress { get; } = new ItemStatus(InProgressValue); + + /// Gets the Completed. + public static ItemStatus Completed { get; } = new ItemStatus(CompletedValue); + + /// Gets the Incomplete. + public static ItemStatus Incomplete { get; } = new ItemStatus(IncompleteValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(ItemStatus left, ItemStatus right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(ItemStatus left, ItemStatus right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator ItemStatus(string value) => new ItemStatus(value); + + /// Converts a string to a . + /// The value. + public static implicit operator ItemStatus?(string value) => value == null ? null : new ItemStatus(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ItemStatus other && Equals(other); + + /// + public bool Equals(ItemStatus other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ItemType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ItemType.cs new file mode 100644 index 000000000000..40b80f80c283 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ItemType.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// + internal readonly partial struct ItemType : IEquatable + { + private readonly string _value; + private const string MessageValue = "message"; + private const string FunctionCallValue = "function_call"; + private const string FunctionCallOutputValue = "function_call_output"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public ItemType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the Message. + public static ItemType Message { get; } = new ItemType(MessageValue); + + /// Gets the FunctionCall. + public static ItemType FunctionCall { get; } = new ItemType(FunctionCallValue); + + /// Gets the FunctionCallOutput. + public static ItemType FunctionCallOutput { get; } = new ItemType(FunctionCallOutputValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(ItemType left, ItemType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(ItemType left, ItemType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator ItemType(string value) => new ItemType(value); + + /// Converts a string to a . + /// The value. + public static implicit operator ItemType?(string value) => value == null ? null : new ItemType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ItemType other && Equals(other); + + /// + public bool Equals(ItemType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/LogProbProperties.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/LogProbProperties.Serialization.cs new file mode 100644 index 000000000000..c78ac4441d75 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/LogProbProperties.Serialization.cs @@ -0,0 +1,168 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// A single log probability entry for a token. + public partial class LogProbProperties : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal LogProbProperties() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(LogProbProperties)} does not support writing '{format}' format."); + } + writer.WritePropertyName("token"u8); + writer.WriteStringValue(Token); + writer.WritePropertyName("logprob"u8); + writer.WriteNumberValue(Logprob); + writer.WritePropertyName("bytes"u8); + writer.WriteStartArray(); + foreach (int item in Bytes) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + LogProbProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual LogProbProperties JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(LogProbProperties)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeLogProbProperties(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static LogProbProperties DeserializeLogProbProperties(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string token = default; + float logprob = default; + IList bytes = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("token"u8)) + { + token = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("logprob"u8)) + { + logprob = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("bytes"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + bytes = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new LogProbProperties(token, logprob, bytes, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(LogProbProperties)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + LogProbProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual LogProbProperties PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeLogProbProperties(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(LogProbProperties)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/LogProbProperties.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/LogProbProperties.cs new file mode 100644 index 000000000000..85f9fea70008 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/LogProbProperties.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// A single log probability entry for a token. + public partial class LogProbProperties + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The token that was used to generate the log probability. + /// The log probability of the token. + /// The bytes that were used to generate the log probability. + internal LogProbProperties(string token, float logprob, IEnumerable bytes) + { + Token = token; + Logprob = logprob; + Bytes = bytes.ToList(); + } + + /// Initializes a new instance of . + /// The token that was used to generate the log probability. + /// The log probability of the token. + /// The bytes that were used to generate the log probability. + /// Keeps track of any properties unknown to the library. + internal LogProbProperties(string token, float logprob, IList bytes, IDictionary additionalBinaryDataProperties) + { + Token = token; + Logprob = logprob; + Bytes = bytes; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The token that was used to generate the log probability. + public string Token { get; } + + /// The log probability of the token. + public float Logprob { get; } + + /// The bytes that were used to generate the log probability. + public IList Bytes { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/MessageRole.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/MessageRole.cs new file mode 100644 index 000000000000..c5c5bface5ba --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/MessageRole.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// + public readonly partial struct MessageRole : IEquatable + { + private readonly string _value; + private const string SystemValue = "system"; + private const string UserValue = "user"; + private const string AssistantValue = "assistant"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public MessageRole(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the System. + public static MessageRole System { get; } = new MessageRole(SystemValue); + + /// Gets the User. + public static MessageRole User { get; } = new MessageRole(UserValue); + + /// Gets the Assistant. + public static MessageRole Assistant { get; } = new MessageRole(AssistantValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(MessageRole left, MessageRole right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(MessageRole left, MessageRole right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator MessageRole(string value) => new MessageRole(value); + + /// Converts a string to a . + /// The value. + public static implicit operator MessageRole?(string value) => value == null ? null : new MessageRole(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is MessageRole other && Equals(other); + + /// + public bool Equals(MessageRole other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Models/AzureAIVoiceLiveContext.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Models/AzureAIVoiceLiveContext.cs new file mode 100644 index 000000000000..5c8c2a9e5962 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Models/AzureAIVoiceLiveContext.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.ClientModel.Primitives; + +namespace Azure.AI.VoiceLive +{ + /// + /// Context class which will be filled in by the System.ClientModel.SourceGeneration. + /// For more information + /// + [ModelReaderWriterBuildable(typeof(ClientEventSessionUpdate))] + [ModelReaderWriterBuildable(typeof(RequestSession))] + [ModelReaderWriterBuildable(typeof(AnimationOptions))] + [ModelReaderWriterBuildable(typeof(InputAudio))] + [ModelReaderWriterBuildable(typeof(TurnDetection))] + [ModelReaderWriterBuildable(typeof(AudioNoiseReduction))] + [ModelReaderWriterBuildable(typeof(AudioEchoCancellation))] + [ModelReaderWriterBuildable(typeof(AvatarConfig))] + [ModelReaderWriterBuildable(typeof(IceServer))] + [ModelReaderWriterBuildable(typeof(VideoParams))] + [ModelReaderWriterBuildable(typeof(VideoCrop))] + [ModelReaderWriterBuildable(typeof(VideoResolution))] + [ModelReaderWriterBuildable(typeof(AudioInputTranscriptionSettings))] + [ModelReaderWriterBuildable(typeof(ToolCall))] + [ModelReaderWriterBuildable(typeof(AzureStandardVoice))] + [ModelReaderWriterBuildable(typeof(AzureCustomVoice))] + [ModelReaderWriterBuildable(typeof(AzurePersonalVoice))] + [ModelReaderWriterBuildable(typeof(UnknownTurnDetection))] + [ModelReaderWriterBuildable(typeof(NoTurnDetection))] + [ModelReaderWriterBuildable(typeof(ServerVad))] + [ModelReaderWriterBuildable(typeof(AzureSemanticVad))] + [ModelReaderWriterBuildable(typeof(UnknownToolCall))] + [ModelReaderWriterBuildable(typeof(FunctionTool))] + [ModelReaderWriterBuildable(typeof(ToolChoiceObject))] + [ModelReaderWriterBuildable(typeof(UnknownToolChoiceObject))] + [ModelReaderWriterBuildable(typeof(ToolChoiceFunctionObject))] + [ModelReaderWriterBuildable(typeof(ToolChoiceFunctionObjectFunction))] + [ModelReaderWriterBuildable(typeof(ClientEvent))] + [ModelReaderWriterBuildable(typeof(UnknownClientEvent))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioBufferAppend))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioBufferCommit))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioBufferClear))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioTurnStart))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioTurnAppend))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioTurnEnd))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioTurnCancel))] + [ModelReaderWriterBuildable(typeof(ClientEventInputAudioClear))] + [ModelReaderWriterBuildable(typeof(ClientEventConversationItemCreate))] + [ModelReaderWriterBuildable(typeof(ConversationItemWithReference))] + [ModelReaderWriterBuildable(typeof(ConversationItemWithReferenceContent))] + [ModelReaderWriterBuildable(typeof(ClientEventConversationItemRetrieve))] + [ModelReaderWriterBuildable(typeof(ClientEventConversationItemTruncate))] + [ModelReaderWriterBuildable(typeof(ClientEventConversationItemDelete))] + [ModelReaderWriterBuildable(typeof(ClientEventResponseCreate))] + [ModelReaderWriterBuildable(typeof(ResponseCreateParams))] + [ModelReaderWriterBuildable(typeof(ConversationRequestItem))] + [ModelReaderWriterBuildable(typeof(UnknownConversationRequestItem))] + [ModelReaderWriterBuildable(typeof(RequestMessageItem))] + [ModelReaderWriterBuildable(typeof(UnknownRequestMessageItem))] + [ModelReaderWriterBuildable(typeof(RequestSystemMessageItem))] + [ModelReaderWriterBuildable(typeof(RequestTextContentPart))] + [ModelReaderWriterBuildable(typeof(ContentPart))] + [ModelReaderWriterBuildable(typeof(UnknownContentPart))] + [ModelReaderWriterBuildable(typeof(RequestAudioContentPart))] + [ModelReaderWriterBuildable(typeof(ResponseTextContentPart))] + [ModelReaderWriterBuildable(typeof(ResponseAudioContentPart))] + [ModelReaderWriterBuildable(typeof(RequestUserMessageItem))] + [ModelReaderWriterBuildable(typeof(RequestAssistantMessageItem))] + [ModelReaderWriterBuildable(typeof(RequestFunctionCallItem))] + [ModelReaderWriterBuildable(typeof(RequestFunctionCallOutputItem))] + [ModelReaderWriterBuildable(typeof(ClientEventResponseCancel))] + [ModelReaderWriterBuildable(typeof(ClientEventSessionAvatarConnect))] + [ModelReaderWriterBuildable(typeof(ForceModelsRequest))] + [ModelReaderWriterBuildable(typeof(ServerEventSessionAvatarConnecting))] + [ModelReaderWriterBuildable(typeof(ServerEvent))] + [ModelReaderWriterBuildable(typeof(UnknownServerEvent))] + [ModelReaderWriterBuildable(typeof(ServerEventSessionCreated))] + [ModelReaderWriterBuildable(typeof(ResponseSession))] + [ModelReaderWriterBuildable(typeof(RespondingAgentConfig))] + [ModelReaderWriterBuildable(typeof(ServerEventSessionUpdated))] + [ModelReaderWriterBuildable(typeof(ServerEventError))] + [ModelReaderWriterBuildable(typeof(ServerEventErrorError))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseTextDelta))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAudioDelta))] + [ModelReaderWriterBuildable(typeof(ServerEventConversationItemCreated))] + [ModelReaderWriterBuildable(typeof(ServerEventConversationItemDeleted))] + [ModelReaderWriterBuildable(typeof(ServerEventConversationItemRetrieved))] + [ModelReaderWriterBuildable(typeof(ServerEventConversationItemTruncated))] + [ModelReaderWriterBuildable(typeof(ServerEventConversationItemInputAudioTranscriptionCompleted))] + [ModelReaderWriterBuildable(typeof(ServerEventConversationItemInputAudioTranscriptionDelta))] + [ModelReaderWriterBuildable(typeof(LogProbProperties))] + [ModelReaderWriterBuildable(typeof(ServerEventConversationItemInputAudioTranscriptionFailed))] + [ModelReaderWriterBuildable(typeof(VoiceLiveErrorDetails))] + [ModelReaderWriterBuildable(typeof(ServerEventInputAudioBufferCommitted))] + [ModelReaderWriterBuildable(typeof(ServerEventInputAudioBufferCleared))] + [ModelReaderWriterBuildable(typeof(ServerEventInputAudioBufferSpeechStarted))] + [ModelReaderWriterBuildable(typeof(ServerEventInputAudioBufferSpeechStopped))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseCreated))] + [ModelReaderWriterBuildable(typeof(VoiceLiveResponse))] + [ModelReaderWriterBuildable(typeof(ResponseStatusDetails))] + [ModelReaderWriterBuildable(typeof(ResponseStatusDetailsError))] + [ModelReaderWriterBuildable(typeof(ConversationResponseItem))] + [ModelReaderWriterBuildable(typeof(ResponseUsage))] + [ModelReaderWriterBuildable(typeof(ResponseUsageInputTokenDetails))] + [ModelReaderWriterBuildable(typeof(ResponseUsageOutputTokenDetails))] + [ModelReaderWriterBuildable(typeof(UnknownConversationResponseItem))] + [ModelReaderWriterBuildable(typeof(ResponseMessageItem))] + [ModelReaderWriterBuildable(typeof(ResponseFunctionCallItem))] + [ModelReaderWriterBuildable(typeof(ResponseFunctionCallOutputItem))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseOutputItemAdded))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseOutputItemDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseContentPartAdded))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseContentPartDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseTextDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAudioTranscriptDelta))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAudioTranscriptDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAudioDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseFunctionCallArgumentsDelta))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseFunctionCallArgumentsDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAnimationBlendshapeDelta))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAnimationBlendshapeDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseEmotionHypothesis))] + [ModelReaderWriterBuildable(typeof(EmotionCandidate))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAudioTimestampDelta))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAudioTimestampDone))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAnimationVisemeDelta))] + [ModelReaderWriterBuildable(typeof(ServerEventResponseAnimationVisemeDone))] + public partial class AzureAIVoiceLiveContext : ModelReaderWriterContext + { + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/NoTurnDetection.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/NoTurnDetection.Serialization.cs new file mode 100644 index 000000000000..649b86745cc6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/NoTurnDetection.Serialization.cs @@ -0,0 +1,121 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Disables turn detection. + public partial class NoTurnDetection : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NoTurnDetection)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + NoTurnDetection IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (NoTurnDetection)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override TurnDetection JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(NoTurnDetection)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeNoTurnDetection(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static NoTurnDetection DeserializeNoTurnDetection(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + TurnDetectionType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString().ToTurnDetectionType(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new NoTurnDetection(@type, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(NoTurnDetection)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + NoTurnDetection IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (NoTurnDetection)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override TurnDetection PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeNoTurnDetection(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(NoTurnDetection)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/NoTurnDetection.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/NoTurnDetection.cs new file mode 100644 index 000000000000..d1d1b7fe39de --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/NoTurnDetection.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Disables turn detection. + public partial class NoTurnDetection : TurnDetection + { + /// Initializes a new instance of . + public NoTurnDetection() : base(TurnDetectionType.None) + { + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal NoTurnDetection(TurnDetectionType @type, IDictionary additionalBinaryDataProperties) : base(@type, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/OAIVoice.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/OAIVoice.Serialization.cs new file mode 100644 index 000000000000..179ca1b43b3c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/OAIVoice.Serialization.cs @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class OAIVoiceExtensions + { + /// The value to serialize. + public static string ToSerialString(this OAIVoice value) => value switch + { + OAIVoice.Alloy => "alloy", + OAIVoice.Ash => "ash", + OAIVoice.Ballad => "ballad", + OAIVoice.Coral => "coral", + OAIVoice.Echo => "echo", + OAIVoice.Sage => "sage", + OAIVoice.Shimmer => "shimmer", + OAIVoice.Verse => "verse", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown OAIVoice value.") + }; + + /// The value to deserialize. + public static OAIVoice ToOAIVoice(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "alloy")) + { + return OAIVoice.Alloy; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "ash")) + { + return OAIVoice.Ash; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "ballad")) + { + return OAIVoice.Ballad; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "coral")) + { + return OAIVoice.Coral; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "echo")) + { + return OAIVoice.Echo; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "sage")) + { + return OAIVoice.Sage; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "shimmer")) + { + return OAIVoice.Shimmer; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "verse")) + { + return OAIVoice.Verse; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown OAIVoice value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/OAIVoice.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/OAIVoice.cs new file mode 100644 index 000000000000..3e195a7e2394 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/OAIVoice.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// Voice identifier for OpenAI-provided voices. + public enum OAIVoice + { + /// Alloy. + Alloy, + /// Ash. + Ash, + /// Ballad. + Ballad, + /// Coral. + Coral, + /// Echo. + Echo, + /// Sage. + Sage, + /// Shimmer. + Shimmer, + /// Verse. + Verse + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Phi4mmVoice.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Phi4mmVoice.Serialization.cs new file mode 100644 index 000000000000..60e48a3e8a9b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Phi4mmVoice.Serialization.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class Phi4mmVoiceExtensions + { + /// The value to serialize. + public static string ToSerialString(this Phi4mmVoice value) => value switch + { + Phi4mmVoice.Cosyvoice => "cosyvoice", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown Phi4mmVoice value.") + }; + + /// The value to deserialize. + public static Phi4mmVoice ToPhi4mmVoice(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "cosyvoice")) + { + return Phi4mmVoice.Cosyvoice; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown Phi4mmVoice value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/Phi4mmVoice.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Phi4mmVoice.cs new file mode 100644 index 000000000000..f99d6764c80c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/Phi4mmVoice.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// Voice identifier for Phi4mm voices. + public enum Phi4mmVoice + { + /// Cosyvoice. + Cosyvoice + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAssistantMessageItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAssistantMessageItem.Serialization.cs new file mode 100644 index 000000000000..27abf2b7be2b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAssistantMessageItem.Serialization.cs @@ -0,0 +1,172 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestAssistantMessageItem. + internal partial class RequestAssistantMessageItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal RequestAssistantMessageItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestAssistantMessageItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("content"u8); + writer.WriteStartArray(); + foreach (RequestTextContentPart item in Content) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestAssistantMessageItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestAssistantMessageItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestAssistantMessageItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestAssistantMessageItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestAssistantMessageItem DeserializeRequestAssistantMessageItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + MessageRole role = default; + ItemStatus? status = default; + IList content = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("role"u8)) + { + role = new MessageRole(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("status"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = new ItemStatus(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("content"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(RequestTextContentPart.DeserializeRequestTextContentPart(item, options)); + } + content = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestAssistantMessageItem( + @type, + id, + additionalBinaryDataProperties, + role, + status, + content); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestAssistantMessageItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestAssistantMessageItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestAssistantMessageItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestAssistantMessageItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestAssistantMessageItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAssistantMessageItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAssistantMessageItem.cs new file mode 100644 index 000000000000..e08777b69681 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAssistantMessageItem.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// The RequestAssistantMessageItem. + internal partial class RequestAssistantMessageItem : RequestMessageItem + { + /// Initializes a new instance of . + /// + /// is null. + public RequestAssistantMessageItem(IEnumerable content) : base(MessageRole.Assistant) + { + Argument.AssertNotNull(content, nameof(content)); + + Content = content.ToList(); + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + internal RequestAssistantMessageItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties, MessageRole role, ItemStatus? status, IList content) : base(@type, id, additionalBinaryDataProperties, role, status) + { + Content = content; + } + + /// Gets the Content. + public IList Content { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAudioContentPart.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAudioContentPart.Serialization.cs new file mode 100644 index 000000000000..bb3924d26ca9 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAudioContentPart.Serialization.cs @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestAudioContentPart. + public partial class RequestAudioContentPart : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestAudioContentPart)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(Transcript)) + { + writer.WritePropertyName("transcript"u8); + writer.WriteStringValue(Transcript); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestAudioContentPart IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestAudioContentPart)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ContentPart JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestAudioContentPart)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestAudioContentPart(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestAudioContentPart DeserializeRequestAudioContentPart(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ContentPartType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string transcript = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ContentPartType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("transcript"u8)) + { + transcript = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestAudioContentPart(@type, additionalBinaryDataProperties, transcript); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestAudioContentPart)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestAudioContentPart IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestAudioContentPart)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ContentPart PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestAudioContentPart(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestAudioContentPart)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAudioContentPart.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAudioContentPart.cs new file mode 100644 index 000000000000..a783f84321e4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestAudioContentPart.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The RequestAudioContentPart. + public partial class RequestAudioContentPart : ContentPart + { + /// Initializes a new instance of . + public RequestAudioContentPart() : base(ContentPartType.InputAudio) + { + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + internal RequestAudioContentPart(ContentPartType @type, IDictionary additionalBinaryDataProperties, string transcript) : base(@type, additionalBinaryDataProperties) + { + Transcript = transcript; + } + + /// Gets or sets the Transcript. + public string Transcript { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallItem.Serialization.cs new file mode 100644 index 000000000000..9ea291691fc5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallItem.Serialization.cs @@ -0,0 +1,178 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestFunctionCallItem. + internal partial class RequestFunctionCallItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal RequestFunctionCallItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestFunctionCallItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("call_id"u8); + writer.WriteStringValue(CallId); + writer.WritePropertyName("arguments"u8); + writer.WriteStringValue(Arguments); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteStringValue(Status.Value.ToString()); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestFunctionCallItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestFunctionCallItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestFunctionCallItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestFunctionCallItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestFunctionCallItem DeserializeRequestFunctionCallItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string name = default; + string callId = default; + string arguments = default; + ItemStatus? status = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("call_id"u8)) + { + callId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("arguments"u8)) + { + arguments = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("status"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = new ItemStatus(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestFunctionCallItem( + @type, + id, + additionalBinaryDataProperties, + name, + callId, + arguments, + status); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestFunctionCallItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestFunctionCallItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestFunctionCallItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestFunctionCallItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestFunctionCallItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallItem.cs new file mode 100644 index 000000000000..097029ad0cf3 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallItem.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The RequestFunctionCallItem. + internal partial class RequestFunctionCallItem : ConversationRequestItem + { + /// Initializes a new instance of . + /// + /// + /// + /// , or is null. + public RequestFunctionCallItem(string name, string callId, string arguments) : base(ItemType.FunctionCall) + { + Argument.AssertNotNull(name, nameof(name)); + Argument.AssertNotNull(callId, nameof(callId)); + Argument.AssertNotNull(arguments, nameof(arguments)); + + Name = name; + CallId = callId; + Arguments = arguments; + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + internal RequestFunctionCallItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties, string name, string callId, string arguments, ItemStatus? status) : base(@type, id, additionalBinaryDataProperties) + { + Name = name; + CallId = callId; + Arguments = arguments; + Status = status; + } + + /// Gets the Name. + public string Name { get; } + + /// Gets the CallId. + public string CallId { get; } + + /// Gets the Arguments. + public string Arguments { get; } + + /// Gets or sets the Status. + public ItemStatus? Status { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallOutputItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallOutputItem.Serialization.cs new file mode 100644 index 000000000000..a0a28249f74a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallOutputItem.Serialization.cs @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestFunctionCallOutputItem. + internal partial class RequestFunctionCallOutputItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal RequestFunctionCallOutputItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestFunctionCallOutputItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("call_id"u8); + writer.WriteStringValue(CallId); + writer.WritePropertyName("output"u8); + writer.WriteStringValue(Output); + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestFunctionCallOutputItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestFunctionCallOutputItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestFunctionCallOutputItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestFunctionCallOutputItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestFunctionCallOutputItem DeserializeRequestFunctionCallOutputItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string callId = default; + string output = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("call_id"u8)) + { + callId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output"u8)) + { + output = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestFunctionCallOutputItem(@type, id, additionalBinaryDataProperties, callId, output); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestFunctionCallOutputItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestFunctionCallOutputItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestFunctionCallOutputItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestFunctionCallOutputItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestFunctionCallOutputItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallOutputItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallOutputItem.cs new file mode 100644 index 000000000000..eb2cfe88401c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestFunctionCallOutputItem.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The RequestFunctionCallOutputItem. + internal partial class RequestFunctionCallOutputItem : ConversationRequestItem + { + /// Initializes a new instance of . + /// + /// + /// or is null. + public RequestFunctionCallOutputItem(string callId, string output) : base(ItemType.FunctionCallOutput) + { + Argument.AssertNotNull(callId, nameof(callId)); + Argument.AssertNotNull(output, nameof(output)); + + CallId = callId; + Output = output; + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + internal RequestFunctionCallOutputItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties, string callId, string output) : base(@type, id, additionalBinaryDataProperties) + { + CallId = callId; + Output = output; + } + + /// Gets the CallId. + public string CallId { get; } + + /// Gets the Output. + public string Output { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestMessageItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestMessageItem.Serialization.cs new file mode 100644 index 000000000000..88d9b4a129d8 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestMessageItem.Serialization.cs @@ -0,0 +1,130 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestMessageItem. + internal partial class RequestMessageItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal RequestMessageItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("role"u8); + writer.WriteStringValue(Role.ToString()); + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteStringValue(Status.Value.ToString()); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestMessageItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestMessageItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestMessageItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestMessageItem DeserializeRequestMessageItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("role"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "system": + return RequestSystemMessageItem.DeserializeRequestSystemMessageItem(element, options); + case "user": + return RequestUserMessageItem.DeserializeRequestUserMessageItem(element, options); + case "assistant": + return RequestAssistantMessageItem.DeserializeRequestAssistantMessageItem(element, options); + } + } + return UnknownRequestMessageItem.DeserializeUnknownRequestMessageItem(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestMessageItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestMessageItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestMessageItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestMessageItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestMessageItem.cs new file mode 100644 index 000000000000..0f89bc86f41a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestMessageItem.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The RequestMessageItem. + internal partial class RequestMessageItem : ConversationRequestItem + { + /// Initializes a new instance of . + /// + public RequestMessageItem(MessageRole role) : base(ItemType.Message) + { + Role = role; + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + internal RequestMessageItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties, MessageRole role, ItemStatus? status) : base(@type, id, additionalBinaryDataProperties) + { + Role = role; + Status = status; + } + + /// Gets or sets the Role. + internal MessageRole Role { get; set; } + + /// Gets or sets the Status. + public ItemStatus? Status { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSession.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSession.Serialization.cs new file mode 100644 index 000000000000..16b35f295c21 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSession.Serialization.cs @@ -0,0 +1,478 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestSession. + public partial class RequestSession : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestSession)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Model)) + { + writer.WritePropertyName("model"u8); + writer.WriteStringValue(Model); + } + if (Optional.IsCollectionDefined(Modalities)) + { + writer.WritePropertyName("modalities"u8); + writer.WriteStartArray(); + foreach (InputModality item in Modalities) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Animation)) + { + writer.WritePropertyName("animation"u8); + writer.WriteObjectValue(Animation, options); + } + if (Optional.IsDefined(Instructions)) + { + writer.WritePropertyName("instructions"u8); + writer.WriteStringValue(Instructions); + } + if (Optional.IsDefined(InputAudio)) + { + writer.WritePropertyName("input_audio"u8); + writer.WriteObjectValue(InputAudio, options); + } + if (Optional.IsDefined(InputAudioSamplingRate)) + { + writer.WritePropertyName("input_audio_sampling_rate"u8); + writer.WriteNumberValue(InputAudioSamplingRate.Value); + } + if (Optional.IsDefined(InputAudioFormat)) + { + writer.WritePropertyName("input_audio_format"u8); + writer.WriteStringValue(InputAudioFormat.Value.ToString()); + } + if (Optional.IsDefined(OutputAudioFormat)) + { + writer.WritePropertyName("output_audio_format"u8); + writer.WriteStringValue(OutputAudioFormat.Value.ToString()); + } + if (Optional.IsDefined(TurnDetection)) + { + writer.WritePropertyName("turn_detection"u8); + writer.WriteObjectValue(TurnDetection, options); + } + if (Optional.IsDefined(InputAudioNoiseReduction)) + { + writer.WritePropertyName("input_audio_noise_reduction"u8); + writer.WriteObjectValue(InputAudioNoiseReduction, options); + } + if (Optional.IsDefined(InputAudioEchoCancellation)) + { + writer.WritePropertyName("input_audio_echo_cancellation"u8); + writer.WriteObjectValue(InputAudioEchoCancellation, options); + } + if (Optional.IsDefined(Avatar)) + { + writer.WritePropertyName("avatar"u8); + writer.WriteObjectValue(Avatar, options); + } + if (Optional.IsDefined(InputAudioTranscription)) + { + writer.WritePropertyName("input_audio_transcription"u8); + writer.WriteObjectValue(InputAudioTranscription, options); + } + if (Optional.IsCollectionDefined(OutputAudioTimestampTypes)) + { + writer.WritePropertyName("output_audio_timestamp_types"u8); + writer.WriteStartArray(); + foreach (AudioTimestampType item in OutputAudioTimestampTypes) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(Tools)) + { + writer.WritePropertyName("tools"u8); + writer.WriteStartArray(); + foreach (ToolCall item in Tools) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Temperature)) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (Optional.IsDefined(_servcieVoice)) + { + writer.WritePropertyName("voice"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(_servcieVoice); +#else + using (JsonDocument document = JsonDocument.Parse(_servcieVoice)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(_maxResponseOutputTokens)) + { + writer.WritePropertyName("max_response_output_tokens"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(_maxResponseOutputTokens); +#else + using (JsonDocument document = JsonDocument.Parse(_maxResponseOutputTokens)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(_toolChoice)) + { + writer.WritePropertyName("tool_choice"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(_toolChoice); +#else + using (JsonDocument document = JsonDocument.Parse(_toolChoice)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestSession IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual RequestSession JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestSession)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestSession(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestSession DeserializeRequestSession(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string model = default; + IList modalities = default; + AnimationOptions animation = default; + string instructions = default; + InputAudio inputAudio = default; + int? inputAudioSamplingRate = default; + AudioFormat? inputAudioFormat = default; + AudioFormat? outputAudioFormat = default; + TurnDetection turnDetection = default; + AudioNoiseReduction inputAudioNoiseReduction = default; + AudioEchoCancellation inputAudioEchoCancellation = default; + AvatarConfig avatar = default; + AudioInputTranscriptionSettings inputAudioTranscription = default; + IList outputAudioTimestampTypes = default; + IList tools = default; + float? temperature = default; + BinaryData servcieVoice = default; + BinaryData maxResponseOutputTokens = default; + BinaryData toolChoice = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("model"u8)) + { + model = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("modalities"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new InputModality(item.GetString())); + } + modalities = array; + continue; + } + if (prop.NameEquals("animation"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + animation = AnimationOptions.DeserializeAnimationOptions(prop.Value, options); + continue; + } + if (prop.NameEquals("instructions"u8)) + { + instructions = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("input_audio"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudio = InputAudio.DeserializeInputAudio(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_sampling_rate"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioSamplingRate = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("input_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioFormat = new AudioFormat(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("output_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputAudioFormat = new AudioFormat(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("turn_detection"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + turnDetection = null; + continue; + } + turnDetection = TurnDetection.DeserializeTurnDetection(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_noise_reduction"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioNoiseReduction = AudioNoiseReduction.DeserializeAudioNoiseReduction(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_echo_cancellation"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioEchoCancellation = AudioEchoCancellation.DeserializeAudioEchoCancellation(prop.Value, options); + continue; + } + if (prop.NameEquals("avatar"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + avatar = AvatarConfig.DeserializeAvatarConfig(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_transcription"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioTranscription = AudioInputTranscriptionSettings.DeserializeAudioInputTranscriptionSettings(prop.Value, options); + continue; + } + if (prop.NameEquals("output_audio_timestamp_types"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new AudioTimestampType(item.GetString())); + } + outputAudioTimestampTypes = array; + continue; + } + if (prop.NameEquals("tools"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ToolCall.DeserializeToolCall(item, options)); + } + tools = array; + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("voice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + servcieVoice = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("max_response_output_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + maxResponseOutputTokens = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("tool_choice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + toolChoice = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestSession( + model, + modalities ?? new ChangeTrackingList(), + animation, + instructions, + inputAudio, + inputAudioSamplingRate, + inputAudioFormat, + outputAudioFormat, + turnDetection, + inputAudioNoiseReduction, + inputAudioEchoCancellation, + avatar, + inputAudioTranscription, + outputAudioTimestampTypes ?? new ChangeTrackingList(), + tools ?? new ChangeTrackingList(), + temperature, + servcieVoice, + maxResponseOutputTokens, + toolChoice, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestSession)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestSession IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual RequestSession PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestSession(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestSession)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSession.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSession.cs new file mode 100644 index 000000000000..1760906eb4a2 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSession.cs @@ -0,0 +1,120 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The RequestSession. + public partial class RequestSession + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public RequestSession() + { + Modalities = new ChangeTrackingList(); + OutputAudioTimestampTypes = new ChangeTrackingList(); + Tools = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal RequestSession(string model, IList modalities, AnimationOptions animation, string instructions, InputAudio inputAudio, int? inputAudioSamplingRate, AudioFormat? inputAudioFormat, AudioFormat? outputAudioFormat, TurnDetection turnDetection, AudioNoiseReduction inputAudioNoiseReduction, AudioEchoCancellation inputAudioEchoCancellation, AvatarConfig avatar, AudioInputTranscriptionSettings inputAudioTranscription, IList outputAudioTimestampTypes, IList tools, float? temperature, BinaryData servcieVoice, BinaryData maxResponseOutputTokens, BinaryData toolChoice, IDictionary additionalBinaryDataProperties) + { + Model = model; + Modalities = modalities; + Animation = animation; + Instructions = instructions; + InputAudio = inputAudio; + InputAudioSamplingRate = inputAudioSamplingRate; + InputAudioFormat = inputAudioFormat; + OutputAudioFormat = outputAudioFormat; + TurnDetection = turnDetection; + InputAudioNoiseReduction = inputAudioNoiseReduction; + InputAudioEchoCancellation = inputAudioEchoCancellation; + Avatar = avatar; + InputAudioTranscription = inputAudioTranscription; + OutputAudioTimestampTypes = outputAudioTimestampTypes; + Tools = tools; + Temperature = temperature; + _servcieVoice = servcieVoice; + _maxResponseOutputTokens = maxResponseOutputTokens; + _toolChoice = toolChoice; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets or sets the Model. + public string Model { get; set; } + + /// Gets the Modalities. + public IList Modalities { get; } + + /// Gets or sets the Animation. + public AnimationOptions Animation { get; set; } + + /// Gets or sets the Instructions. + public string Instructions { get; set; } + + /// Gets or sets the InputAudio. + public InputAudio InputAudio { get; set; } + + /// Gets or sets the InputAudioSamplingRate. + public int? InputAudioSamplingRate { get; set; } + + /// Gets or sets the InputAudioFormat. + public AudioFormat? InputAudioFormat { get; set; } + + /// Gets or sets the OutputAudioFormat. + public AudioFormat? OutputAudioFormat { get; set; } + + /// Gets or sets the TurnDetection. + public TurnDetection TurnDetection { get; set; } + + /// Gets or sets the InputAudioNoiseReduction. + public AudioNoiseReduction InputAudioNoiseReduction { get; set; } + + /// Gets or sets the InputAudioEchoCancellation. + public AudioEchoCancellation InputAudioEchoCancellation { get; set; } + + /// Gets or sets the Avatar. + public AvatarConfig Avatar { get; set; } + + /// Gets or sets the InputAudioTranscription. + public AudioInputTranscriptionSettings InputAudioTranscription { get; set; } + + /// Gets the OutputAudioTimestampTypes. + public IList OutputAudioTimestampTypes { get; } + + /// Gets the Tools. + public IList Tools { get; } + + /// Gets or sets the Temperature. + public float? Temperature { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSystemMessageItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSystemMessageItem.Serialization.cs new file mode 100644 index 000000000000..821fd761379a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSystemMessageItem.Serialization.cs @@ -0,0 +1,172 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestSystemMessageItem. + internal partial class RequestSystemMessageItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal RequestSystemMessageItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestSystemMessageItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("content"u8); + writer.WriteStartArray(); + foreach (RequestTextContentPart item in Content) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestSystemMessageItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestSystemMessageItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestSystemMessageItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestSystemMessageItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestSystemMessageItem DeserializeRequestSystemMessageItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + MessageRole role = default; + ItemStatus? status = default; + IList content = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("role"u8)) + { + role = new MessageRole(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("status"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = new ItemStatus(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("content"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(RequestTextContentPart.DeserializeRequestTextContentPart(item, options)); + } + content = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestSystemMessageItem( + @type, + id, + additionalBinaryDataProperties, + role, + status, + content); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestSystemMessageItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestSystemMessageItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestSystemMessageItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestSystemMessageItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestSystemMessageItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSystemMessageItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSystemMessageItem.cs new file mode 100644 index 000000000000..9d1a75cdf16a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestSystemMessageItem.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// The RequestSystemMessageItem. + internal partial class RequestSystemMessageItem : RequestMessageItem + { + /// Initializes a new instance of . + /// + /// is null. + public RequestSystemMessageItem(IEnumerable content) : base(MessageRole.System) + { + Argument.AssertNotNull(content, nameof(content)); + + Content = content.ToList(); + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + internal RequestSystemMessageItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties, MessageRole role, ItemStatus? status, IList content) : base(@type, id, additionalBinaryDataProperties, role, status) + { + Content = content; + } + + /// Gets the Content. + public IList Content { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestTextContentPart.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestTextContentPart.Serialization.cs new file mode 100644 index 000000000000..dc2c18e95b13 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestTextContentPart.Serialization.cs @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestTextContentPart. + public partial class RequestTextContentPart : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestTextContentPart)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(Text)) + { + writer.WritePropertyName("text"u8); + writer.WriteStringValue(Text); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestTextContentPart IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestTextContentPart)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ContentPart JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestTextContentPart)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestTextContentPart(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestTextContentPart DeserializeRequestTextContentPart(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ContentPartType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string text = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ContentPartType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("text"u8)) + { + text = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestTextContentPart(@type, additionalBinaryDataProperties, text); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestTextContentPart)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestTextContentPart IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestTextContentPart)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ContentPart PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestTextContentPart(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestTextContentPart)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestTextContentPart.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestTextContentPart.cs new file mode 100644 index 000000000000..b933eb39ae8a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestTextContentPart.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The RequestTextContentPart. + public partial class RequestTextContentPart : ContentPart + { + /// Initializes a new instance of . + public RequestTextContentPart() : base(ContentPartType.InputText) + { + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + internal RequestTextContentPart(ContentPartType @type, IDictionary additionalBinaryDataProperties, string text) : base(@type, additionalBinaryDataProperties) + { + Text = text; + } + + /// Gets or sets the Text. + public string Text { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestUserMessageItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestUserMessageItem.Serialization.cs new file mode 100644 index 000000000000..5c60aca6995b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestUserMessageItem.Serialization.cs @@ -0,0 +1,191 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestUserMessageItem. + internal partial class RequestUserMessageItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal RequestUserMessageItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestUserMessageItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("content"u8); + writer.WriteStartArray(); + foreach (BinaryData item in Content) + { + if (item == null) + { + writer.WriteNullValue(); + continue; + } +#if NET6_0_OR_GREATER + writer.WriteRawValue(item); +#else + using (JsonDocument document = JsonDocument.Parse(item)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + writer.WriteEndArray(); + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestUserMessageItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (RequestUserMessageItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestUserMessageItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestUserMessageItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RequestUserMessageItem DeserializeRequestUserMessageItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + MessageRole role = default; + ItemStatus? status = default; + IList content = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("role"u8)) + { + role = new MessageRole(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("status"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = new ItemStatus(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("content"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + if (item.ValueKind == JsonValueKind.Null) + { + array.Add(null); + } + else + { + array.Add(BinaryData.FromString(item.GetRawText())); + } + } + content = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RequestUserMessageItem( + @type, + id, + additionalBinaryDataProperties, + role, + status, + content); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestUserMessageItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestUserMessageItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RequestUserMessageItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestUserMessageItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestUserMessageItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestUserMessageItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestUserMessageItem.cs new file mode 100644 index 000000000000..d683aaa8779e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RequestUserMessageItem.cs @@ -0,0 +1,81 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RequestUserMessageItem. + internal partial class RequestUserMessageItem : RequestMessageItem + { + /// Initializes a new instance of . + /// + /// is null. + public RequestUserMessageItem(IEnumerable content) : base(MessageRole.User) + { + Argument.AssertNotNull(content, nameof(content)); + + Content = content.ToList(); + } + + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + internal RequestUserMessageItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties, MessageRole role, ItemStatus? status, IList content) : base(@type, id, additionalBinaryDataProperties, role, status) + { + Content = content; + } + + /// + /// Gets the Content. + /// To assign an object to the element of this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// . + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public IList Content { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RespondingAgentConfig.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RespondingAgentConfig.Serialization.cs new file mode 100644 index 000000000000..80abd429fcc4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RespondingAgentConfig.Serialization.cs @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The RespondingAgentConfig. + public partial class RespondingAgentConfig : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal RespondingAgentConfig() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RespondingAgentConfig)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + if (Optional.IsDefined(Description)) + { + writer.WritePropertyName("description"u8); + writer.WriteStringValue(Description); + } + writer.WritePropertyName("agent_id"u8); + writer.WriteStringValue(AgentId); + writer.WritePropertyName("thread_id"u8); + writer.WriteStringValue(ThreadId); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + RespondingAgentConfig IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual RespondingAgentConfig JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RespondingAgentConfig)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRespondingAgentConfig(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static RespondingAgentConfig DeserializeRespondingAgentConfig(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @type = default; + string name = default; + string description = default; + string agentId = default; + string threadId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("description"u8)) + { + description = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("agent_id"u8)) + { + agentId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("thread_id"u8)) + { + threadId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new RespondingAgentConfig( + @type, + name, + description, + agentId, + threadId, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RespondingAgentConfig)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RespondingAgentConfig IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual RespondingAgentConfig PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRespondingAgentConfig(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RespondingAgentConfig)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/RespondingAgentConfig.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RespondingAgentConfig.cs new file mode 100644 index 000000000000..e960e5162162 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/RespondingAgentConfig.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The RespondingAgentConfig. + public partial class RespondingAgentConfig + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + /// + /// + internal RespondingAgentConfig(string name, string agentId, string threadId) + { + Name = name; + AgentId = agentId; + ThreadId = threadId; + } + + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal RespondingAgentConfig(string @type, string name, string description, string agentId, string threadId, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Name = name; + Description = description; + AgentId = agentId; + ThreadId = threadId; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Type. + public string Type { get; } = "agent"; + + /// Gets the Name. + public string Name { get; } + + /// Gets the Description. + public string Description { get; } + + /// Gets the AgentId. + public string AgentId { get; } + + /// Gets the ThreadId. + public string ThreadId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseAudioContentPart.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseAudioContentPart.Serialization.cs new file mode 100644 index 000000000000..fe38e84cdd4c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseAudioContentPart.Serialization.cs @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseAudioContentPart. + public partial class ResponseAudioContentPart : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseAudioContentPart)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(Transcript)) + { + writer.WritePropertyName("transcript"u8); + writer.WriteStringValue(Transcript); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseAudioContentPart IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ResponseAudioContentPart)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ContentPart JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseAudioContentPart)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseAudioContentPart(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseAudioContentPart DeserializeResponseAudioContentPart(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ContentPartType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string transcript = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ContentPartType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("transcript"u8)) + { + transcript = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseAudioContentPart(@type, additionalBinaryDataProperties, transcript); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseAudioContentPart)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseAudioContentPart IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ResponseAudioContentPart)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ContentPart PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseAudioContentPart(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseAudioContentPart)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseAudioContentPart.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseAudioContentPart.cs new file mode 100644 index 000000000000..32499ad28d84 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseAudioContentPart.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseAudioContentPart. + public partial class ResponseAudioContentPart : ContentPart + { + /// Initializes a new instance of . + internal ResponseAudioContentPart() : base(ContentPartType.Audio) + { + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + internal ResponseAudioContentPart(ContentPartType @type, IDictionary additionalBinaryDataProperties, string transcript) : base(@type, additionalBinaryDataProperties) + { + Transcript = transcript; + } + + /// Gets the Transcript. + public string Transcript { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseCreateParams.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseCreateParams.Serialization.cs new file mode 100644 index 000000000000..fe17c5aa5979 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseCreateParams.Serialization.cs @@ -0,0 +1,368 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Create a new VoiceLive response with these parameters. + internal partial class ResponseCreateParams : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseCreateParams)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Commit)) + { + writer.WritePropertyName("commit"u8); + writer.WriteBooleanValue(Commit.Value); + } + if (Optional.IsDefined(CancelPrevious)) + { + writer.WritePropertyName("cancel_previous"u8); + writer.WriteBooleanValue(CancelPrevious.Value); + } + if (Optional.IsCollectionDefined(AppendInputItems)) + { + writer.WritePropertyName("append_input_items"u8); + writer.WriteStartArray(); + foreach (ConversationRequestItem item in AppendInputItems) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(InputItems)) + { + writer.WritePropertyName("input_items"u8); + writer.WriteStartArray(); + foreach (ConversationRequestItem item in InputItems) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(Modalities)) + { + writer.WritePropertyName("modalities"u8); + writer.WriteStartArray(); + foreach (InputModality item in Modalities) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Instructions)) + { + writer.WritePropertyName("instructions"u8); + writer.WriteStringValue(Instructions); + } + if (Optional.IsDefined(Voice)) + { + writer.WritePropertyName("voice"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Voice); +#else + using (JsonDocument document = JsonDocument.Parse(Voice)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(OutputAudioFormat)) + { + writer.WritePropertyName("output_audio_format"u8); + writer.WriteStringValue(OutputAudioFormat.Value.ToString()); + } + if (Optional.IsCollectionDefined(Tools)) + { + writer.WritePropertyName("tools"u8); + writer.WriteStartArray(); + foreach (ToolCall item in Tools) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(ToolChoice)) + { + writer.WritePropertyName("tool_choice"u8); + writer.WriteStringValue(ToolChoice); + } + if (Optional.IsDefined(Temperature)) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (Optional.IsDefined(MaxOutputTokens)) + { + writer.WritePropertyName("max_output_tokens"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(MaxOutputTokens); +#else + using (JsonDocument document = JsonDocument.Parse(MaxOutputTokens)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseCreateParams IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ResponseCreateParams JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseCreateParams)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseCreateParams(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseCreateParams DeserializeResponseCreateParams(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + bool? commit = default; + bool? cancelPrevious = default; + IList appendInputItems = default; + IList inputItems = default; + IList modalities = default; + string instructions = default; + BinaryData voice = default; + AudioFormat? outputAudioFormat = default; + IList tools = default; + string toolChoice = default; + float? temperature = default; + BinaryData maxOutputTokens = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("commit"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + commit = prop.Value.GetBoolean(); + continue; + } + if (prop.NameEquals("cancel_previous"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + cancelPrevious = prop.Value.GetBoolean(); + continue; + } + if (prop.NameEquals("append_input_items"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ConversationRequestItem.DeserializeConversationRequestItem(item, options)); + } + appendInputItems = array; + continue; + } + if (prop.NameEquals("input_items"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ConversationRequestItem.DeserializeConversationRequestItem(item, options)); + } + inputItems = array; + continue; + } + if (prop.NameEquals("modalities"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new InputModality(item.GetString())); + } + modalities = array; + continue; + } + if (prop.NameEquals("instructions"u8)) + { + instructions = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("voice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + voice = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("output_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputAudioFormat = new AudioFormat(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("tools"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ToolCall.DeserializeToolCall(item, options)); + } + tools = array; + continue; + } + if (prop.NameEquals("tool_choice"u8)) + { + toolChoice = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("max_output_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + maxOutputTokens = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseCreateParams( + commit, + cancelPrevious, + appendInputItems ?? new ChangeTrackingList(), + inputItems ?? new ChangeTrackingList(), + modalities ?? new ChangeTrackingList(), + instructions, + voice, + outputAudioFormat, + tools ?? new ChangeTrackingList(), + toolChoice, + temperature, + maxOutputTokens, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseCreateParams)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseCreateParams IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ResponseCreateParams PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseCreateParams(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseCreateParams)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseCreateParams.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseCreateParams.cs new file mode 100644 index 000000000000..eb759da2a24c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseCreateParams.cs @@ -0,0 +1,233 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Create a new VoiceLive response with these parameters. + internal partial class ResponseCreateParams + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public ResponseCreateParams() + { + AppendInputItems = new ChangeTrackingList(); + InputItems = new ChangeTrackingList(); + Modalities = new ChangeTrackingList(); + Tools = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// Whether to commit the response to the conversation. Defaults to true. + /// Whether to cancel any ongoing generation before starting this one. Defaults to true. + /// Input items to append to the conversation context before generating a response. + /// + /// Input items to be used as the context for this response. + /// An empty array clears previous context. + /// + /// + /// The set of modalities the model can respond with. To disable audio, + /// set this to ["text"]. + /// + /// + /// The default system instructions (i.e. system message) prepended to model + /// calls. This field allows the client to guide the model on desired + /// responses. The model can be instructed on response content and format, + /// (e.g. "be extremely succinct", "act friendly", "here are examples of good + /// responses") and on audio behavior (e.g. "talk quickly", "inject emotion + /// into your voice", "laugh frequently"). The instructions are not guaranteed + /// to be followed by the model, but they provide guidance to the model on the + /// desired behavior. + /// + /// Note that the server sets default instructions which will be used if this + /// field is not set and are visible in the `session.created` event at the + /// start of the session. + /// + /// supported voice identifiers and configurations. + /// The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. + /// Tools (functions) available to the model. + /// + /// How the model chooses tools. Options are `auto`, `none`, `required`, or + /// specify a function, like `{"type": "function", "function": {"name": "my_function"}}`. + /// + /// Sampling temperature for the model, limited to [0.6, 1.2]. Defaults to 0.8. + /// + /// Maximum number of output tokens for a single assistant response, + /// inclusive of tool calls. Provide an integer between 1 and 4096 to + /// limit output tokens, or `inf` for the maximum available tokens for a + /// given model. Defaults to `inf`. + /// + /// Keeps track of any properties unknown to the library. + internal ResponseCreateParams(bool? commit, bool? cancelPrevious, IList appendInputItems, IList inputItems, IList modalities, string instructions, BinaryData voice, AudioFormat? outputAudioFormat, IList tools, string toolChoice, float? temperature, BinaryData maxOutputTokens, IDictionary additionalBinaryDataProperties) + { + Commit = commit; + CancelPrevious = cancelPrevious; + AppendInputItems = appendInputItems; + InputItems = inputItems; + Modalities = modalities; + Instructions = instructions; + Voice = voice; + OutputAudioFormat = outputAudioFormat; + Tools = tools; + ToolChoice = toolChoice; + Temperature = temperature; + MaxOutputTokens = maxOutputTokens; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Whether to commit the response to the conversation. Defaults to true. + public bool? Commit { get; set; } + + /// Whether to cancel any ongoing generation before starting this one. Defaults to true. + public bool? CancelPrevious { get; set; } + + /// Input items to append to the conversation context before generating a response. + public IList AppendInputItems { get; } + + /// + /// Input items to be used as the context for this response. + /// An empty array clears previous context. + /// + public IList InputItems { get; } + + /// + /// The set of modalities the model can respond with. To disable audio, + /// set this to ["text"]. + /// + public IList Modalities { get; } + + /// + /// The default system instructions (i.e. system message) prepended to model + /// calls. This field allows the client to guide the model on desired + /// responses. The model can be instructed on response content and format, + /// (e.g. "be extremely succinct", "act friendly", "here are examples of good + /// responses") and on audio behavior (e.g. "talk quickly", "inject emotion + /// into your voice", "laugh frequently"). The instructions are not guaranteed + /// to be followed by the model, but they provide guidance to the model on the + /// desired behavior. + /// + /// Note that the server sets default instructions which will be used if this + /// field is not set and are visible in the `session.created` event at the + /// start of the session. + /// + public string Instructions { get; set; } + + /// + /// supported voice identifiers and configurations. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData Voice { get; set; } + + /// The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. + public AudioFormat? OutputAudioFormat { get; set; } + + /// Tools (functions) available to the model. + public IList Tools { get; } + + /// + /// How the model chooses tools. Options are `auto`, `none`, `required`, or + /// specify a function, like `{"type": "function", "function": {"name": "my_function"}}`. + /// + public string ToolChoice { get; set; } + + /// Sampling temperature for the model, limited to [0.6, 1.2]. Defaults to 0.8. + public float? Temperature { get; set; } + + /// + /// Maximum number of output tokens for a single assistant response, + /// inclusive of tool calls. Provide an integer between 1 and 4096 to + /// limit output tokens, or `inf` for the maximum available tokens for a + /// given model. Defaults to `inf`. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// "inf". + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData MaxOutputTokens { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallItem.Serialization.cs new file mode 100644 index 000000000000..15496d788378 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallItem.Serialization.cs @@ -0,0 +1,178 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseFunctionCallItem. + public partial class ResponseFunctionCallItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ResponseFunctionCallItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseFunctionCallItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + writer.WritePropertyName("call_id"u8); + writer.WriteStringValue(CallId); + writer.WritePropertyName("arguments"u8); + writer.WriteStringValue(Arguments); + writer.WritePropertyName("status"u8); + writer.WriteStringValue(Status.ToString()); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseFunctionCallItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ResponseFunctionCallItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseFunctionCallItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseFunctionCallItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseFunctionCallItem DeserializeResponseFunctionCallItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @object = default; + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string name = default; + string callId = default; + string arguments = default; + ItemStatus status = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("object"u8)) + { + @object = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("call_id"u8)) + { + callId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("arguments"u8)) + { + arguments = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("status"u8)) + { + status = new ItemStatus(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseFunctionCallItem( + @object, + @type, + id, + additionalBinaryDataProperties, + name, + callId, + arguments, + status); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseFunctionCallItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseFunctionCallItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ResponseFunctionCallItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseFunctionCallItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseFunctionCallItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallItem.cs new file mode 100644 index 000000000000..8099ef478c2d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallItem.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseFunctionCallItem. + public partial class ResponseFunctionCallItem : ConversationResponseItem + { + /// Initializes a new instance of . + /// + /// + /// + /// + internal ResponseFunctionCallItem(string name, string callId, string arguments, ItemStatus status) : base(ItemType.FunctionCall) + { + Name = name; + CallId = callId; + Arguments = arguments; + Status = status; + } + + /// Initializes a new instance of . + /// + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + internal ResponseFunctionCallItem(string @object, ItemType @type, string id, IDictionary additionalBinaryDataProperties, string name, string callId, string arguments, ItemStatus status) : base(@object, @type, id, additionalBinaryDataProperties) + { + Name = name; + CallId = callId; + Arguments = arguments; + Status = status; + } + + /// Gets the Name. + public string Name { get; } + + /// Gets the CallId. + public string CallId { get; } + + /// Gets the Arguments. + public string Arguments { get; } + + /// Gets the Status. + public ItemStatus Status { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallOutputItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallOutputItem.Serialization.cs new file mode 100644 index 000000000000..59ea6f36bfec --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallOutputItem.Serialization.cs @@ -0,0 +1,160 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseFunctionCallOutputItem. + public partial class ResponseFunctionCallOutputItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ResponseFunctionCallOutputItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseFunctionCallOutputItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("call_id"u8); + writer.WriteStringValue(CallId); + writer.WritePropertyName("output"u8); + writer.WriteStringValue(Output); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseFunctionCallOutputItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ResponseFunctionCallOutputItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseFunctionCallOutputItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseFunctionCallOutputItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseFunctionCallOutputItem DeserializeResponseFunctionCallOutputItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @object = default; + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string callId = default; + string output = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("object"u8)) + { + @object = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("call_id"u8)) + { + callId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output"u8)) + { + output = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseFunctionCallOutputItem( + @object, + @type, + id, + additionalBinaryDataProperties, + callId, + output); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseFunctionCallOutputItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseFunctionCallOutputItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ResponseFunctionCallOutputItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseFunctionCallOutputItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseFunctionCallOutputItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallOutputItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallOutputItem.cs new file mode 100644 index 000000000000..15739f543595 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseFunctionCallOutputItem.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseFunctionCallOutputItem. + public partial class ResponseFunctionCallOutputItem : ConversationResponseItem + { + /// Initializes a new instance of . + /// + /// + internal ResponseFunctionCallOutputItem(string callId, string output) : base(ItemType.FunctionCallOutput) + { + CallId = callId; + Output = output; + } + + /// Initializes a new instance of . + /// + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + internal ResponseFunctionCallOutputItem(string @object, ItemType @type, string id, IDictionary additionalBinaryDataProperties, string callId, string output) : base(@object, @type, id, additionalBinaryDataProperties) + { + CallId = callId; + Output = output; + } + + /// Gets the CallId. + public string CallId { get; } + + /// Gets the Output. + public string Output { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseMessageItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseMessageItem.Serialization.cs new file mode 100644 index 000000000000..baef6f1659af --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseMessageItem.Serialization.cs @@ -0,0 +1,179 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseMessageItem. + public partial class ResponseMessageItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ResponseMessageItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseMessageItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("role"u8); + writer.WriteStringValue(Role.ToString()); + writer.WritePropertyName("content"u8); + writer.WriteStartArray(); + foreach (ContentPart item in Content) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + writer.WritePropertyName("status"u8); + writer.WriteStringValue(Status.ToString()); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseMessageItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ResponseMessageItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseMessageItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseMessageItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseMessageItem DeserializeResponseMessageItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @object = default; + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + MessageRole role = default; + IList content = default; + ItemStatus status = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("object"u8)) + { + @object = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("role"u8)) + { + role = new MessageRole(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("content"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ContentPart.DeserializeContentPart(item, options)); + } + content = array; + continue; + } + if (prop.NameEquals("status"u8)) + { + status = new ItemStatus(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseMessageItem( + @object, + @type, + id, + additionalBinaryDataProperties, + role, + content, + status); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseMessageItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseMessageItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ResponseMessageItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseMessageItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseMessageItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseMessageItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseMessageItem.cs new file mode 100644 index 000000000000..020e9bfd5677 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseMessageItem.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseMessageItem. + public partial class ResponseMessageItem : ConversationResponseItem + { + /// Initializes a new instance of . + /// + /// + /// + internal ResponseMessageItem(MessageRole role, IEnumerable content, ItemStatus status) : base(ItemType.Message) + { + Role = role; + Content = content.ToList(); + Status = status; + } + + /// Initializes a new instance of . + /// + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + internal ResponseMessageItem(string @object, ItemType @type, string id, IDictionary additionalBinaryDataProperties, MessageRole role, IList content, ItemStatus status) : base(@object, @type, id, additionalBinaryDataProperties) + { + Role = role; + Content = content; + Status = status; + } + + /// Gets the Role. + public MessageRole Role { get; } + + /// Gets the Content. + public IList Content { get; } + + /// Gets the Status. + public ItemStatus Status { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseModality.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseModality.Serialization.cs new file mode 100644 index 000000000000..7947f951fef0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseModality.Serialization.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ResponseModalityExtensions + { + /// The value to serialize. + public static string ToSerialString(this ResponseModality value) => value switch + { + ResponseModality.Text => "text", + ResponseModality.Audio => "audio", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseModality value.") + }; + + /// The value to deserialize. + public static ResponseModality ToResponseModality(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "text")) + { + return ResponseModality.Text; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "audio")) + { + return ResponseModality.Audio; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseModality value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseModality.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseModality.cs new file mode 100644 index 000000000000..ee59540ddf45 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseModality.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ResponseModality + { + /// Text. + Text, + /// Audio. + Audio + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseOutputAudioFormat.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseOutputAudioFormat.Serialization.cs new file mode 100644 index 000000000000..b2b85c846550 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseOutputAudioFormat.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ResponseOutputAudioFormatExtensions + { + /// The value to serialize. + public static string ToSerialString(this ResponseOutputAudioFormat value) => value switch + { + ResponseOutputAudioFormat.Pcm16 => "pcm16", + ResponseOutputAudioFormat.G711Ulaw => "g711_ulaw", + ResponseOutputAudioFormat.G711Alaw => "g711_alaw", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseOutputAudioFormat value.") + }; + + /// The value to deserialize. + public static ResponseOutputAudioFormat ToResponseOutputAudioFormat(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "pcm16")) + { + return ResponseOutputAudioFormat.Pcm16; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "g711_ulaw")) + { + return ResponseOutputAudioFormat.G711Ulaw; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "g711_alaw")) + { + return ResponseOutputAudioFormat.G711Alaw; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseOutputAudioFormat value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseOutputAudioFormat.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseOutputAudioFormat.cs new file mode 100644 index 000000000000..62e4bcb1f499 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseOutputAudioFormat.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ResponseOutputAudioFormat + { + /// Pcm16. + Pcm16, + /// G711Ulaw. + G711Ulaw, + /// G711Alaw. + G711Alaw + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseSession.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseSession.Serialization.cs new file mode 100644 index 000000000000..21cd327725be --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseSession.Serialization.cs @@ -0,0 +1,507 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseSession. + public partial class ResponseSession : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseSession)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (Optional.IsDefined(Model)) + { + writer.WritePropertyName("model"u8); + writer.WriteStringValue(Model); + } + if (Optional.IsCollectionDefined(Modalities)) + { + writer.WritePropertyName("modalities"u8); + writer.WriteStartArray(); + foreach (InputModality item in Modalities) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Instructions)) + { + writer.WritePropertyName("instructions"u8); + writer.WriteStringValue(Instructions); + } + if (Optional.IsDefined(Animation)) + { + writer.WritePropertyName("animation"u8); + writer.WriteObjectValue(Animation, options); + } + if (Optional.IsDefined(Voice)) + { + writer.WritePropertyName("voice"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Voice); +#else + using (JsonDocument document = JsonDocument.Parse(Voice)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(InputAudio)) + { + writer.WritePropertyName("input_audio"u8); + writer.WriteObjectValue(InputAudio, options); + } + if (Optional.IsDefined(InputAudioFormat)) + { + writer.WritePropertyName("input_audio_format"u8); + writer.WriteStringValue(InputAudioFormat.Value.ToString()); + } + if (Optional.IsDefined(OutputAudioFormat)) + { + writer.WritePropertyName("output_audio_format"u8); + writer.WriteStringValue(OutputAudioFormat.Value.ToString()); + } + if (Optional.IsDefined(InputAudioSamplingRate)) + { + writer.WritePropertyName("input_audio_sampling_rate"u8); + writer.WriteNumberValue(InputAudioSamplingRate.Value); + } + if (Optional.IsDefined(TurnDetection)) + { + writer.WritePropertyName("turn_detection"u8); + writer.WriteObjectValue(TurnDetection, options); + } + if (Optional.IsDefined(InputAudioNoiseReduction)) + { + writer.WritePropertyName("input_audio_noise_reduction"u8); + writer.WriteObjectValue(InputAudioNoiseReduction, options); + } + if (Optional.IsDefined(InputAudioEchoCancellation)) + { + writer.WritePropertyName("input_audio_echo_cancellation"u8); + writer.WriteObjectValue(InputAudioEchoCancellation, options); + } + if (Optional.IsDefined(Avatar)) + { + writer.WritePropertyName("avatar"u8); + writer.WriteObjectValue(Avatar, options); + } + if (Optional.IsDefined(InputAudioTranscription)) + { + writer.WritePropertyName("input_audio_transcription"u8); + writer.WriteObjectValue(InputAudioTranscription, options); + } + if (Optional.IsCollectionDefined(OutputAudioTimestampTypes)) + { + writer.WritePropertyName("output_audio_timestamp_types"u8); + writer.WriteStartArray(); + foreach (AudioTimestampType item in OutputAudioTimestampTypes) + { + writer.WriteStringValue(item.ToString()); + } + writer.WriteEndArray(); + } + if (Optional.IsCollectionDefined(Tools)) + { + writer.WritePropertyName("tools"u8); + writer.WriteStartArray(); + foreach (ToolCall item in Tools) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(ToolChoice)) + { + writer.WritePropertyName("tool_choice"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(ToolChoice); +#else + using (JsonDocument document = JsonDocument.Parse(ToolChoice)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(Temperature)) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (Optional.IsDefined(MaxResponseOutputTokens)) + { + writer.WritePropertyName("max_response_output_tokens"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(MaxResponseOutputTokens); +#else + using (JsonDocument document = JsonDocument.Parse(MaxResponseOutputTokens)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsDefined(Agent)) + { + writer.WritePropertyName("agent"u8); + writer.WriteObjectValue(Agent, options); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseSession IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ResponseSession JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseSession)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseSession(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseSession DeserializeResponseSession(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string id = default; + string model = default; + IList modalities = default; + string instructions = default; + AnimationOptions animation = default; + BinaryData voice = default; + InputAudio inputAudio = default; + AudioFormat? inputAudioFormat = default; + AudioFormat? outputAudioFormat = default; + int? inputAudioSamplingRate = default; + TurnDetection turnDetection = default; + AudioNoiseReduction inputAudioNoiseReduction = default; + AudioEchoCancellation inputAudioEchoCancellation = default; + AvatarConfig avatar = default; + AudioInputTranscriptionSettings inputAudioTranscription = default; + IList outputAudioTimestampTypes = default; + IList tools = default; + BinaryData toolChoice = default; + float? temperature = default; + BinaryData maxResponseOutputTokens = default; + RespondingAgentConfig agent = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("model"u8)) + { + model = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("modalities"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new InputModality(item.GetString())); + } + modalities = array; + continue; + } + if (prop.NameEquals("instructions"u8)) + { + instructions = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("animation"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + animation = AnimationOptions.DeserializeAnimationOptions(prop.Value, options); + continue; + } + if (prop.NameEquals("voice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + voice = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("input_audio"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudio = InputAudio.DeserializeInputAudio(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioFormat = new AudioFormat(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("output_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputAudioFormat = new AudioFormat(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("input_audio_sampling_rate"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioSamplingRate = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("turn_detection"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + turnDetection = TurnDetection.DeserializeTurnDetection(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_noise_reduction"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioNoiseReduction = AudioNoiseReduction.DeserializeAudioNoiseReduction(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_echo_cancellation"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputAudioEchoCancellation = AudioEchoCancellation.DeserializeAudioEchoCancellation(prop.Value, options); + continue; + } + if (prop.NameEquals("avatar"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + avatar = AvatarConfig.DeserializeAvatarConfig(prop.Value, options); + continue; + } + if (prop.NameEquals("input_audio_transcription"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + inputAudioTranscription = null; + continue; + } + inputAudioTranscription = AudioInputTranscriptionSettings.DeserializeAudioInputTranscriptionSettings(prop.Value, options); + continue; + } + if (prop.NameEquals("output_audio_timestamp_types"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(new AudioTimestampType(item.GetString())); + } + outputAudioTimestampTypes = array; + continue; + } + if (prop.NameEquals("tools"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ToolCall.DeserializeToolCall(item, options)); + } + tools = array; + continue; + } + if (prop.NameEquals("tool_choice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + toolChoice = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("max_response_output_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + maxResponseOutputTokens = null; + continue; + } + maxResponseOutputTokens = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("agent"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + agent = RespondingAgentConfig.DeserializeRespondingAgentConfig(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseSession( + id, + model, + modalities ?? new ChangeTrackingList(), + instructions, + animation, + voice, + inputAudio, + inputAudioFormat, + outputAudioFormat, + inputAudioSamplingRate, + turnDetection, + inputAudioNoiseReduction, + inputAudioEchoCancellation, + avatar, + inputAudioTranscription, + outputAudioTimestampTypes ?? new ChangeTrackingList(), + tools ?? new ChangeTrackingList(), + toolChoice, + temperature, + maxResponseOutputTokens, + agent, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseSession)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseSession IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ResponseSession PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseSession(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseSession)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseSession.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseSession.cs new file mode 100644 index 000000000000..87aca101b220 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseSession.cs @@ -0,0 +1,263 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseSession. + public partial class ResponseSession + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + internal ResponseSession() + { + Modalities = new ChangeTrackingList(); + OutputAudioTimestampTypes = new ChangeTrackingList(); + Tools = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal ResponseSession(string id, string model, IList modalities, string instructions, AnimationOptions animation, BinaryData voice, InputAudio inputAudio, AudioFormat? inputAudioFormat, AudioFormat? outputAudioFormat, int? inputAudioSamplingRate, TurnDetection turnDetection, AudioNoiseReduction inputAudioNoiseReduction, AudioEchoCancellation inputAudioEchoCancellation, AvatarConfig avatar, AudioInputTranscriptionSettings inputAudioTranscription, IList outputAudioTimestampTypes, IList tools, BinaryData toolChoice, float? temperature, BinaryData maxResponseOutputTokens, RespondingAgentConfig agent, IDictionary additionalBinaryDataProperties) + { + Id = id; + Model = model; + Modalities = modalities; + Instructions = instructions; + Animation = animation; + Voice = voice; + InputAudio = inputAudio; + InputAudioFormat = inputAudioFormat; + OutputAudioFormat = outputAudioFormat; + InputAudioSamplingRate = inputAudioSamplingRate; + TurnDetection = turnDetection; + InputAudioNoiseReduction = inputAudioNoiseReduction; + InputAudioEchoCancellation = inputAudioEchoCancellation; + Avatar = avatar; + InputAudioTranscription = inputAudioTranscription; + OutputAudioTimestampTypes = outputAudioTimestampTypes; + Tools = tools; + ToolChoice = toolChoice; + Temperature = temperature; + MaxResponseOutputTokens = maxResponseOutputTokens; + Agent = agent; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets the Id. + public string Id { get; } + + /// Gets the Model. + public string Model { get; } + + /// Gets the Modalities. + public IList Modalities { get; } + + /// Gets the Instructions. + public string Instructions { get; } + + /// Gets the Animation. + public AnimationOptions Animation { get; } + + /// + /// Gets the Voice. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData Voice { get; } + + /// Gets the InputAudio. + public InputAudio InputAudio { get; } + + /// Gets the InputAudioFormat. + public AudioFormat? InputAudioFormat { get; } + + /// Gets the OutputAudioFormat. + public AudioFormat? OutputAudioFormat { get; } + + /// Gets the InputAudioSamplingRate. + public int? InputAudioSamplingRate { get; } + + /// Gets the TurnDetection. + public TurnDetection TurnDetection { get; } + + /// Gets the InputAudioNoiseReduction. + public AudioNoiseReduction InputAudioNoiseReduction { get; } + + /// Gets the InputAudioEchoCancellation. + public AudioEchoCancellation InputAudioEchoCancellation { get; } + + /// Gets the Avatar. + public AvatarConfig Avatar { get; } + + /// Gets the InputAudioTranscription. + public AudioInputTranscriptionSettings InputAudioTranscription { get; } + + /// Gets the OutputAudioTimestampTypes. + public IList OutputAudioTimestampTypes { get; } + + /// Gets the Tools. + public IList Tools { get; } + + /// + /// Gets the ToolChoice. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// . + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData ToolChoice { get; } + + /// Gets the Temperature. + public float? Temperature { get; } + + /// + /// Gets the MaxResponseOutputTokens. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// "inf". + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData MaxResponseOutputTokens { get; } + + /// Gets the Agent. + public RespondingAgentConfig Agent { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatus.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatus.Serialization.cs new file mode 100644 index 000000000000..30aaaa76f3b1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatus.Serialization.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ResponseStatusExtensions + { + /// The value to serialize. + public static string ToSerialString(this ResponseStatus value) => value switch + { + ResponseStatus.Completed => "completed", + ResponseStatus.Cancelled => "cancelled", + ResponseStatus.Failed => "failed", + ResponseStatus.Incomplete => "incomplete", + ResponseStatus.InProgress => "in_progress", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseStatus value.") + }; + + /// The value to deserialize. + public static ResponseStatus ToResponseStatus(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "completed")) + { + return ResponseStatus.Completed; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "cancelled")) + { + return ResponseStatus.Cancelled; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "failed")) + { + return ResponseStatus.Failed; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "incomplete")) + { + return ResponseStatus.Incomplete; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "in_progress")) + { + return ResponseStatus.InProgress; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseStatus value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatus.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatus.cs new file mode 100644 index 000000000000..03d6d0ea812f --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatus.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ResponseStatus + { + /// Completed. + Completed, + /// Cancelled. + Cancelled, + /// Failed. + Failed, + /// Incomplete. + Incomplete, + /// InProgress. + InProgress + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetails.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetails.Serialization.cs new file mode 100644 index 000000000000..da45851e5028 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetails.Serialization.cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseStatusDetails. + public partial class ResponseStatusDetails : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseStatusDetails)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.Value.ToSerialString()); + } + if (Optional.IsDefined(Reason)) + { + writer.WritePropertyName("reason"u8); + writer.WriteStringValue(Reason.Value.ToSerialString()); + } + if (Optional.IsDefined(Error)) + { + writer.WritePropertyName("error"u8); + writer.WriteObjectValue(Error, options); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseStatusDetails IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ResponseStatusDetails JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseStatusDetails)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseStatusDetails(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseStatusDetails DeserializeResponseStatusDetails(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ResponseStatusDetailsType? @type = default; + ResponseStatusDetailsReason? reason = default; + ResponseStatusDetailsError error = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + @type = prop.Value.GetString().ToResponseStatusDetailsType(); + continue; + } + if (prop.NameEquals("reason"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + reason = prop.Value.GetString().ToResponseStatusDetailsReason(); + continue; + } + if (prop.NameEquals("error"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + error = ResponseStatusDetailsError.DeserializeResponseStatusDetailsError(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseStatusDetails(@type, reason, error, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseStatusDetails)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseStatusDetails IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ResponseStatusDetails PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseStatusDetails(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseStatusDetails)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetails.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetails.cs new file mode 100644 index 000000000000..1a75771c70d1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetails.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseStatusDetails. + public partial class ResponseStatusDetails + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + internal ResponseStatusDetails() + { + } + + /// Initializes a new instance of . + /// + /// The type of error that caused the response to fail, corresponding + /// with the `status` field (`completed`, `cancelled`, `incomplete`, + /// `failed`). + /// + /// + /// The reason the Response did not complete. For a `cancelled` Response, + /// one of `turn_detected` (the server VAD detected a new start of speech) + /// or `client_cancelled` (the client sent a cancel event). For an + /// `incomplete` Response, one of `max_output_tokens` or `content_filter` + /// (the server-side safety filter activated and cut off the response). + /// + /// + /// A description of the error that caused the response to fail, + /// populated when the `status` is `failed`. + /// + /// Keeps track of any properties unknown to the library. + internal ResponseStatusDetails(ResponseStatusDetailsType? @type, ResponseStatusDetailsReason? reason, ResponseStatusDetailsError error, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Reason = reason; + Error = error; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// + /// The type of error that caused the response to fail, corresponding + /// with the `status` field (`completed`, `cancelled`, `incomplete`, + /// `failed`). + /// + public ResponseStatusDetailsType? Type { get; } + + /// + /// The reason the Response did not complete. For a `cancelled` Response, + /// one of `turn_detected` (the server VAD detected a new start of speech) + /// or `client_cancelled` (the client sent a cancel event). For an + /// `incomplete` Response, one of `max_output_tokens` or `content_filter` + /// (the server-side safety filter activated and cut off the response). + /// + public ResponseStatusDetailsReason? Reason { get; } + + /// + /// A description of the error that caused the response to fail, + /// populated when the `status` is `failed`. + /// + public ResponseStatusDetailsError Error { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsError.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsError.Serialization.cs new file mode 100644 index 000000000000..438333f31e96 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsError.Serialization.cs @@ -0,0 +1,151 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseStatusDetailsError. + public partial class ResponseStatusDetailsError : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseStatusDetailsError)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + } + if (Optional.IsDefined(Code)) + { + writer.WritePropertyName("code"u8); + writer.WriteStringValue(Code); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseStatusDetailsError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ResponseStatusDetailsError JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseStatusDetailsError)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseStatusDetailsError(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseStatusDetailsError DeserializeResponseStatusDetailsError(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @type = default; + string code = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("code"u8)) + { + code = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseStatusDetailsError(@type, code, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseStatusDetailsError)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseStatusDetailsError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ResponseStatusDetailsError PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseStatusDetailsError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseStatusDetailsError)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsError.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsError.cs new file mode 100644 index 000000000000..d28d9e7a0e11 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsError.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseStatusDetailsError. + public partial class ResponseStatusDetailsError + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + internal ResponseStatusDetailsError() + { + } + + /// Initializes a new instance of . + /// The type of error. + /// Error code, if any. + /// Keeps track of any properties unknown to the library. + internal ResponseStatusDetailsError(string @type, string code, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Code = code; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The type of error. + public string Type { get; } + + /// Error code, if any. + public string Code { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsReason.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsReason.Serialization.cs new file mode 100644 index 000000000000..a57c79ea71c1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsReason.Serialization.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ResponseStatusDetailsReasonExtensions + { + /// The value to serialize. + public static string ToSerialString(this ResponseStatusDetailsReason value) => value switch + { + ResponseStatusDetailsReason.TurnDetected => "turn_detected", + ResponseStatusDetailsReason.ClientCancelled => "client_cancelled", + ResponseStatusDetailsReason.MaxOutputTokens => "max_output_tokens", + ResponseStatusDetailsReason.ContentFilter => "content_filter", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseStatusDetailsReason value.") + }; + + /// The value to deserialize. + public static ResponseStatusDetailsReason ToResponseStatusDetailsReason(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "turn_detected")) + { + return ResponseStatusDetailsReason.TurnDetected; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "client_cancelled")) + { + return ResponseStatusDetailsReason.ClientCancelled; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "max_output_tokens")) + { + return ResponseStatusDetailsReason.MaxOutputTokens; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "content_filter")) + { + return ResponseStatusDetailsReason.ContentFilter; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseStatusDetailsReason value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsReason.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsReason.cs new file mode 100644 index 000000000000..8848755945dc --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsReason.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ResponseStatusDetailsReason + { + /// TurnDetected. + TurnDetected, + /// ClientCancelled. + ClientCancelled, + /// MaxOutputTokens. + MaxOutputTokens, + /// ContentFilter. + ContentFilter + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsType.Serialization.cs new file mode 100644 index 000000000000..893072272bc2 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsType.Serialization.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class ResponseStatusDetailsTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this ResponseStatusDetailsType value) => value switch + { + ResponseStatusDetailsType.Completed => "completed", + ResponseStatusDetailsType.Cancelled => "cancelled", + ResponseStatusDetailsType.Failed => "failed", + ResponseStatusDetailsType.Incomplete => "incomplete", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseStatusDetailsType value.") + }; + + /// The value to deserialize. + public static ResponseStatusDetailsType ToResponseStatusDetailsType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "completed")) + { + return ResponseStatusDetailsType.Completed; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "cancelled")) + { + return ResponseStatusDetailsType.Cancelled; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "failed")) + { + return ResponseStatusDetailsType.Failed; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "incomplete")) + { + return ResponseStatusDetailsType.Incomplete; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ResponseStatusDetailsType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsType.cs new file mode 100644 index 000000000000..19b2ede37c20 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseStatusDetailsType.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + public enum ResponseStatusDetailsType + { + /// Completed. + Completed, + /// Cancelled. + Cancelled, + /// Failed. + Failed, + /// Incomplete. + Incomplete + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseTextContentPart.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseTextContentPart.Serialization.cs new file mode 100644 index 000000000000..5c8650e55c8c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseTextContentPart.Serialization.cs @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseTextContentPart. + public partial class ResponseTextContentPart : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseTextContentPart)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(Text)) + { + writer.WritePropertyName("text"u8); + writer.WriteStringValue(Text); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseTextContentPart IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ResponseTextContentPart)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ContentPart JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseTextContentPart)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseTextContentPart(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseTextContentPart DeserializeResponseTextContentPart(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ContentPartType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string text = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ContentPartType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("text"u8)) + { + text = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseTextContentPart(@type, additionalBinaryDataProperties, text); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseTextContentPart)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseTextContentPart IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ResponseTextContentPart)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ContentPart PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseTextContentPart(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseTextContentPart)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseTextContentPart.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseTextContentPart.cs new file mode 100644 index 000000000000..e301cf9e6f2e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseTextContentPart.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseTextContentPart. + public partial class ResponseTextContentPart : ContentPart + { + /// Initializes a new instance of . + internal ResponseTextContentPart() : base(ContentPartType.Text) + { + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + internal ResponseTextContentPart(ContentPartType @type, IDictionary additionalBinaryDataProperties, string text) : base(@type, additionalBinaryDataProperties) + { + Text = text; + } + + /// Gets the Text. + public string Text { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsage.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsage.Serialization.cs new file mode 100644 index 000000000000..5783dcd79292 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsage.Serialization.cs @@ -0,0 +1,210 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseUsage. + public partial class ResponseUsage : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseUsage)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(TotalTokens)) + { + writer.WritePropertyName("total_tokens"u8); + writer.WriteNumberValue(TotalTokens.Value); + } + if (Optional.IsDefined(InputTokens)) + { + writer.WritePropertyName("input_tokens"u8); + writer.WriteNumberValue(InputTokens.Value); + } + if (Optional.IsDefined(OutputTokens)) + { + writer.WritePropertyName("output_tokens"u8); + writer.WriteNumberValue(OutputTokens.Value); + } + if (Optional.IsDefined(InputTokenDetails)) + { + writer.WritePropertyName("input_token_details"u8); + writer.WriteObjectValue(InputTokenDetails, options); + } + if (Optional.IsDefined(OutputTokenDetails)) + { + writer.WritePropertyName("output_token_details"u8); + writer.WriteObjectValue(OutputTokenDetails, options); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseUsage IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ResponseUsage JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseUsage)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseUsage(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseUsage DeserializeResponseUsage(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int? totalTokens = default; + int? inputTokens = default; + int? outputTokens = default; + ResponseUsageInputTokenDetails inputTokenDetails = default; + ResponseUsageOutputTokenDetails outputTokenDetails = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("total_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + totalTokens = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("input_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputTokens = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("output_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputTokens = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("input_token_details"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + inputTokenDetails = ResponseUsageInputTokenDetails.DeserializeResponseUsageInputTokenDetails(prop.Value, options); + continue; + } + if (prop.NameEquals("output_token_details"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputTokenDetails = ResponseUsageOutputTokenDetails.DeserializeResponseUsageOutputTokenDetails(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseUsage( + totalTokens, + inputTokens, + outputTokens, + inputTokenDetails, + outputTokenDetails, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseUsage)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseUsage IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ResponseUsage PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseUsage(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseUsage)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsage.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsage.cs new file mode 100644 index 000000000000..05f81d84d027 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsage.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseUsage. + public partial class ResponseUsage + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + internal ResponseUsage() + { + } + + /// Initializes a new instance of . + /// + /// The total number of tokens in the Response including input and output + /// text and audio tokens. + /// + /// + /// The number of input tokens used in the Response, including text and + /// audio tokens. + /// + /// + /// The number of output tokens sent in the Response, including text and + /// audio tokens. + /// + /// Details about the input tokens used in the Response. + /// Details about the output tokens used in the Response. + /// Keeps track of any properties unknown to the library. + internal ResponseUsage(int? totalTokens, int? inputTokens, int? outputTokens, ResponseUsageInputTokenDetails inputTokenDetails, ResponseUsageOutputTokenDetails outputTokenDetails, IDictionary additionalBinaryDataProperties) + { + TotalTokens = totalTokens; + InputTokens = inputTokens; + OutputTokens = outputTokens; + InputTokenDetails = inputTokenDetails; + OutputTokenDetails = outputTokenDetails; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// + /// The total number of tokens in the Response including input and output + /// text and audio tokens. + /// + public int? TotalTokens { get; } + + /// + /// The number of input tokens used in the Response, including text and + /// audio tokens. + /// + public int? InputTokens { get; } + + /// + /// The number of output tokens sent in the Response, including text and + /// audio tokens. + /// + public int? OutputTokens { get; } + + /// Details about the input tokens used in the Response. + public ResponseUsageInputTokenDetails InputTokenDetails { get; } + + /// Details about the output tokens used in the Response. + public ResponseUsageOutputTokenDetails OutputTokenDetails { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageInputTokenDetails.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageInputTokenDetails.Serialization.cs new file mode 100644 index 000000000000..454760459880 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageInputTokenDetails.Serialization.cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseUsageInputTokenDetails. + public partial class ResponseUsageInputTokenDetails : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseUsageInputTokenDetails)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(CachedTokens)) + { + writer.WritePropertyName("cached_tokens"u8); + writer.WriteNumberValue(CachedTokens.Value); + } + if (Optional.IsDefined(TextTokens)) + { + writer.WritePropertyName("text_tokens"u8); + writer.WriteNumberValue(TextTokens.Value); + } + if (Optional.IsDefined(AudioTokens)) + { + writer.WritePropertyName("audio_tokens"u8); + writer.WriteNumberValue(AudioTokens.Value); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseUsageInputTokenDetails IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ResponseUsageInputTokenDetails JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseUsageInputTokenDetails)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseUsageInputTokenDetails(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseUsageInputTokenDetails DeserializeResponseUsageInputTokenDetails(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int? cachedTokens = default; + int? textTokens = default; + int? audioTokens = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("cached_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + cachedTokens = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("text_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + textTokens = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + audioTokens = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseUsageInputTokenDetails(cachedTokens, textTokens, audioTokens, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseUsageInputTokenDetails)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseUsageInputTokenDetails IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ResponseUsageInputTokenDetails PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseUsageInputTokenDetails(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseUsageInputTokenDetails)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageInputTokenDetails.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageInputTokenDetails.cs new file mode 100644 index 000000000000..5366dd596ad3 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageInputTokenDetails.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseUsageInputTokenDetails. + public partial class ResponseUsageInputTokenDetails + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + internal ResponseUsageInputTokenDetails() + { + } + + /// Initializes a new instance of . + /// The number of cached tokens used in the Response. + /// The number of text tokens used in the Response. + /// The number of audio tokens used in the Response. + /// Keeps track of any properties unknown to the library. + internal ResponseUsageInputTokenDetails(int? cachedTokens, int? textTokens, int? audioTokens, IDictionary additionalBinaryDataProperties) + { + CachedTokens = cachedTokens; + TextTokens = textTokens; + AudioTokens = audioTokens; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The number of cached tokens used in the Response. + public int? CachedTokens { get; } + + /// The number of text tokens used in the Response. + public int? TextTokens { get; } + + /// The number of audio tokens used in the Response. + public int? AudioTokens { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageOutputTokenDetails.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageOutputTokenDetails.Serialization.cs new file mode 100644 index 000000000000..5d180c8566d1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageOutputTokenDetails.Serialization.cs @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseUsageOutputTokenDetails. + public partial class ResponseUsageOutputTokenDetails : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseUsageOutputTokenDetails)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(TextTokens)) + { + writer.WritePropertyName("text_tokens"u8); + writer.WriteNumberValue(TextTokens.Value); + } + if (Optional.IsDefined(AudioTokens)) + { + writer.WritePropertyName("audio_tokens"u8); + writer.WriteNumberValue(AudioTokens.Value); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ResponseUsageOutputTokenDetails IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ResponseUsageOutputTokenDetails JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ResponseUsageOutputTokenDetails)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeResponseUsageOutputTokenDetails(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ResponseUsageOutputTokenDetails DeserializeResponseUsageOutputTokenDetails(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int? textTokens = default; + int? audioTokens = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("text_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + textTokens = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + audioTokens = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ResponseUsageOutputTokenDetails(textTokens, audioTokens, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ResponseUsageOutputTokenDetails)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ResponseUsageOutputTokenDetails IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ResponseUsageOutputTokenDetails PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeResponseUsageOutputTokenDetails(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ResponseUsageOutputTokenDetails)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageOutputTokenDetails.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageOutputTokenDetails.cs new file mode 100644 index 000000000000..47e581a11c71 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ResponseUsageOutputTokenDetails.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ResponseUsageOutputTokenDetails. + public partial class ResponseUsageOutputTokenDetails + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + internal ResponseUsageOutputTokenDetails() + { + } + + /// Initializes a new instance of . + /// The number of text tokens used in the Response. + /// The number of audio tokens used in the Response. + /// Keeps track of any properties unknown to the library. + internal ResponseUsageOutputTokenDetails(int? textTokens, int? audioTokens, IDictionary additionalBinaryDataProperties) + { + TextTokens = textTokens; + AudioTokens = audioTokens; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The number of text tokens used in the Response. + public int? TextTokens { get; } + + /// The number of audio tokens used in the Response. + public int? AudioTokens { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEvent.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEvent.Serialization.cs new file mode 100644 index 000000000000..fed33f4e1dd9 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEvent.Serialization.cs @@ -0,0 +1,214 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// A voicelive server event. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and . + /// + [PersistableModelProxy(typeof(UnknownServerEvent))] + public abstract partial class ServerEvent : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEvent() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEvent)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEvent IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEvent)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEvent(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEvent DeserializeServerEvent(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "session.avatar.connecting": + return ServerEventSessionAvatarConnecting.DeserializeServerEventSessionAvatarConnecting(element, options); + case "session.created": + return ServerEventSessionCreated.DeserializeServerEventSessionCreated(element, options); + case "session.updated": + return ServerEventSessionUpdated.DeserializeServerEventSessionUpdated(element, options); + case "error": + return ServerEventError.DeserializeServerEventError(element, options); + case "response.text.delta": + return ServerEventResponseTextDelta.DeserializeServerEventResponseTextDelta(element, options); + case "response.audio.delta": + return ServerEventResponseAudioDelta.DeserializeServerEventResponseAudioDelta(element, options); + case "conversation.item.created": + return ServerEventConversationItemCreated.DeserializeServerEventConversationItemCreated(element, options); + case "conversation.item.deleted": + return ServerEventConversationItemDeleted.DeserializeServerEventConversationItemDeleted(element, options); + case "conversation.item.retrieved": + return ServerEventConversationItemRetrieved.DeserializeServerEventConversationItemRetrieved(element, options); + case "conversation.item.truncated": + return ServerEventConversationItemTruncated.DeserializeServerEventConversationItemTruncated(element, options); + case "conversation.item.input_audio_transcription.completed": + return ServerEventConversationItemInputAudioTranscriptionCompleted.DeserializeServerEventConversationItemInputAudioTranscriptionCompleted(element, options); + case "conversation.item.input_audio_transcription.delta": + return ServerEventConversationItemInputAudioTranscriptionDelta.DeserializeServerEventConversationItemInputAudioTranscriptionDelta(element, options); + case "conversation.item.input_audio_transcription.failed": + return ServerEventConversationItemInputAudioTranscriptionFailed.DeserializeServerEventConversationItemInputAudioTranscriptionFailed(element, options); + case "input_audio_buffer.committed": + return ServerEventInputAudioBufferCommitted.DeserializeServerEventInputAudioBufferCommitted(element, options); + case "input_audio_buffer.cleared": + return ServerEventInputAudioBufferCleared.DeserializeServerEventInputAudioBufferCleared(element, options); + case "input_audio_buffer.speech_started": + return ServerEventInputAudioBufferSpeechStarted.DeserializeServerEventInputAudioBufferSpeechStarted(element, options); + case "input_audio_buffer.speech_stopped": + return ServerEventInputAudioBufferSpeechStopped.DeserializeServerEventInputAudioBufferSpeechStopped(element, options); + case "response.created": + return ServerEventResponseCreated.DeserializeServerEventResponseCreated(element, options); + case "response.done": + return ServerEventResponseDone.DeserializeServerEventResponseDone(element, options); + case "response.output_item.added": + return ServerEventResponseOutputItemAdded.DeserializeServerEventResponseOutputItemAdded(element, options); + case "response.output_item.done": + return ServerEventResponseOutputItemDone.DeserializeServerEventResponseOutputItemDone(element, options); + case "response.content_part.added": + return ServerEventResponseContentPartAdded.DeserializeServerEventResponseContentPartAdded(element, options); + case "response.content_part.done": + return ServerEventResponseContentPartDone.DeserializeServerEventResponseContentPartDone(element, options); + case "response.text.done": + return ServerEventResponseTextDone.DeserializeServerEventResponseTextDone(element, options); + case "response.audio_transcript.delta": + return ServerEventResponseAudioTranscriptDelta.DeserializeServerEventResponseAudioTranscriptDelta(element, options); + case "response.audio_transcript.done": + return ServerEventResponseAudioTranscriptDone.DeserializeServerEventResponseAudioTranscriptDone(element, options); + case "response.audio.done": + return ServerEventResponseAudioDone.DeserializeServerEventResponseAudioDone(element, options); + case "response.function_call_arguments.delta": + return ServerEventResponseFunctionCallArgumentsDelta.DeserializeServerEventResponseFunctionCallArgumentsDelta(element, options); + case "response.function_call_arguments.done": + return ServerEventResponseFunctionCallArgumentsDone.DeserializeServerEventResponseFunctionCallArgumentsDone(element, options); + case "response.animation_blendshapes.delta": + return ServerEventResponseAnimationBlendshapeDelta.DeserializeServerEventResponseAnimationBlendshapeDelta(element, options); + case "response.animation_blendshapes.done": + return ServerEventResponseAnimationBlendshapeDone.DeserializeServerEventResponseAnimationBlendshapeDone(element, options); + case "response.emotion_hypothesis": + return ServerEventResponseEmotionHypothesis.DeserializeServerEventResponseEmotionHypothesis(element, options); + case "response.audio_timestamp.delta": + return ServerEventResponseAudioTimestampDelta.DeserializeServerEventResponseAudioTimestampDelta(element, options); + case "response.audio_timestamp.done": + return ServerEventResponseAudioTimestampDone.DeserializeServerEventResponseAudioTimestampDone(element, options); + case "response.animation_viseme.delta": + return ServerEventResponseAnimationVisemeDelta.DeserializeServerEventResponseAnimationVisemeDelta(element, options); + case "response.animation_viseme.done": + return ServerEventResponseAnimationVisemeDone.DeserializeServerEventResponseAnimationVisemeDone(element, options); + } + } + return UnknownServerEvent.DeserializeUnknownServerEvent(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEvent)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEvent IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEvent(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEvent)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEvent.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEvent.cs new file mode 100644 index 000000000000..e032d10c0063 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEvent.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// A voicelive server event. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and . + /// + public abstract partial class ServerEvent + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The type of event. + private protected ServerEvent(ServerEventType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal ServerEvent(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties) + { + Type = @type; + EventId = eventId; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The type of event. + internal ServerEventType Type { get; set; } + + /// Gets the EventId. + public virtual string EventId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemCreated.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemCreated.Serialization.cs new file mode 100644 index 000000000000..a357f8b6cf41 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemCreated.Serialization.cs @@ -0,0 +1,165 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a conversation item is created. There are several scenarios that produce this event: + /// - The server is generating a Response, which if successful will produce + /// either one or two Items, which will be of type `message` + /// (role `assistant`) or type `function_call`. + /// - The input audio buffer has been committed, either by the client or the + /// server (in `server_vad` mode). The server will take the content of the + /// input audio buffer and add it to a new user message Item. + /// - The client has sent a `conversation.item.create` event to add a new Item + /// to the Conversation. + /// + public partial class ServerEventConversationItemCreated : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventConversationItemCreated() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemCreated)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("previous_item_id"u8); + writer.WriteStringValue(PreviousItemId); + if (Optional.IsDefined(Item)) + { + writer.WritePropertyName("item"u8); + writer.WriteObjectValue(Item, options); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventConversationItemCreated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventConversationItemCreated)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemCreated)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventConversationItemCreated(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventConversationItemCreated DeserializeServerEventConversationItemCreated(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string previousItemId = default; + ConversationItemWithReference item = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("previous_item_id"u8)) + { + previousItemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + item = ConversationItemWithReference.DeserializeConversationItemWithReference(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventConversationItemCreated(@type, eventId, additionalBinaryDataProperties, previousItemId, item); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemCreated)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventConversationItemCreated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventConversationItemCreated)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventConversationItemCreated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemCreated)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemCreated.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemCreated.cs new file mode 100644 index 000000000000..a6c99aa16d52 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemCreated.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a conversation item is created. There are several scenarios that produce this event: + /// - The server is generating a Response, which if successful will produce + /// either one or two Items, which will be of type `message` + /// (role `assistant`) or type `function_call`. + /// - The input audio buffer has been committed, either by the client or the + /// server (in `server_vad` mode). The server will take the content of the + /// input audio buffer and add it to a new user message Item. + /// - The client has sent a `conversation.item.create` event to add a new Item + /// to the Conversation. + /// + public partial class ServerEventConversationItemCreated : ServerEvent + { + /// Initializes a new instance of . + /// + /// The ID of the preceding item in the Conversation context, allows the + /// client to understand the order of the conversation. + /// + internal ServerEventConversationItemCreated(string previousItemId) : base(ServerEventType.ConversationItemCreated) + { + PreviousItemId = previousItemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// The ID of the preceding item in the Conversation context, allows the + /// client to understand the order of the conversation. + /// + /// + internal ServerEventConversationItemCreated(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string previousItemId, ConversationItemWithReference item) : base(@type, eventId, additionalBinaryDataProperties) + { + PreviousItemId = previousItemId; + Item = item; + } + + /// + /// The ID of the preceding item in the Conversation context, allows the + /// client to understand the order of the conversation. + /// + public string PreviousItemId { get; } + + /// Gets the Item. + public ConversationItemWithReference Item { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemDeleted.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemDeleted.Serialization.cs new file mode 100644 index 000000000000..4b38a664712b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemDeleted.Serialization.cs @@ -0,0 +1,149 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an item in the conversation is deleted by the client with a + /// `conversation.item.delete` event. This event is used to synchronize the + /// server's understanding of the conversation history with the client's view. + /// + public partial class ServerEventConversationItemDeleted : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventConversationItemDeleted() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemDeleted)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventConversationItemDeleted IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventConversationItemDeleted)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemDeleted)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventConversationItemDeleted(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventConversationItemDeleted DeserializeServerEventConversationItemDeleted(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + string eventId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventConversationItemDeleted(@type, additionalBinaryDataProperties, itemId, eventId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemDeleted)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventConversationItemDeleted IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventConversationItemDeleted)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventConversationItemDeleted(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemDeleted)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemDeleted.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemDeleted.cs new file mode 100644 index 000000000000..84f4a6d31df4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemDeleted.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an item in the conversation is deleted by the client with a + /// `conversation.item.delete` event. This event is used to synchronize the + /// server's understanding of the conversation history with the client's view. + /// + public partial class ServerEventConversationItemDeleted : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the item that was deleted. + internal ServerEventConversationItemDeleted(string itemId) : base(ServerEventType.ConversationItemDeleted) + { + ItemId = itemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// Keeps track of any properties unknown to the library. + /// The ID of the item that was deleted. + /// + internal ServerEventConversationItemDeleted(ServerEventType @type, IDictionary additionalBinaryDataProperties, string itemId, string eventId) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + } + + /// The ID of the item that was deleted. + public string ItemId { get; } + + /// Gets the EventId. + public override string EventId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionCompleted.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionCompleted.Serialization.cs new file mode 100644 index 000000000000..43fdc2cd40e7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionCompleted.Serialization.cs @@ -0,0 +1,173 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// This event is the output of audio transcription for user audio written to the + /// user audio buffer. Transcription begins when the input audio buffer is + /// committed by the client or server (in `server_vad` mode). Transcription runs + /// asynchronously with Response creation, so this event may come before or after + /// the Response events. + /// + /// VoiceLive API models accept audio natively, and thus input transcription is a + /// separate process run on a separate ASR (Automatic Speech Recognition) model. + /// The transcript may diverge somewhat from the model's interpretation, and + /// should be treated as a rough guide. + /// + public partial class ServerEventConversationItemInputAudioTranscriptionCompleted : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventConversationItemInputAudioTranscriptionCompleted() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionCompleted)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("transcript"u8); + writer.WriteStringValue(Transcript); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventConversationItemInputAudioTranscriptionCompleted IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventConversationItemInputAudioTranscriptionCompleted)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionCompleted)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventConversationItemInputAudioTranscriptionCompleted(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventConversationItemInputAudioTranscriptionCompleted DeserializeServerEventConversationItemInputAudioTranscriptionCompleted(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + int contentIndex = default; + string transcript = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("transcript"u8)) + { + transcript = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventConversationItemInputAudioTranscriptionCompleted( + @type, + eventId, + additionalBinaryDataProperties, + itemId, + contentIndex, + transcript); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionCompleted)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventConversationItemInputAudioTranscriptionCompleted IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventConversationItemInputAudioTranscriptionCompleted)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventConversationItemInputAudioTranscriptionCompleted(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionCompleted)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionCompleted.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionCompleted.cs new file mode 100644 index 000000000000..47b1dd33775e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionCompleted.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// This event is the output of audio transcription for user audio written to the + /// user audio buffer. Transcription begins when the input audio buffer is + /// committed by the client or server (in `server_vad` mode). Transcription runs + /// asynchronously with Response creation, so this event may come before or after + /// the Response events. + /// + /// VoiceLive API models accept audio natively, and thus input transcription is a + /// separate process run on a separate ASR (Automatic Speech Recognition) model. + /// The transcript may diverge somewhat from the model's interpretation, and + /// should be treated as a rough guide. + /// + public partial class ServerEventConversationItemInputAudioTranscriptionCompleted : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the user message item containing the audio. + /// The index of the content part containing the audio. + /// The transcribed text. + internal ServerEventConversationItemInputAudioTranscriptionCompleted(string itemId, int contentIndex, string transcript) : base(ServerEventType.ConversationItemInputAudioTranscriptionCompleted) + { + ItemId = itemId; + ContentIndex = contentIndex; + Transcript = transcript; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the user message item containing the audio. + /// The index of the content part containing the audio. + /// The transcribed text. + internal ServerEventConversationItemInputAudioTranscriptionCompleted(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string itemId, int contentIndex, string transcript) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + ContentIndex = contentIndex; + Transcript = transcript; + } + + /// The ID of the user message item containing the audio. + public string ItemId { get; } + + /// The index of the content part containing the audio. + public int ContentIndex { get; } + + /// The transcribed text. + public string Transcript { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionDelta.Serialization.cs new file mode 100644 index 000000000000..b6fc3af96bba --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionDelta.Serialization.cs @@ -0,0 +1,198 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the text value of an input audio transcription content part is updated. + public partial class ServerEventConversationItemInputAudioTranscriptionDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventConversationItemInputAudioTranscriptionDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + if (Optional.IsDefined(ContentIndex)) + { + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex.Value); + } + if (Optional.IsDefined(Delta)) + { + writer.WritePropertyName("delta"u8); + writer.WriteStringValue(Delta); + } + if (Optional.IsCollectionDefined(Logprobs)) + { + writer.WritePropertyName("logprobs"u8); + writer.WriteStartArray(); + foreach (LogProbProperties item in Logprobs) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventConversationItemInputAudioTranscriptionDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventConversationItemInputAudioTranscriptionDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventConversationItemInputAudioTranscriptionDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventConversationItemInputAudioTranscriptionDelta DeserializeServerEventConversationItemInputAudioTranscriptionDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + int? contentIndex = default; + string delta = default; + IList logprobs = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("delta"u8)) + { + delta = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("logprobs"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(LogProbProperties.DeserializeLogProbProperties(item, options)); + } + logprobs = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventConversationItemInputAudioTranscriptionDelta( + @type, + eventId, + additionalBinaryDataProperties, + itemId, + contentIndex, + delta, + logprobs ?? new ChangeTrackingList()); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventConversationItemInputAudioTranscriptionDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventConversationItemInputAudioTranscriptionDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventConversationItemInputAudioTranscriptionDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionDelta.cs new file mode 100644 index 000000000000..ece90cbbaa2e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionDelta.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the text value of an input audio transcription content part is updated. + public partial class ServerEventConversationItemInputAudioTranscriptionDelta : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the item. + internal ServerEventConversationItemInputAudioTranscriptionDelta(string itemId) : base(ServerEventType.ConversationItemInputAudioTranscriptionDelta) + { + ItemId = itemId; + Logprobs = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the item. + /// The index of the content part in the item's content array. + /// The text delta. + /// The log probabilities of the transcription. + internal ServerEventConversationItemInputAudioTranscriptionDelta(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string itemId, int? contentIndex, string delta, IList logprobs) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + ContentIndex = contentIndex; + Delta = delta; + Logprobs = logprobs; + } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the content part in the item's content array. + public int? ContentIndex { get; } + + /// The text delta. + public string Delta { get; } + + /// The log probabilities of the transcription. + public IList Logprobs { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionFailed.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionFailed.Serialization.cs new file mode 100644 index 000000000000..c2314d164ffa --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionFailed.Serialization.cs @@ -0,0 +1,166 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when input audio transcription is configured, and a transcription + /// request for a user message failed. These events are separate from other + /// `error` events so that the client can identify the related Item. + /// + public partial class ServerEventConversationItemInputAudioTranscriptionFailed : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventConversationItemInputAudioTranscriptionFailed() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionFailed)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("error"u8); + writer.WriteObjectValue(Error, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventConversationItemInputAudioTranscriptionFailed IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventConversationItemInputAudioTranscriptionFailed)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionFailed)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventConversationItemInputAudioTranscriptionFailed(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventConversationItemInputAudioTranscriptionFailed DeserializeServerEventConversationItemInputAudioTranscriptionFailed(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + int contentIndex = default; + VoiceLiveErrorDetails error = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("error"u8)) + { + error = VoiceLiveErrorDetails.DeserializeVoiceLiveErrorDetails(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventConversationItemInputAudioTranscriptionFailed( + @type, + eventId, + additionalBinaryDataProperties, + itemId, + contentIndex, + error); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionFailed)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventConversationItemInputAudioTranscriptionFailed IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventConversationItemInputAudioTranscriptionFailed)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventConversationItemInputAudioTranscriptionFailed(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemInputAudioTranscriptionFailed)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionFailed.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionFailed.cs new file mode 100644 index 000000000000..ba2979b504f5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemInputAudioTranscriptionFailed.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when input audio transcription is configured, and a transcription + /// request for a user message failed. These events are separate from other + /// `error` events so that the client can identify the related Item. + /// + public partial class ServerEventConversationItemInputAudioTranscriptionFailed : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the user message item. + /// The index of the content part containing the audio. + /// Details of the transcription error. + internal ServerEventConversationItemInputAudioTranscriptionFailed(string itemId, int contentIndex, VoiceLiveErrorDetails error) : base(ServerEventType.ConversationItemInputAudioTranscriptionFailed) + { + ItemId = itemId; + ContentIndex = contentIndex; + Error = error; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the user message item. + /// The index of the content part containing the audio. + /// Details of the transcription error. + internal ServerEventConversationItemInputAudioTranscriptionFailed(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string itemId, int contentIndex, VoiceLiveErrorDetails error) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + ContentIndex = contentIndex; + Error = error; + } + + /// The ID of the user message item. + public string ItemId { get; } + + /// The index of the content part containing the audio. + public int ContentIndex { get; } + + /// Details of the transcription error. + public VoiceLiveErrorDetails Error { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemRetrieved.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemRetrieved.Serialization.cs new file mode 100644 index 000000000000..cfcb28a7d9da --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemRetrieved.Serialization.cs @@ -0,0 +1,143 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Returned when a conversation item is retrieved with `conversation.item.retrieve`. + public partial class ServerEventConversationItemRetrieved : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemRetrieved)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(ItemId)) + { + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + } + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventConversationItemRetrieved IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventConversationItemRetrieved)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemRetrieved)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventConversationItemRetrieved(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventConversationItemRetrieved DeserializeServerEventConversationItemRetrieved(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + string eventId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventConversationItemRetrieved(@type, additionalBinaryDataProperties, itemId, eventId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemRetrieved)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventConversationItemRetrieved IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventConversationItemRetrieved)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventConversationItemRetrieved(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemRetrieved)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemRetrieved.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemRetrieved.cs new file mode 100644 index 000000000000..7bccf844e8e7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemRetrieved.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Returned when a conversation item is retrieved with `conversation.item.retrieve`. + public partial class ServerEventConversationItemRetrieved : ServerEvent + { + /// Initializes a new instance of . + internal ServerEventConversationItemRetrieved() : base(ServerEventType.ConversationItemRetrieved) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// Keeps track of any properties unknown to the library. + /// + /// + internal ServerEventConversationItemRetrieved(ServerEventType @type, IDictionary additionalBinaryDataProperties, string itemId, string eventId) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + } + + /// Gets the ItemId. + public string ItemId { get; } + + /// Gets the EventId. + public override string EventId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemTruncated.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemTruncated.Serialization.cs new file mode 100644 index 000000000000..b8f2b047e67d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemTruncated.Serialization.cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an earlier assistant audio message item is truncated by the + /// client with a `conversation.item.truncate` event. This event is used to + /// synchronize the server's understanding of the audio with the client's playback. + /// + /// This action will truncate the audio and remove the server-side text transcript + /// to ensure there is no text in the context that hasn't been heard by the user. + /// + public partial class ServerEventConversationItemTruncated : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventConversationItemTruncated() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemTruncated)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("audio_end_ms"u8); + writer.WriteNumberValue(AudioEndMs); + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventConversationItemTruncated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventConversationItemTruncated)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventConversationItemTruncated)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventConversationItemTruncated(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventConversationItemTruncated DeserializeServerEventConversationItemTruncated(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string itemId = default; + int contentIndex = default; + int audioEndMs = default; + string eventId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_end_ms"u8)) + { + audioEndMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventConversationItemTruncated( + @type, + additionalBinaryDataProperties, + itemId, + contentIndex, + audioEndMs, + eventId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemTruncated)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventConversationItemTruncated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventConversationItemTruncated)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventConversationItemTruncated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventConversationItemTruncated)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemTruncated.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemTruncated.cs new file mode 100644 index 000000000000..6edb9dbcd23e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventConversationItemTruncated.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an earlier assistant audio message item is truncated by the + /// client with a `conversation.item.truncate` event. This event is used to + /// synchronize the server's understanding of the audio with the client's playback. + /// + /// This action will truncate the audio and remove the server-side text transcript + /// to ensure there is no text in the context that hasn't been heard by the user. + /// + public partial class ServerEventConversationItemTruncated : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the assistant message item that was truncated. + /// The index of the content part that was truncated. + /// The duration up to which the audio was truncated, in milliseconds. + internal ServerEventConversationItemTruncated(string itemId, int contentIndex, int audioEndMs) : base(ServerEventType.ConversationItemTruncated) + { + ItemId = itemId; + ContentIndex = contentIndex; + AudioEndMs = audioEndMs; + } + + /// Initializes a new instance of . + /// The type of event. + /// Keeps track of any properties unknown to the library. + /// The ID of the assistant message item that was truncated. + /// The index of the content part that was truncated. + /// The duration up to which the audio was truncated, in milliseconds. + /// + internal ServerEventConversationItemTruncated(ServerEventType @type, IDictionary additionalBinaryDataProperties, string itemId, int contentIndex, int audioEndMs, string eventId) : base(@type, eventId, additionalBinaryDataProperties) + { + ItemId = itemId; + ContentIndex = contentIndex; + AudioEndMs = audioEndMs; + } + + /// The ID of the assistant message item that was truncated. + public string ItemId { get; } + + /// The index of the content part that was truncated. + public int ContentIndex { get; } + + /// The duration up to which the audio was truncated, in milliseconds. + public int AudioEndMs { get; } + + /// Gets the EventId. + public override string EventId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventError.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventError.Serialization.cs new file mode 100644 index 000000000000..d8eb0c075093 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventError.Serialization.cs @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an error occurs, which could be a client problem or a server + /// problem. Most errors are recoverable and the session will stay open, we + /// recommend to implementors to monitor and log error messages by default. + /// + public partial class ServerEventError : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventError() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventError)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("error"u8); + writer.WriteObjectValue(Error, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventError)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventError)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventError(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventError DeserializeServerEventError(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + ServerEventErrorError error = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("error"u8)) + { + error = ServerEventErrorError.DeserializeServerEventErrorError(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventError(@type, eventId, additionalBinaryDataProperties, error); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventError)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventError)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventError)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventError.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventError.cs new file mode 100644 index 000000000000..f3b4b86f6559 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventError.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an error occurs, which could be a client problem or a server + /// problem. Most errors are recoverable and the session will stay open, we + /// recommend to implementors to monitor and log error messages by default. + /// + public partial class ServerEventError : ServerEvent + { + /// Initializes a new instance of . + /// Details of the error. + internal ServerEventError(ServerEventErrorError error) : base(ServerEventType.Error) + { + Error = error; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// Details of the error. + internal ServerEventError(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, ServerEventErrorError error) : base(@type, eventId, additionalBinaryDataProperties) + { + Error = error; + } + + /// Details of the error. + public ServerEventErrorError Error { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventErrorError.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventErrorError.Serialization.cs new file mode 100644 index 000000000000..2f72458a00ae --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventErrorError.Serialization.cs @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ServerEventErrorError. + public partial class ServerEventErrorError : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventErrorError() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventErrorError)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + if (Optional.IsDefined(Code)) + { + writer.WritePropertyName("code"u8); + writer.WriteStringValue(Code); + } + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + if (Optional.IsDefined(Param)) + { + writer.WritePropertyName("param"u8); + writer.WriteStringValue(Param); + } + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventErrorError IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ServerEventErrorError JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventErrorError)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventErrorError(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventErrorError DeserializeServerEventErrorError(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @type = default; + string code = default; + string message = default; + string @param = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("code"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + code = null; + continue; + } + code = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("message"u8)) + { + message = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("param"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + @param = null; + continue; + } + @param = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + eventId = null; + continue; + } + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventErrorError( + @type, + code, + message, + @param, + eventId, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventErrorError)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventErrorError IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ServerEventErrorError PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventErrorError(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventErrorError)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventErrorError.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventErrorError.cs new file mode 100644 index 000000000000..fd5938fc396d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventErrorError.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ServerEventErrorError. + public partial class ServerEventErrorError + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// The type of error (e.g., "invalid_request_error", "server_error"). + /// A human-readable error message. + internal ServerEventErrorError(string @type, string message) + { + Type = @type; + Message = message; + } + + /// Initializes a new instance of . + /// The type of error (e.g., "invalid_request_error", "server_error"). + /// Error code, if any. + /// A human-readable error message. + /// Parameter related to the error, if any. + /// The event_id of the client event that caused the error, if applicable. + /// Keeps track of any properties unknown to the library. + internal ServerEventErrorError(string @type, string code, string message, string @param, string eventId, IDictionary additionalBinaryDataProperties) + { + Type = @type; + Code = code; + Message = message; + Param = @param; + EventId = eventId; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The type of error (e.g., "invalid_request_error", "server_error"). + public string Type { get; } + + /// Error code, if any. + public string Code { get; } + + /// A human-readable error message. + public string Message { get; } + + /// Parameter related to the error, if any. + public string Param { get; } + + /// The event_id of the client event that caused the error, if applicable. + public string EventId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCleared.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCleared.Serialization.cs new file mode 100644 index 000000000000..6178eacde811 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCleared.Serialization.cs @@ -0,0 +1,130 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the input audio buffer is cleared by the client with a + /// `input_audio_buffer.clear` event. + /// + public partial class ServerEventInputAudioBufferCleared : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCleared)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventInputAudioBufferCleared IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferCleared)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCleared)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventInputAudioBufferCleared(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventInputAudioBufferCleared DeserializeServerEventInputAudioBufferCleared(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventInputAudioBufferCleared(@type, eventId, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCleared)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventInputAudioBufferCleared IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferCleared)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventInputAudioBufferCleared(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCleared)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCleared.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCleared.cs new file mode 100644 index 000000000000..2ee04c012b01 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCleared.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the input audio buffer is cleared by the client with a + /// `input_audio_buffer.clear` event. + /// + public partial class ServerEventInputAudioBufferCleared : ServerEvent + { + /// Initializes a new instance of . + internal ServerEventInputAudioBufferCleared() : base(ServerEventType.InputAudioBufferCleared) + { + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal ServerEventInputAudioBufferCleared(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties) : base(@type, eventId, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCommitted.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCommitted.Serialization.cs new file mode 100644 index 000000000000..1d27001d0e09 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCommitted.Serialization.cs @@ -0,0 +1,156 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an input audio buffer is committed, either by the client or + /// automatically in server VAD mode. The `item_id` property is the ID of the user + /// message item that will be created, thus a `conversation.item.created` event + /// will also be sent to the client. + /// + public partial class ServerEventInputAudioBufferCommitted : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventInputAudioBufferCommitted() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCommitted)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(PreviousItemId)) + { + writer.WritePropertyName("previous_item_id"u8); + writer.WriteStringValue(PreviousItemId); + } + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventInputAudioBufferCommitted IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferCommitted)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCommitted)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventInputAudioBufferCommitted(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventInputAudioBufferCommitted DeserializeServerEventInputAudioBufferCommitted(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string previousItemId = default; + string itemId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("previous_item_id"u8)) + { + previousItemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventInputAudioBufferCommitted(@type, eventId, additionalBinaryDataProperties, previousItemId, itemId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCommitted)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventInputAudioBufferCommitted IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferCommitted)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventInputAudioBufferCommitted(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferCommitted)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCommitted.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCommitted.cs new file mode 100644 index 000000000000..15ca0b3e5893 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferCommitted.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an input audio buffer is committed, either by the client or + /// automatically in server VAD mode. The `item_id` property is the ID of the user + /// message item that will be created, thus a `conversation.item.created` event + /// will also be sent to the client. + /// + public partial class ServerEventInputAudioBufferCommitted : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the user message item that will be created. + internal ServerEventInputAudioBufferCommitted(string itemId) : base(ServerEventType.InputAudioBufferCommitted) + { + ItemId = itemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the preceding item after which the new item will be inserted. + /// The ID of the user message item that will be created. + internal ServerEventInputAudioBufferCommitted(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string previousItemId, string itemId) : base(@type, eventId, additionalBinaryDataProperties) + { + PreviousItemId = previousItemId; + ItemId = itemId; + } + + /// The ID of the preceding item after which the new item will be inserted. + public string PreviousItemId { get; } + + /// The ID of the user message item that will be created. + public string ItemId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStarted.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStarted.Serialization.cs new file mode 100644 index 000000000000..108a3c53a432 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStarted.Serialization.cs @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Sent by the server when in `server_vad` mode to indicate that speech has been + /// detected in the audio buffer. This can happen any time audio is added to the + /// buffer (unless speech is already detected). The client may want to use this + /// event to interrupt audio playback or provide visual feedback to the user. + /// + /// The client should expect to receive a `input_audio_buffer.speech_stopped` event + /// when speech stops. The `item_id` property is the ID of the user message item + /// that will be created when speech stops and will also be included in the + /// `input_audio_buffer.speech_stopped` event (unless the client manually commits + /// the audio buffer during VAD activation). + /// + public partial class ServerEventInputAudioBufferSpeechStarted : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventInputAudioBufferSpeechStarted() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStarted)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("audio_start_ms"u8); + writer.WriteNumberValue(AudioStartMs); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventInputAudioBufferSpeechStarted IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferSpeechStarted)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStarted)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventInputAudioBufferSpeechStarted(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventInputAudioBufferSpeechStarted DeserializeServerEventInputAudioBufferSpeechStarted(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + int audioStartMs = default; + string itemId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("audio_start_ms"u8)) + { + audioStartMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventInputAudioBufferSpeechStarted(@type, eventId, additionalBinaryDataProperties, audioStartMs, itemId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStarted)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventInputAudioBufferSpeechStarted IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferSpeechStarted)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventInputAudioBufferSpeechStarted(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStarted)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStarted.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStarted.cs new file mode 100644 index 000000000000..b8011c85aad4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStarted.cs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Sent by the server when in `server_vad` mode to indicate that speech has been + /// detected in the audio buffer. This can happen any time audio is added to the + /// buffer (unless speech is already detected). The client may want to use this + /// event to interrupt audio playback or provide visual feedback to the user. + /// + /// The client should expect to receive a `input_audio_buffer.speech_stopped` event + /// when speech stops. The `item_id` property is the ID of the user message item + /// that will be created when speech stops and will also be included in the + /// `input_audio_buffer.speech_stopped` event (unless the client manually commits + /// the audio buffer during VAD activation). + /// + public partial class ServerEventInputAudioBufferSpeechStarted : ServerEvent + { + /// Initializes a new instance of . + /// + /// Milliseconds from the start of all audio written to the buffer during the + /// session when speech was first detected. This will correspond to the + /// beginning of audio sent to the model, and thus includes the + /// `prefix_padding_ms` configured in the Session. + /// + /// The ID of the user message item that will be created when speech stops. + internal ServerEventInputAudioBufferSpeechStarted(int audioStartMs, string itemId) : base(ServerEventType.InputAudioBufferSpeechStarted) + { + AudioStartMs = audioStartMs; + ItemId = itemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// Milliseconds from the start of all audio written to the buffer during the + /// session when speech was first detected. This will correspond to the + /// beginning of audio sent to the model, and thus includes the + /// `prefix_padding_ms` configured in the Session. + /// + /// The ID of the user message item that will be created when speech stops. + internal ServerEventInputAudioBufferSpeechStarted(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, int audioStartMs, string itemId) : base(@type, eventId, additionalBinaryDataProperties) + { + AudioStartMs = audioStartMs; + ItemId = itemId; + } + + /// + /// Milliseconds from the start of all audio written to the buffer during the + /// session when speech was first detected. This will correspond to the + /// beginning of audio sent to the model, and thus includes the + /// `prefix_padding_ms` configured in the Session. + /// + public int AudioStartMs { get; } + + /// The ID of the user message item that will be created when speech stops. + public string ItemId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStopped.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStopped.Serialization.cs new file mode 100644 index 000000000000..993c0cf47714 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStopped.Serialization.cs @@ -0,0 +1,152 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned in `server_vad` mode when the server detects the end of speech in + /// the audio buffer. The server will also send an `conversation.item.created` + /// event with the user message item that is created from the audio buffer. + /// + public partial class ServerEventInputAudioBufferSpeechStopped : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventInputAudioBufferSpeechStopped() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStopped)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("audio_end_ms"u8); + writer.WriteNumberValue(AudioEndMs); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventInputAudioBufferSpeechStopped IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferSpeechStopped)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStopped)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventInputAudioBufferSpeechStopped(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventInputAudioBufferSpeechStopped DeserializeServerEventInputAudioBufferSpeechStopped(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + int audioEndMs = default; + string itemId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("audio_end_ms"u8)) + { + audioEndMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventInputAudioBufferSpeechStopped(@type, eventId, additionalBinaryDataProperties, audioEndMs, itemId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStopped)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventInputAudioBufferSpeechStopped IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventInputAudioBufferSpeechStopped)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventInputAudioBufferSpeechStopped(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventInputAudioBufferSpeechStopped)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStopped.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStopped.cs new file mode 100644 index 000000000000..75bb3a1f5fed --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventInputAudioBufferSpeechStopped.cs @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned in `server_vad` mode when the server detects the end of speech in + /// the audio buffer. The server will also send an `conversation.item.created` + /// event with the user message item that is created from the audio buffer. + /// + public partial class ServerEventInputAudioBufferSpeechStopped : ServerEvent + { + /// Initializes a new instance of . + /// + /// Milliseconds since the session started when speech stopped. This will + /// correspond to the end of audio sent to the model, and thus includes the + /// `min_silence_duration_ms` configured in the Session. + /// + /// The ID of the user message item that will be created. + internal ServerEventInputAudioBufferSpeechStopped(int audioEndMs, string itemId) : base(ServerEventType.InputAudioBufferSpeechStopped) + { + AudioEndMs = audioEndMs; + ItemId = itemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// Milliseconds since the session started when speech stopped. This will + /// correspond to the end of audio sent to the model, and thus includes the + /// `min_silence_duration_ms` configured in the Session. + /// + /// The ID of the user message item that will be created. + internal ServerEventInputAudioBufferSpeechStopped(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, int audioEndMs, string itemId) : base(@type, eventId, additionalBinaryDataProperties) + { + AudioEndMs = audioEndMs; + ItemId = itemId; + } + + /// + /// Milliseconds since the session started when speech stopped. This will + /// correspond to the end of audio sent to the model, and thus includes the + /// `min_silence_duration_ms` configured in the Session. + /// + public int AudioEndMs { get; } + + /// The ID of the user message item that will be created. + public string ItemId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDelta.Serialization.cs new file mode 100644 index 000000000000..1c3b6651a1ad --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDelta.Serialization.cs @@ -0,0 +1,196 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Represents a delta update of blendshape animation frames for a specific output of a response. + public partial class ServerEventResponseAnimationBlendshapeDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAnimationBlendshapeDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("frames"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Frames); +#else + using (JsonDocument document = JsonDocument.Parse(Frames)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + writer.WritePropertyName("frame_index"u8); + writer.WriteNumberValue(FrameIndex); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAnimationBlendshapeDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAnimationBlendshapeDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAnimationBlendshapeDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAnimationBlendshapeDelta DeserializeServerEventResponseAnimationBlendshapeDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + BinaryData frames = default; + int frameIndex = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("frames"u8)) + { + frames = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("frame_index"u8)) + { + frameIndex = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAnimationBlendshapeDelta( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + frames, + frameIndex); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAnimationBlendshapeDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAnimationBlendshapeDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAnimationBlendshapeDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDelta.cs new file mode 100644 index 000000000000..d5cf0d192e2d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDelta.cs @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Represents a delta update of blendshape animation frames for a specific output of a response. + public partial class ServerEventResponseAnimationBlendshapeDelta : ServerEvent + { + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// + internal ServerEventResponseAnimationBlendshapeDelta(string responseId, string itemId, int outputIndex, int contentIndex, BinaryData frames, int frameIndex) : base(ServerEventType.ResponseAnimationBlendshapesDelta) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Frames = frames; + FrameIndex = frameIndex; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + /// + /// + internal ServerEventResponseAnimationBlendshapeDelta(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, BinaryData frames, int frameIndex) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Frames = frames; + FrameIndex = frameIndex; + } + + /// Gets the ResponseId. + public string ResponseId { get; } + + /// Gets the ItemId. + public string ItemId { get; } + + /// Gets the OutputIndex. + public int OutputIndex { get; } + + /// Gets the ContentIndex. + public int ContentIndex { get; } + + /// + /// Gets the Frames. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// where T is of type IList{float}. + /// + /// + /// . + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData Frames { get; } + + /// Gets the FrameIndex. + public int FrameIndex { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDone.Serialization.cs new file mode 100644 index 000000000000..de14c2f4f04d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDone.Serialization.cs @@ -0,0 +1,162 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Indicates the completion of blendshape animation processing for a specific output of a response. + public partial class ServerEventResponseAnimationBlendshapeDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAnimationBlendshapeDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAnimationBlendshapeDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAnimationBlendshapeDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAnimationBlendshapeDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAnimationBlendshapeDone DeserializeServerEventResponseAnimationBlendshapeDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAnimationBlendshapeDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAnimationBlendshapeDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAnimationBlendshapeDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAnimationBlendshapeDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationBlendshapeDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDone.cs new file mode 100644 index 000000000000..7e7450c19eb4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationBlendshapeDone.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Indicates the completion of blendshape animation processing for a specific output of a response. + public partial class ServerEventResponseAnimationBlendshapeDone : ServerEvent + { + /// Initializes a new instance of . + /// + /// + /// + internal ServerEventResponseAnimationBlendshapeDone(string responseId, string itemId, int outputIndex) : base(ServerEventType.ResponseAnimationBlendshapesDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + internal ServerEventResponseAnimationBlendshapeDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + } + + /// Gets the ResponseId. + public string ResponseId { get; } + + /// Gets the ItemId. + public string ItemId { get; } + + /// Gets the OutputIndex. + public int OutputIndex { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDelta.Serialization.cs new file mode 100644 index 000000000000..dc7d62b7df89 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDelta.Serialization.cs @@ -0,0 +1,189 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Represents a viseme ID delta update for animation based on audio. + public partial class ServerEventResponseAnimationVisemeDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAnimationVisemeDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("audio_offset_ms"u8); + writer.WriteNumberValue(AudioOffsetMs); + writer.WritePropertyName("viseme_id"u8); + writer.WriteNumberValue(VisemeId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAnimationVisemeDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAnimationVisemeDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAnimationVisemeDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAnimationVisemeDelta DeserializeServerEventResponseAnimationVisemeDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + int audioOffsetMs = default; + int visemeId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_offset_ms"u8)) + { + audioOffsetMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("viseme_id"u8)) + { + visemeId = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAnimationVisemeDelta( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + audioOffsetMs, + visemeId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAnimationVisemeDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAnimationVisemeDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAnimationVisemeDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDelta.cs new file mode 100644 index 000000000000..888bcfb3c2f4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDelta.cs @@ -0,0 +1,71 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Represents a viseme ID delta update for animation based on audio. + public partial class ServerEventResponseAnimationVisemeDelta : ServerEvent + { + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// + internal ServerEventResponseAnimationVisemeDelta(string responseId, string itemId, int outputIndex, int contentIndex, int audioOffsetMs, int visemeId) : base(ServerEventType.ResponseAnimationVisemeDelta) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + AudioOffsetMs = audioOffsetMs; + VisemeId = visemeId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + /// + /// + internal ServerEventResponseAnimationVisemeDelta(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, int audioOffsetMs, int visemeId) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + AudioOffsetMs = audioOffsetMs; + VisemeId = visemeId; + } + + /// Gets the ResponseId. + public string ResponseId { get; } + + /// Gets the ItemId. + public string ItemId { get; } + + /// Gets the OutputIndex. + public int OutputIndex { get; } + + /// Gets the ContentIndex. + public int ContentIndex { get; } + + /// Gets the AudioOffsetMs. + public int AudioOffsetMs { get; } + + /// Gets the VisemeId. + public int VisemeId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDone.Serialization.cs new file mode 100644 index 000000000000..e33cead7a70d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDone.Serialization.cs @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; +using Azure; + +namespace Azure.AI.VoiceLive +{ + /// Indicates completion of viseme animation delivery for a response. + public partial class ServerEventResponseAnimationVisemeDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAnimationVisemeDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAnimationVisemeDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAnimationVisemeDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAnimationVisemeDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAnimationVisemeDone DeserializeServerEventResponseAnimationVisemeDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAnimationVisemeDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAnimationVisemeDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAnimationVisemeDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAnimationVisemeDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAnimationVisemeDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + + /// The to deserialize the from. + public static explicit operator ServerEventResponseAnimationVisemeDone(Response result) + { + using Response response = result; + using JsonDocument document = JsonDocument.Parse(response.Content); + return DeserializeServerEventResponseAnimationVisemeDone(document.RootElement, ModelSerializationExtensions.WireOptions); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDone.cs new file mode 100644 index 000000000000..765cb9804b53 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAnimationVisemeDone.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Indicates completion of viseme animation delivery for a response. + public partial class ServerEventResponseAnimationVisemeDone : ServerEvent + { + /// Initializes a new instance of . + /// + /// + /// + /// + internal ServerEventResponseAnimationVisemeDone(string responseId, string itemId, int outputIndex, int contentIndex) : base(ServerEventType.ResponseAnimationVisemeDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + internal ServerEventResponseAnimationVisemeDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + } + + /// Gets the ResponseId. + public string ResponseId { get; } + + /// Gets the ItemId. + public string ItemId { get; } + + /// Gets the OutputIndex. + public int OutputIndex { get; } + + /// Gets the ContentIndex. + public int ContentIndex { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDelta.Serialization.cs new file mode 100644 index 000000000000..534ee30d63d9 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDelta.Serialization.cs @@ -0,0 +1,185 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the model-generated audio is updated. + public partial class ServerEventResponseAudioDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAudioDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("delta"u8); + writer.WriteBase64StringValue(Delta.ToArray(), "D"); + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAudioDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAudioDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAudioDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAudioDelta DeserializeServerEventResponseAudioDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + BinaryData delta = default; + string eventId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("delta"u8)) + { + delta = BinaryData.FromBytes(prop.Value.GetBytesFromBase64("D")); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAudioDelta( + @type, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + delta, + eventId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAudioDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAudioDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAudioDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDelta.cs new file mode 100644 index 000000000000..5d99ffee7291 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDelta.cs @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the model-generated audio is updated. + public partial class ServerEventResponseAudioDelta : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// Base64-encoded audio data delta. + internal ServerEventResponseAudioDelta(string responseId, string itemId, int outputIndex, int contentIndex, BinaryData delta) : base(ServerEventType.ResponseAudioDelta) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Delta = delta; + } + + /// Initializes a new instance of . + /// The type of event. + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// Base64-encoded audio data delta. + /// + internal ServerEventResponseAudioDelta(ServerEventType @type, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, BinaryData delta, string eventId) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Delta = delta; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + + /// + /// Base64-encoded audio data delta. + /// + /// To assign a byte[] to this property use . + /// The byte[] will be serialized to a Base64 encoded string. + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromBytes(new byte[] { 1, 2, 3 }). + /// Creates a payload of "AQID". + /// + /// + /// + /// + public BinaryData Delta { get; } + + /// Gets the EventId. + public override string EventId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDone.Serialization.cs new file mode 100644 index 000000000000..1fdd95e902d7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDone.Serialization.cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the model-generated audio is done. Also emitted when a Response + /// is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseAudioDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAudioDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAudioDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAudioDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAudioDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAudioDone DeserializeServerEventResponseAudioDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAudioDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAudioDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAudioDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAudioDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDone.cs new file mode 100644 index 000000000000..c83befa75387 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioDone.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the model-generated audio is done. Also emitted when a Response + /// is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseAudioDone : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + internal ServerEventResponseAudioDone(string responseId, string itemId, int outputIndex, int contentIndex) : base(ServerEventType.ResponseAudioDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + internal ServerEventResponseAudioDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDelta.Serialization.cs new file mode 100644 index 000000000000..08344155a460 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDelta.Serialization.cs @@ -0,0 +1,207 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Represents a word-level audio timestamp delta for a response. + public partial class ServerEventResponseAudioTimestampDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAudioTimestampDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("audio_offset_ms"u8); + writer.WriteNumberValue(AudioOffsetMs); + writer.WritePropertyName("audio_duration_ms"u8); + writer.WriteNumberValue(AudioDurationMs); + writer.WritePropertyName("text"u8); + writer.WriteStringValue(Text); + writer.WritePropertyName("timestamp_type"u8); + writer.WriteStringValue(TimestampType); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAudioTimestampDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAudioTimestampDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAudioTimestampDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAudioTimestampDelta DeserializeServerEventResponseAudioTimestampDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + int audioOffsetMs = default; + int audioDurationMs = default; + string text = default; + string timestampType = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_offset_ms"u8)) + { + audioOffsetMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_duration_ms"u8)) + { + audioDurationMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("text"u8)) + { + text = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("timestamp_type"u8)) + { + timestampType = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAudioTimestampDelta( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + audioOffsetMs, + audioDurationMs, + text, + timestampType); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAudioTimestampDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAudioTimestampDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAudioTimestampDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDelta.cs new file mode 100644 index 000000000000..6994bc1db446 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDelta.cs @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Represents a word-level audio timestamp delta for a response. + public partial class ServerEventResponseAudioTimestampDelta : ServerEvent + { + /// Initializes a new instance of . + /// + /// + /// + /// + /// + /// + /// + internal ServerEventResponseAudioTimestampDelta(string responseId, string itemId, int outputIndex, int contentIndex, int audioOffsetMs, int audioDurationMs, string text) : base(ServerEventType.ResponseAudioTimestampDelta) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + AudioOffsetMs = audioOffsetMs; + AudioDurationMs = audioDurationMs; + Text = text; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + /// + /// + /// + /// + internal ServerEventResponseAudioTimestampDelta(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, int audioOffsetMs, int audioDurationMs, string text, string timestampType) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + AudioOffsetMs = audioOffsetMs; + AudioDurationMs = audioDurationMs; + Text = text; + TimestampType = timestampType; + } + + /// Gets the ResponseId. + public string ResponseId { get; } + + /// Gets the ItemId. + public string ItemId { get; } + + /// Gets the OutputIndex. + public int OutputIndex { get; } + + /// Gets the ContentIndex. + public int ContentIndex { get; } + + /// Gets the AudioOffsetMs. + public int AudioOffsetMs { get; } + + /// Gets the AudioDurationMs. + public int AudioDurationMs { get; } + + /// Gets the Text. + public string Text { get; } + + /// Gets the TimestampType. + public string TimestampType { get; } = "word"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDone.Serialization.cs new file mode 100644 index 000000000000..b49bbf735270 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDone.Serialization.cs @@ -0,0 +1,171 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Indicates completion of audio timestamp delivery for a response. + public partial class ServerEventResponseAudioTimestampDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAudioTimestampDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAudioTimestampDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAudioTimestampDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAudioTimestampDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAudioTimestampDone DeserializeServerEventResponseAudioTimestampDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAudioTimestampDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAudioTimestampDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAudioTimestampDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAudioTimestampDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTimestampDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDone.cs new file mode 100644 index 000000000000..faa267aa2d66 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTimestampDone.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Indicates completion of audio timestamp delivery for a response. + public partial class ServerEventResponseAudioTimestampDone : ServerEvent + { + /// Initializes a new instance of . + /// + /// + /// + /// + internal ServerEventResponseAudioTimestampDone(string responseId, string itemId, int outputIndex, int contentIndex) : base(ServerEventType.ResponseAudioTimestampDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + internal ServerEventResponseAudioTimestampDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + } + + /// Gets the ResponseId. + public string ResponseId { get; } + + /// Gets the ItemId. + public string ItemId { get; } + + /// Gets the OutputIndex. + public int OutputIndex { get; } + + /// Gets the ContentIndex. + public int ContentIndex { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDelta.Serialization.cs new file mode 100644 index 000000000000..f1697a68823d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDelta.Serialization.cs @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the model-generated transcription of audio output is updated. + public partial class ServerEventResponseAudioTranscriptDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAudioTranscriptDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("delta"u8); + writer.WriteStringValue(Delta); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAudioTranscriptDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAudioTranscriptDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAudioTranscriptDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAudioTranscriptDelta DeserializeServerEventResponseAudioTranscriptDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + string delta = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("delta"u8)) + { + delta = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAudioTranscriptDelta( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + delta); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAudioTranscriptDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAudioTranscriptDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAudioTranscriptDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDelta.cs new file mode 100644 index 000000000000..041964f828df --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDelta.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the model-generated transcription of audio output is updated. + public partial class ServerEventResponseAudioTranscriptDelta : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The transcript delta. + internal ServerEventResponseAudioTranscriptDelta(string responseId, string itemId, int outputIndex, int contentIndex, string delta) : base(ServerEventType.ResponseAudioTranscriptDelta) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Delta = delta; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The transcript delta. + internal ServerEventResponseAudioTranscriptDelta(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, string delta) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Delta = delta; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + + /// The transcript delta. + public string Delta { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDone.Serialization.cs new file mode 100644 index 000000000000..121b5fe78d74 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDone.Serialization.cs @@ -0,0 +1,184 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the model-generated transcription of audio output is done + /// streaming. Also emitted when a Response is interrupted, incomplete, or + /// cancelled. + /// + public partial class ServerEventResponseAudioTranscriptDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseAudioTranscriptDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("transcript"u8); + writer.WriteStringValue(Transcript); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseAudioTranscriptDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseAudioTranscriptDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseAudioTranscriptDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseAudioTranscriptDone DeserializeServerEventResponseAudioTranscriptDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + string transcript = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("transcript"u8)) + { + transcript = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseAudioTranscriptDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + transcript); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseAudioTranscriptDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseAudioTranscriptDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseAudioTranscriptDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseAudioTranscriptDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDone.cs new file mode 100644 index 000000000000..a353247cec61 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseAudioTranscriptDone.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the model-generated transcription of audio output is done + /// streaming. Also emitted when a Response is interrupted, incomplete, or + /// cancelled. + /// + public partial class ServerEventResponseAudioTranscriptDone : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The final transcript of the audio. + internal ServerEventResponseAudioTranscriptDone(string responseId, string itemId, int outputIndex, int contentIndex, string transcript) : base(ServerEventType.ResponseAudioTranscriptDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Transcript = transcript; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The final transcript of the audio. + internal ServerEventResponseAudioTranscriptDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, string transcript) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Transcript = transcript; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + + /// The final transcript of the audio. + public string Transcript { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartAdded.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartAdded.Serialization.cs new file mode 100644 index 000000000000..6d7949e1b8e0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartAdded.Serialization.cs @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a new content part is added to an assistant message item during + /// response generation. + /// + public partial class ServerEventResponseContentPartAdded : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseContentPartAdded() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseContentPartAdded)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("part"u8); + writer.WriteObjectValue(Part, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseContentPartAdded IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseContentPartAdded)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseContentPartAdded)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseContentPartAdded(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseContentPartAdded DeserializeServerEventResponseContentPartAdded(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + ContentPart part = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("part"u8)) + { + part = ContentPart.DeserializeContentPart(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseContentPartAdded( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + part); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseContentPartAdded)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseContentPartAdded IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseContentPartAdded)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseContentPartAdded(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseContentPartAdded)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartAdded.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartAdded.cs new file mode 100644 index 000000000000..07e42b22b0a1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartAdded.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a new content part is added to an assistant message item during + /// response generation. + /// + public partial class ServerEventResponseContentPartAdded : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item to which the content part was added. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The content part that was added. + internal ServerEventResponseContentPartAdded(string responseId, string itemId, int outputIndex, int contentIndex, ContentPart part) : base(ServerEventType.ResponseContentPartAdded) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Part = part; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item to which the content part was added. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The content part that was added. + internal ServerEventResponseContentPartAdded(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, ContentPart part) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Part = part; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item to which the content part was added. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + + /// The content part that was added. + public ContentPart Part { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartDone.Serialization.cs new file mode 100644 index 000000000000..dd40438dadb6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartDone.Serialization.cs @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a content part is done streaming in an assistant message item. + /// Also emitted when a Response is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseContentPartDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseContentPartDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseContentPartDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("part"u8); + writer.WriteObjectValue(Part, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseContentPartDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseContentPartDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseContentPartDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseContentPartDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseContentPartDone DeserializeServerEventResponseContentPartDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + ContentPart part = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("part"u8)) + { + part = ContentPart.DeserializeContentPart(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseContentPartDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + part); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseContentPartDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseContentPartDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseContentPartDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseContentPartDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseContentPartDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartDone.cs new file mode 100644 index 000000000000..98428d0a4d23 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseContentPartDone.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a content part is done streaming in an assistant message item. + /// Also emitted when a Response is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseContentPartDone : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The content part that is done. + internal ServerEventResponseContentPartDone(string responseId, string itemId, int outputIndex, int contentIndex, ContentPart part) : base(ServerEventType.ResponseContentPartDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Part = part; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The content part that is done. + internal ServerEventResponseContentPartDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, ContentPart part) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Part = part; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + + /// The content part that is done. + public ContentPart Part { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseCreated.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseCreated.Serialization.cs new file mode 100644 index 000000000000..564b3d6d9a71 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseCreated.Serialization.cs @@ -0,0 +1,143 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a new Response is created. The first event of response creation, + /// where the response is in an initial state of `in_progress`. + /// + public partial class ServerEventResponseCreated : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseCreated() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseCreated)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response"u8); + writer.WriteObjectValue(Response, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseCreated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseCreated)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseCreated)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseCreated(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseCreated DeserializeServerEventResponseCreated(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + VoiceLiveResponse response = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response"u8)) + { + response = VoiceLiveResponse.DeserializeVoiceLiveResponse(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseCreated(@type, eventId, additionalBinaryDataProperties, response); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseCreated)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseCreated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseCreated)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseCreated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseCreated)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseCreated.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseCreated.cs new file mode 100644 index 000000000000..d0159ac2fcfb --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseCreated.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a new Response is created. The first event of response creation, + /// where the response is in an initial state of `in_progress`. + /// + public partial class ServerEventResponseCreated : ServerEvent + { + /// Initializes a new instance of . + /// + internal ServerEventResponseCreated(VoiceLiveResponse response) : base(ServerEventType.ResponseCreated) + { + Response = response; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + internal ServerEventResponseCreated(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, VoiceLiveResponse response) : base(@type, eventId, additionalBinaryDataProperties) + { + Response = response; + } + + /// Gets the Response. + public VoiceLiveResponse Response { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseDone.Serialization.cs new file mode 100644 index 000000000000..ea5c81857c8c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseDone.Serialization.cs @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a Response is done streaming. Always emitted, no matter the + /// final state. The Response object included in the `response.done` event will + /// include all output Items in the Response but will omit the raw audio data. + /// + public partial class ServerEventResponseDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response"u8); + writer.WriteObjectValue(Response, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseDone DeserializeServerEventResponseDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + VoiceLiveResponse response = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response"u8)) + { + response = VoiceLiveResponse.DeserializeVoiceLiveResponse(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseDone(@type, eventId, additionalBinaryDataProperties, response); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseDone.cs new file mode 100644 index 000000000000..c3081dc33d9c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseDone.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a Response is done streaming. Always emitted, no matter the + /// final state. The Response object included in the `response.done` event will + /// include all output Items in the Response but will omit the raw audio data. + /// + public partial class ServerEventResponseDone : ServerEvent + { + /// Initializes a new instance of . + /// + internal ServerEventResponseDone(VoiceLiveResponse response) : base(ServerEventType.ResponseDone) + { + Response = response; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + internal ServerEventResponseDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, VoiceLiveResponse response) : base(@type, eventId, additionalBinaryDataProperties) + { + Response = response; + } + + /// Gets the Response. + public VoiceLiveResponse Response { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseEmotionHypothesis.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseEmotionHypothesis.Serialization.cs new file mode 100644 index 000000000000..042da29cbee0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseEmotionHypothesis.Serialization.cs @@ -0,0 +1,202 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Represents an emotion hypothesis detected from response audio with multiple candidates. + public partial class ServerEventResponseEmotionHypothesis : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseEmotionHypothesis() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseEmotionHypothesis)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("emotion"u8); + writer.WriteStringValue(Emotion); + writer.WritePropertyName("candidates"u8); + writer.WriteStartArray(); + foreach (EmotionCandidate item in Candidates) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + writer.WritePropertyName("audio_offset_ms"u8); + writer.WriteNumberValue(AudioOffsetMs); + writer.WritePropertyName("audio_duration_ms"u8); + writer.WriteNumberValue(AudioDurationMs); + if (Optional.IsDefined(ResponseId)) + { + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + } + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseEmotionHypothesis IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseEmotionHypothesis)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseEmotionHypothesis)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseEmotionHypothesis(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseEmotionHypothesis DeserializeServerEventResponseEmotionHypothesis(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string emotion = default; + IList candidates = default; + int audioOffsetMs = default; + int audioDurationMs = default; + string responseId = default; + string itemId = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("emotion"u8)) + { + emotion = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("candidates"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(EmotionCandidate.DeserializeEmotionCandidate(item, options)); + } + candidates = array; + continue; + } + if (prop.NameEquals("audio_offset_ms"u8)) + { + audioOffsetMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("audio_duration_ms"u8)) + { + audioDurationMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseEmotionHypothesis( + @type, + eventId, + additionalBinaryDataProperties, + emotion, + candidates, + audioOffsetMs, + audioDurationMs, + responseId, + itemId); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseEmotionHypothesis)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseEmotionHypothesis IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseEmotionHypothesis)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseEmotionHypothesis(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseEmotionHypothesis)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseEmotionHypothesis.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseEmotionHypothesis.cs new file mode 100644 index 000000000000..8c02d133b5be --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseEmotionHypothesis.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// Represents an emotion hypothesis detected from response audio with multiple candidates. + public partial class ServerEventResponseEmotionHypothesis : ServerEvent + { + /// Initializes a new instance of . + /// + /// + /// + /// + /// + internal ServerEventResponseEmotionHypothesis(string emotion, IEnumerable candidates, int audioOffsetMs, int audioDurationMs, string itemId) : base(ServerEventType.ResponseEmotionHypothesis) + { + Emotion = emotion; + Candidates = candidates.ToList(); + AudioOffsetMs = audioOffsetMs; + AudioDurationMs = audioDurationMs; + ItemId = itemId; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + /// + /// + internal ServerEventResponseEmotionHypothesis(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string emotion, IList candidates, int audioOffsetMs, int audioDurationMs, string responseId, string itemId) : base(@type, eventId, additionalBinaryDataProperties) + { + Emotion = emotion; + Candidates = candidates; + AudioOffsetMs = audioOffsetMs; + AudioDurationMs = audioDurationMs; + ResponseId = responseId; + ItemId = itemId; + } + + /// Gets the Emotion. + public string Emotion { get; } + + /// Gets the Candidates. + public IList Candidates { get; } + + /// Gets the AudioOffsetMs. + public int AudioOffsetMs { get; } + + /// Gets the AudioDurationMs. + public int AudioDurationMs { get; } + + /// Gets the ResponseId. + public string ResponseId { get; } + + /// Gets the ItemId. + public string ItemId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDelta.Serialization.cs new file mode 100644 index 000000000000..00309ed3b055 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDelta.Serialization.cs @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the model-generated function call arguments are updated. + public partial class ServerEventResponseFunctionCallArgumentsDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseFunctionCallArgumentsDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("call_id"u8); + writer.WriteStringValue(CallId); + writer.WritePropertyName("delta"u8); + writer.WriteStringValue(Delta); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseFunctionCallArgumentsDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseFunctionCallArgumentsDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseFunctionCallArgumentsDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseFunctionCallArgumentsDelta DeserializeServerEventResponseFunctionCallArgumentsDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + string callId = default; + string delta = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("call_id"u8)) + { + callId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("delta"u8)) + { + delta = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseFunctionCallArgumentsDelta( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + callId, + delta); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseFunctionCallArgumentsDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseFunctionCallArgumentsDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseFunctionCallArgumentsDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDelta.cs new file mode 100644 index 000000000000..c75122a70f12 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDelta.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the model-generated function call arguments are updated. + public partial class ServerEventResponseFunctionCallArgumentsDelta : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the function call item. + /// The index of the output item in the response. + /// The ID of the function call. + /// The arguments delta as a JSON string. + internal ServerEventResponseFunctionCallArgumentsDelta(string responseId, string itemId, int outputIndex, string callId, string delta) : base(ServerEventType.ResponseFunctionCallArgumentsDelta) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + CallId = callId; + Delta = delta; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the function call item. + /// The index of the output item in the response. + /// The ID of the function call. + /// The arguments delta as a JSON string. + internal ServerEventResponseFunctionCallArgumentsDelta(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, string callId, string delta) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + CallId = callId; + Delta = delta; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the function call item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The ID of the function call. + public string CallId { get; } + + /// The arguments delta as a JSON string. + public string Delta { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDone.Serialization.cs new file mode 100644 index 000000000000..475589cba542 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDone.Serialization.cs @@ -0,0 +1,192 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the model-generated function call arguments are done streaming. + /// Also emitted when a Response is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseFunctionCallArgumentsDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseFunctionCallArgumentsDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("call_id"u8); + writer.WriteStringValue(CallId); + writer.WritePropertyName("arguments"u8); + writer.WriteStringValue(Arguments); + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseFunctionCallArgumentsDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseFunctionCallArgumentsDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseFunctionCallArgumentsDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseFunctionCallArgumentsDone DeserializeServerEventResponseFunctionCallArgumentsDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + string callId = default; + string arguments = default; + string name = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("call_id"u8)) + { + callId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("arguments"u8)) + { + arguments = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseFunctionCallArgumentsDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + callId, + arguments, + name); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseFunctionCallArgumentsDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseFunctionCallArgumentsDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseFunctionCallArgumentsDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseFunctionCallArgumentsDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDone.cs new file mode 100644 index 000000000000..167107d1ea74 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseFunctionCallArgumentsDone.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the model-generated function call arguments are done streaming. + /// Also emitted when a Response is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseFunctionCallArgumentsDone : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the function call item. + /// The index of the output item in the response. + /// The ID of the function call. + /// The final arguments as a JSON string. + /// The name of the function call. + internal ServerEventResponseFunctionCallArgumentsDone(string responseId, string itemId, int outputIndex, string callId, string arguments, string name) : base(ServerEventType.ResponseFunctionCallArgumentsDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + CallId = callId; + Arguments = arguments; + Name = name; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the function call item. + /// The index of the output item in the response. + /// The ID of the function call. + /// The final arguments as a JSON string. + /// The name of the function call. + internal ServerEventResponseFunctionCallArgumentsDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, string callId, string arguments, string name) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + CallId = callId; + Arguments = arguments; + Name = name; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the function call item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The ID of the function call. + public string CallId { get; } + + /// The final arguments as a JSON string. + public string Arguments { get; } + + /// The name of the function call. + public string Name { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemAdded.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemAdded.Serialization.cs new file mode 100644 index 000000000000..c5269d83c374 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemAdded.Serialization.cs @@ -0,0 +1,169 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Returned when a new Item is created during Response generation. + public partial class ServerEventResponseOutputItemAdded : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseOutputItemAdded() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemAdded)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + if (Optional.IsDefined(Item)) + { + writer.WritePropertyName("item"u8); + writer.WriteObjectValue(Item, options); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseOutputItemAdded IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseOutputItemAdded)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemAdded)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseOutputItemAdded(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseOutputItemAdded DeserializeServerEventResponseOutputItemAdded(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + int outputIndex = default; + ConversationItemWithReference item = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("item"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + item = ConversationItemWithReference.DeserializeConversationItemWithReference(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseOutputItemAdded( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + outputIndex, + item); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemAdded)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseOutputItemAdded IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseOutputItemAdded)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseOutputItemAdded(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemAdded)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemAdded.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemAdded.cs new file mode 100644 index 000000000000..4b34af4953d2 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemAdded.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Returned when a new Item is created during Response generation. + public partial class ServerEventResponseOutputItemAdded : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the Response to which the item belongs. + /// The index of the output item in the Response. + internal ServerEventResponseOutputItemAdded(string responseId, int outputIndex) : base(ServerEventType.ResponseOutputItemAdded) + { + ResponseId = responseId; + OutputIndex = outputIndex; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the Response to which the item belongs. + /// The index of the output item in the Response. + /// + internal ServerEventResponseOutputItemAdded(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, int outputIndex, ConversationItemWithReference item) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + OutputIndex = outputIndex; + Item = item; + } + + /// The ID of the Response to which the item belongs. + public string ResponseId { get; } + + /// The index of the output item in the Response. + public int OutputIndex { get; } + + /// Gets the Item. + public ConversationItemWithReference Item { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemDone.Serialization.cs new file mode 100644 index 000000000000..44c14a5d7b0a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemDone.Serialization.cs @@ -0,0 +1,172 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an Item is done streaming. Also emitted when a Response is + /// interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseOutputItemDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseOutputItemDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + if (Optional.IsDefined(Item)) + { + writer.WritePropertyName("item"u8); + writer.WriteObjectValue(Item, options); + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseOutputItemDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseOutputItemDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseOutputItemDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseOutputItemDone DeserializeServerEventResponseOutputItemDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + int outputIndex = default; + ConversationResponseItem item = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("item"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + item = ConversationResponseItem.DeserializeConversationResponseItem(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseOutputItemDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + outputIndex, + item); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseOutputItemDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseOutputItemDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseOutputItemDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseOutputItemDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemDone.cs new file mode 100644 index 000000000000..1a4316b3c408 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseOutputItemDone.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when an Item is done streaming. Also emitted when a Response is + /// interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseOutputItemDone : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the Response to which the item belongs. + /// The index of the output item in the Response. + internal ServerEventResponseOutputItemDone(string responseId, int outputIndex) : base(ServerEventType.ResponseOutputItemDone) + { + ResponseId = responseId; + OutputIndex = outputIndex; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the Response to which the item belongs. + /// The index of the output item in the Response. + /// + internal ServerEventResponseOutputItemDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, int outputIndex, ConversationResponseItem item) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + OutputIndex = outputIndex; + Item = item; + } + + /// The ID of the Response to which the item belongs. + public string ResponseId { get; } + + /// The index of the output item in the Response. + public int OutputIndex { get; } + + /// Gets the Item. + public ConversationResponseItem Item { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDelta.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDelta.Serialization.cs new file mode 100644 index 000000000000..69cc0b466b22 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDelta.Serialization.cs @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the text value of a "text" content part is updated. + public partial class ServerEventResponseTextDelta : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseTextDelta() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseTextDelta)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("delta"u8); + writer.WriteStringValue(Delta); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseTextDelta IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseTextDelta)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseTextDelta)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseTextDelta(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseTextDelta DeserializeServerEventResponseTextDelta(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + string delta = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("delta"u8)) + { + delta = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseTextDelta( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + delta); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseTextDelta)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseTextDelta IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseTextDelta)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseTextDelta(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseTextDelta)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDelta.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDelta.cs new file mode 100644 index 000000000000..6c7c4df27f5a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDelta.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Returned when the text value of a "text" content part is updated. + public partial class ServerEventResponseTextDelta : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The text delta. + internal ServerEventResponseTextDelta(string responseId, string itemId, int outputIndex, int contentIndex, string delta) : base(ServerEventType.ResponseTextDelta) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Delta = delta; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The text delta. + internal ServerEventResponseTextDelta(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, string delta) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Delta = delta; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + + /// The text delta. + public string Delta { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDone.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDone.Serialization.cs new file mode 100644 index 000000000000..319c4f6d071c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDone.Serialization.cs @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the text value of a "text" content part is done streaming. Also + /// emitted when a Response is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseTextDone : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventResponseTextDone() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseTextDone)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("response_id"u8); + writer.WriteStringValue(ResponseId); + writer.WritePropertyName("item_id"u8); + writer.WriteStringValue(ItemId); + writer.WritePropertyName("output_index"u8); + writer.WriteNumberValue(OutputIndex); + writer.WritePropertyName("content_index"u8); + writer.WriteNumberValue(ContentIndex); + writer.WritePropertyName("text"u8); + writer.WriteStringValue(Text); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventResponseTextDone IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventResponseTextDone)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventResponseTextDone)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventResponseTextDone(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventResponseTextDone DeserializeServerEventResponseTextDone(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string responseId = default; + string itemId = default; + int outputIndex = default; + int contentIndex = default; + string text = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("response_id"u8)) + { + responseId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("item_id"u8)) + { + itemId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("output_index"u8)) + { + outputIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("content_index"u8)) + { + contentIndex = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("text"u8)) + { + text = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventResponseTextDone( + @type, + eventId, + additionalBinaryDataProperties, + responseId, + itemId, + outputIndex, + contentIndex, + text); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventResponseTextDone)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventResponseTextDone IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventResponseTextDone)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventResponseTextDone(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventResponseTextDone)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDone.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDone.cs new file mode 100644 index 000000000000..3a48ef04a732 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventResponseTextDone.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when the text value of a "text" content part is done streaming. Also + /// emitted when a Response is interrupted, incomplete, or cancelled. + /// + public partial class ServerEventResponseTextDone : ServerEvent + { + /// Initializes a new instance of . + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The final text content. + internal ServerEventResponseTextDone(string responseId, string itemId, int outputIndex, int contentIndex, string text) : base(ServerEventType.ResponseTextDone) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Text = text; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The final text content. + internal ServerEventResponseTextDone(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string responseId, string itemId, int outputIndex, int contentIndex, string text) : base(@type, eventId, additionalBinaryDataProperties) + { + ResponseId = responseId; + ItemId = itemId; + OutputIndex = outputIndex; + ContentIndex = contentIndex; + Text = text; + } + + /// The ID of the response. + public string ResponseId { get; } + + /// The ID of the item. + public string ItemId { get; } + + /// The index of the output item in the response. + public int OutputIndex { get; } + + /// The index of the content part in the item's content array. + public int ContentIndex { get; } + + /// The final text content. + public string Text { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionAvatarConnecting.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionAvatarConnecting.Serialization.cs new file mode 100644 index 000000000000..fa69df5a6595 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionAvatarConnecting.Serialization.cs @@ -0,0 +1,140 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Sent when the server is in the process of establishing an avatar media connection and provides its SDP answer. + public partial class ServerEventSessionAvatarConnecting : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventSessionAvatarConnecting() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventSessionAvatarConnecting)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("server_sdp"u8); + writer.WriteStringValue(ServerSdp); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventSessionAvatarConnecting IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventSessionAvatarConnecting)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventSessionAvatarConnecting)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventSessionAvatarConnecting(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventSessionAvatarConnecting DeserializeServerEventSessionAvatarConnecting(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + string serverSdp = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("server_sdp"u8)) + { + serverSdp = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventSessionAvatarConnecting(@type, eventId, additionalBinaryDataProperties, serverSdp); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventSessionAvatarConnecting)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventSessionAvatarConnecting IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventSessionAvatarConnecting)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventSessionAvatarConnecting(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventSessionAvatarConnecting)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionAvatarConnecting.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionAvatarConnecting.cs new file mode 100644 index 000000000000..281f876f4789 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionAvatarConnecting.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Sent when the server is in the process of establishing an avatar media connection and provides its SDP answer. + public partial class ServerEventSessionAvatarConnecting : ServerEvent + { + /// Initializes a new instance of . + /// The server's SDP answer for the avatar connection. + internal ServerEventSessionAvatarConnecting(string serverSdp) : base(ServerEventType.SessionAvatarConnecting) + { + ServerSdp = serverSdp; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// The server's SDP answer for the avatar connection. + internal ServerEventSessionAvatarConnecting(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, string serverSdp) : base(@type, eventId, additionalBinaryDataProperties) + { + ServerSdp = serverSdp; + } + + /// The server's SDP answer for the avatar connection. + public string ServerSdp { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionCreated.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionCreated.Serialization.cs new file mode 100644 index 000000000000..5905c24c5b20 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionCreated.Serialization.cs @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a Session is created. Emitted automatically when a new + /// connection is established as the first server event. This event will contain + /// the default Session configuration. + /// + public partial class ServerEventSessionCreated : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventSessionCreated() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventSessionCreated)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("session"u8); + writer.WriteObjectValue(Session, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventSessionCreated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventSessionCreated)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventSessionCreated)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventSessionCreated(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventSessionCreated DeserializeServerEventSessionCreated(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + ResponseSession session = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("session"u8)) + { + session = ResponseSession.DeserializeResponseSession(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventSessionCreated(@type, eventId, additionalBinaryDataProperties, session); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventSessionCreated)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventSessionCreated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventSessionCreated)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventSessionCreated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventSessionCreated)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionCreated.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionCreated.cs new file mode 100644 index 000000000000..af1b443d8755 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionCreated.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a Session is created. Emitted automatically when a new + /// connection is established as the first server event. This event will contain + /// the default Session configuration. + /// + public partial class ServerEventSessionCreated : ServerEvent + { + /// Initializes a new instance of . + /// + internal ServerEventSessionCreated(ResponseSession session) : base(ServerEventType.SessionCreated) + { + Session = session; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + internal ServerEventSessionCreated(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, ResponseSession session) : base(@type, eventId, additionalBinaryDataProperties) + { + Session = session; + } + + /// Gets the Session. + public ResponseSession Session { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionUpdated.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionUpdated.Serialization.cs new file mode 100644 index 000000000000..172ea74dc202 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionUpdated.Serialization.cs @@ -0,0 +1,143 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a session is updated with a `session.update` event, unless + /// there is an error. + /// + public partial class ServerEventSessionUpdated : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ServerEventSessionUpdated() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventSessionUpdated)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("session"u8); + writer.WriteObjectValue(Session, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEventSessionUpdated IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerEventSessionUpdated)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEventSessionUpdated)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEventSessionUpdated(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerEventSessionUpdated DeserializeServerEventSessionUpdated(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + ResponseSession session = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("session"u8)) + { + session = ResponseSession.DeserializeResponseSession(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerEventSessionUpdated(@type, eventId, additionalBinaryDataProperties, session); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEventSessionUpdated)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEventSessionUpdated IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerEventSessionUpdated)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEventSessionUpdated(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEventSessionUpdated)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionUpdated.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionUpdated.cs new file mode 100644 index 000000000000..d2a8f8454146 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventSessionUpdated.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Returned when a session is updated with a `session.update` event, unless + /// there is an error. + /// + public partial class ServerEventSessionUpdated : ServerEvent + { + /// Initializes a new instance of . + /// + internal ServerEventSessionUpdated(ResponseSession session) : base(ServerEventType.SessionUpdated) + { + Session = session; + } + + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + /// + internal ServerEventSessionUpdated(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties, ResponseSession session) : base(@type, eventId, additionalBinaryDataProperties) + { + Session = session; + } + + /// Gets the Session. + public ResponseSession Session { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventType.cs new file mode 100644 index 000000000000..d86547fd3317 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerEventType.cs @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// Server event types used in VoiceLive protocol. + internal readonly partial struct ServerEventType : IEquatable + { + private readonly string _value; + private const string ErrorValue = "error"; + private const string SessionAvatarConnectingValue = "session.avatar.connecting"; + private const string SessionCreatedValue = "session.created"; + private const string SessionUpdatedValue = "session.updated"; + private const string ConversationItemInputAudioTranscriptionCompletedValue = "conversation.item.input_audio_transcription.completed"; + private const string ConversationItemInputAudioTranscriptionDeltaValue = "conversation.item.input_audio_transcription.delta"; + private const string ConversationItemInputAudioTranscriptionFailedValue = "conversation.item.input_audio_transcription.failed"; + private const string ConversationItemCreatedValue = "conversation.item.created"; + private const string ConversationItemRetrievedValue = "conversation.item.retrieved"; + private const string ConversationItemTruncatedValue = "conversation.item.truncated"; + private const string ConversationItemDeletedValue = "conversation.item.deleted"; + private const string InputAudioBufferCommittedValue = "input_audio_buffer.committed"; + private const string InputAudioBufferClearedValue = "input_audio_buffer.cleared"; + private const string InputAudioBufferSpeechStartedValue = "input_audio_buffer.speech_started"; + private const string InputAudioBufferSpeechStoppedValue = "input_audio_buffer.speech_stopped"; + private const string ResponseCreatedValue = "response.created"; + private const string ResponseDoneValue = "response.done"; + private const string ResponseOutputItemAddedValue = "response.output_item.added"; + private const string ResponseOutputItemDoneValue = "response.output_item.done"; + private const string ResponseContentPartAddedValue = "response.content_part.added"; + private const string ResponseContentPartDoneValue = "response.content_part.done"; + private const string ResponseTextDeltaValue = "response.text.delta"; + private const string ResponseTextDoneValue = "response.text.done"; + private const string ResponseAudioTranscriptDeltaValue = "response.audio_transcript.delta"; + private const string ResponseAudioTranscriptDoneValue = "response.audio_transcript.done"; + private const string ResponseAudioDeltaValue = "response.audio.delta"; + private const string ResponseAudioDoneValue = "response.audio.done"; + private const string ResponseAnimationBlendshapesDeltaValue = "response.animation_blendshapes.delta"; + private const string ResponseAnimationBlendshapesDoneValue = "response.animation_blendshapes.done"; + private const string ResponseEmotionHypothesisValue = "response.emotion_hypothesis"; + private const string ResponseAudioTimestampDeltaValue = "response.audio_timestamp.delta"; + private const string ResponseAudioTimestampDoneValue = "response.audio_timestamp.done"; + private const string ResponseAnimationVisemeDeltaValue = "response.animation_viseme.delta"; + private const string ResponseAnimationVisemeDoneValue = "response.animation_viseme.done"; + private const string ResponseFunctionCallArgumentsDeltaValue = "response.function_call_arguments.delta"; + private const string ResponseFunctionCallArgumentsDoneValue = "response.function_call_arguments.done"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public ServerEventType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the Error. + public static ServerEventType Error { get; } = new ServerEventType(ErrorValue); + + /// Gets the SessionAvatarConnecting. + public static ServerEventType SessionAvatarConnecting { get; } = new ServerEventType(SessionAvatarConnectingValue); + + /// Gets the SessionCreated. + public static ServerEventType SessionCreated { get; } = new ServerEventType(SessionCreatedValue); + + /// Gets the SessionUpdated. + public static ServerEventType SessionUpdated { get; } = new ServerEventType(SessionUpdatedValue); + + /// Gets the ConversationItemInputAudioTranscriptionCompleted. + public static ServerEventType ConversationItemInputAudioTranscriptionCompleted { get; } = new ServerEventType(ConversationItemInputAudioTranscriptionCompletedValue); + + /// Gets the ConversationItemInputAudioTranscriptionDelta. + public static ServerEventType ConversationItemInputAudioTranscriptionDelta { get; } = new ServerEventType(ConversationItemInputAudioTranscriptionDeltaValue); + + /// Gets the ConversationItemInputAudioTranscriptionFailed. + public static ServerEventType ConversationItemInputAudioTranscriptionFailed { get; } = new ServerEventType(ConversationItemInputAudioTranscriptionFailedValue); + + /// Gets the ConversationItemCreated. + public static ServerEventType ConversationItemCreated { get; } = new ServerEventType(ConversationItemCreatedValue); + + /// Gets the ConversationItemRetrieved. + public static ServerEventType ConversationItemRetrieved { get; } = new ServerEventType(ConversationItemRetrievedValue); + + /// Gets the ConversationItemTruncated. + public static ServerEventType ConversationItemTruncated { get; } = new ServerEventType(ConversationItemTruncatedValue); + + /// Gets the ConversationItemDeleted. + public static ServerEventType ConversationItemDeleted { get; } = new ServerEventType(ConversationItemDeletedValue); + + /// Gets the InputAudioBufferCommitted. + public static ServerEventType InputAudioBufferCommitted { get; } = new ServerEventType(InputAudioBufferCommittedValue); + + /// Gets the InputAudioBufferCleared. + public static ServerEventType InputAudioBufferCleared { get; } = new ServerEventType(InputAudioBufferClearedValue); + + /// Gets the InputAudioBufferSpeechStarted. + public static ServerEventType InputAudioBufferSpeechStarted { get; } = new ServerEventType(InputAudioBufferSpeechStartedValue); + + /// Gets the InputAudioBufferSpeechStopped. + public static ServerEventType InputAudioBufferSpeechStopped { get; } = new ServerEventType(InputAudioBufferSpeechStoppedValue); + + /// Gets the ResponseCreated. + public static ServerEventType ResponseCreated { get; } = new ServerEventType(ResponseCreatedValue); + + /// Gets the ResponseDone. + public static ServerEventType ResponseDone { get; } = new ServerEventType(ResponseDoneValue); + + /// Gets the ResponseOutputItemAdded. + public static ServerEventType ResponseOutputItemAdded { get; } = new ServerEventType(ResponseOutputItemAddedValue); + + /// Gets the ResponseOutputItemDone. + public static ServerEventType ResponseOutputItemDone { get; } = new ServerEventType(ResponseOutputItemDoneValue); + + /// Gets the ResponseContentPartAdded. + public static ServerEventType ResponseContentPartAdded { get; } = new ServerEventType(ResponseContentPartAddedValue); + + /// Gets the ResponseContentPartDone. + public static ServerEventType ResponseContentPartDone { get; } = new ServerEventType(ResponseContentPartDoneValue); + + /// Gets the ResponseTextDelta. + public static ServerEventType ResponseTextDelta { get; } = new ServerEventType(ResponseTextDeltaValue); + + /// Gets the ResponseTextDone. + public static ServerEventType ResponseTextDone { get; } = new ServerEventType(ResponseTextDoneValue); + + /// Gets the ResponseAudioTranscriptDelta. + public static ServerEventType ResponseAudioTranscriptDelta { get; } = new ServerEventType(ResponseAudioTranscriptDeltaValue); + + /// Gets the ResponseAudioTranscriptDone. + public static ServerEventType ResponseAudioTranscriptDone { get; } = new ServerEventType(ResponseAudioTranscriptDoneValue); + + /// Gets the ResponseAudioDelta. + public static ServerEventType ResponseAudioDelta { get; } = new ServerEventType(ResponseAudioDeltaValue); + + /// Gets the ResponseAudioDone. + public static ServerEventType ResponseAudioDone { get; } = new ServerEventType(ResponseAudioDoneValue); + + /// Gets the ResponseAnimationBlendshapesDelta. + public static ServerEventType ResponseAnimationBlendshapesDelta { get; } = new ServerEventType(ResponseAnimationBlendshapesDeltaValue); + + /// Gets the ResponseAnimationBlendshapesDone. + public static ServerEventType ResponseAnimationBlendshapesDone { get; } = new ServerEventType(ResponseAnimationBlendshapesDoneValue); + + /// Gets the ResponseEmotionHypothesis. + public static ServerEventType ResponseEmotionHypothesis { get; } = new ServerEventType(ResponseEmotionHypothesisValue); + + /// Gets the ResponseAudioTimestampDelta. + public static ServerEventType ResponseAudioTimestampDelta { get; } = new ServerEventType(ResponseAudioTimestampDeltaValue); + + /// Gets the ResponseAudioTimestampDone. + public static ServerEventType ResponseAudioTimestampDone { get; } = new ServerEventType(ResponseAudioTimestampDoneValue); + + /// Gets the ResponseAnimationVisemeDelta. + public static ServerEventType ResponseAnimationVisemeDelta { get; } = new ServerEventType(ResponseAnimationVisemeDeltaValue); + + /// Gets the ResponseAnimationVisemeDone. + public static ServerEventType ResponseAnimationVisemeDone { get; } = new ServerEventType(ResponseAnimationVisemeDoneValue); + + /// Gets the ResponseFunctionCallArgumentsDelta. + public static ServerEventType ResponseFunctionCallArgumentsDelta { get; } = new ServerEventType(ResponseFunctionCallArgumentsDeltaValue); + + /// Gets the ResponseFunctionCallArgumentsDone. + public static ServerEventType ResponseFunctionCallArgumentsDone { get; } = new ServerEventType(ResponseFunctionCallArgumentsDoneValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(ServerEventType left, ServerEventType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(ServerEventType left, ServerEventType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator ServerEventType(string value) => new ServerEventType(value); + + /// Converts a string to a . + /// The value. + public static implicit operator ServerEventType?(string value) => value == null ? null : new ServerEventType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ServerEventType other && Equals(other); + + /// + public bool Equals(ServerEventType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerVad.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerVad.Serialization.cs new file mode 100644 index 000000000000..b9be5a1404f0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerVad.Serialization.cs @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Base model for VAD-based turn detection. + public partial class ServerVad : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerVad)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + if (Optional.IsDefined(Threshold)) + { + writer.WritePropertyName("threshold"u8); + writer.WriteNumberValue(Threshold.Value); + } + if (Optional.IsDefined(PrefixPaddingMs)) + { + writer.WritePropertyName("prefix_padding_ms"u8); + writer.WriteNumberValue(PrefixPaddingMs.Value); + } + if (Optional.IsDefined(SilenceDurationMs)) + { + writer.WritePropertyName("silence_duration_ms"u8); + writer.WriteNumberValue(SilenceDurationMs.Value); + } + if (Optional.IsDefined(EndOfUtteranceDetection)) + { + writer.WritePropertyName("end_of_utterance_detection"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(EndOfUtteranceDetection); +#else + using (JsonDocument document = JsonDocument.Parse(EndOfUtteranceDetection)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerVad IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ServerVad)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override TurnDetection JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerVad)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerVad(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ServerVad DeserializeServerVad(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + TurnDetectionType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + float? threshold = default; + int? prefixPaddingMs = default; + int? silenceDurationMs = default; + BinaryData endOfUtteranceDetection = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString().ToTurnDetectionType(); + continue; + } + if (prop.NameEquals("threshold"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + threshold = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("prefix_padding_ms"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + prefixPaddingMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("silence_duration_ms"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + silenceDurationMs = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("end_of_utterance_detection"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + endOfUtteranceDetection = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ServerVad( + @type, + additionalBinaryDataProperties, + threshold, + prefixPaddingMs, + silenceDurationMs, + endOfUtteranceDetection); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerVad)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerVad IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ServerVad)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override TurnDetection PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerVad(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerVad)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerVad.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerVad.cs new file mode 100644 index 000000000000..580255908603 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ServerVad.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Base model for VAD-based turn detection. + public partial class ServerVad : TurnDetection + { + /// Initializes a new instance of . + public ServerVad() : base(TurnDetectionType.ServerVad) + { + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + /// + /// + /// + internal ServerVad(TurnDetectionType @type, IDictionary additionalBinaryDataProperties, float? threshold, int? prefixPaddingMs, int? silenceDurationMs, BinaryData endOfUtteranceDetection) : base(@type, additionalBinaryDataProperties) + { + Threshold = threshold; + PrefixPaddingMs = prefixPaddingMs; + SilenceDurationMs = silenceDurationMs; + EndOfUtteranceDetection = endOfUtteranceDetection; + } + + /// Gets or sets the Threshold. + public float? Threshold { get; set; } + + /// Gets or sets the PrefixPaddingMs. + public int? PrefixPaddingMs { get; set; } + + /// Gets or sets the SilenceDurationMs. + public int? SilenceDurationMs { get; set; } + + /// + /// Gets or sets the EndOfUtteranceDetection. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData EndOfUtteranceDetection { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolCall.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolCall.Serialization.cs new file mode 100644 index 000000000000..7f1c37f49219 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolCall.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// The base representation of a voicelive tool definition. + /// Please note this is the abstract base class. The derived classes available for instantiation are: . + /// + [PersistableModelProxy(typeof(UnknownToolCall))] + public abstract partial class ToolCall : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ToolCall() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolCall)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ToolCall IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ToolCall JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolCall)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeToolCall(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ToolCall DeserializeToolCall(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "function": + return FunctionTool.DeserializeFunctionTool(element, options); + } + } + return UnknownToolCall.DeserializeUnknownToolCall(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ToolCall)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ToolCall IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ToolCall PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeToolCall(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ToolCall)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolCall.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolCall.cs new file mode 100644 index 000000000000..d8bf4c6bad07 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolCall.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// The base representation of a voicelive tool definition. + /// Please note this is the abstract base class. The derived classes available for instantiation are: . + /// + public abstract partial class ToolCall + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + private protected ToolCall(ToolType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ToolCall(ToolType @type, IDictionary additionalBinaryDataProperties) + { + Type = @type; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets or sets the Type. + internal ToolType Type { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObject.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObject.Serialization.cs new file mode 100644 index 000000000000..9e27ce93cf16 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObject.Serialization.cs @@ -0,0 +1,134 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The representation of a voicelive tool_choice selecting a named function tool. + public partial class ToolChoiceFunctionObject : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ToolChoiceFunctionObject() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceFunctionObject)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + writer.WritePropertyName("function"u8); + writer.WriteObjectValue(Function, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ToolChoiceFunctionObject IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (ToolChoiceFunctionObject)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ToolChoiceObject JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceFunctionObject)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeToolChoiceFunctionObject(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ToolChoiceFunctionObject DeserializeToolChoiceFunctionObject(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ToolType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + ToolChoiceFunctionObjectFunction function = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ToolType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("function"u8)) + { + function = ToolChoiceFunctionObjectFunction.DeserializeToolChoiceFunctionObjectFunction(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ToolChoiceFunctionObject(@type, additionalBinaryDataProperties, function); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ToolChoiceFunctionObject)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ToolChoiceFunctionObject IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (ToolChoiceFunctionObject)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ToolChoiceObject PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeToolChoiceFunctionObject(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ToolChoiceFunctionObject)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObject.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObject.cs new file mode 100644 index 000000000000..df01e8fb60ee --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObject.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The representation of a voicelive tool_choice selecting a named function tool. + public partial class ToolChoiceFunctionObject : ToolChoiceObject + { + /// Initializes a new instance of . + /// + /// is null. + public ToolChoiceFunctionObject(ToolChoiceFunctionObjectFunction function) : base(ToolType.Function) + { + Argument.AssertNotNull(function, nameof(function)); + + Function = function; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + /// + internal ToolChoiceFunctionObject(ToolType @type, IDictionary additionalBinaryDataProperties, ToolChoiceFunctionObjectFunction function) : base(@type, additionalBinaryDataProperties) + { + Function = function; + } + + /// Gets or sets the Function. + public ToolChoiceFunctionObjectFunction Function { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObjectFunction.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObjectFunction.Serialization.cs new file mode 100644 index 000000000000..8032cdc13ebc --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObjectFunction.Serialization.cs @@ -0,0 +1,142 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The ToolChoiceFunctionObjectFunction. + public partial class ToolChoiceFunctionObjectFunction : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ToolChoiceFunctionObjectFunction() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceFunctionObjectFunction)} does not support writing '{format}' format."); + } + writer.WritePropertyName("name"u8); + writer.WriteStringValue(Name); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ToolChoiceFunctionObjectFunction IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ToolChoiceFunctionObjectFunction JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceFunctionObjectFunction)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeToolChoiceFunctionObjectFunction(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ToolChoiceFunctionObjectFunction DeserializeToolChoiceFunctionObjectFunction(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string name = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("name"u8)) + { + name = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new ToolChoiceFunctionObjectFunction(name, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ToolChoiceFunctionObjectFunction)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ToolChoiceFunctionObjectFunction IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ToolChoiceFunctionObjectFunction PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeToolChoiceFunctionObjectFunction(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ToolChoiceFunctionObjectFunction)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObjectFunction.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObjectFunction.cs new file mode 100644 index 000000000000..036e0ee7fc7b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceFunctionObjectFunction.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The ToolChoiceFunctionObjectFunction. + public partial class ToolChoiceFunctionObjectFunction + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + /// is null. + public ToolChoiceFunctionObjectFunction(string name) + { + Argument.AssertNotNull(name, nameof(name)); + + Name = name; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ToolChoiceFunctionObjectFunction(string name, IDictionary additionalBinaryDataProperties) + { + Name = name; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets or sets the Name. + public string Name { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceLiteral.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceLiteral.cs new file mode 100644 index 000000000000..e964f6cf174a --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceLiteral.cs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// The available set of mode-level, string literal tool_choice options for the voicelive endpoint. + public readonly partial struct ToolChoiceLiteral : IEquatable + { + private readonly string _value; + /// Specifies that the model should freely determine which tool or tools, if any, to call. + private const string AutoValue = "auto"; + /// Specifies that the model should call no tools whatsoever. + private const string NoneValue = "none"; + /// Specifies that the model should call at least one tool. + private const string RequiredValue = "required"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public ToolChoiceLiteral(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Specifies that the model should freely determine which tool or tools, if any, to call. + public static ToolChoiceLiteral Auto { get; } = new ToolChoiceLiteral(AutoValue); + + /// Specifies that the model should call no tools whatsoever. + public static ToolChoiceLiteral None { get; } = new ToolChoiceLiteral(NoneValue); + + /// Specifies that the model should call at least one tool. + public static ToolChoiceLiteral Required { get; } = new ToolChoiceLiteral(RequiredValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(ToolChoiceLiteral left, ToolChoiceLiteral right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(ToolChoiceLiteral left, ToolChoiceLiteral right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator ToolChoiceLiteral(string value) => new ToolChoiceLiteral(value); + + /// Converts a string to a . + /// The value. + public static implicit operator ToolChoiceLiteral?(string value) => value == null ? null : new ToolChoiceLiteral(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ToolChoiceLiteral other && Equals(other); + + /// + public bool Equals(ToolChoiceLiteral other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceObject.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceObject.Serialization.cs new file mode 100644 index 000000000000..b63f505d8774 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceObject.Serialization.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// A base representation for a voicelive tool_choice selecting a named tool. + /// Please note this is the abstract base class. The derived classes available for instantiation are: . + /// + [PersistableModelProxy(typeof(UnknownToolChoiceObject))] + public abstract partial class ToolChoiceObject : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal ToolChoiceObject() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToString()); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + ToolChoiceObject IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual ToolChoiceObject JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeToolChoiceObject(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static ToolChoiceObject DeserializeToolChoiceObject(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "function": + return ToolChoiceFunctionObject.DeserializeToolChoiceFunctionObject(element, options); + } + } + return UnknownToolChoiceObject.DeserializeUnknownToolChoiceObject(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ToolChoiceObject IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual ToolChoiceObject PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeToolChoiceObject(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceObject.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceObject.cs new file mode 100644 index 000000000000..4221e2b53cfb --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolChoiceObject.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// A base representation for a voicelive tool_choice selecting a named tool. + /// Please note this is the abstract base class. The derived classes available for instantiation are: . + /// + public abstract partial class ToolChoiceObject + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + private protected ToolChoiceObject(ToolType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal ToolChoiceObject(ToolType @type, IDictionary additionalBinaryDataProperties) + { + Type = @type; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets or sets the Type. + internal ToolType Type { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolType.cs new file mode 100644 index 000000000000..08ce8c2e684f --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/ToolType.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ComponentModel; + +namespace Azure.AI.VoiceLive +{ + /// + /// The supported tool type discriminators for voicelive tools. + /// Currently, only 'function' tools are supported. + /// + internal readonly partial struct ToolType : IEquatable + { + private readonly string _value; + private const string FunctionValue = "function"; + + /// Initializes a new instance of . + /// The value. + /// is null. + public ToolType(string value) + { + Argument.AssertNotNull(value, nameof(value)); + + _value = value; + } + + /// Gets the Function. + public static ToolType Function { get; } = new ToolType(FunctionValue); + + /// Determines if two values are the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator ==(ToolType left, ToolType right) => left.Equals(right); + + /// Determines if two values are not the same. + /// The left value to compare. + /// The right value to compare. + public static bool operator !=(ToolType left, ToolType right) => !left.Equals(right); + + /// Converts a string to a . + /// The value. + public static implicit operator ToolType(string value) => new ToolType(value); + + /// Converts a string to a . + /// The value. + public static implicit operator ToolType?(string value) => value == null ? null : new ToolType(value); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => obj is ToolType other && Equals(other); + + /// + public bool Equals(ToolType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0; + + /// + public override string ToString() => _value; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetection.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetection.Serialization.cs new file mode 100644 index 000000000000..c06bb2db18a0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetection.Serialization.cs @@ -0,0 +1,143 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// + /// Top-level union for turn detection configuration. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + [PersistableModelProxy(typeof(UnknownTurnDetection))] + public abstract partial class TurnDetection : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal TurnDetection() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(TurnDetection)} does not support writing '{format}' format."); + } + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type.ToSerialString()); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + TurnDetection IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual TurnDetection JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(TurnDetection)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeTurnDetection(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static TurnDetection DeserializeTurnDetection(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + if (element.TryGetProperty("type"u8, out JsonElement discriminator)) + { + switch (discriminator.GetString()) + { + case "none": + return NoTurnDetection.DeserializeNoTurnDetection(element, options); + case "server_vad": + return ServerVad.DeserializeServerVad(element, options); + case "azure_semantic_vad": + return AzureSemanticVad.DeserializeAzureSemanticVad(element, options); + } + } + return UnknownTurnDetection.DeserializeUnknownTurnDetection(element, options); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(TurnDetection)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + TurnDetection IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual TurnDetection PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeTurnDetection(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(TurnDetection)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetection.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetection.cs new file mode 100644 index 000000000000..148c3c1ac4e1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetection.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// + /// Top-level union for turn detection configuration. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + public abstract partial class TurnDetection + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// + private protected TurnDetection(TurnDetectionType @type) + { + Type = @type; + } + + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal TurnDetection(TurnDetectionType @type, IDictionary additionalBinaryDataProperties) + { + Type = @type; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Gets or sets the Type. + internal TurnDetectionType Type { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetectionType.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetectionType.Serialization.cs new file mode 100644 index 000000000000..7b4d86fdf34d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetectionType.Serialization.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; + +namespace Azure.AI.VoiceLive +{ + internal static partial class TurnDetectionTypeExtensions + { + /// The value to serialize. + public static string ToSerialString(this TurnDetectionType value) => value switch + { + TurnDetectionType.None => "none", + TurnDetectionType.ServerVad => "server_vad", + TurnDetectionType.AzureSemanticVad => "azure_semantic_vad", + _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown TurnDetectionType value.") + }; + + /// The value to deserialize. + public static TurnDetectionType ToTurnDetectionType(this string value) + { + if (StringComparer.OrdinalIgnoreCase.Equals(value, "none")) + { + return TurnDetectionType.None; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "server_vad")) + { + return TurnDetectionType.ServerVad; + } + if (StringComparer.OrdinalIgnoreCase.Equals(value, "azure_semantic_vad")) + { + return TurnDetectionType.AzureSemanticVad; + } + throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown TurnDetectionType value."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetectionType.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetectionType.cs new file mode 100644 index 000000000000..675dc1251908 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/TurnDetectionType.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +namespace Azure.AI.VoiceLive +{ + /// + internal enum TurnDetectionType + { + /// None. + None, + /// ServerVad. + ServerVad, + /// AzureSemanticVad. + AzureSemanticVad + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownClientEvent.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownClientEvent.Serialization.cs new file mode 100644 index 000000000000..7334bf4f09cc --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownClientEvent.Serialization.cs @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownClientEvent : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownClientEvent() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEvent)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ClientEvent IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ClientEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ClientEvent)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeClientEvent(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownClientEvent DeserializeUnknownClientEvent(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ClientEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ClientEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownClientEvent(@type, eventId, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ClientEvent)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ClientEvent IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ClientEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeClientEvent(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ClientEvent)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownClientEvent.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownClientEvent.cs new file mode 100644 index 000000000000..a94f5faa155c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownClientEvent.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownClientEvent : ClientEvent + { + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal UnknownClientEvent(ClientEventType @type, string eventId, IDictionary additionalBinaryDataProperties) : base(@type != default ? @type : "unknown", eventId, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownContentPart.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownContentPart.Serialization.cs new file mode 100644 index 000000000000..266b4c3e19f0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownContentPart.Serialization.cs @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownContentPart : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownContentPart() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ContentPart)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ContentPart IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ContentPart JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ContentPart)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeContentPart(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownContentPart DeserializeUnknownContentPart(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ContentPartType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ContentPartType(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownContentPart(@type, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ContentPart)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ContentPart IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ContentPart PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeContentPart(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ContentPart)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownContentPart.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownContentPart.cs new file mode 100644 index 000000000000..3b8e3170348f --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownContentPart.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownContentPart : ContentPart + { + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal UnknownContentPart(ContentPartType @type, IDictionary additionalBinaryDataProperties) : base(@type != default ? @type : "unknown", additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationRequestItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationRequestItem.Serialization.cs new file mode 100644 index 000000000000..8038ee52a2a6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationRequestItem.Serialization.cs @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownConversationRequestItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownConversationRequestItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ConversationRequestItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConversationRequestItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownConversationRequestItem DeserializeUnknownConversationRequestItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownConversationRequestItem(@type, id, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ConversationRequestItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeConversationRequestItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConversationRequestItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationRequestItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationRequestItem.cs new file mode 100644 index 000000000000..947d1ac3c19b --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationRequestItem.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownConversationRequestItem : ConversationRequestItem + { + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + internal UnknownConversationRequestItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties) : base(@type != default ? @type : "unknown", id, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationResponseItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationResponseItem.Serialization.cs new file mode 100644 index 000000000000..6b37d37952c4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationResponseItem.Serialization.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownConversationResponseItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownConversationResponseItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ConversationResponseItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationResponseItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeConversationResponseItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownConversationResponseItem DeserializeUnknownConversationResponseItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string @object = default; + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("object"u8)) + { + @object = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownConversationResponseItem(@object, @type, id, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ConversationResponseItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationResponseItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeConversationResponseItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ConversationResponseItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationResponseItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationResponseItem.cs new file mode 100644 index 000000000000..5f896e1cd639 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownConversationResponseItem.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownConversationResponseItem : ConversationResponseItem + { + /// Initializes a new instance of . + /// + /// + /// + /// Keeps track of any properties unknown to the library. + internal UnknownConversationResponseItem(string @object, ItemType @type, string id, IDictionary additionalBinaryDataProperties) : base(@object, @type != default ? @type : "unknown", id, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownRequestMessageItem.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownRequestMessageItem.Serialization.cs new file mode 100644 index 000000000000..c64a6d0ea545 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownRequestMessageItem.Serialization.cs @@ -0,0 +1,147 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownRequestMessageItem : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownRequestMessageItem() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + RequestMessageItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => (UnknownRequestMessageItem)JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ConversationRequestItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeRequestMessageItem(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownRequestMessageItem DeserializeUnknownRequestMessageItem(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ItemType @type = default; + string id = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + MessageRole role = default; + ItemStatus? status = default; + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ItemType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("role"u8)) + { + role = new MessageRole(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("status"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = new ItemStatus(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownRequestMessageItem(@type, id, additionalBinaryDataProperties, role, status); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + RequestMessageItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (UnknownRequestMessageItem)PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ConversationRequestItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeRequestMessageItem(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(RequestMessageItem)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownRequestMessageItem.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownRequestMessageItem.cs new file mode 100644 index 000000000000..e51a913d4891 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownRequestMessageItem.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownRequestMessageItem : RequestMessageItem + { + /// Initializes a new instance of . + /// + /// + /// Keeps track of any properties unknown to the library. + /// + /// + internal UnknownRequestMessageItem(ItemType @type, string id, IDictionary additionalBinaryDataProperties, MessageRole role, ItemStatus? status) : base(@type != default ? @type : "unknown", id, additionalBinaryDataProperties, role != default ? role : "unknown", status) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownServerEvent.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownServerEvent.Serialization.cs new file mode 100644 index 000000000000..2d5da5bd1171 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownServerEvent.Serialization.cs @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownServerEvent : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownServerEvent() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEvent)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ServerEvent IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ServerEvent JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ServerEvent)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeServerEvent(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownServerEvent DeserializeUnknownServerEvent(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ServerEventType @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ServerEventType(prop.Value.GetString()); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownServerEvent(@type, eventId, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ServerEvent)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ServerEvent IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ServerEvent PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeServerEvent(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ServerEvent)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownServerEvent.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownServerEvent.cs new file mode 100644 index 000000000000..5b2f07e01339 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownServerEvent.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownServerEvent : ServerEvent + { + /// Initializes a new instance of . + /// The type of event. + /// + /// Keeps track of any properties unknown to the library. + internal UnknownServerEvent(ServerEventType @type, string eventId, IDictionary additionalBinaryDataProperties) : base(@type != default ? @type : "unknown", eventId, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolCall.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolCall.Serialization.cs new file mode 100644 index 000000000000..1902195f1c7c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolCall.Serialization.cs @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownToolCall : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownToolCall() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolCall)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ToolCall IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ToolCall JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolCall)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeToolCall(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownToolCall DeserializeUnknownToolCall(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ToolType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ToolType(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownToolCall(@type, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ToolCall)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ToolCall IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ToolCall PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeToolCall(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ToolCall)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolCall.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolCall.cs new file mode 100644 index 000000000000..c10863b768fe --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolCall.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownToolCall : ToolCall + { + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal UnknownToolCall(ToolType @type, IDictionary additionalBinaryDataProperties) : base(@type != default ? @type : "unknown", additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolChoiceObject.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolChoiceObject.Serialization.cs new file mode 100644 index 000000000000..0daedf1baa24 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolChoiceObject.Serialization.cs @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownToolChoiceObject : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownToolChoiceObject() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + ToolChoiceObject IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override ToolChoiceObject JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeToolChoiceObject(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownToolChoiceObject DeserializeUnknownToolChoiceObject(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + ToolType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = new ToolType(prop.Value.GetString()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownToolChoiceObject(@type, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + ToolChoiceObject IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override ToolChoiceObject PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeToolChoiceObject(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(ToolChoiceObject)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolChoiceObject.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolChoiceObject.cs new file mode 100644 index 000000000000..c29130cba504 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownToolChoiceObject.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownToolChoiceObject : ToolChoiceObject + { + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal UnknownToolChoiceObject(ToolType @type, IDictionary additionalBinaryDataProperties) : base(@type != default ? @type : "unknown", additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownTurnDetection.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownTurnDetection.Serialization.cs new file mode 100644 index 000000000000..7cf4a6ccf452 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownTurnDetection.Serialization.cs @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownTurnDetection : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal UnknownTurnDetection() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(TurnDetection)} does not support writing '{format}' format."); + } + base.JsonModelWriteCore(writer, options); + } + + /// The JSON reader. + /// The client options for reading and writing models. + TurnDetection IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected override TurnDetection JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(TurnDetection)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeTurnDetection(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static UnknownTurnDetection DeserializeUnknownTurnDetection(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + TurnDetectionType @type = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString().ToTurnDetectionType(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new UnknownTurnDetection(@type, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(TurnDetection)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + TurnDetection IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected override TurnDetection PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeTurnDetection(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(TurnDetection)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownTurnDetection.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownTurnDetection.cs new file mode 100644 index 000000000000..56eb1c45ffdf --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/UnknownTurnDetection.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + internal partial class UnknownTurnDetection : TurnDetection + { + /// Initializes a new instance of . + /// + /// Keeps track of any properties unknown to the library. + internal UnknownTurnDetection(TurnDetectionType @type, IDictionary additionalBinaryDataProperties) : base(@type, additionalBinaryDataProperties) + { + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoCrop.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoCrop.Serialization.cs new file mode 100644 index 000000000000..d34c59d951e0 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoCrop.Serialization.cs @@ -0,0 +1,170 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Defines a video crop rectangle using top-left and bottom-right coordinates. + public partial class VideoCrop : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal VideoCrop() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VideoCrop)} does not support writing '{format}' format."); + } + writer.WritePropertyName("top_left"u8); + writer.WriteStartArray(); + foreach (int item in TopLeftInternal) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + writer.WritePropertyName("bottom_right"u8); + writer.WriteStartArray(); + foreach (int item in BottomRightInternal) + { + writer.WriteNumberValue(item); + } + writer.WriteEndArray(); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + VideoCrop IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual VideoCrop JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VideoCrop)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeVideoCrop(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static VideoCrop DeserializeVideoCrop(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + IList topLeftInternal = default; + IList bottomRightInternal = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("top_left"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + topLeftInternal = array; + continue; + } + if (prop.NameEquals("bottom_right"u8)) + { + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(item.GetInt32()); + } + bottomRightInternal = array; + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new VideoCrop(topLeftInternal, bottomRightInternal, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(VideoCrop)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + VideoCrop IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual VideoCrop PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeVideoCrop(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(VideoCrop)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoCrop.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoCrop.cs new file mode 100644 index 000000000000..97ae8a537082 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoCrop.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// Defines a video crop rectangle using top-left and bottom-right coordinates. + public partial class VideoCrop + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// Top-left corner of the crop region. + /// Bottom-right corner of the crop region. + /// or is null. + public VideoCrop(IEnumerable topLeftInternal, IEnumerable bottomRightInternal) + { + Argument.AssertNotNull(topLeftInternal, nameof(topLeftInternal)); + Argument.AssertNotNull(bottomRightInternal, nameof(bottomRightInternal)); + + TopLeftInternal = topLeftInternal.ToList(); + BottomRightInternal = bottomRightInternal.ToList(); + } + + /// Initializes a new instance of . + /// Top-left corner of the crop region. + /// Bottom-right corner of the crop region. + /// Keeps track of any properties unknown to the library. + internal VideoCrop(IList topLeftInternal, IList bottomRightInternal, IDictionary additionalBinaryDataProperties) + { + TopLeftInternal = topLeftInternal; + BottomRightInternal = bottomRightInternal; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoParams.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoParams.Serialization.cs new file mode 100644 index 000000000000..04c87bdb658c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoParams.Serialization.cs @@ -0,0 +1,185 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Video streaming parameters for avatar. + public partial class VideoParams : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VideoParams)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Bitrate)) + { + writer.WritePropertyName("bitrate"u8); + writer.WriteNumberValue(Bitrate.Value); + } + if (Optional.IsDefined(Codec)) + { + writer.WritePropertyName("codec"u8); + writer.WriteStringValue(Codec); + } + if (Optional.IsDefined(Crop)) + { + writer.WritePropertyName("crop"u8); + writer.WriteObjectValue(Crop, options); + } + if (Optional.IsDefined(Resolution)) + { + writer.WritePropertyName("resolution"u8); + writer.WriteObjectValue(Resolution, options); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + VideoParams IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual VideoParams JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VideoParams)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeVideoParams(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static VideoParams DeserializeVideoParams(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int? bitrate = default; + string codec = default; + VideoCrop crop = default; + VideoResolution resolution = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("bitrate"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + bitrate = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("codec"u8)) + { + codec = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("crop"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + crop = VideoCrop.DeserializeVideoCrop(prop.Value, options); + continue; + } + if (prop.NameEquals("resolution"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + resolution = VideoResolution.DeserializeVideoResolution(prop.Value, options); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new VideoParams(bitrate, codec, crop, resolution, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(VideoParams)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + VideoParams IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual VideoParams PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeVideoParams(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(VideoParams)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoParams.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoParams.cs new file mode 100644 index 000000000000..67da7139e6a2 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoParams.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Video streaming parameters for avatar. + public partial class VideoParams + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + public VideoParams() + { + } + + /// Initializes a new instance of . + /// Bitrate in bits per second (e.g., 2000000 for 2 Mbps). + /// Codec to use for encoding. Currently only 'h264' is supported. + /// Optional cropping settings for the video stream. + /// Optional resolution settings for the video stream. + /// Keeps track of any properties unknown to the library. + internal VideoParams(int? bitrate, string codec, VideoCrop crop, VideoResolution resolution, IDictionary additionalBinaryDataProperties) + { + Bitrate = bitrate; + Codec = codec; + Crop = crop; + Resolution = resolution; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Bitrate in bits per second (e.g., 2000000 for 2 Mbps). + public int? Bitrate { get; set; } + + /// Codec to use for encoding. Currently only 'h264' is supported. + public string Codec { get; set; } + + /// Optional cropping settings for the video stream. + public VideoCrop Crop { get; set; } + + /// Optional resolution settings for the video stream. + public VideoResolution Resolution { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoResolution.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoResolution.Serialization.cs new file mode 100644 index 000000000000..a3386dd6ec20 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoResolution.Serialization.cs @@ -0,0 +1,150 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Resolution of the video feed in pixels. + public partial class VideoResolution : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal VideoResolution() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VideoResolution)} does not support writing '{format}' format."); + } + writer.WritePropertyName("width"u8); + writer.WriteNumberValue(Width); + writer.WritePropertyName("height"u8); + writer.WriteNumberValue(Height); + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + VideoResolution IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual VideoResolution JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VideoResolution)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeVideoResolution(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static VideoResolution DeserializeVideoResolution(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + int width = default; + int height = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("width"u8)) + { + width = prop.Value.GetInt32(); + continue; + } + if (prop.NameEquals("height"u8)) + { + height = prop.Value.GetInt32(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new VideoResolution(width, height, additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(VideoResolution)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + VideoResolution IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual VideoResolution PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeVideoResolution(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(VideoResolution)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoResolution.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoResolution.cs new file mode 100644 index 000000000000..f568d12d67dd --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VideoResolution.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Resolution of the video feed in pixels. + public partial class VideoResolution + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// Width of the video in pixels. Must be greater than 0. + /// Height of the video in pixels. Must be greater than 0. + public VideoResolution(int width, int height) + { + Width = width; + Height = height; + } + + /// Initializes a new instance of . + /// Width of the video in pixels. Must be greater than 0. + /// Height of the video in pixels. Must be greater than 0. + /// Keeps track of any properties unknown to the library. + internal VideoResolution(int width, int height, IDictionary additionalBinaryDataProperties) + { + Width = width; + Height = height; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Width of the video in pixels. Must be greater than 0. + public int Width { get; set; } + + /// Height of the video in pixels. Must be greater than 0. + public int Height { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClient.RestClient.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClient.RestClient.cs new file mode 100644 index 000000000000..62758e271966 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClient.RestClient.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using Azure; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// + public partial class VoiceLiveClient + { + private static ResponseClassifier _pipelineMessageClassifier200; + + private static ResponseClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 = new StatusCodeClassifier(stackalloc ushort[] { 200 }); + + internal HttpMessage CreateForceModelsRequest(string accept, RequestContent content, RequestContext context) + { + HttpMessage message = Pipeline.CreateMessage(context, PipelineMessageClassifier200); + Request request = message.Request; + request.Method = RequestMethod.Post; + RawRequestUriBuilder uri = new RawRequestUriBuilder(); + uri.Reset(_endpoint); + uri.AppendPath("/voice-agent/realtime", false); + uri.AppendPath("/", false); + request.Uri = uri; + request.Headers.SetValue("Content-Type", "application/json"); + request.Headers.SetValue("Accept", accept); + request.Content = content; + return message; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClient.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClient.cs new file mode 100644 index 000000000000..23954e0255c5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClient.cs @@ -0,0 +1,137 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ + /// The VoiceLiveClient. + public partial class VoiceLiveClient + { + private readonly Uri _endpoint; + /// A credential used to authenticate to the service. + private readonly AzureKeyCredential _keyCredential; + private const string AuthorizationHeader = "api-key"; + /// A credential used to authenticate to the service. + private readonly TokenCredential _tokenCredential; + private static readonly string[] AuthorizationScopes = new string[] { "https://cognitiveservices.azure.com/.default" }; + + /// Initializes a new instance of VoiceLiveClient for mocking. + protected VoiceLiveClient() + { + } + + /// Initializes a new instance of VoiceLiveClient. + /// Service endpoint. + /// A credential used to authenticate to the service. + /// or is null. + public VoiceLiveClient(Uri endpoint, AzureKeyCredential credential) : this(endpoint, credential, new VoiceLiveClientOptions()) + { + } + + /// Initializes a new instance of VoiceLiveClient. + /// Service endpoint. + /// A credential used to authenticate to the service. + /// or is null. + public VoiceLiveClient(Uri endpoint, TokenCredential credential) : this(endpoint, credential, new VoiceLiveClientOptions()) + { + } + + /// The HTTP pipeline for sending and receiving REST requests and responses. + public virtual HttpPipeline Pipeline { get; } + + /// The ClientDiagnostics is used to provide tracing support for the client library. + internal ClientDiagnostics ClientDiagnostics { get; } + + /// + /// [Protocol Method] ForceModels + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + internal virtual Response ForceModels(string accept, RequestContent content, RequestContext context = null) + { + using DiagnosticScope scope = ClientDiagnostics.CreateScope("VoiceLiveClient.ForceModels"); + scope.Start(); + try + { + using HttpMessage message = CreateForceModelsRequest(accept, content, context); + return Pipeline.ProcessMessage(message, context); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// + /// [Protocol Method] ForceModels + /// + /// + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// + /// + /// + /// + /// The content to send as the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. + /// Service returned a non-success status code. + /// The response returned from the service. + internal virtual async Task ForceModelsAsync(string accept, RequestContent content, RequestContext context = null) + { + using DiagnosticScope scope = ClientDiagnostics.CreateScope("VoiceLiveClient.ForceModels"); + scope.Start(); + try + { + using HttpMessage message = CreateForceModelsRequest(accept, content, context); + return await Pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false); + } + catch (Exception e) + { + scope.Failed(e); + throw; + } + } + + /// ForceModels. + /// + /// + /// The cancellation token that can be used to cancel the operation. + /// Service returned a non-success status code. + internal virtual Response ForceModels(string accept, BinaryData @event, CancellationToken cancellationToken = default) + { + ForceModelsRequest spreadModel = new ForceModelsRequest(@event, null); + Response result = ForceModels(accept, spreadModel, cancellationToken.CanBeCanceled ? new RequestContext { CancellationToken = cancellationToken } : null); + return Response.FromValue((ServerEventResponseAnimationVisemeDone)result, result); + } + + /// ForceModels. + /// + /// + /// The cancellation token that can be used to cancel the operation. + /// Service returned a non-success status code. + internal virtual async Task> ForceModelsAsync(string accept, BinaryData @event, CancellationToken cancellationToken = default) + { + ForceModelsRequest spreadModel = new ForceModelsRequest(@event, null); + Response result = await ForceModelsAsync(accept, spreadModel, cancellationToken.CanBeCanceled ? new RequestContext { CancellationToken = cancellationToken } : null).ConfigureAwait(false); + return Response.FromValue((ServerEventResponseAnimationVisemeDone)result, result); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClientBuilderExtensions.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClientBuilderExtensions.cs new file mode 100644 index 000000000000..ba91ded31add --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClientBuilderExtensions.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System.Diagnostics.CodeAnalysis; +using Azure.AI.VoiceLive; +using Azure.Core.Extensions; + +namespace Microsoft.Extensions.Azure +{ + /// Extension methods to add clients to . + public static partial class VoiceLiveClientBuilderExtensions + { + /// Registers a client with the specified . + /// The builder to register with. + /// The configuration to use for the client. + [RequiresUnreferencedCode("Requires unreferenced code until we opt into EnableConfigurationBindingGenerator.")] + [RequiresDynamicCode("Requires unreferenced code until we opt into EnableConfigurationBindingGenerator.")] + public static IAzureClientBuilder AddVoiceLiveClient(this TBuilder builder, TConfiguration configuration) + where TBuilder : IAzureClientFactoryBuilderWithConfiguration + { + return builder.RegisterClientFactory(configuration); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClientOptions.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClientOptions.cs new file mode 100644 index 000000000000..38535b99f477 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveClientOptions.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// Client options for . + public partial class VoiceLiveClientOptions : ClientOptions + { + private const ServiceVersion LatestVersion = ServiceVersion.V2025_05_01_Preview; + + /// Initializes a new instance of VoiceLiveClientOptions. + /// The service version. + public VoiceLiveClientOptions(ServiceVersion version = LatestVersion) + { + Version = version switch + { + ServiceVersion.V2025_05_01_Preview => "2025-05-01-preview", + _ => throw new NotSupportedException() + }; + } + + /// Gets the Version. + internal string Version { get; } + + /// The version of the service to use. + public enum ServiceVersion + { + /// V2025_05_01_Preview. + V2025_05_01_Preview = 1 + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveErrorDetails.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveErrorDetails.Serialization.cs new file mode 100644 index 000000000000..1c33bb7890ab --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveErrorDetails.Serialization.cs @@ -0,0 +1,192 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// Error object returned in case of API failure. + public partial class VoiceLiveErrorDetails : IJsonModel + { + /// Initializes a new instance of for deserialization. + internal VoiceLiveErrorDetails() + { + } + + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VoiceLiveErrorDetails)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Code)) + { + writer.WritePropertyName("code"u8); + writer.WriteStringValue(Code); + } + writer.WritePropertyName("message"u8); + writer.WriteStringValue(Message); + if (Optional.IsDefined(Param)) + { + writer.WritePropertyName("param"u8); + writer.WriteStringValue(Param); + } + if (Optional.IsDefined(Type)) + { + writer.WritePropertyName("type"u8); + writer.WriteStringValue(Type); + } + if (Optional.IsDefined(EventId)) + { + writer.WritePropertyName("event_id"u8); + writer.WriteStringValue(EventId); + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + VoiceLiveErrorDetails IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual VoiceLiveErrorDetails JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VoiceLiveErrorDetails)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeVoiceLiveErrorDetails(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static VoiceLiveErrorDetails DeserializeVoiceLiveErrorDetails(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string code = default; + string message = default; + string @param = default; + string @type = default; + string eventId = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("code"u8)) + { + code = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("message"u8)) + { + message = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("param"u8)) + { + @param = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("type"u8)) + { + @type = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("event_id"u8)) + { + eventId = prop.Value.GetString(); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new VoiceLiveErrorDetails( + code, + message, + @param, + @type, + eventId, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(VoiceLiveErrorDetails)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + VoiceLiveErrorDetails IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual VoiceLiveErrorDetails PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeVoiceLiveErrorDetails(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(VoiceLiveErrorDetails)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveErrorDetails.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveErrorDetails.cs new file mode 100644 index 000000000000..d1da486c30b4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveErrorDetails.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// Error object returned in case of API failure. + public partial class VoiceLiveErrorDetails + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + /// Human-readable error message. + internal VoiceLiveErrorDetails(string message) + { + Message = message; + } + + /// Initializes a new instance of . + /// Error code, or null if unspecified. + /// Human-readable error message. + /// Parameter name related to the error, if applicable. + /// Type or category of the error. + /// Event id of the error. + /// Keeps track of any properties unknown to the library. + internal VoiceLiveErrorDetails(string code, string message, string @param, string @type, string eventId, IDictionary additionalBinaryDataProperties) + { + Code = code; + Message = message; + Param = @param; + Type = @type; + EventId = eventId; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// Error code, or null if unspecified. + public string Code { get; } + + /// Human-readable error message. + public string Message { get; } + + /// Parameter name related to the error, if applicable. + public string Param { get; } + + /// Type or category of the error. + public string Type { get; } + + /// Event id of the error. + public string EventId { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveModelFactory.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveModelFactory.cs new file mode 100644 index 000000000000..9b923b1a7eb7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveModelFactory.cs @@ -0,0 +1,1494 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// A factory class for creating instances of the models for mocking. + public static partial class VoiceLiveModelFactory + { + /// The RequestSession. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static RequestSession RequestSession(string model = default, IEnumerable modalities = default, AnimationOptions animation = default, string instructions = default, InputAudio inputAudio = default, int? inputAudioSamplingRate = default, AudioFormat? inputAudioFormat = default, AudioFormat? outputAudioFormat = default, TurnDetection turnDetection = default, AudioNoiseReduction inputAudioNoiseReduction = default, AudioEchoCancellation inputAudioEchoCancellation = default, AvatarConfig avatar = default, AudioInputTranscriptionSettings inputAudioTranscription = default, IEnumerable outputAudioTimestampTypes = default, IEnumerable tools = default, float? temperature = default, BinaryData servcieVoice = default, BinaryData maxResponseOutputTokens = default, BinaryData toolChoice = default) + { + modalities ??= new ChangeTrackingList(); + outputAudioTimestampTypes ??= new ChangeTrackingList(); + tools ??= new ChangeTrackingList(); + + return new RequestSession( + model, + modalities.ToList(), + animation, + instructions, + inputAudio, + inputAudioSamplingRate, + inputAudioFormat, + outputAudioFormat, + turnDetection, + inputAudioNoiseReduction, + inputAudioEchoCancellation, + avatar, + inputAudioTranscription, + outputAudioTimestampTypes.ToList(), + tools.ToList(), + temperature, + servcieVoice, + maxResponseOutputTokens, + toolChoice, + additionalBinaryDataProperties: null); + } + + /// Configuration for animation outputs including blendshapes, visemes, and emotion metadata. + /// The name of the animation model to use. + /// Set of output data types requested from the animation system. + /// Interval for emotion detection in milliseconds. If not set, emotion detection is disabled. + /// A new instance for mocking. + public static AnimationOptions AnimationOptions(string modelName = default, IEnumerable outputs = default, int? emotionDetectionIntervalMs = default) + { + outputs ??= new ChangeTrackingList(); + + return new AnimationOptions(modelName, outputs.ToList(), emotionDetectionIntervalMs, additionalBinaryDataProperties: null); + } + + /// Voice configuration for Azure standard or platform voices. + /// Name of the voice. + /// Voice type identifier. + /// Optional temperature for generation. + /// A new instance for mocking. + public static AzureStandardVoice AzureStandardVoice(string name = default, AzureStandardVoiceType @type = default, float? temperature = default) + { + return new AzureStandardVoice(name, @type, temperature, additionalBinaryDataProperties: null); + } + + /// Voice configuration for Azure custom voice. + /// Name of the voice. + /// Custom endpoint ID. + /// Voice type identifier. + /// Optional temperature for generation. + /// Optional custom lexicon URL. + /// Preferred locale list for voice rendering. + /// A new instance for mocking. + public static AzureCustomVoice AzureCustomVoice(string name = default, string endpointId = default, AzureCustomVoiceType @type = default, float? temperature = default, Uri customLexiconUri = default, IEnumerable preferLocales = default) + { + preferLocales ??= new ChangeTrackingList(); + + return new AzureCustomVoice( + name, + endpointId, + @type, + temperature, + customLexiconUri, + preferLocales.ToList(), + additionalBinaryDataProperties: null); + } + + /// Voice configuration for Azure personal voice. + /// Name of the voice. + /// Voice type identifier. + /// Personal voice model identifier. + /// A new instance for mocking. + public static AzurePersonalVoice AzurePersonalVoice(string name = default, AzurePersonalVoiceType @type = default, AzurePersonalVoiceModel model = default) + { + return new AzurePersonalVoice(name, @type, model, additionalBinaryDataProperties: null); + } + + /// Configuration for client audio input. Used to specify the audio model and optional phrase list. + /// The name of the model to use for input audio (currently only 'azure-standard' is supported). + /// Optional list of phrases to bias the speech recognition engine. + /// A new instance for mocking. + public static InputAudio InputAudio(string model = default, IEnumerable phraseList = default) + { + phraseList ??= new ChangeTrackingList(); + + return new InputAudio(model, phraseList.ToList(), additionalBinaryDataProperties: null); + } + + /// + /// Top-level union for turn detection configuration. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + /// + /// A new instance for mocking. + public static TurnDetection TurnDetection(string @type = default) + { + return new UnknownTurnDetection(@type.ToTurnDetectionType(), additionalBinaryDataProperties: null); + } + + /// Disables turn detection. + /// A new instance for mocking. + public static NoTurnDetection NoTurnDetection() + { + return new NoTurnDetection(TurnDetectionType.None, additionalBinaryDataProperties: null); + } + + /// Base model for VAD-based turn detection. + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerVad ServerVad(float? threshold = default, int? prefixPaddingMs = default, int? silenceDurationMs = default, BinaryData endOfUtteranceDetection = default) + { + return new ServerVad( + TurnDetectionType.ServerVad, + additionalBinaryDataProperties: null, + threshold, + prefixPaddingMs, + silenceDurationMs, + endOfUtteranceDetection); + } + + /// Semantic VAD settings based on Azure SDK features. + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static AzureSemanticVad AzureSemanticVad(float? negThreshold = default, int? windowSize = default, int? distinctCiPhones = default, bool? requireVowel = default, bool? removeFillerWords = default) + { + return new AzureSemanticVad( + TurnDetectionType.AzureSemanticVad, + additionalBinaryDataProperties: null, + negThreshold, + windowSize, + distinctCiPhones, + requireVowel, + removeFillerWords); + } + + /// Configuration for input audio noise reduction. + /// The type of noise reduction model. + /// A new instance for mocking. + public static AudioNoiseReduction AudioNoiseReduction(string @type = default) + { + return new AudioNoiseReduction(@type, additionalBinaryDataProperties: null); + } + + /// Echo cancellation configuration for server-side audio processing. + /// The type of echo cancellation model to use. + /// A new instance for mocking. + public static AudioEchoCancellation AudioEchoCancellation(string @type = default) + { + return new AudioEchoCancellation(@type, additionalBinaryDataProperties: null); + } + + /// Configuration for avatar streaming and behavior during the session. + /// Optional list of ICE servers to use for WebRTC connection establishment. + /// The character name or ID used for the avatar. + /// Optional avatar style, such as emotional tone or speaking style. + /// Indicates whether the avatar is customized or not. + /// Optional video configuration including resolution, bitrate, and codec. + /// A new instance for mocking. + public static AvatarConfig AvatarConfig(IEnumerable iceServers = default, string character = default, string style = default, bool customized = default, VideoParams video = default) + { + iceServers ??= new ChangeTrackingList(); + + return new AvatarConfig( + iceServers.ToList(), + character, + style, + customized, + video, + additionalBinaryDataProperties: null); + } + + /// ICE server configuration for WebRTC connection negotiation. + /// List of ICE server URLs (e.g., TURN or STUN endpoints). + /// Optional username used for authentication with the ICE server. + /// Optional credential (e.g., password or token) used for authentication. + /// A new instance for mocking. + public static IceServer IceServer(IEnumerable uris = default, string username = default, string credential = default) + { + uris ??= new ChangeTrackingList(); + + return new IceServer(uris.ToList(), username, credential, additionalBinaryDataProperties: null); + } + + /// Video streaming parameters for avatar. + /// Bitrate in bits per second (e.g., 2000000 for 2 Mbps). + /// Codec to use for encoding. Currently only 'h264' is supported. + /// Optional cropping settings for the video stream. + /// Optional resolution settings for the video stream. + /// A new instance for mocking. + public static VideoParams VideoParams(int? bitrate = default, string codec = default, VideoCrop crop = default, VideoResolution resolution = default) + { + return new VideoParams(bitrate, codec, crop, resolution, additionalBinaryDataProperties: null); + } + + /// Defines a video crop rectangle using top-left and bottom-right coordinates. + /// Top-left corner of the crop region. + /// Bottom-right corner of the crop region. + /// A new instance for mocking. + public static VideoCrop VideoCrop(IEnumerable topLeftInternal = default, IEnumerable bottomRightInternal = default) + { + topLeftInternal ??= new ChangeTrackingList(); + bottomRightInternal ??= new ChangeTrackingList(); + + return new VideoCrop(topLeftInternal.ToList(), bottomRightInternal.ToList(), additionalBinaryDataProperties: null); + } + + /// Resolution of the video feed in pixels. + /// Width of the video in pixels. Must be greater than 0. + /// Height of the video in pixels. Must be greater than 0. + /// A new instance for mocking. + public static VideoResolution VideoResolution(int width = default, int height = default) + { + return new VideoResolution(width, height, additionalBinaryDataProperties: null); + } + + /// Configuration for input audio transcription. + /// The model used for transcription. E.g., 'whisper-1', 'azure-fast-transcription', 's2s-ingraph'. + /// The language code to use for transcription, if specified. + /// Whether transcription is enabled. + /// Whether a custom model is being used. + /// A new instance for mocking. + public static AudioInputTranscriptionSettings AudioInputTranscriptionSettings(AudioInputTranscriptionSettingsModel model = default, string language = default, bool enabled = default, bool customModel = default) + { + return new AudioInputTranscriptionSettings(model, language, enabled, customModel, additionalBinaryDataProperties: null); + } + + /// + /// The base representation of a voicelive tool definition. + /// Please note this is the abstract base class. The derived classes available for instantiation are: . + /// + /// + /// A new instance for mocking. + public static ToolCall ToolCall(string @type = default) + { + return new UnknownToolCall(new ToolType(@type), additionalBinaryDataProperties: null); + } + + /// The definition of a function tool as used by the voicelive endpoint. + /// + /// + /// + /// A new instance for mocking. + public static FunctionTool FunctionTool(string name = default, string description = default, BinaryData parameters = default) + { + return new FunctionTool(ToolType.Function, additionalBinaryDataProperties: null, name, description, parameters); + } + + /// + /// A base representation for a voicelive tool_choice selecting a named tool. + /// Please note this is the abstract base class. The derived classes available for instantiation are: . + /// + /// + /// A new instance for mocking. + public static ToolChoiceObject ToolChoiceObject(string @type = default) + { + return new UnknownToolChoiceObject(new ToolType(@type), additionalBinaryDataProperties: null); + } + + /// The representation of a voicelive tool_choice selecting a named function tool. + /// + /// A new instance for mocking. + public static ToolChoiceFunctionObject ToolChoiceFunctionObject(ToolChoiceFunctionObjectFunction function = default) + { + return new ToolChoiceFunctionObject(ToolType.Function, additionalBinaryDataProperties: null, function); + } + + /// The ToolChoiceFunctionObjectFunction. + /// + /// A new instance for mocking. + public static ToolChoiceFunctionObjectFunction ToolChoiceFunctionObjectFunction(string name = default) + { + return new ToolChoiceFunctionObjectFunction(name, additionalBinaryDataProperties: null); + } + + /// The item to add to the conversation. + /// + /// For an item of type (`message` | `function_call` | `function_call_output`) + /// this field allows the client to assign the unique ID of the item. It is + /// not required because the server will generate one if not provided. + /// + /// For an item of type `item_reference`, this field is required and is a + /// reference to any item that has previously existed in the conversation. + /// + /// The type of the item (`message`, `function_call`, `function_call_output`, `item_reference`). + /// Identifier for the API object being returned - always `realtime.item`. + /// + /// The status of the item (`completed`, `incomplete`). These have no effect + /// on the conversation, but are accepted for consistency with the + /// `conversation.item.created` event. + /// + /// + /// The role of the message sender (`user`, `assistant`, `system`), only + /// applicable for `message` items. + /// + /// + /// The content of the message, applicable for `message` items. + /// - Message items of role `system` support only `input_text` content + /// - Message items of role `user` support `input_text` and `input_audio` + /// content + /// - Message items of role `assistant` support `text` content. + /// + /// + /// The ID of the function call (for `function_call` and + /// `function_call_output` items). If passed on a `function_call_output` + /// item, the server will check that a `function_call` item with the same + /// ID exists in the conversation history. + /// + /// The name of the function being called (for `function_call` items). + /// The arguments of the function call (for `function_call` items). + /// The output of the function call (for `function_call_output` items). + /// A new instance for mocking. + public static ConversationItemWithReference ConversationItemWithReference(string id = default, ConversationItemWithReferenceType? @type = default, string @object = default, ConversationItemWithReferenceStatus? status = default, ConversationItemWithReferenceRole? role = default, IEnumerable content = default, string callId = default, string name = default, string arguments = default, string output = default) + { + content ??= new ChangeTrackingList(); + + return new ConversationItemWithReference( + id, + @type, + @object, + status, + role, + content.ToList(), + callId, + name, + arguments, + output, + additionalBinaryDataProperties: null); + } + + /// The ConversationItemWithReferenceContent. + /// The content type (`input_text`, `input_audio`, `item_reference`, `text`). + /// The text content, used for `input_text` and `text` content types. + /// + /// ID of a previous conversation item to reference (for `item_reference` + /// content types in `response.create` events). These can reference both + /// client and server created items. + /// + /// Base64-encoded audio bytes, used for `input_audio` content type. + /// The transcript of the audio, used for `input_audio` content type. + /// A new instance for mocking. + public static ConversationItemWithReferenceContent ConversationItemWithReferenceContent(ConversationItemWithReferenceContentType? @type = default, string text = default, string id = default, string audio = default, string transcript = default) + { + return new ConversationItemWithReferenceContent( + @type, + text, + id, + audio, + transcript, + additionalBinaryDataProperties: null); + } + + /// The RequestTextContentPart. + /// + /// A new instance for mocking. + public static RequestTextContentPart RequestTextContentPart(string text = default) + { + return new RequestTextContentPart(ContentPartType.InputText, additionalBinaryDataProperties: null, text); + } + + /// + /// The ContentPart. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , , and . + /// + /// + /// A new instance for mocking. + public static ContentPart ContentPart(string @type = default) + { + return new UnknownContentPart(new ContentPartType(@type), additionalBinaryDataProperties: null); + } + + /// The RequestAudioContentPart. + /// + /// A new instance for mocking. + public static RequestAudioContentPart RequestAudioContentPart(string transcript = default) + { + return new RequestAudioContentPart(ContentPartType.InputAudio, additionalBinaryDataProperties: null, transcript); + } + + /// The ResponseTextContentPart. + /// + /// A new instance for mocking. + public static ResponseTextContentPart ResponseTextContentPart(string text = default) + { + return new ResponseTextContentPart(ContentPartType.Text, additionalBinaryDataProperties: null, text); + } + + /// The ResponseAudioContentPart. + /// + /// A new instance for mocking. + public static ResponseAudioContentPart ResponseAudioContentPart(string transcript = default) + { + return new ResponseAudioContentPart(ContentPartType.Audio, additionalBinaryDataProperties: null, transcript); + } + + /// Sent when the server is in the process of establishing an avatar media connection and provides its SDP answer. + /// + /// The server's SDP answer for the avatar connection. + /// A new instance for mocking. + public static ServerEventSessionAvatarConnecting ServerEventSessionAvatarConnecting(string eventId = default, string serverSdp = default) + { + return new ServerEventSessionAvatarConnecting(ServerEventType.SessionAvatarConnecting, eventId, additionalBinaryDataProperties: null, serverSdp); + } + + /// + /// A voicelive server event. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and . + /// + /// The type of event. + /// + /// A new instance for mocking. + public static ServerEvent ServerEvent(string @type = default, string eventId = default) + { + return new UnknownServerEvent(new ServerEventType(@type), eventId, additionalBinaryDataProperties: null); + } + + /// + /// Returned when a Session is created. Emitted automatically when a new + /// connection is established as the first server event. This event will contain + /// the default Session configuration. + /// + /// + /// + /// A new instance for mocking. + public static ServerEventSessionCreated ServerEventSessionCreated(string eventId = default, ResponseSession session = default) + { + return new ServerEventSessionCreated(ServerEventType.SessionCreated, eventId, additionalBinaryDataProperties: null, session); + } + + /// The ResponseSession. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ResponseSession ResponseSession(string id = default, string model = default, IEnumerable modalities = default, string instructions = default, AnimationOptions animation = default, BinaryData voice = default, InputAudio inputAudio = default, AudioFormat? inputAudioFormat = default, AudioFormat? outputAudioFormat = default, int? inputAudioSamplingRate = default, TurnDetection turnDetection = default, AudioNoiseReduction inputAudioNoiseReduction = default, AudioEchoCancellation inputAudioEchoCancellation = default, AvatarConfig avatar = default, AudioInputTranscriptionSettings inputAudioTranscription = default, IEnumerable outputAudioTimestampTypes = default, IEnumerable tools = default, BinaryData toolChoice = default, float? temperature = default, BinaryData maxResponseOutputTokens = default, RespondingAgentConfig agent = default) + { + modalities ??= new ChangeTrackingList(); + outputAudioTimestampTypes ??= new ChangeTrackingList(); + tools ??= new ChangeTrackingList(); + + return new ResponseSession( + id, + model, + modalities.ToList(), + instructions, + animation, + voice, + inputAudio, + inputAudioFormat, + outputAudioFormat, + inputAudioSamplingRate, + turnDetection, + inputAudioNoiseReduction, + inputAudioEchoCancellation, + avatar, + inputAudioTranscription, + outputAudioTimestampTypes.ToList(), + tools.ToList(), + toolChoice, + temperature, + maxResponseOutputTokens, + agent, + additionalBinaryDataProperties: null); + } + + /// The RespondingAgentConfig. + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static RespondingAgentConfig RespondingAgentConfig(string @type = default, string name = default, string description = default, string agentId = default, string threadId = default) + { + return new RespondingAgentConfig( + @type, + name, + description, + agentId, + threadId, + additionalBinaryDataProperties: null); + } + + /// + /// Returned when a session is updated with a `session.update` event, unless + /// there is an error. + /// + /// + /// + /// A new instance for mocking. + public static ServerEventSessionUpdated ServerEventSessionUpdated(string eventId = default, ResponseSession session = default) + { + return new ServerEventSessionUpdated(ServerEventType.SessionUpdated, eventId, additionalBinaryDataProperties: null, session); + } + + /// + /// Returned when an error occurs, which could be a client problem or a server + /// problem. Most errors are recoverable and the session will stay open, we + /// recommend to implementors to monitor and log error messages by default. + /// + /// + /// Details of the error. + /// A new instance for mocking. + public static ServerEventError ServerEventError(string eventId = default, ServerEventErrorError error = default) + { + return new ServerEventError(ServerEventType.Error, eventId, additionalBinaryDataProperties: null, error); + } + + /// The ServerEventErrorError. + /// The type of error (e.g., "invalid_request_error", "server_error"). + /// Error code, if any. + /// A human-readable error message. + /// Parameter related to the error, if any. + /// The event_id of the client event that caused the error, if applicable. + /// A new instance for mocking. + public static ServerEventErrorError ServerEventErrorError(string @type = default, string code = default, string message = default, string @param = default, string eventId = default) + { + return new ServerEventErrorError( + @type, + code, + message, + @param, + eventId, + additionalBinaryDataProperties: null); + } + + /// Returned when the text value of a "text" content part is updated. + /// + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The text delta. + /// A new instance for mocking. + public static ServerEventResponseTextDelta ServerEventResponseTextDelta(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, string delta = default) + { + return new ServerEventResponseTextDelta( + ServerEventType.ResponseTextDelta, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + delta); + } + + /// Returned when the model-generated audio is updated. + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// Base64-encoded audio data delta. + /// + /// A new instance for mocking. + public static ServerEventResponseAudioDelta ServerEventResponseAudioDelta(string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, BinaryData delta = default, string eventId = default) + { + return new ServerEventResponseAudioDelta( + ServerEventType.ResponseAudioDelta, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + delta, + eventId); + } + + /// + /// Returned when a conversation item is created. There are several scenarios that produce this event: + /// - The server is generating a Response, which if successful will produce + /// either one or two Items, which will be of type `message` + /// (role `assistant`) or type `function_call`. + /// - The input audio buffer has been committed, either by the client or the + /// server (in `server_vad` mode). The server will take the content of the + /// input audio buffer and add it to a new user message Item. + /// - The client has sent a `conversation.item.create` event to add a new Item + /// to the Conversation. + /// + /// + /// + /// The ID of the preceding item in the Conversation context, allows the + /// client to understand the order of the conversation. + /// + /// + /// A new instance for mocking. + public static ServerEventConversationItemCreated ServerEventConversationItemCreated(string eventId = default, string previousItemId = default, ConversationItemWithReference item = default) + { + return new ServerEventConversationItemCreated(ServerEventType.ConversationItemCreated, eventId, additionalBinaryDataProperties: null, previousItemId, item); + } + + /// + /// Returned when an item in the conversation is deleted by the client with a + /// `conversation.item.delete` event. This event is used to synchronize the + /// server's understanding of the conversation history with the client's view. + /// + /// The ID of the item that was deleted. + /// + /// A new instance for mocking. + public static ServerEventConversationItemDeleted ServerEventConversationItemDeleted(string itemId = default, string eventId = default) + { + return new ServerEventConversationItemDeleted(ServerEventType.ConversationItemDeleted, additionalBinaryDataProperties: null, itemId, eventId); + } + + /// Returned when a conversation item is retrieved with `conversation.item.retrieve`. + /// + /// + /// A new instance for mocking. + public static ServerEventConversationItemRetrieved ServerEventConversationItemRetrieved(string itemId = default, string eventId = default) + { + return new ServerEventConversationItemRetrieved(ServerEventType.ConversationItemRetrieved, additionalBinaryDataProperties: null, itemId, eventId); + } + + /// + /// Returned when an earlier assistant audio message item is truncated by the + /// client with a `conversation.item.truncate` event. This event is used to + /// synchronize the server's understanding of the audio with the client's playback. + /// + /// This action will truncate the audio and remove the server-side text transcript + /// to ensure there is no text in the context that hasn't been heard by the user. + /// + /// The ID of the assistant message item that was truncated. + /// The index of the content part that was truncated. + /// The duration up to which the audio was truncated, in milliseconds. + /// + /// A new instance for mocking. + public static ServerEventConversationItemTruncated ServerEventConversationItemTruncated(string itemId = default, int contentIndex = default, int audioEndMs = default, string eventId = default) + { + return new ServerEventConversationItemTruncated( + ServerEventType.ConversationItemTruncated, + additionalBinaryDataProperties: null, + itemId, + contentIndex, + audioEndMs, + eventId); + } + + /// + /// This event is the output of audio transcription for user audio written to the + /// user audio buffer. Transcription begins when the input audio buffer is + /// committed by the client or server (in `server_vad` mode). Transcription runs + /// asynchronously with Response creation, so this event may come before or after + /// the Response events. + /// + /// VoiceLive API models accept audio natively, and thus input transcription is a + /// separate process run on a separate ASR (Automatic Speech Recognition) model. + /// The transcript may diverge somewhat from the model's interpretation, and + /// should be treated as a rough guide. + /// + /// + /// The ID of the user message item containing the audio. + /// The index of the content part containing the audio. + /// The transcribed text. + /// A new instance for mocking. + public static ServerEventConversationItemInputAudioTranscriptionCompleted ServerEventConversationItemInputAudioTranscriptionCompleted(string eventId = default, string itemId = default, int contentIndex = default, string transcript = default) + { + return new ServerEventConversationItemInputAudioTranscriptionCompleted( + ServerEventType.ConversationItemInputAudioTranscriptionCompleted, + eventId, + additionalBinaryDataProperties: null, + itemId, + contentIndex, + transcript); + } + + /// Returned when the text value of an input audio transcription content part is updated. + /// + /// The ID of the item. + /// The index of the content part in the item's content array. + /// The text delta. + /// The log probabilities of the transcription. + /// A new instance for mocking. + public static ServerEventConversationItemInputAudioTranscriptionDelta ServerEventConversationItemInputAudioTranscriptionDelta(string eventId = default, string itemId = default, int? contentIndex = default, string delta = default, IEnumerable logprobs = default) + { + logprobs ??= new ChangeTrackingList(); + + return new ServerEventConversationItemInputAudioTranscriptionDelta( + ServerEventType.ConversationItemInputAudioTranscriptionDelta, + eventId, + additionalBinaryDataProperties: null, + itemId, + contentIndex, + delta, + logprobs.ToList()); + } + + /// A single log probability entry for a token. + /// The token that was used to generate the log probability. + /// The log probability of the token. + /// The bytes that were used to generate the log probability. + /// A new instance for mocking. + public static LogProbProperties LogProbProperties(string token = default, float logprob = default, IEnumerable bytes = default) + { + bytes ??= new ChangeTrackingList(); + + return new LogProbProperties(token, logprob, bytes.ToList(), additionalBinaryDataProperties: null); + } + + /// + /// Returned when input audio transcription is configured, and a transcription + /// request for a user message failed. These events are separate from other + /// `error` events so that the client can identify the related Item. + /// + /// + /// The ID of the user message item. + /// The index of the content part containing the audio. + /// Details of the transcription error. + /// A new instance for mocking. + public static ServerEventConversationItemInputAudioTranscriptionFailed ServerEventConversationItemInputAudioTranscriptionFailed(string eventId = default, string itemId = default, int contentIndex = default, VoiceLiveErrorDetails error = default) + { + return new ServerEventConversationItemInputAudioTranscriptionFailed( + ServerEventType.ConversationItemInputAudioTranscriptionFailed, + eventId, + additionalBinaryDataProperties: null, + itemId, + contentIndex, + error); + } + + /// Error object returned in case of API failure. + /// Error code, or null if unspecified. + /// Human-readable error message. + /// Parameter name related to the error, if applicable. + /// Type or category of the error. + /// Event id of the error. + /// A new instance for mocking. + public static VoiceLiveErrorDetails VoiceLiveErrorDetails(string code = default, string message = default, string @param = default, string @type = default, string eventId = default) + { + return new VoiceLiveErrorDetails( + code, + message, + @param, + @type, + eventId, + additionalBinaryDataProperties: null); + } + + /// + /// Returned when an input audio buffer is committed, either by the client or + /// automatically in server VAD mode. The `item_id` property is the ID of the user + /// message item that will be created, thus a `conversation.item.created` event + /// will also be sent to the client. + /// + /// + /// The ID of the preceding item after which the new item will be inserted. + /// The ID of the user message item that will be created. + /// A new instance for mocking. + public static ServerEventInputAudioBufferCommitted ServerEventInputAudioBufferCommitted(string eventId = default, string previousItemId = default, string itemId = default) + { + return new ServerEventInputAudioBufferCommitted(ServerEventType.InputAudioBufferCommitted, eventId, additionalBinaryDataProperties: null, previousItemId, itemId); + } + + /// + /// Returned when the input audio buffer is cleared by the client with a + /// `input_audio_buffer.clear` event. + /// + /// + /// A new instance for mocking. + public static ServerEventInputAudioBufferCleared ServerEventInputAudioBufferCleared(string eventId = default) + { + return new ServerEventInputAudioBufferCleared(ServerEventType.InputAudioBufferCleared, eventId, additionalBinaryDataProperties: null); + } + + /// + /// Sent by the server when in `server_vad` mode to indicate that speech has been + /// detected in the audio buffer. This can happen any time audio is added to the + /// buffer (unless speech is already detected). The client may want to use this + /// event to interrupt audio playback or provide visual feedback to the user. + /// + /// The client should expect to receive a `input_audio_buffer.speech_stopped` event + /// when speech stops. The `item_id` property is the ID of the user message item + /// that will be created when speech stops and will also be included in the + /// `input_audio_buffer.speech_stopped` event (unless the client manually commits + /// the audio buffer during VAD activation). + /// + /// + /// + /// Milliseconds from the start of all audio written to the buffer during the + /// session when speech was first detected. This will correspond to the + /// beginning of audio sent to the model, and thus includes the + /// `prefix_padding_ms` configured in the Session. + /// + /// The ID of the user message item that will be created when speech stops. + /// A new instance for mocking. + public static ServerEventInputAudioBufferSpeechStarted ServerEventInputAudioBufferSpeechStarted(string eventId = default, int audioStartMs = default, string itemId = default) + { + return new ServerEventInputAudioBufferSpeechStarted(ServerEventType.InputAudioBufferSpeechStarted, eventId, additionalBinaryDataProperties: null, audioStartMs, itemId); + } + + /// + /// Returned in `server_vad` mode when the server detects the end of speech in + /// the audio buffer. The server will also send an `conversation.item.created` + /// event with the user message item that is created from the audio buffer. + /// + /// + /// + /// Milliseconds since the session started when speech stopped. This will + /// correspond to the end of audio sent to the model, and thus includes the + /// `min_silence_duration_ms` configured in the Session. + /// + /// The ID of the user message item that will be created. + /// A new instance for mocking. + public static ServerEventInputAudioBufferSpeechStopped ServerEventInputAudioBufferSpeechStopped(string eventId = default, int audioEndMs = default, string itemId = default) + { + return new ServerEventInputAudioBufferSpeechStopped(ServerEventType.InputAudioBufferSpeechStopped, eventId, additionalBinaryDataProperties: null, audioEndMs, itemId); + } + + /// + /// Returned when a new Response is created. The first event of response creation, + /// where the response is in an initial state of `in_progress`. + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseCreated ServerEventResponseCreated(string eventId = default, VoiceLiveResponse response = default) + { + return new ServerEventResponseCreated(ServerEventType.ResponseCreated, eventId, additionalBinaryDataProperties: null, response); + } + + /// The response resource. + /// The unique ID of the response. + /// The object type, must be `realtime.response`. + /// + /// The final status of the response (`completed`, `cancelled`, `failed`, or + /// `incomplete`). + /// + /// Additional details about the status. + /// The list of output items generated by the response. + /// + /// Usage statistics for the Response, this will correspond to billing. A + /// VoiceLive API session will maintain a conversation context and append new + /// Items to the Conversation, thus output from previous turns (text and + /// audio tokens) will become the input for later turns. + /// + /// + /// Which conversation the response is added to, determined by the `conversation` + /// field in the `response.create` event. If `auto`, the response will be added to + /// the default conversation and the value of `conversation_id` will be an id like + /// `conv_1234`. If `none`, the response will not be added to any conversation and + /// the value of `conversation_id` will be `null`. If responses are being triggered + /// by server VAD, the response will be added to the default conversation, thus + /// the `conversation_id` will be an id like `conv_1234`. + /// + /// supported voice identifiers and configurations. + /// + /// The set of modalities the model used to respond. If there are multiple modalities, + /// the model will pick one, for example if `modalities` is `["text", "audio"]`, the model + /// could be responding in either text or audio. + /// + /// The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. + /// Sampling temperature for the model, limited to [0.6, 1.2]. Defaults to 0.8. + /// + /// Maximum number of output tokens for a single assistant response, + /// inclusive of tool calls, that was used in this response. + /// + /// A new instance for mocking. + public static VoiceLiveResponse VoiceLiveResponse(string id = default, string @object = default, ResponseStatus? status = default, ResponseStatusDetails statusDetails = default, IEnumerable output = default, ResponseUsage usage = default, string conversationId = default, BinaryData voice = default, IEnumerable modalities = default, ResponseOutputAudioFormat? outputAudioFormat = default, float? temperature = default, BinaryData maxOutputTokens = default) + { + output ??= new ChangeTrackingList(); + modalities ??= new ChangeTrackingList(); + + return new VoiceLiveResponse( + id, + @object, + status, + statusDetails, + output.ToList(), + usage, + conversationId, + voice, + modalities.ToList(), + outputAudioFormat, + temperature, + maxOutputTokens, + additionalBinaryDataProperties: null); + } + + /// The ResponseStatusDetails. + /// + /// The type of error that caused the response to fail, corresponding + /// with the `status` field (`completed`, `cancelled`, `incomplete`, + /// `failed`). + /// + /// + /// The reason the Response did not complete. For a `cancelled` Response, + /// one of `turn_detected` (the server VAD detected a new start of speech) + /// or `client_cancelled` (the client sent a cancel event). For an + /// `incomplete` Response, one of `max_output_tokens` or `content_filter` + /// (the server-side safety filter activated and cut off the response). + /// + /// + /// A description of the error that caused the response to fail, + /// populated when the `status` is `failed`. + /// + /// A new instance for mocking. + public static ResponseStatusDetails ResponseStatusDetails(ResponseStatusDetailsType? @type = default, ResponseStatusDetailsReason? reason = default, ResponseStatusDetailsError error = default) + { + return new ResponseStatusDetails(@type, reason, error, additionalBinaryDataProperties: null); + } + + /// The ResponseStatusDetailsError. + /// The type of error. + /// Error code, if any. + /// A new instance for mocking. + public static ResponseStatusDetailsError ResponseStatusDetailsError(string @type = default, string code = default) + { + return new ResponseStatusDetailsError(@type, code, additionalBinaryDataProperties: null); + } + + /// + /// The ConversationResponseItem. + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// + /// + /// + /// + /// A new instance for mocking. + public static ConversationResponseItem ConversationResponseItem(string @object = default, string @type = default, string id = default) + { + return new UnknownConversationResponseItem(@object, new ItemType(@type), id, additionalBinaryDataProperties: null); + } + + /// The ResponseMessageItem. + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ResponseMessageItem ResponseMessageItem(string @object = default, string id = default, MessageRole role = default, IEnumerable content = default, ItemStatus status = default) + { + content ??= new ChangeTrackingList(); + + return new ResponseMessageItem( + @object, + ItemType.Message, + id, + additionalBinaryDataProperties: null, + role, + content.ToList(), + status); + } + + /// The ResponseFunctionCallItem. + /// + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ResponseFunctionCallItem ResponseFunctionCallItem(string @object = default, string id = default, string name = default, string callId = default, string arguments = default, ItemStatus status = default) + { + return new ResponseFunctionCallItem( + @object, + ItemType.FunctionCall, + id, + additionalBinaryDataProperties: null, + name, + callId, + arguments, + status); + } + + /// The ResponseFunctionCallOutputItem. + /// + /// + /// + /// + /// A new instance for mocking. + public static ResponseFunctionCallOutputItem ResponseFunctionCallOutputItem(string @object = default, string id = default, string callId = default, string output = default) + { + return new ResponseFunctionCallOutputItem( + @object, + ItemType.FunctionCallOutput, + id, + additionalBinaryDataProperties: null, + callId, + output); + } + + /// The ResponseUsage. + /// + /// The total number of tokens in the Response including input and output + /// text and audio tokens. + /// + /// + /// The number of input tokens used in the Response, including text and + /// audio tokens. + /// + /// + /// The number of output tokens sent in the Response, including text and + /// audio tokens. + /// + /// Details about the input tokens used in the Response. + /// Details about the output tokens used in the Response. + /// A new instance for mocking. + public static ResponseUsage ResponseUsage(int? totalTokens = default, int? inputTokens = default, int? outputTokens = default, ResponseUsageInputTokenDetails inputTokenDetails = default, ResponseUsageOutputTokenDetails outputTokenDetails = default) + { + return new ResponseUsage( + totalTokens, + inputTokens, + outputTokens, + inputTokenDetails, + outputTokenDetails, + additionalBinaryDataProperties: null); + } + + /// The ResponseUsageInputTokenDetails. + /// The number of cached tokens used in the Response. + /// The number of text tokens used in the Response. + /// The number of audio tokens used in the Response. + /// A new instance for mocking. + public static ResponseUsageInputTokenDetails ResponseUsageInputTokenDetails(int? cachedTokens = default, int? textTokens = default, int? audioTokens = default) + { + return new ResponseUsageInputTokenDetails(cachedTokens, textTokens, audioTokens, additionalBinaryDataProperties: null); + } + + /// The ResponseUsageOutputTokenDetails. + /// The number of text tokens used in the Response. + /// The number of audio tokens used in the Response. + /// A new instance for mocking. + public static ResponseUsageOutputTokenDetails ResponseUsageOutputTokenDetails(int? textTokens = default, int? audioTokens = default) + { + return new ResponseUsageOutputTokenDetails(textTokens, audioTokens, additionalBinaryDataProperties: null); + } + + /// + /// Returned when a Response is done streaming. Always emitted, no matter the + /// final state. The Response object included in the `response.done` event will + /// include all output Items in the Response but will omit the raw audio data. + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseDone ServerEventResponseDone(string eventId = default, VoiceLiveResponse response = default) + { + return new ServerEventResponseDone(ServerEventType.ResponseDone, eventId, additionalBinaryDataProperties: null, response); + } + + /// Returned when a new Item is created during Response generation. + /// + /// The ID of the Response to which the item belongs. + /// The index of the output item in the Response. + /// + /// A new instance for mocking. + public static ServerEventResponseOutputItemAdded ServerEventResponseOutputItemAdded(string eventId = default, string responseId = default, int outputIndex = default, ConversationItemWithReference item = default) + { + return new ServerEventResponseOutputItemAdded( + ServerEventType.ResponseOutputItemAdded, + eventId, + additionalBinaryDataProperties: null, + responseId, + outputIndex, + item); + } + + /// + /// Returned when an Item is done streaming. Also emitted when a Response is + /// interrupted, incomplete, or cancelled. + /// + /// + /// The ID of the Response to which the item belongs. + /// The index of the output item in the Response. + /// + /// A new instance for mocking. + public static ServerEventResponseOutputItemDone ServerEventResponseOutputItemDone(string eventId = default, string responseId = default, int outputIndex = default, ConversationResponseItem item = default) + { + return new ServerEventResponseOutputItemDone( + ServerEventType.ResponseOutputItemDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + outputIndex, + item); + } + + /// + /// Returned when a new content part is added to an assistant message item during + /// response generation. + /// + /// + /// The ID of the response. + /// The ID of the item to which the content part was added. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The content part that was added. + /// A new instance for mocking. + public static ServerEventResponseContentPartAdded ServerEventResponseContentPartAdded(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, ContentPart part = default) + { + return new ServerEventResponseContentPartAdded( + ServerEventType.ResponseContentPartAdded, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + part); + } + + /// + /// Returned when a content part is done streaming in an assistant message item. + /// Also emitted when a Response is interrupted, incomplete, or cancelled. + /// + /// + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The content part that is done. + /// A new instance for mocking. + public static ServerEventResponseContentPartDone ServerEventResponseContentPartDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, ContentPart part = default) + { + return new ServerEventResponseContentPartDone( + ServerEventType.ResponseContentPartDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + part); + } + + /// + /// Returned when the text value of a "text" content part is done streaming. Also + /// emitted when a Response is interrupted, incomplete, or cancelled. + /// + /// + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The final text content. + /// A new instance for mocking. + public static ServerEventResponseTextDone ServerEventResponseTextDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, string text = default) + { + return new ServerEventResponseTextDone( + ServerEventType.ResponseTextDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + text); + } + + /// Returned when the model-generated transcription of audio output is updated. + /// + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The transcript delta. + /// A new instance for mocking. + public static ServerEventResponseAudioTranscriptDelta ServerEventResponseAudioTranscriptDelta(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, string delta = default) + { + return new ServerEventResponseAudioTranscriptDelta( + ServerEventType.ResponseAudioTranscriptDelta, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + delta); + } + + /// + /// Returned when the model-generated transcription of audio output is done + /// streaming. Also emitted when a Response is interrupted, incomplete, or + /// cancelled. + /// + /// + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// The final transcript of the audio. + /// A new instance for mocking. + public static ServerEventResponseAudioTranscriptDone ServerEventResponseAudioTranscriptDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, string transcript = default) + { + return new ServerEventResponseAudioTranscriptDone( + ServerEventType.ResponseAudioTranscriptDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + transcript); + } + + /// + /// Returned when the model-generated audio is done. Also emitted when a Response + /// is interrupted, incomplete, or cancelled. + /// + /// + /// The ID of the response. + /// The ID of the item. + /// The index of the output item in the response. + /// The index of the content part in the item's content array. + /// A new instance for mocking. + public static ServerEventResponseAudioDone ServerEventResponseAudioDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default) + { + return new ServerEventResponseAudioDone( + ServerEventType.ResponseAudioDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex); + } + + /// Returned when the model-generated function call arguments are updated. + /// + /// The ID of the response. + /// The ID of the function call item. + /// The index of the output item in the response. + /// The ID of the function call. + /// The arguments delta as a JSON string. + /// A new instance for mocking. + public static ServerEventResponseFunctionCallArgumentsDelta ServerEventResponseFunctionCallArgumentsDelta(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, string callId = default, string delta = default) + { + return new ServerEventResponseFunctionCallArgumentsDelta( + ServerEventType.ResponseFunctionCallArgumentsDelta, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + callId, + delta); + } + + /// + /// Returned when the model-generated function call arguments are done streaming. + /// Also emitted when a Response is interrupted, incomplete, or cancelled. + /// + /// + /// The ID of the response. + /// The ID of the function call item. + /// The index of the output item in the response. + /// The ID of the function call. + /// The final arguments as a JSON string. + /// The name of the function call. + /// A new instance for mocking. + public static ServerEventResponseFunctionCallArgumentsDone ServerEventResponseFunctionCallArgumentsDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, string callId = default, string arguments = default, string name = default) + { + return new ServerEventResponseFunctionCallArgumentsDone( + ServerEventType.ResponseFunctionCallArgumentsDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + callId, + arguments, + name); + } + + /// Represents a delta update of blendshape animation frames for a specific output of a response. + /// + /// + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseAnimationBlendshapeDelta ServerEventResponseAnimationBlendshapeDelta(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, BinaryData frames = default, int frameIndex = default) + { + return new ServerEventResponseAnimationBlendshapeDelta( + ServerEventType.ResponseAnimationBlendshapesDelta, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + frames, + frameIndex); + } + + /// Indicates the completion of blendshape animation processing for a specific output of a response. + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseAnimationBlendshapeDone ServerEventResponseAnimationBlendshapeDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default) + { + return new ServerEventResponseAnimationBlendshapeDone( + ServerEventType.ResponseAnimationBlendshapesDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex); + } + + /// Represents an emotion hypothesis detected from response audio with multiple candidates. + /// + /// + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseEmotionHypothesis ServerEventResponseEmotionHypothesis(string eventId = default, string emotion = default, IEnumerable candidates = default, int audioOffsetMs = default, int audioDurationMs = default, string responseId = default, string itemId = default) + { + candidates ??= new ChangeTrackingList(); + + return new ServerEventResponseEmotionHypothesis( + ServerEventType.ResponseEmotionHypothesis, + eventId, + additionalBinaryDataProperties: null, + emotion, + candidates.ToList(), + audioOffsetMs, + audioDurationMs, + responseId, + itemId); + } + + /// The EmotionCandidate. + /// + /// + /// A new instance for mocking. + public static EmotionCandidate EmotionCandidate(string emotion = default, float confidence = default) + { + return new EmotionCandidate(emotion, confidence, additionalBinaryDataProperties: null); + } + + /// Represents a word-level audio timestamp delta for a response. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseAudioTimestampDelta ServerEventResponseAudioTimestampDelta(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, int audioOffsetMs = default, int audioDurationMs = default, string text = default, string timestampType = default) + { + return new ServerEventResponseAudioTimestampDelta( + ServerEventType.ResponseAudioTimestampDelta, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + audioOffsetMs, + audioDurationMs, + text, + timestampType); + } + + /// Indicates completion of audio timestamp delivery for a response. + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseAudioTimestampDone ServerEventResponseAudioTimestampDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default) + { + return new ServerEventResponseAudioTimestampDone( + ServerEventType.ResponseAudioTimestampDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex); + } + + /// Represents a viseme ID delta update for animation based on audio. + /// + /// + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseAnimationVisemeDelta ServerEventResponseAnimationVisemeDelta(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default, int audioOffsetMs = default, int visemeId = default) + { + return new ServerEventResponseAnimationVisemeDelta( + ServerEventType.ResponseAnimationVisemeDelta, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex, + audioOffsetMs, + visemeId); + } + + /// Indicates completion of viseme animation delivery for a response. + /// + /// + /// + /// + /// + /// A new instance for mocking. + public static ServerEventResponseAnimationVisemeDone ServerEventResponseAnimationVisemeDone(string eventId = default, string responseId = default, string itemId = default, int outputIndex = default, int contentIndex = default) + { + return new ServerEventResponseAnimationVisemeDone( + ServerEventType.ResponseAnimationVisemeDone, + eventId, + additionalBinaryDataProperties: null, + responseId, + itemId, + outputIndex, + contentIndex); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveResponse.Serialization.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveResponse.Serialization.cs new file mode 100644 index 000000000000..8809363ffcf6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveResponse.Serialization.cs @@ -0,0 +1,344 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The response resource. + public partial class VoiceLiveResponse : IJsonModel + { + /// The JSON writer. + /// The client options for reading and writing models. + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + JsonModelWriteCore(writer, options); + writer.WriteEndObject(); + } + + /// The JSON writer. + /// The client options for reading and writing models. + protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VoiceLiveResponse)} does not support writing '{format}' format."); + } + if (Optional.IsDefined(Id)) + { + writer.WritePropertyName("id"u8); + writer.WriteStringValue(Id); + } + if (Optional.IsDefined(Object)) + { + writer.WritePropertyName("object"u8); + writer.WriteStringValue(Object); + } + if (Optional.IsDefined(Status)) + { + writer.WritePropertyName("status"u8); + writer.WriteStringValue(Status.Value.ToSerialString()); + } + if (Optional.IsDefined(StatusDetails)) + { + writer.WritePropertyName("status_details"u8); + writer.WriteObjectValue(StatusDetails, options); + } + if (Optional.IsCollectionDefined(Output)) + { + writer.WritePropertyName("output"u8); + writer.WriteStartArray(); + foreach (ConversationResponseItem item in Output) + { + writer.WriteObjectValue(item, options); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(Usage)) + { + writer.WritePropertyName("usage"u8); + writer.WriteObjectValue(Usage, options); + } + if (Optional.IsDefined(ConversationId)) + { + writer.WritePropertyName("conversation_id"u8); + writer.WriteStringValue(ConversationId); + } + if (Optional.IsDefined(Voice)) + { + writer.WritePropertyName("voice"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(Voice); +#else + using (JsonDocument document = JsonDocument.Parse(Voice)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (Optional.IsCollectionDefined(Modalities)) + { + writer.WritePropertyName("modalities"u8); + writer.WriteStartArray(); + foreach (ResponseModality item in Modalities) + { + writer.WriteStringValue(item.ToSerialString()); + } + writer.WriteEndArray(); + } + if (Optional.IsDefined(OutputAudioFormat)) + { + writer.WritePropertyName("output_audio_format"u8); + writer.WriteStringValue(OutputAudioFormat.Value.ToSerialString()); + } + if (Optional.IsDefined(Temperature)) + { + writer.WritePropertyName("temperature"u8); + writer.WriteNumberValue(Temperature.Value); + } + if (Optional.IsDefined(MaxOutputTokens)) + { + writer.WritePropertyName("max_output_tokens"u8); +#if NET6_0_OR_GREATER + writer.WriteRawValue(MaxOutputTokens); +#else + using (JsonDocument document = JsonDocument.Parse(MaxOutputTokens)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + if (options.Format != "W" && _additionalBinaryDataProperties != null) + { + foreach (var item in _additionalBinaryDataProperties) + { + writer.WritePropertyName(item.Key); +#if NET6_0_OR_GREATER + writer.WriteRawValue(item.Value); +#else + using (JsonDocument document = JsonDocument.Parse(item.Value)) + { + JsonSerializer.Serialize(writer, document.RootElement); + } +#endif + } + } + } + + /// The JSON reader. + /// The client options for reading and writing models. + VoiceLiveResponse IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options); + + /// The JSON reader. + /// The client options for reading and writing models. + protected virtual VoiceLiveResponse JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + if (format != "J") + { + throw new FormatException($"The model {nameof(VoiceLiveResponse)} does not support reading '{format}' format."); + } + using JsonDocument document = JsonDocument.ParseValue(ref reader); + return DeserializeVoiceLiveResponse(document.RootElement, options); + } + + /// The JSON element to deserialize. + /// The client options for reading and writing models. + internal static VoiceLiveResponse DeserializeVoiceLiveResponse(JsonElement element, ModelReaderWriterOptions options) + { + if (element.ValueKind == JsonValueKind.Null) + { + return null; + } + string id = default; + string @object = default; + ResponseStatus? status = default; + ResponseStatusDetails statusDetails = default; + IList output = default; + ResponseUsage usage = default; + string conversationId = default; + BinaryData voice = default; + IList modalities = default; + ResponseOutputAudioFormat? outputAudioFormat = default; + float? temperature = default; + BinaryData maxOutputTokens = default; + IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); + foreach (var prop in element.EnumerateObject()) + { + if (prop.NameEquals("id"u8)) + { + id = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("object"u8)) + { + @object = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("status"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + status = prop.Value.GetString().ToResponseStatus(); + continue; + } + if (prop.NameEquals("status_details"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + statusDetails = ResponseStatusDetails.DeserializeResponseStatusDetails(prop.Value, options); + continue; + } + if (prop.NameEquals("output"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(ConversationResponseItem.DeserializeConversationResponseItem(item, options)); + } + output = array; + continue; + } + if (prop.NameEquals("usage"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + usage = ResponseUsage.DeserializeResponseUsage(prop.Value, options); + continue; + } + if (prop.NameEquals("conversation_id"u8)) + { + conversationId = prop.Value.GetString(); + continue; + } + if (prop.NameEquals("voice"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + voice = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (prop.NameEquals("modalities"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + List array = new List(); + foreach (var item in prop.Value.EnumerateArray()) + { + array.Add(item.GetString().ToResponseModality()); + } + modalities = array; + continue; + } + if (prop.NameEquals("output_audio_format"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + outputAudioFormat = prop.Value.GetString().ToResponseOutputAudioFormat(); + continue; + } + if (prop.NameEquals("temperature"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + temperature = prop.Value.GetSingle(); + continue; + } + if (prop.NameEquals("max_output_tokens"u8)) + { + if (prop.Value.ValueKind == JsonValueKind.Null) + { + continue; + } + maxOutputTokens = BinaryData.FromString(prop.Value.GetRawText()); + continue; + } + if (options.Format != "W") + { + additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText())); + } + } + return new VoiceLiveResponse( + id, + @object, + status, + statusDetails, + output ?? new ChangeTrackingList(), + usage, + conversationId, + voice, + modalities ?? new ChangeTrackingList(), + outputAudioFormat, + temperature, + maxOutputTokens, + additionalBinaryDataProperties); + } + + /// The client options for reading and writing models. + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options); + + /// The client options for reading and writing models. + protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + return ModelReaderWriter.Write(this, options, AzureAIVoiceLiveContext.Default); + default: + throw new FormatException($"The model {nameof(VoiceLiveResponse)} does not support writing '{options.Format}' format."); + } + } + + /// The data to parse. + /// The client options for reading and writing models. + VoiceLiveResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options); + + /// The data to parse. + /// The client options for reading and writing models. + protected virtual VoiceLiveResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options) + { + string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + switch (format) + { + case "J": + using (JsonDocument document = JsonDocument.Parse(data)) + { + return DeserializeVoiceLiveResponse(document.RootElement, options); + } + default: + throw new FormatException($"The model {nameof(VoiceLiveResponse)} does not support reading '{options.Format}' format."); + } + } + + /// The client options for reading and writing models. + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveResponse.cs b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveResponse.cs new file mode 100644 index 000000000000..e89b29d2623c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Generated/VoiceLiveResponse.cs @@ -0,0 +1,223 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Text.Json; + +namespace Azure.AI.VoiceLive +{ + /// The response resource. + public partial class VoiceLiveResponse + { + /// Keeps track of any properties unknown to the library. + private protected readonly IDictionary _additionalBinaryDataProperties; + + /// Initializes a new instance of . + internal VoiceLiveResponse() + { + Output = new ChangeTrackingList(); + Modalities = new ChangeTrackingList(); + } + + /// Initializes a new instance of . + /// The unique ID of the response. + /// The object type, must be `realtime.response`. + /// + /// The final status of the response (`completed`, `cancelled`, `failed`, or + /// `incomplete`). + /// + /// Additional details about the status. + /// The list of output items generated by the response. + /// + /// Usage statistics for the Response, this will correspond to billing. A + /// VoiceLive API session will maintain a conversation context and append new + /// Items to the Conversation, thus output from previous turns (text and + /// audio tokens) will become the input for later turns. + /// + /// + /// Which conversation the response is added to, determined by the `conversation` + /// field in the `response.create` event. If `auto`, the response will be added to + /// the default conversation and the value of `conversation_id` will be an id like + /// `conv_1234`. If `none`, the response will not be added to any conversation and + /// the value of `conversation_id` will be `null`. If responses are being triggered + /// by server VAD, the response will be added to the default conversation, thus + /// the `conversation_id` will be an id like `conv_1234`. + /// + /// supported voice identifiers and configurations. + /// + /// The set of modalities the model used to respond. If there are multiple modalities, + /// the model will pick one, for example if `modalities` is `["text", "audio"]`, the model + /// could be responding in either text or audio. + /// + /// The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. + /// Sampling temperature for the model, limited to [0.6, 1.2]. Defaults to 0.8. + /// + /// Maximum number of output tokens for a single assistant response, + /// inclusive of tool calls, that was used in this response. + /// + /// Keeps track of any properties unknown to the library. + internal VoiceLiveResponse(string id, string @object, ResponseStatus? status, ResponseStatusDetails statusDetails, IList output, ResponseUsage usage, string conversationId, BinaryData voice, IList modalities, ResponseOutputAudioFormat? outputAudioFormat, float? temperature, BinaryData maxOutputTokens, IDictionary additionalBinaryDataProperties) + { + Id = id; + Object = @object; + Status = status; + StatusDetails = statusDetails; + Output = output; + Usage = usage; + ConversationId = conversationId; + Voice = voice; + Modalities = modalities; + OutputAudioFormat = outputAudioFormat; + Temperature = temperature; + MaxOutputTokens = maxOutputTokens; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + + /// The unique ID of the response. + public string Id { get; } + + /// The object type, must be `realtime.response`. + public string Object { get; } + + /// + /// The final status of the response (`completed`, `cancelled`, `failed`, or + /// `incomplete`). + /// + public ResponseStatus? Status { get; } + + /// Additional details about the status. + public ResponseStatusDetails StatusDetails { get; } + + /// The list of output items generated by the response. + public IList Output { get; } + + /// + /// Usage statistics for the Response, this will correspond to billing. A + /// VoiceLive API session will maintain a conversation context and append new + /// Items to the Conversation, thus output from previous turns (text and + /// audio tokens) will become the input for later turns. + /// + public ResponseUsage Usage { get; } + + /// + /// Which conversation the response is added to, determined by the `conversation` + /// field in the `response.create` event. If `auto`, the response will be added to + /// the default conversation and the value of `conversation_id` will be an id like + /// `conv_1234`. If `none`, the response will not be added to any conversation and + /// the value of `conversation_id` will be `null`. If responses are being triggered + /// by server VAD, the response will be added to the default conversation, thus + /// the `conversation_id` will be an id like `conv_1234`. + /// + public string ConversationId { get; } + + /// + /// supported voice identifiers and configurations. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// . + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData Voice { get; } + + /// + /// The set of modalities the model used to respond. If there are multiple modalities, + /// the model will pick one, for example if `modalities` is `["text", "audio"]`, the model + /// could be responding in either text or audio. + /// + public IList Modalities { get; } + + /// The format of output audio. Options are `pcm16`, `g711_ulaw`, or `g711_alaw`. + public ResponseOutputAudioFormat? OutputAudioFormat { get; } + + /// Sampling temperature for the model, limited to [0.6, 1.2]. Defaults to 0.8. + public float? Temperature { get; } + + /// + /// Maximum number of output tokens for a single assistant response, + /// inclusive of tool calls, that was used in this response. + /// To assign an object to this property use . + /// To assign an already formatted json string to this property use . + /// + /// + /// Supported types: + /// + /// + /// . + /// + /// + /// "inf". + /// + /// + /// + /// + /// + /// Examples: + /// + /// + /// BinaryData.FromObjectAsJson("foo"). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromString("\"foo\""). + /// Creates a payload of "foo". + /// + /// + /// BinaryData.FromObjectAsJson(new { key = "value" }). + /// Creates a payload of { "key": "value" }. + /// + /// + /// BinaryData.FromString("{\"key\": \"value\"}"). + /// Creates a payload of { "key": "value" }. + /// + /// + /// + /// + public BinaryData MaxOutputTokens { get; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/GlobalSuppressions.cs b/sdk/ai/Azure.AI.VoiceLive/src/GlobalSuppressions.cs new file mode 100644 index 000000000000..17a9a8e7fd4e --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/GlobalSuppressions.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Usage", "AZC0030:Avoid single word type names", Justification = "", Scope = "type", Target = "~T:Azure.AI.VoiceLive.VoiceLiveResponse")] diff --git a/sdk/ai/Azure.AI.VoiceLive/src/IVoiceType.cs b/sdk/ai/Azure.AI.VoiceLive/src/IVoiceType.cs new file mode 100644 index 000000000000..9b8898eadabe --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/IVoiceType.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Azure.AI.VoiceLive +{ + /// + /// Base interface for the different voice types supported by the VoiceLive service + /// + public interface IVoiceType + { + /// + /// + /// + /// + BinaryData ToBinaryData(); + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/Properties/AssemblyInfo.cs b/sdk/ai/Azure.AI.VoiceLive/src/Properties/AssemblyInfo.cs new file mode 100644 index 000000000000..e45593866623 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/Properties/AssemblyInfo.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Azure.AI.VoiceLive.Tests, PublicKey = 0024000004800000940000000602000000240000525341310004000001000100d15ddcb29688295338af4b7686603fe614abd555e09efba8fb88ee09e1f7b1ccaeed2e8f823fa9eef3fdd60217fc012ea67d2479751a0b8c087a4185541b851bd8b16f8d91b840e51b1cb0ba6fe647997e57429265e85ef62d565db50a69ae1647d54d7bd855e4db3d8a91510e5bcbd0edfbbecaa20a7bd9ae74593daa7b11b4")] + +// Replace Microsoft.Test with the correct resource provider namepace for your service and uncomment. +// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-services-resource-providers +// for the list of possible values. +[assembly: Azure.Core.AzureResourceProviderNamespace("Microsoft.Template")] diff --git a/sdk/ai/Azure.AI.VoiceLive/src/ResponseOptions.cs b/sdk/ai/Azure.AI.VoiceLive/src/ResponseOptions.cs new file mode 100644 index 000000000000..31faad85c526 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/ResponseOptions.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// + /// Represents configuration options for VoiceLive response generation. + /// + /// + /// This class provides configuration options for controlling how the VoiceLive service + /// generates responses, including modalities, tools, and response formatting. + /// + public class ResponseOptions + { + /// + /// Gets or sets the modalities to include in the response. + /// + /// + /// A list of modalities (e.g., text, audio) that should be included in the response. + /// If not specified, the service will use default modalities. + /// + public IList Modalities { get; set; } = new List(); + + /// + /// Gets or sets the instructions for response generation. + /// + /// + /// Instructions that guide how the response should be generated. + /// + public string Instructions { get; set; } + + /// + /// Gets or sets the voice configuration for spoken responses. + /// + /// + /// The voice configuration to use for generating spoken responses. + /// + public IVoiceType Voice { get; set; } + + /// + /// Gets or sets the output audio format for the response. + /// + /// + /// The audio format to use for output audio in the response. + /// + public AudioFormat? OutputAudioFormat { get; set; } + + /// + /// Gets or sets the tools available during response generation. + /// + /// + /// A list of tools that can be used during response generation. + /// + public IList Tools { get; set; } = new List(); + + /// + /// Gets or sets the tool choice strategy for response generation. + /// + /// + /// Specifies how tools should be chosen during response generation. + /// + public string ToolChoice { get; set; } + + /// + /// Gets or sets the temperature parameter for response generation. + /// + /// + /// A value between 0.0 and 1.0 controlling the randomness of the response. + /// Higher values produce more random responses. + /// + public float? Temperature { get; set; } + + /// + /// Gets or sets the maximum number of tokens to generate in the response. + /// + /// + /// The maximum number of tokens to generate. If not specified, the service will use a default limit. + /// + public int? MaxOutputTokens { get; set; } + + /// + /// Gets or sets a value indicating whether to commit the response to the conversation. + /// + /// + /// true to commit the response to the conversation; otherwise, false. + /// Default is true. + /// + public bool? Commit { get; set; } + + /// + /// Gets or sets a value indicating whether to cancel any ongoing generation before starting this one. + /// + /// + /// true to cancel ongoing generation; otherwise, false. + /// Default is true. + /// + public bool? CancelPrevious { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public ResponseOptions() + { + } + + /// + /// Converts the response options to a instance. + /// + /// A instance configured with the current options. + /// + /// This method uses the model factory to create the response parameters since the + /// VoiceLiveResponseCreateParams constructor is internal. + /// + internal virtual ResponseCreateParams ToCreateParams() + { + // Since VoiceLiveResponseCreateParams has an internal constructor, + // we need to find another way to create it. For now, we'll return null + // and handle this at the call site. + return null; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/STREAMING_USAGE_EXAMPLES.cs b/sdk/ai/Azure.AI.VoiceLive/src/STREAMING_USAGE_EXAMPLES.cs new file mode 100644 index 000000000000..d0cf2baf36de --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/STREAMING_USAGE_EXAMPLES.cs @@ -0,0 +1,217 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/* +# VoiceLive SDK Server Events Usage Examples + +This file demonstrates how to use the VoiceLive SDK's server event streaming functionality. + +## Basic Server Event Streaming + +```csharp +using Azure.AI.VoiceLive; + +// Create and connect to a VoiceLive session +var client = new VoiceLiveClient(endpoint, credential); +var session = await client.StartSessionAsync(sessionOptions); + +// Get all server events as they arrive +await foreach (VoiceLiveServerEvent serverEvent in session.GetUpdatesAsync()) +{ + Console.WriteLine($"Received event: {serverEvent.Type}"); + + // Handle specific event types + switch (serverEvent) + { + case VoiceLiveServerEventSessionCreated sessionCreated: + Console.WriteLine($"Session created: {sessionCreated.Session?.Id}"); + break; + + case VoiceLiveServerEventResponseTextDelta textDelta: + Console.Write(textDelta.Delta); // Stream text as it arrives + break; + + case VoiceLiveServerEventResponseAudioDelta audioDelta: + ProcessAudioData(audioDelta.Delta); // Process audio chunks + break; + + case VoiceLiveServerEventInputAudioBufferSpeechStarted speechStarted: + Console.WriteLine("User started speaking"); + break; + + case VoiceLiveServerEventConversationItemInputAudioTranscriptionDelta transcriptionDelta: + Console.WriteLine($"Transcription delta: {transcriptionDelta.Delta}"); + break; + + case VoiceLiveServerEventError errorEvent: + Console.WriteLine($"Error: {errorEvent.Error?.Message}"); + break; + } +} +``` + +## Filtered Server Event Streaming + +```csharp +// Get only specific types of server events +await foreach (VoiceLiveServerEventResponseTextDelta textDelta in session.GetUpdatesAsync()) +{ + Console.Write(textDelta.Delta); +} + +// Get only audio delta events +await foreach (VoiceLiveServerEventResponseAudioDelta audioDelta in session.GetUpdatesAsync()) +{ + ProcessAudioData(audioDelta.Delta); +} +``` + +## Synchronous Usage + +```csharp +// For scenarios where you need synchronous processing +foreach (VoiceLiveServerEvent serverEvent in session.GetUpdates()) +{ + ProcessServerEvent(serverEvent); +} +``` + +## Convenience Methods + +```csharp +// Wait for a specific server event type +VoiceLiveServerEventSessionCreated sessionCreated = await session.WaitForUpdateAsync(); +Console.WriteLine($"Session {sessionCreated.Session?.Id} is ready"); + +// Wait for any error event +VoiceLiveServerEventError errorEvent = await session.WaitForUpdateAsync(); +Console.WriteLine($"Error: {errorEvent.Error?.Message}"); +``` + +## Avatar and Animation Events + +```csharp +// Handle avatar-specific events +await foreach (VoiceLiveServerEvent serverEvent in session.GetUpdatesAsync()) +{ + switch (serverEvent) + { + case VoiceLiveServerEventSessionAvatarConnecting avatarConnecting: + Console.WriteLine("Avatar connection in progress"); + break; + + case ResponseAnimationBlendshapeDeltaEvent blendshapeDelta: + ProcessBlendshapeData(blendshapeDelta.Frames); + break; + + case ResponseAnimationVisemeDeltaEvent visemeDelta: + ProcessVisemeData(visemeDelta.VisemeIds); + break; + + case ResponseEmotionHypothesis emotionHypothesis: + Console.WriteLine($"Detected emotion: {emotionHypothesis.Emotion} (confidence: {emotionHypothesis.Candidates?.FirstOrDefault()?.Confidence})"); + break; + } +} +``` + +## Response Lifecycle Tracking + +```csharp +await foreach (VoiceLiveServerEvent serverEvent in session.GetUpdatesAsync()) +{ + switch (serverEvent) + { + case VoiceLiveServerEventResponseCreated responseCreated: + Console.WriteLine($"Response started: {responseCreated.Response?.Id}"); + break; + + case VoiceLiveServerEventResponseOutputItemAdded itemAdded: + Console.WriteLine($"Output item added: {itemAdded.Item?.Id}"); + break; + + case VoiceLiveServerEventResponseOutputItemDone itemDone: + Console.WriteLine($"Output item completed: {itemDone.Item?.Id}"); + break; + + case VoiceLiveServerEventResponseDone responseDone: + Console.WriteLine($"Response completed: {responseDone.Response?.Id} (status: {responseDone.Response?.Status})"); + break; + } +} +``` + +## Event Type Categories + +The VoiceLive service generates several categories of server events: + +### Session Events +- **VoiceLiveServerEventSessionCreated**: Session initialization complete +- **VoiceLiveServerEventSessionUpdated**: Session configuration updated +- **VoiceLiveServerEventSessionAvatarConnecting**: Avatar connection in progress + +### Input Audio Events +- **VoiceLiveServerEventInputAudioBufferSpeechStarted**: Voice activity detected +- **VoiceLiveServerEventInputAudioBufferSpeechStopped**: Voice activity ended +- **VoiceLiveServerEventInputAudioBufferCommitted**: Audio buffer committed +- **VoiceLiveServerEventInputAudioBufferCleared**: Audio buffer cleared + +### Response Events +- **VoiceLiveServerEventResponseCreated**: Response generation started +- **VoiceLiveServerEventResponseDone**: Response generation completed +- **VoiceLiveServerEventResponseOutputItemAdded**: New output item created +- **VoiceLiveServerEventResponseOutputItemDone**: Output item completed + +### Content Streaming Events +- **VoiceLiveServerEventResponseTextDelta**: Text content streaming +- **VoiceLiveServerEventResponseTextDone**: Text content completed +- **VoiceLiveServerEventResponseAudioDelta**: Audio content streaming +- **VoiceLiveServerEventResponseAudioDone**: Audio content completed +- **VoiceLiveServerEventResponseAudioTranscriptDelta**: Audio transcript streaming +- **VoiceLiveServerEventResponseAudioTranscriptDone**: Audio transcript completed + +### Animation Events (VoiceLive-specific) +- **ResponseAnimationBlendshapeDeltaEvent**: Blendshape animation data streaming +- **ResponseAnimationBlendshapeDoneEvent**: Blendshape animation completed +- **ResponseAnimationVisemeDeltaEvent**: Viseme animation data streaming +- **ResponseAnimationVisemeDoneEvent**: Viseme animation completed +- **ResponseEmotionHypothesis**: Emotion detection results + +### Conversation Events +- **VoiceLiveServerEventConversationItemCreated**: New conversation item +- **VoiceLiveServerEventConversationItemDeleted**: Conversation item removed +- **VoiceLiveServerEventConversationItemInputAudioTranscriptionDelta**: Input transcription streaming +- **VoiceLiveServerEventConversationItemInputAudioTranscriptionCompleted**: Input transcription completed + +### Error Events +- **VoiceLiveServerEventError**: Error conditions and failures + +## Error Handling + +```csharp +await foreach (VoiceLiveServerEvent serverEvent in session.GetUpdatesAsync()) +{ + if (serverEvent is VoiceLiveServerEventError errorEvent) + { + Console.WriteLine($"Error occurred: {errorEvent.Error?.Message}"); + Console.WriteLine($"Error type: {errorEvent.Error?.Type}"); + Console.WriteLine($"Error code: {errorEvent.Error?.Code}"); + + // Handle specific error conditions + switch (errorEvent.Error?.Type) + { + case "connection_error": + // Handle connection issues + break; + case "invalid_request_error": + // Handle request validation errors + break; + default: + // Handle other errors + break; + } + } +} +``` + +*/ diff --git a/sdk/ai/Azure.AI.VoiceLive/src/SessionOptions.cs b/sdk/ai/Azure.AI.VoiceLive/src/SessionOptions.cs new file mode 100644 index 000000000000..1f8973c17104 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/SessionOptions.cs @@ -0,0 +1,304 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.ComponentModel; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// + /// Represents configuration options for a VoiceLive session. + /// + /// + /// This unified class provides all configuration options that can be used to customize + /// the behavior of a VoiceLive session, whether for conversation, transcription, or + /// hybrid scenarios. + /// + public class SessionOptions + { + // ==================== Audio Configuration ==================== + + /// + /// Gets or sets the input audio format for the session. + /// + /// + /// The audio format to use for input audio. If not specified, the service will use a default format. + /// + public AudioFormat? InputAudioFormat { get; set; } + + /// + /// Gets or sets the output audio format for the session. + /// + /// + /// The audio format to use for output audio. If not specified, the service will use a default format. + /// + public AudioFormat? OutputAudioFormat { get; set; } + + /// + /// Gets or sets the turn detection configuration for the session. + /// + /// + /// The turn detection configuration to use. If not specified, the service will use server-side VAD. + /// + public TurnDetection TurnDetection { get; set; } + + /// + /// Gets or sets the audio noise reduction settings. + /// + /// + /// Configuration for reducing noise in the input audio to improve accuracy. + /// If not specified, default noise reduction settings will be used. + /// + public AudioNoiseReduction NoiseReduction { get; set; } + + /// + /// Gets or sets the echo cancellation settings. + /// + /// + /// Configuration for cancelling echo in the input audio to improve accuracy. + /// If not specified, default echo cancellation settings will be used. + /// + public AudioEchoCancellation EchoCancellation { get; set; } + + // ==================== Modalities & Core Settings ==================== + + /// + /// Gets or sets the modalities supported by the session. + /// + /// + /// A list of modalities that the session should support. Defaults to text and audio. + /// + public IList Modalities { get; set; } = new List { InputModality.Text, InputModality.Audio }; + + /// + /// Gets or sets the model to use for the session. + /// + /// + /// The model identifier for processing. If not specified, the service will use a default model. + /// + public string Model { get; set; } + + /// + /// Gets or sets the temperature parameter for response generation. + /// + /// + /// A value between 0.0 and 1.0 controlling the randomness of the response. Higher values produce more random responses. + /// + public float? Temperature { get; set; } + + /// + /// Gets or sets the maximum number of tokens to generate in the response. + /// + /// + /// The maximum number of tokens to generate. If not specified, the service will use a default limit. + /// + public int? MaxResponseOutputTokens { get; set; } + + // ==================== Transcription Features ==================== + + /// + /// Gets or sets the input audio transcription settings. + /// + /// + /// Configuration for transcribing input audio. If not specified, transcription is disabled. + /// + public AudioInputTranscriptionSettings InputAudioTranscription { get; set; } + + /// + /// Gets or sets the language for transcription. + /// + /// + /// The language code (e.g., "en-US", "fr-FR") to use for transcription. + /// If not specified, the service will attempt to auto-detect the language. + /// + public string Language { get; set; } + + /// + /// Gets or sets a value indicating whether to include confidence scores in transcription results. + /// + /// + /// true to include confidence scores for transcribed text; otherwise, false. + /// Default is false. + /// + public bool IncludeConfidenceScores { get; set; } + + /// + /// Gets or sets a value indicating whether to include timestamps in transcription results. + /// + /// + /// true to include word-level timestamps in transcribed text; otherwise, false. + /// Default is false. + /// + public bool IncludeTimestamps { get; set; } + + /// + /// Gets or sets a list of words or phrases to boost recognition accuracy. + /// + /// + /// A list of domain-specific words or phrases that should be recognized more accurately. + /// This can improve transcription quality for specialized vocabulary like brand names, + /// technical terms, or industry jargon. + /// + public IList CustomVocabulary { get; set; } = new List(); + + // ==================== Conversation Features ==================== + + /// + /// Gets or sets the voice configuration for the conversation. + /// + /// + /// The voice configuration to use for generating spoken responses. If not specified, + /// the service will use a default voice. + /// + public IVoiceType Voice { get; set; } + + /// + /// Gets or sets the instructions for the conversation assistant. + /// + /// + /// Instructions that guide the assistant's behavior and responses during the conversation. + /// + public string Instructions { get; set; } + + /// + /// Gets or sets the tools available to the conversation assistant. + /// + /// + /// A list of tools that the assistant can use during the conversation. + /// + public IList Tools { get; set; } = new List(); + + /// + /// Gets or sets the tool choice strategy for the conversation. + /// + /// + /// Specifies how the assistant should choose which tools to use. If not specified, + /// the assistant will automatically decide when to use tools. + /// + public string ToolChoice { get; set; } + + /// + /// Gets or sets a value indicating whether to enable parallel tool calling. + /// + /// + /// true to allow the assistant to call multiple tools in parallel; otherwise, false. + /// Default is false. + /// + public bool ParallelToolCalls { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public SessionOptions() + { + } + + /// + /// Converts the session options to a instance. + /// + /// A instance configured with the current options. + internal virtual RequestSession ToRequestSession() + { + var session = new RequestSession(); + + // Audio configuration + if (InputAudioFormat.HasValue) + { + session.InputAudioFormat = InputAudioFormat.Value; + } + + if (OutputAudioFormat.HasValue) + { + session.OutputAudioFormat = OutputAudioFormat.Value; + } + + if (TurnDetection != null) + { + session.TurnDetection = TurnDetection; + } + + if (NoiseReduction != null) + { + session.InputAudioNoiseReduction = NoiseReduction; + } + + if (EchoCancellation != null) + { + session.InputAudioEchoCancellation = EchoCancellation; + } + + // Modalities + if (Modalities != null && Modalities.Count > 0) + { + session.Modalities.Clear(); + foreach (var modality in Modalities) + { + session.Modalities.Add(modality); + } + } + + // Model and generation settings + if (!string.IsNullOrEmpty(Model)) + { + session.Model = Model; + } + + if (Temperature.HasValue) + { + session.Temperature = Temperature.Value; + } + + if (MaxResponseOutputTokens.HasValue) + { + session.MaxResponseOutputTokens = MaxResponseOutputTokens.Value; + } + + // Transcription settings + if (InputAudioTranscription != null) + { + session.InputAudioTranscription = InputAudioTranscription; + } + + if (!string.IsNullOrEmpty(Language)) + { + // Store language in additional properties since it might not be a direct property + session.AdditionalProperties["language"] = BinaryData.FromString($"\"{Language}\""); + } + + // Note: IncludeConfidenceScores, IncludeTimestamps, and CustomVocabulary + // may need special handling based on the service API + + // Conversation settings + if (Voice != null) + { + session.Voice = Voice; + } + + if (!string.IsNullOrEmpty(Instructions)) + { + session.Instructions = Instructions; + } + + if (Tools != null && Tools.Count > 0) + { + session.Tools.Clear(); + foreach (var tool in Tools) + { + session.Tools.Add(tool); + } + } + + if (ToolChoice != null) + { + session.ToolChoice = ToolChoice; + } + + // Note: ParallelToolCalls may need special handling + + return session; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VideoCrop.cs b/sdk/ai/Azure.AI.VoiceLive/src/VideoCrop.cs new file mode 100644 index 000000000000..e66eae02ad1c --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VideoCrop.cs @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable disable + +using System; +using System.Drawing; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Linq; + +namespace Azure.AI.VoiceLive +{ + /// Defines a video crop rectangle. + public partial class VideoCrop + { + /// Initializes a new instance of . + /// Top-left corner of the crop region. + /// Bottom-right corner of the crop region. + /// or is null. + internal VideoCrop(IList topLeftInternal, IList bottomRightInternal) + { + Argument.AssertNotNull(topLeftInternal, nameof(topLeftInternal)); + Argument.AssertNotNull(bottomRightInternal, nameof(bottomRightInternal)); + + TopLeftInternal = topLeftInternal; + BottomRightInternal = bottomRightInternal; + } + + /// Initializes a new instance of . + /// Top-left corner of the crop region. + /// Bottom-right corner of the crop region. + /// or is null. + public VideoCrop(Point topLeft, Point bottomRight) + { + Argument.AssertNotNull(topLeft, nameof(topLeft)); + Argument.AssertNotNull(bottomRight, nameof(bottomRight)); + + TopLeft = topLeft; + BottomRight = bottomRight; + } + + /// Top-left corner of the crop region. + internal IList TopLeftInternal + { + get + { + return new List(new int[] { TopLeft.X, TopLeft.Y }); + } + set + { + TopLeft = ToPoint(value); + } + } + + private static Point ToPoint(IList list) + { + if (null == list) + { + throw new ArgumentNullException(nameof(list)); + } + + var listAsArray = list.ToArray(); + + if (listAsArray.Length != 2) + { + throw new ArgumentException($"List had {listAsArray.Length} elements, which was not 2"); + } + + return new Point(listAsArray[0], listAsArray[1]); + } + + /// Bottom-right corner of the crop region. + internal IList BottomRightInternal + { + get + { + return new List(new int[] { BottomRight.X, BottomRight.Y }); + } + set + { + BottomRight = ToPoint(value); + } + } + + /// Top-left corner of the crop region. + public Point TopLeft { get; set; } + + /// Bottom-right corner of the crop region. + public Point BottomRight { get; set; } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveClient.Overrides.cs b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveClient.Overrides.cs new file mode 100644 index 000000000000..d9b5f4329282 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveClient.Overrides.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ +#pragma warning disable AZC0015, AZC0107 // Client methods should return approved types + public partial class VoiceLiveClient + { + private VoiceLiveClientOptions _options; + + /// Initializes a new instance of VoiceLiveClient. + /// Service endpoint. + /// A credential used to authenticate to the service. + /// The options for configuring the client. + /// or is null. + public VoiceLiveClient(Uri endpoint, AzureKeyCredential credential, VoiceLiveClientOptions options) + { + Argument.AssertNotNull(endpoint, nameof(endpoint)); + Argument.AssertNotNull(credential, nameof(credential)); + + options ??= new VoiceLiveClientOptions(); + + _endpoint = endpoint; + _keyCredential = credential; + _options = options; + ClientDiagnostics = new ClientDiagnostics(options, true); + } + + /// Initializes a new instance of VoiceLiveClient. + /// Service endpoint. + /// A credential used to authenticate to the service. + /// The options for configuring the client. + /// or is null. + public VoiceLiveClient(Uri endpoint, TokenCredential credential, VoiceLiveClientOptions options) + { + Argument.AssertNotNull(endpoint, nameof(endpoint)); + Argument.AssertNotNull(credential, nameof(credential)); + + options ??= new VoiceLiveClientOptions(); + + _endpoint = endpoint; + _tokenCredential = credential; + _options = options; + ClientDiagnostics = new ClientDiagnostics(options, true); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveClient.WebSockets.cs b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveClient.WebSockets.cs new file mode 100644 index 000000000000..bf514a09c8cb --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveClient.WebSockets.cs @@ -0,0 +1,143 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ +#pragma warning disable AZC0015, AZC0107 // Client methods should return approved types + public partial class VoiceLiveClient + { + /// + /// Starts a new for real-time voice communication. + /// + /// + /// The abstracts bidirectional communication between the caller and service, + /// simultaneously sending and receiving WebSocket messages. + /// + /// The cancellation token to use. + /// + /// A task that represents the asynchronous operation. The task result contains a new, connected instance of . + public virtual async Task StartSessionAsync(string model, CancellationToken cancellationToken = default) + { + // Convert the HTTP endpoint to a WebSocket endpoint + Uri webSocketEndpoint = ConvertToWebSocketEndpoint(_endpoint, model); + + VoiceLiveSession session = new(this, webSocketEndpoint, _keyCredential); + + await session.ConnectAsync(cancellationToken).ConfigureAwait(false); + + return session; + } + + /// + /// Starts a new for real-time voice communication. + /// + /// + /// The abstracts bidirectional communication between the caller and service, + /// simultaneously sending and receiving WebSocket messages. + /// + /// The cancellation token to use. + /// + /// A new, connected instance of . + public virtual VoiceLiveSession StartSession(string model, CancellationToken cancellationToken = default) + { + return StartSessionAsync(model, cancellationToken).EnsureCompleted(); + } + + /// + /// Starts a new for real-time voice communication with specified session configuration. + /// + /// + /// The abstracts bidirectional communication between the caller and service, + /// simultaneously sending and receiving WebSocket messages. + /// + /// The configuration for the session. + /// The cancellation token to use. + /// A task that represents the asynchronous operation. The task result contains a new, connected instance of . + public virtual async Task StartSessionAsync( + RequestSession sessionConfig, + CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(sessionConfig, nameof(sessionConfig)); + + VoiceLiveSession session = await StartSessionAsync(sessionConfig.Model, cancellationToken).ConfigureAwait(false); + + // Send the session configuration + ClientEventSessionUpdate sessionUpdateEvent = new(sessionConfig); + await session.SendCommandAsync(sessionUpdateEvent, cancellationToken).ConfigureAwait(false); + + return session; + } + + /// + /// Starts a new for real-time voice communication with specified session configuration. + /// + /// + /// The abstracts bidirectional communication between the caller and service, + /// simultaneously sending and receiving WebSocket messages. + /// + /// The configuration for the session. + /// The cancellation token to use. + /// A new, connected instance of . + public virtual VoiceLiveSession StartSession( + RequestSession sessionConfig, + CancellationToken cancellationToken = default) + { + return StartSessionAsync(sessionConfig, cancellationToken).EnsureCompleted(); + } + + /// + /// Converts an HTTP endpoint to a WebSocket endpoint. + /// + /// The HTTP endpoint to convert. + /// + /// The WebSocket endpoint. + private Uri ConvertToWebSocketEndpoint(Uri httpEndpoint, string model) + { + if (httpEndpoint == null) + { + throw new ArgumentNullException(nameof(httpEndpoint)); + } + + var scheme = httpEndpoint.Scheme.ToLower() switch + { + "wss" => "wss", + "ws" => "ws", + "https" => "wss", + "http" => "ws", + _ => throw new ArgumentException($"Scheme {httpEndpoint.Scheme} is not supported."), + }; + + var builder = new UriBuilder(httpEndpoint) + { + Scheme = scheme + }; + + // Ensure the path includes the WebSocket endpoint + if (!builder.Path.EndsWith("/realtime", StringComparison.OrdinalIgnoreCase)) + { + builder.Path = builder.Path.TrimEnd('/') + "/voice-agent/realtime"; + } + + // Add the query parameter for the API version if it doesn't already exist + if (!builder.Query.Contains("api-version=")) + { + builder.Query = $"{builder.Query.TrimStart('?')}&api-version={_options.Version}"; + } + + if (!builder.Query.Contains("model=")) + { + builder.Query = $"{builder.Query.TrimStart('?')}&model={model}"; + } + + return builder.Uri; + } + } +#pragma warning restore AZC0015, AZC0107 +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveRequestSession.cs b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveRequestSession.cs new file mode 100644 index 000000000000..67bd0a336996 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveRequestSession.cs @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Azure.AI.VoiceLive +{ + /// The VoiceLiveRequestSession. + public partial class RequestSession + { + /// + /// Serialized additional properties for the request session + /// + internal IDictionary AdditionalProperties => this._additionalBinaryDataProperties; + + [CodeGenMember("Voice")] + private BinaryData _servcieVoice; + + /// + /// Gets or sets the Voice. + /// + public IVoiceType Voice + { + get + { + if (_servcieVoice == null) + { + return null; + } + return _servcieVoice.ToObjectFromJson(); + } + set + { + if (value == null) + { + _servcieVoice = null; + } + else + { + _servcieVoice = value.ToBinaryData(); + } + } + } + + [CodeGenMember("MaxResponseOutputTokens")] + private BinaryData _maxResponseOutputTokens; + + /// + /// Gets or sets the maximum number of tokens to generate in the response. + /// + public int? MaxResponseOutputTokens + { + get => _maxResponseOutputTokens.ToObjectFromJson(); + set => _maxResponseOutputTokens = BinaryData.FromObjectAsJson(value); + } + + [CodeGenMember("ToolChoice")] + private BinaryData _toolChoice; + + /// + /// Gets or sets the tool choice strategy for response generation. + /// + public string ToolChoice + { + get => _toolChoice.ToObjectFromJson(); + set => _toolChoice = BinaryData.FromObjectAsJson(value); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Commands.cs b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Commands.cs new file mode 100644 index 000000000000..07be1d087f74 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Commands.cs @@ -0,0 +1,687 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Buffers; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ +#pragma warning disable AZC0107 + public partial class VoiceLiveSession + { + #region Audio Data Transmission + + /// + /// Transmits audio data from a byte array. + /// + /// The audio data to transmit. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when another audio stream is already being sent. + /// A task that represents the asynchronous operation. + public virtual async Task SendInputAudioAsync(byte[] audio, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(audio, nameof(audio)); + ThrowIfDisposed(); + + using (await _audioSendSemaphore.AutoReleaseWaitAsync(cancellationToken).ConfigureAwait(false)) + { + if (_isSendingAudioStream) + { + throw new InvalidOperationException("Cannot send a standalone audio chunk while a stream is already in progress."); + } + + string base64Audio = Convert.ToBase64String(audio); + ClientEventInputAudioBufferAppend appendCommand = new(base64Audio); + await SendCommandAsync(appendCommand, cancellationToken).ConfigureAwait(false); + } + } + + /// + /// Transmits audio data from a byte array. + /// + /// The audio data to transmit. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when another audio stream is already being sent. + public virtual void SendInputAudio(byte[] audio, CancellationToken cancellationToken = default) + { + SendInputAudioAsync(audio, cancellationToken).EnsureCompleted(); + } + + /// + /// Transmits audio data from BinaryData. + /// + /// The audio data to transmit. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when another audio stream is already being sent. + /// A task that represents the asynchronous operation. + public virtual async Task SendInputAudioAsync(BinaryData audio, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(audio, nameof(audio)); + ThrowIfDisposed(); + + using (await _audioSendSemaphore.AutoReleaseWaitAsync(cancellationToken).ConfigureAwait(false)) + { + if (_isSendingAudioStream) + { + throw new InvalidOperationException("Cannot send a standalone audio chunk while a stream is already in progress."); + } + + string base64Audio = Convert.ToBase64String(audio.ToArray()); + ClientEventInputAudioBufferAppend appendCommand = new(base64Audio); + await SendCommandAsync(appendCommand, cancellationToken).ConfigureAwait(false); + } + } + + /// + /// Transmits audio data from BinaryData. + /// + /// The audio data to transmit. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when another audio stream is already being sent. + public virtual void SendInputAudio(BinaryData audio, CancellationToken cancellationToken = default) + { + SendInputAudioAsync(audio, cancellationToken).EnsureCompleted(); + } + + /// + /// Clears the input audio buffer. + /// + /// An optional cancellation token. + /// A task that represents the asynchronous operation. + public virtual async Task ClearInputAudioAsync(CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + ClientEventInputAudioBufferClear clearCommand = new(); + await SendCommandAsync(clearCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Clears the input audio buffer. + /// + /// An optional cancellation token. + public virtual void ClearInputAudio(CancellationToken cancellationToken = default) + { + ClearInputAudioAsync(cancellationToken).EnsureCompleted(); + } + + /// + /// Commits the input audio buffer. + /// + /// An optional cancellation token. + /// A task that represents the asynchronous operation. + public virtual async Task CommitInputAudioAsync(CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + ClientEventInputAudioBufferCommit commitCommand = new(); + await SendCommandAsync(commitCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Commits the input audio buffer. + /// + /// An optional cancellation token. + public virtual void CommitInputAudio(CancellationToken cancellationToken = default) + { + CommitInputAudioAsync(cancellationToken).EnsureCompleted(); + } + + /// + /// Clears all input audio currently being streamed. + /// + /// An optional cancellation token. + /// A task that represents the asynchronous operation. + public virtual async Task ClearStreamingAudioAsync(CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + + ClientEventInputAudioClear clearCommand = new(); + await SendCommandAsync(clearCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Clears all input audio currently being streamed. + /// + /// An optional cancellation token. + public virtual void ClearStreamingAudio(CancellationToken cancellationToken = default) + { + ClearStreamingAudioAsync(cancellationToken).EnsureCompleted(); + } + + #endregion + + #region Audio Turn Management + + /// + /// Starts a new audio input turn. + /// + /// Unique identifier for the input audio turn. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task StartAudioTurnAsync(string turnId, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(turnId, nameof(turnId)); + ThrowIfDisposed(); + + ClientEventInputAudioTurnStart startCommand = new(turnId); + await SendCommandAsync(startCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Starts a new audio input turn. + /// + /// Unique identifier for the input audio turn. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + public virtual void StartAudioTurn(string turnId, CancellationToken cancellationToken = default) + { + StartAudioTurnAsync(turnId, cancellationToken).EnsureCompleted(); + } + + /// + /// Appends audio data to an ongoing input turn. + /// + /// The ID of the turn this audio is part of. + /// The audio data to append. + /// An optional cancellation token. + /// Thrown when or is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task AppendAudioToTurnAsync(string turnId, byte[] audio, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(turnId, nameof(turnId)); + Argument.AssertNotNull(audio, nameof(audio)); + ThrowIfDisposed(); + + string base64Audio = Convert.ToBase64String(audio); + ClientEventInputAudioTurnAppend appendCommand = new(turnId, base64Audio); + await SendCommandAsync(appendCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Appends audio data to an ongoing input turn. + /// + /// The ID of the turn this audio is part of. + /// The audio data to append. + /// An optional cancellation token. + /// Thrown when or is null. + /// Thrown when is empty. + public virtual void AppendAudioToTurn(string turnId, byte[] audio, CancellationToken cancellationToken = default) + { + AppendAudioToTurnAsync(turnId, audio, cancellationToken).EnsureCompleted(); + } + + /// + /// Appends audio data to an ongoing input turn. + /// + /// The ID of the turn this audio is part of. + /// The audio data to append. + /// An optional cancellation token. + /// Thrown when or is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task AppendAudioToTurnAsync(string turnId, BinaryData audio, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(turnId, nameof(turnId)); + Argument.AssertNotNull(audio, nameof(audio)); + ThrowIfDisposed(); + + string base64Audio = Convert.ToBase64String(audio.ToArray()); + ClientEventInputAudioTurnAppend appendCommand = new(turnId, base64Audio); + await SendCommandAsync(appendCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Appends audio data to an ongoing input turn. + /// + /// The ID of the turn this audio is part of. + /// The audio data to append. + /// An optional cancellation token. + /// Thrown when or is null. + /// Thrown when is empty. + public virtual void AppendAudioToTurn(string turnId, BinaryData audio, CancellationToken cancellationToken = default) + { + AppendAudioToTurnAsync(turnId, audio, cancellationToken).EnsureCompleted(); + } + + /// + /// Marks the end of an audio input turn. + /// + /// The ID of the audio turn being ended. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task EndAudioTurnAsync(string turnId, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(turnId, nameof(turnId)); + ThrowIfDisposed(); + + ClientEventInputAudioTurnEnd endCommand = new(turnId); + await SendCommandAsync(endCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Marks the end of an audio input turn. + /// + /// The ID of the audio turn being ended. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + public virtual void EndAudioTurn(string turnId, CancellationToken cancellationToken = default) + { + EndAudioTurnAsync(turnId, cancellationToken).EnsureCompleted(); + } + + /// + /// Cancels an in-progress input audio turn. + /// + /// The ID of the turn to cancel. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task CancelAudioTurnAsync(string turnId, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(turnId, nameof(turnId)); + ThrowIfDisposed(); + + ClientEventInputAudioTurnCancel cancelCommand = new(turnId); + await SendCommandAsync(cancelCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Cancels an in-progress input audio turn. + /// + /// The ID of the turn to cancel. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + public virtual void CancelAudioTurn(string turnId, CancellationToken cancellationToken = default) + { + CancelAudioTurnAsync(turnId, cancellationToken).EnsureCompleted(); + } + + #endregion + + #region Session Configuration + + /// + /// Updates the session configuration. + /// + /// The session configuration options. + /// An optional cancellation token. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task ConfigureSessionAsync(SessionOptions sessionOptions, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(sessionOptions, nameof(sessionOptions)); + ThrowIfDisposed(); + + RequestSession requestSession = sessionOptions.ToRequestSession(); + ClientEventSessionUpdate updateCommand = new(requestSession); + await SendCommandAsync(updateCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Updates the session configuration. + /// + /// The session configuration options. + /// An optional cancellation token. + /// Thrown when is null. + public virtual void ConfigureSession(SessionOptions sessionOptions, CancellationToken cancellationToken = default) + { + ConfigureSessionAsync(sessionOptions, cancellationToken).EnsureCompleted(); + } + + /// + /// Updates the conversation session configuration. + /// + /// The session configuration options. + /// An optional cancellation token. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task ConfigureConversationSessionAsync(SessionOptions sessionOptions, CancellationToken cancellationToken = default) + { + await ConfigureSessionAsync(sessionOptions, cancellationToken).ConfigureAwait(false); + } + + /// + /// Updates the conversation session configuration. + /// + /// The session configuration options. + /// An optional cancellation token. + /// Thrown when is null. + public virtual void ConfigureConversationSession(SessionOptions sessionOptions, CancellationToken cancellationToken = default) + { + ConfigureConversationSessionAsync(sessionOptions, cancellationToken).EnsureCompleted(); + } + + /// + /// Updates the transcription session configuration. + /// + /// The session configuration options. + /// An optional cancellation token. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task ConfigureTranscriptionSessionAsync(SessionOptions sessionOptions, CancellationToken cancellationToken = default) + { + await ConfigureSessionAsync(sessionOptions, cancellationToken).ConfigureAwait(false); + } + + /// + /// Updates the transcription session configuration. + /// + /// The session configuration options. + /// An optional cancellation token. + /// Thrown when is null. + public virtual void ConfigureTranscriptionSession(SessionOptions sessionOptions, CancellationToken cancellationToken = default) + { + ConfigureTranscriptionSessionAsync(sessionOptions, cancellationToken).EnsureCompleted(); + } + + #endregion + + #region Item Management + + /// + /// Adds an item to the conversation. + /// + /// The item to add to the conversation. + /// An optional cancellation token. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task AddItemAsync(ConversationItemWithReference item, CancellationToken cancellationToken = default) + { + await AddItemAsync(item, previousItemId: null, cancellationToken).ConfigureAwait(false); + } + + /// + /// Adds an item to the conversation. + /// + /// The item to add to the conversation. + /// An optional cancellation token. + /// Thrown when is null. + public virtual void AddItem(ConversationItemWithReference item, CancellationToken cancellationToken = default) + { + AddItem(item, previousItemId: null, cancellationToken); + } + + /// + /// Adds an item to the conversation at a specific position. + /// + /// The item to add to the conversation. + /// The ID of the item after which to insert the new item. + /// An optional cancellation token. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task AddItemAsync(ConversationItemWithReference item, string previousItemId, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(item, nameof(item)); + ThrowIfDisposed(); + + // Since the constructor and properties are internal/readonly, we need to + // use the model factory or find another approach + // For now, let's create a simple JSON payload + var itemCreate = new ClientEventConversationItemCreate() + { + Item = item, + PreviousItemId = previousItemId + }; + + await SendCommandAsync(itemCreate, cancellationToken).ConfigureAwait(false); + } + + /// + /// Adds an item to the conversation at a specific position. + /// + /// The item to add to the conversation. + /// The ID of the item after which to insert the new item. + /// An optional cancellation token. + /// Thrown when is null. + public virtual void AddItem(ConversationItemWithReference item, string previousItemId, CancellationToken cancellationToken = default) + { + AddItemAsync(item, previousItemId, cancellationToken).EnsureCompleted(); + } + + /// + /// Retrieves an item from the conversation. + /// + /// The ID of the item to retrieve. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task RequestItemRetrievalAsync(string itemId, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(itemId, nameof(itemId)); + ThrowIfDisposed(); + + ClientEventConversationItemRetrieve retrieveCommand = new(itemId); + await SendCommandAsync(retrieveCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Retrieves an item from the conversation. + /// + /// The ID of the item to retrieve. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + public virtual void RequestItemRetrieval(string itemId, CancellationToken cancellationToken = default) + { + RequestItemRetrievalAsync(itemId, cancellationToken).EnsureCompleted(); + } + + /// + /// Deletes an item from the conversation. + /// + /// The ID of the item to delete. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task DeleteItemAsync(string itemId, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(itemId, nameof(itemId)); + ThrowIfDisposed(); + + ClientEventConversationItemDelete deleteCommand = new(itemId); + await SendCommandAsync(deleteCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Deletes an item from the conversation. + /// + /// The ID of the item to delete. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + public virtual void DeleteItem(string itemId, CancellationToken cancellationToken = default) + { + DeleteItemAsync(itemId, cancellationToken).EnsureCompleted(); + } + + /// + /// Truncates the conversation history. + /// + /// The ID of the item up to which to truncate the conversation. + /// The content index within the item to truncate to. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task TruncateConversationAsync(string itemId, int contentIndex, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(itemId, nameof(itemId)); + ThrowIfDisposed(); + + var truncateEvent = new ClientEventConversationItemTruncate(itemId, contentIndex, 0); + + await SendCommandAsync(truncateEvent, cancellationToken).ConfigureAwait(false); + } + + /// + /// Truncates the conversation history. + /// + /// The ID of the item up to which to truncate the conversation. + /// The content index within the item to truncate to. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + public virtual void TruncateConversation(string itemId, int contentIndex, CancellationToken cancellationToken = default) + { + TruncateConversationAsync(itemId, contentIndex, cancellationToken).EnsureCompleted(); + } + #endregion + + #region Response Management + + /// + /// Starts a new response generation. + /// + /// An optional cancellation token. + /// A task that represents the asynchronous operation. + public virtual async Task StartResponseAsync(CancellationToken cancellationToken = default) + { + await StartResponseAsync(responseOptions: null, cancellationToken).ConfigureAwait(false); + } + + /// + /// Starts a new response generation. + /// + /// An optional cancellation token. + public virtual void StartResponse(CancellationToken cancellationToken = default) + { + StartResponse(responseOptions: null, cancellationToken); + } + + /// + /// Starts a new response generation with specific options. + /// + /// The options for response generation. + /// An optional cancellation token. + /// A task that represents the asynchronous operation. + public virtual async Task StartResponseAsync(ResponseOptions responseOptions, CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + + var responseEvent = new ClientEventResponseCreate() + { + AdditionalInstructions = responseOptions?.Instructions + }; + + await SendCommandAsync(responseEvent, cancellationToken).ConfigureAwait(false); + } + + /// + /// Starts a new response generation with specific options. + /// + /// The options for response generation. + /// An optional cancellation token. + public virtual void StartResponse(ResponseOptions responseOptions, CancellationToken cancellationToken = default) + { + StartResponseAsync(responseOptions, cancellationToken).EnsureCompleted(); + } + + /// + /// Starts a new response generation with additional instructions. + /// + /// Additional instructions for this response. + /// An optional cancellation token. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task StartResponseAsync(string additionalInstructions, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(additionalInstructions, nameof(additionalInstructions)); + ThrowIfDisposed(); + + var response = new ClientEventResponseCreate() + { + AdditionalInstructions = additionalInstructions, + }; + + await SendCommandAsync(response, cancellationToken).ConfigureAwait(false); + } + + /// + /// Starts a new response generation with additional instructions. + /// + /// Additional instructions for this response. + /// An optional cancellation token. + /// Thrown when is null. + public virtual void StartResponse(string additionalInstructions, CancellationToken cancellationToken = default) + { + StartResponseAsync(additionalInstructions, cancellationToken).EnsureCompleted(); + } + + /// + /// Cancels the current response generation. + /// + /// An optional cancellation token. + /// A task that represents the asynchronous operation. + public virtual async Task CancelResponseAsync(CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + + ClientEventResponseCancel cancelCommand = new(); + await SendCommandAsync(cancelCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Cancels the current response generation. + /// + /// An optional cancellation token. + public virtual void CancelResponse(CancellationToken cancellationToken = default) + { + CancelResponseAsync(cancellationToken).EnsureCompleted(); + } + + #endregion + + #region Avatar Management + + /// + /// Connects and provides the client's SDP (Session Description Protocol) for avatar-related media negotiation. + /// + /// The client's SDP offer. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + /// A task that represents the asynchronous operation. + public virtual async Task ConnectAvatarAsync(string clientSdp, CancellationToken cancellationToken = default) + { + Argument.AssertNotNullOrEmpty(clientSdp, nameof(clientSdp)); + ThrowIfDisposed(); + + ClientEventSessionAvatarConnect avatarConnectCommand = new(clientSdp); + await SendCommandAsync(avatarConnectCommand, cancellationToken).ConfigureAwait(false); + } + + /// + /// Connects and provides the client's SDP (Session Description Protocol) for avatar-related media negotiation. + /// + /// The client's SDP offer. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when is empty. + public virtual void ConnectAvatar(string clientSdp, CancellationToken cancellationToken = default) + { + ConnectAvatarAsync(clientSdp, cancellationToken).EnsureCompleted(); + } + + #endregion + } +#pragma warning restore AZC0107 +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Protocol.cs b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Protocol.cs new file mode 100644 index 000000000000..baf336401aac --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Protocol.cs @@ -0,0 +1,108 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ + public partial class VoiceLiveSession + { + /// + /// Initializes an underlying instance for communication with the VoiceLive service and + /// then connects to the service using this socket. + /// + /// The cancellation token to use. + /// A task that represents the asynchronous connection operation. + protected internal virtual async Task ConnectAsync(CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + + WebSocket?.Dispose(); + + var clientWebSocket = new ClientWebSocket(); + + try + { + // Configure the WebSocket connection + //clientWebSocket.Options.AddSubProtocol("voicelive-v1"); + + // Add authorization header + string credentialValue = _credential.Key; + clientWebSocket.Options.SetRequestHeader("api-key", $"{credentialValue}"); + + // Add any additional headers required by the VoiceLive service + clientWebSocket.Options.SetRequestHeader("User-Agent", "Azure-VoiceLive-SDK/.NET"); + + await clientWebSocket.ConnectAsync(_endpoint, cancellationToken).ConfigureAwait(false); + + WebSocket = clientWebSocket; + } + catch + { + clientWebSocket?.Dispose(); + throw; + } + } + + /// + /// Initializes an underlying instance for communication with the VoiceLive service and + /// then connects to the service using this socket. + /// + /// The cancellation token to use. + protected internal virtual void Connect(CancellationToken cancellationToken = default) + { +#pragma warning disable AZC0106 + ConnectAsync(cancellationToken).EnsureCompleted(); +#pragma warning restore AZC0106 + } + + /// + /// Closes the WebSocket connection gracefully. + /// + /// The cancellation token to use. + /// A task that represents the asynchronous close operation. + public virtual async Task CloseAsync(CancellationToken cancellationToken = default) + { + if (WebSocket != null && WebSocket.State == WebSocketState.Open) + { + try + { + await WebSocket.CloseAsync( + WebSocketCloseStatus.NormalClosure, + "Client initiated close", + cancellationToken).ConfigureAwait(false); + } + catch (WebSocketException) + { + // Ignore WebSocket exceptions during close + } + } + } + + /// + /// Closes the WebSocket connection gracefully. + /// + /// The cancellation token to use. + public virtual void Close(CancellationToken cancellationToken = default) + { +#pragma warning disable AZC0107 + CloseAsync(cancellationToken).EnsureCompleted(); +#pragma warning restore AZC0107 + } + + /// + /// Gets the current state of the WebSocket connection. + /// + public WebSocketState ConnectionState => WebSocket?.State ?? WebSocketState.None; + + /// + /// Gets a value indicating whether the session is connected and ready to send/receive messages. + /// + public bool IsConnected => WebSocket?.State == WebSocketState.Open; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Updates.cs b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Updates.cs new file mode 100644 index 000000000000..c13321cdcca5 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.Updates.cs @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Net.WebSockets; +using System.Runtime.CompilerServices; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; +using System.ClientModel.Primitives; + +namespace Azure.AI.VoiceLive +{ + public partial class VoiceLiveSession + { + /// + /// Gets all server events from the VoiceLive service as an asynchronous enumerable. + /// + /// The cancellation token to use. + /// An asynchronous enumerable of VoiceLive server events. + /// + /// This method provides streaming access to all server events from the service, including session events, + /// input audio processing events, response streaming, and error notifications. + /// + /// The method handles WebSocket message fragmentation automatically and ensures that complete + /// messages are processed before yielding events. + /// + public async IAsyncEnumerable GetUpdatesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + + // Ensure we're connected before starting to receive updates + if (WebSocket?.State != WebSocketState.Open) + { + throw new InvalidOperationException("Session must be connected before retrieving updates."); + } + + // Use lock to ensure only one reader at a time + lock (_singleReceiveLock) + { + if (_receiveCollectionResult != null) + { + throw new InvalidOperationException("Only one update enumeration can be active at a time."); + } + + _receiveCollectionResult = new AsyncVoiceLiveMessageCollectionResult(WebSocket, cancellationToken); + } + + try + { + await foreach (BinaryData message in _receiveCollectionResult.WithCancellation(cancellationToken)) + { + // Process the message and yield any server events + foreach (ServerEvent serverEvent in ProcessMessage(message)) + { + yield return serverEvent; + } + } + } + finally + { + lock (_singleReceiveLock) + { + _receiveCollectionResult = null; + } + } + } + + /// + /// Gets all server events from the VoiceLive service synchronously. + /// + /// The cancellation token to use. + /// An enumerable of VoiceLive server events. + /// + /// This method provides synchronous access to all server events from the service. + /// For better performance and resource utilization, consider using instead. + /// + public IEnumerable GetUpdates(CancellationToken cancellationToken = default) + { + return GetUpdatesAsync(cancellationToken).ToBlockingEnumerable(cancellationToken); + } + + /// + /// Gets server events of a specific type from the VoiceLive service. + /// + /// The specific type of server event to filter for. + /// The cancellation token to use. + /// An asynchronous enumerable of server events of the specified type. + public async IAsyncEnumerable GetUpdatesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default) + where T : ServerEvent + { + await foreach (ServerEvent serverEvent in GetUpdatesAsync(cancellationToken).ConfigureAwait(false)) + { + if (serverEvent is T typedEvent) + { + yield return typedEvent; + } + } + } + + /// + /// Waits for the next server event of a specific type. + /// + /// The type of server event to wait for. + /// The cancellation token to use. + /// The next server event of the specified type. + public async Task WaitForUpdateAsync(CancellationToken cancellationToken = default) + where T : ServerEvent + { + await foreach (T serverEvent in GetUpdatesAsync(cancellationToken).ConfigureAwait(false)) + { + return serverEvent; + } + + throw new OperationCanceledException("No server event received before cancellation.", cancellationToken); + } + + /// + /// Processes a WebSocket message and converts it to VoiceLive server events. + /// + /// The message to process. + /// An enumerable of server events extracted from the message. + private IEnumerable ProcessMessage(BinaryData message) + { + if (message == null || message.ToArray().Length == 0) + { + yield break; + } + + ServerEvent serverEvent = null; + try + { + // Try to parse as JSON first + using JsonDocument document = JsonDocument.Parse(message); + JsonElement root = document.RootElement; + + // Deserialize as a server event + serverEvent = ServerEvent.DeserializeServerEvent(root, ModelSerializationExtensions.WireOptions); + } + catch (JsonException) + { + // If JSON parsing fails, ignore the message + yield break; + } + catch (Exception) + { + // If deserialization fails completely, ignore the message + yield break; + } + + if (serverEvent != null) + { + yield return serverEvent; + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.cs b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.cs new file mode 100644 index 000000000000..5b8a9b80def4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/VoiceLiveSession.cs @@ -0,0 +1,376 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Buffers; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.IO; +using System.Net.WebSockets; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ + /// + /// Represents a WebSocket-based session for real-time voice communication with the Azure VoiceLive service. + /// + /// + /// This class abstracts bidirectional communication between the caller and service, + /// simultaneously sending and receiving WebSocket messages. + /// + public partial class VoiceLiveSession : IDisposable, IAsyncDisposable + { + /// + /// Gets the underlying WebSocket connection. + /// + public WebSocket WebSocket { get; protected set; } + + private readonly VoiceLiveClient _parentClient; + private readonly Uri _endpoint; + private readonly AzureKeyCredential _credential; + private readonly SemaphoreSlim _audioSendSemaphore = new(1, 1); + private readonly SemaphoreSlim _clientSendSemaphore = new(1, 1); + private readonly object _singleReceiveLock = new(); + private AsyncVoiceLiveMessageCollectionResult _receiveCollectionResult; + private bool _isSendingAudioStream = false; + private bool _disposed = false; + + /// + /// Gets or sets a value indicating whether turn response data should be buffered. + /// + internal bool ShouldBufferTurnResponseData { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The parent instance. + /// The WebSocket endpoint to connect to. + /// The credential to use for authentication. + protected internal VoiceLiveSession( + VoiceLiveClient parentClient, + Uri endpoint, + AzureKeyCredential credential) + { + Argument.AssertNotNull(parentClient, nameof(parentClient)); + Argument.AssertNotNull(endpoint, nameof(endpoint)); + Argument.AssertNotNull(credential, nameof(credential)); + + _parentClient = parentClient; + _endpoint = endpoint; + _credential = credential; + } + + /// + /// Transmits audio data from a stream, ending the client turn once the stream is complete. + /// + /// The audio stream to transmit. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when another audio stream is already being sent. + /// A task that represents the asynchronous operation. + public virtual async Task SendInputAudioAsync(Stream audio, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(audio, nameof(audio)); + ThrowIfDisposed(); + + using (await _audioSendSemaphore.AutoReleaseWaitAsync(cancellationToken).ConfigureAwait(false)) + { + if (_isSendingAudioStream) + { + throw new InvalidOperationException("Only one stream of audio may be sent at once."); + } + _isSendingAudioStream = true; + } + + byte[] buffer = null; + try + { + buffer = ArrayPool.Shared.Rent(1024 * 16); + while (true) + { + int bytesRead = await audio.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); + if (bytesRead == 0) + { + break; + } + + ReadOnlyMemory audioMemory = buffer.AsMemory(0, bytesRead); + BinaryData audioData = BinaryData.FromBytes(audioMemory); + string base64Audio = Convert.ToBase64String(audioData.ToArray()); + ClientEventInputAudioBufferAppend appendCommand = new(base64Audio); + await SendCommandAsync(appendCommand, cancellationToken).ConfigureAwait(false); + } + } + finally + { + if (buffer is not null) + { + ArrayPool.Shared.Return(buffer); + } + using (await _audioSendSemaphore.AutoReleaseWaitAsync(cancellationToken).ConfigureAwait(false)) + { + _isSendingAudioStream = false; + } + } + } + + /// + /// Transmits audio data from a stream, ending the client turn once the stream is complete. + /// + /// The audio stream to transmit. + /// An optional cancellation token. + /// Thrown when is null. + /// Thrown when another audio stream is already being sent. + public virtual void SendInputAudio(Stream audio, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(audio, nameof(audio)); + ThrowIfDisposed(); + + using (_audioSendSemaphore.AutoReleaseWait(cancellationToken)) + { + if (_isSendingAudioStream) + { + throw new InvalidOperationException("Only one stream of audio may be sent at once."); + } + _isSendingAudioStream = true; + } + + byte[] buffer = null; + try + { + buffer = ArrayPool.Shared.Rent(1024 * 16); + while (true) + { + int bytesRead = audio.Read(buffer, 0, buffer.Length); + if (bytesRead == 0) + { + break; + } + + ReadOnlyMemory audioMemory = buffer.AsMemory(0, bytesRead); + BinaryData audioData = BinaryData.FromBytes(audioMemory); + string base64Audio = Convert.ToBase64String(audioData.ToArray()); + ClientEventInputAudioBufferAppend appendCommand = new(base64Audio); + BinaryData requestData = BinaryData.FromObjectAsJson(appendCommand); + SendCommand(requestData, cancellationToken); + } + } + finally + { + if (buffer is not null) + { + ArrayPool.Shared.Return(buffer); + } + using (_audioSendSemaphore.AutoReleaseWait(cancellationToken)) + { + _isSendingAudioStream = false; + } + } + } + + /// + /// Sends a command to the service asynchronously. + /// + /// The command to send. + /// The cancellation token to use. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + internal virtual async Task SendCommandAsync(ClientEvent command, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(command, nameof(command)); + ThrowIfDisposed(); + + var data = ((IPersistableModel)command).Write(ModelReaderWriterOptions.Json); + await SendCommandAsync(data, cancellationToken).ConfigureAwait(false); + } + + /// + /// Sends a command to the service. + /// + /// The command to send. + /// The cancellation token to use. + /// Thrown when is null. + internal virtual void SendCommand(ClientEvent command, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(command, nameof(command)); + ThrowIfDisposed(); + + BinaryData data = BinaryData.FromObjectAsJson(command); + SendCommand(data, cancellationToken); + } + + /// + /// Sends raw data to the service asynchronously. + /// + /// The data to send. + /// The cancellation token to use. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task SendCommandAsync(BinaryData data, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(data, nameof(data)); + ThrowIfDisposed(); + + ArraySegment messageBytes = new(data.ToArray()); + + await _clientSendSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + try + { + await WebSocket.SendAsync( + messageBytes, + WebSocketMessageType.Text, + endOfMessage: true, + cancellationToken) + .ConfigureAwait(false); + } + finally + { + _clientSendSemaphore.Release(); + } + } + + /// + /// Sends raw data to the service asynchronously. + /// + /// The data to send. + /// The cancellation token to use. + /// Thrown when is null. + /// A task that represents the asynchronous operation. + public virtual async Task SendCommandAsync(RequestContent data, CancellationToken cancellationToken = default) + { + Argument.AssertNotNull(data, nameof(data)); + ThrowIfDisposed(); + + MemoryStream ms = new MemoryStream(); + await data.WriteToAsync(ms, cancellationToken).ConfigureAwait(false); + + ms.Seek(0, SeekOrigin.Begin); + + await SendCommandAsync(BinaryData.FromStream(ms), cancellationToken).ConfigureAwait(false); + } + +#pragma warning disable AZC0107 // Client methods should return approved types + /// + /// Sends raw data to the service. + /// + /// The data to send. + /// The cancellation token to use. + /// Thrown when is null. + public virtual void SendCommand(BinaryData data, CancellationToken cancellationToken = default) + { + // ClientWebSocket does not include a synchronous Send() + SendCommandAsync(data, cancellationToken).EnsureCompleted(); + } +#pragma warning restore AZC0107 + + /// + /// Receives updates from the service asynchronously. + /// + /// The cancellation token to use. + /// An asynchronous enumerable of binary data messages. + public virtual async IAsyncEnumerable ReceiveUpdatesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + + lock (_singleReceiveLock) + { + _receiveCollectionResult ??= new(WebSocket, cancellationToken); + } + + await foreach (BinaryData message in _receiveCollectionResult.WithCancellation(cancellationToken)) + { + yield return message; + } + } + + /// + /// Receives updates from the service. + /// + /// The cancellation token to use. + /// An enumerable of binary data messages. + public virtual IEnumerable ReceiveUpdates(CancellationToken cancellationToken = default) + { + throw new NotSupportedException("Synchronous enumeration of WebSocket messages is not supported. Use ReceiveUpdatesAsync instead."); + } + + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + public async ValueTask DisposeAsync() + { + await DisposeAsyncCore().ConfigureAwait(false); + Dispose(false); + GC.SuppressFinalize(this); + } + + /// + /// Releases the unmanaged resources used by the and optionally releases the managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (!_disposed && disposing) + { + try + { + WebSocket?.Dispose(); + } + catch + { + // Ignore disposal exceptions + } + + _audioSendSemaphore?.Dispose(); + _clientSendSemaphore?.Dispose(); + + _disposed = true; + } + } + + /// + /// Releases the unmanaged resources used by the asynchronously. + /// + /// A task that represents the asynchronous dispose operation. + protected virtual async ValueTask DisposeAsyncCore() + { + if (!_disposed) + { + try + { + if (WebSocket != null && WebSocket.State == WebSocketState.Open) + { + await WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Session disposed", CancellationToken.None) + .ConfigureAwait(false); + } + } + catch + { + // Ignore disposal exceptions + } + + WebSocket?.Dispose(); + _audioSendSemaphore?.Dispose(); + _clientSendSemaphore?.Dispose(); + + _disposed = true; + } + } + + private void ThrowIfDisposed() + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(VoiceLiveSession)); + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncEnumerableExtensions.cs b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncEnumerableExtensions.cs new file mode 100644 index 000000000000..34b9845ca695 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncEnumerableExtensions.cs @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core.Pipeline; + +namespace Azure.AI.VoiceLive +{ + /// + /// Provides extension methods for asynchronous enumerables. + /// + internal static class AsyncEnumerableExtensions + { + /// + /// Converts an IAsyncEnumerable to a blocking enumerable. + /// + /// The type of elements in the enumerable. + /// The async enumerable to convert. + /// The cancellation token to use. + /// A blocking enumerable that will consume the async enumerable. + public static IEnumerable ToBlockingEnumerable(this IAsyncEnumerable asyncEnumerable, CancellationToken cancellationToken = default) + { + return new BlockingEnumerable(asyncEnumerable, cancellationToken); + } + + private sealed class BlockingEnumerable : IEnumerable + { + private readonly IAsyncEnumerable _asyncEnumerable; + private readonly CancellationToken _cancellationToken; + + public BlockingEnumerable(IAsyncEnumerable asyncEnumerable, CancellationToken cancellationToken) + { + _asyncEnumerable = asyncEnumerable ?? throw new ArgumentNullException(nameof(asyncEnumerable)); + _cancellationToken = cancellationToken; + } + + public IEnumerator GetEnumerator() + { + return new BlockingEnumerator(_asyncEnumerable, _cancellationToken); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + + private sealed class BlockingEnumerator : IEnumerator + { + private readonly IAsyncEnumerator _asyncEnumerator; + private readonly CancellationToken _cancellationToken; + private bool _disposed; + + public BlockingEnumerator(IAsyncEnumerable asyncEnumerable, CancellationToken cancellationToken) + { + _asyncEnumerator = asyncEnumerable.GetAsyncEnumerator(cancellationToken); + _cancellationToken = cancellationToken; + } + + public T Current { get; private set; } + + object IEnumerator.Current => Current; + + public bool MoveNext() + { + try + { + var moveNextTask = _asyncEnumerator.MoveNextAsync(); +#pragma warning disable AZC0107 + bool hasNext = moveNextTask.AsTask().EnsureCompleted(); +#pragma warning restore AZC0107 + if (hasNext) + { + Current = _asyncEnumerator.Current; + return true; + } + + Current = default(T); + return false; + } + catch (OperationCanceledException) + { + _cancellationToken.ThrowIfCancellationRequested(); + throw; + } + } + + public void Reset() + { + throw new NotSupportedException(); + } + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; +#pragma warning disable AZC0107 + _asyncEnumerator?.DisposeAsync().AsTask().EnsureCompleted(); +#pragma warning restore AZC0107 + } + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncVoiceLiveMessageCollectionResult.cs b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncVoiceLiveMessageCollectionResult.cs new file mode 100644 index 000000000000..53b8ac9ecf07 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncVoiceLiveMessageCollectionResult.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Net.WebSockets; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// + /// Provides asynchronous enumeration of WebSocket messages as BinaryData. + /// + internal class AsyncVoiceLiveMessageCollectionResult : IAsyncEnumerable + { + private readonly WebSocket _webSocket; + private readonly CancellationToken _cancellationToken; + + /// + /// Initializes a new instance of the class. + /// + /// The WebSocket to collect messages from. + /// The cancellation token to use. + public AsyncVoiceLiveMessageCollectionResult( + WebSocket webSocket, + CancellationToken cancellationToken) + { + Argument.AssertNotNull(webSocket, nameof(webSocket)); + + _webSocket = webSocket; + _cancellationToken = cancellationToken; + } + + /// + public async IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { +#pragma warning disable AZC0100 + await using IAsyncEnumerator enumerator = new AsyncVoiceLiveMessageEnumerator(_webSocket, cancellationToken); +#pragma warning restore AZC0100 + while (await enumerator.MoveNextAsync().ConfigureAwait(false)) + { + yield return enumerator.Current; + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncVoiceLiveMessageEnumerator.cs b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncVoiceLiveMessageEnumerator.cs new file mode 100644 index 000000000000..41baebd5d309 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/AsyncVoiceLiveMessageEnumerator.cs @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// + /// Provides asynchronous enumeration of WebSocket messages as BinaryData. + /// + internal class AsyncVoiceLiveMessageEnumerator : IAsyncEnumerator + { + /// + public BinaryData Current { get; private set; } + + private readonly CancellationToken _cancellationToken; + private readonly WebSocket _webSocket; + private byte[] _receiveBuffer; + + /// + /// Initializes a new instance of the class. + /// + /// The WebSocket to enumerate messages from. + /// The cancellation token to use. + public AsyncVoiceLiveMessageEnumerator(WebSocket webSocket, CancellationToken cancellationToken) + { + Argument.AssertNotNull(webSocket, nameof(webSocket)); + + _webSocket = webSocket; + // Use an 18K buffer size based on traffic observation; the connection will appropriately negotiate and use + // fragmented messages if the buffer size is inadequate. + _receiveBuffer = ArrayPool.Shared.Rent(1024 * 18); + _cancellationToken = cancellationToken; + } + + /// + public ValueTask DisposeAsync() + { + if (Interlocked.Exchange(ref _receiveBuffer, null) is byte[] toReturn) + { + ArrayPool.Shared.Return(toReturn); + } + return default; + } + + /// + public async ValueTask MoveNextAsync() + { + if (_receiveBuffer == null) + { + Current = null; + return false; + } + + try + { + WebSocketPipelineResponse websocketPipelineResponse = new(); + for (int partialMessageCount = 1; !websocketPipelineResponse.IsComplete; partialMessageCount++) + { + WebSocketReceiveResult receiveResult = await _webSocket + .ReceiveAsync(new(_receiveBuffer), _cancellationToken) + .ConfigureAwait(false); + + if (receiveResult.CloseStatus.HasValue) + { + Current = null; + return false; + } + + ReadOnlyMemory receivedBytes = _receiveBuffer.AsMemory(0, receiveResult.Count); + BinaryData receivedData = BinaryData.FromBytes(receivedBytes); + + websocketPipelineResponse.IngestReceivedResult(receiveResult, receivedData); + } + + Current = websocketPipelineResponse.GetContent(); + return true; + } + catch (WebSocketException) + { + Current = null; + return false; + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/SemaphoreSlimExtensions.cs b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/SemaphoreSlimExtensions.cs new file mode 100644 index 000000000000..d9833b541a65 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/SemaphoreSlimExtensions.cs @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Azure.AI.VoiceLive +{ + /// + /// Provides extension methods for to support automatic release patterns. + /// + internal static class SemaphoreSlimExtensions + { + /// + /// Waits asynchronously for the semaphore and returns a disposable that releases it when disposed. + /// + /// The semaphore to wait on. + /// The cancellation token to use. + /// A task that represents the asynchronous wait operation. The task result is a disposable that releases the semaphore. + public static async Task AutoReleaseWaitAsync(this SemaphoreSlim semaphore, CancellationToken cancellationToken = default) + { + await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + return new SemaphoreReleaser(semaphore); + } + + /// + /// Waits for the semaphore and returns a disposable that releases it when disposed. + /// + /// The semaphore to wait on. + /// The cancellation token to use. + /// A disposable that releases the semaphore. + public static IDisposable AutoReleaseWait(this SemaphoreSlim semaphore, CancellationToken cancellationToken = default) + { + semaphore.Wait(cancellationToken); + return new SemaphoreReleaser(semaphore); + } + + private sealed class SemaphoreReleaser : IDisposable + { + private readonly SemaphoreSlim _semaphore; + private bool _disposed; + + public SemaphoreReleaser(SemaphoreSlim semaphore) + { + _semaphore = semaphore ?? throw new ArgumentNullException(nameof(semaphore)); + } + + public void Dispose() + { + if (!_disposed) + { + _semaphore.Release(); + _disposed = true; + } + } + } + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/WebSocketPipelineResponse.cs b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/WebSocketPipelineResponse.cs new file mode 100644 index 000000000000..c3cad22a1024 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/src/WebSocketHelpers/WebSocketPipelineResponse.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable enable + +using System; +using System.IO; +using System.Net.WebSockets; +using Azure.Core; + +namespace Azure.AI.VoiceLive +{ + /// + /// Handles accumulation of WebSocket message data across multiple receive operations. + /// + /// + /// WebSocket messages can be split across multiple network receive operations and a single + /// may thus ingest and present data across several such operations. + /// + internal class WebSocketPipelineResponse + { + private readonly MemoryStream _contentStream = new(); + + /// + /// Gets a value indicating whether the WebSocket message is complete. + /// + public bool IsComplete { get; private set; } = false; + + /// + /// Ingests a received WebSocket result and associated data. + /// + /// The WebSocket receive result. + /// The received data. + public void IngestReceivedResult(WebSocketReceiveResult receivedResult, BinaryData receivedBytes) + { + if (receivedResult.MessageType != WebSocketMessageType.Text) + { + throw new NotSupportedException($"{nameof(WebSocketPipelineResponse)} currently supports only text messages."); + } + + byte[] rawReceivedBytes = receivedBytes.ToArray(); + _contentStream.Position = _contentStream.Length; + _contentStream.Write(rawReceivedBytes, 0, rawReceivedBytes.Length); + _contentStream.Position = 0; + IsComplete = receivedResult.EndOfMessage; + } + + /// + /// Gets the accumulated message content as BinaryData. + /// + /// The complete message content. + public BinaryData GetContent() + { + return BinaryData.FromStream(_contentStream); + } + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/ArgumentValidationTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/ArgumentValidationTests.cs new file mode 100644 index 000000000000..d5c0ed0992ac --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/ArgumentValidationTests.cs @@ -0,0 +1,117 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Comprehensive argument validation tests for public surface area. + /// These verify that null / empty parameters throw the expected or + /// types without performing any live networking. + /// + [TestFixture] + public class ArgumentValidationTests + { + [Test] + public void StartAudioTurnAsync_InvalidTurnIds_Throws() + { + var session = TestSessionFactory.CreateSession(out _); + + // null -> ArgumentNullException + Assert.ThrowsAsync(async () => await session.StartAudioTurnAsync(null)); + // empty -> ArgumentException + Assert.ThrowsAsync(async () => await session.StartAudioTurnAsync(string.Empty)); + } + + [Test] + public void AppendAudioToTurnAsync_InvalidParams_Throws() + { + var session = TestSessionFactory.CreateSession(out _); + + byte[] validAudio = new byte[] { 0x01 }; + + // null turnId + Assert.ThrowsAsync(async () => await session.AppendAudioToTurnAsync(null, validAudio)); + // empty turnId + Assert.ThrowsAsync(async () => await session.AppendAudioToTurnAsync(string.Empty, validAudio)); +#pragma warning disable CS8600 + // null audio + Assert.ThrowsAsync(async () => await session.AppendAudioToTurnAsync("turn1", (byte[])null)); +#pragma warning restore CS8600 + } + + [Test] + public void EndAudioTurnAsync_InvalidTurnId_Throws() + { + var session = TestSessionFactory.CreateSession(out _); + Assert.ThrowsAsync(async () => await session.EndAudioTurnAsync(null)); + Assert.ThrowsAsync(async () => await session.EndAudioTurnAsync(string.Empty)); + } + + [Test] + public void CancelAudioTurnAsync_InvalidTurnId_Throws() + { + var session = TestSessionFactory.CreateSession(out _); + Assert.ThrowsAsync(async () => await session.CancelAudioTurnAsync(null)); + Assert.ThrowsAsync(async () => await session.CancelAudioTurnAsync(string.Empty)); + } + + [Test] + public void TruncateConversationAsync_InvalidItemId_Throws() + { + var session = TestSessionFactory.CreateSession(out _); + Assert.ThrowsAsync(async () => await session.TruncateConversationAsync(null, 0)); + Assert.ThrowsAsync(async () => await session.TruncateConversationAsync(string.Empty, 0)); + } + + [Test] + public void RequestItemRetrievalAsync_InvalidItemId_Throws() + { + var session = TestSessionFactory.CreateSession(out _); + Assert.ThrowsAsync(async () => await session.RequestItemRetrievalAsync(null)); + Assert.ThrowsAsync(async () => await session.RequestItemRetrievalAsync(string.Empty)); + } + + [Test] + public void DeleteItemAsync_InvalidItemId_Throws() + { + var session = TestSessionFactory.CreateSession(out _); + Assert.ThrowsAsync(async () => await session.DeleteItemAsync(null)); + Assert.ThrowsAsync(async () => await session.DeleteItemAsync(string.Empty)); + } + + [Test] + public void SendInputAudioAsync_NullByteArray_Throws() + { + var session = TestSessionFactory.CreateSession(out _); +#pragma warning disable CS8600 + Assert.ThrowsAsync(async () => await session.SendInputAudioAsync((byte[])null)); +#pragma warning restore CS8600 + } + + [Test] + public void SendInputAudioAsync_NullBinaryData_Throws() + { + var session = TestSessionFactory.CreateSession(out _); +#pragma warning disable CS8600 + Assert.ThrowsAsync(async () => await session.SendInputAudioAsync((BinaryData)null)); +#pragma warning restore CS8600 + } + + [Test] + public void StartResponseAsync_NullAdditionalInstructions_Throws() + { + var session = TestSessionFactory.CreateSession(out _); +#pragma warning disable CS8600 + Assert.ThrowsAsync(async () => await session.StartResponseAsync((string)null)); +#pragma warning restore CS8600 + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/Azure.AI.VoiceLive.Tests.csproj b/sdk/ai/Azure.AI.VoiceLive/tests/Azure.AI.VoiceLive.Tests.csproj new file mode 100644 index 000000000000..8ac68ac6e7b1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/Azure.AI.VoiceLive.Tests.csproj @@ -0,0 +1,22 @@ + + + $(RequiredTargetFrameworks) + + $(NoWarn);CS1591 + enable + + + + + + + + + + + + + + + + diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/BasicVoiceAssistantLogicTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/BasicVoiceAssistantLogicTests.cs new file mode 100644 index 000000000000..a124a94b8de4 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/BasicVoiceAssistantLogicTests.cs @@ -0,0 +1,252 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Microsoft.Extensions.Logging; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Unit tests covering BasicVoiceAssistant event handling logic without requiring real audio or WebSocket connections. + /// These tests validate specific reactions to server events by injecting test doubles via reflection. + /// + /// NOTE: BasicVoiceAssistant is located in the samples directory and is not referenced by the test project. + /// These tests provide a blueprint for how such testing could be implemented if the samples were accessible. + /// + [TestFixture] + public class BasicVoiceAssistantLogicTests + { + /// + /// Test double for AudioProcessor that tracks method invocations. + /// This would be used to verify audio-related method calls in BasicVoiceAssistant. + /// + private class TestAudioProcessor : IDisposable + { + public int StartPlaybackAsyncCallCount { get; private set; } + public int StopPlaybackAsyncCallCount { get; private set; } + public int StartCaptureAsyncCallCount { get; private set; } + public int QueueAudioAsyncCallCount { get; private set; } + public int CleanupAsyncCallCount { get; private set; } + public byte[] LastQueuedAudioData { get; private set; } = new byte[0]; + + public Task StartPlaybackAsync() + { + StartPlaybackAsyncCallCount++; + return Task.CompletedTask; + } + + public Task StopPlaybackAsync() + { + StopPlaybackAsyncCallCount++; + return Task.CompletedTask; + } + + public Task StartCaptureAsync() + { + StartCaptureAsyncCallCount++; + return Task.CompletedTask; + } + + public Task QueueAudioAsync(byte[] audioData) + { + QueueAudioAsyncCallCount++; + LastQueuedAudioData = audioData; + return Task.CompletedTask; + } + + public Task CleanupAsync() + { + CleanupAsyncCallCount++; + return Task.CompletedTask; + } + + public void Dispose() + { + // Test implementation - no resources to dispose + } + } + + /// + /// Test double for VoiceLiveSession that tracks method invocations. + /// This would be used to verify session-related method calls in BasicVoiceAssistant. + /// + private class TestVoiceLiveSession : VoiceLiveSession + { + public int CancelResponseAsyncCallCount { get; private set; } + public int ClearStreamingAudioAsyncCallCount { get; private set; } + + public TestVoiceLiveSession(VoiceLiveClient parentClient, Uri endpoint, AzureKeyCredential credential) + : base(parentClient, endpoint, credential) + { + } + + public override async Task CancelResponseAsync(CancellationToken cancellationToken = default) + { + CancelResponseAsyncCallCount++; + await Task.CompletedTask; + } + + public override async Task ClearStreamingAudioAsync(CancellationToken cancellationToken = default) + { + ClearStreamingAudioAsyncCallCount++; + await Task.CompletedTask; + } + } + + [Test] + public void SpeechStartedEvent_CancelsResponseAndClearsStreamingAudio() + { + // This test demonstrates how BasicVoiceAssistant.HandleServerEventAsync would be tested + // if the samples were accessible from the test project. + + Assert.Inconclusive( + "BasicVoiceAssistant is in samples directory and not accessible from tests. " + + "To enable this test: " + + "1. Add project reference to BasicVoiceAssistant sample in test project, OR " + + "2. Move BasicVoiceAssistant to the main SDK with dependency injection support. " + + "Expected behavior: ServerEventInputAudioBufferSpeechStarted should call " + + "CancelResponseAsync(), ClearStreamingAudioAsync(), and StopPlaybackAsync()."); + } + + [Test] + public void SpeechStoppedEvent_StartsPlayback() + { + // This test demonstrates how speech stopped event handling would be verified. + + Assert.Inconclusive( + "BasicVoiceAssistant is in samples directory and not accessible from tests. " + + "To enable this test: " + + "1. Add project reference to BasicVoiceAssistant sample in test project, OR " + + "2. Move BasicVoiceAssistant to the main SDK with dependency injection support. " + + "Expected behavior: ServerEventInputAudioBufferSpeechStopped should call " + + "StartPlaybackAsync() on the AudioProcessor."); + } + + [Test] + public void ResponseAudioDeltaEvent_QueuesAudio() + { + // This test demonstrates how audio delta event handling would be verified. + + Assert.Inconclusive( + "BasicVoiceAssistant is in samples directory and not accessible from tests. " + + "To enable this test: " + + "1. Add project reference to BasicVoiceAssistant sample in test project, OR " + + "2. Move BasicVoiceAssistant to the main SDK with dependency injection support. " + + "Expected behavior: ServerEventResponseAudioDelta with non-empty delta should call " + + "QueueAudioAsync() with the decoded audio data."); + } + + [Test] + public void ReflectionObstacles_ProduceInconclusiveResults() + { + // This test documents the recommended changes to improve testability + // if BasicVoiceAssistant were accessible. + + Assert.Inconclusive( + "BasicVoiceAssistant testing obstacles and recommended solutions: " + + "1. OBSTACLE: BasicVoiceAssistant is in samples directory, not accessible from tests. " + + " SOLUTION: Add project reference or move to main SDK. " + + "2. OBSTACLE: AudioProcessor is concrete class with no interface. " + + " SOLUTION: Introduce IAudioProcessor interface and constructor injection. " + + "3. OBSTACLE: HandleServerEventAsync is private method. " + + " SOLUTION: Make method protected virtual for better testability. " + + "4. OBSTACLE: _audioProcessor and _session fields are private. " + + " SOLUTION: Use dependency injection pattern instead of direct instantiation. " + + "These changes would enable comprehensive unit testing without reflection."); + } + + [Test] + public void ServerEventCreation_ValidatesEventFactory() + { + // This test validates that we can create the server events needed for testing + // and demonstrates the event creation patterns. + + // Create speech started event + var speechStartedEvent = VoiceLiveModelFactory.ServerEventInputAudioBufferSpeechStarted( + eventId: "evt-1", + audioStartMs: 100, + itemId: "item-1"); + + Assert.That(speechStartedEvent, Is.Not.Null); + Assert.That(speechStartedEvent.Type.ToString(), Is.EqualTo("input_audio_buffer.speech_started")); + Assert.That(speechStartedEvent.ItemId, Is.EqualTo("item-1")); + + // Create speech stopped event + var speechStoppedEvent = VoiceLiveModelFactory.ServerEventInputAudioBufferSpeechStopped( + eventId: "evt-2", + audioEndMs: 2000, + itemId: "item-2"); + + Assert.That(speechStoppedEvent, Is.Not.Null); + Assert.That(speechStoppedEvent.Type.ToString(), Is.EqualTo("input_audio_buffer.speech_stopped")); + Assert.That(speechStoppedEvent.ItemId, Is.EqualTo("item-2")); + + // Create audio delta event with test data + var testAudioData = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + var audioDelta = BinaryData.FromBytes(testAudioData); + + var responseAudioDeltaEvent = VoiceLiveModelFactory.ServerEventResponseAudioDelta( + eventId: "evt-3", + responseId: "resp-1", + itemId: "item-3", + outputIndex: 0, + contentIndex: 0, + delta: audioDelta); + + Assert.That(responseAudioDeltaEvent, Is.Not.Null); + Assert.That(responseAudioDeltaEvent.Type.ToString(), Is.EqualTo("response.audio.delta")); + Assert.That(responseAudioDeltaEvent.Delta, Is.Not.Null); + Assert.That(responseAudioDeltaEvent.Delta.ToArray(), Is.EqualTo(testAudioData)); + + Assert.Pass("All server events can be created successfully for testing purposes."); + } + + [Test] + public void TestDoubles_ProvideExpectedBehavior() + { + // This test validates that the test doubles behave as expected + // and could be used effectively in BasicVoiceAssistant tests. + + var testAudioProcessor = new TestAudioProcessor(); + var testSession = new TestVoiceLiveSession( + new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")), + new Uri("wss://example.org/voice-agent/realtime"), + new AzureKeyCredential("test-key")); + + // Test AudioProcessor test double + Assert.That(testAudioProcessor.StartPlaybackAsyncCallCount, Is.EqualTo(0)); + _ = testAudioProcessor.StartPlaybackAsync(); + Assert.That(testAudioProcessor.StartPlaybackAsyncCallCount, Is.EqualTo(1)); + + Assert.That(testAudioProcessor.StopPlaybackAsyncCallCount, Is.EqualTo(0)); + _ = testAudioProcessor.StopPlaybackAsync(); + Assert.That(testAudioProcessor.StopPlaybackAsyncCallCount, Is.EqualTo(1)); + + var testAudioData = new byte[] { 0x01, 0x02 }; + _ = testAudioProcessor.QueueAudioAsync(testAudioData); + Assert.That(testAudioProcessor.QueueAudioAsyncCallCount, Is.EqualTo(1)); + Assert.That(testAudioProcessor.LastQueuedAudioData, Is.EqualTo(testAudioData)); + + // Test VoiceLiveSession test double + Assert.That(testSession.CancelResponseAsyncCallCount, Is.EqualTo(0)); + _ = testSession.CancelResponseAsync(); + Assert.That(testSession.CancelResponseAsyncCallCount, Is.EqualTo(1)); + + Assert.That(testSession.ClearStreamingAudioAsyncCallCount, Is.EqualTo(0)); + _ = testSession.ClearStreamingAudioAsync(); + Assert.That(testSession.ClearStreamingAudioAsyncCallCount, Is.EqualTo(1)); + + testSession.Dispose(); + testAudioProcessor.Dispose(); + + Assert.Pass("Test doubles behave correctly and are ready for use in BasicVoiceAssistant testing."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/FunctionCallingFlowTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/FunctionCallingFlowTests.cs new file mode 100644 index 000000000000..2c9e089b9cc1 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/FunctionCallingFlowTests.cs @@ -0,0 +1,166 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Tests focused on function calling configuration and execution flow patterns. While a dedicated + /// CustomerServiceBot helper is not yet present, we validate the key synthetic workflow a bot would + /// perform after a response.function_call.arguments.done server event (emitting a function_call_output + /// item then requesting a new response). A remaining placeholder covers assistant message tracking + /// awaiting future helper implementation. + /// + [TestFixture] + public class FunctionCallingFlowTests + { + private static List GetSentMessagesOfType(FakeWebSocket socket, string type) + { + return TestUtilities.GetMessagesOfType(socket, type); + } + + [Test] + public async Task ConfigureConversationSession_WithFunctionTools_RegistersAll() + { + var session = TestSessionFactory.CreateSessionWithFakeSocket(out var fake); + + var options = new SessionOptions + { + Model = TestConstants.ModelName, + Voice = new AzureStandardVoice(TestConstants.VoiceName, AzureStandardVoiceType.AzureStandard) + }; + + // Five sample tools (names only sufficient for serialization validation) + options.Tools.Add(new FunctionTool("get_account_balance") { Description = "Gets the customer's account balance." }); + options.Tools.Add(new FunctionTool("lookup_order_status") { Description = "Retrieves the status of an order." }); + options.Tools.Add(new FunctionTool("submit_support_ticket") { Description = "Submits a support ticket." }); + options.Tools.Add(new FunctionTool("apply_refund") { Description = "Applies a refund to an order." }); + options.Tools.Add(new FunctionTool("escalate_case") { Description = "Escalates the current case." }); + + await session.ConfigureConversationSessionAsync(options); + + var updateMessages = GetSentMessagesOfType(fake, "session.update"); + Assert.That(updateMessages, Is.Not.Empty, "Expected a session.update message containing tools."); + + using var last = updateMessages.Last(); + var sessionEl = last.RootElement.GetProperty("session"); + Assert.That(sessionEl.TryGetProperty("tools", out var toolsEl), Is.True, "tools array missing in session.update payload"); + var toolNames = toolsEl.EnumerateArray().Select(t => t.GetProperty("name").GetString()).Where(n => n != null).ToArray(); + Assert.That(toolNames.Length, Is.EqualTo(5), "Expected all 5 tools to be serialized."); + Assert.That(toolNames, Is.EquivalentTo(new[] + { + "get_account_balance", + "lookup_order_status", + "submit_support_ticket", + "apply_refund", + "escalate_case" + })); + + // Dispose other docs not used further + foreach (var d in updateMessages.Where(d => d != last)) d.Dispose(); + } + + [Test] + public async Task FunctionCallArgumentsDone_SyntheticFlow_SendsFunctionCallOutputThenResponseCreate() + { + // This synthetic test simulates the core pieces of the intended bot workflow *without* the + // yet-to-be-added CustomerServiceBot implementation. It validates that after parsing a + // response.function_call.arguments.done server event, a caller could: (a) execute a local + // function, (b) send the function_call_output as a conversation item, and (c) request a + // follow-up assistant response, ensuring ordering of emitted client events. + var session = TestSessionFactory.CreateSessionWithFakeSocket(out var fake); + + // Pretend we received a server event instructing a function call. + string callId = "call-123"; + string functionName = "get_account_balance"; + string argumentsJson = "{ \"accountId\": \"abc\" }"; + string eventJson = TestUtilities.BuildResponseFunctionCallArgumentsDoneEvent(functionName, callId, argumentsJson); + + // Parse to ensure the model factory path works for this event type. + var serverEvent = ServerEvent.DeserializeServerEvent(JsonDocument.Parse(eventJson).RootElement, ModelSerializationExtensions.WireOptions); + Assert.That(serverEvent, Is.TypeOf()); + var fDone = (ServerEventResponseFunctionCallArgumentsDone)serverEvent; + Assert.That(fDone.Name, Is.EqualTo(functionName)); + Assert.That(fDone.CallId, Is.EqualTo(callId)); + + // Simulate executing the function locally -> returns object { success = true, value = 42 } + var functionResultJson = JsonSerializer.Serialize(new { success = true, value = 42 }); + + // Send function_call_output conversation item referencing callId + var functionOutputItem = new ConversationItemWithReference + { + Id = "func-output-" + callId, + Type = ConversationItemWithReferenceType.FunctionCallOutput, + CallId = callId, + Output = functionResultJson + }; + await session.AddItemAsync(functionOutputItem); + + // Request next model response + await session.StartResponseAsync(); + + // Assertions: ensure conversation.item.create precedes response.create + var sent = fake.GetSentTextMessages().ToList(); + int createIndex = -1; + int responseIndex = -1; + for (int i = 0; i < sent.Count; i++) + { + var msg = sent[i]; + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + using var doc = JsonDocument.Parse(msg); + if (!doc.RootElement.TryGetProperty("type", out var tProp) || tProp.ValueKind != JsonValueKind.String) continue; + var typeVal = tProp.GetString(); + if (typeVal == "conversation.item.create" && createIndex == -1) + { + createIndex = i; + // Validate this is the function_call_output item with our call id + Assert.That(doc.RootElement.TryGetProperty("item", out var itemEl), Is.True, "item missing in create payload"); + Assert.That(itemEl.TryGetProperty("call_id", out var callIdEl), Is.True, "call_id missing in item"); + Assert.That(callIdEl.GetString(), Is.EqualTo(callId)); + Assert.That(itemEl.TryGetProperty("output", out var outputEl), Is.True, "output missing"); + // Basic structural assertion on output JSON string contents + StringAssert.Contains("\"value\":42", outputEl.GetString()); + } + if (typeVal == "response.create" && responseIndex == -1) + { + responseIndex = i; + } + } + catch (JsonException) + { + // ignore non-json frame + } + } + + if (createIndex == -1 || responseIndex == -1) + { + Assert.Fail("Did not observe expected conversation.item.create and response.create messages in synthetic flow."); + } + + Assert.That(createIndex, Is.LessThan(responseIndex), "function_call_output item must be emitted before response.create in synthetic handling flow"); + } + + [Test, Ignore("CustomerServiceBot not available; cannot track assistant message response id mapping. When available, test will assert that only tracked assistant response ids influence transcript delta handling.")] + public async Task ResponseOutputItemAdded_AssistantMessageTracked() + { + // Placeholder steps for future enablement: + // 1. Instantiate CustomerServiceBot + session with FakeWebSocket + // 2. Inject a response.output_item.added event containing an assistant 'message' item (track its response id) + // 3. Send a response.audio.transcript.delta event for both tracked and untracked response ids + // 4. Use reflection to inspect internal hash set / logging side-effects to ensure only tracked id processed + await Task.CompletedTask; + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/FakeWebSocket.cs b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/FakeWebSocket.cs new file mode 100644 index 000000000000..498b570dc7e6 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/FakeWebSocket.cs @@ -0,0 +1,222 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Buffers; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Azure.AI.VoiceLive.Tests.Infrastructure +{ + /// + /// A simple in-memory implementation used by unit tests to: + /// 1. Capture all outbound messages sent by the client under test. + /// 2. Provide a scriptable queue of inbound messages delivered via . + /// + /// This implementation purposefully keeps the surface minimal and only supports text frames + /// (binary and fragmented frames are not required for the VoiceLive unit test scenarios). + /// + internal sealed class FakeWebSocket : WebSocket + { + private readonly ConcurrentQueue _inboundQueue = new ConcurrentQueue(); + private readonly List _sentMessages = new List(); + private readonly object _sentLock = new object(); + private readonly SemaphoreSlim _sendSignal = new SemaphoreSlim(0, int.MaxValue); // Signals a newly sent message. + private readonly CancellationTokenSource _lifecycleCts = new CancellationTokenSource(); + + private WebSocketState _state = WebSocketState.Open; + private WebSocketCloseStatus? _closeStatus; + private string? _closeStatusDescription; + private int _disposed; // 0 = false, 1 = true + + /// + /// Enqueues a text message that will be returned by the next call. + /// + /// The textual payload (typically JSON) to deliver to the client. + public void EnqueueTextMessage(string json) + { + if (json == null) throw new ArgumentNullException(nameof(json)); + ThrowIfDisposed(); + _inboundQueue.Enqueue(json); + } + + /// + /// Returns a snapshot of the UTF-8 text messages that have been sent through . + /// + public IReadOnlyList GetSentTextMessages() + { + lock (_sentLock) + { + return _sentMessages.ToArray(); + } + } + + /// + /// Waits until at least messages have been sent, or the elapses. + /// + /// Thrown if the condition is not satisfied within the timeout. + public async Task WaitForAtLeastAsync(int count, TimeSpan timeout) + { + if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); + if (timeout <= TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(timeout)); + ThrowIfDisposed(); + + var deadline = DateTime.UtcNow + timeout; + while (true) + { + int current; + lock (_sentLock) + { + current = _sentMessages.Count; + if (current >= count) + { + return; + } + } + + var remaining = deadline - DateTime.UtcNow; + if (remaining <= TimeSpan.Zero) + { + throw new TimeoutException($"Timed out waiting for at least {count} sent messages."); + } + + // Wait until another message is sent or timeout. + var wait = remaining < TimeSpan.FromMilliseconds(250) ? remaining : TimeSpan.FromMilliseconds(250); + try + { + await _sendSignal.WaitAsync(wait, _lifecycleCts.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) when (_lifecycleCts.IsCancellationRequested) + { + throw new ObjectDisposedException(nameof(FakeWebSocket)); + } + } + } + + /// + public override WebSocketCloseStatus? CloseStatus => _closeStatus; + + /// + public override string? CloseStatusDescription => _closeStatusDescription; + + /// + public override WebSocketState State => _state; + + /// + public override string? SubProtocol => null; + + /// + public override void Abort() + { + if (_state == WebSocketState.Aborted || _state == WebSocketState.Closed) return; + _state = WebSocketState.Aborted; + _lifecycleCts.Cancel(); + } + + /// + public override Task CloseAsync(WebSocketCloseStatus closeStatus, string? statusDescription, CancellationToken cancellationToken) + { + if (_state == WebSocketState.Closed) return Task.CompletedTask; + _closeStatus = closeStatus; + _closeStatusDescription = statusDescription; + _state = WebSocketState.Closed; + _lifecycleCts.Cancel(); + return Task.CompletedTask; + } + + /// + public override Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string? statusDescription, CancellationToken cancellationToken) + { + if (_state == WebSocketState.Closed || _state == WebSocketState.CloseSent) return Task.CompletedTask; + _closeStatus = closeStatus; + _closeStatusDescription = statusDescription; + _state = WebSocketState.CloseSent; + return Task.CompletedTask; + } + + /// + public override async Task ReceiveAsync(ArraySegment buffer, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + if (buffer.Array == null) throw new ArgumentException("Buffer must have a backing array", nameof(buffer)); + + while (true) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (_state != WebSocketState.Open && _inboundQueue.IsEmpty) + { + // Return a 0-length close if closed and no data remains. + return new WebSocketReceiveResult(0, WebSocketMessageType.Text, endOfMessage: true, _closeStatus, _closeStatusDescription); + } + + if (_inboundQueue.TryDequeue(out var message)) + { + var bytes = Encoding.UTF8.GetBytes(message); + if (bytes.Length > buffer.Count) + { + throw new InvalidOperationException($"Provided receive buffer too small. Needed {bytes.Length}, had {buffer.Count}."); + } + + Array.Copy(bytes, 0, buffer.Array, buffer.Offset, bytes.Length); + return new WebSocketReceiveResult(bytes.Length, WebSocketMessageType.Text, endOfMessage: true); + } + + // Brief delay to avoid busy loop; integrate cancellation. + try + { + await Task.Delay(10, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + throw; // propagate per requirements. + } + } + } + + /// + public override Task SendAsync(ArraySegment buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + if (_state != WebSocketState.Open) + { + throw new InvalidOperationException("Cannot send when WebSocket is not open."); + } + + if (messageType == WebSocketMessageType.Text) + { + if (buffer.Array == null) throw new ArgumentException("Buffer must have a backing array", nameof(buffer)); + var text = Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count); + lock (_sentLock) + { + _sentMessages.Add(text); + } + _sendSignal.Release(); + } + // Binary & Close frames are ignored for current test needs. + return Task.CompletedTask; + } + + /// + public override void Dispose() + { + if (Interlocked.Exchange(ref _disposed, 1) == 1) return; + _state = WebSocketState.Closed; + _lifecycleCts.Cancel(); + _lifecycleCts.Dispose(); + _sendSignal.Dispose(); + } + + private void ThrowIfDisposed() + { + if (Volatile.Read(ref _disposed) == 1) + { + throw new ObjectDisposedException(nameof(FakeWebSocket)); + } + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestConstants.cs b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestConstants.cs new file mode 100644 index 000000000000..898b6fa7df72 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestConstants.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.AI.VoiceLive.Tests.Infrastructure +{ + /// + /// Constants used across the VoiceLive unit tests. + /// + public static class TestConstants + { + public const string ModelName = "gpt-4o-mini-realtime-preview"; + public const string VoiceName = "en-US-AvaNeural"; + public const string DefaultLocale = "en-US"; + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestLogger.cs b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestLogger.cs new file mode 100644 index 000000000000..9d07b05752c7 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestLogger.cs @@ -0,0 +1,183 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma warning disable SA1402 // File may only contain a single type + +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; + +namespace Azure.AI.VoiceLive.Tests.Infrastructure +{ + /// + /// A non-generic test logger capturing log entries in-memory. All instances created from a + /// share the same underlying sink so that tests can assert against a consolidated log history. + /// + public sealed class TestLogger : ILogger + { + private readonly string _categoryName; + private readonly List _sink; + private readonly object _syncRoot; + private readonly LogLevel _minimumLevel; + + internal TestLogger(string categoryName, List sink, object syncRoot, LogLevel minimumLevel) + { + _categoryName = categoryName; + _sink = sink; + _syncRoot = syncRoot; + _minimumLevel = minimumLevel; + } + + /// + /// Returns a snapshot list of the current log entries. The returned list will not update after enumeration. + /// + public IReadOnlyList Entries + { + get + { + lock (_syncRoot) + { + return _sink.Count == 0 ? Array.Empty() : new List(_sink); + } + } + } + + public IDisposable BeginScope(TState state) where TState : notnull => NullScope.Instance; + + public bool IsEnabled(LogLevel logLevel) => logLevel >= _minimumLevel; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + if (!IsEnabled(logLevel)) + { + return; + } + + string? message = null; + try + { + if (formatter != null) + { + message = formatter(state, exception); + } + else if (state != null) + { + message = state.ToString(); + } + } + catch + { + // Swallow any formatter exceptions so tests don't fail due to logging errors. + } + + var entry = new LogEntry(logLevel, eventId, message, exception, state); + lock (_syncRoot) + { + _sink.Add(entry); + } + } + + /// + /// Simple disposable used for BeginScope which performs no action. + /// + internal sealed class NullScope : IDisposable + { + public static readonly NullScope Instance = new NullScope(); + private NullScope() { } + public void Dispose() { } + } + } + + /// + /// Generic variant that supplies the category name based on . + /// + /// The category type. + public sealed class TestLogger : ILogger + { + private readonly TestLogger _inner; + + internal TestLogger(TestLogger inner) + { + _inner = inner; + } + + /// + /// Exposes the captured log entries (same shared sink as other loggers from the factory). + /// + public IReadOnlyList Entries => _inner.Entries; + + public IDisposable BeginScope(TState state) where TState : notnull => _inner.BeginScope(state); + public bool IsEnabled(LogLevel logLevel) => _inner.IsEnabled(logLevel); + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + => _inner.Log(logLevel, eventId, state, exception, formatter); + } + + /// + /// Represents a single captured log entry for assertions in tests. + /// + /// The of the log entry. + /// The associated with the entry. + /// The formatted message text (may be null). + /// The exception captured with the log entry (may be null). + /// The original state object supplied to the logger (may be null). + public record LogEntry(LogLevel Level, EventId EventId, string? Message, Exception? Exception, object? State); + + /// + /// Factory for creating instances that produce and loggers + /// writing into a shared in-memory sink. Intended for use in unit tests. + /// + public static class TestLoggerFactory + { + /// + /// Creates an that supplies test loggers which write into a shared sink. + /// + /// Outputs the shared list capturing all log entries produced by loggers from the returned factory. + /// Optional minimum ; entries below this level are ignored. Defaults to . + /// The configured . + public static ILoggerFactory Create(out List sink, LogLevel minimumLevel = LogLevel.Trace) + { + sink = new List(); + return new InMemoryLoggerFactory(sink, minimumLevel); + } + + private sealed class InMemoryLoggerFactory : ILoggerFactory + { + private readonly List _sink; + private readonly object _syncRoot = new object(); + private readonly LogLevel _minimumLevel; + private bool _disposed; + + public InMemoryLoggerFactory(List sink, LogLevel minimumLevel) + { + _sink = sink ?? throw new ArgumentNullException(nameof(sink)); + _minimumLevel = minimumLevel; + } + + public ILogger CreateLogger(string categoryName) + { + EnsureNotDisposed(); + var core = new TestLogger(categoryName, _sink, _syncRoot, _minimumLevel); + return core; + } + + public void AddProvider(ILoggerProvider provider) + { + // External providers are not supported; ignoring keeps behavior simple for tests. + } + + public void Dispose() + { + _disposed = true; + } + + private void EnsureNotDisposed() + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(InMemoryLoggerFactory)); + } + } + } + } +} +#pragma warning restore SA1402 // File may only contain a single type diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestSessionFactory.cs b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestSessionFactory.cs new file mode 100644 index 000000000000..fbe5625903e3 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestSessionFactory.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Azure.Core; + +namespace Azure.AI.VoiceLive.Tests.Infrastructure +{ + /// + /// Factory methods for creating test sessions with injected instances. + /// Provides consistent test setup patterns across all VoiceLive unit tests. + /// + internal static class TestSessionFactory + { + /// + /// Creates a with an injected + /// for testing purposes. The session is configured with test URIs and credentials. + /// + /// Outputs the injected instance for test assertions. + /// A configured ready for testing. + internal static TestableVoiceLiveSession CreateSessionWithFakeSocket(out FakeWebSocket fakeSocket) + { + var client = new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")); + var session = new TestableVoiceLiveSession(client, new Uri("wss://example.org/voice-agent/realtime"), new AzureKeyCredential("test-key")); + fakeSocket = new FakeWebSocket(); + session.SetWebSocket(fakeSocket); + return session; + } + + /// + /// Creates a with an injected + /// for testing purposes. This overload uses a shorter method name for compatibility with existing tests. + /// + /// Outputs the injected instance for test assertions. + /// A configured ready for testing. + internal static TestableVoiceLiveSession CreateSession(out FakeWebSocket socket) + { + return CreateSessionWithFakeSocket(out socket); + } + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestUtilities.cs b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestUtilities.cs new file mode 100644 index 000000000000..46b7019efd83 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestUtilities.cs @@ -0,0 +1,325 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.Json; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests.Infrastructure +{ + /// + /// Shared helpers used across unit tests for crafting minimal server event JSON payloads and + /// performing common JSON assertions. + /// + public static class TestUtilities + { + private static readonly JsonSerializerOptions s_defaultJsonOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = null, + WriteIndented = false + }; + + /// + /// Builds a JSON string representing a generic server event: {"type":"", ... }. + /// Any additional properties defined on are merged into the + /// top-level object. Properties named "type" in the extra object are ignored to avoid collisions. + /// + /// The event type value. + /// An anonymous object supplying additional properties (may be null). + /// The merged JSON string. + public static string BuildServerEvent(string type, object anonymousPayloadExtra) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + + using var ms = new MemoryStream(); + using (var writer = new Utf8JsonWriter(ms, new JsonWriterOptions { Indented = false })) + { + writer.WriteStartObject(); + writer.WriteString("type", type); + + if (anonymousPayloadExtra != null) + { + // Serialize the extra object then merge its top-level properties. + var extraJson = JsonSerializer.SerializeToUtf8Bytes(anonymousPayloadExtra, s_defaultJsonOptions); + using var extraDoc = JsonDocument.Parse(extraJson); + if (extraDoc.RootElement.ValueKind == JsonValueKind.Object) + { + foreach (var prop in extraDoc.RootElement.EnumerateObject()) + { + if (prop.NameEquals("type")) + { + continue; // Preserve the explicit type parameter. + } + prop.WriteTo(writer); + } + } + else + { + // If the extra payload isn't an object, expose it as a property named "payload". + writer.WritePropertyName("payload"); + extraDoc.RootElement.WriteTo(writer); + } + } + + writer.WriteEndObject(); + } + return Encoding.UTF8.GetString(ms.ToArray()); + } + + /// + /// Constructs a minimal valid session.created server event JSON payload. + /// Schema: {"type":"session.created","session":{"id":""}} + /// + /// The session identifier (defaults to "session-123"). + public static string BuildSessionCreatedEvent(string sessionId = "session-123") + { + if (sessionId == null) throw new ArgumentNullException(nameof(sessionId)); + return "{\"type\":\"session.created\",\"session\":{\"id\":\"{EscapeString(sessionId)}\"}}"; + } + + /// + /// Constructs a minimal response.audio.delta event. + /// Schema: {"type":"response.audio.delta","delta":""} + /// + public static string BuildResponseAudioDeltaEvent(string base64Audio = "AAAA") + { + if (base64Audio == null) throw new ArgumentNullException(nameof(base64Audio)); + return "{\"type\":\"response.audio.delta\",\"delta\":\"{EscapeString(base64Audio)}\"}"; + } + + /// + /// Constructs a response.function_call.arguments.done event. + /// Schema: {"type":"response.function_call.arguments.done","name":"","call_id":"","arguments":""} + /// + /// The function name. + /// The function call identifier. + /// The raw JSON string (kept as a literal string value in the payload). + public static string BuildResponseFunctionCallArgumentsDoneEvent(string name, string callId, string argumentsJson) + { + if (name == null) throw new ArgumentNullException(nameof(name)); + if (callId == null) throw new ArgumentNullException(nameof(callId)); + if (argumentsJson == null) throw new ArgumentNullException(nameof(argumentsJson)); + return $"{{\"type\":\"response.function_call_arguments.done\",\"name\":\"{EscapeString(name)}\",\"call_id\":\"{EscapeString(callId)}\",\"arguments\":\"{EscapeString(argumentsJson)}\"}}"; + } + + /// + /// Constructs a minimal assistant message output item added event. + /// Sample structure: + /// { + /// "type":"response.output_item.added", + /// "response_id":"", + /// "item":{ + /// "id":"", + /// "type":"message", + /// "role":"assistant", + /// "content":[] + /// } + /// } + /// + /// The output item id. + /// The response id to associate. + public static string BuildResponseOutputItemAdded_AssistantMessage(string itemId, string responseId) + { + if (itemId == null) throw new ArgumentNullException(nameof(itemId)); + if (responseId == null) throw new ArgumentNullException(nameof(responseId)); + return "{\"type\":\"response.output_item.added\",\"response_id\":\"{EscapeString(responseId)}\",\"item\":{\"id\":\"{EscapeString(itemId)}\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[]}}"; + } + + /// + /// Parses a collection of JSON textual payloads into a list of instances for assertion. + /// Caller is responsible for disposing the returned documents when finished (tests can rely on teardown). + /// + /// Enumerable of JSON strings. + public static List ParseSentPayloads(IEnumerable messages) + { + if (messages == null) throw new ArgumentNullException(nameof(messages)); + var docs = new List(); + foreach (var m in messages) + { + if (string.IsNullOrWhiteSpace(m)) + { + continue; // Skip empty frames. + } + docs.Add(JsonDocument.Parse(m)); + } + return docs; + } + + /// + /// Asserts that the supplied JSON element contains a property specified by a dotted path (e.g. "session.id"). + /// Each segment must correspond to an object property (arrays are not traversed by this helper). + /// + /// The root JSON element. + /// Dot-delimited property path. + public static void AssertJsonHasProperty(JsonElement root, string dottedPath) + { + if (dottedPath == null) throw new ArgumentNullException(nameof(dottedPath)); + var segments = dottedPath.Split(new char[] {'.'},StringSplitOptions.RemoveEmptyEntries ); + if (segments.Length == 0) + { + Assert.Fail("Path must contain at least one segment."); + } + + JsonElement current = root; + var traversed = new List(); + foreach (var segment in segments) + { + traversed.Add(segment); + if (current.ValueKind != JsonValueKind.Object) + { + Assert.Fail($"Segment '{segment}' expected an object at path '{string.Join(".", traversed.Take(traversed.Count - 1))}' but found {current.ValueKind}."); + } + if (!current.TryGetProperty(segment, out var next)) + { + var available = string.Join(",", current.EnumerateObject().Select(p => p.Name)); + Assert.Fail($"Property '{segment}' not found at path '{string.Join(".", traversed.Take(traversed.Count - 1))}'. Available: [{available}]"); + } + current = next; + } + } + + /// + /// Returns the top-level "type" property value if present; otherwise null. + /// + public static string? GetTopLevelType(JsonElement root) + { + if (root.ValueKind == JsonValueKind.Object && root.TryGetProperty("type", out var val) && val.ValueKind == JsonValueKind.String) + { + return val.GetString(); + } + return null; + } + + /// + /// Filters sent messages from a by message type and returns them as parsed instances. + /// Caller is responsible for disposing the returned documents when finished (tests can rely on teardown). + /// + /// The fake WebSocket containing sent messages. + /// The message type to filter by (e.g., "session.update", "input_audio_buffer.append"). + /// A list of instances matching the specified type. + internal static List GetMessagesOfType(FakeWebSocket socket, string type) + { + if (socket == null) throw new ArgumentNullException(nameof(socket)); + if (type == null) throw new ArgumentNullException(nameof(type)); + + var list = new List(); + foreach (var msg in socket.GetSentTextMessages()) + { + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + var doc = JsonDocument.Parse(msg); + if (GetTopLevelType(doc.RootElement) == type) + { + list.Add(doc); + } + else + { + doc.Dispose(); + } + } + catch (JsonException) + { + // Skip invalid JSON + } + } + return list; + } + + /// + /// Gets the last sent message from a that matches the specified type. + /// Returns null if no matching message is found. + /// Caller is responsible for disposing the returned document when finished. + /// + /// The fake WebSocket containing sent messages. + /// The message type to filter by (e.g., "session.update", "input_audio_buffer.append"). + /// The last matching the specified type, or null if none found. + internal static JsonDocument? GetLastMessageOfType(FakeWebSocket socket, string type) + { + if (socket == null) throw new ArgumentNullException(nameof(socket)); + if (type == null) throw new ArgumentNullException(nameof(type)); + + foreach (var msg in socket.GetSentTextMessages().Reverse()) + { + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + var doc = JsonDocument.Parse(msg); + if (GetTopLevelType(doc.RootElement) == type) + { + return doc; + } + doc.Dispose(); + } + catch (JsonException) + { + // Skip invalid JSON + } + } + return null; + } + + /// + /// Gets the last sent JSON message from a regardless of type. + /// Returns null if no valid JSON message is found. + /// Caller is responsible for disposing the returned document when finished. + /// + /// The fake WebSocket containing sent messages. + /// The last valid , or null if none found. + internal static JsonDocument? GetLastJsonMessage(FakeWebSocket socket) + { + if (socket == null) throw new ArgumentNullException(nameof(socket)); + + foreach (var msg in socket.GetSentTextMessages().Reverse()) + { + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + return JsonDocument.Parse(msg); + } + catch (JsonException) + { + // Skip invalid JSON + } + } + return null; + } + + /// + /// Counts the number of sent messages from a that match the specified type. + /// + /// The fake WebSocket containing sent messages. + /// The message type to count (e.g., "session.update", "input_audio_buffer.append"). + /// The number of messages matching the specified type. + internal static int CountMessagesOfType(FakeWebSocket socket, string type) + { + if (socket == null) throw new ArgumentNullException(nameof(socket)); + if (type == null) throw new ArgumentNullException(nameof(type)); + + return socket.GetSentTextMessages().Count(m => + { + if (string.IsNullOrWhiteSpace(m)) + return false; + try + { + using var doc = JsonDocument.Parse(m); + return GetTopLevelType(doc.RootElement) == type; + } + catch (JsonException) + { + return false; + } + }); + } + + private static string EscapeString(string value) + { + // Use JsonEncodedText to ensure proper escaping without allocating a JsonDocument. + return JsonEncodedText.Encode(value).ToString(); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestableVoiceLiveSession.cs b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestableVoiceLiveSession.cs new file mode 100644 index 000000000000..8f8024a949c8 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/Infrastructure/TestableVoiceLiveSession.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Net.WebSockets; +using Azure.Core; + +namespace Azure.AI.VoiceLive.Tests.Infrastructure +{ + /// + /// A lightweight testable subclass that exposes the protected constructor and allows + /// injecting a without modifying production code. + /// This class is shared across all VoiceLive unit tests to provide consistent testing infrastructure. + /// + internal sealed class TestableVoiceLiveSession : VoiceLiveSession + { + /// + /// Initializes a new instance of the class for testing purposes. + /// + /// The VoiceLive client instance. + /// The WebSocket endpoint URI. + /// The authentication credential. + public TestableVoiceLiveSession(VoiceLiveClient client, Uri endpoint, AzureKeyCredential credential) + : base(client, endpoint, credential) + { + } + + /// + /// Sets the WebSocket instance for testing. This allows injection of a + /// to capture sent messages and simulate received messages. + /// + /// The WebSocket instance to inject. + public void SetWebSocket(WebSocket socket) => WebSocket = socket; + } +} \ No newline at end of file diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionAudioTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionAudioTests.cs new file mode 100644 index 000000000000..55264118ba97 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionAudioTests.cs @@ -0,0 +1,280 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Unit tests covering audio transmission APIs and audio turn management commands for . + /// These tests validate that the correct JSON command payloads (type properties and associated fields) are emitted + /// over the injected without performing any live network operations. + /// + [TestFixture] + public class VoiceLiveSessionAudioTests + { + /// + /// A lightweight testable subclass that exposes the protected constructor and allows + /// injecting a without modifying production code. + /// + private sealed class TestableVoiceLiveSession : VoiceLiveSession + { + public TestableVoiceLiveSession(VoiceLiveClient parentClient, Uri endpoint, AzureKeyCredential credential) + : base(parentClient, endpoint, credential) + { + } + + public void SetWebSocket(System.Net.WebSockets.WebSocket socket) => WebSocket = socket; + } + + private static TestableVoiceLiveSession CreateSessionWithFakeSocket(out FakeWebSocket fakeSocket) + { + var client = new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")); + var session = new TestableVoiceLiveSession(client, new Uri("wss://example.org/voice-agent/realtime"), new AzureKeyCredential("test-key")); + fakeSocket = new FakeWebSocket(); + session.SetWebSocket(fakeSocket); + return session; + } + + private static int CountMessagesOfType(FakeWebSocket socket, string type) + { + return socket.GetSentTextMessages().Count(m => + { + if (string.IsNullOrWhiteSpace(m)) + return false; + try + { + using var doc = JsonDocument.Parse(m); + return doc.RootElement.TryGetProperty("type", out var tProp) && + tProp.ValueKind == JsonValueKind.String && + string.Equals(tProp.GetString(), type, StringComparison.OrdinalIgnoreCase); + } + catch (JsonException) + { + return false; + } + }); + } + + private static JsonDocument? GetLastJsonMessage(FakeWebSocket socket) + { + foreach (var msg in socket.GetSentTextMessages().Reverse()) + { + if (string.IsNullOrWhiteSpace(msg)) + continue; + try + { + return JsonDocument.Parse(msg); + } + catch (JsonException) + { + continue; + } + } + return null; + } + + [Test] + public async Task SendInputAudioAsync_EncodesBase64AndWrapsAppendEvent() + { + var session = CreateSessionWithFakeSocket(out var fake); + + byte[] data = new byte[] { 0x01, 0x02, 0x03 }; // Known deterministic bytes -> AQID + await session.SendInputAudioAsync(data); + + using var last = GetLastJsonMessage(fake); + Assert.That(last, Is.Not.Null, "Expected a JSON command to have been sent."); + var root = last!.RootElement; + Assert.That(root.TryGetProperty("type", out var typeProp), Is.True, "type property missing"); + Assert.That(typeProp.GetString(), Is.EqualTo("input_audio_buffer.append")); + Assert.That(root.TryGetProperty("audio", out var audioProp), Is.True, "audio property missing"); + Assert.That(audioProp.GetString(), Is.EqualTo("AQID"), "Base64 encoding mismatch"); + } + + [Test] + public async Task SendInputAudioAsync_Stream_SendsMultipleAppendEvents() + { + var session = CreateSessionWithFakeSocket(out var fake); + + // Deterministic random bytes > 16K so that streaming uses multiple frames. + byte[] data = new byte[40 * 1024]; + new Random(0).NextBytes(data); + using var ms = new MemoryStream(data); + + await session.SendInputAudioAsync(ms); + + int appendCount = CountMessagesOfType(fake, "input_audio_buffer.append"); + Assert.That(appendCount, Is.GreaterThanOrEqualTo(3), "Expected at least three append messages for a 40KB stream."); + } + + /// + /// A blocking stream used to simulate a long running SendInputAudioAsync(stream) call so a second audio send + /// attempt can be made concurrently to trigger the InvalidOperationException logic. + /// + private sealed class BlockingTestStream : Stream + { + private readonly byte[] _firstChunk; + private bool _firstReturned; + private readonly ManualResetEventSlim _continueEvent; + private readonly ManualResetEventSlim _firstChunkReadEvent; + + public BlockingTestStream(byte[] firstChunk, ManualResetEventSlim firstChunkReadEvent, ManualResetEventSlim continueEvent) + { + _firstChunk = firstChunk ?? throw new ArgumentNullException(nameof(firstChunk)); + _firstChunkReadEvent = firstChunkReadEvent ?? throw new ArgumentNullException(nameof(firstChunkReadEvent)); + _continueEvent = continueEvent ?? throw new ArgumentNullException(nameof(continueEvent)); + } + + public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + public override void Flush() { } + public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); + public override void SetLength(long value) => throw new NotSupportedException(); + public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + public override bool CanRead => true; + public override bool CanSeek => false; + public override bool CanWrite => false; + public override long Length => _firstChunk.Length; + public override long Position { get => 0; set => throw new NotSupportedException(); } + + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if (!_firstReturned) + { + _firstReturned = true; + Array.Copy(_firstChunk, 0, buffer, offset, _firstChunk.Length); + _firstChunkReadEvent.Set(); + return _firstChunk.Length; + } + + // Block until released then indicate end of stream. + await Task.Run(() => { _continueEvent.Wait(cancellationToken); }); + return 0; + } + } + + [Test] + [Retry(3)] // Provide resilience in case of rare timing issues. + public async Task SendInputAudioAsync_WhileStreaming_ThrowsInvalidOperation() + { + var session = CreateSessionWithFakeSocket(out var fake); + + var firstChunkRead = new ManualResetEventSlim(false); + var releaseStream = new ManualResetEventSlim(false); + var blockingStream = new BlockingTestStream(new byte[100], firstChunkRead, releaseStream); + + Task streamSendTask = session.SendInputAudioAsync(blockingStream); + + // Wait for first chunk to be processed (so _isSendingAudioStream == true) + Assert.That(firstChunkRead.Wait(TimeSpan.FromSeconds(5)), Is.True, "Timed out waiting for first chunk to be read."); + + // Attempt second send (byte[] variant) which should fail while streaming active. + byte[] secondData = new byte[] { 0x01 }; + Assert.ThrowsAsync(async () => await session.SendInputAudioAsync(secondData)); + + // Allow the streaming operation to finish. + releaseStream.Set(); + await streamSendTask.ConfigureAwait(false); + + // Sanity: at least one append from the streaming plus none from failed second send. + int appendCount = CountMessagesOfType(fake, "input_audio_buffer.append"); + Assert.That(appendCount, Is.GreaterThanOrEqualTo(1)); + } + + [Test] + public async Task ClearInputAudioAsync_SendsBufferClear() + { + var session = CreateSessionWithFakeSocket(out var fake); + await session.ClearInputAudioAsync(); + Assert.That(CountMessagesOfType(fake, "input_audio_buffer.clear"), Is.EqualTo(1)); + } + + [Test] + public async Task CommitInputAudioAsync_SendsCommit() + { + var session = CreateSessionWithFakeSocket(out var fake); + await session.CommitInputAudioAsync(); + Assert.That(CountMessagesOfType(fake, "input_audio_buffer.commit"), Is.EqualTo(1)); + } + + [Test] + public async Task ClearStreamingAudioAsync_SendsStreamingClear() + { + var session = CreateSessionWithFakeSocket(out var fake); + await session.ClearStreamingAudioAsync(); + Assert.That(CountMessagesOfType(fake, "input_audio.clear"), Is.EqualTo(1)); + } + + [Test] + public async Task StartAppendEndAudioTurn_SendsExpectedSequence() + { + var session = CreateSessionWithFakeSocket(out var fake); + string turnId = "turn1"; + byte[] audio = new byte[] { 0x05, 0x06 }; + + await session.StartAudioTurnAsync(turnId); + await session.AppendAudioToTurnAsync(turnId, audio); + await session.EndAudioTurnAsync(turnId); + + var sent = fake.GetSentTextMessages(); + var turnEvents = new List(); + foreach (var msg in sent) + { + if (string.IsNullOrWhiteSpace(msg)) + continue; + try + { + using var doc = JsonDocument.Parse(msg); + if (doc.RootElement.TryGetProperty("type", out var tProp) && tProp.ValueKind == JsonValueKind.String) + { + var tVal = tProp.GetString(); + if (tVal == "input_audio.turn.start" || tVal == "input_audio.turn.append" || tVal == "input_audio.turn.end") + { + turnEvents.Add(tVal); + } + } + } + catch (JsonException) + { + // ignore + } + } + + CollectionAssert.AreEqual(new[] { "input_audio.turn.start", "input_audio.turn.append", "input_audio.turn.end" }, turnEvents, "Unexpected turn event sequence"); + } + + [Test] + public async Task CancelAudioTurnAsync_SendsTurnCancel() + { + var session = CreateSessionWithFakeSocket(out var fake); + await session.CancelAudioTurnAsync("turn123"); + Assert.That(CountMessagesOfType(fake, "input_audio.turn.cancel"), Is.EqualTo(1)); + } + + [Test] + public void AppendAudioToTurnAsync_EmptyTurnId_Throws() + { + var session = CreateSessionWithFakeSocket(out _); + Assert.ThrowsAsync(async () => await session.AppendAudioToTurnAsync(string.Empty, new byte[] { 0x01 })); + } + + [Test] + public void StartAudioTurnAsync_NullOrEmpty_Throws() + { + var session = CreateSessionWithFakeSocket(out _); + + Assert.ThrowsAsync(async () => await session.StartAudioTurnAsync(null)); + Assert.ThrowsAsync(async () => await session.StartAudioTurnAsync(string.Empty)); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionConfigurationTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionConfigurationTests.cs new file mode 100644 index 000000000000..330a37f1baab --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionConfigurationTests.cs @@ -0,0 +1,173 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Unit tests for configuring a using the conversation session helpers. + /// + [TestFixture] + public class VoiceLiveSessionConfigurationTests + { + /// + /// A lightweight testable subclass that exposes the protected constructor and allows + /// injecting a without modifying production code. + /// + private sealed class TestableVoiceLiveSession : VoiceLiveSession + { + public TestableVoiceLiveSession(VoiceLiveClient parentClient, Uri endpoint, AzureKeyCredential credential) + : base(parentClient, endpoint, credential) + { + } + + public void SetWebSocket(System.Net.WebSockets.WebSocket socket) => WebSocket = socket; + } + + private static TestableVoiceLiveSession CreateSessionWithFakeSocket(out FakeWebSocket fakeSocket) + { + var client = new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")); + var session = new TestableVoiceLiveSession(client, new Uri("wss://example.org/voice-agent/realtime"), new AzureKeyCredential("test-key")); + fakeSocket = new FakeWebSocket(); + session.SetWebSocket(fakeSocket); // Inject our capture socket. + return session; + } + + private static List GetSentMessagesOfType(FakeWebSocket socket, string type) + { + var docs = new List(); + foreach (var msg in socket.GetSentTextMessages()) + { + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + var doc = JsonDocument.Parse(msg); + if (doc.RootElement.TryGetProperty("type", out var tProp) && tProp.ValueKind == JsonValueKind.String && string.Equals(tProp.GetString(), type, StringComparison.OrdinalIgnoreCase)) + { + docs.Add(doc); + } + else + { + doc.Dispose(); + } + } + catch (JsonException) + { + // Ignore non-JSON frames for these tests. + } + } + return docs; + } + + [Test] + public async Task ConfigureConversationSession_SetsModalitiesAndVoice() + { + var session = CreateSessionWithFakeSocket(out var fake); + + var options = new SessionOptions + { + Voice = new AzureStandardVoice(TestConstants.VoiceName, AzureStandardVoiceType.AzureStandard), + Model = TestConstants.ModelName, + Instructions = "You are a helpful assistant.", + TurnDetection = new ServerVad { Threshold = 0.5f, SilenceDurationMs = 500 }, + InputAudioFormat = AudioFormat.Pcm16, + OutputAudioFormat = AudioFormat.Pcm16 + }; + // Ensure we control modalities explicitly (clear defaults then add back only text & audio) + options.Modalities.Clear(); + options.Modalities.Add(InputModality.Text); + options.Modalities.Add(InputModality.Audio); + + await session.ConfigureConversationSessionAsync(options); + + var updateMessages = GetSentMessagesOfType(fake, "session.update"); + Assert.That(updateMessages, Is.Not.Empty, "Expected at least one session.update message to be sent."); + + // Inspect the latest update for assertions (most specific state) + using var doc = updateMessages.Last(); + var root = doc.RootElement; + Assert.That(root.TryGetProperty("session", out var sessionElement), Is.True, "session object missing in payload"); + + // Modalities assertion + Assert.That(sessionElement.TryGetProperty("modalities", out var modalitiesElement), Is.True, "modalities missing"); + var modalities = modalitiesElement.EnumerateArray().Select(e => e.GetString()).Where(s => s != null).ToArray(); + Assert.That(modalities, Is.EquivalentTo(new[] { "text", "audio" }), "Modalities did not match expected set"); + + // Voice assertion + Assert.That(sessionElement.TryGetProperty("voice", out var voiceElement), Is.True, "voice object missing"); + Assert.That(voiceElement.TryGetProperty("name", out var voiceNameProp), Is.True, "voice.name missing"); + Assert.That(voiceNameProp.GetString(), Is.EqualTo(TestConstants.VoiceName)); + + // Turn detection assertion (type should be server_vad) + Assert.That(sessionElement.TryGetProperty("turn_detection", out var tdElement), Is.True, "turn_detection missing"); + Assert.That(tdElement.TryGetProperty("type", out var tdTypeProp), Is.True, "turn_detection.type missing"); + Assert.That(tdTypeProp.GetString(), Is.EqualTo("server_vad")); + } + + [Test] + public async Task ConfigureConversationSession_IncludesTools() + { + var session = CreateSessionWithFakeSocket(out var fake); + var options = new SessionOptions + { + Model = TestConstants.ModelName, + Voice = new AzureStandardVoice(TestConstants.VoiceName, AzureStandardVoiceType.AzureStandard) + }; + + options.Tools.Add(new FunctionTool("get_weather") { Description = "Gets the weather." }); + options.Tools.Add(new FunctionTool("book_flight") { Description = "Books a flight." }); + + await session.ConfigureConversationSessionAsync(options); + + var updateMessages = GetSentMessagesOfType(fake, "session.update"); + Assert.That(updateMessages, Is.Not.Empty, "Expected session.update message."); + using var doc = updateMessages.Last(); + var sessionEl = doc.RootElement.GetProperty("session"); + Assert.That(sessionEl.TryGetProperty("tools", out var toolsEl), Is.True, "tools array missing"); + var tools = toolsEl.EnumerateArray().ToArray(); + Assert.That(tools.Length, Is.EqualTo(2), "Unexpected number of tools serialized"); + var names = tools.Select(t => t.GetProperty("name").GetString()).ToArray(); + Assert.That(names, Is.EquivalentTo(new[] { "get_weather", "book_flight" })); + } + + [Test] + public void ConfigureConversationSession_NullOptions_Throws() + { + var session = CreateSessionWithFakeSocket(out _); + Assert.ThrowsAsync(async () => await session.ConfigureConversationSessionAsync(null)); + } + + [Test] + public async Task MultipleConfigureCalls_SendsMultipleUpdateMessages() + { + var session = CreateSessionWithFakeSocket(out var fake); + + var options1 = new SessionOptions { Model = TestConstants.ModelName }; + options1.Modalities.Clear(); + options1.Modalities.Add(InputModality.Text); + + var options2 = new SessionOptions { Model = TestConstants.ModelName }; + options2.Modalities.Clear(); + options2.Modalities.Add(InputModality.Audio); + + await session.ConfigureConversationSessionAsync(options1); + await session.ConfigureConversationSessionAsync(options2); + + var updateMessages = GetSentMessagesOfType(fake, "session.update"); + Assert.That(updateMessages.Count, Is.GreaterThanOrEqualTo(2), "Expected two session.update messages after two configuration calls."); + + // Dispose docs not used further + foreach (var d in updateMessages) d.Dispose(); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionDisposalTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionDisposalTests.cs new file mode 100644 index 000000000000..9157f86bd444 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionDisposalTests.cs @@ -0,0 +1,115 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Unit tests covering disposal and lifecycle behaviors of . + /// These tests validate that API calls after disposal throw the expected , + /// multiple disposal calls are safe (idempotent), and internal audio streaming state is correctly reset + /// once a streaming send completes allowing subsequent audio sends. + /// + [TestFixture] + public class VoiceLiveSessionDisposalTests + { + /// + /// A lightweight testable subclass that exposes the protected constructor and allows + /// injecting a without modifying production code. + /// + private sealed class TestableVoiceLiveSession : VoiceLiveSession + { + public TestableVoiceLiveSession(VoiceLiveClient parentClient, Uri endpoint, AzureKeyCredential credential) + : base(parentClient, endpoint, credential) + { + } + + public void SetWebSocket(System.Net.WebSockets.WebSocket socket) => WebSocket = socket; + } + + private static TestableVoiceLiveSession CreateSessionWithFakeSocket(out FakeWebSocket fakeSocket) + { + var client = new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")); + var session = new TestableVoiceLiveSession(client, new Uri("wss://example.org/voice-agent/realtime"), new AzureKeyCredential("test-key")); + fakeSocket = new FakeWebSocket(); + session.SetWebSocket(fakeSocket); // Inject capture socket. + return session; + } + + private static int CountMessagesOfType(FakeWebSocket socket, string type) + { + return socket.GetSentTextMessages().Count(m => + { + if (string.IsNullOrWhiteSpace(m)) + return false; + try + { + using var doc = JsonDocument.Parse(m); + return doc.RootElement.TryGetProperty("type", out var tProp) && tProp.ValueKind == JsonValueKind.String && string.Equals(tProp.GetString(), type, StringComparison.OrdinalIgnoreCase); + } + catch (JsonException) + { + return false; + } + }); + } + + [Test] + public void MethodsAfterDispose_ThrowObjectDisposedException() + { + var session = CreateSessionWithFakeSocket(out _); + session.Dispose(); + + // SendInputAudioAsync(byte[]) should throw + Assert.ThrowsAsync(async () => await session.SendInputAudioAsync(new byte[] { 0x01 })); + + // ConfigureConversationSessionAsync should throw + var convoOptions = new SessionOptions { Model = TestConstants.ModelName }; + Assert.ThrowsAsync(async () => await session.ConfigureConversationSessionAsync(convoOptions)); + } + + [Test] + public void Dispose_MultipleCalls_NoThrow() + { + var session = CreateSessionWithFakeSocket(out _); + + Assert.DoesNotThrow(() => session.Dispose()); + Assert.DoesNotThrow(() => session.Dispose()); // Second call should be idempotent. + + // Also ensure async dispose after sync dispose is safe. + Assert.DoesNotThrowAsync(async () => await session.DisposeAsync()); + } + + [Test] + public async Task AudioStreamLockReleasedAfterStreamSendCompletes() + { + var session = CreateSessionWithFakeSocket(out var fake); + + // 1. Perform a streaming audio send (MemoryStream triggers stream-based overload) + byte[] largeAudio = new byte[10 * 1024]; + new Random(0).NextBytes(largeAudio); + using var ms = new MemoryStream(largeAudio); + await session.SendInputAudioAsync(ms); // Should complete successfully. + + int appendCountAfterStream = CountMessagesOfType(fake, "input_audio_buffer.append"); + Assert.That(appendCountAfterStream, Is.GreaterThanOrEqualTo(1), "Expected at least one append message from streaming send."); + + // 2. Immediately send a small standalone chunk. This should succeed (no InvalidOperationException) indicating lock/state released. + byte[] smallChunk = new byte[] { 0x05, 0x06, 0x07 }; + await session.SendInputAudioAsync(smallChunk); + + int appendCountFinal = CountMessagesOfType(fake, "input_audio_buffer.append"); + Assert.That(appendCountFinal, Is.EqualTo(appendCountAfterStream + 1), "Expected exactly one additional append message after standalone send."); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionEventsTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionEventsTests.cs new file mode 100644 index 000000000000..9454a29d9a98 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionEventsTests.cs @@ -0,0 +1,157 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Unit tests covering server event streaming APIs (, + /// generic overload filtering, and behavior). + /// These tests validate parsing, enumeration constraints, cancellation, and disposal error paths without any live network traffic. + /// + [TestFixture] + public class VoiceLiveSessionEventsTests + { + /// + /// A lightweight testable subclass that exposes the protected constructor and allows + /// injecting a without modifying production code. + /// + private sealed class TestableVoiceLiveSession : VoiceLiveSession + { + public TestableVoiceLiveSession(VoiceLiveClient parentClient, Uri endpoint, AzureKeyCredential credential) + : base(parentClient, endpoint, credential) + { + } + + public void SetWebSocket(System.Net.WebSockets.WebSocket socket) => WebSocket = socket; + } + + private static TestableVoiceLiveSession CreateSessionWithFakeSocket(out FakeWebSocket fakeSocket) + { + var client = new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")); + var session = new TestableVoiceLiveSession(client, new Uri("wss://example.org/voice-agent/realtime"), new AzureKeyCredential("test-key")); + fakeSocket = new FakeWebSocket(); + session.SetWebSocket(fakeSocket); // Inject capture socket (already Open state) + return session; + } + + private static string CreateSessionCreatedJson(string eventId = "evt-1") + { + // Minimal valid payload for a session.created event. All session fields are optional per deserializer. + return $"{{ \"type\": \"session.created\", \"event_id\": \"{eventId}\", \"session\": {{ }} }}"; + } + + [Test] + public async Task GetUpdatesAsync_ParsesSessionCreatedEvent() + { + var session = CreateSessionWithFakeSocket(out var fake); + fake.EnqueueTextMessage(CreateSessionCreatedJson()); + + await foreach (ServerEvent evt in session.GetUpdatesAsync()) + { + Assert.That(evt, Is.TypeOf()); + var created = (ServerEventSessionCreated)evt; + Assert.That(created.Type.ToString(), Is.EqualTo("session.created")); + Assert.That(created.Session, Is.Not.Null); + break; // Only need first event + } + } + + [Test] + public async Task GetUpdatesAsync_IgnoresInvalidJson() + { + var session = CreateSessionWithFakeSocket(out var fake); + // Enqueue invalid JSON then a good event + fake.EnqueueTextMessage("{ invalid-json"); + fake.EnqueueTextMessage(CreateSessionCreatedJson("evt-2")); + + int count = 0; + await foreach (ServerEvent evt in session.GetUpdatesAsync()) + { + count++; + Assert.That(evt, Is.TypeOf()); + Assert.That(((ServerEventSessionCreated)evt).Type.ToString(), Is.EqualTo("session.created")); + break; // Stop after first valid event to avoid hanging waiting for more + } + + Assert.That(count, Is.EqualTo(1), "Expected only the valid event to be surfaced."); + } + + [Test] + public async Task GetUpdatesAsync_SingleEnumerationOnly() + { + var session = CreateSessionWithFakeSocket(out var fake); + // Ensure at least one event is available so the first enumerator advances promptly. + fake.EnqueueTextMessage(CreateSessionCreatedJson("evt-first")); + + await using var enumerator1 = session.GetUpdatesAsync().GetAsyncEnumerator(); + Assert.That(await enumerator1.MoveNextAsync(), Is.True, "First enumeration should obtain an event."); + Assert.That(enumerator1.Current, Is.TypeOf()); + + // Second enumeration attempt should throw InvalidOperationException when MoveNextAsync invoked. + await using var enumerator2 = session.GetUpdatesAsync().GetAsyncEnumerator(); + var ex = Assert.ThrowsAsync(async () => await enumerator2.MoveNextAsync()); + StringAssert.Contains("Only one update enumeration", ex?.Message); + } + + [Test] + public async Task WaitForUpdateAsync_ReturnsMatchingEvent() + { + var session = CreateSessionWithFakeSocket(out var fake); + + // Inject event after slight delay to ensure awaiting path is exercised. + _ = Task.Run(async () => + { + await Task.Delay(100); + fake.EnqueueTextMessage(CreateSessionCreatedJson("delayed")); + }); + + var result = await session.WaitForUpdateAsync(CancellationToken.None); + Assert.That(result, Is.Not.Null); + Assert.That(result.Type.ToString(), Is.EqualTo("session.created")); + } + + [Test] + public async Task WaitForUpdateAsync_Cancellation_ThrowsOperationCanceled() + { + var session = CreateSessionWithFakeSocket(out _); + using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(200)); + + try + { + await session.WaitForUpdateAsync(cts.Token); + Assert.Fail("Did not throw"); + } + catch (OperationCanceledException) + { + // Happy path, can't use assert because we want any derived type to also be OK. + } + catch (Exception ex) + { + Assert.Fail($"Exception type unexpected {ex}"); + } + } + + [Test] + public void GetUpdatesAsync_DisposedSession_Throws() + { + var session = CreateSessionWithFakeSocket(out _); + session.Dispose(); + + var enumerator = session.GetUpdatesAsync().GetAsyncEnumerator(); + Assert.ThrowsAsync(async () => await enumerator.MoveNextAsync()); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionItemsTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionItemsTests.cs new file mode 100644 index 000000000000..bbb43d848b09 --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionItemsTests.cs @@ -0,0 +1,193 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Unit tests covering conversation item management commands issued by . + /// These validate that the expected JSON command payloads are emitted over the injected + /// without performing any live network operations. + /// + [TestFixture] + public class VoiceLiveSessionItemsTests + { + /// + /// A lightweight testable subclass that exposes the protected constructor and allows + /// injecting a without modifying production code. + /// + private sealed class TestableVoiceLiveSession : VoiceLiveSession + { + public TestableVoiceLiveSession(VoiceLiveClient parentClient, Uri endpoint, AzureKeyCredential credential) + : base(parentClient, endpoint, credential) + { + } + + public void SetWebSocket(System.Net.WebSockets.WebSocket socket) => WebSocket = socket; + } + + private static TestableVoiceLiveSession CreateSessionWithFakeSocket(out FakeWebSocket fakeSocket) + { + var client = new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")); + var session = new TestableVoiceLiveSession(client, new Uri("wss://example.org/voice-agent/realtime"), new AzureKeyCredential("test-key")); + fakeSocket = new FakeWebSocket(); + session.SetWebSocket(fakeSocket); + return session; + } + + private static List GetMessagesOfType(FakeWebSocket socket, string type) + { + var list = new List(); + foreach (var msg in socket.GetSentTextMessages()) + { + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + var doc = JsonDocument.Parse(msg); + if (doc.RootElement.TryGetProperty("type", out var tProp) && tProp.ValueKind == JsonValueKind.String && string.Equals(tProp.GetString(), type, StringComparison.OrdinalIgnoreCase)) + { + list.Add(doc); + } + else + { + doc.Dispose(); + } + } + catch (JsonException) + { + // ignore non-json frames + } + } + return list; + } + + private static JsonDocument? GetLastMessageOfType(FakeWebSocket socket, string type) + { + foreach (var msg in socket.GetSentTextMessages().Reverse()) + { + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + var doc = JsonDocument.Parse(msg); + if (doc.RootElement.TryGetProperty("type", out var tProp) && tProp.ValueKind == JsonValueKind.String && string.Equals(tProp.GetString(), type, StringComparison.OrdinalIgnoreCase)) + { + return doc; // caller disposes + } + doc.Dispose(); + } + catch (JsonException) + { + // ignore + } + } + return null; + } + + private static ConversationItemWithReference CreateSimpleUserMessage(string id, string text) + { + var item = new ConversationItemWithReference + { + Id = id, + Type = ConversationItemWithReferenceType.Message, + Role = ConversationItemWithReferenceRole.User + }; + item.Content.Add(new ConversationItemWithReferenceContent + { + Type = ConversationItemWithReferenceContentType.InputText, + Text = text + }); + return item; + } + + [Test] + public async Task AddItemAsync_SendsConversationItemCreate() + { + var session = CreateSessionWithFakeSocket(out var fake); + var item = CreateSimpleUserMessage("item1", "Hello world"); + + await session.AddItemAsync(item); + + using var last = GetLastMessageOfType(fake, "conversation.item.create"); + Assert.That(last, Is.Not.Null, "Expected conversation.item.create message to be sent."); + var root = last!.RootElement; + Assert.That(root.TryGetProperty("item", out var itemProp), Is.True, "item property missing"); + Assert.That(itemProp.TryGetProperty("id", out var idProp), Is.True, "id missing inside item"); + Assert.That(idProp.GetString(), Is.EqualTo("item1")); + } + + [Test] + public async Task AddItemAsync_WithPreviousItemId_SetsPreviousId() + { + var session = CreateSessionWithFakeSocket(out var fake); + var item = CreateSimpleUserMessage("item2", "Second message"); + + await session.AddItemAsync(item, "root"); + + using var last = GetLastMessageOfType(fake, "conversation.item.create"); + Assert.That(last, Is.Not.Null, "Expected conversation.item.create message to be sent."); + var rootEl = last!.RootElement; + Assert.That(rootEl.TryGetProperty("previous_item_id", out var prevProp), Is.True, "previous_item_id missing"); + Assert.That(prevProp.GetString(), Is.EqualTo("root")); + } + + [Test] + public async Task DeleteItemAsync_SendsDeleteEvent() + { + var session = CreateSessionWithFakeSocket(out var fake); + await session.DeleteItemAsync("dead-item"); + + using var last = GetLastMessageOfType(fake, "conversation.item.delete"); + Assert.That(last, Is.Not.Null, "Expected conversation.item.delete message."); + var root = last!.RootElement; + Assert.That(root.TryGetProperty("item_id", out var idProp), Is.True, "item_id missing"); + Assert.That(idProp.GetString(), Is.EqualTo("dead-item")); + } + + [Test] + public async Task RequestItemRetrievalAsync_SendsRetrieveEvent() + { + var session = CreateSessionWithFakeSocket(out var fake); + await session.RequestItemRetrievalAsync("item123"); + + using var last = GetLastMessageOfType(fake, "conversation.item.retrieve"); + Assert.That(last, Is.Not.Null, "Expected conversation.item.retrieve message."); + var root = last!.RootElement; + Assert.That(root.TryGetProperty("item_id", out var idProp), Is.True, "item_id missing"); + Assert.That(idProp.GetString(), Is.EqualTo("item123")); + } + + [Test] + public async Task TruncateConversationAsync_SendsTruncatePayload() + { + var session = CreateSessionWithFakeSocket(out var fake); + await session.TruncateConversationAsync("assistant-msg-1", 0); + + using var last = GetLastMessageOfType(fake, "conversation.item.truncate"); + Assert.That(last, Is.Not.Null, "Expected conversation.item.truncate message."); + var root = last!.RootElement; + Assert.That(root.TryGetProperty("item_id", out var idProp), Is.True, "item_id missing"); + Assert.That(idProp.GetString(), Is.EqualTo("assistant-msg-1")); + Assert.That(root.TryGetProperty("content_index", out var ciProp), Is.True, "content_index missing"); + Assert.That(ciProp.GetInt32(), Is.EqualTo(0)); + Assert.That(root.TryGetProperty("audio_end_ms", out var aProp), Is.True, "audio_end_ms missing"); + Assert.That(aProp.GetInt32(), Is.EqualTo(0)); // VoiceLiveSession currently always uses 0 + } + + [Test] + public void TruncateConversationAsync_EmptyItemId_Throws() + { + var session = CreateSessionWithFakeSocket(out _); + Assert.ThrowsAsync(async () => await session.TruncateConversationAsync(string.Empty, 0)); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionResponseTests.cs b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionResponseTests.cs new file mode 100644 index 000000000000..0deae85ed05d --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tests/VoiceLiveSessionResponseTests.cs @@ -0,0 +1,187 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; +using Azure; +using Azure.AI.VoiceLive; +using Azure.AI.VoiceLive.Tests.Infrastructure; +using Azure.Core; +using NUnit.Framework; + +namespace Azure.AI.VoiceLive.Tests +{ + /// + /// Unit tests covering response management related commands for . + /// These validate that the expected JSON command payloads are emitted over the injected . + /// + [TestFixture] + public class VoiceLiveSessionResponseTests + { + /// + /// A lightweight testable subclass that exposes the protected constructor and allows + /// injecting a without modifying production code. + /// + private sealed class TestableVoiceLiveSession : VoiceLiveSession + { + public TestableVoiceLiveSession(VoiceLiveClient parentClient, Uri endpoint, AzureKeyCredential credential) + : base(parentClient, endpoint, credential) + { + } + + public void SetWebSocket(System.Net.WebSockets.WebSocket socket) => WebSocket = socket; + } + + private static TestableVoiceLiveSession CreateSessionWithFakeSocket(out FakeWebSocket fakeSocket) + { + var client = new VoiceLiveClient(new Uri("https://example.org"), new AzureKeyCredential("test-key")); + var session = new TestableVoiceLiveSession(client, new Uri("wss://example.org/voice-agent/realtime"), new AzureKeyCredential("test-key")); + fakeSocket = new FakeWebSocket(); + session.SetWebSocket(fakeSocket); // Inject our capture socket. + return session; + } + + private static JsonDocument? GetLastJsonMessage(FakeWebSocket socket) + { + foreach (var msg in socket.GetSentTextMessages().Reverse()) + { + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + return JsonDocument.Parse(msg); + } + catch (JsonException) + { + // ignore non-JSON + } + } + return null; + } + + private static List GetMessagesOfType(FakeWebSocket socket, string type) + { + var list = new List(); + foreach (var m in socket.GetSentTextMessages()) + { + if (string.IsNullOrWhiteSpace(m)) continue; + try + { + var doc = JsonDocument.Parse(m); + if (doc.RootElement.TryGetProperty("type", out var tProp) && tProp.ValueKind == JsonValueKind.String && string.Equals(tProp.GetString(), type, StringComparison.OrdinalIgnoreCase)) + { + list.Add(doc); + } + else + { + doc.Dispose(); + } + } + catch (JsonException) + { + // ignore + } + } + return list; + } + + [Test] + public async Task StartResponseAsync_NoOptions_SendsResponseCreate() + { + var session = CreateSessionWithFakeSocket(out var fake); + + await session.StartResponseAsync(); + + using var last = GetLastJsonMessage(fake); + Assert.That(last, Is.Not.Null, "Expected a response.create message."); + var root = last!.RootElement; + Assert.That(root.TryGetProperty("type", out var typeProp), Is.True); + Assert.That(typeProp.GetString(), Is.EqualTo("response.create")); + // Ensure no additional_instructions property present + Assert.That(root.TryGetProperty("additional_instructions", out _), Is.False, "Did not expect additional_instructions for no-options overload."); + } + + [Test] + public async Task StartResponseAsync_WithAdditionalInstructions_IncludesField() + { + var session = CreateSessionWithFakeSocket(out var fake); + string instructions = "Respond cheerfully."; + + await session.StartResponseAsync(instructions); + + using var last = GetLastJsonMessage(fake); + Assert.That(last, Is.Not.Null); + var root = last!.RootElement; + Assert.That(root.GetProperty("type").GetString(), Is.EqualTo("response.create")); + Assert.That(root.TryGetProperty("additional_instructions", out var aiProp), Is.True, "Expected additional_instructions property."); + Assert.That(aiProp.GetString(), Is.EqualTo(instructions)); + } + + [Test] + public async Task CancelResponseAsync_SendsResponseCancel() + { + var session = CreateSessionWithFakeSocket(out var fake); + + await session.CancelResponseAsync(); + + var cancelMessages = GetMessagesOfType(fake, "response.cancel"); + Assert.That(cancelMessages.Count, Is.EqualTo(1), "Expected one response.cancel message."); + foreach (var d in cancelMessages) d.Dispose(); + } + + [Test] + public async Task StartResponseAfterFunctionCallOutput_SendsFunctionCallOutputThenResponseCreate() + { + var session = CreateSessionWithFakeSocket(out var fake); + + // Construct a function_call_output item. + var item = new ConversationItemWithReference + { + Id = "func-output-1", + Type = ConversationItemWithReferenceType.FunctionCallOutput, + CallId = "call-1", + Output = "{ \"result\": \"ok\" }" + }; + + await session.AddItemAsync(item); + await session.StartResponseAsync(); + + // Examine ordering of messages: conversation.item.create should precede response.create + var sent = fake.GetSentTextMessages().ToList(); + int createIndex = -1; + int responseIndex = -1; + for (int i = 0; i < sent.Count; i++) + { + var msg = sent[i]; + if (string.IsNullOrWhiteSpace(msg)) continue; + try + { + using var doc = JsonDocument.Parse(msg); + if (!doc.RootElement.TryGetProperty("type", out var tProp) || tProp.ValueKind != JsonValueKind.String) continue; + var typeVal = tProp.GetString(); + if (typeVal == "conversation.item.create" && createIndex == -1) + { + createIndex = i; + } + if (typeVal == "response.create" && responseIndex == -1) + { + responseIndex = i; + } + } + catch (JsonException) + { + // ignore + } + } + + if (createIndex == -1 || responseIndex == -1) + { + Assert.Inconclusive("Could not locate required message types in sent frames (conversation.item.create and response.create)." ); + } + + Assert.That(createIndex, Is.LessThan(responseIndex), "conversation.item.create should be sent before response.create"); + } + } +} diff --git a/sdk/ai/Azure.AI.VoiceLive/tsp-location.yaml b/sdk/ai/Azure.AI.VoiceLive/tsp-location.yaml new file mode 100644 index 000000000000..637ad480617f --- /dev/null +++ b/sdk/ai/Azure.AI.VoiceLive/tsp-location.yaml @@ -0,0 +1,6 @@ +directory: specification/ai/data-plane/VoiceLive +commit: 72bd35443981e5364e6f696b5b0c4e78f9240aec +repo: rhurey/azure-rest-api-specs +additionalDirectories: +- specification/ai/data-plane/VoiceLive +emitterPackageJsonPath: eng/azure-typespec-http-client-csharp-emitter-package.json