Skip to content
Tracon

ISpeechProviderResolver

Namespace Tracon · Assembly Tracon.Abstractions.dll

Returns a speech provider by name, after the calling tenant’s provider checks.

public interface ISpeechProviderResolver

Every Tracon path that sends a tenant’s text or audio to a speech provider resolves the provider here: the speak, transcribe and list_voices tools, POST /api/voice/speak, GET /api/voice/voices and the conversation socket. A workflow function node that speaks or voices a dialogue resolves it here too. The one direct call is the platform health check (GET /api/voice/health): it lists the default synthesizer’s voices with the configured credential and sends no tenant data.

A name selects a provider registered with AddSpeechSynthesizer or AddSpeechTranscriber. null selects the unnamed default, the one UseVoice or the consumer’s own ISpeechSynthesizer registration binds. Names are compared in lower case.

Order of the checks. The tenant’s egress policy is checked first, against the instance’s ISpeechSynthesizer.ProviderName (not the registration name, so an alias cannot pass a policy). Then the tenant’s own credential for that provider is looked up. When the tenant has one, the provider must support tenant credentials and the binding must not carry an endpoint override; otherwise the call is refused rather than sent on the setup credential. The returned provider puts the tenant’s credential on every request it makes.

The policy and the binding are read each time a provider is resolved, not cached. A tool call, an HTTP request and a function node resolve for every call, so a policy saved now stops their next call. The conversation socket resolves once, when the connection opens: an open connection keeps the providers it was given until it closes, and a policy saved meanwhile applies from the next connection. A returned instance keeps the decision it was resolved under; do not keep it. When a store fails, the call fails and the provider is not called.

Delivery: no delivery guarantee applies. Resolving sends nothing to the provider; the call made with the returned instance is the caller’s, with that provider’s own guarantee.

DI lifetime — singleton. Registered by AddTracon. Call this interface; do not implement or replace it. The tenant’s egress policy and credential checks above run inside it, and a replacement would send a tenant’s text or audio to a provider without them. To add a provider, register an ISpeechSynthesizer or ISpeechTranscriber as described above.

Tenant behavior — AMBIENT tenant. No member takes a tenant parameter; the checks use the current run’s tenant, or the current ITenantContext outside a run. The returned provider can carry that tenant’s credential: resolve it for each call and do not keep it for another tenant.

A workflow function node that speaks with the engine named in the node’s settings:

builder.AddTracon()
.AddSpeechSynthesizer("studio", provider => new StudioSpeechSynthesizer())
.UseWorkflows()
.AddWorkflowFunction<List<ChatMessage>, List<ChatMessage>, NarrationSettings>(
"narrate",
provider =>
{
var speech = provider.GetRequiredService<ISpeechProviderResolver>();
return async (messages, settings, context, cancellationToken) =>
{
var synthesizer = await speech.GetSynthesizerAsync(settings.Provider, cancellationToken);
var audio = await synthesizer.SynthesizeAsync(
new SpeechRequest { Text = messages[^1].Text },
cancellationToken);
return [new ChatMessage(ChatRole.Assistant, $"{audio.Data.Length} bytes")];
};
});

Gets the registered speech providers, the unnamed defaults included.

IReadOnlyList<SpeechProviderDescriptor> Providers { get; }

IReadOnlyList<SpeechProviderDescriptor>

Synthesizers come first, then transcribers; in each kind the unnamed default comes first, then the named providers in ordinal order of their names. Reading the list applies no tenant check and calls no provider.

GetDialogueSynthesizerAsync(string?, CancellationToken)

Section titled “ GetDialogueSynthesizerAsync(string?, CancellationToken)”

Returns the dialogue capability of a speech synthesizer for the current tenant.

ValueTask<ISpeechDialogueSynthesizer> GetDialogueSynthesizerAsync(string? name = null, CancellationToken cancellationToken = default)

name string?

The registration name of the synthesizer, or null for the unnamed default. Dialogue has no registration of its own: the synthesizer registered under this name must implement ISpeechDialogueSynthesizer.

cancellationToken CancellationToken

The cancellation token.

ValueTask<ISpeechDialogueSynthesizer>

The dialogue synthesizer, carrying the tenant’s credential when it has one.

The capability is read from the synthesizer instance itself, never from a wrapper, so a tenant with its own credential and a tenant without one see the same answer. The tenant’s checks then apply to ISpeechDialogueSynthesizer.ProviderName in the order ISpeechProviderResolver.GetSynthesizerAsync uses.

A host’s own synthesizer that voices no dialogue is reported, not replaced: the call fails naming that provider, and the built-in client is not called in its place.

TraconException

No synthesizer is registered under name, or no default is registered; the synthesizer cannot voice a dialogue; or the tenant’s checks refuse the provider. The message names the provider, never a key value.

OperationCanceledException

cancellationToken was cancelled.

GetSynthesizerAsync(string?, CancellationToken)

Section titled “ GetSynthesizerAsync(string?, CancellationToken)”

Returns a speech synthesizer for the current tenant.

ValueTask<ISpeechSynthesizer> GetSynthesizerAsync(string? name = null, CancellationToken cancellationToken = default)

name string?

The registration name, or null for the unnamed default.

cancellationToken CancellationToken

The cancellation token.

ValueTask<ISpeechSynthesizer>

The synthesizer, carrying the tenant’s credential when it has one.

TraconException

No synthesizer is registered under name, or no default is registered; or the tenant’s checks refuse the provider. The message names the tenant and the provider, never a key value.

OperationCanceledException

cancellationToken was cancelled.

GetTranscriberAsync(string?, CancellationToken)

Section titled “ GetTranscriberAsync(string?, CancellationToken)”

Returns a speech transcriber for the current tenant.

ValueTask<ISpeechTranscriber> GetTranscriberAsync(string? name = null, CancellationToken cancellationToken = default)

name string?

The registration name, or null for the unnamed default.

cancellationToken CancellationToken

The cancellation token.

ValueTask<ISpeechTranscriber>

The transcriber, carrying the tenant’s credential when it has one.

TraconException

No transcriber is registered under name, or no default is registered; or the tenant’s checks refuse the provider.

OperationCanceledException

cancellationToken was cancelled.