rasa-pro 3.12.0.dev12__py3-none-any.whl → 3.12.0rc1__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 (153) hide show
  1. rasa/anonymization/anonymization_rule_executor.py +16 -10
  2. rasa/cli/data.py +16 -0
  3. rasa/cli/inspect.py +20 -1
  4. rasa/cli/project_templates/calm/config.yml +2 -2
  5. rasa/cli/project_templates/calm/endpoints.yml +2 -2
  6. rasa/cli/shell.py +3 -3
  7. rasa/cli/utils.py +12 -0
  8. rasa/core/actions/action.py +99 -193
  9. rasa/core/actions/action_handle_digressions.py +142 -0
  10. rasa/core/actions/action_run_slot_rejections.py +16 -4
  11. rasa/core/actions/forms.py +10 -5
  12. rasa/core/channels/__init__.py +4 -0
  13. rasa/core/channels/studio_chat.py +19 -0
  14. rasa/core/channels/telegram.py +42 -24
  15. rasa/core/channels/voice_ready/audiocodes.py +42 -23
  16. rasa/core/channels/voice_ready/utils.py +1 -1
  17. rasa/core/channels/voice_stream/asr/asr_engine.py +10 -4
  18. rasa/core/channels/voice_stream/asr/azure.py +14 -1
  19. rasa/core/channels/voice_stream/asr/deepgram.py +20 -4
  20. rasa/core/channels/voice_stream/audiocodes.py +264 -0
  21. rasa/core/channels/voice_stream/browser_audio.py +5 -1
  22. rasa/core/channels/voice_stream/call_state.py +10 -1
  23. rasa/core/channels/voice_stream/genesys.py +335 -0
  24. rasa/core/channels/voice_stream/tts/azure.py +11 -2
  25. rasa/core/channels/voice_stream/tts/cartesia.py +29 -10
  26. rasa/core/channels/voice_stream/twilio_media_streams.py +2 -1
  27. rasa/core/channels/voice_stream/voice_channel.py +25 -3
  28. rasa/core/constants.py +2 -0
  29. rasa/core/migrate.py +2 -2
  30. rasa/core/nlg/contextual_response_rephraser.py +18 -1
  31. rasa/core/nlg/generator.py +83 -15
  32. rasa/core/nlg/response.py +6 -3
  33. rasa/core/nlg/translate.py +55 -0
  34. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +1 -1
  35. rasa/core/policies/flows/flow_executor.py +47 -46
  36. rasa/core/processor.py +72 -9
  37. rasa/core/run.py +4 -3
  38. rasa/dialogue_understanding/commands/can_not_handle_command.py +20 -2
  39. rasa/dialogue_understanding/commands/cancel_flow_command.py +80 -4
  40. rasa/dialogue_understanding/commands/change_flow_command.py +20 -2
  41. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +20 -2
  42. rasa/dialogue_understanding/commands/clarify_command.py +29 -3
  43. rasa/dialogue_understanding/commands/command.py +1 -16
  44. rasa/dialogue_understanding/commands/command_syntax_manager.py +55 -0
  45. rasa/dialogue_understanding/commands/correct_slots_command.py +11 -2
  46. rasa/dialogue_understanding/commands/handle_digressions_command.py +150 -0
  47. rasa/dialogue_understanding/commands/human_handoff_command.py +20 -2
  48. rasa/dialogue_understanding/commands/knowledge_answer_command.py +20 -2
  49. rasa/dialogue_understanding/commands/prompt_command.py +94 -0
  50. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +20 -2
  51. rasa/dialogue_understanding/commands/set_slot_command.py +29 -15
  52. rasa/dialogue_understanding/commands/skip_question_command.py +20 -2
  53. rasa/dialogue_understanding/commands/start_flow_command.py +61 -2
  54. rasa/dialogue_understanding/commands/utils.py +98 -4
  55. rasa/dialogue_understanding/constants.py +1 -0
  56. rasa/dialogue_understanding/generator/__init__.py +2 -0
  57. rasa/dialogue_understanding/generator/command_generator.py +110 -73
  58. rasa/dialogue_understanding/generator/command_parser.py +16 -13
  59. rasa/dialogue_understanding/generator/constants.py +3 -0
  60. rasa/dialogue_understanding/generator/llm_based_command_generator.py +170 -5
  61. rasa/dialogue_understanding/generator/llm_command_generator.py +5 -3
  62. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +26 -4
  63. rasa/dialogue_understanding/generator/nlu_command_adapter.py +44 -3
  64. rasa/dialogue_understanding/generator/prompt_templates/__init__.py +0 -0
  65. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +60 -0
  66. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +77 -0
  67. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_default.jinja2 +68 -0
  68. rasa/dialogue_understanding/generator/{single_step/command_prompt_template.jinja2 → prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2} +1 -1
  69. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +460 -0
  70. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +12 -318
  71. rasa/dialogue_understanding/generator/utils.py +32 -1
  72. rasa/dialogue_understanding/patterns/collect_information.py +1 -1
  73. rasa/dialogue_understanding/patterns/correction.py +13 -1
  74. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +78 -2
  75. rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
  76. rasa/dialogue_understanding/patterns/validate_slot.py +65 -0
  77. rasa/dialogue_understanding/processor/command_processor.py +154 -28
  78. rasa/dialogue_understanding/utils.py +31 -0
  79. rasa/dialogue_understanding_test/README.md +50 -0
  80. rasa/dialogue_understanding_test/du_test_case.py +28 -8
  81. rasa/dialogue_understanding_test/du_test_result.py +13 -9
  82. rasa/dialogue_understanding_test/io.py +14 -0
  83. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +3 -3
  84. rasa/e2e_test/utils/io.py +0 -37
  85. rasa/engine/graph.py +1 -0
  86. rasa/engine/language.py +140 -0
  87. rasa/engine/recipes/config_files/default_config.yml +4 -0
  88. rasa/engine/recipes/default_recipe.py +2 -0
  89. rasa/engine/recipes/graph_recipe.py +2 -0
  90. rasa/engine/storage/local_model_storage.py +1 -0
  91. rasa/engine/storage/storage.py +4 -1
  92. rasa/model_manager/runner_service.py +7 -4
  93. rasa/model_manager/socket_bridge.py +7 -6
  94. rasa/model_manager/warm_rasa_process.py +0 -1
  95. rasa/model_training.py +24 -27
  96. rasa/shared/constants.py +15 -13
  97. rasa/shared/core/constants.py +30 -3
  98. rasa/shared/core/domain.py +13 -20
  99. rasa/shared/core/events.py +13 -2
  100. rasa/shared/core/flows/constants.py +11 -0
  101. rasa/shared/core/flows/flow.py +100 -19
  102. rasa/shared/core/flows/flows_yaml_schema.json +69 -3
  103. rasa/shared/core/flows/steps/collect.py +19 -37
  104. rasa/shared/core/flows/utils.py +43 -4
  105. rasa/shared/core/flows/validation.py +1 -1
  106. rasa/shared/core/slot_mappings.py +350 -111
  107. rasa/shared/core/slots.py +154 -3
  108. rasa/shared/core/trackers.py +77 -2
  109. rasa/shared/importers/importer.py +50 -2
  110. rasa/shared/nlu/constants.py +1 -0
  111. rasa/shared/nlu/training_data/schemas/responses.yml +19 -12
  112. rasa/shared/providers/_configs/azure_entra_id_config.py +541 -0
  113. rasa/shared/providers/_configs/azure_openai_client_config.py +138 -3
  114. rasa/shared/providers/_configs/client_config.py +3 -1
  115. rasa/shared/providers/_configs/default_litellm_client_config.py +3 -1
  116. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +3 -1
  117. rasa/shared/providers/_configs/litellm_router_client_config.py +3 -1
  118. rasa/shared/providers/_configs/model_group_config.py +4 -2
  119. rasa/shared/providers/_configs/oauth_config.py +33 -0
  120. rasa/shared/providers/_configs/openai_client_config.py +3 -1
  121. rasa/shared/providers/_configs/rasa_llm_client_config.py +3 -1
  122. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +3 -1
  123. rasa/shared/providers/constants.py +6 -0
  124. rasa/shared/providers/embedding/azure_openai_embedding_client.py +28 -3
  125. rasa/shared/providers/embedding/litellm_router_embedding_client.py +3 -1
  126. rasa/shared/providers/llm/_base_litellm_client.py +42 -17
  127. rasa/shared/providers/llm/azure_openai_llm_client.py +81 -25
  128. rasa/shared/providers/llm/default_litellm_llm_client.py +3 -1
  129. rasa/shared/providers/llm/litellm_router_llm_client.py +29 -8
  130. rasa/shared/providers/llm/llm_client.py +23 -7
  131. rasa/shared/providers/llm/openai_llm_client.py +9 -3
  132. rasa/shared/providers/llm/rasa_llm_client.py +11 -2
  133. rasa/shared/providers/llm/self_hosted_llm_client.py +30 -11
  134. rasa/shared/providers/router/_base_litellm_router_client.py +3 -1
  135. rasa/shared/providers/router/router_client.py +3 -1
  136. rasa/shared/utils/constants.py +3 -0
  137. rasa/shared/utils/llm.py +31 -8
  138. rasa/shared/utils/pykwalify_extensions.py +24 -0
  139. rasa/shared/utils/schemas/domain.yml +26 -1
  140. rasa/telemetry.py +45 -14
  141. rasa/tracing/config.py +2 -0
  142. rasa/tracing/constants.py +12 -0
  143. rasa/tracing/instrumentation/instrumentation.py +36 -0
  144. rasa/tracing/instrumentation/metrics.py +41 -0
  145. rasa/tracing/metric_instrument_provider.py +40 -0
  146. rasa/utils/common.py +0 -1
  147. rasa/validator.py +561 -89
  148. rasa/version.py +1 -1
  149. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/METADATA +2 -1
  150. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/RECORD +153 -134
  151. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/NOTICE +0 -0
  152. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/WHEEL +0 -0
  153. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,18 @@
