# CompiledAgentCache

> 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.compiledagentcache/
> Summary: CompiledAgentCache: Caches compiled agents keyed by (tenant, name, definition fingerprint, dependency fingerprint, culture), holding one entry per (tenant, name, definition.

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

Caches compiled agents keyed by
`(tenant, name, definition fingerprint, dependency fingerprint, culture)`,
holding one entry per `(tenant, name, definition fingerprint, culture)`.

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

**The key measures CONTENT, not a version number.** An earlier
design keyed the entry by the definition's version and relied on "a save
increments the version, so the entry naturally goes stale". That reasoning
does not hold for a DELETE followed by a CREATE of the same name: a store
that restarts numbering (the built-in ones did, until they kept the numbering) makes the
new definition version `1` again, and the
deleted definition's compiled agent kept answering every run - the database
read correctly while the run did not. Measured on a real host.

The version component was therefore replaced by a fingerprint of the
definition's own serialized content
([AgentDefinitionCompiler.CreateDefinitionFingerprint](/api/tracon.agentdefinitioncompiler/#Tracon_AgentDefinitionCompiler_CreateDefinitionFingerprint_Tracon_AgentDefinition_)). Two
entries share a compiled agent only when the definitions that produced them
are byte-identical, which is exactly when sharing is correct. No explicit
invalidation is needed, and none exists: an entry that can no longer be
reached is simply never read again.

The same rule covers what the agent depends on outside its definition. The
dependency fingerprint measures skills, callable sub-agents, a shared
instructions block, the tenant's egress policy, and the connection each remote
(MCP) tool is bound to: a policy saved after an agent was cached changes the
key, and the next resolve compiles again under that policy; a server definition
changed or deleted after an agent was cached changes the key too, and the next
resolve binds the live connection or fails the way an uncached compile does.

**The cache is bounded by definitions, not by dependency changes.**
The dependency fingerprint changes without any operator action: a remote MCP
server that edits a tool's description or schema changes it at the next refresh.
Each `(tenant, name, definition fingerprint, culture)` therefore holds ONE
entry, and a compile under a new dependency fingerprint replaces it; the replaced
agent is never read again. The definition fingerprint stays a separate slot: two
versions of one agent served side by side (an experiment's variants) must not
evict each other on every run. A new definition version still adds a slot, which
only an operator's save can produce.

The `tenant` component of the key is REQUIRED. Agent names are unique
only within a tenant (see `SqlAgentDefinitionStore`) - it is common for
two different tenants to have a definition with the same name (e.g.
`"support"`), byte-identical content, and the same dependency
fingerprint (an empty string for both if they use no skills/callable
agents). If the tenant is not included in the key,
resolution for the second tenant returns the first tenant's compiled agent
(instructions, tool bindings - including the tenant identity bound into
e.g. `search_knowledge`): tenant isolation broken outright.

## Properties

### <a id="Tracon_CompiledAgentCache_Count"></a> Count

Number of entries in the cache: one per tenant, agent name, definition, and culture.

```csharp
public int Count { get; }
```

#### Property Value

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

### <a id="Tracon_CompiledAgentCache_Clear"></a> Clear\(\)

Empties the cache entirely.

```csharp
public void Clear()
```

### <a id="Tracon_CompiledAgentCache_CombineFingerprints_System_String_System_String_"></a> CombineFingerprints\(string, string\)

Combines multiple dependency fingerprints into a single key component.

```csharp
public static string CombineFingerprints(string first, string second)
```

#### Parameters

`first` [string](https://learn.microsoft.com/dotnet/api/system.string)

First fingerprint.

`second` [string](https://learn.microsoft.com/dotnet/api/system.string)

Second fingerprint.

#### Returns

 [string](https://learn.microsoft.com/dotnet/api/system.string)

The combined fingerprint.

#### Remarks

A separator is required: fingerprints may not have a fixed length, and a
direct concatenation would let two different pairs produce the same string.

### <a id="Tracon_CompiledAgentCache_GetOrAdd_System_String_System_String_System_String_System_Func_Microsoft_Agents_AI_AIAgent__"></a> GetOrAdd\(string, string, string, Func<AIAgent\>\)

Retrieves the agent from the cache; if absent, produces it with
`factory` and adds it.

```csharp
public AIAgent GetOrAdd(string tenantId, string name, string definitionFingerprint, Func<AIAgent> factory)
```

#### Parameters

`tenantId` [string](https://learn.microsoft.com/dotnet/api/system.string)

Identifier of the tenant requesting resolution.

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)

Agent name.

`definitionFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

Fingerprint of the definition's own content; see
[AgentDefinitionCompiler.CreateDefinitionFingerprint](/api/tracon.agentdefinitioncompiler/#Tracon_AgentDefinitionCompiler_CreateDefinitionFingerprint_Tracon_AgentDefinition_).

`factory` [Func](https://learn.microsoft.com/dotnet/api/system.func\-1)<AIAgent\>

Producer called when absent from the cache.

#### Returns

 AIAgent

The compiled agent.

#### Exceptions

 [ArgumentNullException](https://learn.microsoft.com/dotnet/api/system.argumentnullexception)

One of the parameters is [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null).

### <a id="Tracon_CompiledAgentCache_GetOrAdd_System_String_System_String_System_String_System_String_System_Func_Microsoft_Agents_AI_AIAgent__"></a> GetOrAdd\(string, string, string, string, Func<AIAgent\>\)

Retrieves the agent from the cache together with its dependency
fingerprint; if absent, produces it with `factory`
and adds it.

```csharp
public AIAgent GetOrAdd(string tenantId, string name, string definitionFingerprint, string dependencyFingerprint, Func<AIAgent> factory)
```

#### Parameters

`tenantId` [string](https://learn.microsoft.com/dotnet/api/system.string)

Identifier of the tenant requesting resolution.

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)

Agent name.

`definitionFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

Fingerprint of the definition's own content; see
[AgentDefinitionCompiler.CreateDefinitionFingerprint](/api/tracon.agentdefinitioncompiler/#Tracon_AgentDefinitionCompiler_CreateDefinitionFingerprint_Tracon_AgentDefinition_).

`dependencyFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

Current fingerprint of what the compiled agent depends on outside its
definition: skills, callable sub-agents, a shared instructions block, the
tenant's egress policy, and the connection each remote tool is bound to.
These can change while the definition stays the same, so they need a
separate key component.

`factory` [Func](https://learn.microsoft.com/dotnet/api/system.func\-1)<AIAgent\>

Producer called when absent from the cache.

#### Returns

 AIAgent

The compiled agent.

### <a id="Tracon_CompiledAgentCache_GetOrAdd_System_String_System_String_System_String_System_String_System_String_System_Func_Microsoft_Agents_AI_AIAgent__"></a> GetOrAdd\(string, string, string, string, string, Func<AIAgent\>\)

Retrieves the agent from the cache together with its dependency fingerprint and
requested culture; if absent, produces it with `factory` and adds it.

```csharp
public AIAgent GetOrAdd(string tenantId, string name, string definitionFingerprint, string dependencyFingerprint, string culture, Func<AIAgent> factory)
```

#### Parameters

`tenantId` [string](https://learn.microsoft.com/dotnet/api/system.string)

Identifier of the tenant requesting resolution.

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)

Agent name.

`definitionFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

Fingerprint of the definition's own content; see
[AgentDefinitionCompiler.CreateDefinitionFingerprint](/api/tracon.agentdefinitioncompiler/#Tracon_AgentDefinitionCompiler_CreateDefinitionFingerprint_Tracon_AgentDefinition_).

`dependencyFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

See [CompiledAgentCache.GetOrAdd](/api/tracon.compiledagentcache/).

`culture` [string](https://learn.microsoft.com/dotnet/api/system.string)

The culture the definition was compiled with (resolved against
[AgentDefinition.InstructionsByCulture](/api/tracon.agentdefinition/#Tracon_AgentDefinition_InstructionsByCulture)).
An empty string when the run requested no culture. Part of the key: two runs of the
same definition in different cultures must not share a compiled agent - the requested
instructions text is baked into `AI.ChatOptions` at
compile time.

`factory` [Func](https://learn.microsoft.com/dotnet/api/system.func\-1)<AIAgent\>

Producer called when absent from the cache.

#### Returns

 AIAgent

The compiled agent.

### <a id="Tracon_CompiledAgentCache_GetOrAddAsync_System_String_System_String_System_String_System_String_System_Func_System_Threading_Tasks_ValueTask_Microsoft_Agents_AI_AIAgent___"></a> GetOrAddAsync\(string, string, string, string, Func<ValueTask<AIAgent\>\>\)

Retrieves the agent from the cache together with its dependency
fingerprint; if absent, produces it asynchronously with
`factory` and adds it.

```csharp
public ValueTask<AIAgent> GetOrAddAsync(string tenantId, string name, string definitionFingerprint, string dependencyFingerprint, Func<ValueTask<AIAgent>> factory)
```

#### Parameters

`tenantId` [string](https://learn.microsoft.com/dotnet/api/system.string)

Identifier of the tenant requesting resolution.

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)

Agent name.

`definitionFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

Fingerprint of the definition's own content; see
[AgentDefinitionCompiler.CreateDefinitionFingerprint](/api/tracon.agentdefinitioncompiler/#Tracon_AgentDefinitionCompiler_CreateDefinitionFingerprint_Tracon_AgentDefinition_).

`dependencyFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

See [CompiledAgentCache.GetOrAdd](/api/tracon.compiledagentcache/).

`factory` [Func](https://learn.microsoft.com/dotnet/api/system.func\-1)<[ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<AIAgent\>\>

Producer called when absent from the cache.

#### Returns

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

#### Remarks

Compiling now needs an async credential lookup on a
cache miss. `Concurrent.ConcurrentDictionary` has no
native async `GetOrAdd`; the same "the factory may run more than
once, production is side-effect free, an extra instance is discarded"
guarantee as the sync overload applies here too.

### <a id="Tracon_CompiledAgentCache_GetOrAddAsync_System_String_System_String_System_String_System_String_System_String_System_Func_System_Threading_Tasks_ValueTask_Microsoft_Agents_AI_AIAgent___"></a> GetOrAddAsync\(string, string, string, string, string, Func<ValueTask<AIAgent\>\>\)

Retrieves the agent from the cache together with its dependency fingerprint and
requested culture; if absent, produces it asynchronously with
`factory` and adds it.

```csharp
public ValueTask<AIAgent> GetOrAddAsync(string tenantId, string name, string definitionFingerprint, string dependencyFingerprint, string culture, Func<ValueTask<AIAgent>> factory)
```

#### Parameters

`tenantId` [string](https://learn.microsoft.com/dotnet/api/system.string)

Identifier of the tenant requesting resolution.

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)

Agent name.

`definitionFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

Fingerprint of the definition's own content; see
[AgentDefinitionCompiler.CreateDefinitionFingerprint](/api/tracon.agentdefinitioncompiler/#Tracon_AgentDefinitionCompiler_CreateDefinitionFingerprint_Tracon_AgentDefinition_).

`dependencyFingerprint` [string](https://learn.microsoft.com/dotnet/api/system.string)

See [CompiledAgentCache.GetOrAdd](/api/tracon.compiledagentcache/).

`culture` [string](https://learn.microsoft.com/dotnet/api/system.string)

See [CompiledAgentCache.GetOrAdd](/api/tracon.compiledagentcache/).

`factory` [Func](https://learn.microsoft.com/dotnet/api/system.func\-1)<[ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<AIAgent\>\>

Producer called when absent from the cache.

#### Returns

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