Skip to content

RunRecordingAgent

Namespace AgentPrism · Assembly AgentPrism.Core.dll

Writes every run of the wrapped agent into IRunStore as events, emits its metrics and collects its spans.

public sealed class RunRecordingAgent : DelegatingAIAgent

object ← AIAgent ← DelegatingAIAgent ← RunRecordingAgent

DelegatingAIAgent.GetService(Type, object?), DelegatingAIAgent.Name, DelegatingAIAgent.Description, AIAgent.GetService(Type, object?), AIAgent.GetService<TService>(object?), AIAgent.CreateSessionAsync(CancellationToken), AIAgent.SerializeSessionAsync(AgentSession, JsonSerializerOptions?, CancellationToken), AIAgent.DeserializeSessionAsync(JsonElement, JsonSerializerOptions?, CancellationToken), AIAgent.RunAsync(AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunAsync(string, AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunAsync(ChatMessage, AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunAsync(IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunStreamingAsync(AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunStreamingAsync(string, AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunStreamingAsync(ChatMessage, AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunStreamingAsync(IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, CancellationToken), AIAgent.RunAsync<T>(AgentSession?, JsonSerializerOptions?, AgentRunOptions?, CancellationToken), AIAgent.RunAsync<T>(string, AgentSession?, JsonSerializerOptions?, AgentRunOptions?, CancellationToken), AIAgent.RunAsync<T>(ChatMessage, AgentSession?, JsonSerializerOptions?, AgentRunOptions?, CancellationToken), AIAgent.RunAsync<T>(IEnumerable<ChatMessage>, AgentSession?, JsonSerializerOptions?, AgentRunOptions?, CancellationToken), AIAgent.Id, AIAgent.Name, AIAgent.Description, AIAgent.CurrentRunContext, object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

This is not a Microsoft Agent Framework middleware but a AI.DelegatingAIAgent wrapper. The reason: the MAF middleware chain is specific to one agent, and HarnessAgent adds its own inner decorators. The outer wrapper works the same way on every agent type, the harness included.

Tool calls are read from the AI.FunctionCallContent and AI.FunctionResultContent contents that MAF produces; no separate hook is necessary.

The root span starts here. The wrapper is the outermost decorator (Order = 0), therefore the agentprism.run span that it opens collects the spans of the inner wrappers and of the model calls as children. This is the only way to link the run identifier and the trace identifier to each other.

RunRecordingAgent(AIAgent, IRunStore, ITenantContext, AgentPrismRunRecordingOptions, ILogger<RunRecordingAgent>, AgentPrismMetrics?, RunTraceCollector?, string?, string?, TimeProvider?, AgentPrismAgentGraphOptions?, int?, bool, IRunPricingResolver?, QuotaEnforcer?, IWebhookPublisher?, IRunCancellationRegistry?, IRunErrorClassifier?, IRunInputStore?, RunSampler?, ContentGuardPipeline?, IRunAttributionContext?, IReadOnlyList<IRunEventSink>?)

Section titled “ RunRecordingAgent(AIAgent, IRunStore, ITenantContext, AgentPrismRunRecordingOptions, ILogger<RunRecordingAgent>, AgentPrismMetrics?, RunTraceCollector?, string?, string?, TimeProvider?, AgentPrismAgentGraphOptions?, int?, bool, IRunPricingResolver?, QuotaEnforcer?, IWebhookPublisher?, IRunCancellationRegistry?, IRunErrorClassifier?, IRunInputStore?, RunSampler?, ContentGuardPipeline?, IRunAttributionContext?, IReadOnlyList<IRunEventSink>?)”

Creates a new recording wrapper.

public RunRecordingAgent(AIAgent innerAgent, IRunStore runStore, ITenantContext tenantContext, AgentPrismRunRecordingOptions options, ILogger<RunRecordingAgent> logger, AgentPrismMetrics? metrics = null, RunTraceCollector? traceCollector = null, string? modelId = null, string? modelProvider = null, TimeProvider? timeProvider = null, AgentPrismAgentGraphOptions? graphOptions = null, int? agentVersion = null, bool includeAgentVersionTag = true, IRunPricingResolver? pricingResolver = null, QuotaEnforcer? quotaEnforcer = null, IWebhookPublisher? webhookPublisher = null, IRunCancellationRegistry? cancellationRegistry = null, IRunErrorClassifier? errorClassifier = null, IRunInputStore? runInputStore = null, RunSampler? runSampler = null, ContentGuardPipeline? contentGuardPipeline = null, IRunAttributionContext? attributionContext = null, IReadOnlyList<IRunEventSink>? sinks = null)

innerAgent AIAgent

The wrapped agent.

runStore IRunStore

The store that the events are written to.

tenantContext ITenantContext

The tenant context.

options AgentPrismRunRecordingOptions

The recording detail settings.

logger ILogger<RunRecordingAgent>

The logger.

metrics AgentPrismMetrics?

The metric instruments. When null, no metric is emitted.

traceCollector RunTraceCollector?

The span collector. When null, no span is written.

modelId string?

The model that the agent is bound to. null when unknown.

modelProvider string?

The model provider that the agent is bound to. It is used only for cost resolution and is not persisted.

timeProvider TimeProvider?

The time source. When null, the system clock is used.

graphOptions AgentPrismAgentGraphOptions?

The call tree limits. When null, the defaults are used.

agentVersion int?

The current definition version that comes from the catalog summary of the agent. null when it is unknown (for example a code agent). On a run that an A/B experiment resolves, AgentPrismRunOptions.AgentVersion overrides it.

includeAgentVersionTag bool

Whether the Tags.AgentVersion tag is added to the span and to the metrics. See AgentPrismObservabilityOptions.IncludeAgentVersionTag.

pricingResolver IRunPricingResolver?

The cost resolver. When null, no cost is calculated.

quotaEnforcer QuotaEnforcer?

The quota accountant. When null, consumption is not counted. Only root runs are counted; child runs are part of the same request and must not be counted twice.

webhookPublisher IWebhookPublisher?

The event publisher. When null, no run.* event is emitted.

cancellationRegistry IRunCancellationRegistry?

The cancellation registry. When null, the run cannot be canceled from outside (POST /api/runs/{id}/cancel).

errorClassifier IRunErrorClassifier?

The error classifier. When null, the error class and the grouping fingerprint are not calculated (RunError.Class/RunError.Fingerprint stay empty).

runInputStore IRunInputStore?

The input store. When null, or when AgentPrismRunRecordingOptions.RecordRunInput is off, the input is not written and the run cannot be replayed.

runSampler RunSampler?

The online evaluation sampler. When null, no run is sampled.

contentGuardPipeline ContentGuardPipeline?

The content guard pipeline. When null, or when ContentGuardPipeline.HasGuards is false, the input is recorded raw. When it is supplied, the input written to the RunStarted event and to IRunInputStore passes through the SAME inspection as the text that AgentPrism.ContentGuardingChatClient sends to the model — if the two diverge, masked or blocked content stays raw in the durable store.

attributionContext IRunAttributionContext?

The attribution context. When null, the run records no user and no labels — the same outcome as the built-in DefaultRunAttributionContext with no ambient scope open.

sinks IReadOnlyList<IRunEventSink>?

The run event observers. When null or empty, every event goes to runStore only — the identical hot path as before this extension point existed.

ArgumentNullException

When one of the required dependencies is null.

RunCoreAsync(IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, CancellationToken)

Section titled “ RunCoreAsync(IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, CancellationToken)”
protected override Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)

messages IEnumerable<ChatMessage>

session AgentSession?

options AgentRunOptions?

cancellationToken CancellationToken

Task<AgentResponse>

RunCoreStreamingAsync(IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, CancellationToken)

Section titled “ RunCoreStreamingAsync(IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, CancellationToken)”
protected override IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)

messages IEnumerable<ChatMessage>

session AgentSession?

options AgentRunOptions?

cancellationToken CancellationToken

IAsyncEnumerable<AgentResponseUpdate>