vangrail 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +655 -43
- data/lib/vangrail/actions.rb +10 -3
- data/lib/vangrail/assessor.rb +249 -0
- data/lib/vangrail/bayes_data.rb +340 -0
- data/lib/vangrail/beta.rb +102 -0
- data/lib/vangrail/builder.rb +354 -0
- data/lib/vangrail/chat.rb +17 -15
- data/lib/vangrail/client/{completion.rb → turn.rb} +3 -3
- data/lib/vangrail/client.rb +27 -18
- data/lib/vangrail/colang/ast.rb +29 -3
- data/lib/vangrail/colang/interpreter.rb +55 -31
- data/lib/vangrail/colang/parser.rb +19 -61
- data/lib/vangrail/colang/value_parser.rb +161 -0
- data/lib/vangrail/completion.rb +86 -0
- data/lib/vangrail/config.rb +35 -15
- data/lib/vangrail/conversation.rb +240 -11
- data/lib/vangrail/dojo.rb +126 -0
- data/lib/vangrail/embeddings.rb +87 -0
- data/lib/vangrail/engine.rb +29 -70
- data/lib/vangrail/errors.rb +6 -1
- data/lib/vangrail/evidence.rb +303 -0
- data/lib/vangrail/evidence_data.rb +113 -0
- data/lib/vangrail/http.rb +18 -13
- data/lib/vangrail/judgement.rb +151 -0
- data/lib/vangrail/known_attacks.rb +45 -0
- data/lib/vangrail/linear_model.rb +124 -0
- data/lib/vangrail/nlp.rb +596 -0
- data/lib/vangrail/origin.rb +249 -0
- data/lib/vangrail/parsers.rb +5 -5
- data/lib/vangrail/profile.rb +114 -0
- data/lib/vangrail/prompt.rb +14 -3
- data/lib/vangrail/provider.rb +106 -75
- data/lib/vangrail/providers/gateway.rb +15 -14
- data/lib/vangrail/providers/llmlite.rb +25 -10
- data/lib/vangrail/providers.rb +6 -8
- data/lib/vangrail/rail.rb +46 -8
- data/lib/vangrail/rails/alignment.rb +91 -0
- data/lib/vangrail/rails/bayes.rb +115 -0
- data/lib/vangrail/rails/budget.rb +2 -2
- data/lib/vangrail/rails/canary.rb +2 -2
- data/lib/vangrail/rails/colang_flow.rb +9 -1
- data/lib/vangrail/rails/escalation.rb +15 -8
- data/lib/vangrail/rails/exfiltration.rb +2 -2
- data/lib/vangrail/rails/grounding.rb +8 -5
- data/lib/vangrail/rails/guard_model.rb +7 -4
- data/lib/vangrail/rails/hidden.rb +52 -9
- data/lib/vangrail/rails/injected_instructions.rb +29 -9
- data/lib/vangrail/rails/jailbreak.rb +2 -6
- data/lib/vangrail/rails/known_answer.rb +6 -2
- data/lib/vangrail/rails/language.rb +87 -0
- data/lib/vangrail/rails/linear.rb +80 -0
- data/lib/vangrail/rails/many_shot.rb +2 -6
- data/lib/vangrail/rails/markup.rb +3 -3
- data/lib/vangrail/rails/missing.rb +1 -5
- data/lib/vangrail/rails/obfuscation.rb +81 -13
- data/lib/vangrail/rails/paraphrase.rb +189 -0
- data/lib/vangrail/rails/pattern.rb +2 -6
- data/lib/vangrail/rails/perplexity.rb +100 -0
- data/lib/vangrail/rails/personal_data.rb +41 -9
- data/lib/vangrail/rails/prompt_leak.rb +132 -0
- data/lib/vangrail/rails/remote.rb +5 -1
- data/lib/vangrail/rails/secrets.rb +2 -2
- data/lib/vangrail/rails/self_check.rb +9 -6
- data/lib/vangrail/rails/semantic.rb +132 -0
- data/lib/vangrail/rails/similarity.rb +96 -0
- data/lib/vangrail/rails/trajectory.rb +10 -5
- data/lib/vangrail/result.rb +3 -3
- data/lib/vangrail/result_cache.rb +0 -0
- data/lib/vangrail/screening.rb +68 -0
- data/lib/vangrail/session.rb +365 -0
- data/lib/vangrail/spotlight.rb +48 -8
- data/lib/vangrail/stream_guard.rb +8 -6
- data/lib/vangrail/tools.rb +58 -0
- data/lib/vangrail/version.rb +1 -1
- data/lib/vangrail.rb +39 -258
- metadata +34 -5
data/lib/vangrail.rb
CHANGED
|
@@ -4,15 +4,26 @@ require_relative 'vangrail/version'
|
|
|
4
4
|
require_relative 'vangrail/errors'
|
|
5
5
|
require_relative 'vangrail/http'
|
|
6
6
|
require_relative 'vangrail/chat'
|
|
7
|
+
require_relative 'vangrail/completion'
|
|
8
|
+
require_relative 'vangrail/embeddings'
|
|
7
9
|
require_relative 'vangrail/parsers'
|
|
8
10
|
require_relative 'vangrail/prompt'
|
|
9
11
|
require_relative 'vangrail/policies'
|
|
10
12
|
require_relative 'vangrail/result'
|
|
11
13
|
require_relative 'vangrail/result_cache'
|
|
14
|
+
require_relative 'vangrail/beta'
|
|
15
|
+
require_relative 'vangrail/evidence'
|
|
16
|
+
require_relative 'vangrail/evidence_data'
|
|
17
|
+
require_relative 'vangrail/judgement'
|
|
18
|
+
require_relative 'vangrail/origin'
|
|
12
19
|
require_relative 'vangrail/rail'
|
|
13
20
|
require_relative 'vangrail/engine'
|
|
14
21
|
require_relative 'vangrail/stream_guard'
|
|
15
22
|
require_relative 'vangrail/conversation'
|
|
23
|
+
require_relative 'vangrail/session'
|
|
24
|
+
require_relative 'vangrail/profile'
|
|
25
|
+
require_relative 'vangrail/tools'
|
|
26
|
+
require_relative 'vangrail/dojo'
|
|
16
27
|
require_relative 'vangrail/actions'
|
|
17
28
|
require_relative 'vangrail/provider'
|
|
18
29
|
require_relative 'vangrail/providers'
|
|
@@ -20,8 +31,20 @@ require_relative 'vangrail/colang/parser'
|
|
|
20
31
|
require_relative 'vangrail/colang/interpreter'
|
|
21
32
|
require_relative 'vangrail/colang/library'
|
|
22
33
|
require_relative 'vangrail/confusables'
|
|
34
|
+
require_relative 'vangrail/nlp'
|
|
35
|
+
require_relative 'vangrail/known_attacks'
|
|
36
|
+
require_relative 'vangrail/linear_model'
|
|
37
|
+
require_relative 'vangrail/bayes_data'
|
|
23
38
|
require_relative 'vangrail/spotlight'
|
|
24
39
|
require_relative 'vangrail/rails/injected_instructions'
|
|
40
|
+
require_relative 'vangrail/rails/paraphrase'
|
|
41
|
+
require_relative 'vangrail/rails/alignment'
|
|
42
|
+
require_relative 'vangrail/rails/language'
|
|
43
|
+
require_relative 'vangrail/rails/similarity'
|
|
44
|
+
require_relative 'vangrail/rails/bayes'
|
|
45
|
+
require_relative 'vangrail/rails/linear'
|
|
46
|
+
require_relative 'vangrail/rails/semantic'
|
|
47
|
+
require_relative 'vangrail/rails/perplexity'
|
|
25
48
|
require_relative 'vangrail/rails/missing'
|
|
26
49
|
require_relative 'vangrail/rails/jailbreak'
|
|
27
50
|
require_relative 'vangrail/rails/pattern'
|
|
@@ -30,6 +53,7 @@ require_relative 'vangrail/rails/hidden'
|
|
|
30
53
|
require_relative 'vangrail/rails/escalation'
|
|
31
54
|
require_relative 'vangrail/rails/many_shot'
|
|
32
55
|
require_relative 'vangrail/rails/canary'
|
|
56
|
+
require_relative 'vangrail/rails/prompt_leak'
|
|
33
57
|
require_relative 'vangrail/rails/personal_data'
|
|
34
58
|
require_relative 'vangrail/rails/markup'
|
|
35
59
|
require_relative 'vangrail/rails/budget'
|
|
@@ -44,6 +68,7 @@ require_relative 'vangrail/rails/colang_flow'
|
|
|
44
68
|
require_relative 'vangrail/rails/remote'
|
|
45
69
|
require_relative 'vangrail/client'
|
|
46
70
|
require_relative 'vangrail/config'
|
|
71
|
+
require_relative 'vangrail/builder'
|
|
47
72
|
|
|
48
73
|
# Guardrails for Ruby applications: input and output rails that run in the
|
|
49
74
|
# calling process, with no Python service anywhere in the path.
|
|
@@ -71,6 +96,12 @@ module Vangrail
|
|
|
71
96
|
# GUARDRAILS_JUDGE_MODEL=<m> instruct model for policy and grounding rails
|
|
72
97
|
# GUARDRAILS_RAILS=input,context,output,grounding,secrets,patterns,links,multiturn
|
|
73
98
|
# GUARDRAILS_CANARY=<token> a marker in your prompt that must not come back
|
|
99
|
+
# GUARDRAILS_PROMPT_FILE=<path> the prompt text that must not come back out
|
|
100
|
+
# GUARDRAILS_EMBED_MODEL=<model> an embedding model, for GUARDRAILS_RAILS=...,semantic
|
|
101
|
+
# GUARDRAILS_SEMANTIC_THRESHOLD=<0..1> calibrate it with script/embedding_probe.rb
|
|
102
|
+
# GUARDRAILS_RAILS=...,perplexity block optimised gibberish, where the
|
|
103
|
+
# endpoint will score a prompt it echoes
|
|
104
|
+
# GUARDRAILS_PERPLEXITY_THRESHOLD=<nats> calibrate it with script/perplexity_probe.rb
|
|
74
105
|
# GUARDRAILS_RAILS=...,privacy redact a reader's own details before sending
|
|
75
106
|
# GUARDRAILS_RAILS=...,markup strip active markup from the answer
|
|
76
107
|
# GUARDRAILS_RAILS=...,budget refuse text too large to be a question
|
|
@@ -83,272 +114,22 @@ module Vangrail
|
|
|
83
114
|
# With no endpoint reachable the engine keeps its offline rails and every
|
|
84
115
|
# model-backed check reports passed with certain false. Nothing is quietly
|
|
85
116
|
# assumed to be running.
|
|
86
|
-
def from_env(env = ENV)
|
|
87
|
-
|
|
88
|
-
|
|
117
|
+
def from_env(env = ENV) = Builder.new(env).engine
|
|
118
|
+
|
|
119
|
+
# Same engine, carrying a posterior across turns. The prior is still
|
|
120
|
+
# required: a session that guessed the base rate would hide the same
|
|
121
|
+
# error `assess` exists to expose.
|
|
122
|
+
def session_from_env(prior:, env: ENV, **kwargs) = Builder.new(env).session(prior: prior, **kwargs)
|
|
89
123
|
|
|
90
124
|
def provider(env = ENV)
|
|
91
125
|
Provider.resolve(env)
|
|
92
126
|
end
|
|
93
127
|
|
|
94
|
-
def engine(**kwargs)
|
|
95
|
-
Engine.new(**kwargs)
|
|
96
|
-
end
|
|
128
|
+
def engine(**kwargs) = Engine.new(**kwargs)
|
|
97
129
|
|
|
98
|
-
def config(dir)
|
|
99
|
-
Config.load(dir)
|
|
100
|
-
end
|
|
130
|
+
def config(dir) = Config.load(dir)
|
|
101
131
|
|
|
102
132
|
def client(base_url:, **kwargs)
|
|
103
133
|
Client.new(base_url: base_url, **kwargs)
|
|
104
134
|
end
|
|
105
|
-
|
|
106
|
-
# Reads the environment into an engine. A class rather than a method so each
|
|
107
|
-
# decision is separable and testable on its own.
|
|
108
|
-
class Builder
|
|
109
|
-
DEFAULT_RAILS = %i[input context output].freeze
|
|
110
|
-
ALL_RAILS = %i[input context output grounding secrets patterns links multiturn privacy
|
|
111
|
-
markup budget].freeze
|
|
112
|
-
|
|
113
|
-
# Deterministic input patterns, kept small on purpose. Each is a phrase
|
|
114
|
-
# whose presence is itself the violation; anything needing judgement belongs
|
|
115
|
-
# in a policy rail, where a false positive is a model's opinion rather than
|
|
116
|
-
# a hard rule.
|
|
117
|
-
INJECTION_PATTERNS = {
|
|
118
|
-
'instruction_override' => /\bignore\s+(?:all\s+|any\s+)?(?:previous|prior|above|earlier)\s+instructions?\b/i,
|
|
119
|
-
'prompt_disclosure' => /\b(?:reveal|print|repeat|show|output)\s+(?:me\s+)?(?:your|the|its)?\s*
|
|
120
|
-
(?:system\s+prompt|initial\s+instructions|developer\s+message)\b/xi,
|
|
121
|
-
'role_reset' => /\byou\s+are\s+now\s+(?:a|an|in)\b.{0,40}\b(?:mode|persona|dan|jailbreak)\b/i
|
|
122
|
-
}.freeze
|
|
123
|
-
|
|
124
|
-
attr_reader :env
|
|
125
|
-
|
|
126
|
-
def initialize(env = ENV)
|
|
127
|
-
@env = env
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def engine
|
|
131
|
-
return Engine.new(on_error: on_error, cache: cache?) if off?
|
|
132
|
-
return config_engine if config_dir
|
|
133
|
-
|
|
134
|
-
Engine.new(input: input_rails, context: context_rails, output: output_rails,
|
|
135
|
-
on_error: on_error, cache: cache?)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def enabled
|
|
139
|
-
text = env['GUARDRAILS_RAILS'].to_s.strip
|
|
140
|
-
return DEFAULT_RAILS if text.empty?
|
|
141
|
-
return [] if off_value?(text) || text.casecmp('none').zero?
|
|
142
|
-
return ALL_RAILS.dup if text.casecmp('all').zero?
|
|
143
|
-
|
|
144
|
-
text.split(/[,\s]+/).map { |s| s.strip.downcase.to_sym } & ALL_RAILS
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def on?(rail)
|
|
148
|
-
enabled.include?(rail)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def off?
|
|
152
|
-
off_value?(env['GUARDRAILS'])
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def on_error
|
|
156
|
-
env['GUARDRAILS_ON_ERROR'].to_s.strip.casecmp('block').zero? ? :block : :allow
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def cache?
|
|
160
|
-
!off_value?(env['GUARDRAILS_CACHE'])
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def config_dir
|
|
164
|
-
present(env['GUARDRAILS_CONFIG'])
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def server_url
|
|
168
|
-
present(env['GUARDRAILS_SERVER'])
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
# The endpoint the model-backed rails call, or nil when none is reachable.
|
|
172
|
-
def provider
|
|
173
|
-
return @provider if defined?(@provider)
|
|
174
|
-
|
|
175
|
-
@provider = Provider.resolve(env)
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
private
|
|
179
|
-
|
|
180
|
-
def config_engine
|
|
181
|
-
Config.load(config_dir).engine(provider: provider, on_error: on_error, cache: cache?)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
# The pattern rail runs whenever any input rail does. It costs microseconds
|
|
185
|
-
# and it is the only part of the input side that still works when the
|
|
186
|
-
# endpoint is down.
|
|
187
|
-
def input_rails
|
|
188
|
-
return [] unless on?(:input) || on?(:patterns)
|
|
189
|
-
|
|
190
|
-
deterministic = [Rails::Pattern.new(patterns: INJECTION_PATTERNS, name: 'injection_patterns',
|
|
191
|
-
sides: [:input]),
|
|
192
|
-
Rails::Jailbreak.new(sides: [:input]),
|
|
193
|
-
Rails::ManyShot.new(sides: [:input])]
|
|
194
|
-
rails = deterministic + [Rails::Obfuscation.new(rails: deterministic, sides: [:input])]
|
|
195
|
-
# A question carrying the canary is too late to prevent and worth
|
|
196
|
-
# knowing: the prompt is already out.
|
|
197
|
-
rails << canary(:input) if canary_token
|
|
198
|
-
# Opt-in: it rewrites the question before the model sees it, which is a
|
|
199
|
-
# deployment's call rather than a default. Where the endpoint is a third
|
|
200
|
-
# party it is close to obligatory, and where it is a local proxy it buys
|
|
201
|
-
# little.
|
|
202
|
-
rails << Rails::PersonalData.new if on?(:privacy)
|
|
203
|
-
rails << Rails::Budget.new(sides: [:input]) if on?(:budget)
|
|
204
|
-
# Off unless asked for: they read history, and a caller that threads none
|
|
205
|
-
# would have every input check come back uncertain, which is true and
|
|
206
|
-
# useless. Conversation is what makes them worth having.
|
|
207
|
-
#
|
|
208
|
-
# The deterministic one goes first so a refused question asked again
|
|
209
|
-
# never reaches the judge: it is free, and the round trip is not.
|
|
210
|
-
rails.concat(multiturn_rails) if on?(:multiturn)
|
|
211
|
-
rails << judged(:input) if on?(:input)
|
|
212
|
-
rails.compact
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
# Deterministic, offline, and free, so it is on by default. The document a
|
|
216
|
-
# retrieval step just fetched is the side an attacker can usually reach
|
|
217
|
-
# without touching the application, and nothing else in this engine reads it.
|
|
218
|
-
#
|
|
219
|
-
# The decoding pass matters more here than anywhere else: a page an
|
|
220
|
-
# attacker edits is a page they can base64.
|
|
221
|
-
def context_rails
|
|
222
|
-
return [] unless on?(:context)
|
|
223
|
-
|
|
224
|
-
deterministic = [Rails::InjectedInstructions.new, Rails::Jailbreak.new(sides: [:context]),
|
|
225
|
-
Rails::ManyShot.new(sides: [:context])]
|
|
226
|
-
# Two passes over the same definitions, for the two ways a page hides
|
|
227
|
-
# one: encoded so the patterns cannot read it, or in markup a reader
|
|
228
|
-
# never sees.
|
|
229
|
-
rails = deterministic + [Rails::Obfuscation.new(rails: deterministic, sides: [:context]),
|
|
230
|
-
Rails::Hidden.new(rails: deterministic)]
|
|
231
|
-
rails << Rails::Budget.new(sides: [:context]) if on?(:budget)
|
|
232
|
-
rails
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def output_rails
|
|
236
|
-
rails = []
|
|
237
|
-
rails << Rails::Secrets.new if on?(:secrets) || on?(:output)
|
|
238
|
-
rails << canary(:output) if canary_token
|
|
239
|
-
# Off by default: a desk whose client renders answers as plain text does
|
|
240
|
-
# not need it, and stripping markup nobody would have executed is noise
|
|
241
|
-
# in the result.
|
|
242
|
-
rails << Rails::Markup.new if on?(:markup)
|
|
243
|
-
rails << exfiltration if link_hosts || on?(:links)
|
|
244
|
-
rails << judged(:output) if on?(:output)
|
|
245
|
-
rails << grounding if on?(:grounding)
|
|
246
|
-
rails.compact
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# The hosts an answer may link to. Not defaulted to anything, because the
|
|
250
|
-
# empty allowlist means "no links at all", which is right for an
|
|
251
|
-
# application that said so and wrong to impose on one that never mentioned
|
|
252
|
-
# links. Naming the variable is the opt-in.
|
|
253
|
-
def link_hosts
|
|
254
|
-
present(env['GUARDRAILS_LINK_HOSTS'])
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
# The pair, because they cover different halves. Escalation sees a retry
|
|
258
|
-
# after a refusal and nothing before one; the judge reads a sequence that
|
|
259
|
-
# has never been refused, which is what the published multi-turn methods
|
|
260
|
-
# are built to produce.
|
|
261
|
-
def multiturn_rails
|
|
262
|
-
rails = [Rails::Escalation.new]
|
|
263
|
-
rails << if provider&.available?
|
|
264
|
-
Rails::Trajectory.new(provider: provider, every: judge_every)
|
|
265
|
-
else
|
|
266
|
-
missing('trajectory', :input)
|
|
267
|
-
end
|
|
268
|
-
rails
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
# One round trip per turn is the honest cost, and a desk may not want to
|
|
272
|
-
# pay it every turn. A staged escalation takes several turns by
|
|
273
|
-
# construction and cannot finish inside a gap of two.
|
|
274
|
-
def judge_every
|
|
275
|
-
value = env['GUARDRAILS_TRAJECTORY_EVERY'].to_i
|
|
276
|
-
value.positive? ? value : 1
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
# The rail class follows what the endpoint can actually serve. A provider
|
|
280
|
-
# hosting a classifier gets one; a provider serving only instruct models
|
|
281
|
-
# gets a written policy in front of one, which is the same job done
|
|
282
|
-
# differently rather than the same job skipped.
|
|
283
|
-
def judged(side)
|
|
284
|
-
return remote(side) if server_url
|
|
285
|
-
return missing("#{side}_model", side) unless provider&.available?
|
|
286
|
-
return guard_model(side) if provider.guard?
|
|
287
|
-
|
|
288
|
-
Rails::SelfCheck.new(provider: provider, sides: [side], name: "policy_#{side}")
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# Asked for and unbuildable. Kept in the list rather than dropped, so the
|
|
292
|
-
# engine's pass stays uncertain instead of resting on the offline rails.
|
|
293
|
-
#
|
|
294
|
-
# `name` is what the rail would have been; `side` is where it would have
|
|
295
|
-
# run. They are not the same thing, and conflating them is how a grounding
|
|
296
|
-
# placeholder ends up claiming a side that does not exist.
|
|
297
|
-
def missing(name, side)
|
|
298
|
-
reason =
|
|
299
|
-
if provider
|
|
300
|
-
"#{provider.name} is not available at #{provider.base_url}"
|
|
301
|
-
else
|
|
302
|
-
'no endpoint resolved: set GUARDRAILS_API_BASE, or start a local one'
|
|
303
|
-
end
|
|
304
|
-
Rails::Missing.new(reason: reason, name: name.to_s, sides: [side])
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
def remote(side)
|
|
308
|
-
Rails::Remote.new(base_url: server_url, config_id: present(env['GUARDRAILS_CONFIG_ID']),
|
|
309
|
-
api_key: present(env['GUARDRAILS_SERVER_API_KEY']), sides: [side])
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def guard_model(side)
|
|
313
|
-
Rails::GuardModel.new(provider: provider, reasoning: truthy?(env['GUARDRAILS_REASONING']),
|
|
314
|
-
sides: [side])
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
# The application generates the token, puts it in its prompt, and names it
|
|
318
|
-
# here. Nothing can be checked without one, so its absence is the off
|
|
319
|
-
# switch.
|
|
320
|
-
def canary_token
|
|
321
|
-
present(env['GUARDRAILS_CANARY'])
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
def canary(side)
|
|
325
|
-
Rails::Canary.new(tokens: canary_token.split(/[,\s]+/), sides: [side])
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
def exfiltration
|
|
329
|
-
hosts = link_hosts.to_s.split(/[,\s]+/).reject(&:empty?)
|
|
330
|
-
images = present(env['GUARDRAILS_IMAGE_HOSTS'])
|
|
331
|
-
Rails::Exfiltration.new(allow_hosts: hosts,
|
|
332
|
-
allow_images: images&.split(/[,\s]+/)&.reject(&:empty?))
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
def grounding
|
|
336
|
-
return missing('grounding', :output) unless provider&.available?
|
|
337
|
-
|
|
338
|
-
Rails::Grounding.new(provider: provider)
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
def off_value?(value)
|
|
342
|
-
%w[0 off false no].include?(value.to_s.strip.downcase)
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
def truthy?(value)
|
|
346
|
-
%w[1 on true yes].include?(value.to_s.strip.downcase)
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
def present(value)
|
|
350
|
-
s = value.to_s.strip
|
|
351
|
-
s.empty? ? nil : s
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
135
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vangrail
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rohit Goswami
|
|
@@ -28,9 +28,10 @@ description: |
|
|
|
28
28
|
or blocked, and reporting whether a rail actually reached the decision.
|
|
29
29
|
Deterministic rails need no network at all; model-backed ones call any
|
|
30
30
|
OpenAI-compatible endpoint through a provider abstraction that prefers a
|
|
31
|
-
local proxy. Reads
|
|
32
|
-
|
|
33
|
-
who already run the Python server. Standard
|
|
31
|
+
local proxy. Reads folders in the NeMo layout and executes a documented
|
|
32
|
+
Colang 1.0 rail-flow subset in process. A NeMo folder is not drop-in.
|
|
33
|
+
Optional client for teams who already run the Python server. Standard
|
|
34
|
+
library only.
|
|
34
35
|
email:
|
|
35
36
|
- rohit.goswami@surf.nl
|
|
36
37
|
executables: []
|
|
@@ -41,28 +42,46 @@ files:
|
|
|
41
42
|
- README.md
|
|
42
43
|
- lib/vangrail.rb
|
|
43
44
|
- lib/vangrail/actions.rb
|
|
45
|
+
- lib/vangrail/assessor.rb
|
|
46
|
+
- lib/vangrail/bayes_data.rb
|
|
47
|
+
- lib/vangrail/beta.rb
|
|
48
|
+
- lib/vangrail/builder.rb
|
|
44
49
|
- lib/vangrail/chat.rb
|
|
45
50
|
- lib/vangrail/client.rb
|
|
46
|
-
- lib/vangrail/client/
|
|
51
|
+
- lib/vangrail/client/turn.rb
|
|
47
52
|
- lib/vangrail/colang/ast.rb
|
|
48
53
|
- lib/vangrail/colang/interpreter.rb
|
|
49
54
|
- lib/vangrail/colang/library.rb
|
|
50
55
|
- lib/vangrail/colang/parser.rb
|
|
56
|
+
- lib/vangrail/colang/value_parser.rb
|
|
57
|
+
- lib/vangrail/completion.rb
|
|
51
58
|
- lib/vangrail/config.rb
|
|
52
59
|
- lib/vangrail/confusables.rb
|
|
53
60
|
- lib/vangrail/confusables_data.rb
|
|
54
61
|
- lib/vangrail/conversation.rb
|
|
62
|
+
- lib/vangrail/dojo.rb
|
|
63
|
+
- lib/vangrail/embeddings.rb
|
|
55
64
|
- lib/vangrail/engine.rb
|
|
56
65
|
- lib/vangrail/errors.rb
|
|
66
|
+
- lib/vangrail/evidence.rb
|
|
67
|
+
- lib/vangrail/evidence_data.rb
|
|
57
68
|
- lib/vangrail/http.rb
|
|
69
|
+
- lib/vangrail/judgement.rb
|
|
70
|
+
- lib/vangrail/known_attacks.rb
|
|
71
|
+
- lib/vangrail/linear_model.rb
|
|
72
|
+
- lib/vangrail/nlp.rb
|
|
73
|
+
- lib/vangrail/origin.rb
|
|
58
74
|
- lib/vangrail/parsers.rb
|
|
59
75
|
- lib/vangrail/policies.rb
|
|
76
|
+
- lib/vangrail/profile.rb
|
|
60
77
|
- lib/vangrail/prompt.rb
|
|
61
78
|
- lib/vangrail/provider.rb
|
|
62
79
|
- lib/vangrail/providers.rb
|
|
63
80
|
- lib/vangrail/providers/gateway.rb
|
|
64
81
|
- lib/vangrail/providers/llmlite.rb
|
|
65
82
|
- lib/vangrail/rail.rb
|
|
83
|
+
- lib/vangrail/rails/alignment.rb
|
|
84
|
+
- lib/vangrail/rails/bayes.rb
|
|
66
85
|
- lib/vangrail/rails/budget.rb
|
|
67
86
|
- lib/vangrail/rails/canary.rb
|
|
68
87
|
- lib/vangrail/rails/colang_flow.rb
|
|
@@ -74,20 +93,30 @@ files:
|
|
|
74
93
|
- lib/vangrail/rails/injected_instructions.rb
|
|
75
94
|
- lib/vangrail/rails/jailbreak.rb
|
|
76
95
|
- lib/vangrail/rails/known_answer.rb
|
|
96
|
+
- lib/vangrail/rails/language.rb
|
|
97
|
+
- lib/vangrail/rails/linear.rb
|
|
77
98
|
- lib/vangrail/rails/many_shot.rb
|
|
78
99
|
- lib/vangrail/rails/markup.rb
|
|
79
100
|
- lib/vangrail/rails/missing.rb
|
|
80
101
|
- lib/vangrail/rails/obfuscation.rb
|
|
102
|
+
- lib/vangrail/rails/paraphrase.rb
|
|
81
103
|
- lib/vangrail/rails/pattern.rb
|
|
104
|
+
- lib/vangrail/rails/perplexity.rb
|
|
82
105
|
- lib/vangrail/rails/personal_data.rb
|
|
106
|
+
- lib/vangrail/rails/prompt_leak.rb
|
|
83
107
|
- lib/vangrail/rails/remote.rb
|
|
84
108
|
- lib/vangrail/rails/secrets.rb
|
|
85
109
|
- lib/vangrail/rails/self_check.rb
|
|
110
|
+
- lib/vangrail/rails/semantic.rb
|
|
111
|
+
- lib/vangrail/rails/similarity.rb
|
|
86
112
|
- lib/vangrail/rails/trajectory.rb
|
|
87
113
|
- lib/vangrail/result.rb
|
|
88
114
|
- lib/vangrail/result_cache.rb
|
|
115
|
+
- lib/vangrail/screening.rb
|
|
116
|
+
- lib/vangrail/session.rb
|
|
89
117
|
- lib/vangrail/spotlight.rb
|
|
90
118
|
- lib/vangrail/stream_guard.rb
|
|
119
|
+
- lib/vangrail/tools.rb
|
|
91
120
|
- lib/vangrail/version.rb
|
|
92
121
|
homepage: https://github.com/HaoZeke/vangrail
|
|
93
122
|
licenses:
|