% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/rate_guard.R
\name{rate_guard}
\alias{rate_guard}
\title{Create or check a rate guard}
\usage{
rate_guard(
  max_tokens = NULL,
  max_requests = NULL,
  window_seconds = 3600L,
  strict = FALSE,
  concurrent = FALSE
)
}
\arguments{
\item{max_tokens}{Maximum tokens per window, \code{NULL}, or an existing
\code{shieldr_rate_guard} when checking a guard with \code{rate_guard(guard)}.}

\item{max_requests}{Maximum requests per window, or \code{NULL}.}

\item{window_seconds}{Window length in seconds.}

\item{strict}{Whether \code{\link[=secure_chat]{secure_chat()}} should reserve estimated prompt tokens
before calling the model.}

\item{concurrent}{Whether to protect \verb{$usage()} and \verb{$update()} with a
file-based lock from the suggested \code{filelock} package.}
}
\value{
When creating a guard, a \code{shieldr_rate_guard} environment. When
checking a guard, \code{TRUE} if usage is within limits.
}
\description{
Rate guards are explicit stateful environments used to cap token and request
budgets for LLM workflows. Resource exhaustion is covered by OWASP LLM10; see
\url{https://genai.owasp.org/llm-top-10/}.
}
\details{
Calling \code{rate_guard()} with limits creates a new \code{shieldr_rate_guard}
environment. The environment stores counters for the current window and
exposes two methods:
\itemize{
\item \verb{$usage()}: returns current counters and configured limits.
\item \verb{$reserve(tokens, requests)}: atomically checks projected usage and then
increments counters when the reservation stays within limits.
\item \verb{$update(tokens, requests)}: backward-compatible alias for \verb{$reserve()}.
\item \verb{$rollback(tokens, requests)}: subtracts a previous reservation after a
guarded operation fails before completion.
}

Calling \code{rate_guard(guard)} checks an existing environment and returns
\code{TRUE} if all counters are within limits. Reservation methods fail before
projected usage exceeds the configured token or request limit. Limits set to
\code{NULL} are disabled for that dimension.

Windows reset automatically when \code{window_seconds} has elapsed. This object
is intentionally stateful; it is the one place where llmshieldr expects
mutable state, because rate limiting is inherently session-based.
}
\section{Concurrency}{

The rate guard is not safe for concurrent use by default. Parallel or async R
code (\code{future}, \code{parallel}, \code{callr}) that shares a single guard environment
will produce inaccurate counts. Use \code{concurrent = TRUE} and install the
\code{filelock} package to make each \verb{$usage()}, \verb{$reserve()}, \verb{$update()}, and
\verb{$rollback()} call acquire a file-based lock within a single machine.
Cross-machine coordination is not supported.
}

\section{Pre-call Reservation}{

With \code{strict = TRUE}, \code{\link[=secure_chat]{secure_chat()}} reserves an estimated prompt token cost
and one request before the model call, then records only the positive
difference between the actual token estimate and the reserved amount after
the call. If the chat call or output scan fails, the pre-call reservation is
rolled back. This makes shared guards more useful under bursty load, but
estimated tokens may differ from actual usage. Strict mode is recommended
when multiple callers share one guard.
}

\examples{
guard <- rate_guard(max_tokens = 100)
guard$reserve(tokens = 10)
rate_guard(guard)
}
