guardrails

package
v1.5.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: Apache-2.0 Imports: 9 Imported by: 3

Documentation

Overview

Package guardrails provides built-in ProviderHook implementations that bridge the unified eval system to the pipeline's hook infrastructure.

Index

Constants

View Source
const (
	DirectionInput  = hooks.DirectionInput
	DirectionOutput = hooks.DirectionOutput
	DirectionBoth   = hooks.DirectionBoth
)

Aliases of the canonical direction constants, retained for existing callers. See runtime/hooks for what each value means; the vocabulary lives there so the pipeline stage need not import a concrete hook implementation to tag a firing.

Variables

View Source
var ErrEmptySpec = errors.New(
	"uninitialized Spec — build it with Input, Output, InputFunc or OutputFunc")

ErrEmptySpec is returned by Spec.Hook for a zero-value Spec — one that never went through Input, Output, InputFunc or OutputFunc. Reachable from a pre-sized slice (make([]guardrails.Spec, n)) whose entries a branch failed to assign; returning an error keeps that config mistake out of the panic path.

View Source
var ErrUnknownGuardrailType = errors.New("unknown guardrail type")

ErrUnknownGuardrailType is returned when a validator names an eval type that is not registered. It is distinguishable from other construction failures because it is treated as fatal: an unknown type has no legitimate use, so dropping it would leave a conversation silently unprotected. See CompileValidators.

Functions

func CompileValidators added in v1.5.8

func CompileValidators(validators []prompt.ValidatorConfig) ([]hooks.ProviderHook, error)

CompileValidators turns pack-declared validators into ProviderHooks suitable for prepending to a hook registry. Both SDK.Open and Arena's per-turn pipeline use this so guardrails run identically in production and in tests.

Per-validator behavior:

  • Validators with Enabled == &false are skipped silently (explicit opt-out). nil Enabled means enabled (spec default).
  • All accepted validators enforce: on a hit they rewrite the assistant message in place (truncate or replace). If you want observe-only behavior, declare an eval and assert on it; guardrails always act.
  • "message" set on the validator becomes the user-facing blocked text, falling back to Params["message"].

Failure policy, split by how ambiguous the mistake is:

  • An **unknown eval type** is FATAL and returns ErrUnknownGuardrailType. A type that is not registered has no legitimate use — it is a typo — and silently dropping it leaves the conversation with no protection while load appears to succeed. That is fail-open on a safety control.
  • A validator whose **params** are unusable is logged and skipped, so one bad entry does not break the others. A pack authored against a newer runtime can legitimately carry params this build does not understand; refusing to load would make packs forward-incompatible.

On a fatal error no hooks are returned, so a caller cannot accidentally proceed with a partial guardrail set.

func CompileValidatorsWithRegistry added in v1.5.8

func CompileValidatorsWithRegistry(
	validators []prompt.ValidatorConfig, registry *evals.EvalTypeRegistry,
) ([]hooks.ProviderHook, error)

CompileValidatorsWithRegistry is CompileValidators resolving each validator's eval type against the supplied registry instead of the built-in default. Pass the registry a caller configured (sdk.WithEvalRegistry) so a custom handler can back a pack validator; a nil registry means the default one.

