# AgentExtensionContext

> 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.agentextensioncontext/
> Summary: AgentExtensionContext: The agent an IAgentExtension is configuring: the definition, the tenant, the one options object the compiler is about to build the agent from, and the wrappers.

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

The agent an [IAgentExtension](/api/tracon.iagentextension/) is configuring: the definition, the
tenant, the one options object the compiler is about to build the agent from, and
the wrappers and chat client rings the extension adds.

```csharp
public sealed class AgentExtensionContext
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.agentextensioncontext/">AgentExtensionContext</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

Exactly one of [AgentExtensionContext.ChatAgentOptions](/api/tracon.agentextensioncontext/#Tracon_AgentExtensionContext_ChatAgentOptions) and [AgentExtensionContext.HarnessAgentOptions](/api/tracon.agentextensioncontext/#Tracon_AgentExtensionContext_HarnessAgentOptions)
is set. It is the one the agent's kind selects: a definition with
[AgentDefinition.Harness](/api/tracon.agentdefinition/#Tracon_AgentDefinition_Harness) is a harness agent. Change the options
object in place; do not keep it. The compiler reads it once after the last
extension has run.

## Properties

### <a id="Tracon_AgentExtensionContext_ChatAgentOptions"></a> ChatAgentOptions

Gets the options of a chat agent, or [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when the agent is a
harness agent.

```csharp
public ChatClientAgentOptions? ChatAgentOptions { get; }
```

#### Property Value

 ChatClientAgentOptions?

### <a id="Tracon_AgentExtensionContext_Definition"></a> Definition

Gets the definition the agent is compiled from. Changing a copy of it has no effect.

```csharp
public AgentDefinition Definition { get; }
```

#### Property Value

 [AgentDefinition](/api/tracon.agentdefinition/)

### <a id="Tracon_AgentExtensionContext_HarnessAgentOptions"></a> HarnessAgentOptions

Gets the options of a harness agent, or [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when the agent is a
chat agent.

```csharp
public HarnessAgentOptions? HarnessAgentOptions { get; }
```

#### Property Value

 HarnessAgentOptions?

### <a id="Tracon_AgentExtensionContext_Services"></a> Services

Gets the application's root service provider. A scoped service is not available
here: the compiled agent outlives the request that compiled it.

```csharp
public IServiceProvider Services { get; }
```

#### Property Value

 [IServiceProvider](https://learn.microsoft.com/dotnet/api/system.iserviceprovider)

### <a id="Tracon_AgentExtensionContext_TenantId"></a> TenantId

Gets the tenant the agent is compiled for.

```csharp
public string TenantId { get; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

## Methods

### <a id="Tracon_AgentExtensionContext_Use_System_Func_Microsoft_Agents_AI_AIAgent_Microsoft_Agents_AI_AIAgent__"></a> Use\(Func<AIAgent, AIAgent\>\)

Adds a wrapper that is put around the compiled agent. A Microsoft Agent
Framework middleware (`AIAgentBuilder.Use`) belongs here.

```csharp
public void Use(Func<AIAgent, AIAgent> wrap)
```

#### Parameters

`wrap` [Func](https://learn.microsoft.com/dotnet/api/system.func\-2)<AIAgent, AIAgent\>

Receives the agent and returns the agent that replaces it.

#### Remarks

A wrapper sits innermost: Tracon's own wrappers and the catalog's decorators (run
recording, budget, tool approval) stay outside it. With several wrappers the
first one added is the innermost.

A wrapper is not checked. It sees what the model call sees and can change it;
that is what a middleware is for.

#### Exceptions

 [ArgumentNullException](https://learn.microsoft.com/dotnet/api/system.argumentnullexception)

`wrap` is [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null).

### <a id="Tracon_AgentExtensionContext_UseChatClient_Tracon_ChatClientSlot_System_Func_Microsoft_Extensions_AI_IChatClient_Microsoft_Extensions_AI_IChatClient__"></a> UseChatClient\(ChatClientSlot, Func<IChatClient, IChatClient\>\)

Adds a ring to the agent's model pipeline in the given slot. A
`Microsoft.Extensions.AI` `AI.DelegatingChatClient` belongs here, for
example a client that the framework documents as one that sees every model call.

```csharp
public void UseChatClient(ChatClientSlot slot, Func<IChatClient, IChatClient> ring)
```

#### Parameters

`slot` [ChatClientSlot](/api/tracon.chatclientslot/)

Where the ring sits in the pipeline.

`ring` [Func](https://learn.microsoft.com/dotnet/api/system.func\-2)<IChatClient, IChatClient\>

Receives the client below the ring and returns the ring.

#### Remarks

The agent keeps every Tracon ring around the one you add: the content guard, the run
budget, the response cache and the `chat` span stay below it, and the circuit breaker,
the fallback chain and error normalization stay above it. A fallback link that answers in
place of the agent's model gets the same ring. The compaction summarizer and the judge of
a loop criterion do not.

With several rings in one slot the first one added is the innermost, as with
[AgentExtensionContext.Use](/api/tracon.agentextensioncontext/#Tracon_AgentExtensionContext_Use_System_Func_Microsoft_Agents_AI_AIAgent_Microsoft_Agents_AI_AIAgent__). A ring is not checked. It sees what the model call sees and can
change it. The content guard still inspects the user, assistant and tool messages that it
sends. The guard does not inspect a system message or `ChatOptions.Instructions`, and
the ring receives the response after the guard has inspected it.

`ring` runs each time the pipeline is built: when the agent is compiled,
and when a fallback link is first used. Keep it cheap and keep state that belongs to one
run out of it. Derive the ring from `AI.DelegatingChatClient`: a
[ChatClientSlot.Turn](/api/tracon.chatclientslot/) ring that hides the tool-call loop below it from
`IChatClient.GetService` fails the compilation.

An exception that the ring throws while it serves a call is the host's own. It is not
counted by the circuit breaker and not masked as a provider failure, as with a wrapper
added by [AgentExtensionContext.Use](/api/tracon.agentextensioncontext/#Tracon_AgentExtensionContext_Use_System_Func_Microsoft_Agents_AI_AIAgent_Microsoft_Agents_AI_AIAgent__). A provider failure that passes up through the ring is still
both.

```csharp
builder.AddTracon()
       .AddAgentExtension(
           "model-call-log",
           context => context.UseChatClient(
               ChatClientSlot.ModelCall,
               inner => new ModelCallLogChatClient(inner)));
```

#### Exceptions

 [ArgumentNullException](https://learn.microsoft.com/dotnet/api/system.argumentnullexception)

`ring` is [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null).

 [ArgumentOutOfRangeException](https://learn.microsoft.com/dotnet/api/system.argumentoutofrangeexception)

`slot` is not a defined value.
