SmallestAIClient implements Microsoft.Extensions.AI.ISpeechToTextClient, so
Pulse drops into any MEAI pipeline. GetTextAsync posts pre-recorded audio;
GetStreamingTextAsync opens the realtime WebSocket and yields interim and
final updates.
MEAI has no first-class notion of diarization, so Pulse knobs go in through
SpeechToTextOptions.AdditionalProperties and speaker-labelled results come
back out through the response's AdditionalProperties — use
SmallestAISpeechToTextPropertyNames for the keys, or read RawRepresentation
for the full typed payload.
Note the Meai alias: the generated SmallestAI.ISpeechToTextClient
sub-client interface collides by simple name with the MEAI one, so inside the
SmallestAI namespace the MEAI types must be qualified.
This example assumes using SmallestAI; is in scope and apiKey contains your SmallestAI API key.
usingvarclient=newSmallestAIClient(apiKey);varaudio=awaitBuildTwoSpeakerWavAsync(client,TestContext.CancellationToken);Meai.ISpeechToTextClientspeechToText=client;speechToText.GetService(typeof(Meai.SpeechToTextClientMetadata))varoptions=newMeai.SpeechToTextOptions{ModelId=SmallestAIClient.PulseModelId,SpeechLanguage="en",AdditionalProperties=newMeai.AdditionalPropertiesDictionary{[SmallestAISpeechToTextPropertyNames.Diarize]=true,[SmallestAISpeechToTextPropertyNames.WordTimestamps]=true,},};usingvarbatchAudio=newMemoryStream(audio);varresponse=awaitspeechToText.GetTextAsync(batchAudio,options,TestContext.CancellationToken);varwords=response.AdditionalProperties?[SmallestAISpeechToTextPropertyNames.Words]asIList<Word>;// The same client streams the same audio over the realtime channel.usingvarstreamingAudio=newMemoryStream(ReadPcm(audio));options.AdditionalProperties![SmallestAISpeechToTextPropertyNames.SampleRate]=FixtureSampleRate;varupdates=newList<Meai.SpeechToTextResponseUpdate>();awaitforeach(varupdateinspeechToText.GetStreamingTextAsync(streamingAudio,options,TestContext.CancellationToken)){updates.Add(update);}