.NET API
TraconBuilderExtensions
Tracon.Core.dllThe registration methods of the Tracon configuration chain that
AddTracon returns.
public static class TraconBuilderExtensions- Inheritance
- object ← TraconBuilderExtensions
- Inherited Members
- object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()
Remarks
Section titled “Remarks”Every registration capability is an extension method on
ITraconBuilder, so a new capability never changes the
interface. Provider and storage packages follow the same shape with their
own extensions (UsePostgreSql, UseOpenAI, and so on).
A chain only has to supply ITraconBuilder.Services: these methods write to that collection and nothing else.
Methods
Section titled “Methods”AddAgent(ITraconBuilder, AgentDefinition)
Section titled “ AddAgent(ITraconBuilder, AgentDefinition)”Defines a declarative agent in code. The definition passes through the Tracon compiler; model and tool validation is applied.
public static ITraconBuilder AddAgent(this ITraconBuilder builder, AgentDefinition definition)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
definition AgentDefinition
The agent definition.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”builder.AddTracon() .AddAgent(new AgentDefinition { Name = "support", Instructions = "Answer support questions from the order data.", Model = new ModelBinding { Provider = "openai", Model = "gpt-4o-mini" }, ToolNames = ["get_order_status"], });Exceptions
Section titled “Exceptions”builder is null.
AddAgent(ITraconBuilder, string, Func<IServiceProvider, AIAgent>, string?)
Section titled “ AddAgent(ITraconBuilder, string, Func<IServiceProvider, AIAgent>, string?)”Defines a factory-based agent in code. How the agent is built is entirely up to the caller.
public static ITraconBuilder AddAgent(this ITraconBuilder builder, string name, Func<IServiceProvider, AIAgent> factory, string? description = null)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
name string
The agent name.
factory Func<IServiceProvider, AIAgent>
The factory that produces the agent.
description string?
A short description.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddAgentDecorator<TDecorator>(ITraconBuilder)
Section titled “ AddAgentDecorator<TDecorator>(ITraconBuilder)”Registers a custom agent decorator as a singleton.
public static ITraconBuilder AddAgentDecorator<TDecorator>(this ITraconBuilder builder) where TDecorator : class, IAgentDecoratorParameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
Returns
Section titled “Returns”The chain, for further configuration.
Type Parameters
Section titled “Type Parameters”TDecorator
The decorator implementation type.
Remarks
Section titled “Remarks”Calling this method more than once for the same decorator type has no effect. The decorator joins the pipeline alongside Tracon’s own (run recording, telemetry, tool approval); see IAgentDecorator.Order for where it lands. It must be thread-safe because the catalog can decorate agents concurrently.
builder.AddTracon() .AddAgentDecorator<AuditingAgentDecorator>();Exceptions
Section titled “Exceptions”builder is null.
AddAgentDecorator(ITraconBuilder, IAgentDecorator)
Section titled “ AddAgentDecorator(ITraconBuilder, IAgentDecorator)”Registers a configured custom agent decorator as a singleton.
public static ITraconBuilder AddAgentDecorator(this ITraconBuilder builder, IAgentDecorator decorator)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
decorator IAgentDecorator
The decorator instance.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddAgentDecorator(ITraconBuilder, Func<IServiceProvider, IAgentDecorator>)
Section titled “ AddAgentDecorator(ITraconBuilder, Func<IServiceProvider, IAgentDecorator>)”Registers a custom agent-decorator factory as a singleton.
public static ITraconBuilder AddAgentDecorator(this ITraconBuilder builder, Func<IServiceProvider, IAgentDecorator> factory)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
factory Func<IServiceProvider, IAgentDecorator>
The factory that creates the decorator.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddAgentExtension<TExtension>(ITraconBuilder)
Section titled “ AddAgentExtension<TExtension>(ITraconBuilder)”Registers an agent extension as a singleton.
public static ITraconBuilder AddAgentExtension<TExtension>(this ITraconBuilder builder) where TExtension : class, IAgentExtensionParameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
Returns
Section titled “Returns”The chain, for further configuration.
Type Parameters
Section titled “Type Parameters”TExtension
The extension implementation type.
Remarks
Section titled “Remarks”A definition selects the extension by IAgentExtension.Name in AgentDefinition.ExtensionNames. Calling this method more than once for the same type has no effect; two types that report the same name are rejected when the compiler is first used.
builder.AddTracon() .AddAgentExtension<PolicyContextExtension>();Exceptions
Section titled “Exceptions”builder is null.
AddAgentExtension(ITraconBuilder, IAgentExtension)
Section titled “ AddAgentExtension(ITraconBuilder, IAgentExtension)”Registers a configured agent extension.
public static ITraconBuilder AddAgentExtension(this ITraconBuilder builder, IAgentExtension extension)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
extension IAgentExtension
The extension instance.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder or extension is null.
AddAgentExtension(ITraconBuilder, string, Action<AgentExtensionContext>, string?)
Section titled “ AddAgentExtension(ITraconBuilder, string, Action<AgentExtensionContext>, string?)”Registers an agent extension from a delegate. A definition selects it by
name in AgentDefinition.ExtensionNames.
public static ITraconBuilder AddAgentExtension(this ITraconBuilder builder, string name, Action<AgentExtensionContext> configure, string? description = null)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
name string
The extension name: 1 to 128 characters of lowercase ASCII letters, digits, .,
_ or -, unique among the registered extensions.
configure Action<AgentExtensionContext>
Changes the options of the agent that is being compiled, or adds a wrapper. It runs when an agent that names the extension is compiled, not on every run.
description string?
What the extension does, in one sentence. The console shows it next to the name and
GET /api/agent-extensions returns it to every reader, so it must not carry a
secret. null shows the name alone.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The escape door for a Microsoft Agent Framework option Tracon does not model.
A hand-built agent in AddAgent(name, factory) bypasses the model ring, the
tenant’s provider credential, egress and cost; an extension keeps all of them
because the agent still goes through the compiler. The compiler refuses a change
to a member the definition or a tenant and security decision owns (the tool chain,
the tool approval settings, the chat history provider, file access, the
working-directory skill scan and the model parameters among them). It does not look
inside a provider or a wrapper the extension adds.
Adds your own context provider to the agents that select it:
builder.AddTracon() .AddAgentExtension( "house-policy", context => { if (context.ChatAgentOptions is { } options) { options.AIContextProviders = [.. options.AIContextProviders ?? [], new HousePolicyProvider()]; } }, description: "Adds the house policy to the instructions of every model call.");Exceptions
Section titled “Exceptions”builder or configure is null.
name is empty.
AddAgentSource<TSource>(ITraconBuilder)
Section titled “ AddAgentSource<TSource>(ITraconBuilder)”Registers a custom agent source as a singleton.
public static ITraconBuilder AddAgentSource<TSource>(this ITraconBuilder builder) where TSource : class, IAgentSourceParameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
Returns
Section titled “Returns”The chain, for further configuration.
Type Parameters
Section titled “Type Parameters”TSource
The source implementation type.
Remarks
Section titled “Remarks”Calling this method more than once for the same source type has no effect. The source can serve global or tenant-aware agents. It must be thread-safe because the catalog calls its methods concurrently.
builder.AddTracon() .AddAgentSource<GitAgentSource>();Exceptions
Section titled “Exceptions”builder is null.
AddAgentSource(ITraconBuilder, IAgentSource)
Section titled “ AddAgentSource(ITraconBuilder, IAgentSource)”Registers a configured custom agent source as a singleton.
public static ITraconBuilder AddAgentSource(this ITraconBuilder builder, IAgentSource source)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
source IAgentSource
The source instance.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddAgentSource(ITraconBuilder, Func<IServiceProvider, IAgentSource>)
Section titled “ AddAgentSource(ITraconBuilder, Func<IServiceProvider, IAgentSource>)”Registers a custom agent-source factory as a singleton.
public static ITraconBuilder AddAgentSource(this ITraconBuilder builder, Func<IServiceProvider, IAgentSource> factory)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
factory Func<IServiceProvider, IAgentSource>
The factory that creates the source.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddEvalCheck(ITraconBuilder, string, EvalCheck)
Section titled “ AddEvalCheck(ITraconBuilder, string, EvalCheck)”Registers a custom eval check. Eval suites can reference it by
this kind name in their checks field.
public static ITraconBuilder AddEvalCheck(this ITraconBuilder builder, string kind, EvalCheck check)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
kind string
The check type name. Must not collide with a built-in type (for example nonEmpty).
check EvalCheck
A code-written check that does not call the model.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”An EvalCheck produced with
Microsoft.Agents.AI.FunctionEvaluator.Create(...) is expected.
Same reason as tools: custom logic is only defined in code, and a
free-form expression cannot be written from the interface.
builder.AddTracon() .AddEvalCheck("mentionsOrderId", FunctionEvaluator.Create( "mentionsOrderId", response => response.Contains("order", StringComparison.OrdinalIgnoreCase)));Exceptions
Section titled “Exceptions”builder is null.
AddHostedTool(ITraconBuilder, string, HostedToolKind, Func<HostedToolContext, AITool>, string?)
Section titled “ AddHostedTool(ITraconBuilder, string, HostedToolKind, Func<HostedToolContext, AITool>, string?)”Registers a tool the model provider runs on its own side: a web search, a code interpreter or a file search.
public static ITraconBuilder AddHostedTool(this ITraconBuilder builder, string name, HostedToolKind kind, Func<HostedToolContext, AITool> factory, string? description = null)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
name string
The name an agent definition selects the tool by in AgentDefinition.ToolNames. It is unique among function tools and hosted tools.
kind HostedToolKind
The kind of tool the factory builds.
factory Func<HostedToolContext, AITool>
Builds the tool for the agent being compiled. It must return the type that matches
kind (HostedWebSearchTool, HostedCodeInterpreterTool or
HostedFileSearchTool) and a new instance on every call.
description string?
The description the agent editor shows, or null.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”A hosted tool is code, as every tool is: the definition selects it by name, and its default is
off. The provider runs the tool inside the model call, so Tracon puts no timeout, approval or
permission in front of it, and what the tool reads (the web, a vector store, the data a code
interpreter is given) goes to the provider the model call already goes to. Each call is billed by the
provider: set Tracon:Pricing:HostedTools:{provider}:{kind}:PerCall so the cost reaches the run’s
budget, the tenant’s quota and the run.completed webhook.
The provider’s API surface decides whether the kind runs. A definition that selects a kind the surface drops does not compile; the agent validation names the tool and the provider. An agent selects at most one hosted tool of each kind.
The factory runs on every run of an agent that selects the tool, for the tenant of the run; keep it cheap.
A value that belongs to the tenant, such as the identifier of the tenant’s own vector store, is read
there. An identifier is not a secret; never put a credential into a hosted tool.
builder.AddTracon() .AddHostedTool( "docs_search", HostedToolKind.FileSearch, context => new HostedFileSearchTool { Inputs = [new HostedVectorStoreContent( context.Services.GetRequiredService<IConfiguration>()["VectorStores:Docs"]!)], }, description: "Searches the product documentation.");Exceptions
Section titled “Exceptions”builder, name or factory is null.
kind is not a defined kind.
The tool name does not follow the tool naming rules.
AddLoopEvaluator(ITraconBuilder, string, LoopEvaluator)
Section titled “ AddLoopEvaluator(ITraconBuilder, string, LoopEvaluator)”Registers a code-defined loop stop criterion with no description. A
definition’s LoopSettings.Criteria can then reference it by
this kind name.
public static ITraconBuilder AddLoopEvaluator(this ITraconBuilder builder, string kind, LoopEvaluator evaluator)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
kind string
The criterion name. It must not be one of the built-in kinds
(completionMarker, todoCompletion, aiJudge,
backgroundTaskCompletion, agentReview); shadowing one is rejected, so the same
definition cannot mean different things in two applications.
evaluator LoopEvaluator
The criterion. One instance serves every agent and every run that names the kind, so it must be thread-safe and keep no state of one run in its fields.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The same registration as the overload that takes a description; the console then shows the kind name alone.
Exceptions
Section titled “Exceptions”builder is null.
AddLoopEvaluator(ITraconBuilder, string, LoopEvaluator, string?)
Section titled “ AddLoopEvaluator(ITraconBuilder, string, LoopEvaluator, string?)”Registers a code-defined loop stop criterion. A definition’s
LoopSettings.Criteria can then reference it by this
kind name.
public static ITraconBuilder AddLoopEvaluator(this ITraconBuilder builder, string kind, LoopEvaluator evaluator, string? description)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
kind string
The criterion name. It must not be one of the built-in kinds
(completionMarker, todoCompletion, aiJudge,
backgroundTaskCompletion, agentReview); shadowing one is rejected, so the same
definition cannot mean different things in two applications.
evaluator LoopEvaluator
The criterion. Microsoft.Agents.AI.DelegateLoopEvaluator wraps a
plain function; a subclass of LoopEvaluator covers anything larger.
One instance serves every agent and every run that names the kind, so it
must be thread-safe and keep no state of one run in its fields.
description string?
What the criterion checks, in one sentence. The console shows it next to
the kind and GET /api/loop-criteria returns it to every reader, so
it must not carry a secret. null shows the kind alone.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”Same reason as tools and eval checks: a stop criterion whose logic is code is only ever defined in code. A definition arriving from the management API names the criterion, it never writes it. A criterion that needs an application service takes the factory overload instead.
The loop types are marked for evaluation only by Microsoft Agent Framework, so naming one in your own code needs the suppression below:
#pragma warning disable MAAI001builder.AddTracon() .AddLoopEvaluator("hasCitations", new DelegateLoopEvaluator((context, ct) => new ValueTask<LoopEvaluation>( context.LastResponse?.Text?.Contains("[1]", StringComparison.Ordinal) == true ? LoopEvaluation.Stop() : LoopEvaluation.Continue("Add a numbered citation for every claim."))));#pragma warning restore MAAI001Exceptions
Section titled “Exceptions”builder is null.
AddLoopEvaluator(ITraconBuilder, string, Func<IServiceProvider, LoopEvaluator>)
Section titled “ AddLoopEvaluator(ITraconBuilder, string, Func<IServiceProvider, LoopEvaluator>)”Registers a code-defined loop stop criterion that is created from the
application’s services. A definition’s LoopSettings.Criteria
can then reference it by this kind name.
public static ITraconBuilder AddLoopEvaluator(this ITraconBuilder builder, string kind, Func<IServiceProvider, LoopEvaluator> factory)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
kind string
The criterion name. It must not be one of the built-in kinds
(completionMarker, todoCompletion, aiJudge,
backgroundTaskCompletion, agentReview); shadowing one, or registering the same
name twice, is rejected before any factory runs.
factory Func<IServiceProvider, LoopEvaluator>
Creates the criterion from the application’s root service provider. It
runs once, on the first compilation of an agent whose loop names
kind, and its result serves every agent, every run and
every tenant from then on.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The same registration as the overload that takes a description; the console then shows the kind name alone. That overload’s remarks say when the factory runs and how a criterion reads the tenant.
Exceptions
Section titled “Exceptions”builder or factory is null.
AddLoopEvaluator(ITraconBuilder, string, Func<IServiceProvider, LoopEvaluator>, string?)
Section titled “ AddLoopEvaluator(ITraconBuilder, string, Func<IServiceProvider, LoopEvaluator>, string?)”Registers a code-defined loop stop criterion that is created from the
application’s services. A definition’s LoopSettings.Criteria
can then reference it by this kind name.
public static ITraconBuilder AddLoopEvaluator(this ITraconBuilder builder, string kind, Func<IServiceProvider, LoopEvaluator> factory, string? description)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
kind string
The criterion name. It must not be one of the built-in kinds
(completionMarker, todoCompletion, aiJudge,
backgroundTaskCompletion, agentReview); shadowing one, or registering the same
name twice, is rejected before any factory runs.
factory Func<IServiceProvider, LoopEvaluator>
Creates the criterion from the application’s root service provider. It
runs once, on the first compilation of an agent whose loop names
kind, and its result serves every agent, every run and
every tenant from then on.
description string?
What the criterion checks, in one sentence. The console shows it next to
the kind and GET /api/loop-criteria returns it to every reader, so
it must not carry a secret. null shows the kind alone.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”A criterion cannot take a service from LoopContext, which carries
none; the factory is where it takes them. The factory runs at the first
compilation rather than at setup, so a criterion may take the agent
catalog (IAgentCatalog): at setup the catalog is still being
built. When the factory throws, that compilation fails with a
TraconCompilationException naming the kind, and the next
compilation calls the factory again; a successful result is kept.
The provider is the root one. Take singletons from it; a scoped service
would outlive its scope. The tenant is not known when the factory runs:
read ITenantContext.TenantId inside
EvaluateAsync, never in the factory or the constructor, or every
tenant would see the first tenant’s value.
A reviewer agent as the criterion. The criterion below
computes a check in code, hands it to a reviewer agent from the catalog
with the draft, and reads the reviewer’s own JSON verdict. The reviewer
runs as a child of the run being evaluated: it appears under that run in
the run tree, spends from the same tree budget, and its tokens are its
own run’s usage. Per-run state, such as the round number, lives in
LoopContext.AdditionalProperties, which belongs to one loop run.
The draft is the last message of the turn: a harness turn can write a
plan or an earlier version first, and LastResponse.Text joins
every message of the turn.
#pragma warning disable MAAI001builder.AddTracon() .AddLoopEvaluator( "reviewed", services => { var catalog = services.GetRequiredService<IAgentCatalog>();
return new DelegateLoopEvaluator(async (context, cancellationToken) => { var messages = context.LastResponse?.Messages; var draft = messages is { Count: > 0 } ? messages[messages.Count - 1].Text : string.Empty; var words = draft.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length; var round = context.AdditionalProperties.TryGetValue("reviewed.round", out var r) ? (int)r! + 1 : 1; context.AdditionalProperties["reviewed.round"] = round;
var scope = TraconRunContext.Current; if (scope?.Budget is { } budget && (scope.Depth + 1 > budget.MaxDepth || !budget.TryReserveRun())) { throw new InvalidOperationException("The run tree has no room for the reviewer."); }
var reviewer = await catalog.ResolveAsync("reviewer", culture: null, cancellationToken) ?? throw new InvalidOperationException("No agent named 'reviewer'."); var options = scope is null ? null : new TraconRunOptions { ParentRunId = scope.RunId, RootRunId = scope.RootRunId, Depth = scope.Depth + 1, Budget = scope.Budget, SessionId = scope.SessionId, };
var review = await reviewer.RunAsync( $"Round {round}. Word count: {words}. Review this draft:\n{draft}", session: null, options, cancellationToken);
// The reviewer's ResponseFormat is a JSON schema: {"pass": bool, "feedback": string}. using var verdict = JsonDocument.Parse(review.Text); return verdict.RootElement.GetProperty("pass").GetBoolean() ? LoopEvaluation.Stop() : LoopEvaluation.Continue(verdict.RootElement.GetProperty("feedback").GetString() ?? "Revise the draft."); }); }, description: "The reviewer agent approves the draft.");#pragma warning restore MAAI001Exceptions
Section titled “Exceptions”builder or factory is null.
AddModelProvider<TProvider>(ITraconBuilder)
Section titled “ AddModelProvider<TProvider>(ITraconBuilder)”Registers a custom model provider as a singleton.
public static ITraconBuilder AddModelProvider<TProvider>(this ITraconBuilder builder) where TProvider : class, IModelProviderParameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
Returns
Section titled “Returns”The chain, for further configuration.
Type Parameters
Section titled “Type Parameters”TProvider
The provider implementation type.
Remarks
Section titled “Remarks”Calling this method more than once for the same provider type has no effect. Prefer this overload when the provider has no state to configure by hand; use TraconBuilderExtensions.AddModelProvider or the factory overload when it does.
builder.AddTracon() .AddModelProvider<OnPremiseModelProvider>();Exceptions
Section titled “Exceptions”builder is null.
AddModelProvider(ITraconBuilder, IModelProvider)
Section titled “ AddModelProvider(ITraconBuilder, IModelProvider)”Registers a model provider.
public static ITraconBuilder AddModelProvider(this ITraconBuilder builder, IModelProvider provider)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
provider IModelProvider
The provider.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The shipped provider packages (UseOpenAI, UseAnthropic,
and the rest) call this method. Register your own provider here when the
model sits behind an endpoint none of them describes.
builder.AddTracon() .AddModelProvider(new OnPremiseModelProvider(endpoint));Exceptions
Section titled “Exceptions”builder is null.
AddModelProvider(ITraconBuilder, Func<IServiceProvider, IModelProvider>)
Section titled “ AddModelProvider(ITraconBuilder, Func<IServiceProvider, IModelProvider>)”Registers a model provider through a factory.
public static ITraconBuilder AddModelProvider(this ITraconBuilder builder, Func<IServiceProvider, IModelProvider> factory)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
factory Func<IServiceProvider, IModelProvider>
The factory that produces the provider.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddRunJudge<TJudge>(ITraconBuilder)
Section titled “ AddRunJudge<TJudge>(ITraconBuilder)”Registers a custom run judge as a singleton.
public static ITraconBuilder AddRunJudge<TJudge>(this ITraconBuilder builder) where TJudge : class, IRunJudgeParameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
Returns
Section titled “Returns”The chain, for further configuration.
Type Parameters
Section titled “Type Parameters”TJudge
The judge implementation type.
Remarks
Section titled “Remarks”Repeating this overload for the same implementation type has no effect. The container creates and owns the singleton. The judge must be thread-safe because evaluations can overlap, including when a timed-out call finishes after a retry starts.
builder.AddTracon() .AddRunJudge<ResponseQualityJudge>();Exceptions
Section titled “Exceptions”builder is null.
AddRunJudge(ITraconBuilder, IRunJudge)
Section titled “ AddRunJudge(ITraconBuilder, IRunJudge)”Registers a configured run-judge instance as a singleton.
public static ITraconBuilder AddRunJudge(this ITraconBuilder builder, IRunJudge judge)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
judge IRunJudge
The judge instance.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The caller owns the instance and any resources it holds. Different configured instances of the same CLR type are preserved. Their IRunJudge.Name values must still be unique.
Exceptions
Section titled “Exceptions”builder is null.
AddRunJudge(ITraconBuilder, Func<IServiceProvider, IRunJudge>)
Section titled “ AddRunJudge(ITraconBuilder, Func<IServiceProvider, IRunJudge>)”Registers a run-judge factory as a singleton.
public static ITraconBuilder AddRunJudge(this ITraconBuilder builder, Func<IServiceProvider, IRunJudge> factory)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
factory Func<IServiceProvider, IRunJudge>
The factory that creates the judge.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The container owns the produced singleton. The factory must not capture a scoped dependency because the result outlives that scope. Different factories and configured results are preserved.
Exceptions
Section titled “Exceptions”builder is null.
AddScopedTool(ITraconBuilder, AIFunction, Action<ToolRegistrationOptions>)
Section titled “ AddScopedTool(ITraconBuilder, AIFunction, Action<ToolRegistrationOptions>)”Registers a tool that runs inside its own dependency-injection scope on every call.
public static ITraconBuilder AddScopedTool(this ITraconBuilder builder, AIFunction tool, Action<ToolRegistrationOptions> configure)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
tool AIFunction
The tool to register.
configure Action<ToolRegistrationOptions>
Configures the tool metadata.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”Identical in shape to TraconBuilderExtensions.AddTool —
the one difference is the word “scoped”, and its meaning is exactly
this: every call opens a fresh DependencyInjection.IServiceScope, exposes it
through AIFunctionArguments.Services, and closes it as
soon as the call finishes. Microsoft Agent Framework otherwise passes
an empty provider there — a dependency resolved from
AIFunctionArguments.Services without this method throws or
returns nothing, it is never silently wrong.
Use this for a tool that needs a repository, a DbContext, or
any other per-call dependency. Two concurrent calls never share a
scope.
builder.AddTracon() .AddScopedTool(AIFunctionFactory.Create( async (string orderId, AIFunctionArguments arguments) => { var orders = arguments.Services!.GetRequiredService<IOrderRepository>(); return await orders.GetAsync(orderId); }, "get_order"), options => options.RequiredPermission = "orders.read");Exceptions
Section titled “Exceptions”builder is null.
AddScopedTool(ITraconBuilder, AIFunction)
Section titled “ AddScopedTool(ITraconBuilder, AIFunction)”Registers a tool that runs inside its own dependency-injection scope on every call, with default metadata.
public static ITraconBuilder AddScopedTool(this ITraconBuilder builder, AIFunction tool)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
tool AIFunction
The tool to register.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddSkill(ITraconBuilder, AgentSkillDefinition)
Section titled “ AddSkill(ITraconBuilder, AgentSkillDefinition)”Defines a skill in code. A skill defined in code takes precedence over a runtime skill with the same name.
public static ITraconBuilder AddSkill(this ITraconBuilder builder, AgentSkillDefinition skill)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
skill AgentSkillDefinition
The skill to register.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”A skill is instruction text an agent loads by name. When it carries
AgentSkillDefinition.Scripts, those scripts run on the
server like stored ones: they need AllowStoredScripts, an
allow-listed interpreter, and a grant pinned to their content. The hash
to grant is read from GET /api/skills/{name}, which resolves a code
skill first. A deployment that changes a script changes its hash, so the
script needs a new grant before it runs again.
builder.AddTracon() .AddSkill(new AgentSkillDefinition { TenantId = "default", Name = "refund-policy", Description = "How a refund decision is made.", Instructions = "A refund under 100 USD is approved without review.", });Exceptions
Section titled “Exceptions”builder is null.
AddSpeechSynthesizer(ITraconBuilder, string, Func<IServiceProvider, ISpeechSynthesizer>)
Section titled “ AddSpeechSynthesizer(ITraconBuilder, string, Func<IServiceProvider, ISpeechSynthesizer>)”Registers a named speech synthesizer as a singleton.
public static ITraconBuilder AddSpeechSynthesizer(this ITraconBuilder builder, string name, Func<IServiceProvider, ISpeechSynthesizer> factory)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
name string
The registration name: 1 to 64 characters of a-z, 0-9, .,
_ or -, compared in lower case.
factory Func<IServiceProvider, ISpeechSynthesizer>
Creates the synthesizer once, the first time the name is resolved.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”A caller selects the synthesizer by name through
ISpeechProviderResolver.GetSynthesizerAsync: a workflow function
node, or POST /api/voice/speak with provider. The unnamed default
(UseVoice, or your own ISpeechSynthesizer registration)
is not affected, and the call can come before or after UseVoice.
The tenant’s egress policy applies to the synthesizer’s
ISpeechSynthesizer.ProviderName, not to name:
two names for one service are one provider to the policy. A factory that
returns the same instance for two names shares that instance, and its
concurrency limit, between them.
A synthesizer that can call the service with a tenant’s own key sets ISpeechSynthesizer.SupportsTenantCredentials and reads SpeechRequest.Credential. One that cannot is refused for a tenant that has its own binding for its provider name.
builder.AddTracon() .AddSpeechSynthesizer("studio", provider => new StudioSpeechSynthesizer( provider.GetRequiredService<IConfiguration>()["Studio:ApiKey"]));Exceptions
Section titled “Exceptions”builder or factory is null.
name is not a valid speech provider name.
A synthesizer with the same name is already registered.
AddSpeechSynthesizer(ITraconBuilder, string, TextToSpeechClientBinding)
Section titled “ AddSpeechSynthesizer(ITraconBuilder, string, TextToSpeechClientBinding)”Registers a named speech synthesizer that serves a Microsoft.Extensions.AI text-to-speech client.
public static ITraconBuilder AddSpeechSynthesizer(this ITraconBuilder builder, string name, TextToSpeechClientBinding binding)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
name string
The registration name: 1 to 64 characters of a-z, 0-9, .,
_ or -, compared in lower case.
binding TextToSpeechClientBinding
Which client in the container serves the name, and what the client cannot say about itself.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The result is an ordinary named synthesizer: the rules of TraconBuilderExtensions.AddSpeechSynthesizer apply. Every call passes the tenant’s egress policy against the provider name, and a tenant that has its own key for that provider is refused: a bridged client was built with the setup credential and cannot use another.
The host does not start when the client is not registered or has no provider name. Billing is an estimate: the client reports no billed characters, so Tracon records the length of the text and labels it SpeechUsageSource.Estimated. A request for character timing (SpeechRequest.IncludeTimestamps) is refused, and the synthesizer cannot voice a dialogue.
Do not put a secret in SpeechRequest.ProviderSettings: the values reach
the client unchanged, and a client wrapped in LoggingTextToSpeechClient logs its
options at Trace level.
#pragma warning disable MEAI001 // Microsoft.Extensions.AI marks its speech clients experimentalbuilder.Services.AddKeyedTextToSpeechClient("studio", provider => new StudioTextToSpeechClient( provider.GetRequiredService<IConfiguration>()["Studio:ApiKey"]));
builder.AddTracon() .AddSpeechSynthesizer("studio", new TextToSpeechClientBinding { ServiceKey = "studio", ProviderName = "studio", MaxCharactersPerRequest = 4000, });Exceptions
Section titled “Exceptions”builder or binding is null.
name is not a valid speech provider name, or
TextToSpeechClientBinding.MaxCharactersPerRequest is not greater than zero.
A synthesizer with the same name is already registered.
AddSpeechTranscriber(ITraconBuilder, string, Func<IServiceProvider, ISpeechTranscriber>)
Section titled “ AddSpeechTranscriber(ITraconBuilder, string, Func<IServiceProvider, ISpeechTranscriber>)”Registers a named speech transcriber as a singleton.
public static ITraconBuilder AddSpeechTranscriber(this ITraconBuilder builder, string name, Func<IServiceProvider, ISpeechTranscriber> factory)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
name string
The registration name: 1 to 64 characters of a-z, 0-9, .,
_ or -, compared in lower case. Transcriber names are separate
from synthesizer names.
factory Func<IServiceProvider, ISpeechTranscriber>
Creates the transcriber once, the first time the name is resolved.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”A caller selects the transcriber by name through ISpeechProviderResolver.GetTranscriberAsync. The rules of TraconBuilderExtensions.AddSpeechSynthesizer apply: the tenant’s policy reads ISpeechTranscriber.ProviderName, and a tenant credential reaches the transcriber only in SpeechTranscriptionOptions.Credential.
builder.AddTracon() .AddSpeechTranscriber("on-prem", provider => new OnPremiseTranscriber( new Uri("http://gpu-01:9000/")));Exceptions
Section titled “Exceptions”builder or factory is null.
name is not a valid speech provider name.
A transcriber with the same name is already registered.
AddSpeechTranscriber(ITraconBuilder, string, SpeechToTextClientBinding)
Section titled “ AddSpeechTranscriber(ITraconBuilder, string, SpeechToTextClientBinding)”Registers a named speech transcriber that serves a Microsoft.Extensions.AI speech-to-text client.
public static ITraconBuilder AddSpeechTranscriber(this ITraconBuilder builder, string name, SpeechToTextClientBinding binding)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
name string
The registration name: 1 to 64 characters of a-z, 0-9, .,
_ or -, compared in lower case. Transcriber names are separate
from synthesizer names.
binding SpeechToTextClientBinding
Which client in the container serves the name, and what the client cannot say about itself.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The rules of TraconBuilderExtensions.AddSpeechSynthesizer apply: the tenant’s egress policy and provider bindings read the provider name, and the host does not start when the client is missing or has no name.
The client’s contract takes the audio stream and no media type, so
mediaType is not passed on. The transcript has no duration unless the client
reports a start and an end time, and a transcription without a duration has no cost.
#pragma warning disable MEAI001 // Microsoft.Extensions.AI marks its speech clients experimentalbuilder.Services.AddKeyedSpeechToTextClient("studio", provider => new StudioSpeechToTextClient( provider.GetRequiredService<IConfiguration>()["Studio:ApiKey"]));
builder.AddTracon() .AddSpeechTranscriber("studio", new SpeechToTextClientBinding { ServiceKey = "studio", ProviderName = "studio", });Exceptions
Section titled “Exceptions”builder or binding is null.
name is not a valid speech provider name.
A transcriber with the same name is already registered.
AddTool(ITraconBuilder, AIFunction, Action<ToolRegistrationOptions>)
Section titled “ AddTool(ITraconBuilder, AIFunction, Action<ToolRegistrationOptions>)”Registers a tool.
public static ITraconBuilder AddTool(this ITraconBuilder builder, AIFunction tool, Action<ToolRegistrationOptions> configure)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
tool AIFunction
The tool to register.
configure Action<ToolRegistrationOptions>
Configures the tool metadata.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”The AOT-safe overload: the caller supplies the built
AI.AIFunction, so no reflection is involved.
builder.AddTracon() .AddTool(refundTool, options => options.RequiresApproval = true);Exceptions
Section titled “Exceptions”builder is null.
AddTool(ITraconBuilder, AIFunction)
Section titled “ AddTool(ITraconBuilder, AIFunction)”Registers a tool with default metadata.
public static ITraconBuilder AddTool(this ITraconBuilder builder, AIFunction tool)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
tool AIFunction
The tool to register.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddTool(ITraconBuilder, Delegate, string?, string?, Action<ToolRegistrationOptions>?)
Section titled “ AddTool(ITraconBuilder, Delegate, string?, string?, Action<ToolRegistrationOptions>?)”Builds and registers a tool from a method.
[RequiresUnreferencedCode("Building a tool from a method uses reflection; type information may be lost in trimmed applications.")][RequiresDynamicCode("Building a tool from a method may require code generation at runtime.")]public static ITraconBuilder AddTool(this ITraconBuilder builder, Delegate method, string? name = null, string? description = null, Action<ToolRegistrationOptions>? configure = null)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
method Delegate
The method to expose as a tool.
name string?
The tool name.
description string?
The tool description.
configure Action<ToolRegistrationOptions>?
Configures the tool metadata.
Returns
Section titled “Returns”The chain, for further configuration.
Exceptions
Section titled “Exceptions”builder is null.
AddToolsFrom<T>(ITraconBuilder)
Section titled “ AddToolsFrom<T>(ITraconBuilder)”Registers, as tools, the methods on a type that are marked with TraconToolAttribute.
[RequiresUnreferencedCode("Tool scanning uses reflection; method information may be lost in trimmed applications.")][RequiresDynamicCode("Tool scanning may require code generation at runtime.")]public static ITraconBuilder AddToolsFrom<T>(this ITraconBuilder builder)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
Returns
Section titled “Returns”The chain, for further configuration.
Type Parameters
Section titled “Type Parameters”T
The type to scan.
Remarks
Section titled “Remarks”Marking is an explicit choice: every new method added to the class is not automatically exposed to agents. Static methods bind directly; for instance methods, the owning object is resolved from the service provider at call time.
A static class cannot be a type argument (a C# rule).
If your tools live in a static class, use the
TraconBuilderExtensions.AddToolsFrom overload instead.
This method uses reflection and is not safe under trimming or native AOT scenarios. Applications targeting AOT should use the TraconBuilderExtensions.AddTool overload instead.
builder.AddTracon() .AddToolsFrom<OrderTools>();Exceptions
Section titled “Exceptions”builder is null.
T has no marked method, or a marked method cannot
be converted to a tool.
AddToolsFrom(ITraconBuilder, Type)
Section titled “ AddToolsFrom(ITraconBuilder, Type)”Registers, as tools, the methods on a type that are marked with TraconToolAttribute.
[RequiresUnreferencedCode("Tool scanning uses reflection; method information may be lost in trimmed applications.")][RequiresDynamicCode("Tool scanning may require code generation at runtime.")]public static ITraconBuilder AddToolsFrom(this ITraconBuilder builder, Type type)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
type Type
The type to scan. May be a static class.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”A static class cannot be a type argument under C# rules; this overload
makes the AddToolsFrom(typeof(OrderTools)) form possible.
Exceptions
Section titled “Exceptions”builder or type is null.
type has no marked method, or a marked method cannot
be converted to a tool.
Configure(ITraconBuilder, Action<TraconOptions>)
Section titled “ Configure(ITraconBuilder, Action<TraconOptions>)”Modifies the runtime settings.
public static ITraconBuilder Configure(this ITraconBuilder builder, Action<TraconOptions> configure)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
configure Action<TraconOptions>
The settings modifier.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”Runs after the configuration section is bound, so a value set here wins
over appsettings.json.
builder.AddTracon() .Configure(options => options.Tools.DefaultTimeout = TimeSpan.FromSeconds(60));Exceptions
Section titled “Exceptions”builder is null.
RequireCustomBinding<T>(ITraconBuilder)
Section titled “ RequireCustomBinding<T>(ITraconBuilder)”Declares that T must resolve to the application’s
own registration. The host does not start when Tracon’s built-in
default is what resolves.
public static ITraconBuilder RequireCustomBinding<T>(this ITraconBuilder builder) where T : classParameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
Returns
Section titled “Returns”The chain, for further configuration.
Type Parameters
Section titled “Type Parameters”T
One of the seven embedding points: ITenantContext,
IRunAttributionContext, IToolAuthorizationHandler,
IRunAuthorizationHandler, IRunEventSink,
IAttachmentStorage, or IToolApprovalPresenter;
or a contract Tracon registers a built-in default for: a store interface,
or ISkillScriptExecutor once UseSkillScripts is called.
Any other type stops the host from starting, with a message naming the seven.
Remarks
Section titled “Remarks”Off by default: an application that never calls this behaves exactly as
before. Every extension point is registered with TryAdd, so a host
that binds nothing runs on the built-in default and starts silently. That
suits a first run; it does not suit a deployment whose module order can
leave an authorization handler on the permissive default without anyone
noticing until the first unauthorized request.
The check runs while the host starts, not when endpoints are mapped, so
an embedded host with no HTTP surface gets the same guarantee. Register
the implementation BEFORE AddTracon: a TryAdd
registration made afterwards is dropped, and the built-in default stays.
This is a composition gate. It proves which implementation is bound; it proves nothing about whether that implementation decides correctly.
builder.Services.AddSingleton<IRunAuthorizationHandler, OrderDeskAuthorization>();
builder.AddTracon() .RequireCustomBinding<IRunAuthorizationHandler>() .RequireCustomBinding<IToolAuthorizationHandler>();Exceptions
Section titled “Exceptions”builder is null.
RequireProductionProfile(ITraconBuilder, Action<TraconProductionProfileOptions>?)
Section titled “ RequireProductionProfile(ITraconBuilder, Action<TraconProductionProfileOptions>?)”Refuses to start the host while a security-sensitive decision is still on its permissive default and the deployment has not accepted the risk by name.
public static ITraconBuilder RequireProductionProfile(this ITraconBuilder builder, Action<TraconProductionProfileOptions>? configure = null)Parameters
Section titled “Parameters”builder ITraconBuilder
The Tracon configuration chain.
configure Action<TraconProductionProfileOptions>?
The risks this deployment has deliberately decided to carry. Omit it to accept none, which is the strictest form.
Returns
Section titled “Returns”The chain, for further configuration.
Remarks
Section titled “Remarks”This does not make anything secure and changes no setting. It sets no value, chooses no policy and turns nothing on. The only thing it does is turn a skipped decision into a startup failure - which is the one thing a permissive default cannot do for itself.
Off by default: an application that never calls this behaves exactly as
before. AddTracon brings every security-sensitive switch up
permissive on purpose, so a first run surprises nobody. A production
deployment wants the opposite, and today it can reach production having
never separated tenants, never decided who owns a session and never
registered a content guard, in complete silence.
Six decisions are asked about: tenant separation, session ownership, at-rest content protection, content inspection, request rate limiting and retention. Each one is either answered by turning the feature on, or accepted by name. Acceptance is per item and there is no way to accept them all at once.
The set of decisions is a versioned contract. A later release that adds one stops a host that calls this method until the new decision is answered or accepted. Read that cost before adopting the method: it is the method working, not failing.
This is a composition gate, not a security proof. It proves a feature is switched on; it proves nothing about whether the policy behind it is right.
builder.AddTracon() .RequireProductionProfile(profile => profile .Accept(TraconProductionRisk.SingleTenant) .Accept(TraconProductionRisk.UnboundedRetention));Exceptions
Section titled “Exceptions”builder is null.