rasa-pro 3.11.4__py3-none-any.whl → 3.12.0__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 (580) hide show
  1. README.md +10 -13
  2. rasa/__main__.py +7 -7
  3. rasa/anonymization/anonymisation_rule_yaml_reader.py +1 -1
  4. rasa/anonymization/anonymization_pipeline.py +3 -3
  5. rasa/anonymization/anonymization_rule_executor.py +17 -11
  6. rasa/anonymization/anonymization_rule_orchestrator.py +2 -3
  7. rasa/cli/arguments/data.py +2 -2
  8. rasa/cli/arguments/default_arguments.py +1 -1
  9. rasa/cli/arguments/evaluate.py +2 -1
  10. rasa/cli/arguments/interactive.py +1 -1
  11. rasa/cli/arguments/run.py +1 -1
  12. rasa/cli/arguments/test.py +7 -5
  13. rasa/cli/arguments/train.py +3 -3
  14. rasa/cli/arguments/visualize.py +2 -2
  15. rasa/cli/arguments/x.py +1 -0
  16. rasa/cli/data.py +20 -3
  17. rasa/cli/dialogue_understanding_test.py +386 -0
  18. rasa/cli/evaluate.py +1 -1
  19. rasa/cli/export.py +6 -6
  20. rasa/cli/inspect.py +20 -1
  21. rasa/cli/interactive.py +4 -5
  22. rasa/cli/llm_fine_tuning.py +51 -16
  23. rasa/cli/markers.py +1 -2
  24. rasa/cli/project_templates/calm/actions/add_contact.py +1 -1
  25. rasa/cli/project_templates/calm/config.yml +2 -2
  26. rasa/cli/project_templates/calm/domain/list_contacts.yml +1 -2
  27. rasa/cli/project_templates/calm/domain/remove_contact.yml +1 -2
  28. rasa/cli/project_templates/calm/domain/shared.yml +1 -4
  29. rasa/cli/project_templates/calm/endpoints.yml +2 -2
  30. rasa/cli/project_templates/tutorial/actions/actions.py +3 -2
  31. rasa/cli/shell.py +5 -6
  32. rasa/cli/studio/download.py +1 -2
  33. rasa/cli/studio/studio.py +2 -3
  34. rasa/cli/studio/train.py +0 -1
  35. rasa/cli/telemetry.py +2 -2
  36. rasa/cli/test.py +11 -11
  37. rasa/cli/train.py +3 -0
  38. rasa/cli/utils.py +25 -5
  39. rasa/constants.py +0 -1
  40. rasa/core/__init__.py +0 -1
  41. rasa/core/actions/action.py +137 -208
  42. rasa/core/actions/action_handle_digressions.py +164 -0
  43. rasa/core/actions/action_hangup.py +1 -1
  44. rasa/core/actions/action_repeat_bot_messages.py +2 -2
  45. rasa/core/actions/action_run_slot_rejections.py +18 -6
  46. rasa/core/actions/action_trigger_chitchat.py +1 -1
  47. rasa/core/actions/action_trigger_flow.py +5 -5
  48. rasa/core/actions/action_trigger_search.py +1 -1
  49. rasa/core/actions/custom_action_executor.py +1 -1
  50. rasa/core/actions/direct_custom_actions_executor.py +1 -0
  51. rasa/core/actions/forms.py +22 -15
  52. rasa/core/actions/http_custom_action_executor.py +8 -1
  53. rasa/core/actions/loops.py +3 -3
  54. rasa/core/actions/two_stage_fallback.py +13 -13
  55. rasa/core/auth_retry_tracker_store.py +1 -2
  56. rasa/core/brokers/broker.py +2 -1
  57. rasa/core/brokers/file.py +1 -1
  58. rasa/core/brokers/kafka.py +8 -8
  59. rasa/core/brokers/pika.py +8 -9
  60. rasa/core/brokers/sql.py +4 -3
  61. rasa/core/channels/__init__.py +7 -0
  62. rasa/core/channels/botframework.py +2 -2
  63. rasa/core/channels/callback.py +4 -4
  64. rasa/core/channels/channel.py +11 -11
  65. rasa/core/channels/console.py +0 -1
  66. rasa/core/channels/development_inspector.py +80 -24
  67. rasa/core/channels/facebook.py +5 -5
  68. rasa/core/channels/hangouts.py +7 -8
  69. rasa/core/channels/inspector/dist/assets/Tableau10-1b767f5e.js +1 -0
  70. rasa/core/channels/inspector/dist/assets/arc-9f1365dc.js +1 -0
  71. rasa/core/channels/inspector/dist/assets/blockDiagram-38ab4fdb-e0f81b12.js +118 -0
  72. rasa/core/channels/inspector/dist/assets/c4Diagram-3d4e48cf-9deaee1c.js +10 -0
  73. rasa/core/channels/inspector/dist/assets/channel-44956714.js +1 -0
  74. rasa/core/channels/inspector/dist/assets/classDiagram-70f12bd4-20450a96.js +2 -0
  75. rasa/core/channels/inspector/dist/assets/classDiagram-v2-f2320105-749d2abf.js +2 -0
  76. rasa/core/channels/inspector/dist/assets/clone-a9475142.js +1 -0
  77. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-89c73b31.js → createText-2e5e7dd3-bef0b38c.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/edges-e0da2a9e-943801a7.js +4 -0
  79. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-907e0440.js → erDiagram-9861fffd-d523a948.js} +4 -4
  80. rasa/core/channels/inspector/dist/assets/flowDb-956e92f1-54e4cf19.js +10 -0
  81. rasa/core/channels/inspector/dist/assets/flowDiagram-66a62f08-48bfbbe8.js +4 -0
  82. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-43fa749a.js +1 -0
  83. rasa/core/channels/inspector/dist/assets/flowchart-elk-definition-4a651766-17c30827.js +139 -0
  84. rasa/core/channels/inspector/dist/assets/ganttDiagram-c361ad54-43086f2d.js +257 -0
  85. rasa/core/channels/inspector/dist/assets/gitGraphDiagram-72cf32ee-5c8b693e.js +70 -0
  86. rasa/core/channels/inspector/dist/assets/graph-41a90d26.js +1 -0
  87. rasa/core/channels/inspector/dist/assets/index-3862675e-b43eeae9.js +1 -0
  88. rasa/core/channels/inspector/dist/assets/{index-e793d777.js → index-e8affe45.js} +201 -196
  89. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-8ceba4db.js → infoDiagram-f8f76790-0b20676b.js} +1 -1
  90. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-960d3809.js → journeyDiagram-49397b02-39bce7b5.js} +4 -4
  91. rasa/core/channels/inspector/dist/assets/katex-498eb57e.js +261 -0
  92. rasa/core/channels/inspector/dist/assets/layout-dc8eeea4.js +1 -0
  93. rasa/core/channels/inspector/dist/assets/{line-eeccc4e2.js → line-c4d2e756.js} +1 -1
  94. rasa/core/channels/inspector/dist/assets/linear-86f6f2d9.js +1 -0
  95. rasa/core/channels/inspector/dist/assets/mindmap-definition-fc14e90a-4216f771.js +312 -0
  96. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-dc9b5e1b.js → pieDiagram-8a3498a8-1a0cfa96.js} +7 -7
  97. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-a08cba6d.js → quadrantDiagram-120e2f19-f91e67cf.js} +1 -1
  98. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-87242b9e.js → requirementDiagram-deff3bca-d4046bed.js} +2 -2
  99. rasa/core/channels/inspector/dist/assets/sankeyDiagram-04a897e0-2cf6d1d7.js +8 -0
  100. rasa/core/channels/inspector/dist/assets/sequenceDiagram-704730f1-751ac4f5.js +122 -0
  101. rasa/core/channels/inspector/dist/assets/stateDiagram-587899a1-f734f4d4.js +1 -0
  102. rasa/core/channels/inspector/dist/assets/stateDiagram-v2-d93cdb3a-91c65710.js +1 -0
  103. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-cef936a6.js → styles-6aaf32cf-e0cff7be.js} +1 -1
  104. rasa/core/channels/inspector/dist/assets/styles-9a916d00-c8029e5d.js +160 -0
  105. rasa/core/channels/inspector/dist/assets/styles-c10674c1-114f312a.js +116 -0
  106. rasa/core/channels/inspector/dist/assets/svgDrawCommon-08f97a94-b7b9dc00.js +1 -0
  107. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-0d39bdb2.js → timeline-definition-85554ec2-9536d189.js} +3 -3
  108. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-a03fa445.js → xychartDiagram-e933f94c-bf3b0f36.js} +3 -3
  109. rasa/core/channels/inspector/dist/index.html +1 -1
  110. rasa/core/channels/inspector/package.json +11 -3
  111. rasa/core/channels/inspector/src/App.tsx +15 -2
  112. rasa/core/channels/inspector/src/components/RasaLogo.tsx +31 -0
  113. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +68 -0
  114. rasa/core/channels/inspector/src/components/Welcome.tsx +19 -13
  115. rasa/core/channels/inspector/yarn.lock +94 -99
  116. rasa/core/channels/mattermost.py +4 -4
  117. rasa/core/channels/rasa_chat.py +4 -4
  118. rasa/core/channels/rest.py +11 -12
  119. rasa/core/channels/rocketchat.py +4 -3
  120. rasa/core/channels/slack.py +6 -5
  121. rasa/core/channels/socketio.py +8 -28
  122. rasa/core/channels/studio_chat.py +212 -0
  123. rasa/core/channels/telegram.py +105 -55
  124. rasa/core/channels/twilio.py +3 -3
  125. rasa/core/channels/vier_cvg.py +2 -2
  126. rasa/core/channels/voice_ready/audiocodes.py +51 -32
  127. rasa/core/channels/voice_ready/jambonz.py +5 -5
  128. rasa/core/channels/voice_ready/jambonz_protocol.py +3 -4
  129. rasa/core/channels/voice_ready/twilio_voice.py +9 -8
  130. rasa/core/channels/voice_ready/utils.py +2 -2
  131. rasa/core/channels/voice_stream/asr/asr_engine.py +12 -6
  132. rasa/core/channels/voice_stream/asr/asr_event.py +5 -0
  133. rasa/core/channels/voice_stream/asr/azure.py +16 -3
  134. rasa/core/channels/voice_stream/asr/deepgram.py +76 -19
  135. rasa/core/channels/voice_stream/audiocodes.py +292 -0
  136. rasa/core/channels/voice_stream/browser_audio.py +14 -7
  137. rasa/core/channels/voice_stream/call_state.py +6 -2
  138. rasa/core/channels/voice_stream/genesys.py +320 -0
  139. rasa/core/channels/voice_stream/tts/azure.py +13 -5
  140. rasa/core/channels/voice_stream/tts/cartesia.py +34 -14
  141. rasa/core/channels/voice_stream/tts/tts_cache.py +3 -2
  142. rasa/core/channels/voice_stream/tts/tts_engine.py +1 -1
  143. rasa/core/channels/voice_stream/twilio_media_streams.py +12 -8
  144. rasa/core/channels/voice_stream/util.py +1 -1
  145. rasa/core/channels/voice_stream/voice_channel.py +100 -56
  146. rasa/core/channels/webexteams.py +3 -4
  147. rasa/core/constants.py +2 -0
  148. rasa/core/evaluation/marker.py +7 -6
  149. rasa/core/evaluation/marker_base.py +15 -16
  150. rasa/core/evaluation/marker_stats.py +3 -4
  151. rasa/core/evaluation/marker_tracker_loader.py +5 -4
  152. rasa/core/exporter.py +4 -4
  153. rasa/core/featurizers/precomputation.py +8 -8
  154. rasa/core/featurizers/single_state_featurizer.py +7 -7
  155. rasa/core/featurizers/tracker_featurizers.py +13 -13
  156. rasa/core/http_interpreter.py +3 -4
  157. rasa/core/information_retrieval/__init__.py +1 -1
  158. rasa/core/information_retrieval/faiss.py +4 -4
  159. rasa/core/information_retrieval/information_retrieval.py +2 -2
  160. rasa/core/information_retrieval/milvus.py +3 -3
  161. rasa/core/information_retrieval/qdrant.py +3 -3
  162. rasa/core/jobs.py +1 -0
  163. rasa/core/lock.py +2 -3
  164. rasa/core/lock_store.py +3 -3
  165. rasa/core/migrate.py +12 -9
  166. rasa/core/nlg/__init__.py +1 -1
  167. rasa/core/nlg/callback.py +2 -3
  168. rasa/core/nlg/contextual_response_rephraser.py +82 -14
  169. rasa/core/nlg/generator.py +85 -17
  170. rasa/core/nlg/interpolator.py +4 -3
  171. rasa/core/nlg/response.py +9 -7
  172. rasa/core/nlg/summarize.py +1 -0
  173. rasa/core/nlg/translate.py +55 -0
  174. rasa/core/persistor.py +3 -3
  175. rasa/core/policies/ensemble.py +10 -9
  176. rasa/core/policies/enterprise_search_policy.py +87 -21
  177. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +1 -1
  178. rasa/core/policies/flow_policy.py +13 -14
  179. rasa/core/policies/flows/flow_executor.py +85 -55
  180. rasa/core/policies/intentless_policy.py +6 -7
  181. rasa/core/policies/memoization.py +22 -20
  182. rasa/core/policies/policy.py +24 -22
  183. rasa/core/policies/rule_policy.py +37 -36
  184. rasa/core/policies/ted_policy.py +87 -85
  185. rasa/core/policies/unexpected_intent_policy.py +77 -75
  186. rasa/core/processor.py +167 -74
  187. rasa/core/run.py +5 -4
  188. rasa/core/secrets_manager/endpoints.py +2 -3
  189. rasa/core/secrets_manager/factory.py +2 -3
  190. rasa/core/secrets_manager/secret_manager.py +2 -3
  191. rasa/core/secrets_manager/vault.py +2 -2
  192. rasa/core/test.py +30 -30
  193. rasa/core/tracker_store.py +138 -49
  194. rasa/core/train.py +1 -1
  195. rasa/core/training/__init__.py +2 -2
  196. rasa/core/training/converters/responses_prefix_converter.py +1 -2
  197. rasa/core/training/interactive.py +13 -13
  198. rasa/core/training/story_conflict.py +4 -5
  199. rasa/core/training/training.py +3 -5
  200. rasa/core/utils.py +5 -5
  201. rasa/core/visualize.py +1 -1
  202. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -2
  203. rasa/dialogue_understanding/coexistence/llm_based_router.py +5 -5
  204. rasa/dialogue_understanding/commands/__init__.py +22 -22
  205. rasa/dialogue_understanding/commands/can_not_handle_command.py +38 -1
  206. rasa/dialogue_understanding/commands/cancel_flow_command.py +96 -9
  207. rasa/dialogue_understanding/commands/change_flow_command.py +36 -2
  208. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +36 -4
  209. rasa/dialogue_understanding/commands/clarify_command.py +46 -4
  210. rasa/dialogue_understanding/commands/command.py +3 -2
  211. rasa/dialogue_understanding/commands/command_syntax_manager.py +55 -0
  212. rasa/dialogue_understanding/commands/correct_slots_command.py +14 -5
  213. rasa/dialogue_understanding/commands/error_command.py +1 -1
  214. rasa/dialogue_understanding/commands/free_form_answer_command.py +2 -1
  215. rasa/dialogue_understanding/commands/handle_code_change_command.py +2 -2
  216. rasa/dialogue_understanding/commands/handle_digressions_command.py +144 -0
  217. rasa/dialogue_understanding/commands/human_handoff_command.py +34 -4
  218. rasa/dialogue_understanding/commands/knowledge_answer_command.py +36 -4
  219. rasa/dialogue_understanding/commands/noop_command.py +2 -1
  220. rasa/dialogue_understanding/commands/prompt_command.py +94 -0
  221. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +34 -4
  222. rasa/dialogue_understanding/commands/restart_command.py +2 -5
  223. rasa/dialogue_understanding/commands/session_end_command.py +3 -5
  224. rasa/dialogue_understanding/commands/session_start_command.py +3 -5
  225. rasa/dialogue_understanding/commands/set_slot_command.py +55 -16
  226. rasa/dialogue_understanding/commands/skip_question_command.py +34 -4
  227. rasa/dialogue_understanding/commands/start_flow_command.py +78 -2
  228. rasa/dialogue_understanding/commands/user_silence_command.py +3 -5
  229. rasa/dialogue_understanding/commands/utils.py +126 -43
  230. rasa/dialogue_understanding/constants.py +2 -0
  231. rasa/dialogue_understanding/generator/__init__.py +2 -0
  232. rasa/dialogue_understanding/generator/command_generator.py +120 -79
  233. rasa/dialogue_understanding/generator/command_parser.py +245 -0
  234. rasa/dialogue_understanding/generator/constants.py +12 -4
  235. rasa/dialogue_understanding/generator/flow_retrieval.py +7 -7
  236. rasa/dialogue_understanding/generator/llm_based_command_generator.py +187 -59
  237. rasa/dialogue_understanding/generator/llm_command_generator.py +6 -3
  238. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +106 -110
  239. rasa/dialogue_understanding/generator/nlu_command_adapter.py +53 -11
  240. rasa/dialogue_understanding/generator/prompt_templates/__init__.py +0 -0
  241. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +58 -0
  242. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +57 -0
  243. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +574 -0
  244. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +41 -386
  245. rasa/dialogue_understanding/generator/utils.py +76 -0
  246. rasa/dialogue_understanding/patterns/cancel.py +2 -1
  247. rasa/dialogue_understanding/patterns/cannot_handle.py +1 -0
  248. rasa/dialogue_understanding/patterns/chitchat.py +1 -1
  249. rasa/dialogue_understanding/patterns/clarify.py +2 -1
  250. rasa/dialogue_understanding/patterns/code_change.py +2 -0
  251. rasa/dialogue_understanding/patterns/collect_information.py +7 -4
  252. rasa/dialogue_understanding/patterns/completed.py +1 -1
  253. rasa/dialogue_understanding/patterns/continue_interrupted.py +1 -1
  254. rasa/dialogue_understanding/patterns/correction.py +17 -3
  255. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +78 -2
  256. rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
  257. rasa/dialogue_understanding/patterns/human_handoff.py +1 -1
  258. rasa/dialogue_understanding/patterns/internal_error.py +1 -0
  259. rasa/dialogue_understanding/patterns/search.py +1 -1
  260. rasa/dialogue_understanding/patterns/session_start.py +1 -1
  261. rasa/dialogue_understanding/patterns/skip_question.py +1 -0
  262. rasa/dialogue_understanding/patterns/user_silence.py +1 -1
  263. rasa/dialogue_understanding/patterns/validate_slot.py +65 -0
  264. rasa/dialogue_understanding/processor/command_processor.py +193 -43
  265. rasa/dialogue_understanding/processor/command_processor_component.py +1 -1
  266. rasa/dialogue_understanding/stack/dialogue_stack.py +4 -3
  267. rasa/dialogue_understanding/stack/frames/__init__.py +2 -2
  268. rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +4 -1
  269. rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +2 -3
  270. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +5 -2
  271. rasa/dialogue_understanding/stack/frames/search_frame.py +4 -1
  272. rasa/dialogue_understanding/stack/utils.py +56 -10
  273. rasa/dialogue_understanding/utils.py +164 -0
  274. rasa/dialogue_understanding_test/README.md +429 -0
  275. rasa/dialogue_understanding_test/__init__.py +0 -0
  276. rasa/dialogue_understanding_test/command_comparison.py +60 -0
  277. rasa/dialogue_understanding_test/command_metric_calculation.py +122 -0
  278. rasa/dialogue_understanding_test/constants.py +22 -0
  279. rasa/dialogue_understanding_test/du_test_case.py +448 -0
  280. rasa/dialogue_understanding_test/du_test_result.py +390 -0
  281. rasa/dialogue_understanding_test/du_test_runner.py +322 -0
  282. rasa/dialogue_understanding_test/du_test_schema.yml +161 -0
  283. rasa/dialogue_understanding_test/io.py +443 -0
  284. rasa/dialogue_understanding_test/test_case_simulation/__init__.py +0 -0
  285. rasa/dialogue_understanding_test/test_case_simulation/exception.py +28 -0
  286. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +336 -0
  287. rasa/dialogue_understanding_test/utils.py +70 -0
  288. rasa/dialogue_understanding_test/validation.py +77 -0
  289. rasa/e2e_test/aggregate_test_stats_calculator.py +1 -1
  290. rasa/e2e_test/assertions.py +202 -175
  291. rasa/e2e_test/assertions_schema.yml +6 -0
  292. rasa/e2e_test/constants.py +16 -1
  293. rasa/e2e_test/e2e_config.py +102 -41
  294. rasa/e2e_test/e2e_config_schema.yml +28 -10
  295. rasa/e2e_test/e2e_test_case.py +5 -5
  296. rasa/e2e_test/e2e_test_converter.py +2 -3
  297. rasa/e2e_test/e2e_test_coverage_report.py +6 -6
  298. rasa/e2e_test/e2e_test_result.py +1 -1
  299. rasa/e2e_test/e2e_test_runner.py +143 -38
  300. rasa/e2e_test/llm_judge_prompts/answer_relevance_prompt_template.jinja2 +93 -0
  301. rasa/e2e_test/llm_judge_prompts/groundedness_prompt_template.jinja2 +169 -0
  302. rasa/e2e_test/stub_custom_action.py +1 -1
  303. rasa/e2e_test/utils/generative_assertions.py +243 -0
  304. rasa/e2e_test/utils/io.py +123 -93
  305. rasa/e2e_test/utils/validation.py +101 -3
  306. rasa/engine/caching.py +5 -7
  307. rasa/engine/constants.py +1 -1
  308. rasa/engine/graph.py +3 -2
  309. rasa/engine/language.py +182 -0
  310. rasa/engine/recipes/config_files/default_config.yml +4 -0
  311. rasa/engine/recipes/default_components.py +13 -15
  312. rasa/engine/recipes/default_recipe.py +65 -49
  313. rasa/engine/recipes/graph_recipe.py +10 -7
  314. rasa/engine/recipes/recipe.py +2 -2
  315. rasa/engine/runner/dask.py +2 -2
  316. rasa/engine/runner/interface.py +1 -0
  317. rasa/engine/storage/local_model_storage.py +6 -4
  318. rasa/engine/storage/resource.py +2 -1
  319. rasa/engine/storage/storage.py +8 -3
  320. rasa/engine/training/components.py +2 -1
  321. rasa/engine/training/fingerprinting.py +4 -2
  322. rasa/engine/training/graph_trainer.py +4 -4
  323. rasa/engine/training/hooks.py +2 -2
  324. rasa/engine/validation.py +36 -33
  325. rasa/exceptions.py +3 -2
  326. rasa/graph_components/converters/nlu_message_converter.py +3 -3
  327. rasa/graph_components/providers/domain_for_core_training_provider.py +3 -3
  328. rasa/graph_components/providers/domain_provider.py +3 -2
  329. rasa/graph_components/providers/flows_provider.py +2 -3
  330. rasa/graph_components/providers/forms_provider.py +4 -4
  331. rasa/graph_components/providers/nlu_training_data_provider.py +5 -3
  332. rasa/graph_components/providers/responses_provider.py +4 -4
  333. rasa/graph_components/providers/rule_only_provider.py +3 -2
  334. rasa/graph_components/providers/story_graph_provider.py +8 -8
  335. rasa/graph_components/providers/training_tracker_provider.py +3 -2
  336. rasa/graph_components/validators/default_recipe_validator.py +16 -16
  337. rasa/graph_components/validators/finetuning_validator.py +10 -8
  338. rasa/hooks.py +19 -14
  339. rasa/jupyter.py +2 -2
  340. rasa/llm_fine_tuning/annotation_module.py +4 -4
  341. rasa/llm_fine_tuning/conversations.py +5 -33
  342. rasa/llm_fine_tuning/llm_data_preparation_module.py +6 -4
  343. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -4
  344. rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +18 -13
  345. rasa/llm_fine_tuning/paraphrasing_module.py +6 -2
  346. rasa/llm_fine_tuning/storage.py +3 -3
  347. rasa/llm_fine_tuning/train_test_split_module.py +27 -27
  348. rasa/llm_fine_tuning/utils.py +7 -0
  349. rasa/markers/marker.py +2 -3
  350. rasa/markers/marker_base.py +1 -2
  351. rasa/markers/upload.py +2 -2
  352. rasa/markers/validate.py +2 -3
  353. rasa/model.py +3 -5
  354. rasa/model_manager/config.py +1 -1
  355. rasa/model_manager/model_api.py +5 -4
  356. rasa/model_manager/runner_service.py +13 -10
  357. rasa/model_manager/socket_bridge.py +15 -9
  358. rasa/model_manager/studio_jwt_auth.py +1 -0
  359. rasa/model_manager/trainer_service.py +9 -7
  360. rasa/model_manager/utils.py +1 -1
  361. rasa/model_manager/warm_rasa_process.py +14 -9
  362. rasa/model_service.py +5 -6
  363. rasa/model_testing.py +13 -15
  364. rasa/model_training.py +29 -29
  365. rasa/nlu/classifiers/diet_classifier.py +72 -73
  366. rasa/nlu/classifiers/fallback_classifier.py +9 -8
  367. rasa/nlu/classifiers/keyword_intent_classifier.py +7 -6
  368. rasa/nlu/classifiers/logistic_regression_classifier.py +3 -3
  369. rasa/nlu/classifiers/mitie_intent_classifier.py +5 -4
  370. rasa/nlu/classifiers/regex_message_handler.py +3 -2
  371. rasa/nlu/classifiers/sklearn_intent_classifier.py +2 -2
  372. rasa/nlu/convert.py +2 -2
  373. rasa/nlu/emulators/dialogflow.py +3 -3
  374. rasa/nlu/emulators/luis.py +5 -5
  375. rasa/nlu/emulators/no_emulator.py +1 -0
  376. rasa/nlu/emulators/wit.py +4 -4
  377. rasa/nlu/extractors/crf_entity_extractor.py +11 -11
  378. rasa/nlu/extractors/duckling_entity_extractor.py +7 -6
  379. rasa/nlu/extractors/entity_synonyms.py +10 -9
  380. rasa/nlu/extractors/extractor.py +16 -16
  381. rasa/nlu/extractors/mitie_entity_extractor.py +10 -9
  382. rasa/nlu/extractors/regex_entity_extractor.py +11 -10
  383. rasa/nlu/extractors/spacy_entity_extractor.py +2 -2
  384. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +15 -14
  385. rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +2 -1
  386. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +10 -9
  387. rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +9 -7
  388. rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +13 -12
  389. rasa/nlu/featurizers/featurizer.py +5 -4
  390. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +6 -6
  391. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -4
  392. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +4 -4
  393. rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +2 -0
  394. rasa/nlu/model.py +0 -1
  395. rasa/nlu/selectors/response_selector.py +67 -68
  396. rasa/nlu/test.py +38 -38
  397. rasa/nlu/tokenizers/jieba_tokenizer.py +1 -2
  398. rasa/nlu/tokenizers/mitie_tokenizer.py +2 -2
  399. rasa/nlu/tokenizers/spacy_tokenizer.py +3 -3
  400. rasa/nlu/tokenizers/tokenizer.py +6 -7
  401. rasa/nlu/tokenizers/whitespace_tokenizer.py +1 -1
  402. rasa/nlu/utils/bilou_utils.py +7 -7
  403. rasa/nlu/utils/hugging_face/registry.py +22 -22
  404. rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +2 -1
  405. rasa/nlu/utils/mitie_utils.py +2 -1
  406. rasa/nlu/utils/pattern_utils.py +1 -1
  407. rasa/nlu/utils/spacy_utils.py +3 -3
  408. rasa/plugin.py +12 -1
  409. rasa/server.py +6 -3
  410. rasa/shared/constants.py +45 -18
  411. rasa/shared/core/command_payload_reader.py +15 -7
  412. rasa/shared/core/constants.py +34 -4
  413. rasa/shared/core/conversation.py +1 -2
  414. rasa/shared/core/domain.py +19 -20
  415. rasa/shared/core/events.py +60 -39
  416. rasa/shared/core/flows/__init__.py +0 -1
  417. rasa/shared/core/flows/constants.py +11 -0
  418. rasa/shared/core/flows/flow.py +107 -26
  419. rasa/shared/core/flows/flow_step.py +4 -3
  420. rasa/shared/core/flows/flow_step_links.py +1 -2
  421. rasa/shared/core/flows/flow_step_sequence.py +1 -1
  422. rasa/shared/core/flows/flows_list.py +3 -3
  423. rasa/shared/core/flows/flows_yaml_schema.json +69 -3
  424. rasa/shared/core/flows/nlu_trigger.py +1 -1
  425. rasa/shared/core/flows/steps/__init__.py +2 -2
  426. rasa/shared/core/flows/steps/action.py +1 -1
  427. rasa/shared/core/flows/steps/call.py +1 -1
  428. rasa/shared/core/flows/steps/collect.py +22 -40
  429. rasa/shared/core/flows/steps/internal.py +1 -1
  430. rasa/shared/core/flows/steps/link.py +1 -1
  431. rasa/shared/core/flows/steps/no_operation.py +2 -2
  432. rasa/shared/core/flows/steps/set_slots.py +1 -1
  433. rasa/shared/core/flows/utils.py +44 -4
  434. rasa/shared/core/flows/validation.py +4 -6
  435. rasa/shared/core/generator.py +20 -21
  436. rasa/shared/core/slot_mappings.py +360 -121
  437. rasa/shared/core/slots.py +163 -6
  438. rasa/shared/core/trackers.py +108 -33
  439. rasa/shared/core/training_data/loading.py +1 -1
  440. rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
  441. rasa/shared/core/training_data/story_reader/story_step_builder.py +4 -4
  442. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +29 -31
  443. rasa/shared/core/training_data/story_writer/yaml_story_writer.py +22 -24
  444. rasa/shared/core/training_data/structures.py +11 -12
  445. rasa/shared/core/training_data/visualization.py +10 -10
  446. rasa/shared/data.py +6 -6
  447. rasa/shared/engine/caching.py +0 -1
  448. rasa/shared/exceptions.py +2 -2
  449. rasa/shared/importers/importer.py +58 -2
  450. rasa/shared/importers/rasa.py +5 -6
  451. rasa/shared/importers/utils.py +1 -1
  452. rasa/shared/nlu/constants.py +9 -0
  453. rasa/shared/nlu/training_data/entities_parser.py +6 -6
  454. rasa/shared/nlu/training_data/features.py +3 -3
  455. rasa/shared/nlu/training_data/formats/__init__.py +1 -1
  456. rasa/shared/nlu/training_data/formats/dialogflow.py +4 -5
  457. rasa/shared/nlu/training_data/formats/luis.py +7 -8
  458. rasa/shared/nlu/training_data/formats/rasa.py +4 -5
  459. rasa/shared/nlu/training_data/formats/rasa_yaml.py +17 -16
  460. rasa/shared/nlu/training_data/formats/readerwriter.py +8 -11
  461. rasa/shared/nlu/training_data/formats/wit.py +3 -4
  462. rasa/shared/nlu/training_data/loading.py +4 -4
  463. rasa/shared/nlu/training_data/lookup_tables_parser.py +1 -1
  464. rasa/shared/nlu/training_data/message.py +13 -14
  465. rasa/shared/nlu/training_data/schemas/data_schema.py +1 -1
  466. rasa/shared/nlu/training_data/schemas/responses.yml +19 -11
  467. rasa/shared/nlu/training_data/synonyms_parser.py +3 -3
  468. rasa/shared/nlu/training_data/training_data.py +12 -13
  469. rasa/shared/nlu/training_data/util.py +11 -10
  470. rasa/shared/providers/_configs/azure_entra_id_config.py +541 -0
  471. rasa/shared/providers/_configs/azure_openai_client_config.py +150 -15
  472. rasa/shared/providers/_configs/client_config.py +3 -1
  473. rasa/shared/providers/_configs/default_litellm_client_config.py +9 -7
  474. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +13 -11
  475. rasa/shared/providers/_configs/litellm_router_client_config.py +12 -10
  476. rasa/shared/providers/_configs/model_group_config.py +8 -5
  477. rasa/shared/providers/_configs/oauth_config.py +33 -0
  478. rasa/shared/providers/_configs/openai_client_config.py +14 -12
  479. rasa/shared/providers/_configs/rasa_llm_client_config.py +5 -3
  480. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +12 -11
  481. rasa/shared/providers/_configs/utils.py +1 -0
  482. rasa/shared/providers/_ssl_verification_utils.py +5 -6
  483. rasa/shared/providers/_utils.py +5 -5
  484. rasa/shared/providers/constants.py +6 -0
  485. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -1
  486. rasa/shared/providers/embedding/azure_openai_embedding_client.py +32 -7
  487. rasa/shared/providers/embedding/embedding_client.py +1 -1
  488. rasa/shared/providers/embedding/litellm_router_embedding_client.py +5 -2
  489. rasa/shared/providers/llm/_base_litellm_client.py +43 -18
  490. rasa/shared/providers/llm/azure_openai_llm_client.py +90 -34
  491. rasa/shared/providers/llm/default_litellm_llm_client.py +4 -2
  492. rasa/shared/providers/llm/litellm_router_llm_client.py +32 -9
  493. rasa/shared/providers/llm/llm_client.py +24 -8
  494. rasa/shared/providers/llm/llm_response.py +61 -2
  495. rasa/shared/providers/llm/openai_llm_client.py +11 -5
  496. rasa/shared/providers/llm/rasa_llm_client.py +17 -14
  497. rasa/shared/providers/llm/self_hosted_llm_client.py +35 -15
  498. rasa/shared/providers/mappings.py +18 -19
  499. rasa/shared/providers/router/_base_litellm_router_client.py +48 -15
  500. rasa/shared/providers/router/router_client.py +3 -1
  501. rasa/shared/utils/cli.py +1 -1
  502. rasa/shared/utils/common.py +15 -1
  503. rasa/shared/utils/constants.py +3 -0
  504. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +1 -1
  505. rasa/shared/utils/health_check/health_check.py +3 -3
  506. rasa/shared/utils/health_check/llm_health_check_mixin.py +1 -1
  507. rasa/shared/utils/io.py +1 -1
  508. rasa/shared/utils/llm.py +100 -18
  509. rasa/shared/utils/pykwalify_extensions.py +25 -1
  510. rasa/shared/utils/schemas/domain.yml +26 -1
  511. rasa/shared/utils/schemas/events.py +1 -1
  512. rasa/shared/utils/yaml.py +24 -20
  513. rasa/studio/auth.py +3 -3
  514. rasa/studio/config.py +1 -2
  515. rasa/studio/data_handler.py +3 -3
  516. rasa/studio/download.py +1 -1
  517. rasa/studio/results_logger.py +3 -3
  518. rasa/studio/upload.py +21 -5
  519. rasa/telemetry.py +127 -48
  520. rasa/tracing/config.py +5 -3
  521. rasa/tracing/constants.py +12 -0
  522. rasa/tracing/instrumentation/attribute_extractors.py +92 -14
  523. rasa/tracing/instrumentation/instrumentation.py +61 -5
  524. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +1 -1
  525. rasa/tracing/instrumentation/metrics.py +52 -11
  526. rasa/tracing/metric_instrument_provider.py +54 -14
  527. rasa/utils/common.py +12 -24
  528. rasa/utils/endpoints.py +1 -1
  529. rasa/utils/io.py +7 -7
  530. rasa/utils/licensing.py +3 -4
  531. rasa/utils/log_utils.py +7 -6
  532. rasa/utils/ml_utils.py +1 -0
  533. rasa/utils/plotting.py +3 -3
  534. rasa/utils/sanic_error_handler.py +1 -1
  535. rasa/utils/tensorflow/callback.py +2 -2
  536. rasa/utils/tensorflow/crf.py +2 -2
  537. rasa/utils/tensorflow/data_generator.py +5 -5
  538. rasa/utils/tensorflow/environment.py +3 -3
  539. rasa/utils/tensorflow/feature_array.py +2 -3
  540. rasa/utils/tensorflow/layers.py +18 -12
  541. rasa/utils/tensorflow/layers_utils.py +2 -1
  542. rasa/utils/tensorflow/metrics.py +2 -2
  543. rasa/utils/tensorflow/model_data.py +7 -7
  544. rasa/utils/tensorflow/model_data_utils.py +10 -9
  545. rasa/utils/tensorflow/models.py +31 -32
  546. rasa/utils/tensorflow/rasa_layers.py +20 -19
  547. rasa/utils/tensorflow/types.py +2 -1
  548. rasa/utils/train_utils.py +23 -21
  549. rasa/utils/url_tools.py +1 -1
  550. rasa/validator.py +594 -115
  551. rasa/version.py +1 -1
  552. {rasa_pro-3.11.4.dist-info → rasa_pro-3.12.0.dist-info}/METADATA +23 -26
  553. rasa_pro-3.12.0.dist-info/RECORD +829 -0
  554. rasa/core/channels/inspector/dist/assets/arc-632a63ec.js +0 -1
  555. rasa/core/channels/inspector/dist/assets/c4Diagram-d0fbc5ce-081e0df4.js +0 -10
  556. rasa/core/channels/inspector/dist/assets/classDiagram-936ed81e-3df0afc2.js +0 -2
  557. rasa/core/channels/inspector/dist/assets/classDiagram-v2-c3cb15f1-8c5ed31e.js +0 -2
  558. rasa/core/channels/inspector/dist/assets/edges-f2ad444c-4fc48c3e.js +0 -4
  559. rasa/core/channels/inspector/dist/assets/flowDb-1972c806-9ec53a3c.js +0 -6
  560. rasa/core/channels/inspector/dist/assets/flowDiagram-7ea5b25a-41da787a.js +0 -4
  561. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-8bea338b.js +0 -1
  562. rasa/core/channels/inspector/dist/assets/flowchart-elk-definition-abe16c3d-ce370633.js +0 -139
  563. rasa/core/channels/inspector/dist/assets/ganttDiagram-9b5ea136-90a36523.js +0 -266
  564. rasa/core/channels/inspector/dist/assets/gitGraphDiagram-99d0ae7c-41e1aa3f.js +0 -70
  565. rasa/core/channels/inspector/dist/assets/index-2c4b9a3b-e6f2af62.js +0 -1
  566. rasa/core/channels/inspector/dist/assets/layout-498807d8.js +0 -1
  567. rasa/core/channels/inspector/dist/assets/linear-8a078617.js +0 -1
  568. rasa/core/channels/inspector/dist/assets/mindmap-definition-beec6740-396d17dd.js +0 -109
  569. rasa/core/channels/inspector/dist/assets/sankeyDiagram-8f13d901-53f6f391.js +0 -8
  570. rasa/core/channels/inspector/dist/assets/sequenceDiagram-b655622a-715c9c20.js +0 -122
  571. rasa/core/channels/inspector/dist/assets/stateDiagram-59f0c015-2e8fb31f.js +0 -1
  572. rasa/core/channels/inspector/dist/assets/stateDiagram-v2-2b26beab-7e2d2aa0.js +0 -1
  573. rasa/core/channels/inspector/dist/assets/styles-080da4f6-4420cea6.js +0 -110
  574. rasa/core/channels/inspector/dist/assets/styles-3dcbcfbf-28676cf4.js +0 -159
  575. rasa/core/channels/inspector/dist/assets/svgDrawCommon-4835440b-151251e9.js +0 -1
  576. rasa_pro-3.11.4.dist-info/RECORD +0 -779
  577. /rasa/dialogue_understanding/generator/{single_step → prompt_templates}/command_prompt_template.jinja2 +0 -0
  578. {rasa_pro-3.11.4.dist-info → rasa_pro-3.12.0.dist-info}/NOTICE +0 -0
  579. {rasa_pro-3.11.4.dist-info → rasa_pro-3.12.0.dist-info}/WHEEL +0 -0
  580. {rasa_pro-3.11.4.dist-info → rasa_pro-3.12.0.dist-info}/entry_points.txt +0 -0
