alexa_generator 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4805b19d31381011f755d8270dc535a64bb75879
4
- data.tar.gz: c0360ca35a27e1c95432681ba41c670c361e3606
3
+ metadata.gz: 5e8ba24c9e6ca19a170be8d4e925ac95e89511e2
4
+ data.tar.gz: 48408c740b0ec858c3159824f2ea190a9ff487df
5
5
  SHA512:
6
- metadata.gz: 3a760ba8c02c4f78922b4e42e4f93b6795c5f4b7a0d506b6ac67231df366194b1ba0320f4dd17e6089ff13dd58994ed089aee42f9834013acb6f66683c35b67a
7
- data.tar.gz: b50e3df34f7742573f1c2c49cacbe96aa96a54f358d56dc4098ae8991f0d6284ad389bfcb347fad5e88c61aa43038e2286153b1b2221384200fae7bb37c301eb
6
+ metadata.gz: 7048fadeedc9213ce2f34823c7a12257ea7092b32a3b1b691f175ea6d5cd374b927cff87907811871e75260c8066390fa83c9acf96283f2caee05edfeca53d7d
7
+ data.tar.gz: 4f94f8409c5e413a44f71b5ba2d1b5a6386bf4c8622c1b32d83b566a501f6779180ca947075980b0a88d8ac5b30eb2b6a35d68766f1331c6575a2c994f5cf3bb
@@ -1,4 +1,7 @@
1
1
  module AlexaGenerator
2
2
  class AlexaSyntaxError < StandardError
3
3
  end
4
+
5
+ class InvalidIntentError < StandardError
6
+ end
4
7
  end
@@ -3,6 +3,31 @@ require 'alexa_generator/sample_utterance_template'
3
3
 
4
4
  module AlexaGenerator
5
5
  class Intent
6
+
7
+ module AmazonIntentType
8
+ VALUES = [
9
+ CANCEL = :"AMAZON.CancelIntent",
10
+ HELP = :"AMAZON.HelpIntent",
11
+ LOOP_OFF = :"AMAZON.LoopOffIntent",
12
+ LOOP_ON = :"AMAZON.LoopOnIntent",
13
+ NEXT = :"AMAZON.NextIntent",
14
+ NO = :"AMAZON.NoIntent",
15
+ PAUSE = :"AMAZON.PauseIntent",
16
+ PREVIOUS = :"AMAZON.PreviousIntent",
17
+ REPEAT = :"AMAZON.RepeatIntent",
18
+ RESUME = :"AMAZON.ResumeIntent",
19
+ SHUFFLE_OFF = :"AMAZON.ShuffleOffIntent",
20
+ SHUFFLE_ON = :"AMAZON.ShuffleOnIntent",
21
+ START_OVER = :"AMAZON.StartOverIntent",
22
+ STOP = :"AMAZON.StopIntent",
23
+ YES = :"AMAZON.YesIntent"
24
+ ]
25
+
26
+ def self.amazon_intent?(val)
27
+ VALUES.include?(val.to_sym)
28
+ end
29
+ end
30
+
6
31
  attr_reader :name, :slots
7
32
 
8
33
  class Builder
@@ -16,6 +41,11 @@ module AlexaGenerator
16
41
  end
17
42
 
18
43
  def add_slot(name, type, &block)
44
+ if AmazonIntentType.amazon_intent?(@name)
45
+ raise AlexaGenerator::InvalidIntentError,
46
+ "Amazon intents don't support slots. Tried to add a slot to intent of type: #{type}"
47
+ end
48
+
19
49
  builder = Slot.build(name, type, &block)
20
50
 
21
51
  slot_bindings = builder.bindings.map { |x| SlotBinding.new(name, x) }
@@ -41,10 +71,14 @@ module AlexaGenerator
41
71
  @name = name
42
72
  @slots = slots
43
73
  end
74
+
75
+ def amazon_intent?
76
+ AmazonIntentType.amazon_intent?(@name)
77
+ end
44
78
 
45
79
  def self.build(name, &block)
46
80
  builder = Builder.new(name)
47
- block.call(builder)
81
+ block.call(builder) if block
48
82
  builder
49
83
  end
50
84
  end
@@ -45,29 +45,35 @@ module AlexaGenerator
45
45
  end
46
46
 
47
47
  def intent_schema
48
- {
49
- intents: @intents.values.map do |intent|
50
- {
51
- intent: intent.name,
52
- slots: intent.slots.map do |slot|
53
- {
54
- name: slot.name,
55
- type: slot.type
56
- }
57
- end
58
- }
59
- end
60
- }
48
+ intents = []
49
+
50
+ @intents.values.each do |intent|
51
+ slots = []
52
+
53
+ intent.slots.each do |slot|
54
+ slots << {name: slot.name, type: slot.type}
55
+ end
56
+
57
+ intents << {intent: intent.name, slots: slots}
58
+ end
59
+
60
+ { intents: intents }
61
61
  end
