Skip to content
Tracon

ModelBinding

Namespace Tracon · Assembly Tracon.Abstractions.dll

Determines the provider and the model an agent runs with. It carries no credentials; the API key is resolved from configuration.

public sealed record ModelBinding : IEquatable<ModelBinding>
Inheritance
object ← ModelBinding
Implements
IEquatable<ModelBinding>
Inherited Members
object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()
public ModelBinding()

Gets whether the model may ask for several tool calls in one turn. The provider default is used when it is null.

public bool? AllowMultipleToolCalls { get; init; }

bool?

It is not ToolLoopSettings.AllowConcurrentToolCalls: this one controls what the model may ask for, that one controls whether Tracon runs the calls at the same time.

Gets the ordered fallback chain tried when the primary provider is unavailable. Empty by default.

public IReadOnlyList<ModelFallback> Fallbacks { get; init; }

IReadOnlyList<ModelFallback>

Empty by default: with no fallback configured, today’s behavior is preserved exactly — a provider failure (for example an open circuit) still throws, and no fallback code path runs.

A fallback link carries only a provider and a model, not a full ModelBinding. The fallback call receives the primary call’s request options — ModelBinding.Temperature, ModelBinding.TopP, ModelBinding.MaxOutputTokens, ModelBinding.ResponseFormat, the other sampling fields (ModelBinding.Seed, ModelBinding.TopK, ModelBinding.StopSequences, the penalties, ModelBinding.ToolMode, ModelBinding.AllowMultipleToolCalls, ModelBinding.ReasoningOutput) and the tools — with only the model name replaced; the link also takes ModelBinding.ToolLoop as one object. ModelBinding.ProviderSettings do not carry over: they configure the primary provider’s client. A fallback model that needs its own settings is a separate configuration concern, not something this chain expresses.

Switching to a fallback is never silent: the run record gets an explicit ModelFallbackUsed event, and cost and model attribution (RunStatistics.ByModel) reflect the model that actually answered, not the primary binding.

That applies to the agent’s own binding. A binding the run calls on the side, such as the context compaction summarizer or the judge of an aiJudge loop criterion, keeps its fallback to that call: the run keeps the agent’s model and gets no event, the call’s tokens are priced at the model that answered, and the switch is logged.

Gets the frequency penalty. The provider default is used when it is null.

public float? FrequencyPenalty { get; init; }

float?

Gets the upper output token limit. The provider default is used when it is null.

public int? MaxOutputTokens { get; init; }

int?

Gets the model name, for example gpt-5.4-mini.

public required string Model { get; init; }

string

Gets the presence penalty. The provider default is used when it is null.

public float? PresencePenalty { get; init; }

float?

Gets the provider name, for example openai.

public required string Provider { get; init; }

string

Gets the provider-specific extra settings. A key has the form {provider}.{setting}.

public IReadOnlyDictionary<string, JsonElement> ProviderSettings { get; init; }

IReadOnlyDictionary<string, JsonElement>

The prompt caching of Anthropic or the safety thresholds of Gemini do not fit the fixed fields of this contract. Adding them to the body of ModelBinding would leak one vendor’s concept into Tracon.Abstractions. This dictionary keeps the contract clean: each provider reads only its own prefix.

An unknown key is not ignored silently. When a provider sees a key it does not recognize, the build fails and lists the keys it supports. The reason is the same as for ModelBinding.ReasoningEffort: a setting that is ignored silently makes the user miss the behaviour they expect without seeing why.

Keys are compared with StringComparer.OrdinalIgnoreCase. Use the ModelProviderSettings helpers to read them.

"ProviderSettings": {
"anthropic.promptCaching": true,
"anthropic.thinking.budgetTokens": 8000,
"google.safety.harassment": "BLOCK_ONLY_HIGH"
}

Gets the reasoning effort level. Models that support it use the value; the other providers ignore it.

public string? ReasoningEffort { get; init; }

string?

The valid values are the Microsoft.Extensions.AI.ReasoningEffort names: None, Low, Medium, High, ExtraHigh. The comparison is case insensitive. An unrecognized value is rejected while the agent is built, with TraconCompilationException; it is not ignored silently.