rasa/e2e_test/utils/io.py CHANGED
@@ -6,7 +6,7 @@ import sys
6
6
  from functools import lru_cache
7
7
  from pathlib import Path
8
8
  from textwrap import dedent
9
- from typing import Any, Dict, Generator, List, Optional, TYPE_CHECKING, Tuple, Union
9
+ from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Tuple, Union
10
10
 
11
11
  import matplotlib.pyplot as plt
12
12
  import pandas as pd
@@ -27,7 +27,11 @@ from rasa.e2e_test.constants import (
27
27
  STATUS_PASSED,
28
28
  STUB_CUSTOM_ACTION_NAME_SEPARATOR,
29
29
  )
30
- from rasa.e2e_test.e2e_test_case import Fixture, Metadata, TestSuite, TestCase
30
+ from rasa.e2e_test.e2e_test_case import Fixture, Metadata, TestCase, TestSuite
31
+ from rasa.e2e_test.stub_custom_action import (
32
+ StubCustomAction,
33
+ get_stub_custom_action_key,
34
+ )
31
35
  from rasa.e2e_test.utils.validation import (
32
36
  read_e2e_test_schema,
33
37
  validate_path_to_test_cases,
@@ -41,11 +45,10 @@ from rasa.shared.utils.yaml import (
41
45
  from rasa.utils.beta import BetaNotEnabledException, ensure_beta_feature_is_enabled
42
46
 
43
47
  if TYPE_CHECKING:
44
- from rasa.e2e_test.e2e_test_result import TestResult
45
48
  from rasa.e2e_test.aggregate_test_stats_calculator import AccuracyCalculation
49
+ from rasa.e2e_test.e2e_test_result import TestResult
46
50
 
47
51
 
48
- RASA_PRO_BETA_E2E_ASSERTIONS_ENV_VAR_NAME = "RASA_PRO_BETA_E2E_ASSERTIONS"
49
52
  RASA_PRO_BETA_STUB_CUSTOM_ACTION_ENV_VAR_NAME = "RASA_PRO_BETA_STUB_CUSTOM_ACTION"
50
53
 
51
54
  structlogger = structlog.get_logger()
@@ -274,16 +277,6 @@ def split_into_passed_failed(
274
277
  return passed_cases, failed_cases
275
278
 
276
279
 
277
- def has_test_case_with_assertions(test_cases: List["TestCase"]) -> bool:
278
- """Check if the test cases contain assertions."""
279
- try:
280
- next(test_case for test_case in test_cases if test_case.uses_assertions())
281
- except StopIteration:
282
- return False
283
-
284
- return True
285
-
286
-
287
280
  @lru_cache(maxsize=1)
288
281
  def extract_test_case_from_path(path: str) -> Tuple[str, str]:
289
282
  """Extract test case from path if specified.
@@ -318,6 +311,104 @@ def is_test_case_file(file_path: Union[str, Path]) -> bool:
318
311
  )
319
312
 
320
313
 
314
+ def extract_test_cases(
315
+ test_file_content: dict,
316
+ test_case_name: str,
317
+ test_file: str,
318
+ ) -> List[TestCase]:
319
+ """Extract test cases from the test file content.
320
+
321
+ Args:
322
+ test_file_content: Content of the test file.
323
+ test_case_name: Name of the test case to extract.
324
+ test_file: Path to the test file.
325
+
326
+ Returns:
327
+ List of test cases.
328
+ """
329
+ test_cases_content = test_file_content.get(KEY_TEST_CASES) or []
330
+ if test_case_name:
331
+ return [
332
+ TestCase.from_dict(test_case_dict, file=test_file)
333
+ for test_case_dict in test_cases_content
334
+ if test_case_name == test_case_dict.get(KEY_TEST_CASE)
335
+ ]
336
+ return [
337
+ TestCase.from_dict(test_case_dict, file=test_file)
338
+ for test_case_dict in test_cases_content
339
+ ]
340
+
341
+
342
+ def extract_fixtures(
343
+ test_file_content: dict, existing_fixtures: Dict[str, Fixture]
344
+ ) -> Dict[str, Fixture]:
345
+ """Extract fixtures from the test file content.
346
+
347
+ Args:
348
+ test_file_content: Content of the test file.
349
+ existing_fixtures: Existing fixtures.
350
+
351
+ Returns:
352
+ Dict of fixtures.
353
+ """
354
+ fixtures_content = test_file_content.get(KEY_FIXTURES) or []
355
+ _fixtures = {}
356
+ for fixture in fixtures_content:
357
+ fixture_obj = Fixture.from_dict(fixture_dict=fixture)
358
+ if existing_fixtures.get(fixture_obj.name) is None:
359
+ _fixtures[fixture_obj.name] = fixture_obj
360
+ return _fixtures
361
+
362
+
363
+ def extract_metadata(
364
+ test_file_content: dict, existing_metadata: Dict[str, Metadata]
365
+ ) -> Dict[str, Metadata]:
366
+ """Extract metadata from the test file content.
367
+
368
+ Args:
369
+ test_file_content: Content of the test file.
370
+ existing_metadata: Existing metadata.
371
+
372
+ Returns:
373
+ Dict of metadata.
374
+ """
375
+ metadata_contents = test_file_content.get(KEY_METADATA) or []
376
+ _metadata = {}
377
+ for metadata_content in metadata_contents:
378
+ metadata_obj = Metadata.from_dict(metadata_dict=metadata_content)
379
+ if existing_metadata.get(metadata_obj.name) is None:
380
+ _metadata[metadata_obj.name] = metadata_obj
381
+ return _metadata
382
+
383
+
384
+ def extract_stub_custom_actions(
385
+ test_file_content: dict, test_file: str
386
+ ) -> Dict[str, StubCustomAction]:
387
+ """Extract stub custom actions from the test file content.
388
+
389
+ Args:
390
+ test_file_content: Content of the test file.
391
+ test_file: Path to the test file.
392
+
393
+ Returns:
394
+ Dict of stub custom actions.
395
+ """
396
+ stub_custom_actions_contents = test_file_content.get(KEY_STUB_CUSTOM_ACTIONS) or {}
397
+ _stub_custom_actions = {}
398
+ for action_name, stub_data in stub_custom_actions_contents.items():
399
+ if STUB_CUSTOM_ACTION_NAME_SEPARATOR in action_name:
400
+ stub_custom_action_key = action_name
401
+ else:
402
+ test_file_name = Path(test_file).name
403
+ stub_custom_action_key = get_stub_custom_action_key(
404
+ test_file_name, action_name
405
+ )
406
+ _stub_custom_actions[stub_custom_action_key] = StubCustomAction.from_dict(
407
+ action_name=action_name, stub_data=stub_data
408
+ )
409
+ return _stub_custom_actions
410
+
411
+
321
412
  def read_test_cases(path: str) -> TestSuite:
322
413
  """Read test cases from the given path.
323
414
 
@@ -327,92 +418,41 @@ def read_test_cases(path: str) -> TestSuite:
327
418
  Returns:
328
419
  TestSuite.
329
420
  """
330
- from rasa.e2e_test.stub_custom_action import (
331
- StubCustomAction,
332
- get_stub_custom_action_key,
333
- )
334
-
421
+ # Extract test case path and name
335
422
  path, test_case_name = extract_test_case_from_path(path)
336
423
  validate_path_to_test_cases(path)
337
424
 
425
+ # Load test files and schema
338
426
  test_files = rasa.shared.data.get_data_files([path], is_test_case_file)
339
427
  e2e_test_schema = read_e2e_test_schema()
340
428
 
429
+ # Initialize containers
341
430
  input_test_cases = []
342
431
  fixtures: Dict[str, Fixture] = {}
343
432
  metadata: Dict[str, Metadata] = {}
344
433
  stub_custom_actions: Dict[str, StubCustomAction] = {}
345
434
 
346
- beta_flag_verified = False
347
-
435
+ # Process each test file
348
436
  for test_file in test_files:
349
437
  test_file_content = parse_raw_yaml(Path(test_file).read_text(encoding="utf-8"))
350
438
 
439
+ # Validate YAML content using the provided function
351
440
  validate_yaml_data_using_schema_with_assertions(
352
441
  yaml_data=test_file_content, schema_content=e2e_test_schema
353
442
  )
354
443
 
355
- test_cases_content = test_file_content.get(KEY_TEST_CASES) or []
356
-
357
- if test_case_name:
358
- test_cases = [
359
- TestCase.from_dict(test_case_dict, file=test_file)
360
- for test_case_dict in test_cases_content
361
- if test_case_name == test_case_dict.get(KEY_TEST_CASE)
362
- ]
363
- else:
364
- test_cases = [
365
- TestCase.from_dict(test_case_dict, file=test_file)
366
- for test_case_dict in test_cases_content
367
- ]
368
-
369
- beta_flag_verified = verify_beta_feature_flag_for_assertions(
370
- test_cases, beta_flag_verified
444
+ # Parse test cases, fixtures, metadata, and stub custom actions
445
+ test_cases = extract_test_cases(test_file_content, test_case_name, test_file)
446
+ fixtures.update(extract_fixtures(test_file_content, fixtures))
447
+ metadata.update(extract_metadata(test_file_content, metadata))
448
+ stub_custom_actions.update(
449
+ extract_stub_custom_actions(test_file_content, test_file)
371
450
  )
372
-
373
451
  input_test_cases.extend(test_cases)
374
- fixtures_content = test_file_content.get(KEY_FIXTURES) or []
375
- for fixture in fixtures_content:
376
- fixture_obj = Fixture.from_dict(fixture_dict=fixture)
377
452
 
378
- # avoid adding duplicates from across multiple files
379
- if fixtures.get(fixture_obj.name) is None:
380
- fixtures[fixture_obj.name] = fixture_obj
381
-
382
- metadata_contents = test_file_content.get(KEY_METADATA) or []
383
- for metadata_content in metadata_contents:
384
- metadata_obj = Metadata.from_dict(metadata_dict=metadata_content)
385
-
386
- # avoid adding duplicates from across multiple files
387
- if metadata.get(metadata_obj.name) is None:
388
- metadata[metadata_obj.name] = metadata_obj
389
-
390
- stub_custom_actions_contents = (
391
- test_file_content.get(KEY_STUB_CUSTOM_ACTIONS) or {}
392
- )
393
-
394
- for action_name, stub_data in stub_custom_actions_contents.items():
395
- if STUB_CUSTOM_ACTION_NAME_SEPARATOR in action_name:
396
- stub_custom_action_key = action_name
397
- else:
398
- test_file_name = Path(test_file).name
399
- stub_custom_action_key = get_stub_custom_action_key(
400
- test_file_name, action_name
401
- )
402
- stub_custom_actions[stub_custom_action_key] = StubCustomAction.from_dict(
403
- action_name=action_name,
404
- stub_data=stub_data,
405
- )
406
-
407
- validate_test_case(test_case_name, input_test_cases)
408
- try:
409
- if stub_custom_actions:
410
- ensure_beta_feature_is_enabled(
411
- "enabling stubs for custom actions",
412
- RASA_PRO_BETA_STUB_CUSTOM_ACTION_ENV_VAR_NAME,
413
- )
414
- except BetaNotEnabledException as exc:
415
- rasa.shared.utils.cli.print_error_and_exit(str(exc))
453
+ validate_test_case(test_case_name, input_test_cases, fixtures, metadata)
454
+ if stub_custom_actions:
455
+ check_beta_feature_flag_for_custom_actions_stubs()
416
456
 
417
457
  return TestSuite(
418
458
  input_test_cases,
@@ -422,26 +462,16 @@ def read_test_cases(path: str) -> TestSuite:
422
462
  )
423
463
 
424
464
 
425
- def verify_beta_feature_flag_for_assertions(
426
- test_cases: List["TestCase"], beta_flag_verified: bool
427
- ) -> bool:
428
- """Verify the beta feature flag for assertions."""
429
- if beta_flag_verified:
430
- return True
431
-
432
- if not has_test_case_with_assertions(test_cases):
433
- return beta_flag_verified
434
-
465
+ def check_beta_feature_flag_for_custom_actions_stubs() -> None:
466
+ """Check the beta feature flag for custom actions stub and exit if not enabled."""
435
467
  try:
436
468
  ensure_beta_feature_is_enabled(
437
- "end-to-end testing with assertions",
438
- RASA_PRO_BETA_E2E_ASSERTIONS_ENV_VAR_NAME,
469
+ "enabling stubs for custom actions",
470
+ RASA_PRO_BETA_STUB_CUSTOM_ACTION_ENV_VAR_NAME,
439
471
  )
440
472
  except BetaNotEnabledException as exc:
441
473
  rasa.shared.utils.cli.print_error_and_exit(str(exc))
442
474
 
443
- return True
444
-
445
475
 
446
476
  def _save_coverage_report(
447
477
  report: Optional[pd.DataFrame], test_status: str, output_dir: str
@@ -1,11 +1,12 @@
1
1
  import sys
2
2
  from pathlib import Path
3
- from typing import Any, Dict, List, Optional, TYPE_CHECKING, Union
3
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
4
4
 
5
5
  import structlog
6
6
 
7
7
  import rasa.shared.utils.io
8
8
  from rasa.e2e_test.constants import SCHEMA_FILE_PATH
9
+ from rasa.e2e_test.e2e_test_case import Fixture, Metadata
9
10
  from rasa.shared.utils.yaml import read_schema_file
10
11
 
11
12
  if TYPE_CHECKING:
@@ -27,8 +28,24 @@ def validate_path_to_test_cases(path: str) -> None:
27
28
  sys.exit(1)
28
29
 
29
30
 
30
- def validate_test_case(test_case_name: str, input_test_cases: List["TestCase"]) -> None:
31
- """Validate that test case exists."""
31
+ def validate_test_case(
32
+ test_case_name: str,
33
+ input_test_cases: List["TestCase"],
34
+ fixtures: Dict[str, Fixture],
35
+ metadata: Dict[str, Metadata],
36
+ ) -> None:
37
+ """
38
+ Validate the test case, its fixtures, and metadata.
39
+
40
+ Args:
41
+ test_case_name (str): The name of the test case to validate.
42
+ input_test_cases (List["TestCase"]): A list of test cases to validate.
43
+ fixtures (Dict[str, Fixture]): A dictionary of defined fixtures.
44
+ metadata (Dict[str, Metadata]): A dictionary of defined metadata.
45
+
46
+ Raises:
47
+ SystemExit: If the test case, fixtures, or metadata are not defined.
48
+ """
32
49
  if test_case_name and not input_test_cases:
33
50
  rasa.shared.utils.io.raise_warning(
34
51
  f"Test case does not exist: {test_case_name}. "
@@ -38,6 +55,87 @@ def validate_test_case(test_case_name: str, input_test_cases: List["TestCase"])
38
55
  )
39
56
  sys.exit(1)
40
57
 
58
+ all_good = True
59
+ for test_case in input_test_cases:
60
+ all_good_fixtures = validate_test_case_fixtures(test_case, fixtures)
61
+ all_good_metadata = validate_test_case_metadata(test_case, metadata)
62
+ all_good = all_good and all_good_fixtures and all_good_metadata
63
+
64
+ if not all_good:
65
+ sys.exit(1)
66
+
67
+
68
+ def validate_test_case_fixtures(
69
+ test_case: "TestCase", fixtures: Dict[str, Fixture]
70
+ ) -> bool:
71
+ """Validates that the fixtures used in the test case are defined.
72
+
73
+ Args:
74
+ test_case (TestCase): The test case to validate.
75
+ fixtures (Dict[str, Fixture]): A dictionary of defined fixtures.
76
+
77
+ Returns:
78
+ True if all fixtures used in the test case are defined, False otherwise.
79
+
80
+ Raises:
81
+ Logs an error if a fixture used in the test case is not defined.
82
+ """
83
+ all_good = True
84
+ if not test_case.fixture_names:
85
+ return all_good
86
+
87
+ for fixture_name in test_case.fixture_names:
88
+ if fixture_name not in fixtures:
89
+ structlogger.error(
90
+ "validation.validate_test_case_fixtures",
91
+ event_info=(
92
+ f"Fixture '{fixture_name}' referenced in the "
93
+ f"test case '{test_case.name}' is not defined."
94
+ ),
95
+ )
96
+ all_good = False
97
+ return all_good
98
+
99
+
100
+ def validate_test_case_metadata(
101
+ test_case: "TestCase", metadata: Dict[str, Metadata]
102
+ ) -> bool:
103
+ """
104
+ Validates that the metadata used in the test case and its steps are defined.
105
+
106
+ Args:
107
+ test_case (TestCase): The test case to validate.
108
+ metadata (Dict[str, Metadata]): A dictionary of defined metadata.
109
+
110
+ Returns:
111
+ True if all fixtures used in the test case are defined, False otherwise.
112
+
113
+ Raises:
114
+ Logs an error if metadata used in the test case or its steps is not defined.
115
+ """
116
+ all_good = True
117
+ if test_case.metadata_name and test_case.metadata_name not in metadata:
118
+ structlogger.error(
119
+ "validation.validate_test_case_metadata.test_case_metadata",
120
+ event_info=(
121
+ f"Metadata '{test_case.metadata_name}' referenced in "
122
+ f"the test case '{test_case.name}' is not defined."
123
+ ),
124
+ )
125
+ all_good = False
126
+
127
+ for step in test_case.steps:
128
+ if step.metadata_name and step.metadata_name not in metadata:
129
+ structlogger.error(
130
+ "validation.validate_test_case_metadata.step_metadata",
131
+ event_info=(
132
+ f"Metadata '{step.metadata_name}' referenced in the "
133
+ f"step of the test case '{test_case.name}' is not defined."
134
+ ),
135
+ )
136
+ all_good = False
137
+ return all_good
138
+
41
139
 
42
140
  def validate_model_path(model_path: Optional[str], parameter: str, default: str) -> str:
43
141
  """Validate the model path.
rasa/engine/caching.py CHANGED
@@ -5,27 +5,25 @@ import logging
5
5
  import shutil
6
6
  from datetime import datetime
7
7
  from pathlib import Path
8
- from typing import Text, Any, Optional, Tuple, List
8
+ from typing import Any, List, Optional, Text, Tuple
9
9
 
10
+ import sqlalchemy as sa
11
+ import sqlalchemy.orm
10
12
  from packaging import version
11
13
  from sqlalchemy.engine import URL
12
-
13
14
  from sqlalchemy.exc import OperationalError
14
15
  from typing_extensions import Protocol, runtime_checkable
15
16
 
16
17
  import rasa
17
18
  import rasa.model
18
- import rasa.utils.common
19
19
  import rasa.shared.utils.common
20
+ import rasa.utils.common
20
21
  from rasa.constants import MINIMUM_COMPATIBLE_VERSION
21
- import sqlalchemy as sa
22
- import sqlalchemy.orm
23
-
24
22
  from rasa.engine.storage.storage import ModelStorage
25
23
  from rasa.shared.engine.caching import (
24
+ get_cache_database_name,
26
25
  get_local_cache_location,
27
26
  get_max_cache_size,
28
- get_cache_database_name,
29
27
  )
30
28
 
31
29
  logger = logging.getLogger(__name__)
rasa/engine/constants.py CHANGED
@@ -1,9 +1,9 @@
1
1
  from typing import List, Optional
2
2
 
3
3
  from rasa.core.channels import UserMessage
4
+ from rasa.core.utils import AvailableEndpoints
4
5
  from rasa.shared.core.trackers import DialogueStateTracker
5
6
  from rasa.shared.importers.importer import TrainingDataImporter
6
- from rasa.core.utils import AvailableEndpoints
7
7
 
8
8
  PLACEHOLDER_IMPORTER = "__importer__"
9
9
  PLACEHOLDER_MESSAGE = "__message__"
rasa/engine/graph.py CHANGED
@@ -1,12 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import asyncio
3
4
  import dataclasses
4
5
  from abc import ABC, abstractmethod
5
6
  from dataclasses import dataclass, field
6
- from typing import Any, Callable, Dict, List, Optional, Text, Type, Tuple, Union
7
+ from typing import Any, Callable, Dict, List, Optional, Text, Tuple, Type, Union
7
8
 
8
9
  import structlog
9
- import asyncio
10
10
 
11
11
  import rasa.shared.utils.common
12
12
  import rasa.utils.common
@@ -640,3 +640,4 @@ class GraphModelConfiguration:
640
640
  language: Optional[Text]
641
641
  core_target: Optional[Text]
642
642
  nlu_target: Optional[Text]
643
+ additional_languages: Optional[List[Text]]
@@ -0,0 +1,182 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any, Dict, Text
3
+
4
+ from langcodes import Language as LangcodesLanguage
5
+ from langcodes import standardize_tag
6
+ from langcodes.tag_parser import LanguageTagError
7
+
8
+ from rasa.shared.exceptions import RasaException
9
+
10
+ CUSTOM_LANGUAGE_CODE_PREFIX = "x-"
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class Language:
15
+ code: str
16
+ label: str
17
+ is_default: bool
18
+
19
+ @classmethod
20
+ def from_language_code(
21
+ cls, language_code: str, is_default: bool = False
22
+ ) -> "Language":
23
+ """Creates a Language object from a language code.
24
+
25
+ Args:
26
+ language_code: The language code.
27
+ is_default: Whether the language is the default language.
28
+
29
+ Returns:
30
+ A Language object.
31
+
32
+ Raises:
33
+ RasaException: If the language code or custom language code is invalid.
34
+ """
35
+ if cls.is_custom_language_code(language_code):
36
+ cls.validate_custom_language_code(language_code)
37
+ elif not cls.is_language_code_bcp_47_standard(language_code):
38
+ raise RasaException(
39
+ f"Language '{language_code}' is not a BCP 47 standard language code."
40
+ )
41
+
42
+ language = LangcodesLanguage.get(language_code)
43
+ return cls(
44
+ code=language_code,
45
+ label=cls.get_language_label(language),
46
+ is_default=is_default,
47
+ )
48
+
49
+ @staticmethod
50
+ def is_language_code_bcp_47_standard(language_code: str) -> bool:
51
+ """Checks if a language code is a BCP 47 standard language code.
52
+
53
+ Args:
54
+ language_code: The language code to check.
55
+
56
+ Returns:
57
+ `True` if the language code is a BCP 47 standard, `False` otherwise.
58
+ """
59
+ try:
60
+ standardized_language_code = standardize_tag(language_code)
61
+ return (
62
+ standardized_language_code == language_code
63
+ and LangcodesLanguage.get(language_code).is_valid()
64
+ )
65
+ except LanguageTagError:
66
+ return False
67
+
68
+ @staticmethod
69
+ def is_custom_language_code(language_code: str) -> bool:
70
+ """Checks if a language code is a custom language code.
71
+
72
+ Args:
73
+ language_code: The language code to check.
74
+
75
+ Returns:
76
+ `True` if the language code is a custom language code, `False` otherwise.
77
+ """
78
+ return language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX)
79
+
80
+ @classmethod
81
+ def get_language_label(cls, language: LangcodesLanguage) -> str:
82
+ """Gets the display name of a language.
83
+
84
+ For custom languages (in the format "x-<base_lang>-<custom_label>"),
85
+ the label is derived from the base language code.
86
+ This method considers that the language code has previously been validated.
87
+
88
+ Args:
89
+ language: The language code.
90
+
91
+ Returns:
92
+ The display name of the language.
93
+ """
94
+ language_code = str(language)
95
+
96
+ if cls.is_custom_language_code(language_code):
97
+ # If it's a custom language, derive the label from the base language code.
98
+ without_prefix = language_code[len(CUSTOM_LANGUAGE_CODE_PREFIX) :]
99
+ base_language_code, _ = without_prefix.rsplit("-", 1)
100
+ base_language = LangcodesLanguage.get(base_language_code)
101
+ return base_language.display_name()
102
+ else:
103
+ return language.display_name()
104
+
105
+ @classmethod
106
+ def validate_language(cls, language: LangcodesLanguage) -> None:
107
+ """Validates a language code.
108
+
109
+ Args:
110
+ language: The language object to validate.
111
+
112
+ Raises:
113
+ RasaException: If the language validation fails.
114
+ """
115
+ if not language.is_valid():
116
+ raise RasaException(f"Language '{language}' is not a valid language code.")
117
+
118
+ language_code = str(language)
119
+ if language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX):
120
+ cls.validate_custom_language_code(language_code)
121
+
122
+ @classmethod
123
+ def validate_custom_language_code(cls, custom_language_code: str) -> None:
124
+ """Validates a custom language code.
125
+
126
+ A valid custom language code should adhere to the format:
127
+ "x-<existing_language_code>-<custom_label>"
128
+ Example: x-en-formal or x-en-US-formal.
129
+
130
+ Args:
131
+ custom_language_code: The custom language code to validate.
132
+
133
+ Raises:
134
+ RasaException: If the custom language code validation fails.
135
+ """
136
+ # Ensure the custom language code starts with the custom prefix.
137
+ if not custom_language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX):
138
+ raise RasaException(
139
+ f"Custom language '{custom_language_code}' must "
140
+ f"start with '{CUSTOM_LANGUAGE_CODE_PREFIX}'."
141
+ )
142
+
143
+ # Remove the custom prefix.
144
+ without_prefix = custom_language_code[len(CUSTOM_LANGUAGE_CODE_PREFIX) :]
145
+ if "-" not in without_prefix:
146
+ raise RasaException(
147
+ f"Custom language '{custom_language_code}' must be in the format "
148
+ f"'{CUSTOM_LANGUAGE_CODE_PREFIX}<language_code>-<custom_label>'."
149
+ )
150
+
151
+ base_language_code, custom_label = without_prefix.rsplit("-", 1)
152
+ if not base_language_code:
153
+ raise RasaException(
154
+ f"Base language in '{custom_language_code}' cannot be empty. "
155
+ f"Expected custom language code format is "
156
+ f"'{CUSTOM_LANGUAGE_CODE_PREFIX}<language_code>-<custom_label>'."
157
+ )
158
+ if not custom_label:
159
+ raise RasaException(
160
+ f"Custom label in '{custom_language_code}' cannot be empty."
161
+ f"Expected custom language code format is "
162
+ f"'{CUSTOM_LANGUAGE_CODE_PREFIX}<language_code>-<custom_label>'."
163
+ )
164
+
165
+ # Validate the base language code using langcodes.
166
+ if not cls.is_language_code_bcp_47_standard(base_language_code):
167
+ raise RasaException(
168
+ f"Base language '{base_language_code}' in custom language "
169
+ f"'{custom_language_code}' is not a valid language code."
170
+ )
171
+
172
+ def as_dict(self) -> Dict[Text, Any]:
173
+ """Converts the Language dataclass instance into a dictionary.
174
+
175
+ Returns:
176
+ A dictionary representing the Language object.
177
+ """
178
+ return {
179
+ "code": self.code,
180
+ "label": self.label,
181
+ "is_default": self.is_default,
182
+ }
@@ -9,6 +9,10 @@ assistant_id: placeholder_default
9
9
  # Configuration for the Rasa NLU components.
10
10
  # https://rasa.com/docs/rasa-pro/nlu-based-assistants/components
11
11
  language: en
12
+ additional_languages:
13
+ - it
14
+ - de
15
+ - es
12
16
 
13
17
  pipeline:
14
18
  - name: WhitespaceTokenizer