1
- from typing import TYPE_CHECKING, List, Optional, Union
1
+ from typing import TYPE_CHECKING, Any, List, Optional, Tuple, Union
2
2
 
3
3
  import structlog
4
4
 
5
+ from rasa.dialogue_understanding.patterns.validate_slot import (
6
+ ValidateSlotPatternFlowStackFrame,
7
+ )
8
+ from rasa.shared.constants import (
9
+ ACTION_ASK_PREFIX,
10
+ UTTER_ASK_PREFIX,
11
+ )
12
+ from rasa.shared.core.events import Event, SlotSet
13
+ from rasa.shared.core.slots import Slot
14
+ from rasa.shared.core.trackers import DialogueStateTracker
15
+
5
16
  if TYPE_CHECKING:
6
17
  from rasa.dialogue_understanding.commands import StartFlowCommand
7
18
  from rasa.shared.core.flows import FlowsList
@@ -25,10 +36,13 @@ def start_flow_by_name(
25
36
 
26
37
  def extract_cleaned_options(options_str: str) -> List[str]:
27
38
  """Extract and clean options from a string."""
39
+ delimiters = [",", " "]
40
+
41
+ for delimiter in delimiters:
42
+ options_str = options_str.replace(delimiter, " ")
43
+
28
44
  return sorted(
29
- opt.strip().strip('"').strip("'")
30
- for opt in options_str.split(" ")
31
- if opt.strip()
45
+ opt.strip().strip('"').strip("'") for opt in options_str.split() if opt.strip()
32
46
  )
33
47
 
34
48
 
@@ -62,3 +76,83 @@ def get_nullable_slot_value(slot_value: str) -> Union[str, None]:
62
76
  The slot value or None if the value is a none value.
63
77
  """
64
78
  return slot_value if not is_none_value(slot_value) else None
79
+
80
+
81
+ def initialize_pattern_validate_slot(
82
+ slot: Slot,
83
+ ) -> Optional[ValidateSlotPatternFlowStackFrame]:
84
+ """Initialize the pattern to validate a slot value."""
85
+ if not slot.requires_validation():
86
+ return None
87
+
88
+ validation = slot.validation
89
+ slot_name = slot.name
90
+ return ValidateSlotPatternFlowStackFrame(
91
+ validate=slot_name,
92
+ refill_utter=validation.refill_utter or f"{UTTER_ASK_PREFIX}{slot_name}", # type: ignore[union-attr]
93
+ refill_action=f"{ACTION_ASK_PREFIX}{slot_name}",
94
+ rejections=validation.rejections, # type: ignore[union-attr]
95
+ )
96
+
97
+
98
+ def create_validate_frames_from_slot_set_events(
99
+ tracker: DialogueStateTracker,
100
+ events: List[Event],
101
+ validate_frames: List[ValidateSlotPatternFlowStackFrame] = [],
102
+ should_break: bool = False,
103
+ update_corrected_slots: bool = False,
104
+ ) -> Tuple[DialogueStateTracker, List[ValidateSlotPatternFlowStackFrame]]:
105
+ """Process SlotSet events and create validation frames.
106
+
107
+ Args:
108
+ tracker: The dialogue state tracker.
109
+ events: List of events to process.
110
+ should_break: whether or not to break after the first non-SlotSet event.
111
+ if True, break out of the event loop as soon as the first non-SlotSet
112
+ event is encountered.
113
+ if False, continue processing the events until the end.
114
+ update_corrected_slots: whether or not corrected slots in the last
115
+ correction frame need to be updated.
116
+
117
+ Returns:
118
+ Tuple of (updated tracker, list of validation frames).
119
+ """
120
+ for event in events:
121
+ if not isinstance(event, SlotSet):
122
+ if should_break:
123
+ # we want to only process the most recent SlotSet events
124
+ # so we break once we encounter a different event
125
+ break
126
+ continue
127
+
128
+ slot = tracker.slots.get(event.key)
129
+ frame = initialize_pattern_validate_slot(slot)
130
+
131
+ if frame:
132
+ validate_frames.append(frame)
133
+ if update_corrected_slots:
134
+ tracker = update_corrected_slots_in_correction_frame(
135
+ tracker, event.key, event.value
136
+ )
137
+
138
+ return tracker, validate_frames
139
+
140
+
141
+ def update_corrected_slots_in_correction_frame(
142
+ tracker: DialogueStateTracker, slot_name: str, slot_value: Any
143
+ ) -> DialogueStateTracker:
144
+ """Update the corrected_slots and new_slot_values of the
145
+ CorrectionPatternFlowStackFrame with only valid values.
146
+ """
147
+ stack = tracker.stack
148
+ top_frame = stack.top()
149
+ del top_frame.corrected_slots[slot_name] # type: ignore[union-attr]
150
+ top_frame.new_slot_values.remove(slot_value) # type: ignore[union-attr]
151
+
152
+ # since we can't directly modify a stack we have to pop first
153
+ # and then push back the updated frame
154
+ stack.pop()
155
+ stack.push(top_frame)
156
+ new_events = tracker.create_stack_updated_events(stack)
157
+ tracker.update_with_events(new_events)
158
+ return tracker
@@ -1 +1,2 @@
1
1
  RASA_RECORD_COMMANDS_AND_PROMPTS_ENV_VAR_NAME = "RASA_RECORD_COMMANDS_AND_PROMPTS"
2
+ KEY_MINIMIZE_NUM_CALLS = "minimize_num_calls"
@@ -9,6 +9,7 @@ from rasa.dialogue_understanding.generator.multi_step.multi_step_llm_command_gen
9
9
  MultiStepLLMCommandGenerator,
10
10
  )
11
11
  from rasa.dialogue_understanding.generator.single_step.single_step_llm_command_generator import ( # noqa: E501
12
+ CompactLLMCommandGenerator,
12
13
  SingleStepLLMCommandGenerator,
13
14
  )
14
15
 
@@ -18,4 +19,5 @@ __all__ = [
18
19
  "LLMCommandGenerator",
19
20
  "MultiStepLLMCommandGenerator",
20
21
  "SingleStepLLMCommandGenerator",
22
+ "CompactLLMCommandGenerator",
21
23
  ]
@@ -1,23 +1,24 @@
1
1
  from dataclasses import dataclass
2
- from typing import Any, Dict, List, Optional, Text
2
+ from typing import Any, Dict, List, Optional, Set, Text, Tuple
3
3
 
4
4
  import structlog
5
5
 
6
6
  from rasa.dialogue_understanding.commands import (
7
7
  Command,
8
+ CorrectSlotsCommand,
8
9
  ErrorCommand,
9
10
  SetSlotCommand,
10
11
  StartFlowCommand,
11
12
  )
12
- from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
13
+ from rasa.dialogue_understanding.utils import (
14
+ _handle_via_nlu_in_coexistence,
15
+ )
13
16
  from rasa.shared.constants import (
14
17
  RASA_PATTERN_INTERNAL_ERROR_USER_INPUT_EMPTY,
15
18
  RASA_PATTERN_INTERNAL_ERROR_USER_INPUT_TOO_LONG,
16
19
  )
17
- from rasa.shared.core.constants import SlotMappingType
18
20
  from rasa.shared.core.domain import Domain
19
21
  from rasa.shared.core.flows import FlowsList
20
- from rasa.shared.core.slot_mappings import SlotFillingManager
21
22
  from rasa.shared.core.trackers import DialogueStateTracker
22
23
  from rasa.shared.nlu.constants import (
23
24
  COMMANDS,
@@ -92,9 +93,9 @@ class CommandGenerator:
92
93
  )
93
94
 
94
95
  for message in messages:
95
- if message.get(COMMANDS):
96
- # do not overwrite commands if they are already present
97
- # i.e. another command generator already predicted commands
96
+ if _handle_via_nlu_in_coexistence(tracker, message):
97
+ # Skip running the CALM pipeline if the message should
98
+ # be handled by the NLU-based system in a coexistence mode.
98
99
  continue
99
100
 
100
101
  commands = await self._evaluate_and_predict(
@@ -106,9 +107,6 @@ class CommandGenerator:
106
107
  commands = self._check_commands_against_startable_flows(
107
108
  commands, startable_flows
108
109
  )
109
- commands = self._check_commands_against_slot_mappings(
110
- commands, tracker, domain
111
- )
112
110
  commands_dicts = [command.as_dict() for command in commands]
113
111
  message.set(COMMANDS, commands_dicts, add_to_output=True)
114
112
 
@@ -202,6 +200,94 @@ class CommandGenerator:
202
200
  """
203
201
  raise NotImplementedError()
204
202
 
203
+ def _check_commands_overlap(
204
+ self, prior_commands: List[Command], commands: List[Command]
205
+ ) -> List[Command]:
206
+ """Check if there is overlap between the prior commands and the current ones.
207
+
208
+ Args:
209
+ prior_commands: The prior commands.
210
+ commands: The commands to check.
211
+
212
+ Returns:
213
+ The final commands.
214
+ """
215
+ if not prior_commands:
216
+ return commands
217
+
218
+ prior_commands, commands = self._check_slot_command_overlap(
219
+ prior_commands, commands
220
+ )
221
+
222
+ prior_start_flow_names = {
223
+ command.flow
224
+ for command in prior_commands
225
+ if isinstance(command, StartFlowCommand)
226
+ }
227
+ current_start_flow_names = {
228
+ command.flow
229
+ for command in commands
230
+ if isinstance(command, StartFlowCommand)
231
+ }
232
+
233
+ return self._check_start_flow_command_overlap(
234
+ prior_commands,
235
+ commands,
236
+ prior_start_flow_names,
237
+ current_start_flow_names,
238
+ )
239
+
240
+ def _check_start_flow_command_overlap(
241
+ self,
242
+ prior_commands: List[Command],
243
+ commands: List[Command],
244
+ prior_start_flow_names: Set[str],
245
+ current_start_flow_names: Set[str],
246
+ ) -> List[Command]:
247
+ """Get the final commands.
248
+
249
+ Args:
250
+ prior_commands: The prior commands.
251
+ commands: The currently predicted commands to check.
252
+ prior_start_flow_names: The names of the flows from the prior commands.
253
+ current_start_flow_names: The names of the flows from the current commands.
254
+
255
+ Returns:
256
+ The final commands.
257
+ """
258
+ raise NotImplementedError()
259
+
260
+ def _check_slot_command_overlap(
261
+ self,
262
+ prior_commands: List[Command],
263
+ commands: List[Command],
264
+ ) -> Tuple[List[Command], List[Command]]:
265
+ """Check if the current commands overlap with the prior commands."""
266
+ prior_slot_names = gather_slot_names(prior_commands)
267
+ current_slot_names = gather_slot_names(commands)
268
+ overlapping_slot_names = prior_slot_names.intersection(current_slot_names)
269
+
270
+ structlogger.debug(
271
+ "command_generator.check_slot_command_overlap",
272
+ overlapping_slot_names=overlapping_slot_names,
273
+ )
274
+
275
+ if not overlapping_slot_names:
276
+ return prior_commands, commands
277
+
278
+ return self._filter_slot_commands(
279
+ prior_commands, commands, overlapping_slot_names
280
+ )
281
+
282
+ def _filter_slot_commands(
283
+ self,
284
+ prior_commands: List[Command],
285
+ commands: List[Command],
286
+ overlapping_slot_names: Set[str],
287
+ ) -> Tuple[List[Command], List[Command]]:
288
+ """Filter out the overlapping slot commands."""
289
+ raise NotImplementedError()
290
+
205
291
  def _check_commands_against_startable_flows(
206
292
  self, commands: List[Command], startable_flows: FlowsList
207
293
  ) -> List[Command]:
@@ -278,70 +364,21 @@ class CommandGenerator:
278
364
  return len(message.get(TEXT, "").strip()) == 0
279
365
 
280
366
  @staticmethod
281
- def _check_commands_against_slot_mappings(
282
- commands: List[Command],
283
- tracker: DialogueStateTracker,
284
- domain: Optional[Domain] = None,
285
- ) -> List[Command]:
286
- """Check if the LLM-issued slot commands are fillable.
287
-
288
- The LLM-issued slot commands are fillable if the slot
289
- mappings are satisfied.
290
- """
291
- if not domain:
292
- return commands
293
-
294
- llm_fillable_slot_names = [
295
- command.name
296
- for command in commands
297
- if isinstance(command, SetSlotCommand)
298
- and command.extractor == SetSlotExtractor.LLM.value
299
- ]
300
-
301
- if not llm_fillable_slot_names:
302
- return commands
303
-
304
- llm_fillable_slots = [
305
- slot for slot in domain.slots if slot.name in llm_fillable_slot_names
367
+ def _get_prior_commands(message: Message) -> List[Command]:
368
+ """Get the prior commands from the tracker."""
369
+ return [
370
+ Command.command_from_json(command) for command in message.get(COMMANDS, [])
306
371
  ]
307
372
 
308
- slot_filling_manager = SlotFillingManager(domain, tracker)
309
- slots_to_be_removed = []
310
373
 
311
- structlogger.debug(
312
- "command_processor.check_commands_against_slot_mappings.active_flow",
313
- active_flow=tracker.active_flow,
314
- )
315
-
316
- for slot in llm_fillable_slots:
317
- should_fill_slot = False
318
- for mapping in slot.mappings:
319
- mapping_type = SlotMappingType(mapping.get("type"))
320
-
321
- should_fill_slot = slot_filling_manager.should_fill_slot(
322
- slot.name, mapping_type, mapping
323
- )
324
-
325
- if should_fill_slot:
326
- break
327
-
328
- if not should_fill_slot:
329
- structlogger.debug(
330
- "command_processor.check_commands_against_slot_mappings.slot_not_fillable",
331
- slot_name=slot.name,
332
- )
333
- slots_to_be_removed.append(slot.name)
334
-
335
- if not slots_to_be_removed:
336
- return commands
337
-
338
- filtered_commands = [
339
- command
340
- for command in commands
341
- if not (
342
- isinstance(command, SetSlotCommand)
343
- and command.name in slots_to_be_removed
344
- )
345
- ]
374
+ def gather_slot_names(commands: List[Command]) -> Set[str]:
375
+ """Gather all slot names from the commands."""
376
+ slot_names = set()
377
+ for command in commands:
378
+ if isinstance(command, SetSlotCommand):
379
+ slot_names.add(command.name)
380
+ if isinstance(command, CorrectSlotsCommand):
381
+ for slot in command.corrected_slots:
382
+ slot_names.add(slot.name)
346
383
 
347
- return filtered_commands
384
+ return slot_names
@@ -16,6 +16,7 @@ from rasa.dialogue_understanding.commands import (
16
16
  SkipQuestionCommand,
17
17
  StartFlowCommand,
18
18
  )
19
+ from rasa.dialogue_understanding.commands.prompt_command import PromptCommand
19
20
  from rasa.dialogue_understanding.commands.utils import start_flow_by_name
20
21
  from rasa.shared.core.flows import FlowsList
21
22
 
@@ -41,8 +42,8 @@ def _get_compiled_pattern(pattern_str: str) -> re.Pattern:
41
42
 
42
43
 
43
44
  def _create_default_commands(
44
- default_commands_to_remove: Union[List[Type[Command]], List[str]],
45
- ) -> List[Type[Command]]:
45
+ default_commands_to_remove: Union[List[Type[PromptCommand]], List[str]],
46
+ ) -> List[Type[PromptCommand]]:
46
47
  """Return an updated list of default commands after removing the provided commands.
47
48
 
48
49
  Args:
@@ -64,11 +65,11 @@ def _create_default_commands(
64
65
 
65
66
 
66
67
  def _get_additional_parsing_logic(
67
- command_clz: Type[Command],
68
- ) -> Optional[Callable[[Command, FlowsList], Optional[Command]]]:
68
+ command_clz: Type[PromptCommand],
69
+ ) -> Optional[Callable[[PromptCommand, FlowsList], Optional[PromptCommand]]]:
69
70
  """Get additional parsing logic for a command."""
70
71
  command_to_parsing_fn_mapper: Dict[
71
- Type[Command], Callable[..., Optional[Command]]
72
+ Type[PromptCommand], Callable[..., Optional[PromptCommand]]
72
73
  ] = {
73
74
  ClarifyCommand: _parse_clarify_command,
74
75
  SetSlotCommand: _parse_set_slot_command,
@@ -81,8 +82,10 @@ def parse_commands(
81
82
  actions: Optional[str],
82
83
  flows: FlowsList,
83
84
  is_handle_flows_prompt: bool = False,
84
- additional_commands: Optional[List[Type[Command]]] = None,
85
- default_commands_to_remove: Optional[Union[List[Type[Command]], List[str]]] = None,
85
+ additional_commands: Optional[List[Type[PromptCommand]]] = None,
86
+ default_commands_to_remove: Optional[
87
+ Union[List[Type[PromptCommand]], List[str]]
88
+ ] = None,
86
89
  **kwargs: Any,
87
90
  ) -> List[Command]:
88
91
  """Parse a list of action commands."""
@@ -116,7 +119,7 @@ def parse_commands(
116
119
 
117
120
 
118
121
  def _parse_standard_commands(
119
- standard_commands: List[Type[Command]],
122
+ standard_commands: List[Type[PromptCommand]],
120
123
  action: str,
121
124
  flows: FlowsList,
122
125
  **kwargs: Any,
@@ -125,7 +128,7 @@ def _parse_standard_commands(
125
128
  commands: List[Command] = []
126
129
  for command_clz in standard_commands:
127
130
  pattern = _get_compiled_pattern(command_clz.regex_pattern())
128
- if match := pattern.search(action.strip()):
131
+ if match := pattern.search(action):
129
132
  parsed_command = command_clz.from_dsl(match, **kwargs)
130
133
  if _additional_parsing_fn := _get_additional_parsing_logic(command_clz):
131
134
  parsed_command = _additional_parsing_fn(parsed_command, flows, **kwargs)
@@ -135,7 +138,7 @@ def _parse_standard_commands(
135
138
 
136
139
 
137
140
  def _parse_custom_commands(
138
- custom_commands: List[Type[Command]],
141
+ custom_commands: List[Type[PromptCommand]],
139
142
  action: str,
140
143
  flows: FlowsList,
141
144
  **kwargs: Any,
@@ -152,7 +155,7 @@ def _parse_custom_commands(
152
155
 
153
156
  def _parse_set_slot_command(
154
157
  parsed_command: Optional[SetSlotCommand], flows: FlowsList, **kwargs: Any
155
- ) -> Optional[Command]:
158
+ ) -> Optional[PromptCommand]:
156
159
  """Additional parsing logic for the SetSlotCommand."""
157
160
  if not parsed_command:
158
161
  return None
@@ -164,7 +167,7 @@ def _parse_set_slot_command(
164
167
 
165
168
  def _parse_clarify_command(
166
169
  parsed_command: Optional[ClarifyCommand], flows: FlowsList, **kwargs: Any
167
- ) -> Optional[Command]:
170
+ ) -> Optional[PromptCommand]:
168
171
  """Additional parsing logic for the ClarifyCommand."""
169
172
  if not parsed_command:
170
173
  return None
@@ -194,7 +197,7 @@ def _parse_clarify_command(
194
197
 
195
198
  def _parse_start_flow_command(
196
199
  parsed_command: Optional[StartFlowCommand], flows: FlowsList, **kwargs: Any
197
- ) -> Optional[Command]:
200
+ ) -> Optional[PromptCommand]:
198
201
  """Additional parsing logic for the StartFlowCommand."""
199
202
  if not parsed_command:
200
203
  return None
@@ -25,3 +25,6 @@ FLOW_RETRIEVAL_ACTIVE_KEY = "active"
25
25
  FLOW_RETRIEVAL_EMBEDDINGS_CONFIG_KEY = "embeddings"
26
26
 
27
27
  FLOW_RETRIEVAL_FLOW_THRESHOLD = 20
28
+
29
+ COMMAND_PROMPT_FILE_NAME = "command_prompt.jinja2"
30
+ LLM_BASED_COMMAND_GENERATOR_CONFIG_FILE = "config.json"