Gets how much of the model’s reasoning the response carries. The provider default is used when it is null.

public string? ReasoningOutput { get; init; }

string?

The valid values are the Microsoft.Extensions.AI.ReasoningOutput names: None, Summary, Full. The comparison is case insensitive. An unrecognized value is rejected while the agent is built, with TraconCompilationException, in the same way as ModelBinding.ReasoningEffort.

Gets the response caching settings. Disabled when null.

public ResponseCacheSettings? ResponseCache { get; init; }

ResponseCacheSettings?

Disabled by default: with no cache configured, today’s behavior is preserved exactly — every call reaches the model, and no cache ring is added to the pipeline.

Enabling it while no IDistributedCache is registered is not silently ignored: compilation stops with TraconCompilationException, naming the missing registration.

Gets the requested output format. When it is null today’s behaviour does not change: no format constraint is sent to the provider.

public AgentResponseFormat? ResponseFormat { get; init; }

AgentResponseFormat?

AgentResponseFormatKind.Text differs from null: null means “say nothing”, Text means “ask for plain text explicitly”. An invalid combination (for example AgentResponseFormatKind.JsonSchema without a schema) is rejected while the agent is built, with TraconCompilationException.

Gets the sampling seed. The provider default is used when it is null.

public long? Seed { get; init; }

long?

Sent only by the API surfaces that support it (see ISamplingSupport); a definition that sets it for a provider that does not is rejected while the agent is built. The same holds for ModelBinding.TopK, ModelBinding.StopSequences, ModelBinding.FrequencyPenalty, ModelBinding.PresencePenalty, ModelBinding.ToolMode, ModelBinding.AllowMultipleToolCalls and ModelBinding.ReasoningOutput, on the primary provider and on every ModelBinding.Fallbacks link.

Gets the sequences that stop generation. Nothing is sent when it is null or empty.

public IReadOnlyList<string>? StopSequences { get; init; }

IReadOnlyList<string>?

An entry must not be empty. The providers limit how many sequences a request may carry; the provider’s own error is returned when the limit is exceeded.

Gets the sampling temperature. The provider default is used when it is null.

public float? Temperature { get; init; }

float?

Gets the settings of the tool-call loop the model pipeline builds.

public ToolLoopSettings ToolLoop { get; init; }

ToolLoopSettings

The defaults keep today’s behavior: the loop runs tool calls one after another and uses its own limits. A fallback link takes this object as it is.

It is never null when read, and it accepts null when set: null becomes the default settings, so a client that sends "toolLoop": null is not refused. A source-generated JSON reader assigns null to a member that is absent from the JSON when the type has required members (measured), which is what a definition stored before this member existed looks like.

Gets how the model may use the agent’s tools. The provider default (the model decides) is used when it is null.

public string? ToolMode { get; init; }

string?

The values are auto, none, required (the model must call a tool) and required:<tool> (the model must call that tool). The comparison is case insensitive. The tool in required:<tool> must be one of the definition’s AgentDefinition.ToolNames. An unrecognized value is rejected while the agent is built, with TraconCompilationException.

required and required:<tool> force the first model call of a turn only: the tool-call loop lifts the requirement for the calls that follow, or the model could never answer.

Gets the top-k sampling limit. The provider default is used when it is null.

public int? TopK { get; init; }

int?

It must be greater than zero.

Gets the nucleus sampling threshold. The provider default is used when it is null.

public float? TopP { get; init; }

float?

public override bool Equals(object? obj)

obj object?

bool

public bool Equals(ModelBinding? other)

other ModelBinding?

bool

public override int GetHashCode()

int

public override string ToString()

string

operator ==(ModelBinding?, ModelBinding?)

Section titled “ operator ==(ModelBinding?, ModelBinding?)”
public static bool operator ==(ModelBinding? left, ModelBinding? right)

left ModelBinding?

right ModelBinding?

bool

operator !=(ModelBinding?, ModelBinding?)

Section titled “ operator !=(ModelBinding?, ModelBinding?)”
public static bool operator !=(ModelBinding? left, ModelBinding? right)

left ModelBinding?

right ModelBinding?

bool