Class: Boxcars::EngineBoxcar

Inherits:
Boxcar
  • Object
show all
Defined in:
lib/boxcars/boxcar/engine_boxcar.rb

Overview

For Boxcars that use an engine to do their work.

Instance Attribute Summary collapse

Attributes inherited from Boxcar

#description, #name, #parameters, #return_direct

Instance Method Summary collapse

Methods inherited from Boxcar

assi, #conduct, hist, #load, #run, #save, #schema, syst, user, #validate_inputs, #validate_outputs

Constructor Details

#initialize(prompt:, engine: nil, **kwargs) ⇒ EngineBoxcar

A Boxcar is a container for a single tool to run.

Parameters:

  • prompt (Boxcars::Prompt)

    The prompt to use for this boxcar with sane defaults.

  • engine (Boxcars::Engine) (defaults to: nil)

    The engine to user for this boxcar. Can be inherited from a train if nil.

  • kwargs (Hash)

    Additional arguments including: name, description, top_k, return_direct, and stop



13
14
15
16
17
18
19
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 13

def initialize(prompt:, engine: nil, **kwargs)
  @prompt = prompt
  @engine = engine || Boxcars.engine.new
  @top_k = kwargs.delete(:top_k) || 5
  @stop = kwargs.delete(:stop) || ["Answer:"]
  super(**kwargs)
end

Instance Attribute Details

#engineObject

Returns the value of attribute engine.



7
8
9
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 7

def engine
  @engine
end

#promptObject

Returns the value of attribute prompt.



7
8
9
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 7

def prompt
  @prompt
end

#stopObject

Returns the value of attribute stop.



7
8
9
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 7

def stop
  @stop
end

#top_kObject

Returns the value of attribute top_k.



7
8
9
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 7

def top_k
  @top_k
end

Instance Method Details

#apply(input_list:, current_conversation: nil) ⇒ Hash

apply a response from the engine

Parameters:

  • input_list (Array<Hash>)

    A list of hashes of input values to use for the prompt.

  • current_conversation (Boxcars::Conversation) (defaults to: nil)

    Optional ongoing conversation to use for the prompt.

Returns:

  • (Hash)

    A hash of the output key and the output value.



56
57
58
59
60
61
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 56

def apply(input_list:, current_conversation: nil)
  response = generate(input_list: input_list, current_conversation: current_conversation)
  response.generations.to_h do |generation|
    [output_key, generation[0].text]
  end
end

#call(inputs:) ⇒ Hash

call the boxcar

Parameters:

  • inputs (Hash)

    The inputs to the boxcar.

Returns:

  • (Hash)

    The outputs from the boxcar.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 84

def call(inputs:)
  # if we get errors back, try predicting again giving the errors with the inputs
  conversation = nil
  answer = nil
  4.times do
    text = predict(current_conversation: conversation, **prediction_variables(inputs)).strip
    answer = get_answer(text)
    if answer.status == :error
      Boxcars.debug "have error, trying again: #{answer.answer}", :red
      conversation ||= Conversation.new
      conversation.add_assistant(text)
      conversation.add_user(answer.answer)
    else
      Boxcars.debug answer.to_json, :magenta
      return { output_key => answer }
    end
  end
  Boxcars.error answer.to_json, :red
  { output_key => "Error: #{answer}" }
rescue Boxcars::ConfigurationError, Boxcars::SecurityError => e
  raise e
rescue Boxcars::Error => e
  Boxcars.error e.message, :red
  { output_key => "Error: #{e.message}" }
end

#check_output_keysObject

check that there is exactly one output key

Raises:



75
76
77
78
79
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 75

def check_output_keys
  return unless output_keys.length != 1

  raise Boxcars::ArgumentError, "not supported when there is not exactly one output key. Got #{output_keys}."
end

#extract_code(code) ⇒ String

remove backticks or triple backticks from the code

Parameters:

  • code (String)

    The code to remove backticks from.

Returns:

  • (String)

    The code without backticks.



130
131
132
133
134
135
136
137
138
139
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 130

def extract_code(code)
  case code
  when /^```\w*/
    code.split(/```\w*\n/).last.split('```').first.strip
  when /^`(.+)`/
    ::Regexp.last_match(1)
  else
    code.gsub("`", "")
  end
end

#generate(input_list:, current_conversation: nil) ⇒ Boxcars::EngineResult

generate a response from the engine

Parameters:

  • input_list (Array<Hash>)

    A list of hashes of input values to use for the prompt.

  • current_conversation (Boxcars::Conversation) (defaults to: nil)

    Optional ongoing conversation to use for the prompt.

Returns:



45
46
47
48
49
50
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 45

def generate(input_list:, current_conversation: nil)
  stop = input_list[0][:stop]
  the_prompt = current_conversation ? prompt.with_conversation(current_conversation) : prompt
  prompts = input_list.map { |inputs| [the_prompt, inputs] }
  engine.generate(prompts: prompts, stop: stop)
end

#input_keyObject

the first input key for the prompt



27
28
29
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 27

def input_key
  input_keys.first
end

#input_keysObject

input keys for the prompt



22
23
24
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 22

def input_keys
  prompt.input_variables
end

#output_keyObject

the first output key



37
38
39
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 37

def output_key
  output_keys.first
end

#output_keysObject

output keys



32
33
34
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 32

def output_keys
  prompt.output_variables
end

#predict(current_conversation: nil, **kwargs) ⇒ String

predict a response from the engine

Parameters:

  • current_conversation (Boxcars::Conversation) (defaults to: nil)

    Optional ongoing conversation to use for the prompt.

  • kwargs (Hash)

    A hash of input values to use for the prompt.

Returns:

  • (String)

    The output value.



67
68
69
70
71
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 67

def predict(current_conversation: nil, **kwargs)
  prediction = apply(current_conversation: current_conversation, input_list: [kwargs])[output_key]
  Boxcars.debug(prediction, :white) if Boxcars.configuration.log_generated
  prediction
end

#prediction_additional(_inputs) ⇒ Object

Returns Hash The additional variables for this boxcar.

Returns:

  • Hash The additional variables for this boxcar.



117
118
119
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 117

def prediction_additional(_inputs)
  { stop: stop, top_k: top_k }
end

#prediction_input(inputs) ⇒ Object

Returns Hash The input variable for this boxcar.

Parameters:

  • inputs (Hash)

    The inputs to the boxcar.

Returns:

  • Hash The input variable for this boxcar.



112
113
114
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 112

def prediction_input(inputs)
  { input_key => inputs[input_key] }
end

#prediction_variables(inputs) ⇒ Object

Returns Hash The variables for this boxcar.

Parameters:

  • inputs (Hash)

    The inputs to the boxcar.

Returns:

  • Hash The variables for this boxcar.



123
124
125
# File 'lib/boxcars/boxcar/engine_boxcar.rb', line 123

def prediction_variables(inputs)
  prediction_additional(inputs).merge(inputs)
end