Skip to content

QuotaEnforcer

Namespace AgentPrism · Assembly AgentPrism.Core.dll

Enforces quota rules and records the consumption of completed runs.

public sealed class QuotaEnforcer

objectQuotaEnforcer

object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

The quota is approximate. The check happens before a run starts; consumption is written after it finishes. Runs that start at the same time can exceed the quota by a small margin. A strict guarantee would require taking a lock before every run and adds latency to every request. “Approximate quota” is an honest statement; “exact quota” would promise something that is not delivered.

An in-progress run is not cut off when the quota is exceeded: a half-finished response with tokens already spent is worse than a consistent result. Only a new run gets 429.

QuotaEnforcer(IQuotaStore, IOptionsMonitor<AgentPrismQuotaOptions>, IWebhookPublisher?, TimeProvider?, ILogger<QuotaEnforcer>?)

Section titled “ QuotaEnforcer(IQuotaStore, IOptionsMonitor<AgentPrismQuotaOptions>, IWebhookPublisher?, TimeProvider?, ILogger<QuotaEnforcer>?)”

Enforces quota rules and records the consumption of completed runs.

public QuotaEnforcer(IQuotaStore store, IOptionsMonitor<AgentPrismQuotaOptions> optionsMonitor, IWebhookPublisher? webhookPublisher = null, TimeProvider? timeProvider = null, ILogger<QuotaEnforcer>? logger = null)

store IQuotaStore

optionsMonitor IOptionsMonitor<AgentPrismQuotaOptions>

webhookPublisher IWebhookPublisher?

timeProvider TimeProvider?

logger ILogger<QuotaEnforcer>?

The quota is approximate. The check happens before a run starts; consumption is written after it finishes. Runs that start at the same time can exceed the quota by a small margin. A strict guarantee would require taking a lock before every run and adds latency to every request. “Approximate quota” is an honest statement; “exact quota” would promise something that is not delivered.

An in-progress run is not cut off when the quota is exceeded: a half-finished response with tokens already spent is worse than a consistent result. Only a new run gets 429.

CheckAsync(string, string, CancellationToken)

Section titled “ CheckAsync(string, string, CancellationToken)”

Checks whether a new run is allowed.

public ValueTask<QuotaDecision> CheckAsync(string tenantId, string agentName, CancellationToken cancellationToken = default)

tenantId string

The tenant identity.

agentName string

The name of the agent to run.

cancellationToken CancellationToken

The cancellation token.

ValueTask<QuotaDecision>

The decision. If allowed, QuotaDecision.IsAllowed is true.

RecordAsync(QuotaConsumption, CancellationToken)

Section titled “ RecordAsync(QuotaConsumption, CancellationToken)”

Adds a completed run’s consumption to the counters and, if needed, publishes a threshold event.

public ValueTask RecordAsync(QuotaConsumption consumption, CancellationToken cancellationToken = default)

consumption QuotaConsumption

The consumption.

cancellationToken CancellationToken

The cancellation token.

ValueTask

The completion task.

This call never throws: quota accounting is an observability function and must not retroactively break a completed run.