charyf 0.1.1
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 +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +154 -0
- data/LICENSE.txt +21 -0
- data/README.md +18 -0
- data/Rakefile +6 -0
- data/bin/charyf-debug +7 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/charyf.gemspec +48 -0
- data/exe/charyf +4 -0
- data/lib/charyf/deps.rb +9 -0
- data/lib/charyf/engine/all.rb +22 -0
- data/lib/charyf/engine/charyf.rb +5 -0
- data/lib/charyf/engine/context.rb +61 -0
- data/lib/charyf/engine/controller/actions.rb +29 -0
- data/lib/charyf/engine/controller/controller.rb +62 -0
- data/lib/charyf/engine/controller/conversation.rb +58 -0
- data/lib/charyf/engine/controller/helpers.rb +38 -0
- data/lib/charyf/engine/controller/renderers.rb +103 -0
- data/lib/charyf/engine/dispatcher/base.rb +121 -0
- data/lib/charyf/engine/dispatcher/default.rb +60 -0
- data/lib/charyf/engine/intent/intent.rb +54 -0
- data/lib/charyf/engine/intent/processors/dummy.rb +30 -0
- data/lib/charyf/engine/intent/processors/helpers.rb +32 -0
- data/lib/charyf/engine/intent/processors/processor.rb +56 -0
- data/lib/charyf/engine/interface/interface.rb +35 -0
- data/lib/charyf/engine/interface/program.rb +59 -0
- data/lib/charyf/engine/request.rb +32 -0
- data/lib/charyf/engine/response.rb +41 -0
- data/lib/charyf/engine/session/processors/default.rb +42 -0
- data/lib/charyf/engine/session/processors/processor.rb +39 -0
- data/lib/charyf/engine/session/session.rb +68 -0
- data/lib/charyf/engine/skill/info.rb +24 -0
- data/lib/charyf/engine/skill/routing.rb +57 -0
- data/lib/charyf/engine/skill/skill.rb +40 -0
- data/lib/charyf/engine.rb +3 -0
- data/lib/charyf/support/all.rb +4 -0
- data/lib/charyf/support/hash.rb +43 -0
- data/lib/charyf/support/object.rb +7 -0
- data/lib/charyf/support/string.rb +94 -0
- data/lib/charyf/support/string_inquirer.rb +17 -0
- data/lib/charyf/support.rb +1 -0
- data/lib/charyf/utils/all.rb +13 -0
- data/lib/charyf/utils/app_engine/extensions.rb +21 -0
- data/lib/charyf/utils/app_engine.rb +24 -0
- data/lib/charyf/utils/app_loader.rb +38 -0
- data/lib/charyf/utils/application/bootstrap.rb +176 -0
- data/lib/charyf/utils/application/configuration.rb +51 -0
- data/lib/charyf/utils/application.rb +131 -0
- data/lib/charyf/utils/charyf.rb +44 -0
- data/lib/charyf/utils/cli.rb +14 -0
- data/lib/charyf/utils/command/actions.rb +24 -0
- data/lib/charyf/utils/command/base.rb +138 -0
- data/lib/charyf/utils/command/behavior.rb +81 -0
- data/lib/charyf/utils/command/environment_argument.rb +40 -0
- data/lib/charyf/utils/command.rb +106 -0
- data/lib/charyf/utils/commands/all.rb +6 -0
- data/lib/charyf/utils/commands/application/application_command.rb +21 -0
- data/lib/charyf/utils/commands/cli/cli_command.rb +115 -0
- data/lib/charyf/utils/commands/console/console_command.rb +77 -0
- data/lib/charyf/utils/commands/destroy/destroy_command.rb +26 -0
- data/lib/charyf/utils/commands/generate/generate_command.rb +31 -0
- data/lib/charyf/utils/commands/help/USAGE +9 -0
- data/lib/charyf/utils/commands/help/help.rb +20 -0
- data/lib/charyf/utils/commands.rb +15 -0
- data/lib/charyf/utils/configuration.rb +36 -0
- data/lib/charyf/utils/error_handler.rb +26 -0
- data/lib/charyf/utils/extension/configurable.rb +41 -0
- data/lib/charyf/utils/extension/configuration.rb +63 -0
- data/lib/charyf/utils/extension.rb +129 -0
- data/lib/charyf/utils/generator/actions.rb +281 -0
- data/lib/charyf/utils/generator/base.rb +288 -0
- data/lib/charyf/utils/generators/app/USAGE +8 -0
- data/lib/charyf/utils/generators/app/app_generator.rb +274 -0
- data/lib/charyf/utils/generators/app/templates/Gemfile.erb +20 -0
- data/lib/charyf/utils/generators/app/templates/README.md +24 -0
- data/lib/charyf/utils/generators/app/templates/app/skill_controller.rb.tt +8 -0
- data/lib/charyf/utils/generators/app/templates/bin/charyf +5 -0
- data/lib/charyf/utils/generators/app/templates/config/application.rb.tt +32 -0
- data/lib/charyf/utils/generators/app/templates/config/boot.rb.tt +4 -0
- data/lib/charyf/utils/generators/app/templates/config/chapp.rb.tt +5 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/development.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/production.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/test.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/load.rb.tt +17 -0
- data/lib/charyf/utils/generators/app/templates/gitignore +18 -0
- data/lib/charyf/utils/generators/app_base.rb +277 -0
- data/lib/charyf/utils/generators/defaults.rb +75 -0
- data/lib/charyf/utils/generators/intents/intents_generator.rb +41 -0
- data/lib/charyf/utils/generators/named_base.rb +73 -0
- data/lib/charyf/utils/generators/skill/skill_generator.rb +47 -0
- data/lib/charyf/utils/generators/skill/templates/controllers/skill_controller.rb.tt +10 -0
- data/lib/charyf/utils/generators/skill/templates/module.rb.tt +6 -0
- data/lib/charyf/utils/generators/skill/templates/skill.rb.tt +3 -0
- data/lib/charyf/utils/generators.rb +187 -0
- data/lib/charyf/utils/initializable.rb +95 -0
- data/lib/charyf/utils/logger.rb +26 -0
- data/lib/charyf/utils/machine.rb +129 -0
- data/lib/charyf/utils/parser/en_parser.rb +97 -0
- data/lib/charyf/utils/parser/parser.rb +37 -0
- data/lib/charyf/utils/ruby_version_check.rb +15 -0
- data/lib/charyf/utils/storage/provider.rb +44 -0
- data/lib/charyf/utils/strategy.rb +44 -0
- data/lib/charyf/utils/utils.rb +64 -0
- data/lib/charyf/utils.rb +2 -0
- data/lib/charyf/version.rb +19 -0
- data/lib/charyf.rb +18 -0
- data/lib/locale/en.yml +206 -0
- data/todo.md +3 -0
- metadata +272 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
require_relative '../../utils'
|
|
4
|
+
|
|
5
|
+
module Charyf
|
|
6
|
+
module Controller
|
|
7
|
+
module Renderers
|
|
8
|
+
|
|
9
|
+
class ResponseFileMissingError < StandardError; end
|
|
10
|
+
class NoResponseFound < StandardError; end
|
|
11
|
+
class InvalidState < StandardError; end
|
|
12
|
+
|
|
13
|
+
def self.included(base)
|
|
14
|
+
base.extend(ClassMethods)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module ClassMethods
|
|
18
|
+
|
|
19
|
+
def auto_reply(only: [], except: [])
|
|
20
|
+
@_render_filters = Charyf::Utils.create_action_filters(only, except)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def _render_on?(action)
|
|
24
|
+
Charyf::Utils.match_action_filters?(action.to_sym, _render_filters)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def _render_filters
|
|
28
|
+
@_render_filters ||= Charyf::Utils.create_action_filters
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end # End of ClassMethods
|
|
32
|
+
|
|
33
|
+
# TODO sig
|
|
34
|
+
def response_folder
|
|
35
|
+
return nil if skill_name.to_s.blank?
|
|
36
|
+
|
|
37
|
+
return skill_name.to_s.constantize.skill_root.join('responses', controller_path)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def ensure_responses_for(action)
|
|
41
|
+
unless response_folder
|
|
42
|
+
raise Charyf::Controller::Renderers::InvalidState.new('Controller without skill can not render views')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if responses_for(action).empty?
|
|
46
|
+
raise Charyf::Controller::Renderers::NoResponseFound.new('No responses files found for action ' + action.to_s + "\n" +
|
|
47
|
+
"Expected #{action}.[html|txt].erb in #{response_folder}")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# TODO sig
|
|
52
|
+
def responses_for(action)
|
|
53
|
+
Dir[response_folder.join("#{action}**")]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# TODO sig
|
|
57
|
+
def render_text_response(action)
|
|
58
|
+
file_path = response_folder.join("#{action}.txt.erb")
|
|
59
|
+
|
|
60
|
+
return nil unless exists?(file_path)
|
|
61
|
+
|
|
62
|
+
_render_sample_response file_path
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# TODO sig
|
|
66
|
+
def render_html_response(action)
|
|
67
|
+
file_path = response_folder.join("#{action}.html.erb")
|
|
68
|
+
|
|
69
|
+
return nil unless exists?(file_path)
|
|
70
|
+
|
|
71
|
+
_render_response file_path
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def _render_sample_response(file)
|
|
77
|
+
sample = File.read(file).split("###").map(&:strip).sample
|
|
78
|
+
ERB.new(sample).result(binding)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def _render_response(file)
|
|
82
|
+
sample = File.read(file)
|
|
83
|
+
ERB.new(sample).result(binding)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# TODO sig
|
|
88
|
+
def controller_path
|
|
89
|
+
controller_name.underscore
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# TODO sig
|
|
93
|
+
def exists?(path)
|
|
94
|
+
File.exists?(path)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def exists!(path)
|
|
98
|
+
raise ResponseFileMissingError.new(path) unless exists?(path)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require_relative '../../utils'
|
|
2
|
+
|
|
3
|
+
require_relative '../context'
|
|
4
|
+
require_relative '../request'
|
|
5
|
+
|
|
6
|
+
module Charyf
|
|
7
|
+
module Engine
|
|
8
|
+
module Dispatcher
|
|
9
|
+
class Base
|
|
10
|
+
|
|
11
|
+
include Charyf::Strategy
|
|
12
|
+
def self.base
|
|
13
|
+
Base
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
sig ['Charyf::Engine::Request'], nil,
|
|
17
|
+
def dispatch(request)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.setup
|
|
21
|
+
# Do your setup here
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def self.intent_processors
|
|
28
|
+
Charyf.application.intent_processors
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.session_processor
|
|
32
|
+
Charyf.application.session_processor
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def intent_processors
|
|
36
|
+
self.class.intent_processors
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def session_processor
|
|
40
|
+
self.class.session_processor
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
sig ['Charyf::Engine::Context'], nil,
|
|
44
|
+
def spawn_controller(context)
|
|
45
|
+
begin
|
|
46
|
+
prepare_context context
|
|
47
|
+
|
|
48
|
+
Charyf.logger.flow_request("[FLOW] Dispatching request [#{context.request.inspect}]" +
|
|
49
|
+
", detected intent: [#{context.intent.inspect}]" +
|
|
50
|
+
", session : [#{context.session.inspect}]"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
controller = get_controller(context)
|
|
54
|
+
|
|
55
|
+
handle_before_actions(controller)
|
|
56
|
+
controller.send(context.action_name)
|
|
57
|
+
handle_after_actions(controller)
|
|
58
|
+
rescue Exception => e
|
|
59
|
+
# Dispatch the error to all error handlers
|
|
60
|
+
Charyf.configuration.error_handlers.handle_exception(e)
|
|
61
|
+
|
|
62
|
+
# Catch any error that may occur inside the user controller
|
|
63
|
+
controller.send(:reply, text: 'There was a problem processing your request. Check the logs please.')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def prepare_context(context)
|
|
71
|
+
context.intent ||= Charyf::Engine::Intent::UNKNOWN
|
|
72
|
+
|
|
73
|
+
context
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def get_controller(context)
|
|
77
|
+
controller_name = context.full_controller_name + 'Controller'
|
|
78
|
+
|
|
79
|
+
Object.const_get(controller_name).new(context)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def get_action_name(context)
|
|
83
|
+
if context.session && context.session.action
|
|
84
|
+
return context.session.action
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context.intent.action
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def handle_before_actions(controller)
|
|
91
|
+
action = controller.action_name
|
|
92
|
+
|
|
93
|
+
# Handle before actions
|
|
94
|
+
controller.class._before_actions(action).each do |method_name|
|
|
95
|
+
controller.send(method_name)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def handle_after_actions(controller)
|
|
101
|
+
action = controller.action_name
|
|
102
|
+
|
|
103
|
+
# Auto render responses
|
|
104
|
+
if controller.class._render_on? action
|
|
105
|
+
controller.send(:reply)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end # End of Base.class
|
|
110
|
+
|
|
111
|
+
def self.known
|
|
112
|
+
Base.known
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def self.list
|
|
116
|
+
Base.list
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module Charyf
|
|
4
|
+
module Engine
|
|
5
|
+
module Dispatcher
|
|
6
|
+
class BaseDispatcher < Base
|
|
7
|
+
|
|
8
|
+
strategy_name :default
|
|
9
|
+
|
|
10
|
+
def self.setup
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def dispatch(request)
|
|
15
|
+
# Find if session exist for this request
|
|
16
|
+
|
|
17
|
+
context = Charyf::Engine::Context.new
|
|
18
|
+
context.request = request
|
|
19
|
+
|
|
20
|
+
# TODO process session as well
|
|
21
|
+
context.session = session_processor.get.process(request)
|
|
22
|
+
|
|
23
|
+
# Get intents
|
|
24
|
+
intents = intent_processors.collect do |processor_klass|
|
|
25
|
+
processor = processor_klass.get_for(context.session ? context.session.skill : nil)
|
|
26
|
+
|
|
27
|
+
processor.determine(
|
|
28
|
+
request
|
|
29
|
+
)
|
|
30
|
+
end.collect do |intent|
|
|
31
|
+
[intent, intent.alternatives].flatten
|
|
32
|
+
end.flatten.sort_by do |intent|
|
|
33
|
+
intent.confidence
|
|
34
|
+
end.reverse
|
|
35
|
+
|
|
36
|
+
# Sort by confidence
|
|
37
|
+
best_match = intents.shift
|
|
38
|
+
|
|
39
|
+
# Return best match with alternatives
|
|
40
|
+
if best_match
|
|
41
|
+
context.intent = Charyf::Engine::Intent.new(
|
|
42
|
+
best_match.skill,
|
|
43
|
+
best_match.controller,
|
|
44
|
+
best_match.action,
|
|
45
|
+
best_match.confidence,
|
|
46
|
+
best_match.matches,
|
|
47
|
+
intents
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
context.intent = best_match
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# TODO
|
|
54
|
+
spawn_controller(context)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Charyf
|
|
2
|
+
module Engine
|
|
3
|
+
class Intent
|
|
4
|
+
|
|
5
|
+
sig [['Symbol', 'String', 'NilClass'], ['Symbol', 'String'], ['Symbol', 'String'], 'Numeric', 'Hash', 'Array'], nil,
|
|
6
|
+
def initialize(skill, controller, action, confidence, matches = Hash.new, alternatives = [])
|
|
7
|
+
@_skill = skill.to_s
|
|
8
|
+
@_controller = controller.to_s
|
|
9
|
+
@_action = action.to_s.downcase
|
|
10
|
+
@_confidence = confidence
|
|
11
|
+
@_matches = matches
|
|
12
|
+
@_alternatives = alternatives
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
sig [], 'Hash',
|
|
16
|
+
def matches
|
|
17
|
+
@_matches
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
sig [], 'Numeric',
|
|
21
|
+
def confidence
|
|
22
|
+
@_confidence
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
sig [], ['Symbol', 'String'],
|
|
26
|
+
def full_controller_name
|
|
27
|
+
@_skill.blank? ? @_controller.camelize : @_skill.camelize + '::' + @_controller.camelize
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
sig [], ['Symbol', 'String'],
|
|
31
|
+
def controller
|
|
32
|
+
@_controller
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
sig [], ['Symbol', 'String'],
|
|
36
|
+
def action
|
|
37
|
+
@_action
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
sig [], 'Array',
|
|
41
|
+
def alternatives
|
|
42
|
+
@_alternatives
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
sig [], ['String', 'Symbol'],
|
|
46
|
+
def skill
|
|
47
|
+
@_skill
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
UNKNOWN = Intent.new(nil, :Skill, :unknown, 0)
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative '../../../utils'
|
|
2
|
+
|
|
3
|
+
require_relative '../intent'
|
|
4
|
+
require_relative 'processor'
|
|
5
|
+
|
|
6
|
+
module Charyf
|
|
7
|
+
module Engine
|
|
8
|
+
class Intent
|
|
9
|
+
module Processor
|
|
10
|
+
class Dummy < Base
|
|
11
|
+
|
|
12
|
+
strategy_name :dummy
|
|
13
|
+
|
|
14
|
+
def self.get_for(skill_name = nil)
|
|
15
|
+
self.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def determine(request)
|
|
19
|
+
unknown
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def load(skill_name, block)
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Charyf
|
|
2
|
+
module Engine
|
|
3
|
+
class Intent
|
|
4
|
+
module Processor
|
|
5
|
+
module Helpers
|
|
6
|
+
|
|
7
|
+
def self.included(base)
|
|
8
|
+
base.extend(ClassMethods)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module ClassMethods
|
|
12
|
+
|
|
13
|
+
def scoped_name(skill_name, *args)
|
|
14
|
+
([skill_name.to_s] + args).join('_')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def unscope_name(skill_name, name)
|
|
18
|
+
name.start_with?(skill_name.to_s) ? name.sub("#{skill_name.to_s}_", '') : name
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end # End of ClassMethods
|
|
22
|
+
|
|
23
|
+
sig [], 'Charyf::Engine::Intent',
|
|
24
|
+
def unknown
|
|
25
|
+
Charyf::Engine::Intent::UNKNOWN
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require_relative '../../../utils'
|
|
2
|
+
|
|
3
|
+
require_relative 'helpers'
|
|
4
|
+
require_relative '../intent'
|
|
5
|
+
|
|
6
|
+
module Charyf
|
|
7
|
+
module Engine
|
|
8
|
+
class Intent
|
|
9
|
+
module Processor
|
|
10
|
+
class Base
|
|
11
|
+
|
|
12
|
+
include Charyf::Strategy
|
|
13
|
+
include Charyf::Engine::Intent::Processor::Helpers
|
|
14
|
+
|
|
15
|
+
def self.base
|
|
16
|
+
Base
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
sig ['Charyf::Engine::Request'], 'Charyf::Engine::Intent',
|
|
20
|
+
def determine(request)
|
|
21
|
+
raise Charyf::Utils::NotImplemented.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Load single block of intent definitions
|
|
26
|
+
#
|
|
27
|
+
sig_self ['Symbol', 'Proc'], nil,
|
|
28
|
+
def load(skill_name, block)
|
|
29
|
+
raise Charyf::Utils::NotImplemented.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
sig_self ['Symbol'], 'Charyf::Engine::Intent::Processor::Base',
|
|
33
|
+
def self.get_for(skill = nil)
|
|
34
|
+
raise Charyf::Utils::NotImplemented.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
sig_self [], 'Charyf::Engine::Intent::Processor::Base',
|
|
38
|
+
def self.get_global
|
|
39
|
+
get_for(nil)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def self.known
|
|
46
|
+
Base.known
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.list
|
|
50
|
+
Base.list
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative '../../utils'
|
|
2
|
+
|
|
3
|
+
require_relative '../response'
|
|
4
|
+
require_relative '../dispatcher/base'
|
|
5
|
+
|
|
6
|
+
module Charyf
|
|
7
|
+
module Interface
|
|
8
|
+
class Base
|
|
9
|
+
|
|
10
|
+
include Charyf::Strategy
|
|
11
|
+
def self.base
|
|
12
|
+
Base
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
sig_self [], 'Charyf::Engine::Dispatcher::Base',
|
|
16
|
+
def self.dispatcher
|
|
17
|
+
Charyf.application.dispatcher.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
sig_self ['String', 'Charyf::Engine::Response'], nil,
|
|
21
|
+
def self.reply(conversation_id, response)
|
|
22
|
+
raise Charyf::Utils::NotImplemented.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.known
|
|
28
|
+
Base.known
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.list
|
|
32
|
+
Base.list
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require_relative 'interface'
|
|
2
|
+
require_relative '../request'
|
|
3
|
+
|
|
4
|
+
module Charyf
|
|
5
|
+
module Interface
|
|
6
|
+
class Program < Charyf::Interface::Base
|
|
7
|
+
|
|
8
|
+
class InvalidConversationError < StandardError; end
|
|
9
|
+
|
|
10
|
+
strategy_name :program
|
|
11
|
+
|
|
12
|
+
attr_reader :handler, :conversation_id
|
|
13
|
+
|
|
14
|
+
sig_self ['String', 'Charyf::Engine::Response'], nil,
|
|
15
|
+
def self.reply(conversation_id, response)
|
|
16
|
+
interface = _interfaces[conversation_id]
|
|
17
|
+
raise InvalidConversationError.new("No program interface found for conversation #{conversation_id}") unless interface
|
|
18
|
+
|
|
19
|
+
interface.reply(response)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
sig_self ['String', 'Proc'], 'Charyf::Interface::Program',
|
|
23
|
+
def self.create(conversation_id, handler)
|
|
24
|
+
interface = self.new(conversation_id, handler)
|
|
25
|
+
|
|
26
|
+
_interfaces[conversation_id] = interface
|
|
27
|
+
|
|
28
|
+
interface
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self._interfaces
|
|
32
|
+
@_interfaces ||= Hash.new
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
sig [nil, 'Proc'],
|
|
36
|
+
def initialize(conversation_id, handler)
|
|
37
|
+
|
|
38
|
+
@handler = handler
|
|
39
|
+
@conversation_id = conversation_id.to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
sig ['Charyf::Engine::Request'],
|
|
43
|
+
def process(request)
|
|
44
|
+
self.class.dispatcher.dispatch(request)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
sig ['Charyf::Engine::Response'],
|
|
48
|
+
def reply(response)
|
|
49
|
+
handler.call(response)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
sig [], 'Charyf::Engine::Request',
|
|
53
|
+
def request
|
|
54
|
+
Charyf::Engine::Request.new(self.class, conversation_id)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Charyf
|
|
2
|
+
module Engine
|
|
3
|
+
class Request
|
|
4
|
+
|
|
5
|
+
attr_accessor :text
|
|
6
|
+
|
|
7
|
+
# Module -> anything of type Charyf::Interface::Base
|
|
8
|
+
sig ['Module', 'String'], nil,
|
|
9
|
+
def initialize(referer, conversation_id)
|
|
10
|
+
@referer = referer
|
|
11
|
+
@conversation_id = conversation_id
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Module -> Charyf::Interface::Base
|
|
15
|
+
sig [], 'Module',
|
|
16
|
+
def referer
|
|
17
|
+
@referer
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
sig [], 'String',
|
|
21
|
+
def conversation_id
|
|
22
|
+
@conversation_id
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
sig [], 'String',
|
|
26
|
+
def id
|
|
27
|
+
@referer.strategy_name.to_s + '_#_' + @conversation_id
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Charyf
|
|
2
|
+
module Engine
|
|
3
|
+
class Response
|
|
4
|
+
|
|
5
|
+
attr_accessor :text, :html
|
|
6
|
+
|
|
7
|
+
sig [['String', 'NilClass'], ['String', 'NilClass']], nil,
|
|
8
|
+
def initialize(text, html)
|
|
9
|
+
@text = text
|
|
10
|
+
@html = html
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def empty?
|
|
14
|
+
text.blank? && html.blank?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Attr methods for type-checking
|
|
18
|
+
|
|
19
|
+
sig ['String', 'NilClass'], ['String', 'NilClass'],
|
|
20
|
+
def text=(text)
|
|
21
|
+
@text = text
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
sig [], ['String', 'NilClass'],
|
|
25
|
+
def text
|
|
26
|
+
@text
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
sig ['String', 'NilClass'], ['String', 'NilClass'],
|
|
30
|
+
def html=(html)
|
|
31
|
+
@html = html
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
sig [], ['String', 'NilClass'],
|
|
35
|
+
def html
|
|
36
|
+
@html
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require_relative '../../../utils'
|
|
2
|
+
|
|
3
|
+
require_relative '../session'
|
|
4
|
+
require_relative 'processor'
|
|
5
|
+
|
|
6
|
+
module Charyf
|
|
7
|
+
module Engine
|
|
8
|
+
class Session
|
|
9
|
+
module Processor
|
|
10
|
+
class Default < Base
|
|
11
|
+
|
|
12
|
+
# 10 Minute
|
|
13
|
+
# TODO - move to config?
|
|
14
|
+
SESSION_TIMEOUT = 10 * 60
|
|
15
|
+
|
|
16
|
+
strategy_name :default
|
|
17
|
+
|
|
18
|
+
def process(request)
|
|
19
|
+
# session = Charyf::Engine::Session.get(request.id)
|
|
20
|
+
#
|
|
21
|
+
# return unless session
|
|
22
|
+
#
|
|
23
|
+
# if session && Time.now - session.timestamp > SESSION_TIMEOUT
|
|
24
|
+
# session.destroy!
|
|
25
|
+
# return nil
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# session.invalidate!
|
|
29
|
+
# session
|
|
30
|
+
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.get
|
|
35
|
+
self.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require_relative '../../../utils'
|
|
2
|
+
|
|
3
|
+
module Charyf
|
|
4
|
+
module Engine
|
|
5
|
+
class Session
|
|
6
|
+
module Processor
|
|
7
|
+
class Base
|
|
8
|
+
|
|
9
|
+
include Charyf::Strategy
|
|
10
|
+
def self.base
|
|
11
|
+
Base
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
sig ['Charyf::Engine::Request'], ['Charyf::Engine::Session', 'NilClass'],
|
|
16
|
+
def process(request)
|
|
17
|
+
raise Charyf::Utils::NotImplemented.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
sig_self [], ['Charyf::Engine::Session::Processor::Base'],
|
|
21
|
+
def self.get
|
|
22
|
+
raise Charyf::Utils::NotImplemented.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def self.known
|
|
29
|
+
Base.known
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.list
|
|
33
|
+
Base.list
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|