rasa-pro 3.12.4__py3-none-any.whl → 3.12.6__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.

Files changed (49) hide show
  1. rasa/core/actions/action.py +0 -6
  2. rasa/core/channels/voice_ready/audiocodes.py +52 -17
  3. rasa/core/channels/voice_stream/audiocodes.py +53 -9
  4. rasa/core/channels/voice_stream/genesys.py +146 -16
  5. rasa/core/policies/flows/flow_executor.py +3 -38
  6. rasa/core/policies/intentless_policy.py +6 -59
  7. rasa/core/processor.py +19 -5
  8. rasa/core/utils.py +53 -0
  9. rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -59
  10. rasa/dialogue_understanding/commands/start_flow_command.py +0 -41
  11. rasa/dialogue_understanding/generator/_jinja_filters.py +9 -0
  12. rasa/dialogue_understanding/generator/command_generator.py +67 -0
  13. rasa/dialogue_understanding/generator/constants.py +4 -0
  14. rasa/dialogue_understanding/generator/llm_based_command_generator.py +22 -16
  15. rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -1
  16. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +2 -2
  17. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +2 -2
  18. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +0 -61
  19. rasa/dialogue_understanding/processor/command_processor.py +27 -70
  20. rasa/dialogue_understanding/processor/command_processor_component.py +5 -2
  21. rasa/dialogue_understanding/stack/utils.py +0 -38
  22. rasa/e2e_test/llm_judge_prompts/answer_relevance_prompt_template.jinja2 +1 -1
  23. rasa/engine/validation.py +36 -1
  24. rasa/model_training.py +2 -1
  25. rasa/shared/constants.py +2 -0
  26. rasa/shared/core/constants.py +0 -8
  27. rasa/shared/core/domain.py +12 -3
  28. rasa/shared/core/flows/flow.py +0 -17
  29. rasa/shared/core/flows/flows_yaml_schema.json +3 -38
  30. rasa/shared/core/flows/steps/collect.py +5 -18
  31. rasa/shared/core/flows/utils.py +1 -16
  32. rasa/shared/core/policies/__init__.py +0 -0
  33. rasa/shared/core/policies/utils.py +87 -0
  34. rasa/shared/core/slot_mappings.py +23 -5
  35. rasa/shared/nlu/constants.py +0 -1
  36. rasa/shared/utils/common.py +11 -1
  37. rasa/tracing/instrumentation/attribute_extractors.py +2 -0
  38. rasa/validator.py +1 -123
  39. rasa/version.py +1 -1
  40. {rasa_pro-3.12.4.dist-info → rasa_pro-3.12.6.dist-info}/METADATA +4 -5
  41. {rasa_pro-3.12.4.dist-info → rasa_pro-3.12.6.dist-info}/RECORD +44 -46
  42. {rasa_pro-3.12.4.dist-info → rasa_pro-3.12.6.dist-info}/WHEEL +1 -1
  43. README.md +0 -38
  44. rasa/core/actions/action_handle_digressions.py +0 -164
  45. rasa/dialogue_understanding/commands/handle_digressions_command.py +0 -144
  46. rasa/dialogue_understanding/patterns/handle_digressions.py +0 -81
  47. rasa/keys +0 -1
  48. {rasa_pro-3.12.4.dist-info → rasa_pro-3.12.6.dist-info}/NOTICE +0 -0
  49. {rasa_pro-3.12.4.dist-info → rasa_pro-3.12.6.dist-info}/entry_points.txt +0 -0