62
62
 
63
63
  def sample_utterances(intent_name)
64
64
  templates = @utterance_templates[intent_name] || []
65
+ slot_types = collect_slot_types
65
66
  utterances = Set.new
66
67
 
67
68
  templates.each do |template|
68
69
  # Consider only the slots that are referenced in this template
69
70
  relevant_slots = template.referenced_slots
70
71
 
72
+ # Amazon wants only the LITERAL ones
73
+ relevant_slots.select! do |s|
74
+ AlexaGenerator::Slot::SlotType.literal?(slot_types[s.to_sym])
75
+ end
76
+
71
77
  # Compute all possible value bindings for the relevant slots
72
78
  slot_values = relevant_slots.
73
79
  # Extract value bindings for each slot
@@ -106,6 +112,16 @@ module AlexaGenerator
106
112
  end
107
113
  end
108
114
 
115
+ def collect_slot_types
116
+ out = {}
117
+ @intents.values.each do |intent|
118
+ intent.slots.map do |slot|
119
+ out[slot.name.to_sym] = slot.type.to_s
120
+ end
121
+ end
122
+ out
123
+ end
124
+
109
125
  def self.build(&block)
110
126
  builder = Builder.new
111
127
  block.call(builder)
@@ -1,11 +1,15 @@
1
1
  module AlexaGenerator
2
2
  class Slot
3
3
  module SlotType
4
- LITERAL = :LITERAL
5
- NUMBER = :NUMBER
6
- DATE = :DATE
7
- TIME = :TIME
8
- DURATION = :DURATION
4
+ LITERAL = :"AMAZON.LITERAL"
5
+ NUMBER = :"AMAZON.NUMBER"
6
+ DATE = :"AMAZON.DATE"
7
+ TIME = :"AMAZON.TIME"
8
+ DURATION = :"AMAZON.DURATION"
9
+
10
+ def self.literal?(value)
11
+ [:LITERAL, LITERAL].include?(value.to_sym)
12
+ end
9
13
  end
10
14
 
11
15
  class Builder
@@ -1,3 +1,3 @@
1
1
  module AlexaGenerator
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -1,3 +1,3 @@
1
1
  require 'alexa_generator/interaction_model'
2
- require 'alexa_generator/alexa_syntax_error'
2
+ require 'alexa_generator/errors'
3
3
  require 'alexa_generator/version'
@@ -33,5 +33,13 @@ describe AlexaGenerator::Slot do
33
33
  expect(intent.slots.count).to eq(1)
34
34
  expect(intent.slots.first.name).to eq(:SlotOne)
35
35
  end
36
+
37
+ it 'should whine when trying to add a slot to an Amazon intent' do
38
+ AlexaGenerator::Intent.build(AlexaGenerator::Intent::AmazonIntentType::CANCEL) do |intent|
39
+ expect {
40
+ intent.add_slot(:SlotOne, AlexaGenerator::Slot::SlotType::LITERAL)
41
+ }.to raise_error(AlexaGenerator::InvalidIntentError)
42
+ end
43
+ end
36
44
  end
37
45
  end
@@ -43,6 +43,56 @@ describe AlexaGenerator::InteractionModel do
43
43
  })
44
44
  end
45
45
 
46
+ it 'should allow built in intents' do
47
+ iface = AlexaGenerator::InteractionModel.build do |iface|
48
+ iface.add_intent(AlexaGenerator::Intent::AmazonIntentType::CANCEL)
49
+ end
50
+
51
+ expect(iface).to be_an_instance_of(AlexaGenerator::InteractionModel)
52
+ expect(iface.intent_schema).to eq(
53
+ {
54
+ intents: [
55
+ {
56
+ intent: :"AMAZON.CancelIntent",
57
+ slots: []
58
+ }
59
+ ]
60
+ })
61
+ end
62
+
63
+ it 'should combine custom and built in intents' do
64
+ iface = AlexaGenerator::InteractionModel.build do |iface|
65
+ iface.add_intent(AlexaGenerator::Intent::AmazonIntentType::CANCEL)
66
+ iface.add_intent(:IntentOne) do |intent|
67
+ intent.add_slot(:SlotOne, AlexaGenerator::Slot::SlotType::LITERAL) do |slot|
68
+ slot.add_binding('value1')
69
+ end
70
+
71
+ intent.add_utterance_template('test {SlotOne} test')
72
+ end
73
+ end
74
+
75
+ expect(iface).to be_an_instance_of(AlexaGenerator::InteractionModel)
76
+ expect(iface.intent_schema).to eq(
77
+ {
78
+ intents: [
79
+ {
80
+ intent: :"AMAZON.CancelIntent",
81
+ slots: []
82
+ },
83
+ {
84
+ intent: :IntentOne,
85
+ slots: [
86
+ {
87
+ name: :SlotOne,
88
+ type: AlexaGenerator::Slot::SlotType::LITERAL
89
+ }
90
+ ]
91
+ }
92
+ ]
93
+ })
94
+ end
95
+
46
96
  it 'should produce bound utterances' do
