ContentGuardPipeline
AgentPrism.Core.dllPipeline that runs the registered IContentGuard implementations in sequence and records their decisions.
public sealed class ContentGuardPipelineInheritance
Section titled “Inheritance”Inherited Members
Section titled “Inherited Members”object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()
Remarks
Section titled “Remarks”Guards run in registration order and the strictest decision wins: if a guard returns ContentGuardAction.Mask the text is replaced and the replaced version is handed to the next guard; if a guard returns ContentGuardAction.Block the chain stops immediately. Because Block is the taxonomy’s highest value, the outcome does not depend on registration order.
If a guard throws, the run fails. The “observability does not break functionality” rule does not apply here: a guard is a control, not an observation tool, and content that cannot be inspected is not let through.
The recording of the decision, however, is subject to that rule: if the event writer or the audit log fails, the failure is logged and the decision is still applied. The decision itself is never lost.
Constructors
Section titled “Constructors”ContentGuardPipeline(IEnumerable<IContentGuard>, IOptionsMonitor<AgentPrismContentGuardOptions>, IAuditLog, IAuditActorResolver, ITenantContext, ILoggerFactory)
Section titled “ ContentGuardPipeline(IEnumerable<IContentGuard>, IOptionsMonitor<AgentPrismContentGuardOptions>, IAuditLog, IAuditActorResolver, ITenantContext, ILoggerFactory)”Creates a new pipeline.
public ContentGuardPipeline(IEnumerable<IContentGuard> guards, IOptionsMonitor<AgentPrismContentGuardOptions> options, IAuditLog auditLog, IAuditActorResolver actorResolver, ITenantContext tenantContext, ILoggerFactory loggerFactory)Parameters
Section titled “Parameters”guards IEnumerable<IContentGuard>
The registered guards. May be empty.
options IOptionsMonitor<AgentPrismContentGuardOptions>
Pipeline settings.
auditLog IAuditLog
The audit log to write blocking decisions to.
actorResolver IAuditActorResolver
The audit log actor resolver.
tenantContext ITenantContext
The tenant context to use when no run scope is available.
loggerFactory ILoggerFactory
The logger factory.
Exceptions
Section titled “Exceptions”One of the dependencies is null.
Properties
Section titled “Properties”HasGuards
Section titled “ HasGuards”Whether at least one guard is registered.
public bool HasGuards { get; }Property Value
Section titled “Property Value”Remarks
Section titled “Remarks”If false, ModelProviderRegistry
never adds the inspection wrapper to the pipeline: not
even a single if runs on the model-call path.
Options
Section titled “ Options”The pipeline’s current settings.
public AgentPrismContentGuardOptions Options { get; }Property Value
Section titled “Property Value”Methods
Section titled “Methods”InspectAsync(ContentGuardDirection, string, string?, CancellationToken)
Section titled “ InspectAsync(ContentGuardDirection, string, string?, CancellationToken)”Runs a piece of text through every guard.
public ValueTask<string?> InspectAsync(ContentGuardDirection direction, string text, string? modelId, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”direction ContentGuardDirection
The direction of the inspection.
text string
The text to inspect.
modelId string?
The identity of the model being called.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”The masked text; null if no guard requested a change. A null return tells the caller it needs to rebuild nothing, and is the allocation-free path.
Exceptions
Section titled “Exceptions”AgentPrismContentBlockedException
A guard returned ContentGuardAction.Block.
PreviewAsync(ContentGuardDirection, string, string?, CancellationToken)
Section titled “ PreviewAsync(ContentGuardDirection, string, string?, CancellationToken)”Runs text through every guard but records no
decision — it writes to neither the event writer nor the audit log.
public ValueTask<string?> PreviewAsync(ContentGuardDirection direction, string text, string? modelId, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”direction ContentGuardDirection
text string
modelId string?
cancellationToken CancellationToken
Returns
Section titled “Returns”The text to record; null if no guard requested a change (the caller should use the original text).
Remarks
Section titled “Remarks”This exists for RunRecordingAgent’s BeginRunAsync:
the text written to the RunStarted event and to
IRunInputStore must be THE SAME as the guard’s decision,
but at this stage the run row (runs) does not exist
yet. When ContentGuardPipeline.InspectAsync finds a decision it calls
scope.Writer.AppendAsync; without a runs row the store
rejects it and the writer is PERMANENTLY disabled for the whole run
(RunEventWriter.IsDisabled). This method applies THE SAME
guard order and masking chain without carrying that risk; the actual
decision recording happens when AgentPrism.ContentGuardingChatClient
calls ContentGuardPipeline.InspectAsync normally on the way to the model.
On a block, no exception is thrown — the caller should
continue starting the run; the real block happens on the way to the
model, and the run then closes with Failed/content_blocked.