aws-lex-conversation 3.0.0 → 4.0.2

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/README.md +28 -6
  4. data/lib/aws/lex/conversation.rb +9 -21
  5. data/lib/aws/lex/conversation/base.rb +13 -10
  6. data/lib/aws/lex/conversation/handler/delegate.rb +1 -3
  7. data/lib/aws/lex/conversation/handler/echo.rb +6 -4
  8. data/lib/aws/lex/conversation/response/base.rb +11 -10
  9. data/lib/aws/lex/conversation/response/close.rb +5 -11
  10. data/lib/aws/lex/conversation/response/confirm_intent.rb +4 -13
  11. data/lib/aws/lex/conversation/response/delegate.rb +4 -11
  12. data/lib/aws/lex/conversation/response/elicit_intent.rb +4 -7
  13. data/lib/aws/lex/conversation/response/elicit_slot.rb +5 -12
  14. data/lib/aws/lex/conversation/slot/elicitation.rb +6 -4
  15. data/lib/aws/lex/conversation/support/mixins/responses.rb +14 -20
  16. data/lib/aws/lex/conversation/type/base.rb +10 -4
  17. data/lib/aws/lex/conversation/type/bot.rb +3 -1
  18. data/lib/aws/lex/conversation/type/checkpoint.rb +57 -0
  19. data/lib/aws/lex/conversation/type/{confirmation_status.rb → confirmation_state.rb} +1 -1
  20. data/lib/aws/lex/conversation/type/context.rb +4 -4
  21. data/lib/aws/lex/conversation/type/{slot_detail.rb → dialog_action.rb} +4 -4
  22. data/lib/aws/lex/conversation/type/dialog_action_type.rb +3 -3
  23. data/lib/aws/lex/conversation/type/event.rb +26 -19
  24. data/lib/aws/lex/conversation/type/{output_dialog_mode.rb → input_mode.rb} +3 -2
  25. data/lib/aws/lex/conversation/type/intent.rb +14 -23
  26. data/lib/aws/lex/conversation/type/intent_confidence.rb +5 -5
  27. data/lib/aws/lex/conversation/type/interpretation.rb +23 -0
  28. data/lib/aws/lex/conversation/type/message.rb +4 -2
  29. data/lib/aws/lex/conversation/type/message/content_type.rb +2 -1
  30. data/lib/aws/lex/conversation/type/response.rb +3 -4
  31. data/lib/aws/lex/conversation/type/response_card.rb +5 -6
  32. data/lib/aws/lex/conversation/type/{sentiment_label.rb → sentiment.rb} +1 -1
  33. data/lib/aws/lex/conversation/type/sentiment_response.rb +3 -3
  34. data/lib/aws/lex/conversation/type/sentiment_score.rb +10 -20
  35. data/lib/aws/lex/conversation/type/session_attributes.rb +29 -0
  36. data/lib/aws/lex/conversation/type/session_state.rb +25 -0
  37. data/lib/aws/lex/conversation/type/slot.rb +54 -29
  38. data/lib/aws/lex/conversation/type/{slot_resolution.rb → slot_shape.rb} +4 -3
  39. data/lib/aws/lex/conversation/type/slot_value.rb +40 -0
  40. data/lib/aws/lex/conversation/version.rb +1 -1
  41. metadata +13 -12
  42. data/lib/aws/lex/conversation/type/recent_intent_summary_view.rb +0 -70
  43. data/lib/aws/lex/conversation/type/response_card/content_type.rb +0 -17
  44. data/lib/aws/lex/conversation/type/response_card/generic_attachment.rb +0 -26
@@ -8,51 +8,45 @@ module Aws
8
8
  module Responses
9
9
  def close(opts = {})
10
10
  params = {
11
- active_contexts: lex.active_contexts,
12
- recent_intent_summary_view: pending_checkpoints,
13
- session_attributes: lex.session_attributes
11
+ session_state: lex.session_state,
12
+ request_attributes: lex.request_attributes
14
13
  }.merge(opts)
15
14
  Response::Close.new(params).to_lex
16
15
  end
17
16
 
18
17
  def confirm_intent(opts = {})
19
18
  params = {
20
- active_contexts: lex.active_contexts,
21
- intent_name: lex.current_intent.name,
22
- recent_intent_summary_view: pending_checkpoints,
23
- session_attributes: lex.session_attributes,
24
- slots: lex.current_intent.slots
19
+ session_state: lex.session_state,
20
+ request_attributes: lex.request_attributes,
21
+ intent: lex.current_intent
25
22
  }.merge(opts)
23
+ lex.session_state.intent = params.fetch(:intent)
26
24
  Response::ConfirmIntent.new(params).to_lex
27
25
  end
28
26
 
29
27
  def delegate(opts = {})
30
28
  params = {
31
- active_contexts: lex.active_contexts,
32
- recent_intent_summary_view: pending_checkpoints,
33
- session_attributes: lex.session_attributes,
34
- slots: lex.current_intent.slots
29
+ session_state: lex.session_state,
30
+ request_attributes: lex.request_attributes
35
31
  }.merge(opts)
36
32
  Response::Delegate.new(params).to_lex
37
33
  end
38
34
 
39
35
  def elicit_intent(opts = {})
40
36
  params = {
41
- active_contexts: lex.active_contexts,
42
- recent_intent_summary_view: pending_checkpoints,
43
- session_attributes: lex.session_attributes
37
+ session_state: lex.session_state,
38
+ request_attributes: lex.request_attributes
44
39
  }.merge(opts)
45
40
  Response::ElicitIntent.new(params).to_lex
46
41
  end
47
42
 
48
43
  def elicit_slot(opts = {})
49
44
  params = {
50
- active_contexts: lex.active_contexts,
51
- intent_name: lex.current_intent.name,
52
- recent_intent_summary_view: pending_checkpoints,
53
- session_attributes: lex.session_attributes,
54
- slots: lex.current_intent.slots
45
+ session_state: lex.session_state,
46
+ request_attributes: lex.request_attributes,
47
+ intent: lex.current_intent
55
48
  }.merge(opts)
49
+ lex.session_state.intent = params.fetch(:intent)
56
50
  Response::ElicitSlot.new(params).to_lex
57
51
  end
58
52
  end
@@ -26,10 +26,11 @@ module Aws
26
26
  end
27
27
 
28
28
  def to_lex
29
- self.class.attributes.each_with_object({}) do |attribute, hash|
30
- value = transform_to_lex(instance_variable_get("@#{attribute}"))
29
+ output = self.class.attributes.each_with_object({}) do |attribute, hash|
30
+ value = transform_to_lex(public_send(attribute))
31
31
  hash[self.class.mapping.fetch(attribute)] = value
32
32
  end
33
+ output.compact
33
34
  end
34
35
 
35
36
  private
@@ -37,8 +38,13 @@ module Aws
37
38
  def transform_to_lex(value)
38
39
  case value
39
40
  when Hash
40
- value.each_with_object({}) do |(key, val), hash|
41
- hash[key.to_sym] = transform_to_lex(val)
41
+ if value.respond_to?(:to_lex)
42
+ value.to_lex
43
+ else
44
+ output = value.each_with_object({}) do |(key, val), hash|
45
+ hash[key.to_sym] = transform_to_lex(val)
46
+ end
47
+ output.compact
42
48
  end
43
49
  when Array
44
50
  value.map { |v| transform_to_lex(v) }
@@ -7,8 +7,10 @@ module Aws
7
7
  class Bot
8
8
  include Base
9
9
 
10
+ required :alias_id
11
+ required :id
12
+ required :locale_id
10
13
  required :name
11
- required :alias
12
14
  required :version
13
15
  end
14
16
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Lex
5
+ class Conversation
6
+ module Type
7
+ class Checkpoint
8
+ include Base
9
+
10
+ required :dialog_action_type
11
+ required :intent
12
+
13
+ optional :label
14
+ optional :fulfillment_state
15
+ optional :slot_to_elicit
16
+
17
+ coerce(
18
+ intent: Intent,
19
+ dialog_action_type: DialogActionType,
20
+ fulfillment_state: FulfillmentState
21
+ )
22
+
23
+ # rubocop:disable Metrics/MethodLength
24
+ def restore(conversation, opts = {})
25
+ case dialog_action_type.raw
26
+ when 'Close'
27
+ conversation.close(
28
+ fulfillment_state: opts.fetch(:fulfillment_state) { fulfillment_state },
29
+ messages: opts.fetch(:messages)
30
+ )
31
+ when 'ConfirmIntent'
32
+ conversation.confirm_intent(
33
+ intent: intent,
34
+ messages: opts.fetch(:messages)
35
+ )
36
+ when 'Delegate'
37
+ conversation.delegate
38
+ when 'ElicitIntent'
39
+ conversation.elicit_intent(
40
+ messages: opts.fetch(:messages)
41
+ )
42
+ when 'ElicitSlot'
43
+ conversation.elicit_slot(
44
+ intent: intent,
45
+ messages: opts.fetch(:messages),
46
+ slot_to_elicit: slot_to_elicit
47
+ )
48
+ else
49
+ raise ArgumentError, "invalid DialogActionType: `#{dialog_action_type.raw}`"
50
+ end
51
+ end
52
+ # rubocop:enable Metrics/MethodLength
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -4,7 +4,7 @@ module Aws
4
4
  module Lex
5
5
  class Conversation
6
6
  module Type
7
- class ConfirmationStatus
7
+ class ConfirmationState
8
8
  include Enumeration
9
9
 
10
10
  enumeration('None')
@@ -7,13 +7,13 @@ module Aws
7
7
  class Context
8
8
  include Base
9
9
 
10
- required :time_to_live
10
+ required :context_attributes
11
11
  required :name
12
- required :parameters
12
+ required :time_to_live
13
13
 
14
14
  coerce(
15
- time_to_live: TimeToLive,
16
- parameters: symbolize_hash!
15
+ context_attributes: symbolize_hash!,
16
+ time_to_live: TimeToLive
17
17
  )
18
18
  end
19
19
  end
@@ -4,14 +4,14 @@ module Aws
4
4
  module Lex
5
5
  class Conversation
6
6
  module Type
7
- class SlotDetail
7
+ class DialogAction
8
8
  include Base
9
9
 
10
- required :resolutions
11
- required :original_value
10
+ optional :slot_to_elicit
11
+ required :type
12
12
 
13
13
  coerce(
14
- resolutions: Array[SlotResolution]
14
+ type: DialogActionType
15
15
  )
16
16
  end
17
17
  end
@@ -7,11 +7,11 @@ module Aws
7
7
  class DialogActionType
8
8
  include Enumeration
9
9
 
10
- enumeration('ElicitIntent')
11
- enumeration('ElicitSlot')
10
+ enumeration('Close')
12
11
  enumeration('ConfirmIntent')
13
12
  enumeration('Delegate')
14
- enumeration('Close')
13
+ enumeration('ElicitIntent')
14
+ enumeration('ElicitSlot')
15
15
  end
16
16
  end
17
17
  end
@@ -7,36 +7,43 @@ module Aws
7
7
  class Event
8
8
  include Base
9
9
 
10
- required :active_contexts, default: -> { [] }
11
- required :alternative_intents, default: -> { [] }
12
- required :current_intent
13
10
  required :bot
14
- required :user_id
15
- required :input_transcript
11
+ required :input_mode
12
+ required :input_transcript, default: -> { '' }
13
+ required :interpretations
16
14
  required :invocation_source
17
- required :output_dialog_mode
18
15
  required :message_version
19
- required :session_attributes
20
- required :recent_intent_summary_view, default: -> { [] }
21
- optional :request_attributes
22
- optional :sentiment_response
23
- optional :kendra_response
16
+ required :request_attributes, default: -> { {} }
17
+ required :response_content_type
18
+ required :session_id
19
+ required :session_state
20
+
21
+ computed_property :current_intent, ->(instance) do
22
+ instance.session_state.intent.tap do |intent|
23
+ intent.nlu_confidence = instance.interpretations.find { |i| i.intent.name == intent.name }.nlu_confidence
24
+ end
25
+ end
24
26
 
25
27
  computed_property :intents, ->(instance) do
26
- [instance.current_intent] | instance.alternative_intents
28
+ instance.interpretations.map(&:intent).tap do |intents|
29
+ intents.map do |intent|
30
+ intent.nlu_confidence = instance.interpretations.find { |i| i.intent.name == intent.name }.nlu_confidence
31
+ end
32
+ end
33
+ end
34
+
35
+ computed_property :alternate_intents, ->(instance) do
36
+ instance.intents.reject { |intent| intent.name == instance.current_intent.name }
27
37
  end
28
38
 
29
39
  coerce(
30
- active_contexts: Array[Context],
31
- alternative_intents: Array[Intent],
32
- current_intent: Intent,
33
40
  bot: Bot,
41
+ input_mode: InputMode,
42
+ interpretations: Array[Interpretation],
34
43
  invocation_source: InvocationSource,
35
- output_dialog_mode: OutputDialogMode,
36
- session_attributes: symbolize_hash!,
37
44
  request_attributes: symbolize_hash!,
38
- recent_intent_summary_view: Array[RecentIntentSummaryView],
39
- sentiment_response: SentimentResponse
45
+ response_content_type: Message::ContentType,
46
+ session_state: SessionState
40
47
  )
41
48
  end
42
49
  end
@@ -4,10 +4,11 @@ module Aws
4
4
  module Lex
5
5
  class Conversation
6
6
  module Type
7
- class OutputDialogMode
7
+ class InputMode
8
8
  include Enumeration
9
9
 
10
- enumeration('Voice')
10
+ enumeration('DTMF')
11
+ enumeration('Speech')
11
12
  enumeration('Text')
12
13
  end
13
14
  end
@@ -7,46 +7,37 @@ module Aws
7
7
  class Intent
8
8
  include Base
9
9
 
10
+ required :confirmation_state
11
+ optional :kendra_response
10
12
  required :name
11
13
  required :raw_slots, from: :slots, virtual: true
12
- required :slot_details
13
- required :confirmation_status
14
- optional :nlu_intent_confidence_score
14
+ required :state
15
+ optional :originating_request_id
16
+ optional :nlu_confidence
15
17
 
16
18
  computed_property :slots, ->(instance) do
17
19
  # any keys indexed without a value will return an empty Slot instance
18
20
  default_hash = Hash.new do |_hash, key|
19
- Slot.new(active: false, name: key.to_sym, value: nil, current_intent: instance)
21
+ Slot.shrink_wrap(active: false, name: key.to_sym, value: nil, shape: 'Scalar')
20
22
  end
21
23
 
22
24
  instance.raw_slots.each_with_object(default_hash) do |(key, value), hash|
25
+ normalized = value&.transform_keys(&:to_sym) || { shape: 'Scalar' }
23
26
  hash[key.to_sym] = Slot.shrink_wrap(
24
27
  active: true,
25
28
  name: key,
26
- value: value,
27
- # pass a reference to the parent down to the slot so that each slot
28
- # instance can view a broader scope such as slot_details/resolutions
29
- current_intent: instance
29
+ shape: normalized[:shape],
30
+ value: normalized[:value],
31
+ values: normalized[:values]
30
32
  )
31
33
  end
32
34
  end
33
35
 
34
- class << self
35
- def slot_details!
36
- ->(val) do
37
- val
38
- .compact
39
- .each_with_object({}) do |(key, value), hash|
40
- hash[key.to_sym] = SlotDetail.shrink_wrap(value)
41
- end
42
- end
43
- end
44
- end
45
-
46
36
  coerce(
47
- slot_details: slot_details!,
48
- confirmation_status: ConfirmationStatus,
49
- nlu_intent_confidence_score: float!(nilable: true)
37
+ raw_slots: symbolize_hash!,
38
+ slots: Array[Slot],
39
+ confirmation_state: ConfirmationState,
40
+ nlu_confidence: float!(nilable: true)
50
41
  )
51
42
  end
52
43
  end
@@ -28,9 +28,9 @@ module Aws
28
28
  def candidates(threshold: standard_deviation)
29
29
  intents = event.intents.select do |intent|
30
30
  diff = event.current_intent
31
- .nlu_intent_confidence_score
31
+ .nlu_confidence
32
32
  .to_f
33
- .-(intent.nlu_intent_confidence_score.to_f)
33
+ .-(intent.nlu_confidence.to_f)
34
34
  .abs
35
35
 
36
36
  diff <= threshold
@@ -38,7 +38,7 @@ module Aws
38
38
 
39
39
  # sort descending
40
40
  intents.sort do |a, b|
41
- b.nlu_intent_confidence_score.to_f <=> a.nlu_intent_confidence_score.to_f
41
+ b.nlu_confidence.to_f <=> a.nlu_confidence.to_f
42
42
  end
43
43
  end
44
44
 
@@ -58,13 +58,13 @@ module Aws
58
58
  private
59
59
 
60
60
  def calculate_mean
61
- sum = event.intents.sum { |i| i.nlu_intent_confidence_score.to_f }
61
+ sum = event.intents.sum { |i| i.nlu_confidence.to_f }
62
62
  sum / event.intents.size
63
63
  end
64
64
 
65
65
  def calculate_standard_deviation
66
66
  normalized = event.intents.map do |intent|
67
- (intent.nlu_intent_confidence_score.to_f - mean) ** 2
67
+ (intent.nlu_confidence.to_f - mean) ** 2
68
68
  end
69
69
  normalized_mean = normalized.sum / normalized.size
70
70
  Math.sqrt(normalized_mean)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Lex
5
+ class Conversation
6
+ module Type
7
+ class Interpretation
8
+ include Base
9
+
10
+ required :intent
11
+ optional :nlu_confidence
12
+ optional :sentiment_response
13
+
14
+ coerce(
15
+ intent: Intent,
16
+ nlu_confidence: float!(nilable: true),
17
+ sentiment_response: SentimentResponse
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -7,11 +7,13 @@ module Aws
7
7
  class Message
8
8
  include Base
9
9
 
10
- optional :content_type, default: 'PlainText'
10
+ required :content_type, default: -> { 'PlainText' }
11
11
  required :content
12
+ optional :image_response_card
12
13
 
13
14
  coerce(
14
- content_type: Message::ContentType
15
+ content_type: Message::ContentType,
16
+ image_response_card: Aws::Lex::Conversation::Type::ResponseCard
15
17
  )
16
18
  end
17
19
  end