Class: Riffer::Guardrails::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/riffer/guardrails/runner.rb

Overview

Executes guardrails sequentially and manages the processing pipeline.

The runner processes guardrails in order, passing the output of each to the next. If any guardrail blocks, execution stops and a tripwire is returned.

runner = Runner.new(guardrail_configs, phase: :before, context: context)
data, tripwire, modifications = runner.run(messages)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(guardrail_configs, phase:, context: nil) ⇒ Runner

Creates a new runner.

guardrail_configs

configs with :class and :options keys.

phase

:before or :after.

context

optional context to pass to guardrails.

– : (Array[Hash[Symbol, untyped]], phase: Symbol, ?context: untyped) -> void



30
31
32
33
34
# File 'lib/riffer/guardrails/runner.rb', line 30

def initialize(guardrail_configs, phase:, context: nil)
  @guardrail_configs = guardrail_configs
  @phase = phase
  @context = context
end

Instance Attribute Details

#contextObject (readonly)

The context passed to guardrails.



20
21
22
# File 'lib/riffer/guardrails/runner.rb', line 20

def context
  @context
end

#guardrail_configsObject (readonly)

The guardrail configs to execute.



14
15
16
# File 'lib/riffer/guardrails/runner.rb', line 14

def guardrail_configs
  @guardrail_configs
end

#phaseObject (readonly)

The execution phase (:before or :after).



17
18
19
# File 'lib/riffer/guardrails/runner.rb', line 17

def phase
  @phase
end

Instance Method Details

#run(data, messages: nil) ⇒ Object

Runs the guardrails sequentially.

For before phase, data should be an array of messages. For after phase, data should be a response and messages must be provided.

data

the data to process (messages for before, response for after).

messages

the conversation messages (required for after phase).

– : (untyped, ?messages: Array?) -> [untyped, Riffer::Guardrails::Tripwire?, Array]



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/riffer/guardrails/runner.rb', line 46

def run(data, messages: nil)
  current_data = data
  modifications = [] #: Array[Riffer::Guardrails::Modification]

  guardrail_configs.each do |config|
    guardrail = instantiate_guardrail(config)
    result = execute_guardrail(guardrail, current_data, messages: messages)

    if result.block?
      tripwire = Riffer::Guardrails::Tripwire.new(
        reason: result.data,
        guardrail: guardrail.class,
        phase: phase,
        metadata: result.
      )
      return [current_data, tripwire, modifications]
    end

    if result.transform?
      modifications << Riffer::Guardrails::Modification.new(
        guardrail: guardrail.class,
        phase: phase,
        message_indices: detect_changed_indices(current_data, result.data)
      )
    end

    current_data = result.data
  end

  [current_data, nil, modifications]
end