Rejects text in which a regular expression finds no match.
Works as both an InputGuardrail and an OutputGuardrail. Use it to enforce a format (an email address, a phone number, an order id) or to require that some text is present.
The pattern is searched for, not matched against the whole text: [0-9]+ accepts order 66. Anchor the pattern (^[0-9]+$) to require that the whole text fits, with one caveat: by default $ also matches just before a line terminator that ends the text, so ^[0-9]+$ accepts 66 followed by one line break. These are standard java.util.regex semantics, and inline flags such as (?m), (?s) and (?d) change them; see java.util.regex.Pattern for the details.
Patterns are user-supplied, so matching goes through org.llm4s.security.RegexSafetyManager, whichever way the validator was built: text that is null or longer than 100000 characters is rejected before matching, and a match that exceeds its character-access budget (the guard against catastrophic backtracking) is aborted. Only the companion's String factories also pre-screen the pattern itself: there a pattern that is null, empty after trimming, longer than 1000 characters, or matches a known catastrophic-backtracking shape is refused. The shape check is a rough textual heuristic aimed at nested quantifiers and quantified alternation (it refuses (a+)+ and (cat|dog)*): it refuses some harmless patterns and misses some dangerous ones. A pattern passed as a scala.util.matching.Regex or a compiled java.util.regex.Pattern (the constructors, RegexValidator(regex), RegexValidator.email, RegexValidator.phone and RegexValidator.alphanumeric) is used as given, with no pre-screen; its matching is still bounded.
validate reports failures as a org.llm4s.error.ValidationError for the field value. Its detail is errorMessage when one was given, else Value does not match pattern: <pattern>, for a plain mismatch. Other failures use their own detail: Regex security error: <reason> when the text is null or too long, or the match is aborted or otherwise fails, and Invalid or unsafe regex pattern: <reason> for every text when the pattern was given as a String and was refused or did not compile. That last failure replaces any custom message, so a bad pattern shows up on the first validation rather than as a startup error.
The JDK regex engine recurses as it matches some patterns, such as (a|aa)*b, and on long enough text it can overflow the stack before reaching the character-access budget. The safety manager catches that StackOverflowError and aborts the match, so validate returns a Regex security error Left for it too rather than throwing. The String factories' pre-screen refuses some of these shapes (including that one), but not all of them.
Prefer the String factories (RegexValidator("...") and RegexValidator("...", errorMessage)) for patterns that are not fixed in code: they are the only ones that compile through org.llm4s.security.RegexSafetyManager.safeCompile and pre-screen the pattern.
Value parameters
- compiledPattern
-
the pattern to search for, already compiled; used as given, without the safety manager's pre-screen
- errorMessage
-
the detail to report on a plain mismatch; the default message names the pattern
- fallbackError
-
when set,
validatefails every text with this detail, ignoring the pattern; the companion'sStringfactories set it when the pattern is refused or does not compile - patternDescription
-
the pattern's source text, used in the default error and in
description
Attributes
- Example
-
import org.llm4s.agent.guardrails.builtin.RegexValidator val orderId = RegexValidator("^ORD-[0-9]{6}$", "Order ids look like ORD-123456") orderId.validate("ORD-123456") // Right("ORD-123456") orderId.validate("ORD-123456\n") // Right: `$` also accepts one trailing line break orderId.validate("ORD-12") // Left(ValidationError): "Order ids look like ORD-123456" agent.run(query, tools, inputGuardrails = Seq(RegexValidator.email)) - Companion
- object
- Graph
-
- Supertypes
-
trait OutputGuardrailtrait InputGuardrailtrait Guardrail[String]class Objecttrait Matchableclass Any