Class: Vangrail::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/vangrail/builder.rb

Overview

Reads the environment into an engine. A class rather than a method so each decision is separable and testable on its own.

Constant Summary collapse

DEFAULT_RAILS =
%i[input context output].freeze
ALL_RAILS =
%i[input context output grounding secrets patterns links multiturn privacy
markup budget semantic perplexity bayes linear].freeze
INJECTION_PATTERNS =

Deterministic input patterns, kept small on purpose. Each is a phrase whose presence is itself the violation; anything needing judgement belongs in a policy rail, where a false positive is a model's opinion rather than a hard rule.

{
  'instruction_override' => /\b(?:ignore|disregard)\s+(?:(?:all|any|the|your|those|these)\s+)?(?:previous|prior|above|earlier)\s+instructions?\b/i,
  'prompt_disclosure' => /\b(?:reveal|print|repeat|show|output)\s+(?:me\s+)?(?:your|the|its)?\s*
                          (?:system\s+prompt|initial\s+instructions|developer\s+message)\b/xi,
  'role_reset' => /\byou\s+are\s+now\s+(?:a|an|in)\b.{0,40}\b(?:mode|persona|dan|jailbreak)\b/i,
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env = ENV) ⇒ Builder

Returns a new instance of Builder.



24
25
26
# File 'lib/vangrail/builder.rb', line 24

def initialize(env = ENV)
  @env = env
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



22
23
24
# File 'lib/vangrail/builder.rb', line 22

def env
  @env
end

Class Method Details

.deterministic(side, patterns: true) ⇒ Object

The offline stack that does not need a folder or an endpoint: patterns, concepts, near-copies, the decoding pass, and the language posture. Config#engine(stdlib: true) prepends the same list so a NeMo folder does not certain-pass a question nothing here can read.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/vangrail/builder.rb', line 44

def self.deterministic(side, patterns: true)
  side = side.to_sym
  return [] if side == :output

  core = [
    (Rails::InjectedInstructions.new if side == :context),
    (if side == :input && patterns
       Rails::Pattern.new(patterns: INJECTION_PATTERNS, name: 'injection_patterns',
                          sides: [side])
     end),
    Rails::Jailbreak.new(sides: [side]),
    Rails::Paraphrase.new(sides: [side]),
    Rails::Alignment.new(sides: [side]),
    Rails::Similarity.new(sides: [side]),
    Rails::ManyShot.new(sides: [side]),
  ].compact
  extras = [Rails::Obfuscation.new(rails: core, sides: [side])]
  extras << Rails::Hidden.new(rails: core) if side == :context
  extras << Rails::Language.new(sides: [side])
  core + extras
end

Instance Method Details

#cache?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/vangrail/builder.rb', line 91

def cache?
  !off_value?(env['GUARDRAILS_CACHE'])
end

#config_dirObject



95
96
97
# File 'lib/vangrail/builder.rb', line 95

def config_dir
  present(env['GUARDRAILS_CONFIG'])
end

#enabledObject

Raises:

  • (ArgumentError)


66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/vangrail/builder.rb', line 66

def enabled
  text = env['GUARDRAILS_RAILS'].to_s.strip
  return DEFAULT_RAILS if text.empty?
  return [] if off_value?(text) || text.casecmp('none').zero?
  return ALL_RAILS.dup if text.casecmp('all').zero?

  names = text.split(/[,\s]+/).map { |s| s.strip.downcase.to_sym }
  unknown = names - ALL_RAILS
  raise ArgumentError, "unknown rail name(s): #{unknown.join(', ')}" unless unknown.empty?

  names & ALL_RAILS
end

#engineObject



28
29
30
31
32
33
34
# File 'lib/vangrail/builder.rb', line 28

def engine
  return Engine.new(on_error: on_error, cache: cache?) if off?
  return config_engine if config_dir

  Engine.new(input: input_rails, context: context_rails, output: output_rails,
             on_error: on_error, cache: cache?)
end

#off?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/vangrail/builder.rb', line 83

def off?
  off_value?(env['GUARDRAILS'])
end

#on?(rail) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/vangrail/builder.rb', line 79

def on?(rail)
  enabled.include?(rail)
end

#on_errorObject



87
88
89
# File 'lib/vangrail/builder.rb', line 87

def on_error
  env['GUARDRAILS_ON_ERROR'].to_s.strip.casecmp('block').zero? ? :block : :allow
end

#providerObject

The endpoint the model-backed rails call, or nil when none is reachable.



104
105
106
107
108
# File 'lib/vangrail/builder.rb', line 104

def provider
  return @provider if defined?(@provider)

  @provider = Provider.resolve(env)
end

#server_urlObject



99
100
101
# File 'lib/vangrail/builder.rb', line 99

def server_url
  present(env['GUARDRAILS_SERVER'])
end

#session(prior:, **kwargs) ⇒ Object



36
37
38
# File 'lib/vangrail/builder.rb', line 36

def session(prior:, **kwargs)
  Session.new(engine: engine, prior: prior, **kwargs)
end