rasa-pro 3.11.0__py3-none-any.whl → 3.11.0a1__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 (220) 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 +7 -15
  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/__init__.py +0 -2
  31. rasa/core/channels/channel.py +0 -20
  32. rasa/core/channels/development_inspector.py +3 -10
  33. rasa/core/channels/inspector/dist/assets/{arc-bc141fb2.js → arc-86942a71.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-be2db283.js → c4Diagram-d0fbc5ce-b0290676.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-55366915.js → classDiagram-936ed81e-f6405f6e.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-bb529518.js → classDiagram-v2-c3cb15f1-ef61ac77.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-b0ec81d6.js → createText-62fc7601-f0411e58.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-6166330c.js → edges-f2ad444c-7dcc4f3b.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-5ccc6a8e.js → erDiagram-9d236eb7-e0c092d7.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-fca3bfe4.js → flowDb-1972c806-fba2e3ce.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4739080f.js → flowDiagram-7ea5b25a-7a70b71a.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-24a5f41a.js +1 -0
  43. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-7c1b0e0f.js → flowchart-elk-definition-abe16c3d-00a59b68.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-772fd050.js → ganttDiagram-9b5ea136-293c91fa.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-8eae1dc9.js → gitGraphDiagram-99d0ae7c-07b2d68c.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-f55afcdf.js → index-2c4b9a3b-bc959fbd.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{index-e7cef9de.js → index-3a8a5a28.js} +143 -143
  48. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-124d4a14.js → infoDiagram-736b4530-4a350f72.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-7c4fae44.js → journeyDiagram-df861f2b-af464fb7.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{layout-b9885fb6.js → layout-0071f036.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{line-7c59abb6.js → line-2f73cc83.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{linear-4776f780.js → linear-f014b4cc.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2332c46c.js → mindmap-definition-beec6740-d2426fb6.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-8fb39303.js → pieDiagram-dbbf0591-776f01a2.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-3c7180a2.js → quadrantDiagram-4d7f4fd6-82e00b57.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-e910bcb8.js → requirementDiagram-6fc4c22a-ea13c6bb.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-ead16c89.js → sankeyDiagram-8f13d901-1feca7e9.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-29a02a19.js → sequenceDiagram-b655622a-070c61d2.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-042b3137.js → stateDiagram-59f0c015-24f46263.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-2178c0f3.js → stateDiagram-v2-2b26beab-c9056051.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-23ffa4fc.js → styles-080da4f6-08abc34a.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-94f59763.js → styles-3dcbcfbf-bc74c25a.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-78a6bebc.js → styles-9c745c82-4e5d66de.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-eae2a6f6.js → svgDrawCommon-4835440b-849c4517.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-5c968d92.js → timeline-definition-5b62e21b-d0fb1598.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-fd3db0d5.js → xychartDiagram-2b33534f-04d115e2.js} +1 -1
  67. rasa/core/channels/inspector/dist/index.html +1 -1
  68. rasa/core/channels/inspector/src/App.tsx +1 -1
  69. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +3 -6
  70. rasa/core/channels/socketio.py +2 -7
  71. rasa/core/channels/telegram.py +1 -1
  72. rasa/core/channels/twilio.py +1 -1
  73. rasa/core/channels/voice_ready/audiocodes.py +4 -15
  74. rasa/core/channels/voice_ready/jambonz.py +4 -15
  75. rasa/core/channels/voice_ready/twilio_voice.py +21 -6
  76. rasa/core/channels/voice_ready/utils.py +5 -6
  77. rasa/core/channels/voice_stream/asr/asr_engine.py +1 -19
  78. rasa/core/channels/voice_stream/asr/asr_event.py +0 -5
  79. rasa/core/channels/voice_stream/asr/deepgram.py +15 -28
  80. rasa/core/channels/voice_stream/audio_bytes.py +0 -1
  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 +13 -89
  98. rasa/core/run.py +2 -2
  99. rasa/core/training/interactive.py +35 -34
  100. rasa/core/utils.py +22 -58
  101. rasa/dialogue_understanding/coexistence/llm_based_router.py +12 -39
  102. rasa/dialogue_understanding/commands/__init__.py +0 -4
  103. rasa/dialogue_understanding/commands/change_flow_command.py +0 -6
  104. rasa/dialogue_understanding/commands/utils.py +0 -5
  105. rasa/dialogue_understanding/generator/constants.py +0 -2
  106. rasa/dialogue_understanding/generator/flow_retrieval.py +4 -49
  107. rasa/dialogue_understanding/generator/llm_based_command_generator.py +23 -37
  108. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +10 -57
  109. rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -19
  110. rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +0 -3
  111. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +10 -90
  112. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +0 -53
  113. rasa/dialogue_understanding/processor/command_processor.py +1 -21
  114. rasa/e2e_test/assertions.py +16 -133
  115. rasa/e2e_test/assertions_schema.yml +0 -23
  116. rasa/e2e_test/e2e_test_case.py +6 -85
  117. rasa/e2e_test/e2e_test_runner.py +4 -6
  118. rasa/e2e_test/utils/io.py +1 -3
  119. rasa/engine/loader.py +0 -12
  120. rasa/engine/validation.py +11 -541
  121. rasa/keys +1 -0
  122. rasa/llm_fine_tuning/notebooks/unsloth_finetuning.ipynb +407 -0
  123. rasa/model_training.py +7 -29
  124. rasa/nlu/classifiers/diet_classifier.py +25 -38
  125. rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
  126. rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
  127. rasa/nlu/extractors/crf_entity_extractor.py +50 -93
  128. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +16 -45
  129. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +17 -52
  130. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
  131. rasa/nlu/tokenizers/whitespace_tokenizer.py +14 -3
  132. rasa/server.py +1 -3
  133. rasa/shared/constants.py +0 -61
  134. rasa/shared/core/constants.py +0 -9
  135. rasa/shared/core/domain.py +5 -8
  136. rasa/shared/core/flows/flow.py +0 -5
  137. rasa/shared/core/flows/flows_list.py +1 -5
  138. rasa/shared/core/flows/flows_yaml_schema.json +0 -10
  139. rasa/shared/core/flows/validation.py +0 -96
  140. rasa/shared/core/flows/yaml_flows_io.py +4 -13
  141. rasa/shared/core/slots.py +0 -5
  142. rasa/shared/importers/importer.py +2 -19
  143. rasa/shared/importers/rasa.py +1 -5
  144. rasa/shared/nlu/training_data/features.py +2 -120
  145. rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -18
  146. rasa/shared/providers/_configs/azure_openai_client_config.py +3 -5
  147. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  148. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +0 -1
  149. rasa/shared/providers/_configs/utils.py +0 -16
  150. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +29 -18
  151. rasa/shared/providers/embedding/azure_openai_embedding_client.py +21 -54
  152. rasa/shared/providers/embedding/default_litellm_embedding_client.py +0 -24
  153. rasa/shared/providers/llm/_base_litellm_client.py +31 -63
  154. rasa/shared/providers/llm/azure_openai_llm_client.py +29 -50
  155. rasa/shared/providers/llm/default_litellm_llm_client.py +0 -24
  156. rasa/shared/providers/llm/self_hosted_llm_client.py +29 -17
  157. rasa/shared/providers/mappings.py +0 -19
  158. rasa/shared/utils/common.py +2 -37
  159. rasa/shared/utils/io.py +6 -28
  160. rasa/shared/utils/llm.py +46 -353
  161. rasa/shared/utils/yaml.py +82 -181
  162. rasa/studio/auth.py +5 -3
  163. rasa/studio/config.py +4 -13
  164. rasa/studio/constants.py +0 -1
  165. rasa/studio/data_handler.py +4 -13
  166. rasa/studio/upload.py +80 -175
  167. rasa/telemetry.py +17 -94
  168. rasa/tracing/config.py +1 -3
  169. rasa/tracing/instrumentation/attribute_extractors.py +17 -94
  170. rasa/tracing/instrumentation/instrumentation.py +0 -121
  171. rasa/utils/common.py +0 -5
  172. rasa/utils/endpoints.py +1 -27
  173. rasa/utils/io.py +81 -7
  174. rasa/utils/log_utils.py +2 -9
  175. rasa/utils/tensorflow/model_data.py +193 -2
  176. rasa/validator.py +4 -110
  177. rasa/version.py +1 -1
  178. rasa_pro-3.11.0a1.dist-info/METADATA +576 -0
  179. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/RECORD +182 -216
  180. rasa/core/actions/action_repeat_bot_messages.py +0 -89
  181. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +0 -1
  182. rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -165
  183. rasa/core/channels/voice_stream/asr/azure.py +0 -129
  184. rasa/core/channels/voice_stream/browser_audio.py +0 -107
  185. rasa/core/channels/voice_stream/call_state.py +0 -23
  186. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +0 -60
  187. rasa/dialogue_understanding/commands/user_silence_command.py +0 -59
  188. rasa/dialogue_understanding/patterns/repeat.py +0 -37
  189. rasa/dialogue_understanding/patterns/user_silence.py +0 -37
  190. rasa/model_manager/__init__.py +0 -0
  191. rasa/model_manager/config.py +0 -40
  192. rasa/model_manager/model_api.py +0 -559
  193. rasa/model_manager/runner_service.py +0 -286
  194. rasa/model_manager/socket_bridge.py +0 -146
  195. rasa/model_manager/studio_jwt_auth.py +0 -86
  196. rasa/model_manager/trainer_service.py +0 -325
  197. rasa/model_manager/utils.py +0 -87
  198. rasa/model_manager/warm_rasa_process.py +0 -187
  199. rasa/model_service.py +0 -112
  200. rasa/shared/core/flows/utils.py +0 -39
  201. rasa/shared/providers/_configs/litellm_router_client_config.py +0 -220
  202. rasa/shared/providers/_configs/model_group_config.py +0 -167
  203. rasa/shared/providers/_configs/rasa_llm_client_config.py +0 -73
  204. rasa/shared/providers/_utils.py +0 -79
  205. rasa/shared/providers/embedding/litellm_router_embedding_client.py +0 -135
  206. rasa/shared/providers/llm/litellm_router_llm_client.py +0 -182
  207. rasa/shared/providers/llm/rasa_llm_client.py +0 -112
  208. rasa/shared/providers/router/__init__.py +0 -0
  209. rasa/shared/providers/router/_base_litellm_router_client.py +0 -183
  210. rasa/shared/providers/router/router_client.py +0 -73
  211. rasa/shared/utils/health_check/__init__.py +0 -0
  212. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +0 -31
  213. rasa/shared/utils/health_check/health_check.py +0 -258
  214. rasa/shared/utils/health_check/llm_health_check_mixin.py +0 -31
  215. rasa/utils/sanic_error_handler.py +0 -32
  216. rasa/utils/tensorflow/feature_array.py +0 -366
  217. rasa_pro-3.11.0.dist-info/METADATA +0 -198
  218. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/NOTICE +0 -0
  219. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/WHEEL +0 -0
  220. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/entry_points.txt +0 -0
@@ -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:
@@ -1,10 +1,8 @@
1
+ import logging
1
2
  from collections import OrderedDict
2
- from collections import defaultdict
3
3
  from dataclasses import dataclass
4
4
  from typing import Any, Dict, List, Optional, Text, Union
5
5
 
6
- import structlog
7
-
8
6
  from rasa.e2e_test.assertions import Assertion
9
7
  from rasa.e2e_test.constants import (
10
8
  KEY_ASSERTIONS,
@@ -22,11 +20,10 @@ from rasa.e2e_test.constants import (
22
20
  KEY_USER_INPUT,
23
21
  )
24
22
  from rasa.e2e_test.stub_custom_action import StubCustomAction
25
- from rasa.shared.constants import DOCS_BASE_URL
26
23
  from rasa.shared.core.events import BotUttered, SlotSet, UserUttered
27
24
  from rasa.shared.exceptions import RasaException
28
25
 
29
- structlogger = structlog.get_logger(__name__)
26
+ logger = logging.getLogger(__name__)
30
27
 
31
28
 
32
29
  @dataclass(frozen=True)
@@ -346,10 +343,9 @@ class ActualStepOutput:
346
343
  try:
347
344
  return self.user_uttered_events[0]
348
345
  except IndexError:
349
- structlogger.debug(
350
- "e2e_test_case.get_user_uttered_event.no_user_uttered_event",
351
- event_info=f"Could not find `UserUttered` event in the "
352
- f"ActualStepOutput: {self}",
346
+ logger.debug(
347
+ f"Could not find `UserUttered` event in the ActualStepOutput: "
348
+ f"{self}"
353
349
  )
354
350
  return None
355
351
  return None
@@ -399,7 +395,7 @@ class TestCase:
399
395
  else:
400
396
  steps.append(TestStep.from_dict(step))
401
397
 
402
- test_case = TestCase(
398
+ return TestCase(
403
399
  name=input_test_case.get(KEY_TEST_CASE, "default"),
404
400
  steps=steps,
405
401
  file=file,
@@ -409,81 +405,6 @@ class TestCase:
409
405
  fixture_names=input_test_case.get(KEY_FIXTURES),
410
406
  metadata_name=input_test_case.get(KEY_METADATA),
411
407
  )
412
- test_case.validate()
413
- return test_case
414
-
415
- def validate(self) -> None:
416
- """Validates the test case.
417
-
418
- This method calls all validation methods required for the test case.
419
- """
420
- if self.uses_assertions():
421
- self.validate_duplicate_user_messages_metadata()
422
-
423
- def validate_duplicate_user_messages_metadata(self) -> None:
424
- """Validates that duplicate user messages use metadata correctly.
425
-
426
- Ensures that each duplicate user message uses unique metadata.
427
-
428
- Raises warnings if any issues are found.
429
- """
430
- docs_link = (
431
- f"{DOCS_BASE_URL}/testing/e2e-testing-assertions/assertions-how-to-guide/"
432
- "#how-to-handle-duplicate-user-text-messages-in-the-same-test-case"
433
- )
434
- no_metadata_event_info = (
435
- "Test case '{name}' has duplicate user steps with text '{text}', "
436
- "and user step at line {line} lacks metadata. When using "
437
- "duplicate user messages, metadata should be set on each step to ensure "
438
- f"correct processing. Please refer to the documentation: {docs_link}"
439
- )
440
- non_unique_metadata_event_info = (
441
- "Test case '{name}' has duplicate user steps with text '{text}', "
442
- "and user step at line {line} has duplicate metadata "
443
- "name '{metadata_name}'. Metadata names should be unique for each user "
444
- "step among duplicates. This may cause issues in processing "
445
- f"user messages. Please refer to the documentation: {docs_link}"
446
- )
447
-
448
- # Use dict[str, list] structure to group steps by user message text to easily
449
- # identify and validate instances with duplicate messages and their metadata.
450
- message_steps = defaultdict(list)
451
-
452
- # Collect user steps by text
453
- for step in self.steps:
454
- if step.actor == KEY_USER_INPUT and step.text:
455
- message_steps[step.text].append(step)
456
-
457
- # Check for duplicate messages
458
- for text, steps in message_steps.items():
459
- if len(steps) <= 1:
460
- continue
461
-
462
- metadata_names_used = set()
463
- for step in steps:
464
- if not step.metadata_name:
465
- structlogger.warning(
466
- "e2e_test_case.validate_duplicate_user_messages_metadata.no_metadata",
467
- event_info=no_metadata_event_info.format(
468
- name=self.name,
469
- text=text,
470
- line=step.line,
471
- ),
472
- )
473
- break
474
- elif step.metadata_name in metadata_names_used:
475
- structlogger.warning(
476
- "e2e_test_case.validate_duplicate_user_messages_metadata.non_unique_metadata",
477
- event_info=non_unique_metadata_event_info.format(
478
- name=self.name,
479
- text=text,
480
- line=step.line,
481
- metadata_name=step.metadata_name,
482
- ),
483
- )
484
- break
485
- else:
486
- metadata_names_used.add(step.metadata_name)
487
408
 
488
409
  def as_dict(self) -> Dict[Text, Any]:
489
410
  """Returns the test case as a dictionary."""
@@ -136,7 +136,7 @@ class E2ETestRunner:
136
136
  return turns
137
137
 
138
138
  tracker = await self.agent.processor.fetch_tracker_with_initial_session(
139
- sender_id, output_channel=collector
139
+ sender_id
140
140
  )
141
141
  # turn -1 i used to contain events that happen during
142
142
  # the start of the session and before the first user message
@@ -190,11 +190,11 @@ class E2ETestRunner:
190
190
  error=f"Message handling timed out for user message '{step.text}'.",
191
191
  exc_info=True,
192
192
  )
193
- except Exception as exc:
193
+ except Exception:
194
194
  structlogger.error(
195
195
  "e2e_test_runner.run_prediction_loop",
196
196
  error=f"An exception occurred while handling "
197
- f"user message '{step.text}'. Error: {exc}",
197
+ f"user message '{step.text}'.",
198
198
  )
199
199
  tracker = await self.agent.tracker_store.retrieve(sender_id) # type: ignore[assignment]
200
200
  turns[position], event_cursor = self.get_actual_step_output(
@@ -826,7 +826,7 @@ class E2ETestRunner:
826
826
  return
827
827
 
828
828
  tracker = await self.agent.processor.fetch_tracker_with_initial_session(
829
- sender_id, output_channel=CollectingOutputChannel()
829
+ sender_id
830
830
  )
831
831
 
832
832
  for fixture in fixtures:
@@ -1155,8 +1155,6 @@ class E2ETestRunner:
1155
1155
  flow_paths_stack
1156
1156
  and self.agent.domain
1157
1157
  and self.agent.domain.is_custom_action(event.action_name)
1158
- and STEP_ID_METADATA_KEY in event.metadata
1159
- and ACTIVE_FLOW_METADATA_KEY in event.metadata
1160
1158
  ):
1161
1159
  flow_paths_stack[-1].nodes.append(self._create_path_node(event))
1162
1160
 
rasa/e2e_test/utils/io.py CHANGED
@@ -346,7 +346,7 @@ def read_test_cases(path: str) -> TestSuite:
346
346
  beta_flag_verified = False
347
347
 
348
348
  for test_file in test_files:
349
- test_file_content = parse_raw_yaml(Path(test_file).read_text(encoding="utf-8"))
349
+ test_file_content = parse_raw_yaml(Path(test_file).read_text())
350
350
 
351
351
  validate_yaml_data_using_schema_with_assertions(
352
352
  yaml_data=test_file_content, schema_content=e2e_test_schema
@@ -506,8 +506,6 @@ def transform_results_output_to_yaml(yaml_string: str) -> str:
506
506
  result.append(s)
507
507
  elif s.startswith("\n"):
508
508
  result.append(s.strip())
509
- elif s.strip().startswith("#"):
510
- continue
511
509
  else:
512
510
  result.append(s)
513
511
  return "".join(result)
rasa/engine/loader.py CHANGED
@@ -4,10 +4,6 @@ from typing import Tuple, Type
4
4
  from rasa.engine.graph import ExecutionContext
5
5
  from rasa.engine.runner.interface import GraphRunner
6
6
  from rasa.engine.storage.storage import ModelMetadata, ModelStorage
7
- from rasa.engine.validation import (
8
- validate_model_client_configuration_setup_during_inference_time,
9
- validate_model_group_configuration_setup,
10
- )
11
7
 
12
8
 
13
9
  def load_predict_graph_runner(
@@ -30,14 +26,6 @@ def load_predict_graph_runner(
30
26
  model_storage, model_metadata = model_storage_class.from_model_archive(
31
27
  storage_path=storage_path, model_archive_path=model_archive_path
32
28
  )
33
-
34
- # Components using LLMs or embeddings can reference model groups defined in
35
- # the endpoints.yml file for their client configurations. To ensure they will work
36
- # properly validate model group references before loading
37
- # the components.
38
- validate_model_group_configuration_setup()
39
- validate_model_client_configuration_setup_during_inference_time(model_metadata)
40
-
41
29
  runner = graph_runner_class.create(
42
30
  graph_schema=model_metadata.predict_schema,
43
31
  model_storage=model_storage,