.NET API
ISpeechDialogueSynthesizer
Tracon.Abstractions.dllA speech provider that voices a dialogue: an ordered list of turns, each spoken by its own voice, in one request and one audio result.
public interface ISpeechDialogueSynthesizerRemarks
Section titled “Remarks”A capability next to ISpeechSynthesizer, not a part of it: a provider
that speaks one voice per request implements no dialogue member. The same instance
implements both interfaces, and it is registered as an ISpeechSynthesizer
(the unnamed default, or by name with AddSpeechSynthesizer). It is not
registered as ISpeechDialogueSynthesizer: a caller takes the capability
from ISpeechProviderResolver.GetDialogueSynthesizerAsync, which applies
the tenant’s checks first.
Splitting is the caller’s job. A request that exceeds ISpeechDialogueSynthesizer.DialogueCapabilities is refused before the service is called; the implementation never splits or truncates a dialogue. The caller plans its requests from SpeechDialogueCapabilities.MaxVoices and SpeechDialogueCapabilities.MaxCharactersPerRequest, and joins the audio itself.
DI lifetime — singleton. The capability lives on the synthesizer instance, which is a container singleton; it holds no per-call state.
Tenant behavior — TENANT-INDEPENDENT implementation, tenant-gated calls. The instance never reads the tenant. ISpeechProviderResolver applies the tenant’s egress policy to ISpeechDialogueSynthesizer.ProviderName and passes the tenant’s own credential in SpeechDialogueRequest.Credential, only to an implementation whose ISpeechDialogueSynthesizer.SupportsTenantCredentials is true.
Delivery: no delivery guarantee applies. One call is one request to the provider; it is not retried here, and a failed call produces no audio.
A workflow function node that voices two turns with the default synthesizer:
tracon.AddWorkflowFunction<List<ChatMessage>, List<ChatMessage>>( "two-voices", provider => { var speech = provider.GetRequiredService<ISpeechProviderResolver>();
return async (messages, context, cancellationToken) => { var dialogue = await speech.GetDialogueSynthesizerAsync(cancellationToken: cancellationToken); var result = await dialogue.SynthesizeDialogueAsync( new SpeechDialogueRequest { Turns = [ new SpeechDialogueTurn { Text = "Welcome back.", VoiceId = "host-voice" }, new SpeechDialogueTurn { Text = "Glad to be here.", VoiceId = "guest-voice" }, ], IncludeTimestamps = true, }, cancellationToken);
var timing = new List<string>();
foreach (var segment in result.Segments ?? []) { timing.Add($"turn {segment.TurnIndex}: {segment.Start} - {segment.End}"); }
return [new ChatMessage(ChatRole.Assistant, string.Join(", ", timing))]; }; });Properties
Section titled “Properties”DialogueCapabilities
Section titled “ DialogueCapabilities”Gets the limits of one dialogue request.
SpeechDialogueCapabilities DialogueCapabilities { get; }Property Value
Section titled “Property Value”ProviderName
Section titled “ ProviderName”The provider name. Used in cost records and in the tenant’s checks.
string ProviderName { get; }Property Value
Section titled “Property Value”Remarks
Section titled “Remarks”A tenant’s egress policy and provider bindings name this value, not the name the synthesizer was registered under.
SupportsTenantCredentials
Section titled “ SupportsTenantCredentials”Gets whether the implementation honours a tenant credential passed in SpeechDialogueRequest.Credential.
bool SupportsTenantCredentials { get; }Property Value
Section titled “Property Value”Remarks
Section titled “Remarks”The default is false. Tracon then refuses a dialogue for a tenant that has its own binding for ISpeechDialogueSynthesizer.ProviderName rather than make it on the configured credential, which would bill the wrong account. An implementation that returns true uses the credential for the call it came with and never falls back to its configured one.
Methods
Section titled “Methods”SynthesizeDialogueAsync(SpeechDialogueRequest, CancellationToken)
Section titled “ SynthesizeDialogueAsync(SpeechDialogueRequest, CancellationToken)”Voices a dialogue.
ValueTask<SpeechDialogueAudio> SynthesizeDialogueAsync(SpeechDialogueRequest request, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”request SpeechDialogueRequest
The turns and the settings.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<SpeechDialogueAudio>
The audio of the whole dialogue and, when requested, each turn’s time range.
Exceptions
Section titled “Exceptions”request is null.
The request breaks a limit of ISpeechDialogueSynthesizer.DialogueCapabilities, a turn has no text or no voice, a provider setting is unknown or has the wrong type, or the provider answered with an error. The service is not called for the first three. The message names the limit or the key, never a turn’s text or a setting’s value.
SpeechDialogueRequest.Credential is set and ISpeechDialogueSynthesizer.SupportsTenantCredentials is false.