# ModelProviderRegistry

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.modelproviderregistry/
> Summary: ModelProviderRegistry: Registry that holds the registered IModelProvider implementations by name, and the single place that assembles the model-call pipeline.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Core.dll</code></div>

Registry that holds the registered [IModelProvider](/api/tracon.imodelprovider/)
implementations by name, and the single place that assembles the model-call pipeline.

```csharp
public sealed class ModelProviderRegistry : IModelProviderRegistry
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.modelproviderregistry/">ModelProviderRegistry</a></dd><dt>Implements</dt><dd><a href="/api/tracon.imodelproviderregistry/">IModelProviderRegistry</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Remarks

By default no provider is registered; the `Tracon.OpenAI` package
 adds the first provider with `UseOpenAI`. Trying to compile
while no provider is registered produces a clear error.

**The entire pipeline is assembled here**.
Previously the four provider packages each assembled the
`UseFunctionInvocation` + `UseOpenTelemetry` chain
*inside themselves*; every ring the registry wrapped stayed OUTSIDE
that chain, making it impossible to write a ring that sees the tool-call
turns. Now [IModelProvider](/api/tracon.imodelprovider/) returns the **raw**
client and the pipeline is assembled in a single place; a third-party
provider inherits every ring for free too.

`AddTracon` registers the registry as a singleton; resolve it as
[IModelProviderRegistry](/api/tracon.imodelproviderregistry/) with `GetRequiredService<IModelProviderRegistry>`.

## Methods

### <a id="Tracon_ModelProviderRegistry_CreateChatClient_Tracon_ModelBinding_"></a> CreateChatClient\(ModelBinding\)

Produces a chat client for the given binding, using the provider's
setup-time credential.

```csharp
public IChatClient CreateChatClient(ModelBinding binding)
```

#### Parameters

`binding` [ModelBinding](/api/tracon.modelbinding/)

The model binding.

#### Returns

 IChatClient

The chat client.

#### Remarks

This overload does **not** resolve a tenant provider
binding (BYOK) or check an egress policy: both need
an async store lookup, which this synchronous method cannot perform.
Callers that must honor a tenant's own credential and egress policy —
this includes the real agent-run compile path — use
[IModelProviderRegistry.CreateChatClientAsync](/api/tracon.imodelproviderregistry/#Tracon_IModelProviderRegistry_CreateChatClientAsync_Tracon_ModelBinding_System_Threading_CancellationToken_) instead.

#### Exceptions

 [TraconException](/api/tracon.traconexception/)

No provider is registered with the name in [ModelBinding.Provider](/api/tracon.modelbinding/#Tracon_ModelBinding_Provider).

### <a id="Tracon_ModelProviderRegistry_CreateChatClientAsync_Tracon_ModelBinding_System_Threading_CancellationToken_"></a> CreateChatClientAsync\(ModelBinding, CancellationToken\)

Produces a chat client for the given binding, first resolving the
current tenant's own provider credential and egress policy.

```csharp
public ValueTask<IChatClient> CreateChatClientAsync(ModelBinding binding, CancellationToken cancellationToken = default)
```

#### Parameters

`binding` [ModelBinding](/api/tracon.modelbinding/)

The model binding.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<IChatClient\>

The chat client.

#### Remarks

When no tenant context is registered, or the tenant has no binding for
the provider, behavior is identical to [IModelProviderRegistry.CreateChatClient](/api/tracon.imodelproviderregistry/#Tracon_IModelProviderRegistry_CreateChatClient_Tracon_ModelBinding_)
(the no-surprises rule: behavior does not change until BYOK is configured).

#### Exceptions

 [TraconException](/api/tracon.traconexception/)

No provider is registered with the name in [ModelBinding.Provider](/api/tracon.modelbinding/#Tracon_ModelBinding_Provider).

 [TraconTenantProviderRefusedException](/api/tracon.tracontenantproviderrefusedexception/)

The tenant's egress policy does not allow the provider, the tenant's provider
binding cannot be resolved to a credential value, or the provider cannot take
a tenant's own credential.

### <a id="Tracon_ModelProviderRegistry_CreateSetupChatClientAsync_Tracon_ModelBinding_System_Threading_CancellationToken_"></a> CreateSetupChatClientAsync\(ModelBinding, CancellationToken\)

Produces a chat client after applying the current tenant's egress policy.

```csharp
public ValueTask<IChatClient> CreateSetupChatClientAsync(ModelBinding binding, CancellationToken cancellationToken = default)
```

#### Parameters

`binding` [ModelBinding](/api/tracon.modelbinding/)

The model binding.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<IChatClient\>

The chat client.

#### Exceptions

 [TraconException](/api/tracon.traconexception/)

No provider is registered with the name in [ModelBinding.Provider](/api/tracon.modelbinding/#Tracon_ModelBinding_Provider).

 [TraconTenantProviderRefusedException](/api/tracon.tracontenantproviderrefusedexception/)

The tenant's egress policy does not allow the provider.

### <a id="Tracon_ModelProviderRegistry_HasTenantProviderOverrideAsync_Tracon_ModelBinding_System_Threading_CancellationToken_"></a> HasTenantProviderOverrideAsync\(ModelBinding, CancellationToken\)

Reports whether the current tenant has its own provider binding for
`binding`'s primary provider or any of its
[ModelBinding.Fallbacks](/api/tracon.modelbinding/#Tracon_ModelBinding_Fallbacks) (BYOK).

```csharp
public ValueTask<bool> HasTenantProviderOverrideAsync(ModelBinding binding, CancellationToken cancellationToken = default)
```

#### Parameters

`binding` [ModelBinding](/api/tracon.modelbinding/)

The model binding to check.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[bool](https://learn.microsoft.com/dotnet/api/system.boolean)\>

[true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) if a tenant-specific credential would be baked
into the chat client [IModelProviderRegistry.CreateChatClientAsync](/api/tracon.imodelproviderregistry/#Tracon_IModelProviderRegistry_CreateChatClientAsync_Tracon_ModelBinding_System_Threading_CancellationToken_) produces for
this binding.

#### Remarks

A compiled agent's chat client is a fixed pipeline object — once a
tenant's credential is resolved into it, changing or deleting the
underlying binding has no further effect on that object. A cache
keyed only by definition identity (`CompiledAgentCache`) must
therefore never hold an agent built with a tenant-specific credential;
callers use this method to decide whether to bypass that cache.

### <a id="Tracon_ModelProviderRegistry_List"></a> List\(\)

Returns the definitions of the registered providers.

```csharp
public IReadOnlyList<ModelProviderDescriptor> List()
```

#### Returns

 [IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[ModelProviderDescriptor](/api/tracon.modelproviderdescriptor/)\>

The provider definitions.