47
97
  iface = AlexaGenerator::InteractionModel.build do |iface|
48
98
  iface.add_intent(:MyIntent) do |intent|
@@ -67,15 +117,10 @@ describe AlexaGenerator::InteractionModel do
67
117
 
68
118
  actual = iface.sample_utterances(:MyIntent)
69
119
 
70
- expect(actual.count).to eq(8)
71
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {one|SlotTwo} at {noon|SlotThree}')
72
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {two|SlotTwo} at {noon|SlotThree}')
73
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {one|SlotTwo} at {noon|SlotThree}')
74
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {two|SlotTwo} at {noon|SlotThree}')
75
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {one|SlotTwo} at {6 a.m.|SlotThree}')
76
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {two|SlotTwo} at {6 a.m.|SlotThree}')
77
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {one|SlotTwo} at {6 a.m.|SlotThree}')
78
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {two|SlotTwo} at {6 a.m.|SlotThree}')
120
+ # only the literal ones get examples
121
+ expect(actual.count).to eq(2)
122
+ expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {SlotTwo} at {SlotThree}')
123
+ expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {SlotTwo} at {SlotThree}')
79
124
  end
80
125
  end
81
126
 
@@ -144,15 +189,10 @@ describe AlexaGenerator::InteractionModel do
144
189
  it 'should produce bound utterances' do
145
190
  actual = AlexaGenerator::InteractionModel.new(intents, utterance_templates, slot_bindings).sample_utterances(:MyIntent)
146
191
 
147
- expect(actual.count).to eq(8)
148
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {one|SlotTwo} at {noon|SlotThree}')
149
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {two|SlotTwo} at {noon|SlotThree}')
150
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {one|SlotTwo} at {noon|SlotThree}')
151
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {two|SlotTwo} at {noon|SlotThree}')
152
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {one|SlotTwo} at {6 a.m.|SlotThree}')
153
- expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {two|SlotTwo} at {6 a.m.|SlotThree}')
154
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {one|SlotTwo} at {6 a.m.|SlotThree}')
155
- expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {two|SlotTwo} at {6 a.m.|SlotThree}')
192
+ # only the literal ones get examples
193
+ expect(actual.count).to eq(2)
194
+ expect(actual).to include('MyIntent Alexa, please {fix my motorcycle|SlotOne} {SlotTwo} at {SlotThree}')
195
+ expect(actual).to include('MyIntent Alexa, please {make me a sandwich|SlotOne} {SlotTwo} at {SlotThree}')
156
196
  end
157
197
  end
158
198
  end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alexa_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Mullins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-21 00:00:00.000000000 Z
11
+ date: 2016-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.0.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  description:
@@ -44,14 +44,14 @@ executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
- - .gitignore
47
+ - ".gitignore"
48
48
  - Gemfile
49
49
  - LICENSE
50
50
  - README.md
51
51
  - Rakefile
52
52
  - alexa_generator.gemspec
53
53
  - lib/alexa_generator.rb
54
- - lib/alexa_generator/alexa_syntax_error.rb
54
+ - lib/alexa_generator/errors.rb
55
55
  - lib/alexa_generator/intent.rb
56
56
  - lib/alexa_generator/intent_schema.rb
57
57
  - lib/alexa_generator/interaction_model.rb
@@ -73,17 +73,17 @@ require_paths:
73
73
  - lib
74
74
  required_ruby_version: !ruby/object:Gem::Requirement
75
75
  requirements:
76
- - - '>='
76
+ - - ">="
77
77
  - !ruby/object:Gem::Version
78
78
  version: '0'
79
79
  required_rubygems_version: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - '>='
81
+ - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  requirements: []
85
85
  rubyforge_project:
86
- rubygems_version: 2.0.14
86
+ rubygems_version: 2.5.1
87
87
  signing_key:
88
88
  specification_version: 4
89
89
  summary: Generates voice interfaces for Alexa apps based on templates.