Class: Vangrail::Colang::Interpreter

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

Overview

Runs one flow and reports what it decided.

The mapping onto rail statuses is the whole design:

`bot <message>` then `stop`     -> blocked, with the message as content
assignment to $user_message or
$bot_message                    -> modified, with the new value
falls off the end               -> passed

A stop without a preceding bot still blocks; it just has no refusal text to show. Actions are plain Ruby callables, so the flow decides the control shape and Ruby does the work.

Defined Under Namespace

Classes: Outcome, Stopped

Constant Summary collapse

CONTENT_VARS =

Variables a flow assigns to when it rewrites the turn rather than refusing it, matching the names the toolkit's own flows use.

%w[user_message bot_message user_input bot_response].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(program:, actions:) ⇒ Interpreter

Returns a new instance of Interpreter.



39
40
41
42
# File 'lib/vangrail/colang/interpreter.rb', line 39

def initialize(program:, actions:)
  @program = program
  @actions = actions
end

Instance Attribute Details

#actionsObject (readonly)

Returns the value of attribute actions.



37
38
39
# File 'lib/vangrail/colang/interpreter.rb', line 37

def actions
  @actions
end

#programObject (readonly)

Returns the value of attribute program.



37
38
39
# File 'lib/vangrail/colang/interpreter.rb', line 37

def program
  @program
end

Instance Method Details

#run(flow_name, context = {}) ⇒ Object

Raises:



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

def run(flow_name, context = {})
  flow = program.flow(flow_name)
  raise UnknownAction, "no flow named #{flow_name.inspect}" unless flow

  state = { 'context' => context }
  last_bot = nil
  begin
    last_bot = execute(flow.body, state, context)
  rescue Stopped => e
    return Outcome.new(status: :blocked, content: e.message_text, reason: flow_name, variables: state)
  end

  rewrite = CONTENT_VARS.filter_map { |v| state[v] if state.key?(v) }.last
  if rewrite
    return Outcome.new(status: :modified, content: rewrite.to_s, reason: flow_name,
                       variables: state)
  end

  Outcome.new(status: :passed, content: last_bot, reason: nil, variables: state)
end