rasa-pro 3.12.0.dev2__py3-none-any.whl → 3.12.0.dev4__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 (502) hide show
  1. rasa/__main__.py +7 -7
  2. rasa/anonymization/anonymisation_rule_yaml_reader.py +1 -1
  3. rasa/anonymization/anonymization_pipeline.py +3 -3
  4. rasa/anonymization/anonymization_rule_executor.py +1 -1
  5. rasa/anonymization/anonymization_rule_orchestrator.py +2 -3
  6. rasa/cli/arguments/data.py +2 -2
  7. rasa/cli/arguments/evaluate.py +2 -1
  8. rasa/cli/arguments/interactive.py +1 -1
  9. rasa/cli/arguments/run.py +1 -1
  10. rasa/cli/arguments/test.py +7 -5
  11. rasa/cli/arguments/train.py +3 -3
  12. rasa/cli/arguments/visualize.py +2 -2
  13. rasa/cli/arguments/x.py +1 -0
  14. rasa/cli/data.py +4 -3
  15. rasa/cli/dialogue_understanding_test.py +121 -18
  16. rasa/cli/evaluate.py +1 -1
  17. rasa/cli/export.py +6 -6
  18. rasa/cli/interactive.py +4 -5
  19. rasa/cli/llm_fine_tuning.py +5 -5
  20. rasa/cli/markers.py +1 -2
  21. rasa/cli/project_templates/calm/actions/add_contact.py +1 -1
  22. rasa/cli/project_templates/tutorial/actions/actions.py +3 -2
  23. rasa/cli/shell.py +2 -3
  24. rasa/cli/studio/download.py +1 -2
  25. rasa/cli/studio/studio.py +2 -3
  26. rasa/cli/studio/train.py +0 -1
  27. rasa/cli/telemetry.py +2 -2
  28. rasa/cli/test.py +11 -11
  29. rasa/cli/utils.py +7 -5
  30. rasa/core/__init__.py +0 -1
  31. rasa/core/actions/action.py +42 -21
  32. rasa/core/actions/action_hangup.py +1 -1
  33. rasa/core/actions/action_repeat_bot_messages.py +2 -2
  34. rasa/core/actions/action_run_slot_rejections.py +2 -2
  35. rasa/core/actions/action_trigger_chitchat.py +1 -1
  36. rasa/core/actions/action_trigger_flow.py +5 -5
  37. rasa/core/actions/action_trigger_search.py +1 -1
  38. rasa/core/actions/forms.py +14 -12
  39. rasa/core/actions/http_custom_action_executor.py +8 -1
  40. rasa/core/actions/loops.py +3 -3
  41. rasa/core/actions/two_stage_fallback.py +13 -13
  42. rasa/core/auth_retry_tracker_store.py +1 -2
  43. rasa/core/brokers/broker.py +2 -1
  44. rasa/core/brokers/file.py +1 -1
  45. rasa/core/brokers/kafka.py +8 -8
  46. rasa/core/brokers/pika.py +8 -9
  47. rasa/core/brokers/sql.py +4 -3
  48. rasa/core/channels/__init__.py +3 -0
  49. rasa/core/channels/botframework.py +2 -2
  50. rasa/core/channels/callback.py +4 -4
  51. rasa/core/channels/channel.py +11 -11
  52. rasa/core/channels/console.py +0 -1
  53. rasa/core/channels/development_inspector.py +6 -6
  54. rasa/core/channels/facebook.py +5 -5
  55. rasa/core/channels/hangouts.py +7 -8
  56. rasa/core/channels/inspector/dist/assets/{arc-861ddd57.js → arc-632a63ec.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-921f02db.js → c4Diagram-d0fbc5ce-081e0df4.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-b436c4f8.js → classDiagram-936ed81e-3df0afc2.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-511a23cb.js → classDiagram-v2-c3cb15f1-8c5ed31e.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-ef476ecd.js → createText-62fc7601-89c73b31.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-f1878e0a.js → edges-f2ad444c-4fc48c3e.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-fac75185.js → erDiagram-9d236eb7-907e0440.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-201c5bbc.js → flowDb-1972c806-9ec53a3c.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-f904ae41.js → flowDiagram-7ea5b25a-41da787a.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-8bea338b.js +1 -0
  66. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-1813da66.js → flowchart-elk-definition-abe16c3d-ce370633.js} +1 -1
  67. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-872af172.js → ganttDiagram-9b5ea136-90a36523.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-34a0af5a.js → gitGraphDiagram-99d0ae7c-41e1aa3f.js} +1 -1
  69. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-42ba3e3d.js → index-2c4b9a3b-e6f2af62.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/{index-37817b51.js → index-e793d777.js} +3 -3
  71. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-6b731386.js → infoDiagram-736b4530-8ceba4db.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-e8579ac6.js → journeyDiagram-df861f2b-960d3809.js} +1 -1
  73. rasa/core/channels/inspector/dist/assets/{layout-89e6403a.js → layout-498807d8.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/{line-dc73d3fc.js → line-eeccc4e2.js} +1 -1
  75. rasa/core/channels/inspector/dist/assets/{linear-f5b1d2bc.js → linear-8a078617.js} +1 -1
  76. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-82cb74fa.js → mindmap-definition-beec6740-396d17dd.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-bdf5f29b.js → pieDiagram-dbbf0591-dc9b5e1b.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-c7a0cbe4.js → quadrantDiagram-4d7f4fd6-a08cba6d.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-7ec5410f.js → requirementDiagram-6fc4c22a-87242b9e.js} +1 -1
  80. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-caee5554.js → sankeyDiagram-8f13d901-53f6f391.js} +1 -1
  81. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-2935f8db.js → sequenceDiagram-b655622a-715c9c20.js} +1 -1
  82. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-8f5d9693.js → stateDiagram-59f0c015-2e8fb31f.js} +1 -1
  83. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-d565d1de.js → stateDiagram-v2-2b26beab-7e2d2aa0.js} +1 -1
  84. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-75ad421d.js → styles-080da4f6-4420cea6.js} +1 -1
  85. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-7e764226.js → styles-3dcbcfbf-28676cf4.js} +1 -1
  86. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-7a4e0e61.js → styles-9c745c82-cef936a6.js} +1 -1
  87. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-4019d1bf.js → svgDrawCommon-4835440b-151251e9.js} +1 -1
  88. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-01ea12df.js → timeline-definition-5b62e21b-0d39bdb2.js} +1 -1
  89. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-89407137.js → xychartDiagram-2b33534f-a03fa445.js} +1 -1
  90. rasa/core/channels/inspector/dist/index.html +3 -1
  91. rasa/core/channels/inspector/index.html +2 -0
  92. rasa/core/channels/inspector/src/App.tsx +1 -4
  93. rasa/core/channels/mattermost.py +4 -4
  94. rasa/core/channels/rasa_chat.py +4 -4
  95. rasa/core/channels/rest.py +11 -12
  96. rasa/core/channels/rocketchat.py +4 -3
  97. rasa/core/channels/slack.py +6 -5
  98. rasa/core/channels/socketio.py +7 -28
  99. rasa/core/channels/studio_chat.py +193 -0
  100. rasa/core/channels/telegram.py +73 -41
  101. rasa/core/channels/twilio.py +3 -3
  102. rasa/core/channels/vier_cvg.py +2 -2
  103. rasa/core/channels/voice_ready/audiocodes.py +8 -8
  104. rasa/core/channels/voice_ready/jambonz.py +5 -5
  105. rasa/core/channels/voice_ready/jambonz_protocol.py +3 -4
  106. rasa/core/channels/voice_ready/twilio_voice.py +9 -8
  107. rasa/core/channels/voice_ready/utils.py +1 -1
  108. rasa/core/channels/voice_stream/asr/asr_engine.py +2 -2
  109. rasa/core/channels/voice_stream/asr/azure.py +2 -2
  110. rasa/core/channels/voice_stream/asr/deepgram.py +57 -16
  111. rasa/core/channels/voice_stream/browser_audio.py +9 -6
  112. rasa/core/channels/voice_stream/call_state.py +2 -1
  113. rasa/core/channels/voice_stream/tts/azure.py +1 -2
  114. rasa/core/channels/voice_stream/tts/cartesia.py +5 -4
  115. rasa/core/channels/voice_stream/tts/tts_cache.py +3 -2
  116. rasa/core/channels/voice_stream/tts/tts_engine.py +1 -1
  117. rasa/core/channels/voice_stream/twilio_media_streams.py +10 -7
  118. rasa/core/channels/voice_stream/util.py +1 -1
  119. rasa/core/channels/voice_stream/voice_channel.py +15 -15
  120. rasa/core/channels/webexteams.py +3 -4
  121. rasa/core/evaluation/marker.py +7 -6
  122. rasa/core/evaluation/marker_base.py +15 -16
  123. rasa/core/evaluation/marker_stats.py +3 -4
  124. rasa/core/evaluation/marker_tracker_loader.py +5 -4
  125. rasa/core/exporter.py +4 -4
  126. rasa/core/featurizers/precomputation.py +8 -8
  127. rasa/core/featurizers/single_state_featurizer.py +7 -7
  128. rasa/core/featurizers/tracker_featurizers.py +13 -13
  129. rasa/core/http_interpreter.py +3 -4
  130. rasa/core/information_retrieval/__init__.py +1 -1
  131. rasa/core/information_retrieval/faiss.py +4 -4
  132. rasa/core/information_retrieval/information_retrieval.py +2 -2
  133. rasa/core/information_retrieval/milvus.py +3 -3
  134. rasa/core/information_retrieval/qdrant.py +3 -3
  135. rasa/core/jobs.py +1 -0
  136. rasa/core/lock.py +2 -3
  137. rasa/core/lock_store.py +3 -3
  138. rasa/core/migrate.py +11 -8
  139. rasa/core/nlg/__init__.py +1 -1
  140. rasa/core/nlg/callback.py +2 -3
  141. rasa/core/nlg/contextual_response_rephraser.py +63 -13
  142. rasa/core/nlg/generator.py +2 -2
  143. rasa/core/nlg/interpolator.py +4 -3
  144. rasa/core/nlg/response.py +3 -4
  145. rasa/core/nlg/summarize.py +1 -0
  146. rasa/core/persistor.py +3 -3
  147. rasa/core/policies/ensemble.py +10 -9
  148. rasa/core/policies/enterprise_search_policy.py +86 -21
  149. rasa/core/policies/flow_policy.py +13 -14
  150. rasa/core/policies/flows/flow_executor.py +35 -11
  151. rasa/core/policies/intentless_policy.py +6 -7
  152. rasa/core/policies/memoization.py +22 -20
  153. rasa/core/policies/policy.py +24 -22
  154. rasa/core/policies/rule_policy.py +37 -36
  155. rasa/core/policies/ted_policy.py +87 -85
  156. rasa/core/policies/unexpected_intent_policy.py +77 -75
  157. rasa/core/processor.py +96 -65
  158. rasa/core/run.py +1 -1
  159. rasa/core/secrets_manager/endpoints.py +2 -3
  160. rasa/core/secrets_manager/factory.py +2 -3
  161. rasa/core/secrets_manager/secret_manager.py +2 -3
  162. rasa/core/secrets_manager/vault.py +2 -2
  163. rasa/core/test.py +30 -30
  164. rasa/core/tracker_store.py +15 -15
  165. rasa/core/train.py +1 -1
  166. rasa/core/training/__init__.py +2 -2
  167. rasa/core/training/converters/responses_prefix_converter.py +1 -2
  168. rasa/core/training/interactive.py +13 -13
  169. rasa/core/training/story_conflict.py +4 -5
  170. rasa/core/training/training.py +3 -5
  171. rasa/core/utils.py +5 -5
  172. rasa/core/visualize.py +1 -1
  173. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -2
  174. rasa/dialogue_understanding/coexistence/llm_based_router.py +5 -5
  175. rasa/dialogue_understanding/commands/__init__.py +22 -22
  176. rasa/dialogue_understanding/commands/can_not_handle_command.py +20 -1
  177. rasa/dialogue_understanding/commands/cancel_flow_command.py +18 -7
  178. rasa/dialogue_understanding/commands/change_flow_command.py +18 -2
  179. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +18 -4
  180. rasa/dialogue_understanding/commands/clarify_command.py +19 -3
  181. rasa/dialogue_understanding/commands/command.py +19 -3
  182. rasa/dialogue_understanding/commands/correct_slots_command.py +3 -3
  183. rasa/dialogue_understanding/commands/error_command.py +1 -1
  184. rasa/dialogue_understanding/commands/free_form_answer_command.py +2 -1
  185. rasa/dialogue_understanding/commands/handle_code_change_command.py +2 -2
  186. rasa/dialogue_understanding/commands/human_handoff_command.py +16 -4
  187. rasa/dialogue_understanding/commands/knowledge_answer_command.py +18 -4
  188. rasa/dialogue_understanding/commands/noop_command.py +2 -1
  189. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +16 -4
  190. rasa/dialogue_understanding/commands/restart_command.py +2 -5
  191. rasa/dialogue_understanding/commands/session_end_command.py +3 -5
  192. rasa/dialogue_understanding/commands/session_start_command.py +3 -5
  193. rasa/dialogue_understanding/commands/set_slot_command.py +27 -3
  194. rasa/dialogue_understanding/commands/skip_question_command.py +16 -4
  195. rasa/dialogue_understanding/commands/start_flow_command.py +17 -2
  196. rasa/dialogue_understanding/commands/user_silence_command.py +3 -5
  197. rasa/dialogue_understanding/commands/utils.py +64 -45
  198. rasa/dialogue_understanding/constants.py +1 -0
  199. rasa/dialogue_understanding/generator/command_generator.py +2 -119
  200. rasa/dialogue_understanding/generator/command_parser.py +201 -0
  201. rasa/dialogue_understanding/generator/constants.py +2 -2
  202. rasa/dialogue_understanding/generator/flow_retrieval.py +7 -7
  203. rasa/dialogue_understanding/generator/llm_based_command_generator.py +11 -57
  204. rasa/dialogue_understanding/generator/llm_command_generator.py +2 -1
  205. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +67 -120
  206. rasa/dialogue_understanding/generator/nlu_command_adapter.py +8 -10
  207. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +32 -93
  208. rasa/dialogue_understanding/generator/utils.py +45 -0
  209. rasa/dialogue_understanding/patterns/cancel.py +2 -1
  210. rasa/dialogue_understanding/patterns/cannot_handle.py +1 -0
  211. rasa/dialogue_understanding/patterns/chitchat.py +1 -1
  212. rasa/dialogue_understanding/patterns/clarify.py +2 -1
  213. rasa/dialogue_understanding/patterns/code_change.py +2 -0
  214. rasa/dialogue_understanding/patterns/collect_information.py +6 -3
  215. rasa/dialogue_understanding/patterns/completed.py +1 -1
  216. rasa/dialogue_understanding/patterns/continue_interrupted.py +10 -1
  217. rasa/dialogue_understanding/patterns/correction.py +4 -2
  218. rasa/dialogue_understanding/patterns/human_handoff.py +1 -1
  219. rasa/dialogue_understanding/patterns/internal_error.py +1 -0
  220. rasa/dialogue_understanding/patterns/search.py +1 -1
  221. rasa/dialogue_understanding/patterns/session_start.py +1 -1
  222. rasa/dialogue_understanding/patterns/skip_question.py +1 -0
  223. rasa/dialogue_understanding/patterns/user_silence.py +1 -1
  224. rasa/dialogue_understanding/processor/command_processor.py +13 -9
  225. rasa/dialogue_understanding/processor/command_processor_component.py +1 -1
  226. rasa/dialogue_understanding/stack/dialogue_stack.py +4 -3
  227. rasa/dialogue_understanding/stack/frames/__init__.py +2 -2
  228. rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +4 -1
  229. rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +2 -3
  230. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +5 -2
  231. rasa/dialogue_understanding/stack/frames/search_frame.py +4 -1
  232. rasa/dialogue_understanding/stack/utils.py +8 -4
  233. rasa/dialogue_understanding/utils.py +121 -2
  234. rasa/dialogue_understanding_test/README.md +379 -0
  235. rasa/dialogue_understanding_test/command_comparison.py +60 -0
  236. rasa/dialogue_understanding_test/command_metric_calculation.py +110 -4
  237. rasa/dialogue_understanding_test/constants.py +6 -1
  238. rasa/dialogue_understanding_test/du_test_case.py +252 -38
  239. rasa/dialogue_understanding_test/du_test_result.py +291 -2
  240. rasa/dialogue_understanding_test/du_test_runner.py +239 -10
  241. rasa/dialogue_understanding_test/du_test_schema.yml +161 -0
  242. rasa/dialogue_understanding_test/io.py +338 -20
  243. rasa/dialogue_understanding_test/test_case_simulation/__init__.py +0 -0
  244. rasa/dialogue_understanding_test/test_case_simulation/exception.py +28 -0
  245. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +336 -0
  246. rasa/dialogue_understanding_test/utils.py +70 -0
  247. rasa/dialogue_understanding_test/validation.py +59 -4
  248. rasa/e2e_test/aggregate_test_stats_calculator.py +1 -1
  249. rasa/e2e_test/assertions.py +1 -1
  250. rasa/e2e_test/e2e_config.py +1 -1
  251. rasa/e2e_test/e2e_test_case.py +3 -4
  252. rasa/e2e_test/e2e_test_converter.py +2 -3
  253. rasa/e2e_test/e2e_test_coverage_report.py +6 -6
  254. rasa/e2e_test/e2e_test_result.py +1 -1
  255. rasa/e2e_test/e2e_test_runner.py +134 -31
  256. rasa/e2e_test/stub_custom_action.py +1 -1
  257. rasa/e2e_test/utils/e2e_yaml_utils.py +1 -1
  258. rasa/e2e_test/utils/io.py +132 -65
  259. rasa/e2e_test/utils/validation.py +1 -1
  260. rasa/engine/caching.py +5 -7
  261. rasa/engine/constants.py +1 -1
  262. rasa/engine/graph.py +2 -2
  263. rasa/engine/recipes/default_components.py +13 -15
  264. rasa/engine/recipes/recipe.py +2 -2
  265. rasa/engine/runner/dask.py +2 -2
  266. rasa/engine/runner/interface.py +1 -0
  267. rasa/engine/storage/local_model_storage.py +5 -4
  268. rasa/engine/storage/resource.py +2 -1
  269. rasa/engine/storage/storage.py +5 -3
  270. rasa/engine/training/components.py +2 -1
  271. rasa/engine/training/fingerprinting.py +4 -2
  272. rasa/engine/training/graph_trainer.py +4 -4
  273. rasa/engine/training/hooks.py +2 -2
  274. rasa/engine/validation.py +34 -33
  275. rasa/exceptions.py +3 -2
  276. rasa/graph_components/converters/nlu_message_converter.py +3 -3
  277. rasa/graph_components/providers/domain_for_core_training_provider.py +3 -3
  278. rasa/graph_components/providers/domain_provider.py +3 -2
  279. rasa/graph_components/providers/flows_provider.py +2 -3
  280. rasa/graph_components/providers/forms_provider.py +4 -4
  281. rasa/graph_components/providers/nlu_training_data_provider.py +5 -3
  282. rasa/graph_components/providers/responses_provider.py +4 -4
  283. rasa/graph_components/providers/rule_only_provider.py +3 -2
  284. rasa/graph_components/providers/story_graph_provider.py +8 -8
  285. rasa/graph_components/providers/training_tracker_provider.py +3 -2
  286. rasa/graph_components/validators/default_recipe_validator.py +16 -16
  287. rasa/graph_components/validators/finetuning_validator.py +10 -8
  288. rasa/hooks.py +18 -12
  289. rasa/jupyter.py +2 -2
  290. rasa/llm_fine_tuning/annotation_module.py +4 -4
  291. rasa/llm_fine_tuning/conversations.py +6 -6
  292. rasa/llm_fine_tuning/llm_data_preparation_module.py +1 -1
  293. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -4
  294. rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +1 -1
  295. rasa/llm_fine_tuning/paraphrasing_module.py +1 -1
  296. rasa/llm_fine_tuning/storage.py +3 -3
  297. rasa/markers/marker.py +2 -3
  298. rasa/markers/marker_base.py +1 -2
  299. rasa/markers/upload.py +2 -2
  300. rasa/markers/validate.py +2 -3
  301. rasa/model.py +3 -5
  302. rasa/model_manager/config.py +1 -1
  303. rasa/model_manager/model_api.py +5 -4
  304. rasa/model_manager/runner_service.py +6 -6
  305. rasa/model_manager/socket_bridge.py +8 -3
  306. rasa/model_manager/studio_jwt_auth.py +1 -0
  307. rasa/model_manager/trainer_service.py +9 -7
  308. rasa/model_manager/utils.py +1 -1
  309. rasa/model_manager/warm_rasa_process.py +14 -8
  310. rasa/model_service.py +5 -6
  311. rasa/model_testing.py +13 -15
  312. rasa/nlu/classifiers/diet_classifier.py +72 -73
  313. rasa/nlu/classifiers/fallback_classifier.py +9 -11
  314. rasa/nlu/classifiers/keyword_intent_classifier.py +7 -6
  315. rasa/nlu/classifiers/logistic_regression_classifier.py +3 -3
  316. rasa/nlu/classifiers/mitie_intent_classifier.py +5 -4
  317. rasa/nlu/classifiers/regex_message_handler.py +3 -2
  318. rasa/nlu/classifiers/sklearn_intent_classifier.py +2 -2
  319. rasa/nlu/convert.py +2 -2
  320. rasa/nlu/emulators/dialogflow.py +3 -3
  321. rasa/nlu/emulators/luis.py +5 -5
  322. rasa/nlu/emulators/no_emulator.py +1 -0
  323. rasa/nlu/emulators/wit.py +4 -4
  324. rasa/nlu/extractors/crf_entity_extractor.py +11 -11
  325. rasa/nlu/extractors/duckling_entity_extractor.py +7 -6
  326. rasa/nlu/extractors/entity_synonyms.py +10 -9
  327. rasa/nlu/extractors/extractor.py +16 -16
  328. rasa/nlu/extractors/mitie_entity_extractor.py +10 -9
  329. rasa/nlu/extractors/regex_entity_extractor.py +11 -10
  330. rasa/nlu/extractors/spacy_entity_extractor.py +2 -2
  331. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +15 -14
  332. rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +2 -1
  333. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +10 -9
  334. rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +9 -7
  335. rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +13 -12
  336. rasa/nlu/featurizers/featurizer.py +5 -4
  337. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +6 -6
  338. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -4
  339. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +4 -4
  340. rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +2 -0
  341. rasa/nlu/model.py +0 -1
  342. rasa/nlu/selectors/response_selector.py +67 -68
  343. rasa/nlu/test.py +38 -38
  344. rasa/nlu/tokenizers/jieba_tokenizer.py +1 -2
  345. rasa/nlu/tokenizers/mitie_tokenizer.py +2 -2
  346. rasa/nlu/tokenizers/spacy_tokenizer.py +3 -3
  347. rasa/nlu/tokenizers/tokenizer.py +6 -7
  348. rasa/nlu/tokenizers/whitespace_tokenizer.py +1 -1
  349. rasa/nlu/utils/bilou_utils.py +7 -7
  350. rasa/nlu/utils/hugging_face/registry.py +22 -22
  351. rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +2 -1
  352. rasa/nlu/utils/mitie_utils.py +2 -1
  353. rasa/nlu/utils/pattern_utils.py +1 -1
  354. rasa/nlu/utils/spacy_utils.py +3 -3
  355. rasa/plugin.py +12 -1
  356. rasa/server.py +37 -1
  357. rasa/shared/constants.py +22 -2
  358. rasa/shared/core/command_payload_reader.py +15 -7
  359. rasa/shared/core/constants.py +4 -1
  360. rasa/shared/core/conversation.py +1 -2
  361. rasa/shared/core/events.py +47 -37
  362. rasa/shared/core/flows/__init__.py +0 -1
  363. rasa/shared/core/flows/flow.py +11 -11
  364. rasa/shared/core/flows/flow_step.py +19 -13
  365. rasa/shared/core/flows/flow_step_links.py +21 -14
  366. rasa/shared/core/flows/flow_step_sequence.py +6 -4
  367. rasa/shared/core/flows/flows_list.py +3 -3
  368. rasa/shared/core/flows/nlu_trigger.py +1 -1
  369. rasa/shared/core/flows/steps/__init__.py +2 -2
  370. rasa/shared/core/flows/steps/action.py +4 -3
  371. rasa/shared/core/flows/steps/call.py +4 -4
  372. rasa/shared/core/flows/steps/collect.py +7 -4
  373. rasa/shared/core/flows/steps/continuation.py +3 -1
  374. rasa/shared/core/flows/steps/end.py +3 -1
  375. rasa/shared/core/flows/steps/internal.py +3 -2
  376. rasa/shared/core/flows/steps/link.py +6 -4
  377. rasa/shared/core/flows/steps/no_operation.py +7 -5
  378. rasa/shared/core/flows/steps/set_slots.py +4 -3
  379. rasa/shared/core/flows/steps/start.py +3 -1
  380. rasa/shared/core/flows/utils.py +1 -0
  381. rasa/shared/core/flows/validation.py +3 -5
  382. rasa/shared/core/generator.py +20 -21
  383. rasa/shared/core/slot_mappings.py +15 -15
  384. rasa/shared/core/slots.py +3 -3
  385. rasa/shared/core/trackers.py +31 -31
  386. rasa/shared/core/training_data/loading.py +1 -1
  387. rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
  388. rasa/shared/core/training_data/story_reader/story_step_builder.py +4 -4
  389. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +29 -31
  390. rasa/shared/core/training_data/story_writer/yaml_story_writer.py +22 -24
  391. rasa/shared/core/training_data/structures.py +11 -12
  392. rasa/shared/core/training_data/visualization.py +10 -10
  393. rasa/shared/data.py +6 -6
  394. rasa/shared/engine/caching.py +0 -1
  395. rasa/shared/exceptions.py +2 -2
  396. rasa/shared/importers/rasa.py +5 -6
  397. rasa/shared/importers/utils.py +1 -1
  398. rasa/shared/nlu/constants.py +3 -0
  399. rasa/shared/nlu/training_data/entities_parser.py +6 -6
  400. rasa/shared/nlu/training_data/features.py +3 -3
  401. rasa/shared/nlu/training_data/formats/__init__.py +1 -1
  402. rasa/shared/nlu/training_data/formats/dialogflow.py +4 -5
  403. rasa/shared/nlu/training_data/formats/luis.py +7 -8
  404. rasa/shared/nlu/training_data/formats/rasa.py +4 -5
  405. rasa/shared/nlu/training_data/formats/rasa_yaml.py +17 -16
  406. rasa/shared/nlu/training_data/formats/readerwriter.py +8 -11
  407. rasa/shared/nlu/training_data/formats/wit.py +3 -4
  408. rasa/shared/nlu/training_data/loading.py +4 -4
  409. rasa/shared/nlu/training_data/lookup_tables_parser.py +1 -1
  410. rasa/shared/nlu/training_data/message.py +13 -14
  411. rasa/shared/nlu/training_data/schemas/data_schema.py +1 -1
  412. rasa/shared/nlu/training_data/schemas/responses.yml +1 -0
  413. rasa/shared/nlu/training_data/synonyms_parser.py +3 -3
  414. rasa/shared/nlu/training_data/training_data.py +12 -13
  415. rasa/shared/nlu/training_data/util.py +11 -10
  416. rasa/shared/providers/_configs/azure_openai_client_config.py +3 -119
  417. rasa/shared/providers/_configs/client_config.py +1 -3
  418. rasa/shared/providers/_configs/default_litellm_client_config.py +1 -3
  419. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -3
  420. rasa/shared/providers/_configs/litellm_router_client_config.py +1 -3
  421. rasa/shared/providers/_configs/model_group_config.py +2 -7
  422. rasa/shared/providers/_configs/openai_client_config.py +1 -3
  423. rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -3
  424. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -3
  425. rasa/shared/providers/_configs/utils.py +1 -0
  426. rasa/shared/providers/_ssl_verification_utils.py +5 -6
  427. rasa/shared/providers/_utils.py +5 -5
  428. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -1
  429. rasa/shared/providers/embedding/azure_openai_embedding_client.py +3 -26
  430. rasa/shared/providers/embedding/embedding_client.py +1 -1
  431. rasa/shared/providers/embedding/litellm_router_embedding_client.py +1 -3
  432. rasa/shared/providers/llm/_base_litellm_client.py +1 -3
  433. rasa/shared/providers/llm/azure_openai_llm_client.py +25 -79
  434. rasa/shared/providers/llm/default_litellm_llm_client.py +1 -3
  435. rasa/shared/providers/llm/litellm_router_llm_client.py +2 -21
  436. rasa/shared/providers/llm/llm_client.py +1 -3
  437. rasa/shared/providers/llm/llm_response.py +41 -2
  438. rasa/shared/providers/llm/openai_llm_client.py +3 -9
  439. rasa/shared/providers/llm/rasa_llm_client.py +6 -20
  440. rasa/shared/providers/llm/self_hosted_llm_client.py +3 -9
  441. rasa/shared/providers/mappings.py +18 -19
  442. rasa/shared/providers/router/_base_litellm_router_client.py +1 -3
  443. rasa/shared/providers/router/router_client.py +1 -3
  444. rasa/shared/utils/cli.py +1 -1
  445. rasa/shared/utils/common.py +1 -1
  446. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +1 -1
  447. rasa/shared/utils/health_check/health_check.py +3 -3
  448. rasa/shared/utils/health_check/llm_health_check_mixin.py +1 -1
  449. rasa/shared/utils/io.py +1 -1
  450. rasa/shared/utils/llm.py +5 -9
  451. rasa/shared/utils/pykwalify_extensions.py +1 -1
  452. rasa/shared/utils/schemas/events.py +1 -1
  453. rasa/shared/utils/yaml.py +29 -26
  454. rasa/studio/auth.py +3 -3
  455. rasa/studio/config.py +1 -2
  456. rasa/studio/data_handler.py +3 -3
  457. rasa/studio/download.py +1 -1
  458. rasa/studio/results_logger.py +3 -3
  459. rasa/studio/upload.py +2 -0
  460. rasa/telemetry.py +31 -0
  461. rasa/tracing/config.py +3 -3
  462. rasa/tracing/instrumentation/attribute_extractors.py +54 -0
  463. rasa/tracing/instrumentation/instrumentation.py +25 -5
  464. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +1 -1
  465. rasa/tracing/instrumentation/metrics.py +11 -11
  466. rasa/tracing/metric_instrument_provider.py +14 -14
  467. rasa/utils/common.py +12 -9
  468. rasa/utils/endpoints.py +1 -1
  469. rasa/utils/io.py +7 -7
  470. rasa/utils/licensing.py +3 -4
  471. rasa/utils/log_utils.py +7 -6
  472. rasa/utils/ml_utils.py +1 -0
  473. rasa/utils/plotting.py +3 -3
  474. rasa/utils/sanic_error_handler.py +1 -1
  475. rasa/utils/tensorflow/callback.py +2 -2
  476. rasa/utils/tensorflow/crf.py +2 -2
  477. rasa/utils/tensorflow/data_generator.py +5 -5
  478. rasa/utils/tensorflow/environment.py +3 -3
  479. rasa/utils/tensorflow/feature_array.py +2 -3
  480. rasa/utils/tensorflow/layers.py +18 -12
  481. rasa/utils/tensorflow/layers_utils.py +2 -1
  482. rasa/utils/tensorflow/metrics.py +2 -2
  483. rasa/utils/tensorflow/model_data.py +7 -7
  484. rasa/utils/tensorflow/model_data_utils.py +10 -9
  485. rasa/utils/tensorflow/models.py +31 -32
  486. rasa/utils/tensorflow/rasa_layers.py +20 -19
  487. rasa/utils/tensorflow/types.py +2 -1
  488. rasa/utils/train_utils.py +23 -21
  489. rasa/utils/url_tools.py +1 -1
  490. rasa/validator.py +17 -1
  491. rasa/version.py +1 -1
  492. {rasa_pro-3.12.0.dev2.dist-info → rasa_pro-3.12.0.dev4.dist-info}/METADATA +9 -10
  493. rasa_pro-3.12.0.dev4.dist-info/RECORD +800 -0
  494. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-b080d6f2.js +0 -1
  495. rasa/shared/providers/_configs/azure_entra_id_client_creds.py +0 -40
  496. rasa/shared/providers/_configs/azure_entra_id_config.py +0 -533
  497. rasa/shared/providers/_configs/oauth_config.py +0 -33
  498. rasa/shared/providers/constants.py +0 -6
  499. rasa_pro-3.12.0.dev2.dist-info/RECORD +0 -793
  500. {rasa_pro-3.12.0.dev2.dist-info → rasa_pro-3.12.0.dev4.dist-info}/NOTICE +0 -0
  501. {rasa_pro-3.12.0.dev2.dist-info → rasa_pro-3.12.0.dev4.dist-info}/WHEEL +0 -0
  502. {rasa_pro-3.12.0.dev2.dist-info → rasa_pro-3.12.0.dev4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,336 @@
1
+ from datetime import datetime
2
+ from typing import List, Optional
3
+
4
+ import structlog
5
+ from pydantic import BaseModel
6
+
7
+ from rasa.core.agent import Agent
8
+ from rasa.core.channels import CollectingOutputChannel, UserMessage
9
+ from rasa.dialogue_understanding.commands import Command, SetSlotCommand
10
+ from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
11
+ from rasa.dialogue_understanding_test.constants import (
12
+ PLACEHOLDER_GENERATED_ANSWER_TEMPLATE,
13
+ )
14
+ from rasa.dialogue_understanding_test.du_test_case import (
15
+ DialogueUnderstandingTestCase,
16
+ DialogueUnderstandingTestStep,
17
+ )
18
+ from rasa.dialogue_understanding_test.test_case_simulation.exception import (
19
+ TestCaseTrackerSimulatorException,
20
+ )
21
+ from rasa.dialogue_understanding_test.utils import filter_metadata
22
+ from rasa.e2e_test.e2e_test_case import Fixture, Metadata
23
+ from rasa.shared.core.constants import MAPPING_TYPE, SlotMappingType
24
+ from rasa.shared.core.events import BotUttered, SlotSet, UserUttered
25
+ from rasa.shared.core.trackers import DialogueStateTracker
26
+ from rasa.shared.nlu.constants import COMMANDS, ENTITIES, INTENT
27
+
28
+ structlogger = structlog.get_logger()
29
+
30
+
31
+ class TestCaseTrackerSimulatorResult(BaseModel):
32
+ sender_id: str
33
+ user_uttered_event_indices: List[int]
34
+
35
+
36
+ class TestCaseTrackerSimulator:
37
+ """Builds up a tracker for a test case.
38
+
39
+ The tracker is built up by simulating a conversation with the bot
40
+ using the user and bot steps of the test case.
41
+ As the user steps are annotated with commands, the user messages
42
+ are sent to the bot with the commands, i.e. skipping any LLM call.
43
+ """
44
+
45
+ def __init__(
46
+ self,
47
+ agent: Agent,
48
+ test_case: DialogueUnderstandingTestCase,
49
+ output_channel: Optional[CollectingOutputChannel] = None,
50
+ ):
51
+ self.agent = agent
52
+ self.test_case = test_case
53
+ self.output_channel = output_channel or CollectingOutputChannel()
54
+
55
+ self.sender_id = self._generate_sender_id()
56
+
57
+ async def simulate_test_case(
58
+ self,
59
+ metadata: List[Metadata],
60
+ ) -> TestCaseTrackerSimulatorResult:
61
+ """Simulates a conversation with the bot using the test case.
62
+
63
+ Args:
64
+ metadata: The available metadata.
65
+
66
+ Returns:
67
+ The result of the simulation.
68
+ """
69
+ step_index = 0
70
+ user_uttered_event_indices: List[int] = []
71
+
72
+ while step_index < len(self.test_case.steps):
73
+ user_step, bot_steps = self.test_case.get_next_user_and_bot_steps(
74
+ step_index
75
+ )
76
+ if user_step is None:
77
+ raise TestCaseTrackerSimulatorException(
78
+ test_case_name=self.test_case.full_name(),
79
+ failure_reason="Could not retrieve next user step.",
80
+ )
81
+
82
+ step_index += len(bot_steps) + 1 # for the user step
83
+
84
+ # we don't need to simulate the last user message
85
+ if step_index >= len(self.test_case.steps):
86
+ tracker = await self.agent.tracker_store.retrieve(self.sender_id)
87
+ if tracker is None:
88
+ raise TestCaseTrackerSimulatorException(
89
+ test_case_name=self.test_case.full_name(),
90
+ user_message=user_step.text,
91
+ failure_reason="The tracker could not be retrieved.",
92
+ )
93
+ # add the index of the last user uttered event
94
+ user_uttered_event_indices.append(len(tracker.events))
95
+
96
+ return TestCaseTrackerSimulatorResult(
97
+ sender_id=self.sender_id,
98
+ user_uttered_event_indices=user_uttered_event_indices,
99
+ )
100
+
101
+ # send the user message to the agent
102
+ try:
103
+ await self._send_user_message_with_commands(
104
+ user_step,
105
+ metadata,
106
+ )
107
+ except Exception as e:
108
+ raise TestCaseTrackerSimulatorException(
109
+ test_case_name=self.test_case.full_name(),
110
+ user_message=user_step.text,
111
+ failure_reason="Sending the user message failed.",
112
+ original_exception=e.__dict__,
113
+ )
114
+
115
+ tracker = await self.agent.tracker_store.retrieve(self.sender_id)
116
+ if tracker is None:
117
+ raise TestCaseTrackerSimulatorException(
118
+ test_case_name=self.test_case.full_name(),
119
+ user_message=user_step.text,
120
+ failure_reason="The tracker could not be retrieved.",
121
+ )
122
+
123
+ # add latest user uttered event index to the list
124
+ user_uttered_event_indices.append(
125
+ await self._get_latest_user_uttered_event_index(
126
+ tracker, user_uttered_event_indices
127
+ )
128
+ )
129
+
130
+ # check if bot responses match the expected bot steps
131
+ if not self._do_bot_responses_match(tracker, bot_steps):
132
+ structlogger.error(
133
+ "dialogue_understanding_test.tracker_simulator.stop_simulation.bot_utterance_mismatch",
134
+ test_case=self.test_case.full_name(),
135
+ user_message=user_step.text,
136
+ bot_steps=bot_steps,
137
+ bot_uttered_events=TestCaseTrackerSimulator._get_latest_bot_uttered_events(
138
+ tracker
139
+ ),
140
+ )
141
+ # stop the simulation if the bot responses do not match
142
+ # we can still test the steps up until the mismatch
143
+ return TestCaseTrackerSimulatorResult(
144
+ sender_id=self.sender_id,
145
+ user_uttered_event_indices=user_uttered_event_indices,
146
+ )
147
+
148
+ return TestCaseTrackerSimulatorResult(
149
+ sender_id=self.sender_id,
150
+ user_uttered_event_indices=user_uttered_event_indices,
151
+ )
152
+
153
+ def _generate_sender_id(self) -> str:
154
+ # add timestamp suffix to ensure sender_id is unique
155
+ return f"{self.test_case.name}_{datetime.now()}"
156
+
157
+ @staticmethod
158
+ async def _get_latest_user_uttered_event_index(
159
+ tracker: DialogueStateTracker, user_uttered_event_indices: List[int]
160
+ ) -> int:
161
+ """Get the index of the latest user uttered event in the tracker."""
162
+ # search the tracker events for the latest user message starting from the
163
+ # index of the user message before
164
+ # +1 to avoid getting the same index for duplicate user messages,
165
+ # such as, "yes"
166
+ from_index = (
167
+ user_uttered_event_indices[-1] + 1 if user_uttered_event_indices else 0
168
+ )
169
+ return tracker.events.index(tracker.latest_message, from_index)
170
+
171
+ def _do_bot_responses_match(
172
+ self,
173
+ tracker: DialogueStateTracker,
174
+ bot_steps: List[DialogueUnderstandingTestStep],
175
+ ) -> bool:
176
+ # get all bot uttered events until the last user message
177
+ bot_uttered_events = self._get_latest_bot_uttered_events(tracker)
178
+
179
+ if len(bot_uttered_events) != len(bot_steps):
180
+ return False
181
+
182
+ for step in bot_steps:
183
+ if step.template:
184
+ if not self._does_template_match(step, bot_uttered_events):
185
+ return False
186
+ elif step.text:
187
+ if not self._does_text_match(step, bot_uttered_events):
188
+ return False
189
+
190
+ return True
191
+
192
+ @staticmethod
193
+ def _does_template_match(
194
+ step: DialogueUnderstandingTestStep, bot_uttered_events: List[BotUttered]
195
+ ) -> bool:
196
+ for event in bot_uttered_events:
197
+ if step.template == PLACEHOLDER_GENERATED_ANSWER_TEMPLATE:
198
+ return True
199
+ elif "utter_action" not in event.metadata:
200
+ # a chitchat or knowledge base command was triggered,
201
+ # or the response comes from a custom action,
202
+ # continue with the simulation
203
+ return True
204
+ elif event.metadata["utter_action"] == step.template:
205
+ return True
206
+ return False
207
+
208
+ @staticmethod
209
+ def _does_text_match(
210
+ step: DialogueUnderstandingTestStep, bot_uttered_events: List[BotUttered]
211
+ ) -> bool:
212
+ for event in bot_uttered_events:
213
+ if event.text == step.text:
214
+ return True
215
+
216
+ return False
217
+
218
+ @staticmethod
219
+ def _get_latest_bot_uttered_events(
220
+ tracker: DialogueStateTracker,
221
+ ) -> List[BotUttered]:
222
+ """Get the latest bot uttered events in the tracker."""
223
+ # collect all bot uttered events until a user uttered event is reached
224
+ # starting from the end of the tracker events
225
+ bot_uttered_events = []
226
+ for event in reversed(tracker.events):
227
+ if isinstance(event, BotUttered):
228
+ bot_uttered_events.append(event)
229
+ if isinstance(event, UserUttered):
230
+ break
231
+ return bot_uttered_events
232
+
233
+ async def initialize_tracker(self, fixtures: List[Fixture]) -> None:
234
+ """Initializes a new tracker with fixtures."""
235
+ assert self.agent.processor is not None
236
+
237
+ tracker = await self.agent.processor.fetch_tracker_with_initial_session(
238
+ self.sender_id, output_channel=self.output_channel
239
+ )
240
+
241
+ if fixtures and self.test_case.fixture_names:
242
+ test_fixtures = self._filter_fixtures_for_test_case(
243
+ self.test_case.fixture_names, fixtures
244
+ )
245
+ await self._set_up_fixtures(test_fixtures, tracker)
246
+
247
+ # store the tracker with the unique sender id
248
+ await self.agent.tracker_store.save(tracker)
249
+
250
+ async def _set_up_fixtures(
251
+ self,
252
+ fixtures: List[Fixture],
253
+ tracker: DialogueStateTracker,
254
+ ) -> None:
255
+ """Sets up fixtures in the tracker."""
256
+ if not fixtures or not self.agent.processor:
257
+ return
258
+
259
+ for fixture in fixtures:
260
+ for slot_name, slot_value in fixture.slots_set.items():
261
+ tracker.update(SlotSet(slot_name, slot_value))
262
+
263
+ @staticmethod
264
+ def _filter_fixtures_for_test_case(
265
+ fixture_names: Optional[List[str]], fixtures: List[Fixture]
266
+ ) -> List[Fixture]:
267
+ """Filters fixtures applicable to the test case."""
268
+ return [
269
+ fixture
270
+ for fixture in fixtures
271
+ if fixture_names and fixture.name in fixture_names
272
+ ]
273
+
274
+ async def _send_user_message_with_commands(
275
+ self,
276
+ user_step: DialogueUnderstandingTestStep,
277
+ metadata: List[Metadata],
278
+ ) -> None:
279
+ """Sends a user message with commands to the agent."""
280
+ user_message = self._create_user_message(user_step, metadata)
281
+ await self.agent.handle_message(user_message)
282
+
283
+ def _create_user_message(
284
+ self,
285
+ user_step: DialogueUnderstandingTestStep,
286
+ metadata: List[Metadata],
287
+ ) -> UserMessage:
288
+ """Creates a user message with commands."""
289
+ user_message = user_step.text
290
+ # Get the metadata for the step
291
+ metadata_for_step = filter_metadata(
292
+ self.test_case, user_step, metadata, self.sender_id
293
+ )
294
+ # Update the extractor of SetSlotCommand based on the slot mapping type
295
+ commands = self._update_extractor_of_set_slot_commands(
296
+ user_step.commands, user_message
297
+ )
298
+
299
+ return UserMessage(
300
+ user_message,
301
+ self.output_channel,
302
+ self.sender_id,
303
+ parse_data={
304
+ INTENT: {},
305
+ ENTITIES: [],
306
+ COMMANDS: [command.as_dict() for command in commands],
307
+ },
308
+ metadata=metadata_for_step,
309
+ )
310
+
311
+ def _update_extractor_of_set_slot_commands(
312
+ self, commands: List[Command], user_message: str
313
+ ) -> List[Command]:
314
+ """Update the extractor for SetSlotCommand based on the slot mapping type."""
315
+ slots = []
316
+ if self.agent.domain is not None:
317
+ slots = self.agent.domain.slots
318
+
319
+ for command in commands:
320
+ if isinstance(command, SetSlotCommand):
321
+ slot_definition = next(
322
+ (slot for slot in slots if slot.name == command.name), slots[0]
323
+ )
324
+
325
+ # Use the SetSlotExtractor.COMMAND_PAYLOAD_READER extractor if the user
326
+ # message starts with the /SetSlot.
327
+ if user_message.startswith(r"/SetSlot"):
328
+ command.extractor = SetSlotExtractor.COMMAND_PAYLOAD_READER.value
329
+ # Use the SetSlotExtractor.NLU extractor if the slot mapping type is
330
+ # not FROM_LLM.
331
+ elif SlotMappingType.FROM_LLM.value not in [
332
+ mapping[MAPPING_TYPE] for mapping in slot_definition.mappings
333
+ ]:
334
+ command.extractor = SetSlotExtractor.NLU.value
335
+
336
+ return commands
@@ -0,0 +1,70 @@
1
+ from typing import Dict, List, Tuple
2
+
3
+ from rasa.dialogue_understanding_test.du_test_case import (
4
+ DialogueUnderstandingTestCase,
5
+ DialogueUnderstandingTestStep,
6
+ )
7
+ from rasa.e2e_test.e2e_test_case import Metadata
8
+ from rasa.e2e_test.e2e_test_runner import E2ETestRunner
9
+
10
+
11
+ def filter_metadata(
12
+ test_case: DialogueUnderstandingTestCase,
13
+ user_step: DialogueUnderstandingTestStep,
14
+ metadata: List[Metadata],
15
+ sender_id: str,
16
+ ) -> Dict[str, str]:
17
+ """Filter metadata for a test case and a step."""
18
+ # test case metadata
19
+ test_case_metadata = E2ETestRunner.filter_metadata_for_input(
20
+ test_case.metadata_name, metadata
21
+ )
22
+ test_case_metadata_dict = test_case_metadata.metadata if test_case_metadata else {}
23
+
24
+ # step metadata
25
+ step_metadata = E2ETestRunner.filter_metadata_for_input(
26
+ user_step.metadata_name, metadata
27
+ )
28
+ step_metadata_dict = step_metadata.metadata if step_metadata else {}
29
+
30
+ # merge metadata
31
+ return E2ETestRunner.merge_metadata(
32
+ sender_id, user_step.text, test_case_metadata_dict, step_metadata_dict
33
+ )
34
+
35
+
36
+ def get_command_comparison(step: DialogueUnderstandingTestStep) -> List[str]:
37
+ expected_commands = (
38
+ [command.to_dsl() for command in step.commands] if step.commands else []
39
+ )
40
+ predicted_commands = [command.to_dsl() for command in step.get_predicted_commands()]
41
+
42
+ expected_commands.insert(0, "---EXPECTED---")
43
+ predicted_commands.insert(0, "---PREDICTED---")
44
+
45
+ max_line_length = max(len(line) for line in expected_commands)
46
+ expected_commands, predicted_commands = make_lists_equal(
47
+ expected_commands, predicted_commands
48
+ )
49
+
50
+ command_comparison = []
51
+ for i, (expected_line, actual_line) in enumerate(
52
+ zip(expected_commands, predicted_commands)
53
+ ):
54
+ expected_line += " " * (max_line_length - len(expected_line))
55
+ if i == 0:
56
+ # make the first line red:
57
+ expected_line = "[red3]" + expected_line + "[/red3]"
58
+ actual_line = "[red3]" + actual_line + "[/red3]"
59
+ command_comparison.append(f"{expected_line} | {actual_line}")
60
+
61
+ return command_comparison
62
+
63
+
64
+ def make_lists_equal(list1: List[str], list2: List[str]) -> Tuple[List[str], List[str]]:
65
+ if len(list1) < len(list2):
66
+ list1.extend([""] * (len(list2) - len(list1)))
67
+ return list1, list2
68
+
69
+ list2.extend([""] * (len(list1) - len(list2)))
70
+ return list1, list2
@@ -1,7 +1,17 @@
1
1
  import argparse
2
- from typing import List
2
+ import sys
3
+ from typing import List, Optional
3
4
 
5
+ import structlog
6
+
7
+ from rasa.dialogue_understanding_test.constants import (
8
+ ACTOR_BOT,
9
+ PLACEHOLDER_GENERATED_ANSWER_TEMPLATE,
10
+ )
4
11
  from rasa.dialogue_understanding_test.du_test_case import DialogueUnderstandingTestCase
12
+ from rasa.shared.core.domain import Domain
13
+
14
+ structlogger = structlog.get_logger()
5
15
 
6
16
 
7
17
  def validate_cli_arguments(args: argparse.Namespace) -> None:
@@ -10,13 +20,58 @@ def validate_cli_arguments(args: argparse.Namespace) -> None:
10
20
  Args:
11
21
  args: Commandline arguments.
12
22
  """
13
- pass
23
+ # Model path, endpoints file path, and the path to test cases are validated
24
+ # in other places.
25
+ # Validate remote storage option
26
+ supported_remote_storages = ["aws", "gcs", "azure"]
27
+ if (
28
+ args.remote_storage
29
+ and args.remote_storage.lower() not in supported_remote_storages
30
+ ):
31
+ structlogger.error(
32
+ "dialogue_understanding_test.validate_cli_arguments.invalid_remote_storage",
33
+ event_info=(
34
+ f"Invalid remote storage option - '{args.remote_storage}'. Supported "
35
+ f"options are: {supported_remote_storages}"
36
+ ),
37
+ )
38
+ sys.exit(1)
14
39
 
15
40
 
16
- def validate_test_cases(test_cases: List[DialogueUnderstandingTestCase]) -> None:
41
+ def validate_test_cases(
42
+ test_cases: List[DialogueUnderstandingTestCase], domain: Optional[Domain]
43
+ ) -> None:
17
44
  """Validate the dialogue understanding test cases.
18
45
 
19
46
  Args:
20
47
  test_cases: Test cases to validate.
48
+ domain: Domain of the assistant.
21
49
  """
22
- pass
50
+ if not domain:
51
+ structlogger.error(
52
+ "dialogue_understanding_test.validate_test_cases.no_domain",
53
+ event_info="No domain found. Retrain the model with a valid domain.",
54
+ )
55
+ sys.exit(1)
56
+
57
+ # Retrieve all valid templates from the domain
58
+ valid_templates = domain.utterances_for_response
59
+
60
+ # Add 'placeholder_generated_answer' as a valid template
61
+ valid_templates.add(PLACEHOLDER_GENERATED_ANSWER_TEMPLATE)
62
+
63
+ for test_case in test_cases:
64
+ for step in test_case.steps:
65
+ if step.actor == ACTOR_BOT and step.template:
66
+ if step.template not in valid_templates:
67
+ structlogger.error(
68
+ "dialogue_understanding_test.validate_test_cases.invalid_template",
69
+ event_info=(
70
+ f"Invalid bot utterance template '{step.template}' in test "
71
+ f"case '{test_case.name}' at line {step.line}. Please "
72
+ f"the template exists."
73
+ ),
74
+ test_case=test_case.name,
75
+ template=step.template,
76
+ )
77
+ sys.exit(1)
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass
2
- from typing import List, Optional, Set, TYPE_CHECKING
2
+ from typing import TYPE_CHECKING, List, Optional, Set
3
3
 
4
4
  import structlog
5
5
 
@@ -7,13 +7,13 @@ from dataclasses import dataclass
7
7
  from enum import Enum
8
8
  from functools import lru_cache
9
9
  from typing import (
10
+ TYPE_CHECKING,
10
11
  Any,
11
12
  Callable,
12
13
  Dict,
13
14
  List,
14
15
  Optional,
15
16
  Set,
16
- TYPE_CHECKING,
17
17
  Text,
18
18
  Tuple,
19
19
  Type,
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import dataclasses
4
4
  from dataclasses import dataclass
5
5
  from pathlib import Path
6
- from typing import Generator, Optional, Dict, Any
6
+ from typing import Any, Dict, Generator, Optional
7
7
 
8
8
  import structlog
9
9
  from pydantic import BaseModel
@@ -1,5 +1,4 @@
1
- from collections import OrderedDict
2
- from collections import defaultdict
1
+ from collections import OrderedDict, defaultdict
3
2
  from dataclasses import dataclass
4
3
  from typing import Any, Dict, List, Optional, Text, Union
5
4
 
@@ -8,16 +7,16 @@ import structlog
8
7
  from rasa.dialogue_understanding_test.du_test_case import DialogueUnderstandingTestCase
9
8
  from rasa.e2e_test.assertions import Assertion
10
9
  from rasa.e2e_test.constants import (
11
- KEY_ASSERTIONS,
12
10
  KEY_ASSERTION_ORDER_ENABLED,
11
+ KEY_ASSERTIONS,
13
12
  KEY_BOT_INPUT,
14
13
  KEY_BOT_UTTERED,
15
14
  KEY_FIXTURES,
16
15
  KEY_METADATA,
17
- KEY_STUB_CUSTOM_ACTIONS,
18
16
  KEY_SLOT_NOT_SET,
19
17
  KEY_SLOT_SET,
20
18
  KEY_STEPS,
19
+ KEY_STUB_CUSTOM_ACTIONS,
21
20
  KEY_TEST_CASE,
22
21
  KEY_TEST_CASES,
23
22
  KEY_USER_INPUT,
@@ -5,8 +5,7 @@ from dataclasses import dataclass, field
5
5
  from importlib.resources import read_text
6
6
  from pathlib import Path
7
7
  from textwrap import dedent
8
- from typing import List, Dict, Any
9
- from typing import Optional
8
+ from typing import Any, Dict, List, Optional
10
9
 
11
10
  import pandas as pd
12
11
  import ruamel
@@ -21,8 +20,8 @@ from rasa.e2e_test.utils.validation import read_e2e_test_schema
21
20
  from rasa.exceptions import RasaException
22
21
  from rasa.shared.utils.llm import llm_factory
23
22
  from rasa.shared.utils.yaml import (
24
- validate_yaml_data_using_schema_with_assertions,
25
23
  YamlValidationException,
24
+ validate_yaml_data_using_schema_with_assertions,
26
25
  )
27
26
 
28
27
  structlogger = structlog.get_logger()
@@ -1,17 +1,17 @@
1
- from typing import List, Dict, Any, Optional, Set
1
+ from typing import Any, Dict, List, Optional, Set
2
2
 
3
3
  import pandas as pd
4
4
  import structlog
5
5
 
6
6
  from rasa.dialogue_understanding.commands import (
7
- KnowledgeAnswerCommand,
8
- StartFlowCommand,
9
- SetSlotCommand,
10
- ClarifyCommand,
11
- HumanHandoffCommand,
12
7
  CancelFlowCommand,
13
8
  ChitChatAnswerCommand,
9
+ ClarifyCommand,
10
+ HumanHandoffCommand,
11
+ KnowledgeAnswerCommand,
12
+ SetSlotCommand,
14
13
  SkipQuestionCommand,
14
+ StartFlowCommand,
15
15
  )
16
16
  from rasa.e2e_test.e2e_test_result import TestResult
17
17
  from rasa.shared.core.flows import FlowsList
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass
2
- from typing import Any, Dict, List, Optional, TYPE_CHECKING, Text
2
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text
3
3
 
4
4
  if TYPE_CHECKING:
5
5
  from rasa.e2e_test.assertions import AssertionFailure