guard

package
v1.9.2 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package guard defines the guardrails subsystem for content safety.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Action

type Action string

Action describes the guard's response.

const (
	ActionAllow  Action = "allow"
	ActionBlock  Action = "block"
	ActionRedact Action = "redact" // remove sensitive content
	ActionWarn   Action = "warn"   // allow but flag
)

type BlockedError

type BlockedError struct {
	Guard    string
	Phase    Phase
	Reason   string
	Usage    *provider.Usage
	Model    string
	Provider string
}

BlockedError reports that a guard refused a request. Guard names the guard that blocked it. An output-phase block happens after the provider answered and charged for it, so Usage, Model and Provider carry what the refused response consumed; they are empty for an input block.

func (*BlockedError) Error

func (e *BlockedError) Error() string

func (*BlockedError) RefusalCode

func (e *BlockedError) RefusalCode() string

RefusalCode and StatusCode let an HTTP edge map a block to 400 the way it maps any other refusal. The usage stage still records it as blocked.

func (*BlockedError) StatusCode

func (e *BlockedError) StatusCode() int

type CheckInput

type CheckInput struct {
	Messages []provider.Message
	TenantID string
	Metadata map[string]string
}

CheckInput is the content to evaluate.

type CheckResult

type CheckResult struct {
	Passed   bool               // true if content is OK
	Blocked  bool               // true if content should be rejected
	Action   Action             // what to do
	Reason   string             // human-readable explanation
	Modified bool               // true if messages were altered (e.g., PII redacted)
	Messages []provider.Message // modified messages (if Modified)
	Details  map[string]any     // guard-specific details
	Guard    string             // set by Service: the guard that blocked, or the last one that modified the messages
}

CheckResult is the guard's verdict.

type Guard

type Guard interface {
	// Name returns the guard identifier.
	Name() string

	// Phase returns when this guard runs: "input", "output", or "both".
	Phase() Phase

	// Check evaluates content against this guard's rules.
	Check(ctx context.Context, input *CheckInput) (*CheckResult, error)
}

Guard is a single content safety rule.

type GuardedStream

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

GuardedStream wraps a provider.Stream and applies guardrails.

func NewGuardedStream

func NewGuardedStream(inner provider.Stream, guards []StreamGuard, strategy StreamStrategy) *GuardedStream

NewGuardedStream creates a new guarded stream wrapper.

func (*GuardedStream) Close

func (gs *GuardedStream) Close() error

Close releases resources.

func (*GuardedStream) Next

Next returns the next chunk, applying the configured guard strategy.

func (*GuardedStream) Usage

func (gs *GuardedStream) Usage() *provider.Usage

Usage returns final usage after stream completes.

type OutputGuardedStream

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

OutputGuardedStream runs output-phase guards over a streamed response. The strategy decides when the consumer sees the chunks:

  • StrategyBuffer holds every chunk until the stream ends, then checks the whole message (text and tool calls). A block ends the stream with *BlockedError before any chunk is delivered. A rewrite is replayed as a new stream built from the rewritten message: one content delta, one complete tool-call delta per call, the finish reason and the usage. It carries no reasoning and no native content. Otherwise the original chunks are replayed.
  • StrategyPassthrough delivers chunks as they arrive and checks the message when the provider ends the stream. A block replaces io.EOF with *BlockedError, so a consumer that runs tool calls only after a clean end never runs a blocked one. A rewrite cannot be applied to text already delivered: the stream ends with io.EOF and the change is lost.
  • StrategyChunkwise checks every chunk with the registered StreamGuards before delivering it, then checks the message at the end as StrategyPassthrough does.

StreamGuards also check each chunk under StrategyBuffer, before anything is delivered. StrategyPassthrough does not run them.

Native content holds the reply's original text and thinking. Under the streaming strategies the chunks that carry it are held back until the verdict: a block never delivers them, and a rewrite delivers them without it.

func NewOutputGuardedStream

func NewOutputGuardedStream(inner provider.Stream, svc Service, input *CheckInput, strategy StreamStrategy) *OutputGuardedStream

NewOutputGuardedStream wraps inner so that svc's output-phase guards check the streamed message. input carries the tenant and metadata the guards see; its Messages are replaced with the streamed message. An empty or unknown strategy is StrategyBuffer. A nil svc runs no output guards.

func (*OutputGuardedStream) Close

func (s *OutputGuardedStream) Close() error

Close closes the upstream stream once.

func (*OutputGuardedStream) Next

Next returns the next chunk the strategy has cleared, or the verdict.

func (*OutputGuardedStream) Usage

func (s *OutputGuardedStream) Usage() *provider.Usage

Usage returns the usage the stream reported in its chunks, or the upstream stream's own.

func (*OutputGuardedStream) WithStreamGuards

func (s *OutputGuardedStream) WithStreamGuards(guards ...StreamGuard) *OutputGuardedStream

WithStreamGuards adds guards that check every chunk under StrategyBuffer and StrategyChunkwise.

type Phase

type Phase string

Phase indicates when a guard runs.

const (
	PhaseInput  Phase = "input"
	PhaseOutput Phase = "output"
	PhaseBoth   Phase = "both"
)

type Service

type Service interface {
	// Register adds a guard.
	Register(g Guard)

	// Check runs all applicable guards for the given phase.
	// Returns on first block; aggregates all redactions.
	Check(ctx context.Context, input *CheckInput) (*CheckResult, error)

	// CheckPhase runs guards for a specific phase only.
	CheckPhase(ctx context.Context, phase Phase, input *CheckInput) (*CheckResult, error)

	// List returns all registered guards.
	List() []Guard
}

Service manages and executes guards.

func NewService

func NewService() Service

NewService creates a new guard service.

type StreamGuard

type StreamGuard interface {
	Guard

	// CheckChunk evaluates a single stream chunk.
	CheckChunk(ctx context.Context, chunk *provider.StreamChunk) (*CheckResult, error)
}

StreamGuard applies content safety checks to streaming responses.

type StreamStrategy

type StreamStrategy string

StreamStrategy controls how guards are applied to streams.

const (
	// StrategyBuffer buffers the entire response, then checks it.
	StrategyBuffer StreamStrategy = "buffer"

	// StrategyPassthrough lets chunks through immediately with post-hoc audit.
	StrategyPassthrough StreamStrategy = "passthrough"

	// StrategyChunkwise checks each chunk individually as it arrives.
	StrategyChunkwise StreamStrategy = "chunkwise"
)

Directories

Path Synopsis
Package guards provides built-in guardrail implementations.
Package guards provides built-in guardrail implementations.
Package shieldadapter provides a guardrail adapter that bridges an external Shield content safety engine to the Nexus guard.Guard interface.
Package shieldadapter provides a guardrail adapter that bridges an external Shield content safety engine to the Nexus guard.Guard interface.

Jump to

Keyboard shortcuts

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