Without this the default registry does not know a custom type, construction fails, and — on the lenient path — the guardrail is logged and dropped, which leaves the conversation unprotected while load appears to succeed (#1717).

func NewGuardrailHook

func NewGuardrailHook(typeName string, params map[string]any, opts ...GuardrailOption) (hooks.ProviderHook, error)

NewGuardrailHook creates a guardrail ProviderHook using the default eval registry.

func NewGuardrailHookFromRegistry added in v1.3.12

func NewGuardrailHookFromRegistry(
	typeName string, params map[string]any, registry *evals.EvalTypeRegistry,
	opts ...GuardrailOption,
) (hooks.ProviderHook, error)

NewGuardrailHookFromRegistry creates a guardrail ProviderHook using the eval registry. Any registered eval handler (including aliases) can be used as a guardrail.

If the handler implements evals.ParamValidator, the params are normalised (ApplyDefaults + NormalizeParams) and passed to ValidateParams before the hook is constructed. This surfaces invalid pack validators at SDK load time instead of silently failing every turn — handlers for which params are unusable return an error here, and the SDK's warn-and-skip loop in convertPackValidatorsToHooks logs and drops them.

func ValidatorsToHooks deprecated added in v1.4.9

func ValidatorsToHooks(validators []prompt.ValidatorConfig) []hooks.ProviderHook

ValidatorsToHooks is the lenient form: every unusable validator — including an unknown eval type — is logged and skipped, and the usable ones are still returned.

Deprecated: use CompileValidators. This form cannot report an unknown eval type, so a typo'd validator is silently dropped and the caller proceeds unprotected. Retained unchanged so existing callers keep their behavior.

func ValidatorsToHooksWithRegistry deprecated added in v1.5.8

func ValidatorsToHooksWithRegistry(
	validators []prompt.ValidatorConfig, registry *evals.EvalTypeRegistry,
) []hooks.ProviderHook

ValidatorsToHooksWithRegistry is the lenient form of CompileValidatorsWithRegistry: every unusable validator — including an unknown eval type — is logged and skipped. A nil registry means the default one.

Deprecated: use CompileValidatorsWithRegistry. This form cannot report an unknown eval type, so a typo'd validator is silently dropped and the caller proceeds unprotected.

Types

type GuardrailHookAdapter added in v1.3.12

type GuardrailHookAdapter struct {
	// contains filtered or unexported fields
}

GuardrailHookAdapter wraps an evals.EvalTypeHandler as a hooks.ProviderHook. This bridges the unified eval system to the pipeline's hook infrastructure, allowing any registered eval handler to be used as a guardrail.

Guardrails always enforce: on a hit the adapter mutates the response (truncate or replace) and returns an Enforced decision so the pipeline continues. If you want observe-only behavior, declare an eval — not a guardrail — and assert on it in scenarios.

func (*GuardrailHookAdapter) AfterCall added in v1.3.12

AfterCall checks provider output when direction is "output" or "both". When the guardrail triggers, it enforces in-place on resp.Message (truncating or replacing content) and returns an Enforced decision.

func (*GuardrailHookAdapter) BeforeCall added in v1.3.12

BeforeCall checks input when direction is "input" or "both".

It evaluates only when the last message is a user message (see lastUserTurn). BeforeCall runs once per round inside the tool loop, where later rounds end in a tool-result message rather than user input — evaluating those would score the wrong content and rebill LLM-judged checks every round. The gate is deliberately content-based rather than round-based: a round check would also misfire on a round whose last message is an assistant message, and round numbering is per-ProviderStage (it restarts in each composition sub-pipeline), so it is not a reliable proxy for "there is new user input".

func (*GuardrailHookAdapter) Name added in v1.3.12

func (a *GuardrailHookAdapter) Name() string

Name returns the eval type identifier for this guardrail.

func (*GuardrailHookAdapter) OnChunk added in v1.3.12

OnChunk evaluates streaming chunks via StreamableEvalHandler.EvalPartial. When a guardrail triggers, it truncates the chunk content and returns an Enforced decision so the provider stage can stop reading but continue the pipeline.

type GuardrailOption added in v1.3.12

type GuardrailOption func(*GuardrailHookAdapter)

GuardrailOption configures a GuardrailHookAdapter.

func WithMessage added in v1.3.12

func WithMessage(msg string) GuardrailOption

WithMessage sets the user-facing message shown when content is blocked.

type Spec added in v1.5.8

type Spec struct {
	// contains filtered or unexported fields
}

Spec is a declared guardrail, not yet built into a hook. Construction errors (unknown eval type, invalid params) surface from Hook() so callers can declare guardrails inline and report all failures at one point — typically sdk.Open.

func Input added in v1.5.8

func Input(evalType string, params map[string]any, opts ...GuardrailOption) Spec

Input declares an eval-backed guardrail that gates the user's input before the provider call. Any registered eval handler may be named.

guardrails.Input("pii_leakage", nil)

func InputFunc added in v1.5.8

func InputFunc(
	name string, fn func(context.Context, *hooks.InputRequest) hooks.Decision,
) Spec

InputFunc declares a guardrail from a plain function gating user input. The function runs once per user turn: it is skipped on tool-loop rounds, where the last message is a tool result rather than user input.

guardrails.InputFunc("no-wires", func(ctx context.Context, in *hooks.InputRequest) hooks.Decision {
    if strings.Contains(in.UserInput, "wire transfer") {
        in.Replacement = "I can't help with transfers."
        return hooks.Enforced("wire transfer requested", nil)
    }
    return hooks.Allow
})

func Output added in v1.5.8

func Output(evalType string, params map[string]any, opts ...GuardrailOption) Spec

Output declares an eval-backed guardrail that gates the assistant's response.

func OutputFunc added in v1.5.8

func OutputFunc(
	name string, fn func(context.Context, *hooks.OutputRequest) hooks.Decision,
) Spec

OutputFunc declares a guardrail from a plain function gating the assistant response. Mutate OutputRequest.Message in place and return Enforced to rewrite. Returning Enforced also stops the provider round loop and drops any tool calls the response requested; downstream pipeline stages still run.

func (Spec) Hook added in v1.5.8

func (s Spec) Hook() (hooks.ProviderHook, error)

Hook builds the ProviderHook this Spec describes against the default eval registry. A zero-value Spec returns ErrEmptySpec rather than panicking.

func (Spec) HookWithRegistry added in v1.5.8

func (s Spec) HookWithRegistry(registry *evals.EvalTypeRegistry) (hooks.ProviderHook, error)

HookWithRegistry builds the ProviderHook resolving an eval-backed guardrail's type against registry. A nil registry means the default one, so HookWithRegistry(nil) and Hook() are equivalent.

Callers that let a user supply their own evals.EvalTypeRegistry — the SDK's WithEvalRegistry — must use this form. Building against the default registry makes a custom eval type unknown, and the guardrail is then dropped rather than enforced (#1717). Func-backed Specs (InputFunc, OutputFunc) ignore the registry: they carry their own logic.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL