rasa-pro 3.12.0.dev10__py3-none-any.whl → 3.12.0.dev12__py3-none-any.whl
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.
Potentially problematic release.
This version of rasa-pro might be problematic. Click here for more details.
- rasa/core/actions/action.py +3 -17
- rasa/core/actions/forms.py +2 -4
- rasa/core/channels/voice_ready/audiocodes.py +23 -42
- rasa/core/channels/voice_stream/tts/azure.py +1 -2
- rasa/core/migrate.py +2 -2
- rasa/core/policies/flows/flow_executor.py +1 -33
- rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -2
- rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -62
- rasa/dialogue_understanding/commands/change_flow_command.py +2 -2
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -2
- rasa/dialogue_understanding/commands/clarify_command.py +2 -2
- rasa/dialogue_understanding/commands/correct_slots_command.py +2 -11
- rasa/dialogue_understanding/commands/human_handoff_command.py +2 -2
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -2
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -2
- rasa/dialogue_understanding/commands/set_slot_command.py +15 -7
- rasa/dialogue_understanding/commands/skip_question_command.py +2 -2
- rasa/dialogue_understanding/commands/start_flow_command.py +2 -43
- rasa/dialogue_understanding/commands/utils.py +1 -1
- rasa/dialogue_understanding/constants.py +0 -1
- rasa/dialogue_understanding/generator/command_generator.py +76 -10
- rasa/dialogue_understanding/generator/command_parser.py +1 -1
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +2 -126
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +2 -10
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -4
- rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +79 -53
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +19 -11
- rasa/dialogue_understanding/patterns/correction.py +1 -13
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +2 -62
- rasa/dialogue_understanding/processor/command_processor.py +28 -117
- rasa/dialogue_understanding/utils.py +0 -31
- rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +2 -2
- rasa/shared/core/constants.py +1 -22
- rasa/shared/core/domain.py +4 -6
- rasa/shared/core/events.py +2 -13
- rasa/shared/core/flows/flow.py +0 -17
- rasa/shared/core/flows/flows_yaml_schema.json +0 -38
- rasa/shared/core/flows/steps/collect.py +1 -18
- rasa/shared/core/flows/utils.py +1 -16
- rasa/shared/core/slot_mappings.py +6 -6
- rasa/shared/core/slots.py +0 -19
- rasa/shared/core/trackers.py +1 -3
- rasa/shared/nlu/constants.py +0 -1
- rasa/shared/utils/llm.py +1 -1
- rasa/shared/utils/schemas/domain.yml +1 -0
- rasa/validator.py +22 -172
- rasa/version.py +1 -1
- {rasa_pro-3.12.0.dev10.dist-info → rasa_pro-3.12.0.dev12.dist-info}/METADATA +1 -1
- {rasa_pro-3.12.0.dev10.dist-info → rasa_pro-3.12.0.dev12.dist-info}/RECORD +52 -55
- rasa/core/actions/action_handle_digressions.py +0 -142
- rasa/dialogue_understanding/commands/handle_digressions_command.py +0 -150
- rasa/dialogue_understanding/patterns/handle_digressions.py +0 -81
- {rasa_pro-3.12.0.dev10.dist-info → rasa_pro-3.12.0.dev12.dist-info}/NOTICE +0 -0
- {rasa_pro-3.12.0.dev10.dist-info → rasa_pro-3.12.0.dev12.dist-info}/WHEEL +0 -0
- {rasa_pro-3.12.0.dev10.dist-info → rasa_pro-3.12.0.dev12.dist-info}/entry_points.txt +0 -0
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
version: "3.1"
|
|
2
2
|
responses:
|
|
3
3
|
|
|
4
|
-
utter_ask_continue_previous_flow:
|
|
5
|
-
- text: "Confirm if you would like to continue with the initial topic: {{context.interrupted_flow_id}}?"
|
|
6
|
-
metadata:
|
|
7
|
-
rephrase: True
|
|
8
|
-
template: jinja
|
|
9
|
-
buttons:
|
|
10
|
-
- title: Continue with the previous topic.
|
|
11
|
-
payload: /SetSlots(continue_previous_flow=True)
|
|
12
|
-
- title: Switch to new topic.
|
|
13
|
-
payload: /SetSlots(continue_previous_flow=False)
|
|
14
|
-
|
|
15
4
|
utter_ask_rephrase:
|
|
16
5
|
- text: I’m sorry I am unable to understand you, could you please rephrase?
|
|
17
6
|
|
|
@@ -20,20 +9,6 @@ responses:
|
|
|
20
9
|
metadata:
|
|
21
10
|
rephrase: True
|
|
22
11
|
|
|
23
|
-
utter_block_digressions:
|
|
24
|
-
- text: "We can look into {{ context.interrupting_flow_id }} later. Let's focus on the current topic: {{ context.interrupted_flow_id }}."
|
|
25
|
-
metadata:
|
|
26
|
-
rephrase: True
|
|
27
|
-
template: jinja
|
|
28
|
-
- text: "Let's continue with the current topic: {{ context.interrupted_flow_id }}."
|
|
29
|
-
condition:
|
|
30
|
-
- type: slot
|
|
31
|
-
name: continue_previous_flow
|
|
32
|
-
value: True
|
|
33
|
-
metadata:
|
|
34
|
-
rephrase: True
|
|
35
|
-
template: jinja
|
|
36
|
-
|
|
37
12
|
utter_boolean_slot_rejection:
|
|
38
13
|
- text: "Sorry, the value you provided, `{{value}}`, is not valid. Please respond with a valid value."
|
|
39
14
|
metadata:
|
|
@@ -60,14 +35,8 @@ responses:
|
|
|
60
35
|
rephrase: True
|
|
61
36
|
template: jinja
|
|
62
37
|
|
|
63
|
-
utter_continue_interruption:
|
|
64
|
-
- text: "Let's continue with the chosen topic instead: {{ context.interrupting_flow_id }}."
|
|
65
|
-
metadata:
|
|
66
|
-
rephrase: True
|
|
67
|
-
template: jinja
|
|
68
|
-
|
|
69
38
|
utter_corrected_previous_input:
|
|
70
|
-
- text: "Ok, I am updating {{ context.corrected_slots.keys()|join(', ') }} to {{ context.
|
|
39
|
+
- text: "Ok, I am updating {{ context.corrected_slots.keys()|join(', ') }} to {{ context.corrected_slots.values()|join(', ') }} respectively."
|
|
71
40
|
metadata:
|
|
72
41
|
rephrase: True
|
|
73
42
|
template: jinja
|
|
@@ -150,10 +119,7 @@ slots:
|
|
|
150
119
|
type: float
|
|
151
120
|
initial_value: 0.0
|
|
152
121
|
max_value: 1000000
|
|
153
|
-
|
|
154
|
-
type: bool
|
|
155
|
-
mappings:
|
|
156
|
-
- type: from_llm
|
|
122
|
+
|
|
157
123
|
|
|
158
124
|
flows:
|
|
159
125
|
pattern_cancel_flow:
|
|
@@ -197,7 +163,6 @@ flows:
|
|
|
197
163
|
steps:
|
|
198
164
|
- action: action_clarify_flows
|
|
199
165
|
- action: utter_clarification_options_rasa
|
|
200
|
-
- action: action_listen
|
|
201
166
|
|
|
202
167
|
pattern_code_change:
|
|
203
168
|
description: Conversation repair flow for cleaning the stack after an assistant update
|
|
@@ -247,31 +212,6 @@ flows:
|
|
|
247
212
|
next: END
|
|
248
213
|
- else: END
|
|
249
214
|
|
|
250
|
-
pattern_handle_digressions:
|
|
251
|
-
description: Conversation repair flow for handling digressions
|
|
252
|
-
name: pattern handle digressions
|
|
253
|
-
steps:
|
|
254
|
-
- noop: true
|
|
255
|
-
id: branching
|
|
256
|
-
next:
|
|
257
|
-
- if: context.ask_confirm_digressions contains context.interrupting_flow_id
|
|
258
|
-
then: continue_previous_flow
|
|
259
|
-
- if: context.block_digressions contains context.interrupting_flow_id
|
|
260
|
-
then: block_digression
|
|
261
|
-
- else: continue_digression
|
|
262
|
-
- id: continue_previous_flow
|
|
263
|
-
collect: continue_previous_flow
|
|
264
|
-
next:
|
|
265
|
-
- if: slots.continue_previous_flow
|
|
266
|
-
then: block_digression
|
|
267
|
-
- else: continue_digression
|
|
268
|
-
- id: block_digression
|
|
269
|
-
action: action_block_digression
|
|
270
|
-
next: END
|
|
271
|
-
- id: continue_digression
|
|
272
|
-
action: action_continue_digression
|
|
273
|
-
next: END
|
|
274
|
-
|
|
275
215
|
pattern_human_handoff:
|
|
276
216
|
description: Conversation repair flow for switching users to a human agent if their request can't be handled
|
|
277
217
|
name: pattern human handoff
|
|
@@ -18,9 +18,6 @@ from rasa.dialogue_understanding.commands import (
|
|
|
18
18
|
from rasa.dialogue_understanding.commands.handle_code_change_command import (
|
|
19
19
|
HandleCodeChangeCommand,
|
|
20
20
|
)
|
|
21
|
-
from rasa.dialogue_understanding.commands.handle_digressions_command import (
|
|
22
|
-
HandleDigressionsCommand,
|
|
23
|
-
)
|
|
24
21
|
from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
|
|
25
22
|
from rasa.dialogue_understanding.patterns.chitchat import FLOW_PATTERN_CHITCHAT
|
|
26
23
|
from rasa.dialogue_understanding.patterns.collect_information import (
|
|
@@ -45,8 +42,6 @@ from rasa.shared.constants import (
|
|
|
45
42
|
from rasa.shared.core.constants import (
|
|
46
43
|
ACTION_TRIGGER_CHITCHAT,
|
|
47
44
|
FLOW_HASHES_SLOT,
|
|
48
|
-
KEY_ALLOW_NLU_CORRECTION,
|
|
49
|
-
KEY_MAPPING_TYPE,
|
|
50
45
|
SlotMappingType,
|
|
51
46
|
)
|
|
52
47
|
from rasa.shared.core.events import Event, SlotSet
|
|
@@ -400,28 +395,6 @@ def clean_up_commands(
|
|
|
400
395
|
command=command,
|
|
401
396
|
)
|
|
402
397
|
|
|
403
|
-
elif isinstance(command, StartFlowCommand) and active_flow is not None:
|
|
404
|
-
# push handle digressions command if we are at a collect step of
|
|
405
|
-
# a flow and a new flow is started
|
|
406
|
-
collect_info = get_current_collect_step(tracker.stack, all_flows)
|
|
407
|
-
current_flow = all_flows.flow_by_id(active_flow)
|
|
408
|
-
current_flow_condition = current_flow and (
|
|
409
|
-
current_flow.ask_confirm_digressions or current_flow.block_digressions
|
|
410
|
-
)
|
|
411
|
-
|
|
412
|
-
if collect_info and (
|
|
413
|
-
collect_info.ask_confirm_digressions
|
|
414
|
-
or collect_info.block_digressions
|
|
415
|
-
or current_flow_condition
|
|
416
|
-
):
|
|
417
|
-
clean_commands.append(HandleDigressionsCommand(flow=command.flow))
|
|
418
|
-
structlogger.debug(
|
|
419
|
-
"command_processor.clean_up_commands.push_handle_digressions",
|
|
420
|
-
command=command,
|
|
421
|
-
)
|
|
422
|
-
else:
|
|
423
|
-
clean_commands.append(command)
|
|
424
|
-
|
|
425
398
|
# handle chitchat command differently from other free-form answer commands
|
|
426
399
|
elif isinstance(command, ChitChatAnswerCommand):
|
|
427
400
|
clean_commands = clean_up_chitchat_command(
|
|
@@ -554,48 +527,13 @@ def clean_up_slot_command(
|
|
|
554
527
|
)
|
|
555
528
|
return resulting_commands
|
|
556
529
|
|
|
557
|
-
if not should_slot_be_set(slot, command
|
|
558
|
-
structlogger.debug(
|
|
559
|
-
"command_processor.clean_up_slot_command.skip_command.extractor_"
|
|
560
|
-
"does_not_match_slot_mapping",
|
|
561
|
-
extractor=command.extractor,
|
|
562
|
-
slot_name=slot.name,
|
|
563
|
-
)
|
|
564
|
-
|
|
565
|
-
# prevent adding a cannot handle command in case commands_so_far already
|
|
566
|
-
# contains a valid prior set slot command for the same slot whose current
|
|
567
|
-
# slot command was rejected by should_slot_be_set
|
|
568
|
-
slot_command_exists_already = any(
|
|
569
|
-
isinstance(command, SetSlotCommand) and command.name == slot.name
|
|
570
|
-
for command in resulting_commands
|
|
571
|
-
)
|
|
572
|
-
|
|
530
|
+
if not should_slot_be_set(slot, command):
|
|
573
531
|
cannot_handle = CannotHandleCommand(reason=CANNOT_HANDLE_REASON)
|
|
574
|
-
if
|
|
532
|
+
if cannot_handle not in resulting_commands:
|
|
575
533
|
resulting_commands.append(cannot_handle)
|
|
576
534
|
|
|
577
535
|
return resulting_commands
|
|
578
536
|
|
|
579
|
-
if (
|
|
580
|
-
slot.filled_by == SetSlotExtractor.NLU.value
|
|
581
|
-
and command.extractor == SetSlotExtractor.LLM.value
|
|
582
|
-
):
|
|
583
|
-
allow_nlu_correction = any(
|
|
584
|
-
[
|
|
585
|
-
mapping.get(KEY_ALLOW_NLU_CORRECTION, False)
|
|
586
|
-
for mapping in slot.mappings
|
|
587
|
-
if mapping.get(KEY_MAPPING_TYPE) == SlotMappingType.FROM_LLM.value
|
|
588
|
-
]
|
|
589
|
-
)
|
|
590
|
-
|
|
591
|
-
if not allow_nlu_correction:
|
|
592
|
-
structlogger.debug(
|
|
593
|
-
"command_processor.clean_up_slot_command"
|
|
594
|
-
".skip_command.disallow_llm_correction_of_nlu_set_value",
|
|
595
|
-
command=command,
|
|
596
|
-
)
|
|
597
|
-
return resulting_commands
|
|
598
|
-
|
|
599
537
|
if command.name in slots_so_far and command.name != ROUTE_TO_CALM_SLOT:
|
|
600
538
|
current_collect_info = get_current_collect_step(stack, all_flows)
|
|
601
539
|
|
|
@@ -636,7 +574,7 @@ def clean_up_slot_command(
|
|
|
636
574
|
)
|
|
637
575
|
|
|
638
576
|
# Group all corrections into one command
|
|
639
|
-
corrected_slot = CorrectedSlot(command.name, command.value
|
|
577
|
+
corrected_slot = CorrectedSlot(command.name, command.value)
|
|
640
578
|
for c in resulting_commands:
|
|
641
579
|
if isinstance(c, CorrectSlotsCommand):
|
|
642
580
|
c.corrected_slots.append(corrected_slot)
|
|
@@ -720,9 +658,7 @@ def clean_up_chitchat_command(
|
|
|
720
658
|
return resulting_commands
|
|
721
659
|
|
|
722
660
|
|
|
723
|
-
def should_slot_be_set(
|
|
724
|
-
slot: Slot, command: SetSlotCommand, commands_so_far: Optional[List[Command]] = None
|
|
725
|
-
) -> bool:
|
|
661
|
+
def should_slot_be_set(slot: Slot, command: SetSlotCommand) -> bool:
|
|
726
662
|
"""Check if a slot should be set by a command."""
|
|
727
663
|
if command.extractor == SetSlotExtractor.COMMAND_PAYLOAD_READER.value:
|
|
728
664
|
# if the command is issued by the command payload reader, it means the slot
|
|
@@ -730,62 +666,37 @@ def should_slot_be_set(
|
|
|
730
666
|
# we can always set it
|
|
731
667
|
return True
|
|
732
668
|
|
|
733
|
-
if commands_so_far is None:
|
|
734
|
-
commands_so_far = []
|
|
735
|
-
|
|
736
|
-
set_slot_commands_so_far = [
|
|
737
|
-
command
|
|
738
|
-
for command in commands_so_far
|
|
739
|
-
if isinstance(command, SetSlotCommand) and command.name == slot.name
|
|
740
|
-
]
|
|
741
|
-
|
|
742
669
|
slot_mappings = slot.mappings
|
|
743
670
|
|
|
744
|
-
if not
|
|
745
|
-
slot_mappings = [{
|
|
746
|
-
|
|
747
|
-
mapping_types = [
|
|
748
|
-
SlotMappingType(mapping.get(KEY_MAPPING_TYPE, SlotMappingType.FROM_LLM.value))
|
|
749
|
-
for mapping in slot_mappings
|
|
750
|
-
]
|
|
751
|
-
|
|
752
|
-
slot_has_nlu_mapping = any(
|
|
753
|
-
[mapping_type.is_predefined_type() for mapping_type in mapping_types]
|
|
754
|
-
)
|
|
755
|
-
slot_has_llm_mapping = any(
|
|
756
|
-
[mapping_type == SlotMappingType.FROM_LLM for mapping_type in mapping_types]
|
|
757
|
-
)
|
|
758
|
-
slot_has_custom_mapping = any(
|
|
759
|
-
[mapping_type == SlotMappingType.CUSTOM for mapping_type in mapping_types]
|
|
760
|
-
)
|
|
671
|
+
if not slot_mappings:
|
|
672
|
+
slot_mappings = [{"type": SlotMappingType.FROM_LLM.value}]
|
|
761
673
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
# scenario 2: NLU mapping is unable to extract a value for slot_a → If LLM extracts a value for slot_a, it is accepted. # noqa: E501
|
|
766
|
-
command_has_nlu_extractor = any(
|
|
767
|
-
[
|
|
768
|
-
command.extractor == SetSlotExtractor.NLU.value
|
|
769
|
-
for command in set_slot_commands_so_far
|
|
770
|
-
]
|
|
674
|
+
for mapping in slot_mappings:
|
|
675
|
+
mapping_type = SlotMappingType(
|
|
676
|
+
mapping.get("type", SlotMappingType.FROM_LLM.value)
|
|
771
677
|
)
|
|
772
|
-
return not command_has_nlu_extractor and slot_has_llm_mapping
|
|
773
678
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
679
|
+
should_be_set_by_llm = (
|
|
680
|
+
command.extractor == SetSlotExtractor.LLM.value
|
|
681
|
+
and mapping_type == SlotMappingType.FROM_LLM
|
|
682
|
+
)
|
|
683
|
+
should_be_set_by_nlu = (
|
|
684
|
+
command.extractor == SetSlotExtractor.NLU.value
|
|
685
|
+
and mapping_type.is_predefined_type()
|
|
686
|
+
)
|
|
780
687
|
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
):
|
|
786
|
-
return False
|
|
688
|
+
if should_be_set_by_llm or should_be_set_by_nlu:
|
|
689
|
+
# if the extractor matches the mapping type, we can continue
|
|
690
|
+
# setting the slot
|
|
691
|
+
break
|
|
787
692
|
|
|
788
|
-
|
|
693
|
+
structlogger.debug(
|
|
694
|
+
"command_processor.clean_up_slot_command.skip_command.extractor_"
|
|
695
|
+
"does_not_match_slot_mapping",
|
|
696
|
+
extractor=command.extractor,
|
|
697
|
+
slot_name=slot.name,
|
|
698
|
+
mapping_type=mapping_type.value,
|
|
699
|
+
)
|
|
789
700
|
return False
|
|
790
701
|
|
|
791
702
|
return True
|
|
@@ -5,10 +5,7 @@ from rasa.dialogue_understanding.commands import Command
|
|
|
5
5
|
from rasa.dialogue_understanding.constants import (
|
|
6
6
|
RASA_RECORD_COMMANDS_AND_PROMPTS_ENV_VAR_NAME,
|
|
7
7
|
)
|
|
8
|
-
from rasa.shared.constants import ROUTE_TO_CALM_SLOT
|
|
9
|
-
from rasa.shared.core.trackers import DialogueStateTracker
|
|
10
8
|
from rasa.shared.nlu.constants import (
|
|
11
|
-
COMMANDS,
|
|
12
9
|
KEY_COMPONENT_NAME,
|
|
13
10
|
KEY_LLM_RESPONSE_METADATA,
|
|
14
11
|
KEY_PROMPT_NAME,
|
|
@@ -16,7 +13,6 @@ from rasa.shared.nlu.constants import (
|
|
|
16
13
|
KEY_USER_PROMPT,
|
|
17
14
|
PREDICTED_COMMANDS,
|
|
18
15
|
PROMPTS,
|
|
19
|
-
SET_SLOT_COMMAND,
|
|
20
16
|
)
|
|
21
17
|
from rasa.shared.nlu.training_data.message import Message
|
|
22
18
|
from rasa.shared.providers.llm.llm_response import LLMResponse
|
|
@@ -135,30 +131,3 @@ def add_prompt_to_message_parse_data(
|
|
|
135
131
|
|
|
136
132
|
# Update the message with the new prompts list.
|
|
137
133
|
message.set(PROMPTS, prompts, add_to_output=True)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
def _handle_via_nlu_in_coexistence(
|
|
141
|
-
tracker: Optional[DialogueStateTracker], message: Message
|
|
142
|
-
) -> bool:
|
|
143
|
-
"""Check if the message should be handled by the NLU subsystem in coexistence mode.""" # noqa: E501
|
|
144
|
-
if not tracker:
|
|
145
|
-
return False
|
|
146
|
-
|
|
147
|
-
if not tracker.has_coexistence_routing_slot:
|
|
148
|
-
return False
|
|
149
|
-
|
|
150
|
-
value = tracker.get_slot(ROUTE_TO_CALM_SLOT)
|
|
151
|
-
if value is not None:
|
|
152
|
-
return not value
|
|
153
|
-
|
|
154
|
-
# routing slot has been reset so we need to check
|
|
155
|
-
# the command issued by the Router component
|
|
156
|
-
if message.get(COMMANDS):
|
|
157
|
-
for command in message.get(COMMANDS):
|
|
158
|
-
if (
|
|
159
|
-
command.get("command") == SET_SLOT_COMMAND
|
|
160
|
-
and command.get("name") == ROUTE_TO_CALM_SLOT
|
|
161
|
-
):
|
|
162
|
-
return not command.get("value")
|
|
163
|
-
|
|
164
|
-
return False
|
|
@@ -20,7 +20,7 @@ from rasa.dialogue_understanding_test.test_case_simulation.exception import (
|
|
|
20
20
|
)
|
|
21
21
|
from rasa.dialogue_understanding_test.utils import filter_metadata
|
|
22
22
|
from rasa.e2e_test.e2e_test_case import Fixture, Metadata
|
|
23
|
-
from rasa.shared.core.constants import
|
|
23
|
+
from rasa.shared.core.constants import MAPPING_TYPE, SlotMappingType
|
|
24
24
|
from rasa.shared.core.events import BotUttered, SlotSet, UserUttered
|
|
25
25
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
26
26
|
from rasa.shared.nlu.constants import COMMANDS, ENTITIES, INTENT
|
|
@@ -329,7 +329,7 @@ class TestCaseTrackerSimulator:
|
|
|
329
329
|
# Use the SetSlotExtractor.NLU extractor if the slot mapping type is
|
|
330
330
|
# not FROM_LLM.
|
|
331
331
|
elif SlotMappingType.FROM_LLM.value not in [
|
|
332
|
-
mapping[
|
|
332
|
+
mapping[MAPPING_TYPE] for mapping in slot_definition.mappings
|
|
333
333
|
]:
|
|
334
334
|
command.extractor = SetSlotExtractor.NLU.value
|
|
335
335
|
|
rasa/shared/core/constants.py
CHANGED
|
@@ -51,8 +51,6 @@ ACTION_TRIGGER_CHITCHAT = "action_trigger_chitchat"
|
|
|
51
51
|
ACTION_RESET_ROUTING = "action_reset_routing"
|
|
52
52
|
ACTION_HANGUP = "action_hangup"
|
|
53
53
|
ACTION_REPEAT_BOT_MESSAGES = "action_repeat_bot_messages"
|
|
54
|
-
ACTION_BLOCK_DIGRESSION = "action_block_digression"
|
|
55
|
-
ACTION_CONTINUE_DIGRESSION = "action_continue_digression"
|
|
56
54
|
|
|
57
55
|
ACTION_METADATA_EXECUTION_SUCCESS = "execution_success"
|
|
58
56
|
ACTION_METADATA_EXECUTION_ERROR_MESSAGE = "execution_error_message"
|
|
@@ -83,8 +81,6 @@ DEFAULT_ACTION_NAMES = [
|
|
|
83
81
|
ACTION_RESET_ROUTING,
|
|
84
82
|
ACTION_HANGUP,
|
|
85
83
|
ACTION_REPEAT_BOT_MESSAGES,
|
|
86
|
-
ACTION_BLOCK_DIGRESSION,
|
|
87
|
-
ACTION_CONTINUE_DIGRESSION,
|
|
88
84
|
]
|
|
89
85
|
|
|
90
86
|
ACTION_SHOULD_SEND_DOMAIN = "send_domain"
|
|
@@ -141,8 +137,7 @@ DEFAULT_SLOT_NAMES = {
|
|
|
141
137
|
|
|
142
138
|
SLOT_MAPPINGS = "mappings"
|
|
143
139
|
MAPPING_CONDITIONS = "conditions"
|
|
144
|
-
|
|
145
|
-
KEY_ALLOW_NLU_CORRECTION = "allow_nlu_correction"
|
|
140
|
+
MAPPING_TYPE = "type"
|
|
146
141
|
|
|
147
142
|
|
|
148
143
|
class SlotMappingType(Enum):
|
|
@@ -164,18 +159,6 @@ class SlotMappingType(Enum):
|
|
|
164
159
|
return not (self == SlotMappingType.CUSTOM or self == SlotMappingType.FROM_LLM)
|
|
165
160
|
|
|
166
161
|
|
|
167
|
-
class SetSlotExtractor(Enum):
|
|
168
|
-
"""The extractors that can set a slot."""
|
|
169
|
-
|
|
170
|
-
LLM = "LLM"
|
|
171
|
-
COMMAND_PAYLOAD_READER = "CommandPayloadReader"
|
|
172
|
-
NLU = "NLU"
|
|
173
|
-
CUSTOM = "CUSTOM"
|
|
174
|
-
|
|
175
|
-
def __str__(self) -> str:
|
|
176
|
-
return self.value
|
|
177
|
-
|
|
178
|
-
|
|
179
162
|
# the keys for `State` (USER, PREVIOUS_ACTION, SLOTS, ACTIVE_LOOP)
|
|
180
163
|
# represent the origin of a `SubState`
|
|
181
164
|
USER = "user"
|
|
@@ -198,7 +181,3 @@ POLICY_NAME_RULE = "RulePolicy"
|
|
|
198
181
|
CLASSIFIER_NAME_FALLBACK = "FallbackClassifier"
|
|
199
182
|
|
|
200
183
|
POLICIES_THAT_EXTRACT_ENTITIES = {"TEDPolicy"}
|
|
201
|
-
|
|
202
|
-
# digression constants
|
|
203
|
-
KEY_ASK_CONFIRM_DIGRESSIONS = "ask_confirm_digressions"
|
|
204
|
-
KEY_BLOCK_DIGRESSIONS = "block_digressions"
|
rasa/shared/core/domain.py
CHANGED
|
@@ -47,9 +47,9 @@ from rasa.shared.constants import (
|
|
|
47
47
|
from rasa.shared.core.constants import (
|
|
48
48
|
ACTION_SHOULD_SEND_DOMAIN,
|
|
49
49
|
ACTIVE_LOOP,
|
|
50
|
-
KEY_MAPPING_TYPE,
|
|
51
50
|
KNOWLEDGE_BASE_SLOT_NAMES,
|
|
52
51
|
MAPPING_CONDITIONS,
|
|
52
|
+
MAPPING_TYPE,
|
|
53
53
|
SLOT_MAPPINGS,
|
|
54
54
|
SlotMappingType,
|
|
55
55
|
)
|
|
@@ -596,7 +596,7 @@ class Domain:
|
|
|
596
596
|
),
|
|
597
597
|
)
|
|
598
598
|
slot_dict[slot_name][SLOT_MAPPINGS] = [
|
|
599
|
-
{
|
|
599
|
+
{MAPPING_TYPE: SlotMappingType.FROM_LLM.value}
|
|
600
600
|
]
|
|
601
601
|
|
|
602
602
|
slot = slot_class(slot_name, **slot_dict[slot_name])
|
|
@@ -1570,9 +1570,7 @@ class Domain:
|
|
|
1570
1570
|
|
|
1571
1571
|
for mapping in slot.mappings:
|
|
1572
1572
|
mapping_conditions = mapping.get(MAPPING_CONDITIONS)
|
|
1573
|
-
if mapping[
|
|
1574
|
-
SlotMappingType.FROM_ENTITY
|
|
1575
|
-
) or (
|
|
1573
|
+
if mapping[MAPPING_TYPE] != str(SlotMappingType.FROM_ENTITY) or (
|
|
1576
1574
|
mapping_conditions
|
|
1577
1575
|
and mapping_conditions[0].get(ACTIVE_LOOP) is not None
|
|
1578
1576
|
):
|
|
@@ -2023,7 +2021,7 @@ class Domain:
|
|
|
2023
2021
|
for slot in self.slots:
|
|
2024
2022
|
total_mappings += len(slot.mappings)
|
|
2025
2023
|
for mapping in slot.mappings:
|
|
2026
|
-
if mapping[
|
|
2024
|
+
if mapping[MAPPING_TYPE] == str(SlotMappingType.CUSTOM):
|
|
2027
2025
|
custom_mappings += 1
|
|
2028
2026
|
|
|
2029
2027
|
if MAPPING_CONDITIONS in mapping:
|
rasa/shared/core/events.py
CHANGED
|
@@ -1032,7 +1032,6 @@ class SlotSet(Event):
|
|
|
1032
1032
|
value: Optional[Any] = None,
|
|
1033
1033
|
timestamp: Optional[float] = None,
|
|
1034
1034
|
metadata: Optional[Dict[Text, Any]] = None,
|
|
1035
|
-
filled_by: Optional[str] = None,
|
|
1036
1035
|
) -> None:
|
|
1037
1036
|
"""Creates event to set slot.
|
|
1038
1037
|
|
|
@@ -1044,7 +1043,6 @@ class SlotSet(Event):
|
|
|
1044
1043
|
"""
|
|
1045
1044
|
self.key = key
|
|
1046
1045
|
self.value = value
|
|
1047
|
-
self._filled_by = filled_by
|
|
1048
1046
|
super().__init__(timestamp, metadata)
|
|
1049
1047
|
|
|
1050
1048
|
def __repr__(self) -> Text:
|
|
@@ -1062,14 +1060,6 @@ class SlotSet(Event):
|
|
|
1062
1060
|
|
|
1063
1061
|
return (self.key, self.value) == (other.key, other.value)
|
|
1064
1062
|
|
|
1065
|
-
@property
|
|
1066
|
-
def filled_by(self) -> Optional[str]:
|
|
1067
|
-
return self._filled_by
|
|
1068
|
-
|
|
1069
|
-
@filled_by.setter
|
|
1070
|
-
def filled_by(self, value: str) -> None:
|
|
1071
|
-
self._filled_by = value
|
|
1072
|
-
|
|
1073
1063
|
def as_story_string(self) -> Text:
|
|
1074
1064
|
"""Returns text representation of event."""
|
|
1075
1065
|
props = json.dumps({self.key: self.value}, ensure_ascii=False)
|
|
@@ -1091,7 +1081,7 @@ class SlotSet(Event):
|
|
|
1091
1081
|
def as_dict(self) -> Dict[Text, Any]:
|
|
1092
1082
|
"""Returns serialized event."""
|
|
1093
1083
|
d = super().as_dict()
|
|
1094
|
-
d.update({"name": self.key, "value": self.value
|
|
1084
|
+
d.update({"name": self.key, "value": self.value})
|
|
1095
1085
|
return d
|
|
1096
1086
|
|
|
1097
1087
|
@classmethod
|
|
@@ -1102,14 +1092,13 @@ class SlotSet(Event):
|
|
|
1102
1092
|
parameters.get("value"),
|
|
1103
1093
|
parameters.get("timestamp"),
|
|
1104
1094
|
parameters.get("metadata"),
|
|
1105
|
-
filled_by=parameters.get("filled_by"),
|
|
1106
1095
|
)
|
|
1107
1096
|
except KeyError as e:
|
|
1108
1097
|
raise ValueError(f"Failed to parse set slot event. {e}")
|
|
1109
1098
|
|
|
1110
1099
|
def apply_to(self, tracker: "DialogueStateTracker") -> None:
|
|
1111
1100
|
"""Applies event to current conversation state."""
|
|
1112
|
-
tracker._set_slot(self.key, self.value
|
|
1101
|
+
tracker._set_slot(self.key, self.value)
|
|
1113
1102
|
|
|
1114
1103
|
|
|
1115
1104
|
class Restarted(AlwaysEqualEventMixin):
|
rasa/shared/core/flows/flow.py
CHANGED
|
@@ -11,10 +11,6 @@ from pypred import Predicate
|
|
|
11
11
|
|
|
12
12
|
import rasa.shared.utils.io
|
|
13
13
|
from rasa.shared.constants import RASA_DEFAULT_FLOW_PATTERN_PREFIX
|
|
14
|
-
from rasa.shared.core.constants import (
|
|
15
|
-
KEY_ASK_CONFIRM_DIGRESSIONS,
|
|
16
|
-
KEY_BLOCK_DIGRESSIONS,
|
|
17
|
-
)
|
|
18
14
|
from rasa.shared.core.flows.flow_path import FlowPath, FlowPathsList, PathNode
|
|
19
15
|
from rasa.shared.core.flows.flow_step import FlowStep
|
|
20
16
|
from rasa.shared.core.flows.flow_step_links import (
|
|
@@ -37,7 +33,6 @@ from rasa.shared.core.flows.steps.constants import (
|
|
|
37
33
|
START_STEP,
|
|
38
34
|
)
|
|
39
35
|
from rasa.shared.core.flows.steps.continuation import ContinueFlowStep
|
|
40
|
-
from rasa.shared.core.flows.utils import extract_digression_prop
|
|
41
36
|
from rasa.shared.core.slots import Slot
|
|
42
37
|
|
|
43
38
|
structlogger = structlog.get_logger()
|
|
@@ -67,10 +62,6 @@ class Flow:
|
|
|
67
62
|
"""The path to the file where the flow is stored."""
|
|
68
63
|
persisted_slots: List[str] = field(default_factory=list)
|
|
69
64
|
"""The list of slots that should be persisted after the flow ends."""
|
|
70
|
-
ask_confirm_digressions: List[str] = field(default_factory=list)
|
|
71
|
-
"""The flow ids for which the assistant should ask for confirmation."""
|
|
72
|
-
block_digressions: List[str] = field(default_factory=list)
|
|
73
|
-
"""The flow ids that the assistant should block from digressing to."""
|
|
74
65
|
|
|
75
66
|
@staticmethod
|
|
76
67
|
def from_json(
|
|
@@ -107,10 +98,6 @@ class Flow:
|
|
|
107
98
|
# data. When the model is trained, take the provided file_path.
|
|
108
99
|
file_path=data.get("file_path") if "file_path" in data else file_path,
|
|
109
100
|
persisted_slots=data.get("persisted_slots", []),
|
|
110
|
-
ask_confirm_digressions=extract_digression_prop(
|
|
111
|
-
KEY_ASK_CONFIRM_DIGRESSIONS, data
|
|
112
|
-
),
|
|
113
|
-
block_digressions=extract_digression_prop(KEY_BLOCK_DIGRESSIONS, data),
|
|
114
101
|
)
|
|
115
102
|
|
|
116
103
|
def get_full_name(self) -> str:
|
|
@@ -185,10 +172,6 @@ class Flow:
|
|
|
185
172
|
data["file_path"] = self.file_path
|
|
186
173
|
if self.persisted_slots:
|
|
187
174
|
data["persisted_slots"] = self.persisted_slots
|
|
188
|
-
if self.ask_confirm_digressions:
|
|
189
|
-
data[KEY_ASK_CONFIRM_DIGRESSIONS] = self.ask_confirm_digressions
|
|
190
|
-
if self.block_digressions:
|
|
191
|
-
data[KEY_BLOCK_DIGRESSIONS] = self.block_digressions
|
|
192
175
|
|
|
193
176
|
return data
|
|
194
177
|
|
|
@@ -217,12 +217,6 @@
|
|
|
217
217
|
"reset_after_flow_ends": {
|
|
218
218
|
"type": "boolean"
|
|
219
219
|
},
|
|
220
|
-
"ask_confirm_digressions": {
|
|
221
|
-
"$ref": "#/$defs/ask_confirm_digressions"
|
|
222
|
-
},
|
|
223
|
-
"block_digressions": {
|
|
224
|
-
"$ref": "#/$defs/block_digressions"
|
|
225
|
-
},
|
|
226
220
|
"utter": {
|
|
227
221
|
"type": "string"
|
|
228
222
|
},
|
|
@@ -253,32 +247,6 @@
|
|
|
253
247
|
}
|
|
254
248
|
}
|
|
255
249
|
},
|
|
256
|
-
"ask_confirm_digressions": {
|
|
257
|
-
"oneOf": [
|
|
258
|
-
{
|
|
259
|
-
"type": "boolean"
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
"type": "array",
|
|
263
|
-
"items": {
|
|
264
|
-
"type": "string"
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
]
|
|
268
|
-
},
|
|
269
|
-
"block_digressions": {
|
|
270
|
-
"oneOf": [
|
|
271
|
-
{
|
|
272
|
-
"type": "boolean"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
"type": "array",
|
|
276
|
-
"items": {
|
|
277
|
-
"type": "string"
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
]
|
|
281
|
-
},
|
|
282
250
|
"flow": {
|
|
283
251
|
"required": [
|
|
284
252
|
"steps",
|
|
@@ -314,12 +282,6 @@
|
|
|
314
282
|
},
|
|
315
283
|
"persisted_slots": {
|
|
316
284
|
"$ref": "#/$defs/persisted_slots"
|
|
317
|
-
},
|
|
318
|
-
"ask_confirm_digressions": {
|
|
319
|
-
"$ref": "#/$defs/ask_confirm_digressions"
|
|
320
|
-
},
|
|
321
|
-
"block_digressions": {
|
|
322
|
-
"$ref": "#/$defs/block_digressions"
|
|
323
285
|
}
|
|
324
286
|
}
|
|
325
287
|
},
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass
|
|
3
|
+
from dataclasses import dataclass
|
|
4
4
|
from typing import Any, Dict, List, Set, Text
|
|
5
5
|
|
|
6
6
|
from rasa.shared.constants import ACTION_ASK_PREFIX, UTTER_ASK_PREFIX
|
|
7
|
-
from rasa.shared.core.constants import (
|
|
8
|
-
KEY_ASK_CONFIRM_DIGRESSIONS,
|
|
9
|
-
KEY_BLOCK_DIGRESSIONS,
|
|
10
|
-
)
|
|
11
7
|
from rasa.shared.core.flows.flow_step import FlowStep
|
|
12
|
-
from rasa.shared.core.flows.utils import extract_digression_prop
|
|
13
8
|
|
|
14
9
|
|
|
15
10
|
@dataclass
|
|
@@ -64,10 +59,6 @@ class CollectInformationFlowStep(FlowStep):
|
|
|
64
59
|
"""Whether to always ask the question even if the slot is already filled."""
|
|
65
60
|
reset_after_flow_ends: bool = True
|
|
66
61
|
"""Whether to reset the slot value at the end of the flow."""
|
|
67
|
-
ask_confirm_digressions: List[str] = field(default_factory=list)
|
|
68
|
-
"""The flow id digressions for which the assistant should ask for confirmation."""
|
|
69
|
-
block_digressions: List[str] = field(default_factory=list)
|
|
70
|
-
"""The flow id digressions that should be blocked during the flow step."""
|
|
71
62
|
|
|
72
63
|
@classmethod
|
|
73
64
|
def from_json(
|
|
@@ -95,10 +86,6 @@ class CollectInformationFlowStep(FlowStep):
|
|
|
95
86
|
SlotRejection.from_dict(rejection)
|
|
96
87
|
for rejection in data.get("rejections", [])
|
|
97
88
|
],
|
|
98
|
-
ask_confirm_digressions=extract_digression_prop(
|
|
99
|
-
KEY_ASK_CONFIRM_DIGRESSIONS, data
|
|
100
|
-
),
|
|
101
|
-
block_digressions=extract_digression_prop(KEY_BLOCK_DIGRESSIONS, data),
|
|
102
89
|
**base.__dict__,
|
|
103
90
|
)
|
|
104
91
|
|
|
@@ -114,10 +101,6 @@ class CollectInformationFlowStep(FlowStep):
|
|
|
114
101
|
data["ask_before_filling"] = self.ask_before_filling
|
|
115
102
|
data["reset_after_flow_ends"] = self.reset_after_flow_ends
|
|
116
103
|
data["rejections"] = [rejection.as_dict() for rejection in self.rejections]
|
|
117
|
-
data["ask_confirm_digressions"] = self.ask_confirm_digressions
|
|
118
|
-
data["block_digressions"] = (
|
|
119
|
-
self.block_digressions if self.block_digressions else False
|
|
120
|
-
)
|
|
121
104
|
|
|
122
105
|
return data
|
|
123
106
|
|