@@ -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.commands.utils import (
26
23
  create_validate_frames_from_slot_set_events,
@@ -54,9 +51,11 @@ from rasa.shared.core.constants import (
54
51
  FLOW_HASHES_SLOT,
55
52
  SlotMappingType,
56
53
  )
54
+ from rasa.shared.core.domain import Domain
57
55
  from rasa.shared.core.events import Event, SlotSet
58
56
  from rasa.shared.core.flows import FlowsList
59
57
  from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
58
+ from rasa.shared.core.policies.utils import contains_intentless_policy_responses
60
59
  from rasa.shared.core.slot_mappings import SlotMapping
61
60
  from rasa.shared.core.slots import Slot
62
61
  from rasa.shared.core.trackers import DialogueStateTracker
@@ -197,6 +196,7 @@ def execute_commands(
197
196
  all_flows: FlowsList,
198
197
  execution_context: ExecutionContext,
199
198
  story_graph: Optional[StoryGraph] = None,
199
+ domain: Optional[Domain] = None,
200
200
  ) -> List[Event]:
201
201
  """Executes a list of commands.
202
202
 
@@ -206,6 +206,7 @@ def execute_commands(
206
206
  all_flows: All flows.
207
207
  execution_context: Information about the single graph run.
208
208
  story_graph: StoryGraph object with stories available for training.
209
+ domain: The domain of the bot.
209
210
 
210
211
  Returns:
211
212
  A list of the events that were created.
@@ -214,7 +215,7 @@ def execute_commands(
214
215
  original_tracker = tracker.copy()
215
216
 
216
217
  commands = clean_up_commands(
217
- commands, tracker, all_flows, execution_context, story_graph
218
+ commands, tracker, all_flows, execution_context, story_graph, domain
218
219
  )
219
220
 
220
221
  updated_flows = find_updated_flows(tracker, all_flows)
@@ -381,6 +382,7 @@ def clean_up_commands(
381
382
  all_flows: FlowsList,
382
383
  execution_context: ExecutionContext,
383
384
  story_graph: Optional[StoryGraph] = None,
385
+ domain: Optional[Domain] = None,
384
386
  ) -> List[Command]:
385
387
  """Clean up a list of commands.
386
388
 
@@ -396,10 +398,13 @@ def clean_up_commands(
396
398
  all_flows: All flows.
397
399
  execution_context: Information about a single graph run.
398
400
  story_graph: StoryGraph object with stories available for training.
401
+ domain: The domain of the bot.
399
402
 
400
403
  Returns:
401
404
  The cleaned up commands.
402
405
  """
406
+ domain = domain if domain else Domain.empty()
407
+
403
408
  slots_so_far, active_flow = filled_slots_for_active_flow(tracker, all_flows)
404
409
 
405
410
  clean_commands: List[Command] = []
@@ -446,26 +451,17 @@ def clean_up_commands(
446
451
  )
447
452
  continue
448
453
 
449
- if should_add_handle_digressions_command(tracker, all_flows, top_flow_id):
450
- handle_digression_command = HandleDigressionsCommand(flow=command.flow)
451
- if handle_digression_command in clean_commands:
452
- structlogger.debug(
453
- "command_processor.clean_up_commands.skip_handle_digressions.command_already_present",
454
- command=handle_digression_command,
455
- )
456
- continue
457
- clean_commands.append(handle_digression_command)
458
- structlogger.debug(
459
- "command_processor.clean_up_commands.push_handle_digressions",
460
- command=command,
461
- )
462
- else:
463
- clean_commands.append(command)
454
+ clean_commands.append(command)
464
455
 
465
456
  # handle chitchat command differently from other free-form answer commands
466
457
  elif isinstance(command, ChitChatAnswerCommand):
467
458
  clean_commands = clean_up_chitchat_command(
468
- clean_commands, command, all_flows, execution_context, story_graph
459
+ clean_commands,
460
+ command,
461
+ all_flows,
462
+ execution_context,
463
+ domain,
464
+ story_graph,
469
465
  )
470
466
 
471
467
  elif isinstance(command, FreeFormAnswerCommand):
@@ -490,21 +486,9 @@ def clean_up_commands(
490
486
  # when coexistence is enabled, by default there will be a SetSlotCommand
491
487
  # for the ROUTE_TO_CALM_SLOT slot.
492
488
  if tracker.has_coexistence_routing_slot and len(clean_commands) > 2:
493
- clean_commands = filter_cannot_handle_command_for_skipped_slots(clean_commands)
489
+ clean_commands = filter_cannot_handle_command(clean_commands)
494
490
  elif not tracker.has_coexistence_routing_slot and len(clean_commands) > 1:
495
- clean_commands = filter_cannot_handle_command_for_skipped_slots(clean_commands)
496
-
497
- # remove cancel flow when there is a handle digression command
498
- # otherwise the cancel command will cancel the active flow which defined a specific
499
- # behavior for the digression
500
- if contains_command(clean_commands, HandleDigressionsCommand) and contains_command(
501
- clean_commands, CancelFlowCommand
502
- ):
503
- clean_commands = [
504
- command
505
- for command in clean_commands
506
- if not isinstance(command, CancelFlowCommand)
507
- ]
491
+ clean_commands = filter_cannot_handle_command(clean_commands)
508
492
 
509
493
  clean_commands = ensure_max_number_of_command_type(
510
494
  clean_commands, RepeatBotMessagesCommand, 1
@@ -708,6 +692,7 @@ def clean_up_chitchat_command(
708
692
  command: ChitChatAnswerCommand,
709
693
  flows: FlowsList,
710
694
  execution_context: ExecutionContext,
695
+ domain: Domain,
711
696
  story_graph: Optional[StoryGraph] = None,
712
697
  ) -> List[Command]:
713
698
  """Clean up a chitchat answer command.
@@ -721,6 +706,8 @@ def clean_up_chitchat_command(
721
706
  flows: All flows.
722
707
  execution_context: Information about a single graph run.
723
708
  story_graph: StoryGraph object with stories available for training.
709
+ domain: The domain of the bot.
710
+
724
711
  Returns:
725
712
  The cleaned up commands.
726
713
  """
@@ -746,10 +733,9 @@ def clean_up_chitchat_command(
746
733
  )
747
734
  defines_intentless_policy = execution_context.has_node(IntentlessPolicy)
748
735
 
749
- has_e2e_stories = True if (story_graph and story_graph.has_e2e_stories()) else False
750
-
751
736
  if (has_action_trigger_chitchat and not defines_intentless_policy) or (
752
- defines_intentless_policy and not has_e2e_stories
737
+ defines_intentless_policy
738
+ and not contains_intentless_policy_responses(flows, domain, story_graph)
753
739
  ):
754
740
  resulting_commands.insert(
755
741
  0, CannotHandleCommand(RASA_PATTERN_CANNOT_HANDLE_CHITCHAT)
@@ -842,12 +828,12 @@ def should_slot_be_set(
842
828
  return True
843
829
 
844
830
 
845
- def filter_cannot_handle_command_for_skipped_slots(
831
+ def filter_cannot_handle_command(
846
832
  clean_commands: List[Command],
847
833
  ) -> List[Command]:
848
- """Filter out a 'cannot handle' command for skipped slots.
834
+ """Filter out a 'cannot handle' command.
849
835
 
850
- This is used to filter out a 'cannot handle' command for skipped slots
836
+ This is used to filter out a 'cannot handle' command
851
837
  in case other commands are present.
852
838
 
853
839
  Returns:
@@ -856,34 +842,5 @@ def filter_cannot_handle_command_for_skipped_slots(
856
842
  return [
857
843
  command
858
844
  for command in clean_commands
859
- if not (
860
- isinstance(command, CannotHandleCommand)
861
- and command.reason
862
- and CANNOT_HANDLE_REASON == command.reason
863
- )
845
+ if not isinstance(command, CannotHandleCommand)
864
846
  ]
865
-
866
-
867
- def should_add_handle_digressions_command(
868
- tracker: DialogueStateTracker, all_flows: FlowsList, top_flow_id: str
869
- ) -> bool:
870
- """Check if a handle digressions command should be added to the commands.
871
-
872
- The command should replace a StartFlow command only if we are at a collect step of
873
- a flow and a new flow is predicted by the command generator to start.
874
- """
875
- current_flow = all_flows.flow_by_id(top_flow_id)
876
- current_flow_condition = current_flow and (
877
- current_flow.ask_confirm_digressions or current_flow.block_digressions
878
- )
879
-
880
- collect_info = get_current_collect_step(tracker.stack, all_flows)
881
-
882
- if collect_info and (
883
- collect_info.ask_confirm_digressions
884
- or collect_info.block_digressions
885
- or current_flow_condition
886
- ):
887
- return True
888
-
889
- return False
@@ -6,6 +6,7 @@ import rasa.dialogue_understanding.processor.command_processor
6
6
  from rasa.engine.graph import ExecutionContext, GraphComponent
7
7
  from rasa.engine.storage.resource import Resource
8
8
  from rasa.engine.storage.storage import ModelStorage
9
+ from rasa.shared.core.domain import Domain
9
10
  from rasa.shared.core.events import Event
10
11
  from rasa.shared.core.flows import FlowsList
11
12
  from rasa.shared.core.trackers import DialogueStateTracker
@@ -15,7 +16,8 @@ from rasa.shared.core.training_data.structures import StoryGraph
15
16
  class CommandProcessorComponent(GraphComponent):
16
17
  """Processes commands by issuing events to modify a tracker.
17
18
 
18
- Minimal component that applies commands to a tracker."""
19
+ Minimal component that applies commands to a tracker.
20
+ """
19
21
 
20
22
  def __init__(self, execution_context: ExecutionContext):
21
23
  self._execution_context = execution_context
@@ -36,8 +38,9 @@ class CommandProcessorComponent(GraphComponent):
36
38
  tracker: DialogueStateTracker,
37
39
  flows: FlowsList,
38
40
  story_graph: StoryGraph,
41
+ domain: Domain,
39
42
  ) -> List[Event]:
40
43
  """Execute commands to update tracker state."""
41
44
  return rasa.dialogue_understanding.processor.command_processor.execute_commands(
42
- tracker, flows, self._execution_context, story_graph
45
+ tracker, flows, self._execution_context, story_graph, domain
43
46
  )
@@ -4,9 +4,6 @@ from typing import List, Optional, Set, Tuple
4
4
  from rasa.dialogue_understanding.patterns.collect_information import (
5
5
  CollectInformationPatternFlowStackFrame,
6
6
  )
7
- from rasa.dialogue_understanding.patterns.continue_interrupted import (
8
- ContinueInterruptedPatternFlowStackFrame,
9
- )
10
7
  from rasa.dialogue_understanding.stack.dialogue_stack import DialogueStack
11
8
  from rasa.dialogue_understanding.stack.frames import (
12
9
  BaseFlowStackFrame,
@@ -221,38 +218,3 @@ def get_collect_steps_excluding_ask_before_filling_for_active_flow(
221
218
  for step in active_flow.get_collect_steps()
222
219
  if not step.ask_before_filling
223
220
  )
224
-
225
-
226
- def remove_digression_from_stack(stack: DialogueStack, flow_id: str) -> DialogueStack:
227
- """Remove a specific flow frame from the stack and other frames that reference it.
228
-
229
- The main use-case is to prevent duplicate digressions from being added to the stack.
230
-
231
- Args:
232
- stack: The dialogue stack.
233
- flow_id: The flow to remove.
234
-
235
- Returns:
236
- The updated dialogue stack.
237
- """
238
- updated_stack = stack.copy()
239
- original_frames = updated_stack.frames[:]
240
- found_digression_index = -1
241
- for index, frame in enumerate(original_frames):
242
- if isinstance(frame, BaseFlowStackFrame) and frame.flow_id == flow_id:
243
- updated_stack.frames.pop(index)
244
- found_digression_index = index
245
-
246
- # we also need to remove the `ContinueInterruptedPatternFlowStackFrame`
247
- elif (
248
- isinstance(frame, ContinueInterruptedPatternFlowStackFrame)
249
- and frame.previous_flow_name == flow_id
250
- and found_digression_index + 1 == index
251
- ):
252
- # we know that this frame is always added after the digressing flow frame
253
- # that was blocked previously by action_block_digressions,
254
- # so this check would occur after the digressing flow was popped.
255
- # Therefore, we need to update the index dynamically before popping.
256
- updated_stack.frames.pop(index - 1)
257
-
258
- return updated_stack
@@ -6,7 +6,7 @@ Each question variation should be a question that the input answer is attempting
6
6
  Follow these steps to complete the task:
7
7
 
8
8
  1. Generate {{ num_variations }} question variations that the input answer is attempting to answer.
9
- 3. Compile all the question variations into a JSON object.
9
+ 2. Compile all the question variations into a JSON object.
10
10
 
11
11
  ### JSON Output
12
12
 
rasa/engine/validation.py CHANGED
@@ -86,7 +86,9 @@ from rasa.shared.constants import (
86
86
  from rasa.shared.core.constants import ACTION_RESET_ROUTING, ACTION_TRIGGER_CHITCHAT
87
87
  from rasa.shared.core.domain import Domain
88
88
  from rasa.shared.core.flows import Flow, FlowsList
89
+ from rasa.shared.core.policies.utils import contains_intentless_policy_responses
89
90
  from rasa.shared.core.slots import Slot
91
+ from rasa.shared.core.training_data.structures import StoryGraph
90
92
  from rasa.shared.exceptions import RasaException
91
93
  from rasa.shared.nlu.training_data.message import Message
92
94
  from rasa.shared.utils.common import display_research_study_prompt
@@ -642,11 +644,18 @@ def _recursively_check_required_components(
642
644
 
643
645
 
644
646
  def validate_flow_component_dependencies(
645
- flows: FlowsList, model_configuration: GraphModelConfiguration
647
+ flows: FlowsList,
648
+ domain: Domain,
649
+ story_graph: StoryGraph,
650
+ model_configuration: GraphModelConfiguration,
646
651
  ) -> None:
647
652
  if (pattern_chitchat := flows.flow_by_id(FLOW_PATTERN_CHITCHAT)) is not None:
648
653
  _validate_chitchat_dependencies(pattern_chitchat, model_configuration)
649
654
 
655
+ _validate_intentless_policy_responses(
656
+ flows, domain, story_graph, model_configuration
657
+ )
658
+
650
659
 
651
660
  def _validate_chitchat_dependencies(
652
661
  pattern_chitchat: Flow, model_configuration: GraphModelConfiguration
@@ -674,6 +683,32 @@ def _validate_chitchat_dependencies(
674
683
  )
675
684
 
676
685
 
686
+ def _validate_intentless_policy_responses(
687
+ flows: FlowsList,
688
+ domain: Domain,
689
+ story_graph: StoryGraph,
690
+ model_configuration: GraphModelConfiguration,
691
+ ) -> None:
692
+ """If IntentlessPolicy is configured, validate that it has responses to use:
693
+ either responses from the domain that are not part of any flow, or from
694
+ end-to-end stories.
695
+ """
696
+ if not model_configuration.predict_schema.has_node(IntentlessPolicy):
697
+ return
698
+
699
+ if not contains_intentless_policy_responses(flows, domain, story_graph):
700
+ structlogger.error(
701
+ "validation.intentless_policy.no_applicable_responses_found",
702
+ event_info=(
703
+ "IntentlessPolicy is configured, but no applicable responses are "
704
+ "found. Please make sure that there are responses defined in the "
705
+ "domain that are not part of any flow, or that there are "
706
+ "end-to-end stories in the training data."
707
+ ),
708
+ )
709
+ sys.exit(1)
710
+
711
+
677
712
  def get_component_index(schema: GraphSchema, component_class: Type) -> Optional[int]:
678
713
  """Extracts the index of a component of the given class in the schema.
679
714
  This function assumes that each component's node name is stored in a way
rasa/model_training.py CHANGED
@@ -315,6 +315,7 @@ async def _train_graph(
315
315
  )
316
316
  flows = file_importer.get_flows()
317
317
  domain = file_importer.get_domain()
318
+ story_graph = file_importer.get_stories()
318
319
  model_configuration = recipe.graph_config_for_recipe(
319
320
  config,
320
321
  kwargs,
@@ -330,7 +331,7 @@ async def _train_graph(
330
331
  config
331
332
  )
332
333
  rasa.engine.validation.validate_flow_component_dependencies(
333
- flows, model_configuration
334
+ flows, domain, story_graph, model_configuration
334
335
  )
335
336
  rasa.engine.validation.validate_command_generator_setup(model_configuration)
336
337
 
rasa/shared/constants.py CHANGED
@@ -99,6 +99,8 @@ UTTER_ASK_PREFIX = "utter_ask_"
99
99
  ACTION_ASK_PREFIX = "action_ask_"
100
100
  FLOW_PREFIX = "flow_"
101
101
 
102
+ UTTER_FREE_CHITCHAT_RESPONSE = "utter_free_chitchat_response"
103
+
102
104
  ASSISTANT_ID_KEY = "assistant_id"
103
105
  ASSISTANT_ID_DEFAULT_VALUE = "placeholder_default"
104
106
 
@@ -52,8 +52,6 @@ ACTION_TRIGGER_CHITCHAT = "action_trigger_chitchat"
52
52
  ACTION_RESET_ROUTING = "action_reset_routing"
53
53
  ACTION_HANGUP = "action_hangup"
54
54
  ACTION_REPEAT_BOT_MESSAGES = "action_repeat_bot_messages"
55
- ACTION_BLOCK_DIGRESSION = "action_block_digression"
56
- ACTION_CONTINUE_DIGRESSION = "action_continue_digression"
57
55
 
58
56
  ACTION_METADATA_EXECUTION_SUCCESS = "execution_success"
59
57
  ACTION_METADATA_EXECUTION_ERROR_MESSAGE = "execution_error_message"
@@ -84,8 +82,6 @@ DEFAULT_ACTION_NAMES = [
84
82
  ACTION_RESET_ROUTING,
85
83
  ACTION_HANGUP,
86
84
  ACTION_REPEAT_BOT_MESSAGES,
87
- ACTION_BLOCK_DIGRESSION,
88
- ACTION_CONTINUE_DIGRESSION,
89
85
  ]
90
86
 
91
87
  ACTION_SHOULD_SEND_DOMAIN = "send_domain"
@@ -205,8 +201,4 @@ CLASSIFIER_NAME_FALLBACK = "FallbackClassifier"
205
201
 
206
202
  POLICIES_THAT_EXTRACT_ENTITIES = {"TEDPolicy"}
207
203
 
208
- # digression constants
209
- KEY_ASK_CONFIRM_DIGRESSIONS = "ask_confirm_digressions"
210
- KEY_BLOCK_DIGRESSIONS = "block_digressions"
211
-
212
204
  ERROR_CODE_KEY = "error_code"
@@ -1678,6 +1678,14 @@ class Domain:
1678
1678
  """Write domain to a file."""
1679
1679
  as_yaml = self.as_yaml()
1680
1680
  rasa.shared.utils.io.write_text_file(as_yaml, filename)
1681
+ # run the check again on the written domain to catch any errors
1682
+ # that may have been missed in the user defined domain files
1683
+ structlogger.info(
1684
+ "domain.persist.domain_written_to_file",
1685
+ event_info="The entire domain content has been written to file.",
1686
+ filename=filename,
1687
+ )
1688
+ Domain.is_domain_file(filename)
1681
1689
 
1682
1690
  def as_yaml(self) -> Text:
1683
1691
  """Dump the `Domain` object as a YAML string.
@@ -1972,17 +1980,18 @@ class Domain:
1972
1980
 
1973
1981
  try:
1974
1982
  content = read_yaml_file(filename, expand_env_vars=cls.expand_env_vars)
1975
- except (RasaException, YamlSyntaxException):
1976
- structlogger.warning(
1983
+ except (RasaException, YamlSyntaxException) as error:
1984
+ structlogger.error(
1977
1985
  "domain.cannot_load_domain_file",
1978
1986
  file=filename,
1987
+ error=error,
1979
1988
  event_info=(
1980
1989
  f"The file {filename} could not be loaded as domain file. "
1981
1990
  f"You can use https://yamlchecker.com/ to validate "
1982
1991
  f"the YAML syntax of your file."
1983
1992
  ),
1984
1993
  )
1985
- return False
1994
+ raise RasaException(f"Domain could not be loaded: {error}")
1986
1995
 
1987
1996
  return any(key in content for key in ALL_DOMAIN_KEYS)
1988
1997
 
@@ -13,10 +13,6 @@ from pypred import Predicate
13
13
  import rasa.shared.utils.io
14
14
  from rasa.engine.language import Language
15
15
  from rasa.shared.constants import RASA_DEFAULT_FLOW_PATTERN_PREFIX
16
- from rasa.shared.core.constants import (
17
- KEY_ASK_CONFIRM_DIGRESSIONS,
18
- KEY_BLOCK_DIGRESSIONS,
19
- )
20
16
  from rasa.shared.core.flows.constants import (
21
17
  KEY_ALWAYS_INCLUDE_IN_PROMPT,
22
18
  KEY_DESCRIPTION,
@@ -52,7 +48,6 @@ from rasa.shared.core.flows.steps.constants import (
52
48
  START_STEP,
53
49
  )
54
50
  from rasa.shared.core.flows.steps.continuation import ContinueFlowStep
55
- from rasa.shared.core.flows.utils import extract_digression_prop
56
51
  from rasa.shared.core.slots import Slot
57
52
 
58
53
  structlogger = structlog.get_logger()
@@ -94,10 +89,6 @@ class Flow:
94
89
  """The path to the file where the flow is stored."""
95
90
  persisted_slots: List[str] = field(default_factory=list)
96
91
  """The list of slots that should be persisted after the flow ends."""
97
- ask_confirm_digressions: List[str] = field(default_factory=list)
98
- """The flow ids for which the assistant should ask for confirmation."""
99
- block_digressions: List[str] = field(default_factory=list)
100
- """The flow ids that the assistant should block from digressing to."""
101
92
  run_pattern_completed: bool = True
102
93
  """Whether the pattern_completed flow should be run after the flow ends."""
103
94
 
@@ -138,10 +129,6 @@ class Flow:
138
129
  # data. When the model is trained, take the provided file_path.
139
130
  file_path=data.get(KEY_FILE_PATH) if KEY_FILE_PATH in data else file_path,
140
131
  persisted_slots=data.get(KEY_PERSISTED_SLOTS, []),
141
- ask_confirm_digressions=extract_digression_prop(
142
- KEY_ASK_CONFIRM_DIGRESSIONS, data
143
- ),
144
- block_digressions=extract_digression_prop(KEY_BLOCK_DIGRESSIONS, data),
145
132
  run_pattern_completed=data.get(KEY_RUN_PATTERN_COMPLETED, True),
146
133
  translation=extract_translations(
147
134
  translation_data=data.get(KEY_TRANSLATION, {})
@@ -220,10 +207,6 @@ class Flow:
220
207
  data[KEY_FILE_PATH] = self.file_path
221
208
  if self.persisted_slots:
222
209
  data[KEY_PERSISTED_SLOTS] = self.persisted_slots
223
- if self.ask_confirm_digressions:
224
- data[KEY_ASK_CONFIRM_DIGRESSIONS] = self.ask_confirm_digressions
225
- if self.block_digressions:
226
- data[KEY_BLOCK_DIGRESSIONS] = self.block_digressions
227
210
  if self.run_pattern_completed is not None:
228
211
  data["run_pattern_completed"] = self.run_pattern_completed
229
212
  if self.translation:
@@ -217,15 +217,12 @@
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
  },
223
+ "force_slot_filling": {
224
+ "type": "boolean"
225
+ },
229
226
  "rejections": {
230
227
  "type": "array",
231
228
  "schema_name": "list of rejections",
@@ -253,32 +250,6 @@
253
250
  }
254
251
  }
255
252
  },
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
253
  "flow": {
283
254
  "required": [
284
255
  "steps",
@@ -340,12 +311,6 @@
340
311
  "persisted_slots": {
341
312
  "$ref": "#/$defs/persisted_slots"
342
313
  },
343
- "ask_confirm_digressions": {
344
- "$ref": "#/$defs/ask_confirm_digressions"
345
- },
346
- "block_digressions": {
347
- "$ref": "#/$defs/block_digressions"
348
- },
349
314
  "run_pattern_completed": {
350
315
  "type": "boolean"
351
316
  }
@@ -1,15 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
- from dataclasses import dataclass, field
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
  from rasa.shared.core.slots import SlotRejection
14
9
 
15
10
 
@@ -29,10 +24,8 @@ class CollectInformationFlowStep(FlowStep):
29
24
  """Whether to always ask the question even if the slot is already filled."""
30
25
  reset_after_flow_ends: bool = True
31
26
  """Whether to reset the slot value at the end of the flow."""
32
- ask_confirm_digressions: List[str] = field(default_factory=list)
33
- """The flow id digressions for which the assistant should ask for confirmation."""
34
- block_digressions: List[str] = field(default_factory=list)
35
- """The flow id digressions that should be blocked during the flow step."""
27
+ force_slot_filling: bool = False
28
+ """Whether to keep only the SetSlot command for the collected slot."""
36
29
 
37
30
  @classmethod
38
31
  def from_json(
@@ -60,10 +53,7 @@ class CollectInformationFlowStep(FlowStep):
60
53
  SlotRejection.from_dict(rejection)
61
54
  for rejection in data.get("rejections", [])
62
55
  ],
63
- ask_confirm_digressions=extract_digression_prop(
64
- KEY_ASK_CONFIRM_DIGRESSIONS, data
65
- ),
66
- block_digressions=extract_digression_prop(KEY_BLOCK_DIGRESSIONS, data),
56
+ force_slot_filling=data.get("force_slot_filling", False),
67
57
  **base.__dict__,
68
58
  )
69
59
 
@@ -79,10 +69,7 @@ class CollectInformationFlowStep(FlowStep):
79
69
  data["ask_before_filling"] = self.ask_before_filling
80
70
  data["reset_after_flow_ends"] = self.reset_after_flow_ends
81
71
  data["rejections"] = [rejection.as_dict() for rejection in self.rejections]
82
- data["ask_confirm_digressions"] = self.ask_confirm_digressions
83
- data["block_digressions"] = (
84
- self.block_digressions if self.block_digressions else False
85
- )
72
+ data["force_slot_filling"] = self.force_slot_filling
86
73
 
87
74
  return data
88
75
 
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, Any, Dict, List, Set, Text
1
+ from typing import TYPE_CHECKING, Any, Dict, Set, Text
2
2
 
3
3
  from rasa.shared.utils.io import raise_deprecation_warning
4
4
 
@@ -8,7 +8,6 @@ if TYPE_CHECKING:
8
8
 
9
9
  RESET_PROPERTY_NAME = "reset_after_flow_ends"
10
10
  PERSIST_PROPERTY_NAME = "persisted_slots"
11
- ALL_LABEL = "ALL"
12
11
 
13
12
 
14
13
  def warn_deprecated_collect_step_config() -> None:
@@ -45,20 +44,6 @@ def get_invalid_slot_persistence_config_error_message(
45
44
  )
46
45
 
47
46
 
48
- def extract_digression_prop(prop: str, data: Dict[str, Any]) -> List[str]:
49
- """Extracts the digression property from the data.
50
-
51
- There can be two types of properties: ask_confirm_digressions and
52
- block_digressions.
53
- """
54
- digression_property = data.get(prop, [])
55
-
56
- if isinstance(digression_property, bool):
57
- digression_property = [ALL_LABEL] if digression_property else []
58
-
59
- return digression_property
60
-
61
-
62
47
  def extract_translations(
63
48
  translation_data: Dict[Text, Any],
64
49
  ) -> Dict[Text, "FlowLanguageTranslation"]:
File without changes