rasa-pro 3.11.0__py3-none-any.whl → 3.11.0a2__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 (217) hide show
  1. README.md +396 -17
  2. rasa/__main__.py +15 -31
  3. rasa/api.py +1 -5
  4. rasa/cli/arguments/default_arguments.py +2 -1
  5. rasa/cli/arguments/shell.py +1 -5
  6. rasa/cli/arguments/train.py +0 -14
  7. rasa/cli/e2e_test.py +1 -1
  8. rasa/cli/evaluate.py +8 -8
  9. rasa/cli/inspect.py +5 -7
  10. rasa/cli/interactive.py +0 -1
  11. rasa/cli/llm_fine_tuning.py +1 -1
  12. rasa/cli/project_templates/calm/config.yml +7 -5
  13. rasa/cli/project_templates/calm/endpoints.yml +2 -15
  14. rasa/cli/project_templates/tutorial/config.yml +5 -8
  15. rasa/cli/project_templates/tutorial/data/flows.yml +1 -1
  16. rasa/cli/project_templates/tutorial/data/patterns.yml +0 -5
  17. rasa/cli/project_templates/tutorial/domain.yml +0 -14
  18. rasa/cli/project_templates/tutorial/endpoints.yml +0 -5
  19. rasa/cli/run.py +1 -1
  20. rasa/cli/scaffold.py +2 -4
  21. rasa/cli/studio/studio.py +8 -18
  22. rasa/cli/studio/upload.py +15 -0
  23. rasa/cli/train.py +0 -3
  24. rasa/cli/utils.py +1 -6
  25. rasa/cli/x.py +8 -8
  26. rasa/constants.py +1 -3
  27. rasa/core/actions/action.py +33 -75
  28. rasa/core/actions/e2e_stub_custom_action_executor.py +1 -5
  29. rasa/core/actions/http_custom_action_executor.py +0 -4
  30. rasa/core/channels/channel.py +0 -20
  31. rasa/core/channels/development_inspector.py +2 -8
  32. rasa/core/channels/inspector/dist/assets/{arc-bc141fb2.js → arc-6852c607.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-be2db283.js → c4Diagram-d0fbc5ce-acc952b2.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-55366915.js → classDiagram-936ed81e-848a7597.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-bb529518.js → classDiagram-v2-c3cb15f1-a73d3e68.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-b0ec81d6.js → createText-62fc7601-e5ee049d.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-6166330c.js → edges-f2ad444c-771e517e.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-5ccc6a8e.js → erDiagram-9d236eb7-aa347178.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-fca3bfe4.js → flowDb-1972c806-651fc57d.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4739080f.js → flowDiagram-7ea5b25a-ca67804f.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-587d82d8.js +1 -0
  42. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-7c1b0e0f.js → flowchart-elk-definition-abe16c3d-2dbc568d.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-772fd050.js → ganttDiagram-9b5ea136-25a65bd8.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-8eae1dc9.js → gitGraphDiagram-99d0ae7c-fdc7378d.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-f55afcdf.js → index-2c4b9a3b-6f1fd606.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{index-e7cef9de.js → index-efdd30c1.js} +68 -68
  47. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-124d4a14.js → infoDiagram-736b4530-cb1a041a.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-7c4fae44.js → journeyDiagram-df861f2b-14609879.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{layout-b9885fb6.js → layout-2490f52b.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{line-7c59abb6.js → line-40186f1f.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{linear-4776f780.js → linear-08814e93.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2332c46c.js → mindmap-definition-beec6740-1a534584.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-8fb39303.js → pieDiagram-dbbf0591-72397b61.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-3c7180a2.js → quadrantDiagram-4d7f4fd6-3bb0b6a3.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-e910bcb8.js → requirementDiagram-6fc4c22a-57334f61.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-ead16c89.js → sankeyDiagram-8f13d901-111e1297.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-29a02a19.js → sequenceDiagram-b655622a-10bcfe62.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-042b3137.js → stateDiagram-59f0c015-acaf7513.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-2178c0f3.js → stateDiagram-v2-2b26beab-3ec2a235.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-23ffa4fc.js → styles-080da4f6-62730289.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-94f59763.js → styles-3dcbcfbf-5284ee76.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-78a6bebc.js → styles-9c745c82-642435e3.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-eae2a6f6.js → svgDrawCommon-4835440b-b250a350.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-5c968d92.js → timeline-definition-5b62e21b-c2b147ed.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-fd3db0d5.js → xychartDiagram-2b33534f-f92cfea9.js} +1 -1
  66. rasa/core/channels/inspector/dist/index.html +1 -1
  67. rasa/core/channels/inspector/src/App.tsx +1 -1
  68. rasa/core/channels/inspector/src/helpers/audiostream.ts +16 -77
  69. rasa/core/channels/socketio.py +2 -7
  70. rasa/core/channels/telegram.py +1 -1
  71. rasa/core/channels/twilio.py +1 -1
  72. rasa/core/channels/voice_ready/audiocodes.py +4 -15
  73. rasa/core/channels/voice_ready/jambonz.py +4 -15
  74. rasa/core/channels/voice_ready/twilio_voice.py +21 -6
  75. rasa/core/channels/voice_ready/utils.py +5 -6
  76. rasa/core/channels/voice_stream/asr/asr_engine.py +1 -19
  77. rasa/core/channels/voice_stream/asr/asr_event.py +0 -5
  78. rasa/core/channels/voice_stream/asr/deepgram.py +15 -28
  79. rasa/core/channels/voice_stream/audio_bytes.py +0 -1
  80. rasa/core/channels/voice_stream/browser_audio.py +9 -32
  81. rasa/core/channels/voice_stream/tts/azure.py +3 -9
  82. rasa/core/channels/voice_stream/tts/cartesia.py +8 -12
  83. rasa/core/channels/voice_stream/tts/tts_engine.py +1 -11
  84. rasa/core/channels/voice_stream/twilio_media_streams.py +19 -28
  85. rasa/core/channels/voice_stream/util.py +4 -4
  86. rasa/core/channels/voice_stream/voice_channel.py +42 -222
  87. rasa/core/featurizers/single_state_featurizer.py +1 -22
  88. rasa/core/featurizers/tracker_featurizers.py +18 -115
  89. rasa/core/information_retrieval/qdrant.py +0 -1
  90. rasa/core/nlg/contextual_response_rephraser.py +25 -44
  91. rasa/core/persistor.py +34 -191
  92. rasa/core/policies/enterprise_search_policy.py +60 -119
  93. rasa/core/policies/flows/flow_executor.py +4 -7
  94. rasa/core/policies/intentless_policy.py +22 -82
  95. rasa/core/policies/ted_policy.py +33 -58
  96. rasa/core/policies/unexpected_intent_policy.py +7 -15
  97. rasa/core/processor.py +5 -32
  98. rasa/core/training/interactive.py +35 -34
  99. rasa/core/utils.py +22 -58
  100. rasa/dialogue_understanding/coexistence/llm_based_router.py +12 -39
  101. rasa/dialogue_understanding/commands/__init__.py +0 -4
  102. rasa/dialogue_understanding/commands/change_flow_command.py +0 -6
  103. rasa/dialogue_understanding/commands/utils.py +0 -5
  104. rasa/dialogue_understanding/generator/constants.py +0 -2
  105. rasa/dialogue_understanding/generator/flow_retrieval.py +4 -49
  106. rasa/dialogue_understanding/generator/llm_based_command_generator.py +23 -37
  107. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +10 -57
  108. rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -19
  109. rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +0 -3
  110. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +10 -90
  111. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +0 -53
  112. rasa/dialogue_understanding/processor/command_processor.py +1 -21
  113. rasa/e2e_test/assertions.py +16 -133
  114. rasa/e2e_test/assertions_schema.yml +0 -23
  115. rasa/e2e_test/e2e_test_case.py +6 -85
  116. rasa/e2e_test/e2e_test_runner.py +4 -6
  117. rasa/e2e_test/utils/io.py +1 -3
  118. rasa/engine/loader.py +0 -12
  119. rasa/engine/validation.py +11 -541
  120. rasa/keys +1 -0
  121. rasa/llm_fine_tuning/notebooks/unsloth_finetuning.ipynb +407 -0
  122. rasa/model_training.py +7 -29
  123. rasa/nlu/classifiers/diet_classifier.py +25 -38
  124. rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
  125. rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
  126. rasa/nlu/extractors/crf_entity_extractor.py +50 -93
  127. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +16 -45
  128. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +17 -52
  129. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
  130. rasa/nlu/tokenizers/whitespace_tokenizer.py +14 -3
  131. rasa/server.py +1 -3
  132. rasa/shared/constants.py +0 -61
  133. rasa/shared/core/constants.py +0 -9
  134. rasa/shared/core/domain.py +5 -8
  135. rasa/shared/core/flows/flow.py +0 -5
  136. rasa/shared/core/flows/flows_list.py +1 -5
  137. rasa/shared/core/flows/flows_yaml_schema.json +0 -10
  138. rasa/shared/core/flows/validation.py +0 -96
  139. rasa/shared/core/flows/yaml_flows_io.py +4 -13
  140. rasa/shared/core/slots.py +0 -5
  141. rasa/shared/importers/importer.py +2 -19
  142. rasa/shared/importers/rasa.py +1 -5
  143. rasa/shared/nlu/training_data/features.py +2 -120
  144. rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -18
  145. rasa/shared/providers/_configs/azure_openai_client_config.py +3 -5
  146. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  147. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +0 -1
  148. rasa/shared/providers/_configs/utils.py +0 -16
  149. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +29 -18
  150. rasa/shared/providers/embedding/azure_openai_embedding_client.py +21 -54
  151. rasa/shared/providers/embedding/default_litellm_embedding_client.py +0 -24
  152. rasa/shared/providers/llm/_base_litellm_client.py +31 -63
  153. rasa/shared/providers/llm/azure_openai_llm_client.py +29 -50
  154. rasa/shared/providers/llm/default_litellm_llm_client.py +0 -24
  155. rasa/shared/providers/llm/self_hosted_llm_client.py +29 -17
  156. rasa/shared/providers/mappings.py +0 -19
  157. rasa/shared/utils/common.py +2 -37
  158. rasa/shared/utils/io.py +6 -28
  159. rasa/shared/utils/llm.py +46 -353
  160. rasa/shared/utils/yaml.py +82 -181
  161. rasa/studio/auth.py +5 -3
  162. rasa/studio/config.py +4 -13
  163. rasa/studio/constants.py +0 -1
  164. rasa/studio/data_handler.py +4 -13
  165. rasa/studio/upload.py +80 -175
  166. rasa/telemetry.py +17 -94
  167. rasa/tracing/config.py +1 -3
  168. rasa/tracing/instrumentation/attribute_extractors.py +17 -94
  169. rasa/tracing/instrumentation/instrumentation.py +0 -121
  170. rasa/utils/common.py +0 -5
  171. rasa/utils/endpoints.py +1 -27
  172. rasa/utils/io.py +81 -7
  173. rasa/utils/log_utils.py +2 -9
  174. rasa/utils/tensorflow/model_data.py +193 -2
  175. rasa/validator.py +4 -110
  176. rasa/version.py +1 -1
  177. rasa_pro-3.11.0a2.dist-info/METADATA +576 -0
  178. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/RECORD +181 -213
  179. rasa/core/actions/action_repeat_bot_messages.py +0 -89
  180. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +0 -1
  181. rasa/core/channels/voice_stream/asr/azure.py +0 -129
  182. rasa/core/channels/voice_stream/call_state.py +0 -23
  183. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +0 -60
  184. rasa/dialogue_understanding/commands/user_silence_command.py +0 -59
  185. rasa/dialogue_understanding/patterns/repeat.py +0 -37
  186. rasa/dialogue_understanding/patterns/user_silence.py +0 -37
  187. rasa/model_manager/__init__.py +0 -0
  188. rasa/model_manager/config.py +0 -40
  189. rasa/model_manager/model_api.py +0 -559
  190. rasa/model_manager/runner_service.py +0 -286
  191. rasa/model_manager/socket_bridge.py +0 -146
  192. rasa/model_manager/studio_jwt_auth.py +0 -86
  193. rasa/model_manager/trainer_service.py +0 -325
  194. rasa/model_manager/utils.py +0 -87
  195. rasa/model_manager/warm_rasa_process.py +0 -187
  196. rasa/model_service.py +0 -112
  197. rasa/shared/core/flows/utils.py +0 -39
  198. rasa/shared/providers/_configs/litellm_router_client_config.py +0 -220
  199. rasa/shared/providers/_configs/model_group_config.py +0 -167
  200. rasa/shared/providers/_configs/rasa_llm_client_config.py +0 -73
  201. rasa/shared/providers/_utils.py +0 -79
  202. rasa/shared/providers/embedding/litellm_router_embedding_client.py +0 -135
  203. rasa/shared/providers/llm/litellm_router_llm_client.py +0 -182
  204. rasa/shared/providers/llm/rasa_llm_client.py +0 -112
  205. rasa/shared/providers/router/__init__.py +0 -0
  206. rasa/shared/providers/router/_base_litellm_router_client.py +0 -183
  207. rasa/shared/providers/router/router_client.py +0 -73
  208. rasa/shared/utils/health_check/__init__.py +0 -0
  209. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +0 -31
  210. rasa/shared/utils/health_check/health_check.py +0 -258
  211. rasa/shared/utils/health_check/llm_health_check_mixin.py +0 -31
  212. rasa/utils/sanic_error_handler.py +0 -32
  213. rasa/utils/tensorflow/feature_array.py +0 -366
  214. rasa_pro-3.11.0.dist-info/METADATA +0 -198
  215. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/NOTICE +0 -0
  216. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/WHEEL +0 -0
  217. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/entry_points.txt +0 -0
@@ -16,13 +16,11 @@ from rasa.dialogue_understanding.commands import (
16
16
  KnowledgeAnswerCommand,
17
17
  ClarifyCommand,
18
18
  CannotHandleCommand,
19
- RepeatBotMessagesCommand,
20
19
  )
21
20
  from rasa.dialogue_understanding.generator.constants import (
22
21
  LLM_CONFIG_KEY,
23
22
  USER_INPUT_CONFIG_KEY,
24
23
  FLOW_RETRIEVAL_KEY,
25
- DEFAULT_LLM_CONFIG,
26
24
  )
27
25
  from rasa.dialogue_understanding.generator.flow_retrieval import (
28
26
  FlowRetrieval,
@@ -39,7 +37,6 @@ from rasa.shared.constants import (
39
37
  ROUTE_TO_CALM_SLOT,
40
38
  PROMPT_CONFIG_KEY,
41
39
  PROMPT_TEMPLATE_CONFIG_KEY,
42
- EMBEDDINGS_CONFIG_KEY,
43
40
  )
44
41
  from rasa.shared.core.flows import FlowsList
45
42
  from rasa.shared.core.trackers import DialogueStateTracker
@@ -51,9 +48,7 @@ from rasa.shared.utils.llm import (
51
48
  get_prompt_template,
52
49
  tracker_as_readable_transcript,
53
50
  sanitize_message_for_prompt,
54
- resolve_model_client_config,
55
51
  )
56
- from rasa.utils.beta import ensure_beta_feature_is_enabled, BetaNotEnabledException
57
52
  from rasa.utils.log_utils import log_llm
58
53
 
59
54
  COMMAND_PROMPT_FILE_NAME = "command_prompt.jinja2"
@@ -62,7 +57,6 @@ DEFAULT_COMMAND_PROMPT_TEMPLATE = importlib.resources.read_text(
62
57
  "rasa.dialogue_understanding.generator.single_step",
63
58
  "command_prompt_template.jinja2",
64
59
  )
65
- SINGLE_STEP_LLM_COMMAND_GENERATOR_CONFIG_FILE = "config.json"
66
60
 
67
61
  structlogger = structlog.get_logger()
68
62
 
@@ -113,7 +107,6 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
113
107
  )
114
108
 
115
109
  self.trace_prompt_tokens = self.config.get("trace_prompt_tokens", False)
116
- self.repeat_command_enabled = self.is_repeat_command_enabled()
117
110
 
118
111
  ### Implementations of LLMBasedCommandGenerator parent
119
112
  @staticmethod
@@ -137,21 +130,10 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
137
130
  **kwargs: Any,
138
131
  ) -> "SingleStepLLMCommandGenerator":
139
132
  """Loads trained component (see parent class for full docstring)."""
140
-
141
- # Perform health check of the LLM API endpoint
142
- llm_config = resolve_model_client_config(config.get(LLM_CONFIG_KEY, {}))
143
- cls.perform_llm_health_check(
144
- llm_config,
145
- DEFAULT_LLM_CONFIG,
146
- "single_step_llm_command_generator.load",
147
- SingleStepLLMCommandGenerator.__name__,
148
- )
149
-
150
133
  # load prompt template from the model storage.
151
134
  prompt_template = cls.load_prompt_template_from_model_storage(
152
135
  model_storage, resource, COMMAND_PROMPT_FILE_NAME
153
136
  )
154
-
155
137
  # init base command generator
156
138
  command_generator = cls(config, model_storage, resource, prompt_template)
157
139
  # load flow retrieval if enabled
@@ -159,29 +141,18 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
159
141
  command_generator.flow_retrieval = cls.load_flow_retrival(
160
142
  command_generator.config, model_storage, resource
161
143
  )
162
-
163
144
  return command_generator
164
145
 
165
146
  def persist(self) -> None:
166
147
  """Persist this component to disk for future loading."""
167
- self._persist_prompt_template()
168
- self._persist_config()
169
- if self.flow_retrieval is not None:
170
- self.flow_retrieval.persist()
171
-
172
- def _persist_prompt_template(self) -> None:
173
- """Persist prompt template for future loading."""
148
+ # persist prompt template
174
149
  with self._model_storage.write_to(self._resource) as path:
175
150
  rasa.shared.utils.io.write_text_file(
176
151
  self.prompt_template, path / COMMAND_PROMPT_FILE_NAME
177
152
  )
178
-
179
- def _persist_config(self) -> None:
180
- """Persist config as a source of truth for resolved clients."""
181
- with self._model_storage.write_to(self._resource) as path:
182
- rasa.shared.utils.io.dump_obj_as_json_to_file(
183
- path / SINGLE_STEP_LLM_COMMAND_GENERATOR_CONFIG_FILE, self.config
184
- )
153
+ # persist flow retrieval
154
+ if self.flow_retrieval is not None:
155
+ self.flow_retrieval.persist()
185
156
 
186
157
  async def predict_commands(
187
158
  self,
@@ -214,12 +185,6 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
214
185
 
215
186
  if not commands:
216
187
  # no commands are parsed or there's an invalid command
217
- structlogger.warning(
218
- "single_step_llm_command_generator.predict_commands",
219
- message="No commands were predicted as the LLM response could "
220
- "not be parsed or the LLM responded with an invalid command."
221
- "Returning a CannotHandleCommand instead.",
222
- )
223
188
  commands = [CannotHandleCommand()]
224
189
 
225
190
  if tracker.has_coexistence_routing_slot:
@@ -320,17 +285,14 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
320
285
 
321
286
  commands: List[Command] = []
322
287
 
323
- slot_set_re = re.compile(
324
- r"""SetSlot\(['"]?([a-zA-Z_][a-zA-Z0-9_-]*)['"]?, ?['"]?(.*)['"]?\)"""
325
- )
326
- start_flow_re = re.compile(r"StartFlow\(['\"]?([a-zA-Z0-9_-]+)['\"]?\)")
288
+ slot_set_re = re.compile(r"""SetSlot\(([a-zA-Z_][a-zA-Z0-9_-]*?), ?(.*)\)""")
289
+ start_flow_re = re.compile(r"StartFlow\(([a-zA-Z0-9_-]+?)\)")
327
290
  cancel_flow_re = re.compile(r"CancelFlow\(\)")
328
291
  chitchat_re = re.compile(r"ChitChat\(\)")
329
292
  skip_question_re = re.compile(r"SkipQuestion\(\)")
330
293
  knowledge_re = re.compile(r"SearchAndReply\(\)")
331
294
  humand_handoff_re = re.compile(r"HumanHandoff\(\)")
332
- clarify_re = re.compile(r"Clarify\(([\"\'a-zA-Z0-9_, ]+)\)")
333
- repeat_re = re.compile(r"RepeatLastBotMessages\(\)")
295
+ clarify_re = re.compile(r"Clarify\(([a-zA-Z0-9_, ]+)\)")
334
296
 
335
297
  for action in actions.strip().splitlines():
336
298
  if match := slot_set_re.search(action):
@@ -357,40 +319,21 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
357
319
  commands.append(KnowledgeAnswerCommand())
358
320
  elif humand_handoff_re.search(action):
359
321
  commands.append(HumanHandoffCommand())
360
- elif repeat_re.search(action):
361
- commands.append(RepeatBotMessagesCommand())
362
322
  elif match := clarify_re.search(action):
363
323
  options = sorted([opt.strip() for opt in match.group(1).split(",")])
364
- # Remove surrounding quotes if present
365
- cleaned_options = []
366
- for flow in options:
367
- if (flow.startswith('"') and flow.endswith('"')) or (
368
- flow.startswith("'") and flow.endswith("'")
369
- ):
370
- cleaned_options.append(flow[1:-1])
371
- else:
372
- cleaned_options.append(flow)
373
- # check if flow is valid
374
324
  valid_options = [
375
- flow for flow in cleaned_options if flow in flows.user_flow_ids
325
+ flow for flow in options if flow in flows.user_flow_ids
376
326
  ]
377
327
  if len(set(valid_options)) == 1:
378
328
  commands.extend(cls.start_flow_by_name(valid_options[0], flows))
379
329
  elif len(valid_options) > 1:
380
330
  commands.append(ClarifyCommand(valid_options))
381
331
 
382
- if not commands:
383
- structlogger.debug(
384
- "single_step_llm_command_generator.parse_commands",
385
- message="No commands were parsed from the LLM actions.",
386
- actions=actions,
387
- )
388
-
389
332
  return commands
390
333
 
391
334
  @classmethod
392
335
  def fingerprint_addon(cls: Any, config: Dict[str, Any]) -> Optional[str]:
393
- """Add a fingerprint for the graph."""
336
+ """Add a fingerprint of the knowledge base for the graph."""
394
337
  config_prompt = (
395
338
  config.get(PROMPT_CONFIG_KEY)
396
339
  or config.get(PROMPT_TEMPLATE_CONFIG_KEY)
@@ -400,16 +343,7 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
400
343
  config_prompt,
401
344
  DEFAULT_COMMAND_PROMPT_TEMPLATE,
402
345
  )
403
- llm_config = resolve_model_client_config(
404
- config.get(LLM_CONFIG_KEY), SingleStepLLMCommandGenerator.__name__
405
- )
406
- embedding_config = resolve_model_client_config(
407
- config.get(FLOW_RETRIEVAL_KEY, {}).get(EMBEDDINGS_CONFIG_KEY),
408
- FlowRetrieval.__name__,
409
- )
410
- return deep_container_fingerprint(
411
- [prompt_template, llm_config, embedding_config]
412
- )
346
+ return deep_container_fingerprint(prompt_template)
413
347
 
414
348
  ### Helper methods
415
349
  def render_template(
@@ -459,20 +393,6 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
459
393
  "current_slot": current_slot,
460
394
  "current_slot_description": current_slot_description,
461
395
  "user_message": latest_user_message,
462
- "is_repeat_command_enabled": self.repeat_command_enabled,
463
396
  }
464
397
 
465
398
  return self.compile_template(self.prompt_template).render(**inputs)
466
-
467
- def is_repeat_command_enabled(self) -> bool:
468
- """Check for feature flag"""
469
- RASA_PRO_BETA_REPEAT_COMMAND_ENV_VAR_NAME = "RASA_PRO_BETA_REPEAT_COMMAND"
470
- try:
471
- ensure_beta_feature_is_enabled(
472
- "Repeat Command",
473
- env_flag=RASA_PRO_BETA_REPEAT_COMMAND_ENV_VAR_NAME,
474
- )
475
- except BetaNotEnabledException:
476
- return False
477
-
478
- return True
@@ -4,11 +4,6 @@ responses:
4
4
  utter_ask_rephrase:
5
5
  - text: I’m sorry I am unable to understand you, could you please rephrase?
6
6
 
7
- utter_ask_still_there:
8
- - text: "Hello, are you still there?"
9
- metadata:
10
- rephrase: True
11
-
12
7
  utter_boolean_slot_rejection:
13
8
  - text: "Sorry, the value you provided, `{{value}}`, is not valid. Please respond with a valid value."
14
9
  metadata:
@@ -80,11 +75,6 @@ responses:
80
75
  metadata:
81
76
  rephrase: True
82
77
 
83
- utter_inform_hangup:
84
- - text: It seems you are not there anymore. I will hang up shortly.
85
- metadata:
86
- rephrase: True
87
-
88
78
  utter_internal_error_rasa:
89
79
  - text: Sorry, I am having trouble with that. Please try again in a few minutes.
90
80
 
@@ -111,15 +101,6 @@ slots:
111
101
  type: bool
112
102
  mappings:
113
103
  - type: from_llm
114
- silence_timeout:
115
- type: float
116
- initial_value: 6.0
117
- max_value: 1000000
118
- consecutive_silence_timeouts:
119
- type: float
120
- initial_value: 0.0
121
- max_value: 1000000
122
-
123
104
 
124
105
  flows:
125
106
  pattern_cancel_flow:
@@ -236,11 +217,6 @@ flows:
236
217
  - action: utter_internal_error_rasa
237
218
  next: END
238
219
 
239
- pattern_repeat_bot_messages:
240
- description: Voice conversation repair pattern to repeat bot messages
241
- name: pattern repeat bot messages
242
- steps:
243
- - action: action_repeat_bot_messages
244
220
 
245
221
  pattern_restart:
246
222
  description: Flow for restarting the conversation
@@ -270,32 +246,3 @@ flows:
270
246
  name: pattern skip question
271
247
  steps:
272
248
  - action: utter_skip_question_answer
273
-
274
- pattern_user_silence:
275
- description: Reacting to user silence in voice bots
276
- name: pattern react to silence
277
- nlu_trigger:
278
- - intent: silence_timeout
279
- persisted_slots:
280
- - consecutive_silence_timeouts
281
- steps:
282
- - noop: true
283
- next:
284
- - if: "slots.consecutive_silence_timeouts = 0.0"
285
- then:
286
- - set_slots:
287
- - consecutive_silence_timeouts: 1.0
288
- - action: action_repeat_bot_messages
289
- next: END
290
- - if: "slots.consecutive_silence_timeouts = 1.0"
291
- then:
292
- - set_slots:
293
- - consecutive_silence_timeouts: 2.0
294
- - action: utter_ask_still_there
295
- next: END
296
- - if: "slots.consecutive_silence_timeouts > 1.0"
297
- then:
298
- - action: utter_inform_hangup
299
- - action: action_hangup
300
- next: END
301
- - else: END
@@ -8,7 +8,6 @@ from rasa.dialogue_understanding.commands import (
8
8
  Command,
9
9
  CorrectSlotsCommand,
10
10
  CorrectedSlot,
11
- RepeatBotMessagesCommand,
12
11
  SetSlotCommand,
13
12
  StartFlowCommand,
14
13
  FreeFormAnswerCommand,
@@ -423,9 +422,6 @@ def clean_up_commands(
423
422
  elif not tracker.has_coexistence_routing_slot and len(clean_commands) > 1:
424
423
  clean_commands = filter_cannot_handle_command_for_skipped_slots(clean_commands)
425
424
 
426
- clean_commands = ensure_max_number_of_command_type(
427
- clean_commands, RepeatBotMessagesCommand, 1
428
- )
429
425
  structlogger.debug(
430
426
  "command_processor.clean_up_commands.final_commands",
431
427
  command=clean_commands,
@@ -434,22 +430,6 @@ def clean_up_commands(
434
430
  return clean_commands
435
431
 
436
432
 
437
- def ensure_max_number_of_command_type(
438
- commands: List[Command], command_type: Type[Command], n: int
439
- ) -> List[Command]:
440
- """Ensures that for a given command type only the first n stay in the list."""
441
- filtered: List[Command] = []
442
- count = 0
443
- for c in commands:
444
- if isinstance(c, command_type):
445
- if count >= n:
446
- continue
447
- else:
448
- count += 1
449
- filtered.append(c)
450
- return filtered
451
-
452
-
453
433
  def clean_up_clarify_command(
454
434
  commands_so_far: List[Command],
455
435
  all_commands: List[Command],
@@ -472,7 +452,7 @@ def clean_up_clarify_command(
472
452
  if not (isinstance(c, SetSlotCommand) and c.name == ROUTE_TO_CALM_SLOT)
473
453
  ]
474
454
 
475
- # if all commands are clarify commands, add the first one only, otherwise add none
455
+ # if there are multiple clarify commands, do add the first one
476
456
  if all(
477
457
  isinstance(c, ClarifyCommand) for c in commands_without_route_to_calm_set_slot
478
458
  ):
@@ -71,7 +71,6 @@ class AssertionType(Enum):
71
71
  SLOT_WAS_SET = "slot_was_set"
72
72
  SLOT_WAS_NOT_SET = "slot_was_not_set"
73
73
  BOT_UTTERED = "bot_uttered"
74
- BOT_DID_NOT_UTTER = "bot_did_not_utter"
75
74
  GENERATIVE_RESPONSE_IS_RELEVANT = "generative_response_is_relevant"
76
75
  GENERATIVE_RESPONSE_IS_GROUNDED = "generative_response_is_grounded"
77
76
 
@@ -723,7 +722,6 @@ class BotUtteredAssertion(Assertion):
723
722
  ) -> Tuple[Optional[AssertionFailure], Optional[Event]]:
724
723
  """Run the bot_uttered assertion on the given events for that user turn."""
725
724
  matching_event = None
726
- error_messages = []
727
725
 
728
726
  if self.utter_name is not None:
729
727
  try:
@@ -734,8 +732,11 @@ class BotUtteredAssertion(Assertion):
734
732
  and event.metadata.get("utter_action") == self.utter_name
735
733
  )
736
734
  except StopIteration:
737
- error_messages.append(
738
- f"Bot did not utter '{self.utter_name}' response."
735
+ error_message = f"Bot did not utter '{self.utter_name}' response."
736
+ error_message += assertion_order_error_message
737
+
738
+ return self._generate_assertion_failure(
739
+ error_message, prior_events, turn_events, self.line
739
740
  )
740
741
 
741
742
  if self.text_matches is not None:
@@ -747,11 +748,16 @@ class BotUtteredAssertion(Assertion):
747
748
  if isinstance(event, BotUttered) and pattern.search(event.text)
748
749
  )
749
750
  except StopIteration:
750
- error_messages.append(
751
+ error_message = (
751
752
  f"Bot did not utter any response which "
752
753
  f"matches the provided text pattern "
753
754
  f"'{self.text_matches}'."
754
755
  )
756
+ error_message += assertion_order_error_message
757
+
758
+ return self._generate_assertion_failure(
759
+ error_message, prior_events, turn_events, self.line
760
+ )
755
761
 
756
762
  if self.buttons:
757
763
  try:
@@ -761,16 +767,13 @@ class BotUtteredAssertion(Assertion):
761
767
  if isinstance(event, BotUttered) and self._buttons_match(event)
762
768
  )
763
769
  except StopIteration:
764
- error_messages.append(
770
+ error_message = (
765
771
  "Bot did not utter any response with the expected buttons."
766
772
  )
767
-
768
- if error_messages:
769
- error_message = " ".join(error_messages)
770
- error_message += assertion_order_error_message
771
- return self._generate_assertion_failure(
772
- error_message, prior_events, turn_events, self.line
773
- )
773
+ error_message += assertion_order_error_message
774
+ return self._generate_assertion_failure(
775
+ error_message, prior_events, turn_events, self.line
776
+ )
774
777
 
775
778
  return None, matching_event
776
779
 
@@ -800,126 +803,6 @@ class BotUtteredAssertion(Assertion):
800
803
  return hash(json.dumps(self.as_dict()))
801
804
 
802
805
 
803
- @dataclass
804
- class BotDidNotUtterAssertion(Assertion):
805
- """Class for the 'bot_did_not_utter' assertion."""
806
-
807
- utter_name: Optional[str] = None
808
- text_matches: Optional[str] = None
809
- buttons: Optional[List[AssertedButton]] = None
810
- line: Optional[int] = None
811
-
812
- @classmethod
813
- def type(cls) -> str:
814
- return AssertionType.BOT_DID_NOT_UTTER.value
815
-
816
- @staticmethod
817
- def from_dict(assertion_dict: Dict[Text, Any]) -> BotDidNotUtterAssertion:
818
- """Creates a BotDidNotUtterAssertion from a dictionary."""
819
- assertion_dict = assertion_dict.get(AssertionType.BOT_DID_NOT_UTTER.value, {})
820
- utter_name = assertion_dict.get("utter_name")
821
- text_matches = assertion_dict.get("text_matches")
822
- buttons = [
823
- AssertedButton.from_dict(button)
824
- for button in assertion_dict.get("buttons", [])
825
- ]
826
-
827
- if not utter_name and not text_matches and not buttons:
828
- raise RasaException(
829
- "A 'bot_did_not_utter' assertion is empty. "
830
- "It should contain at least one of the allowed properties: "
831
- "'utter_name', 'text_matches', or 'buttons'."
832
- )
833
-
834
- return BotDidNotUtterAssertion(
835
- utter_name=utter_name,
836
- text_matches=text_matches,
837
- buttons=buttons,
838
- line=assertion_dict.lc.line + 1 if hasattr(assertion_dict, "lc") else None,
839
- )
840
-
841
- def run(
842
- self,
843
- turn_events: List[Event],
844
- prior_events: List[Event],
845
- assertion_order_error_message: str = "",
846
- **kwargs: Any,
847
- ) -> Tuple[Optional[AssertionFailure], Optional[Event]]:
848
- """Checks that the bot did not utter the specified messages or buttons."""
849
- for event in turn_events:
850
- if isinstance(event, BotUttered):
851
- error_messages = []
852
- if self._utter_name_matches(event):
853
- error_messages.append(
854
- f"Bot uttered a forbidden utterance '{self.utter_name}'."
855
- )
856
- if self._text_matches(event):
857
- error_messages.append(
858
- f"Bot uttered a forbidden message matching "
859
- f"the pattern '{self.text_matches}'."
860
- )
861
- if self._buttons_match(event):
862
- error_messages.append(
863
- "Bot uttered a forbidden response with specified buttons."
864
- )
865
-
866
- if error_messages:
867
- error_message = " ".join(error_messages)
868
- error_message += assertion_order_error_message
869
- return self._generate_assertion_failure(
870
- error_message, prior_events, turn_events, self.line
871
- )
872
- return None, None
873
-
874
- def _utter_name_matches(self, event: BotUttered) -> bool:
875
- if self.utter_name is not None:
876
- if event.metadata.get("utter_action") == self.utter_name:
877
- return True
878
- return False
879
-
880
- def _text_matches(self, event: BotUttered) -> bool:
881
- if self.text_matches is not None:
882
- pattern = re.compile(self.text_matches)
883
- if pattern.search(event.text):
884
- return True
885
- return False
886
-
887
- def _buttons_match(self, event: BotUttered) -> bool:
888
- """Check if the bot response contains any of the forbidden buttons."""
889
- if self.buttons is None:
890
- return False
891
-
892
- actual_buttons = event.data.get("buttons", [])
893
- if not actual_buttons:
894
- return False
895
-
896
- for actual_button in actual_buttons:
897
- if any(
898
- self._is_forbidden_button(actual_button, forbidden_button)
899
- for forbidden_button in self.buttons
900
- ):
901
- return True
902
- return False
903
-
904
- @staticmethod
905
- def _is_forbidden_button(
906
- actual_button: Dict[str, Any], forbidden_button: AssertedButton
907
- ) -> bool:
908
- """Check if the button matches any of the forbidden buttons."""
909
- actual_title = actual_button.get("title")
910
- actual_payload = actual_button.get("payload")
911
-
912
- title_matches = forbidden_button.title == actual_title
913
- payload_matches = forbidden_button.payload == actual_payload
914
- if title_matches and payload_matches:
915
- return True
916
- return False
917
-
918
- def __hash__(self) -> int:
919
- """Hash method to ensure the assertion is hashable."""
920
- return hash(json.dumps(self.as_dict()))
921
-
922
-
923
806
  @dataclass
924
807
  class GenerativeResponseMixin(Assertion):
925
808
  """Mixin class for storing generative response assertions."""
@@ -83,29 +83,6 @@ schema;assertions:
83
83
  text_matches:
84
84
  type: str
85
85
  nullable: false
86
- bot_did_not_utter:
87
- type: map
88
- nullable: false
89
- mapping:
90
- utter_name:
91
- type: str
92
- nullable: false
93
- buttons:
94
- type: seq
95
- nullable: false
96
- matching: "all"
97
- sequence:
98
- - type: map
99
- mapping:
100
- title:
101
- type: str
102
- nullable: false
103
- payload:
104
- type: str
105
- nullable: false
106
- text_matches:
107
- type: str
108
- nullable: false
109
86
  generative_response_is_relevant:
110
87
  type: map
111
88
  mapping: