rasa-pro 3.11.5__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 (559) 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 +135 -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/{arc-f0f8bd46.js → arc-9f1365dc.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7162c77d.js → blockDiagram-38ab4fdb-e0f81b12.js} +1 -1
  71. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-b1d0d098.js → c4Diagram-3d4e48cf-9deaee1c.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/channel-44956714.js +1 -0
  73. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-807a1b27.js → classDiagram-70f12bd4-20450a96.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-5238dcdb.js → classDiagram-v2-f2320105-749d2abf.js} +1 -1
  75. rasa/core/channels/inspector/dist/assets/clone-a9475142.js +1 -0
  76. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-75dfaa67.js → createText-2e5e7dd3-bef0b38c.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-df20501d.js → edges-e0da2a9e-943801a7.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-13cf4797.js → erDiagram-9861fffd-d523a948.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-a4991264.js → flowDb-956e92f1-54e4cf19.js} +1 -1
  80. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-ccecf773.js → flowDiagram-66a62f08-48bfbbe8.js} +1 -1
  81. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-43fa749a.js +1 -0
  82. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-b5801783.js → flowchart-elk-definition-4a651766-17c30827.js} +1 -1
  83. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-161e079a.js → ganttDiagram-c361ad54-43086f2d.js} +1 -1
  84. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-f38e86a4.js → gitGraphDiagram-72cf32ee-5c8b693e.js} +1 -1
  85. rasa/core/channels/inspector/dist/assets/{graph-be6ef5d8.js → graph-41a90d26.js} +1 -1
  86. rasa/core/channels/inspector/dist/assets/{index-3862675e-d9ce8994.js → index-3862675e-b43eeae9.js} +1 -1
  87. rasa/core/channels/inspector/dist/assets/{index-7794b245.js → index-e8affe45.js} +155 -155
  88. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-5000a3dc.js → infoDiagram-f8f76790-0b20676b.js} +1 -1
  89. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-8ef0a17a.js → journeyDiagram-49397b02-39bce7b5.js} +1 -1
  90. rasa/core/channels/inspector/dist/assets/{layout-d649bc98.js → layout-dc8eeea4.js} +1 -1
  91. rasa/core/channels/inspector/dist/assets/{line-95add810.js → line-c4d2e756.js} +1 -1
  92. rasa/core/channels/inspector/dist/assets/{linear-f6025094.js → linear-86f6f2d9.js} +1 -1
  93. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-2e8531c4.js → mindmap-definition-fc14e90a-4216f771.js} +1 -1
  94. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-918adfdb.js → pieDiagram-8a3498a8-1a0cfa96.js} +1 -1
  95. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-cbd01797.js → quadrantDiagram-120e2f19-f91e67cf.js} +1 -1
  96. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6a8b877b.js → requirementDiagram-deff3bca-d4046bed.js} +1 -1
  97. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-c377c3fe.js → sankeyDiagram-04a897e0-2cf6d1d7.js} +1 -1
  98. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-ab9e9b7f.js → sequenceDiagram-704730f1-751ac4f5.js} +1 -1
  99. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-5e6ae67d.js → stateDiagram-587899a1-f734f4d4.js} +1 -1
  100. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-40643476.js → stateDiagram-v2-d93cdb3a-91c65710.js} +1 -1
  101. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-afb8d108.js → styles-6aaf32cf-e0cff7be.js} +1 -1
  102. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-7edc9423.js → styles-9a916d00-c8029e5d.js} +1 -1
  103. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-c1d8f7e9.js → styles-c10674c1-114f312a.js} +1 -1
  104. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f494b2ef.js → svgDrawCommon-08f97a94-b7b9dc00.js} +1 -1
  105. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-11c7cdd0.js → timeline-definition-85554ec2-9536d189.js} +1 -1
  106. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-3f191ec1.js → xychartDiagram-e933f94c-bf3b0f36.js} +1 -1
  107. rasa/core/channels/inspector/dist/index.html +1 -1
  108. rasa/core/channels/inspector/package.json +1 -0
  109. rasa/core/channels/inspector/src/App.tsx +15 -2
  110. rasa/core/channels/inspector/src/components/RasaLogo.tsx +31 -0
  111. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +68 -0
  112. rasa/core/channels/inspector/src/components/Welcome.tsx +19 -13
  113. rasa/core/channels/inspector/yarn.lock +5 -0
  114. rasa/core/channels/mattermost.py +4 -4
  115. rasa/core/channels/rasa_chat.py +4 -4
  116. rasa/core/channels/rest.py +11 -12
  117. rasa/core/channels/rocketchat.py +4 -3
  118. rasa/core/channels/slack.py +6 -5
  119. rasa/core/channels/socketio.py +8 -28
  120. rasa/core/channels/studio_chat.py +212 -0
  121. rasa/core/channels/telegram.py +105 -55
  122. rasa/core/channels/twilio.py +3 -3
  123. rasa/core/channels/vier_cvg.py +2 -2
  124. rasa/core/channels/voice_ready/audiocodes.py +9 -9
  125. rasa/core/channels/voice_ready/jambonz.py +5 -5
  126. rasa/core/channels/voice_ready/jambonz_protocol.py +3 -4
  127. rasa/core/channels/voice_ready/twilio_voice.py +9 -8
  128. rasa/core/channels/voice_ready/utils.py +2 -2
  129. rasa/core/channels/voice_stream/asr/asr_engine.py +12 -6
  130. rasa/core/channels/voice_stream/asr/asr_event.py +5 -0
  131. rasa/core/channels/voice_stream/asr/azure.py +16 -3
  132. rasa/core/channels/voice_stream/asr/deepgram.py +76 -19
  133. rasa/core/channels/voice_stream/audiocodes.py +292 -0
  134. rasa/core/channels/voice_stream/browser_audio.py +14 -7
  135. rasa/core/channels/voice_stream/call_state.py +6 -2
  136. rasa/core/channels/voice_stream/genesys.py +320 -0
  137. rasa/core/channels/voice_stream/tts/azure.py +13 -5
  138. rasa/core/channels/voice_stream/tts/cartesia.py +34 -14
  139. rasa/core/channels/voice_stream/tts/tts_cache.py +3 -2
  140. rasa/core/channels/voice_stream/tts/tts_engine.py +1 -1
  141. rasa/core/channels/voice_stream/twilio_media_streams.py +12 -8
  142. rasa/core/channels/voice_stream/util.py +1 -1
  143. rasa/core/channels/voice_stream/voice_channel.py +100 -56
  144. rasa/core/channels/webexteams.py +3 -4
  145. rasa/core/constants.py +2 -0
  146. rasa/core/evaluation/marker.py +7 -6
  147. rasa/core/evaluation/marker_base.py +15 -16
  148. rasa/core/evaluation/marker_stats.py +3 -4
  149. rasa/core/evaluation/marker_tracker_loader.py +5 -4
  150. rasa/core/exporter.py +4 -4
  151. rasa/core/featurizers/precomputation.py +8 -8
  152. rasa/core/featurizers/single_state_featurizer.py +7 -7
  153. rasa/core/featurizers/tracker_featurizers.py +13 -13
  154. rasa/core/http_interpreter.py +3 -4
  155. rasa/core/information_retrieval/__init__.py +1 -1
  156. rasa/core/information_retrieval/faiss.py +4 -4
  157. rasa/core/information_retrieval/information_retrieval.py +2 -2
  158. rasa/core/information_retrieval/milvus.py +3 -3
  159. rasa/core/information_retrieval/qdrant.py +3 -3
  160. rasa/core/jobs.py +1 -0
  161. rasa/core/lock.py +2 -3
  162. rasa/core/lock_store.py +3 -3
  163. rasa/core/migrate.py +12 -9
  164. rasa/core/nlg/__init__.py +1 -1
  165. rasa/core/nlg/callback.py +2 -3
  166. rasa/core/nlg/contextual_response_rephraser.py +82 -14
  167. rasa/core/nlg/generator.py +85 -17
  168. rasa/core/nlg/interpolator.py +4 -3
  169. rasa/core/nlg/response.py +9 -7
  170. rasa/core/nlg/summarize.py +1 -0
  171. rasa/core/nlg/translate.py +55 -0
  172. rasa/core/persistor.py +3 -3
  173. rasa/core/policies/ensemble.py +10 -9
  174. rasa/core/policies/enterprise_search_policy.py +87 -21
  175. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +1 -1
  176. rasa/core/policies/flow_policy.py +13 -14
  177. rasa/core/policies/flows/flow_executor.py +85 -55
  178. rasa/core/policies/intentless_policy.py +6 -7
  179. rasa/core/policies/memoization.py +22 -20
  180. rasa/core/policies/policy.py +24 -22
  181. rasa/core/policies/rule_policy.py +37 -36
  182. rasa/core/policies/ted_policy.py +87 -85
  183. rasa/core/policies/unexpected_intent_policy.py +77 -75
  184. rasa/core/processor.py +167 -74
  185. rasa/core/run.py +5 -4
  186. rasa/core/secrets_manager/endpoints.py +2 -3
  187. rasa/core/secrets_manager/factory.py +2 -3
  188. rasa/core/secrets_manager/secret_manager.py +2 -3
  189. rasa/core/secrets_manager/vault.py +2 -2
  190. rasa/core/test.py +30 -30
  191. rasa/core/tracker_store.py +138 -49
  192. rasa/core/train.py +1 -1
  193. rasa/core/training/__init__.py +2 -2
  194. rasa/core/training/converters/responses_prefix_converter.py +1 -2
  195. rasa/core/training/interactive.py +13 -13
  196. rasa/core/training/story_conflict.py +4 -5
  197. rasa/core/training/training.py +3 -5
  198. rasa/core/utils.py +5 -5
  199. rasa/core/visualize.py +1 -1
  200. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -2
  201. rasa/dialogue_understanding/coexistence/llm_based_router.py +5 -5
  202. rasa/dialogue_understanding/commands/__init__.py +22 -22
  203. rasa/dialogue_understanding/commands/can_not_handle_command.py +38 -1
  204. rasa/dialogue_understanding/commands/cancel_flow_command.py +96 -9
  205. rasa/dialogue_understanding/commands/change_flow_command.py +36 -2
  206. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +36 -4
  207. rasa/dialogue_understanding/commands/clarify_command.py +46 -4
  208. rasa/dialogue_understanding/commands/command.py +3 -2
  209. rasa/dialogue_understanding/commands/command_syntax_manager.py +55 -0
  210. rasa/dialogue_understanding/commands/correct_slots_command.py +14 -5
  211. rasa/dialogue_understanding/commands/error_command.py +1 -1
  212. rasa/dialogue_understanding/commands/free_form_answer_command.py +2 -1
  213. rasa/dialogue_understanding/commands/handle_code_change_command.py +2 -2
  214. rasa/dialogue_understanding/commands/handle_digressions_command.py +144 -0
  215. rasa/dialogue_understanding/commands/human_handoff_command.py +34 -4
  216. rasa/dialogue_understanding/commands/knowledge_answer_command.py +36 -4
  217. rasa/dialogue_understanding/commands/noop_command.py +2 -1
  218. rasa/dialogue_understanding/commands/prompt_command.py +94 -0
  219. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +34 -4
  220. rasa/dialogue_understanding/commands/restart_command.py +2 -5
  221. rasa/dialogue_understanding/commands/session_end_command.py +3 -5
  222. rasa/dialogue_understanding/commands/session_start_command.py +3 -5
  223. rasa/dialogue_understanding/commands/set_slot_command.py +55 -16
  224. rasa/dialogue_understanding/commands/skip_question_command.py +34 -4
  225. rasa/dialogue_understanding/commands/start_flow_command.py +78 -2
  226. rasa/dialogue_understanding/commands/user_silence_command.py +3 -5
  227. rasa/dialogue_understanding/commands/utils.py +126 -43
  228. rasa/dialogue_understanding/constants.py +2 -0
  229. rasa/dialogue_understanding/generator/__init__.py +2 -0
  230. rasa/dialogue_understanding/generator/command_generator.py +120 -79
  231. rasa/dialogue_understanding/generator/command_parser.py +245 -0
  232. rasa/dialogue_understanding/generator/constants.py +12 -4
  233. rasa/dialogue_understanding/generator/flow_retrieval.py +7 -7
  234. rasa/dialogue_understanding/generator/llm_based_command_generator.py +187 -59
  235. rasa/dialogue_understanding/generator/llm_command_generator.py +6 -3
  236. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +106 -110
  237. rasa/dialogue_understanding/generator/nlu_command_adapter.py +53 -11
  238. rasa/dialogue_understanding/generator/prompt_templates/__init__.py +0 -0
  239. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +58 -0
  240. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +57 -0
  241. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +574 -0
  242. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +41 -386
  243. rasa/dialogue_understanding/generator/utils.py +76 -0
  244. rasa/dialogue_understanding/patterns/cancel.py +2 -1
  245. rasa/dialogue_understanding/patterns/cannot_handle.py +1 -0
  246. rasa/dialogue_understanding/patterns/chitchat.py +1 -1
  247. rasa/dialogue_understanding/patterns/clarify.py +2 -1
  248. rasa/dialogue_understanding/patterns/code_change.py +2 -0
  249. rasa/dialogue_understanding/patterns/collect_information.py +7 -4
  250. rasa/dialogue_understanding/patterns/completed.py +1 -1
  251. rasa/dialogue_understanding/patterns/continue_interrupted.py +1 -1
  252. rasa/dialogue_understanding/patterns/correction.py +17 -3
  253. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +78 -2
  254. rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
  255. rasa/dialogue_understanding/patterns/human_handoff.py +1 -1
  256. rasa/dialogue_understanding/patterns/internal_error.py +1 -0
  257. rasa/dialogue_understanding/patterns/search.py +1 -1
  258. rasa/dialogue_understanding/patterns/session_start.py +1 -1
  259. rasa/dialogue_understanding/patterns/skip_question.py +1 -0
  260. rasa/dialogue_understanding/patterns/user_silence.py +1 -1
  261. rasa/dialogue_understanding/patterns/validate_slot.py +65 -0
  262. rasa/dialogue_understanding/processor/command_processor.py +193 -43
  263. rasa/dialogue_understanding/processor/command_processor_component.py +1 -1
  264. rasa/dialogue_understanding/stack/dialogue_stack.py +4 -3
  265. rasa/dialogue_understanding/stack/frames/__init__.py +2 -2
  266. rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +4 -1
  267. rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +2 -3
  268. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +5 -2
  269. rasa/dialogue_understanding/stack/frames/search_frame.py +4 -1
  270. rasa/dialogue_understanding/stack/utils.py +56 -10
  271. rasa/dialogue_understanding/utils.py +164 -0
  272. rasa/dialogue_understanding_test/README.md +429 -0
  273. rasa/dialogue_understanding_test/__init__.py +0 -0
  274. rasa/dialogue_understanding_test/command_comparison.py +60 -0
  275. rasa/dialogue_understanding_test/command_metric_calculation.py +122 -0
  276. rasa/dialogue_understanding_test/constants.py +22 -0
  277. rasa/dialogue_understanding_test/du_test_case.py +448 -0
  278. rasa/dialogue_understanding_test/du_test_result.py +390 -0
  279. rasa/dialogue_understanding_test/du_test_runner.py +322 -0
  280. rasa/dialogue_understanding_test/du_test_schema.yml +161 -0
  281. rasa/dialogue_understanding_test/io.py +443 -0
  282. rasa/dialogue_understanding_test/test_case_simulation/__init__.py +0 -0
  283. rasa/dialogue_understanding_test/test_case_simulation/exception.py +28 -0
  284. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +336 -0
  285. rasa/dialogue_understanding_test/utils.py +70 -0
  286. rasa/dialogue_understanding_test/validation.py +77 -0
  287. rasa/e2e_test/aggregate_test_stats_calculator.py +1 -1
  288. rasa/e2e_test/assertions.py +202 -175
  289. rasa/e2e_test/assertions_schema.yml +6 -0
  290. rasa/e2e_test/constants.py +16 -1
  291. rasa/e2e_test/e2e_config.py +102 -41
  292. rasa/e2e_test/e2e_config_schema.yml +28 -10
  293. rasa/e2e_test/e2e_test_case.py +5 -5
  294. rasa/e2e_test/e2e_test_converter.py +2 -3
  295. rasa/e2e_test/e2e_test_coverage_report.py +6 -6
  296. rasa/e2e_test/e2e_test_result.py +1 -1
  297. rasa/e2e_test/e2e_test_runner.py +143 -38
  298. rasa/e2e_test/llm_judge_prompts/answer_relevance_prompt_template.jinja2 +93 -0
  299. rasa/e2e_test/llm_judge_prompts/groundedness_prompt_template.jinja2 +169 -0
  300. rasa/e2e_test/stub_custom_action.py +1 -1
  301. rasa/e2e_test/utils/generative_assertions.py +243 -0
  302. rasa/e2e_test/utils/io.py +123 -93
  303. rasa/e2e_test/utils/validation.py +101 -3
  304. rasa/engine/caching.py +5 -7
  305. rasa/engine/constants.py +1 -1
  306. rasa/engine/graph.py +3 -2
  307. rasa/engine/language.py +182 -0
  308. rasa/engine/recipes/config_files/default_config.yml +4 -0
  309. rasa/engine/recipes/default_components.py +13 -15
  310. rasa/engine/recipes/default_recipe.py +65 -49
  311. rasa/engine/recipes/graph_recipe.py +10 -7
  312. rasa/engine/recipes/recipe.py +2 -2
  313. rasa/engine/runner/dask.py +2 -2
  314. rasa/engine/runner/interface.py +1 -0
  315. rasa/engine/storage/local_model_storage.py +6 -4
  316. rasa/engine/storage/resource.py +2 -1
  317. rasa/engine/storage/storage.py +8 -3
  318. rasa/engine/training/components.py +2 -1
  319. rasa/engine/training/fingerprinting.py +4 -2
  320. rasa/engine/training/graph_trainer.py +4 -4
  321. rasa/engine/training/hooks.py +2 -2
  322. rasa/engine/validation.py +36 -33
  323. rasa/exceptions.py +3 -2
  324. rasa/graph_components/converters/nlu_message_converter.py +3 -3
  325. rasa/graph_components/providers/domain_for_core_training_provider.py +3 -3
  326. rasa/graph_components/providers/domain_provider.py +3 -2
  327. rasa/graph_components/providers/flows_provider.py +2 -3
  328. rasa/graph_components/providers/forms_provider.py +4 -4
  329. rasa/graph_components/providers/nlu_training_data_provider.py +5 -3
  330. rasa/graph_components/providers/responses_provider.py +4 -4
  331. rasa/graph_components/providers/rule_only_provider.py +3 -2
  332. rasa/graph_components/providers/story_graph_provider.py +8 -8
  333. rasa/graph_components/providers/training_tracker_provider.py +3 -2
  334. rasa/graph_components/validators/default_recipe_validator.py +16 -16
  335. rasa/graph_components/validators/finetuning_validator.py +10 -8
  336. rasa/hooks.py +19 -14
  337. rasa/jupyter.py +2 -2
  338. rasa/llm_fine_tuning/annotation_module.py +4 -4
  339. rasa/llm_fine_tuning/conversations.py +5 -33
  340. rasa/llm_fine_tuning/llm_data_preparation_module.py +6 -4
  341. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -4
  342. rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +18 -13
  343. rasa/llm_fine_tuning/paraphrasing_module.py +6 -2
  344. rasa/llm_fine_tuning/storage.py +3 -3
  345. rasa/llm_fine_tuning/train_test_split_module.py +27 -27
  346. rasa/llm_fine_tuning/utils.py +7 -0
  347. rasa/markers/marker.py +2 -3
  348. rasa/markers/marker_base.py +1 -2
  349. rasa/markers/upload.py +2 -2
  350. rasa/markers/validate.py +2 -3
  351. rasa/model.py +3 -5
  352. rasa/model_manager/config.py +1 -1
  353. rasa/model_manager/model_api.py +5 -4
  354. rasa/model_manager/runner_service.py +13 -10
  355. rasa/model_manager/socket_bridge.py +15 -9
  356. rasa/model_manager/studio_jwt_auth.py +1 -0
  357. rasa/model_manager/trainer_service.py +9 -7
  358. rasa/model_manager/utils.py +1 -1
  359. rasa/model_manager/warm_rasa_process.py +14 -9
  360. rasa/model_service.py +5 -6
  361. rasa/model_testing.py +13 -15
  362. rasa/model_training.py +29 -29
  363. rasa/nlu/classifiers/diet_classifier.py +72 -73
  364. rasa/nlu/classifiers/fallback_classifier.py +9 -8
  365. rasa/nlu/classifiers/keyword_intent_classifier.py +7 -6
  366. rasa/nlu/classifiers/logistic_regression_classifier.py +3 -3
  367. rasa/nlu/classifiers/mitie_intent_classifier.py +5 -4
  368. rasa/nlu/classifiers/regex_message_handler.py +3 -2
  369. rasa/nlu/classifiers/sklearn_intent_classifier.py +2 -2
  370. rasa/nlu/convert.py +2 -2
  371. rasa/nlu/emulators/dialogflow.py +3 -3
  372. rasa/nlu/emulators/luis.py +5 -5
  373. rasa/nlu/emulators/no_emulator.py +1 -0
  374. rasa/nlu/emulators/wit.py +4 -4
  375. rasa/nlu/extractors/crf_entity_extractor.py +11 -11
  376. rasa/nlu/extractors/duckling_entity_extractor.py +7 -6
  377. rasa/nlu/extractors/entity_synonyms.py +10 -9
  378. rasa/nlu/extractors/extractor.py +16 -16
  379. rasa/nlu/extractors/mitie_entity_extractor.py +10 -9
  380. rasa/nlu/extractors/regex_entity_extractor.py +11 -10
  381. rasa/nlu/extractors/spacy_entity_extractor.py +2 -2
  382. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +15 -14
  383. rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +2 -1
  384. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +10 -9
  385. rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +9 -7
  386. rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +13 -12
  387. rasa/nlu/featurizers/featurizer.py +5 -4
  388. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +6 -6
  389. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -4
  390. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +4 -4
  391. rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +2 -0
  392. rasa/nlu/model.py +0 -1
  393. rasa/nlu/selectors/response_selector.py +67 -68
  394. rasa/nlu/test.py +38 -38
  395. rasa/nlu/tokenizers/jieba_tokenizer.py +1 -2
  396. rasa/nlu/tokenizers/mitie_tokenizer.py +2 -2
  397. rasa/nlu/tokenizers/spacy_tokenizer.py +3 -3
  398. rasa/nlu/tokenizers/tokenizer.py +6 -7
  399. rasa/nlu/tokenizers/whitespace_tokenizer.py +1 -1
  400. rasa/nlu/utils/bilou_utils.py +7 -7
  401. rasa/nlu/utils/hugging_face/registry.py +22 -22
  402. rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +2 -1
  403. rasa/nlu/utils/mitie_utils.py +2 -1
  404. rasa/nlu/utils/pattern_utils.py +1 -1
  405. rasa/nlu/utils/spacy_utils.py +3 -3
  406. rasa/plugin.py +12 -1
  407. rasa/server.py +3 -2
  408. rasa/shared/constants.py +45 -18
  409. rasa/shared/core/command_payload_reader.py +15 -7
  410. rasa/shared/core/constants.py +34 -4
  411. rasa/shared/core/conversation.py +1 -2
  412. rasa/shared/core/domain.py +19 -20
  413. rasa/shared/core/events.py +60 -39
  414. rasa/shared/core/flows/__init__.py +0 -1
  415. rasa/shared/core/flows/constants.py +11 -0
  416. rasa/shared/core/flows/flow.py +107 -26
  417. rasa/shared/core/flows/flow_step.py +4 -3
  418. rasa/shared/core/flows/flow_step_links.py +1 -2
  419. rasa/shared/core/flows/flow_step_sequence.py +1 -1
  420. rasa/shared/core/flows/flows_list.py +3 -3
  421. rasa/shared/core/flows/flows_yaml_schema.json +69 -3
  422. rasa/shared/core/flows/nlu_trigger.py +1 -1
  423. rasa/shared/core/flows/steps/__init__.py +2 -2
  424. rasa/shared/core/flows/steps/action.py +1 -1
  425. rasa/shared/core/flows/steps/call.py +1 -1
  426. rasa/shared/core/flows/steps/collect.py +22 -40
  427. rasa/shared/core/flows/steps/internal.py +1 -1
  428. rasa/shared/core/flows/steps/link.py +1 -1
  429. rasa/shared/core/flows/steps/no_operation.py +2 -2
  430. rasa/shared/core/flows/steps/set_slots.py +1 -1
  431. rasa/shared/core/flows/utils.py +44 -4
  432. rasa/shared/core/flows/validation.py +4 -6
  433. rasa/shared/core/generator.py +20 -21
  434. rasa/shared/core/slot_mappings.py +360 -121
  435. rasa/shared/core/slots.py +163 -6
  436. rasa/shared/core/trackers.py +108 -33
  437. rasa/shared/core/training_data/loading.py +1 -1
  438. rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
  439. rasa/shared/core/training_data/story_reader/story_step_builder.py +4 -4
  440. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +29 -31
  441. rasa/shared/core/training_data/story_writer/yaml_story_writer.py +22 -24
  442. rasa/shared/core/training_data/structures.py +11 -12
  443. rasa/shared/core/training_data/visualization.py +10 -10
  444. rasa/shared/data.py +6 -6
  445. rasa/shared/engine/caching.py +0 -1
  446. rasa/shared/exceptions.py +2 -2
  447. rasa/shared/importers/importer.py +58 -2
  448. rasa/shared/importers/rasa.py +5 -6
  449. rasa/shared/importers/utils.py +1 -1
  450. rasa/shared/nlu/constants.py +9 -0
  451. rasa/shared/nlu/training_data/entities_parser.py +6 -6
  452. rasa/shared/nlu/training_data/features.py +3 -3
  453. rasa/shared/nlu/training_data/formats/__init__.py +1 -1
  454. rasa/shared/nlu/training_data/formats/dialogflow.py +4 -5
  455. rasa/shared/nlu/training_data/formats/luis.py +7 -8
  456. rasa/shared/nlu/training_data/formats/rasa.py +4 -5
  457. rasa/shared/nlu/training_data/formats/rasa_yaml.py +17 -16
  458. rasa/shared/nlu/training_data/formats/readerwriter.py +8 -11
  459. rasa/shared/nlu/training_data/formats/wit.py +3 -4
  460. rasa/shared/nlu/training_data/loading.py +4 -4
  461. rasa/shared/nlu/training_data/lookup_tables_parser.py +1 -1
  462. rasa/shared/nlu/training_data/message.py +13 -14
  463. rasa/shared/nlu/training_data/schemas/data_schema.py +1 -1
  464. rasa/shared/nlu/training_data/schemas/responses.yml +19 -11
  465. rasa/shared/nlu/training_data/synonyms_parser.py +3 -3
  466. rasa/shared/nlu/training_data/training_data.py +12 -13
  467. rasa/shared/nlu/training_data/util.py +11 -10
  468. rasa/shared/providers/_configs/azure_entra_id_config.py +541 -0
  469. rasa/shared/providers/_configs/azure_openai_client_config.py +150 -15
  470. rasa/shared/providers/_configs/client_config.py +3 -1
  471. rasa/shared/providers/_configs/default_litellm_client_config.py +9 -7
  472. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +13 -11
  473. rasa/shared/providers/_configs/litellm_router_client_config.py +12 -10
  474. rasa/shared/providers/_configs/model_group_config.py +8 -5
  475. rasa/shared/providers/_configs/oauth_config.py +33 -0
  476. rasa/shared/providers/_configs/openai_client_config.py +14 -12
  477. rasa/shared/providers/_configs/rasa_llm_client_config.py +5 -3
  478. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +12 -11
  479. rasa/shared/providers/_configs/utils.py +1 -0
  480. rasa/shared/providers/_ssl_verification_utils.py +5 -6
  481. rasa/shared/providers/_utils.py +5 -5
  482. rasa/shared/providers/constants.py +6 -0
  483. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -1
  484. rasa/shared/providers/embedding/azure_openai_embedding_client.py +32 -7
  485. rasa/shared/providers/embedding/embedding_client.py +1 -1
  486. rasa/shared/providers/embedding/litellm_router_embedding_client.py +5 -2
  487. rasa/shared/providers/llm/_base_litellm_client.py +43 -18
  488. rasa/shared/providers/llm/azure_openai_llm_client.py +90 -34
  489. rasa/shared/providers/llm/default_litellm_llm_client.py +4 -2
  490. rasa/shared/providers/llm/litellm_router_llm_client.py +32 -9
  491. rasa/shared/providers/llm/llm_client.py +24 -8
  492. rasa/shared/providers/llm/llm_response.py +61 -2
  493. rasa/shared/providers/llm/openai_llm_client.py +11 -5
  494. rasa/shared/providers/llm/rasa_llm_client.py +17 -14
  495. rasa/shared/providers/llm/self_hosted_llm_client.py +35 -15
  496. rasa/shared/providers/mappings.py +18 -19
  497. rasa/shared/providers/router/_base_litellm_router_client.py +48 -15
  498. rasa/shared/providers/router/router_client.py +3 -1
  499. rasa/shared/utils/cli.py +1 -1
  500. rasa/shared/utils/common.py +15 -1
  501. rasa/shared/utils/constants.py +3 -0
  502. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +1 -1
  503. rasa/shared/utils/health_check/health_check.py +3 -3
  504. rasa/shared/utils/health_check/llm_health_check_mixin.py +1 -1
  505. rasa/shared/utils/io.py +1 -1
  506. rasa/shared/utils/llm.py +100 -18
  507. rasa/shared/utils/pykwalify_extensions.py +25 -1
  508. rasa/shared/utils/schemas/domain.yml +26 -1
  509. rasa/shared/utils/schemas/events.py +1 -1
  510. rasa/shared/utils/yaml.py +24 -20
  511. rasa/studio/auth.py +3 -3
  512. rasa/studio/config.py +1 -2
  513. rasa/studio/data_handler.py +3 -3
  514. rasa/studio/download.py +1 -1
  515. rasa/studio/results_logger.py +3 -3
  516. rasa/studio/upload.py +21 -5
  517. rasa/telemetry.py +127 -48
  518. rasa/tracing/config.py +5 -3
  519. rasa/tracing/constants.py +12 -0
  520. rasa/tracing/instrumentation/attribute_extractors.py +92 -14
  521. rasa/tracing/instrumentation/instrumentation.py +61 -5
  522. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +1 -1
  523. rasa/tracing/instrumentation/metrics.py +52 -11
  524. rasa/tracing/metric_instrument_provider.py +54 -14
  525. rasa/utils/common.py +12 -24
  526. rasa/utils/endpoints.py +1 -1
  527. rasa/utils/io.py +7 -7
  528. rasa/utils/licensing.py +3 -4
  529. rasa/utils/log_utils.py +7 -6
  530. rasa/utils/ml_utils.py +1 -0
  531. rasa/utils/plotting.py +3 -3
  532. rasa/utils/sanic_error_handler.py +1 -1
  533. rasa/utils/tensorflow/callback.py +2 -2
  534. rasa/utils/tensorflow/crf.py +2 -2
  535. rasa/utils/tensorflow/data_generator.py +5 -5
  536. rasa/utils/tensorflow/environment.py +3 -3
  537. rasa/utils/tensorflow/feature_array.py +2 -3
  538. rasa/utils/tensorflow/layers.py +18 -12
  539. rasa/utils/tensorflow/layers_utils.py +2 -1
  540. rasa/utils/tensorflow/metrics.py +2 -2
  541. rasa/utils/tensorflow/model_data.py +7 -7
  542. rasa/utils/tensorflow/model_data_utils.py +10 -9
  543. rasa/utils/tensorflow/models.py +31 -32
  544. rasa/utils/tensorflow/rasa_layers.py +20 -19
  545. rasa/utils/tensorflow/types.py +2 -1
  546. rasa/utils/train_utils.py +23 -21
  547. rasa/utils/url_tools.py +1 -1
  548. rasa/validator.py +594 -115
  549. rasa/version.py +1 -1
  550. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/METADATA +23 -26
  551. rasa_pro-3.12.0.dist-info/RECORD +829 -0
  552. rasa/core/channels/inspector/dist/assets/channel-e265ea59.js +0 -1
  553. rasa/core/channels/inspector/dist/assets/clone-21f8a43d.js +0 -1
  554. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-5c8ce12d.js +0 -1
  555. rasa_pro-3.11.5.dist-info/RECORD +0 -785
  556. /rasa/dialogue_understanding/generator/{single_step → prompt_templates}/command_prompt_template.jinja2 +0 -0
  557. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/NOTICE +0 -0
  558. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/WHEEL +0 -0
  559. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/entry_points.txt +0 -0
@@ -1,26 +1,31 @@
1
1
  from __future__ import annotations
2
2
 
3
- import dataclasses
4
- from dataclasses import dataclass
5
3
  from pathlib import Path
6
- from typing import Generator, Optional, Dict, Any
4
+ from typing import Any, Dict, Generator, Optional, Tuple
7
5
 
8
6
  import structlog
9
- from pydantic import BaseModel
7
+ from pydantic import BaseModel, Field
10
8
 
11
9
  from rasa.e2e_test.constants import (
10
+ DEFAULT_E2E_TESTING_MODEL,
12
11
  E2E_CONFIG_SCHEMA_FILE_PATH,
13
- KEY_LLM_AS_JUDGE,
12
+ KEY_EXTRA_PARAMETERS,
14
13
  KEY_LLM_E2E_TEST_CONVERSION,
14
+ KEY_LLM_JUDGE,
15
15
  )
16
16
  from rasa.shared.constants import (
17
17
  API_BASE_CONFIG_KEY,
18
18
  DEPLOYMENT_CONFIG_KEY,
19
+ EMBEDDINGS_CONFIG_KEY,
19
20
  MODEL_CONFIG_KEY,
21
+ MODELS_CONFIG_KEY,
20
22
  OPENAI_PROVIDER,
21
23
  PROVIDER_CONFIG_KEY,
22
24
  )
23
- from rasa.shared.exceptions import RasaException
25
+ from rasa.shared.utils.llm import (
26
+ combine_custom_and_default_config,
27
+ resolve_model_client_config,
28
+ )
24
29
  from rasa.shared.utils.yaml import (
25
30
  parse_raw_yaml,
26
31
  read_schema_file,
@@ -32,42 +37,103 @@ structlogger = structlog.get_logger()
32
37
  CONFTEST_PATTERNS = ["conftest.yml", "conftest.yaml"]
33
38
 
34
39
 
35
- class InvalidLLMConfiguration(RasaException):
36
- """Exception raised when the LLM configuration is invalid."""
40
+ class BaseModelConfig(BaseModel):
41
+ """Base class for model configurations used by generative assertions."""
37
42
 
38
- def __init__(self, error_message: str) -> None:
39
- """Creates a `InvalidLLMConfiguration`."""
40
- super().__init__(error_message)
43
+ provider: Optional[str] = None
44
+ model: Optional[str] = None
45
+ extra_parameters: Dict[str, Any] = Field(default_factory=dict)
46
+ model_group: Optional[str] = None
41
47
 
42
48
 
43
- @dataclass
44
- class LLMJudgeConfig:
45
- """Class for storing the configuration of the LLM-As-Judge.
49
+ class LLMJudgeConfig(BaseModel):
50
+ """Class for storing the configuration of the LLM-Judge.
46
51
 
47
- The LLM-As-Judge is used to measure the factual accuracy
52
+ The LLM-Judge is used to measure the factual correctness
48
53
  (i.e., how grounded in the source documents the response is),
49
54
  or relevance of the generated response during E2E testing.
50
55
  """
51
56
 
52
- api_type: str = "openai"
53
- model: str = "gpt-4o-mini"
57
+ llm_config: BaseModelConfig
58
+ embeddings: Optional[BaseModelConfig] = None
54
59
 
55
- @staticmethod
56
- def from_dict(config_data: Dict[str, Any]) -> LLMJudgeConfig:
60
+ @classmethod
61
+ def get_default_llm_config(cls) -> Dict[str, Any]:
62
+ return {
63
+ PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
64
+ MODEL_CONFIG_KEY: DEFAULT_E2E_TESTING_MODEL,
65
+ }
66
+
67
+ @classmethod
68
+ def from_dict(cls, config_data: Dict[str, Any]) -> LLMJudgeConfig:
57
69
  """Loads the configuration from a dictionary."""
58
- llm_type = config_data.pop("api_type", "openai")
59
- if llm_type != "openai":
60
- raise InvalidLLMConfiguration(
61
- f"Invalid LLM type '{llm_type}'. Only 'openai' is supported."
62
- )
70
+ embeddings = config_data.pop(EMBEDDINGS_CONFIG_KEY, None)
71
+ llm_config = config_data.pop("llm", {})
72
+
73
+ llm_config = resolve_model_client_config(llm_config)
74
+ llm_config, extra_parameters = cls.extract_attributes(llm_config)
75
+ llm_config = combine_custom_and_default_config(
76
+ llm_config, cls.get_default_llm_config()
77
+ )
78
+ embeddings_config = resolve_model_client_config(embeddings)
63
79
 
64
- return LLMJudgeConfig(**config_data)
80
+ return LLMJudgeConfig(
81
+ llm_config=BaseModelConfig(extra_parameters=extra_parameters, **llm_config),
82
+ embeddings=BaseModelConfig(**embeddings_config)
83
+ if embeddings_config
84
+ else None,
85
+ )
65
86
 
66
- def as_dict(self) -> Dict[str, Any]:
67
- return dataclasses.asdict(self)
87
+ @classmethod
88
+ def extract_attributes(
89
+ cls, llm_config: Dict[str, Any]
90
+ ) -> Tuple[Dict[str, Any], Dict[str, Any]]:
91
+ """Extract the expected fields from the configuration."""
92
+ required_config = {}
93
+
94
+ expected_fields = [
95
+ PROVIDER_CONFIG_KEY,
96
+ MODEL_CONFIG_KEY,
97
+ ]
98
+
99
+ if PROVIDER_CONFIG_KEY in llm_config:
100
+ required_config = {
101
+ expected_field: llm_config.pop(expected_field, None)
102
+ for expected_field in expected_fields
103
+ }
104
+
105
+ elif MODELS_CONFIG_KEY in llm_config:
106
+ llm_config = llm_config.pop(MODELS_CONFIG_KEY)[0]
107
+
108
+ required_config = {
109
+ expected_field: llm_config.pop(expected_field, None)
110
+ for expected_field in expected_fields
111
+ }
112
+
113
+ clean_config = clean_up_config(required_config)
114
+ return clean_config, llm_config
115
+
116
+ @property
117
+ def llm_config_as_dict(self) -> Dict[str, Any]:
118
+ return extract_config(self.llm_config)
68
119
 
69
- def get_model_uri(self) -> str:
70
- return f"{self.api_type}:/{self.model}"
120
+ @property
121
+ def embeddings_config_as_dict(self) -> Dict[str, Any]:
122
+ if self.embeddings is None:
123
+ return {}
124
+
125
+ return extract_config(self.embeddings)
126
+
127
+
128
+ def clean_up_config(config_data: Dict[str, Any]) -> Dict[str, Any]:
129
+ """Remove None values from the configuration."""
130
+ return {key: value for key, value in config_data.items() if value}
131
+
132
+
133
+ def extract_config(config: BaseModelConfig) -> Dict[str, Any]:
134
+ clean_config = clean_up_config(dict(config))
135
+ extra_parameters = clean_config.pop(KEY_EXTRA_PARAMETERS, {})
136
+ return {**clean_config, **extra_parameters}
71
137
 
72
138
 
73
139
  class LLME2ETestConverterConfig(BaseModel):
@@ -99,7 +165,10 @@ class LLME2ETestConverterConfig(BaseModel):
99
165
 
100
166
  @classmethod
101
167
  def get_default_config(cls) -> Dict[str, Any]:
102
- return {PROVIDER_CONFIG_KEY: OPENAI_PROVIDER, MODEL_CONFIG_KEY: "gpt-4o-mini"}
168
+ return {
169
+ PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
170
+ MODEL_CONFIG_KEY: DEFAULT_E2E_TESTING_MODEL,
171
+ }
103
172
 
104
173
  @staticmethod
105
174
  def _clean_up_config(config_data: Dict[str, Any]) -> Dict[str, Any]:
@@ -160,24 +229,16 @@ def create_llm_judge_config(test_case_path: Optional[Path]) -> LLMJudgeConfig:
160
229
  structlogger.debug("e2e_config.create_llm_judge_config.no_conftest_detected")
161
230
  return LLMJudgeConfig.from_dict(config_data)
162
231
 
163
- llm_judge_config_data = config_data.get(KEY_LLM_AS_JUDGE, {})
232
+ llm_judge_config_data = config_data.get(KEY_LLM_JUDGE, {})
164
233
  if not llm_judge_config_data:
165
- structlogger.debug("e2e_config.create_llm_judge_config.no_llm_as_judge_key")
234
+ structlogger.debug("e2e_config.create_llm_judge_config.no_llm_judge_key")
166
235
 
167
236
  structlogger.info(
168
237
  "e2e_config.create_llm_judge_config.success",
169
238
  llm_judge_config_data=llm_judge_config_data,
170
239
  )
171
240
 
172
- try:
173
- return LLMJudgeConfig.from_dict(llm_judge_config_data)
174
- except InvalidLLMConfiguration as e:
175
- structlogger.error(
176
- "e2e_config.create_llm_judge_config.invalid_llm_configuration",
177
- error_message=str(e),
178
- event_info="Falling back to default configuration.",
179
- )
180
- return LLMJudgeConfig()
241
+ return LLMJudgeConfig.from_dict(llm_judge_config_data)
181
242
 
182
243
 
183
244
  def create_llm_e2e_test_converter_config(
@@ -1,19 +1,37 @@
1
1
  mapping:
2
- llm_as_judge:
2
+ llm_judge:
3
3
  type: map
4
4
  mapping:
5
- api_type:
6
- type: str
7
- required: true
8
- nullable: false
9
- model:
10
- type: str
11
- required: true
12
- nullable: false
5
+ llm:
6
+ type: map
7
+ allowempty: true
8
+ mapping:
9
+ provider:
10
+ type: str
11
+ nullable: false
12
+ model:
13
+ type: str
14
+ nullable: false
15
+ model_group:
16
+ type: str
17
+ nullable: false
18
+ embeddings:
19
+ type: map
20
+ allowempty: true
21
+ mapping:
22
+ provider:
23
+ type: str
24
+ nullable: false
25
+ model:
26
+ type: str
27
+ nullable: false
28
+ model_group:
29
+ type: str
30
+ nullable: false
13
31
  llm_e2e_test_conversion:
14
32
  type: map
15
33
  mapping:
16
- api_type:
34
+ provider:
17
35
  type: str
18
36
  model:
19
37
  type: str
@@ -1,22 +1,22 @@
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
 
6
5
  import structlog
7
6
 
7
+ from rasa.dialogue_understanding_test.du_test_case import DialogueUnderstandingTestCase
8
8
  from rasa.e2e_test.assertions import Assertion
9
9
  from rasa.e2e_test.constants import (
10
- KEY_ASSERTIONS,
11
10
  KEY_ASSERTION_ORDER_ENABLED,
11
+ KEY_ASSERTIONS,
12
12
  KEY_BOT_INPUT,
13
13
  KEY_BOT_UTTERED,
14
14
  KEY_FIXTURES,
15
15
  KEY_METADATA,
16
- KEY_STUB_CUSTOM_ACTIONS,
17
16
  KEY_SLOT_NOT_SET,
18
17
  KEY_SLOT_SET,
19
18
  KEY_STEPS,
19
+ KEY_STUB_CUSTOM_ACTIONS,
20
20
  KEY_TEST_CASE,
21
21
  KEY_TEST_CASES,
22
22
  KEY_USER_INPUT,
@@ -551,7 +551,7 @@ class Metadata:
551
551
  class TestSuite:
552
552
  """Class for representing all top level test suite keys."""
553
553
 
554
- test_cases: List[TestCase]
554
+ test_cases: List[Union[TestCase, DialogueUnderstandingTestCase]]
555
555
  fixtures: List[Fixture]
556
556
  metadata: List[Metadata]
557
557
  stub_custom_actions: Dict[Text, StubCustomAction]
@@ -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
@@ -5,7 +5,7 @@ import difflib
5
5
  from asyncio import CancelledError
6
6
  from collections import defaultdict
7
7
  from pathlib import Path
8
- from typing import Any, DefaultDict, Dict, List, Optional, Text, Tuple, Union
8
+ from typing import Any, Callable, DefaultDict, Dict, List, Optional, Text, Tuple, Union
9
9
  from urllib.parse import urlparse
10
10
 
11
11
  import requests
@@ -18,6 +18,7 @@ from rasa.core.constants import ACTIVE_FLOW_METADATA_KEY, STEP_ID_METADATA_KEY
18
18
  from rasa.core.exceptions import AgentNotReady
19
19
  from rasa.core.persistor import StorageType
20
20
  from rasa.core.utils import AvailableEndpoints
21
+ from rasa.dialogue_understanding_test.du_test_case import DialogueUnderstandingTestCase
21
22
  from rasa.e2e_test.constants import TEST_CASE_NAME, TEST_FILE_NAME
22
23
  from rasa.e2e_test.e2e_config import create_llm_judge_config
23
24
  from rasa.e2e_test.e2e_test_case import (
@@ -123,11 +124,11 @@ class E2ETestRunner:
123
124
  collector: Output channel.
124
125
  steps: List of steps to run.
125
126
  sender_id: The test case name with added timestamp suffix.
126
- test_case_metadata: Metadata of test case.
127
+ test_case_metadata: Metadata of the test case.
127
128
  input_metadata: List of metadata.
128
129
 
129
130
  Returns:
130
- Test turns: {turn_sequence (int) : TestStep or ActualStepOutput}.
131
+ Test turns: {turn_sequence (int): TestStep or ActualStepOutput}.
131
132
  """
132
133
  turns: TEST_TURNS_TYPE = {}
133
134
  event_cursor = 0
@@ -151,9 +152,23 @@ class E2ETestRunner:
151
152
  event_cursor,
152
153
  )
153
154
 
155
+ # This variable tracks the position of the last user step.
156
+ # We use it to determine from which turn onward we should check
157
+ # for failures in case of the fail-fast logic.
158
+ last_user_step_position = 0
154
159
  for position, step in enumerate(steps):
155
160
  if step.actor != "user":
156
161
  turns[position] = step
162
+
163
+ # Check for failures after each bot step
164
+ try:
165
+ self.fail_fast_check(
166
+ test_turns=turns,
167
+ last_user_step_position=last_user_step_position,
168
+ )
169
+ except RasaException:
170
+ break
171
+
157
172
  continue
158
173
  elif not step.text:
159
174
  rasa.shared.utils.io.raise_warning(
@@ -163,6 +178,8 @@ class E2ETestRunner:
163
178
  UserWarning,
164
179
  )
165
180
  continue
181
+ # Update to the current position because we have a valid user step
182
+ last_user_step_position = position
166
183
 
167
184
  metadata = test_case_metadata.metadata if test_case_metadata else {}
168
185
 
@@ -202,6 +219,26 @@ class E2ETestRunner:
202
219
  )
203
220
  return turns
204
221
 
222
+ def fail_fast_check(
223
+ self, test_turns: TEST_TURNS_TYPE, last_user_step_position: int
224
+ ) -> None:
225
+ """Checks whether there are any test failures in 'test_turns'.
226
+
227
+ Args:
228
+ test_turns (TEST_TURNS_TYPE): The transcript of test cases and events.
229
+ last_user_step_position (int): The start position in the test turns.
230
+
231
+ Raises:
232
+ RasaException if a failure is found.
233
+ """
234
+ failures_found = self.find_test_failures(
235
+ test_turns=test_turns,
236
+ test_case=None,
237
+ last_user_step_position=last_user_step_position,
238
+ )
239
+ if failures_found:
240
+ raise RasaException("Test failure found. Aborting early.")
241
+
205
242
  @staticmethod
206
243
  def merge_metadata(
207
244
  sender_id: Text,
@@ -754,13 +791,15 @@ class E2ETestRunner:
754
791
  def find_test_failures(
755
792
  cls,
756
793
  test_turns: TEST_TURNS_TYPE,
757
- test_case: TestCase,
794
+ test_case: Optional[TestCase],
795
+ last_user_step_position: int = 0,
758
796
  ) -> List[Tuple[TestFailure, int]]:
759
797
  """Finds the test failures in the transcript.
760
798
 
761
799
  Args:
762
- test_turns: The transcript of test cases and events.
763
- test_case: The test case.
800
+ test_turns (TEST_TURNS_TYPE): The transcript of test cases and events.
801
+ test_case (Optional[TestCase]): The test case.
802
+ last_user_step_position (int): The start position in the test turns.
764
803
 
765
804
  Returns:
766
805
  The test failures or an empty list if there is no test failure.
@@ -769,9 +808,10 @@ class E2ETestRunner:
769
808
  # with a user step
770
809
  latest_response: ActualStepOutput = test_turns[-1] # type: ignore[assignment]
771
810
  failures = []
772
- position = 0
773
811
  match = None
774
- for position in range(len(test_turns) - 1):
812
+ for position in range(last_user_step_position, len(test_turns) - 1):
813
+ if position not in test_turns:
814
+ continue
775
815
  turn_value = test_turns[position]
776
816
  if isinstance(turn_value, ActualStepOutput):
777
817
  latest_response = turn_value
@@ -924,19 +964,11 @@ class E2ETestRunner:
924
964
  ).name
925
965
  self.agent.endpoints.action.kwargs[TEST_CASE_NAME] = test_case_name
926
966
 
927
- # add timestamp suffix to ensure sender_id is unique
928
- sender_id = f"{test_case_name}_{datetime.datetime.now()}"
929
- test_turns = await self._run_test_case(
930
- sender_id, input_fixtures, input_metadata, test_case
967
+ sender_id = self.generate_sender_id(test_case.name)
968
+ _, test_result = await self._process_test_case(
969
+ test_case, sender_id, input_fixtures, input_metadata
931
970
  )
932
971
 
933
- if not test_case.uses_assertions():
934
- test_result = self.generate_test_result(test_turns, test_case)
935
- else:
936
- test_result = await self.run_assertions(
937
- sender_id, test_case, input_metadata
938
- )
939
-
940
972
  results.append(test_result)
941
973
 
942
974
  coverage = kwargs.get("coverage", False)
@@ -983,6 +1015,32 @@ class E2ETestRunner:
983
1015
  input_metadata,
984
1016
  )
985
1017
 
1018
+ @staticmethod
1019
+ def generate_sender_id(test_case_name: str) -> str:
1020
+ # add timestamp suffix to ensure sender_id is unique
1021
+ return f"{test_case_name}_{datetime.datetime.now()}"
1022
+
1023
+ async def _process_test_case(
1024
+ self,
1025
+ test_case: TestCase,
1026
+ sender_id: str,
1027
+ input_fixtures: List[Fixture],
1028
+ input_metadata: Optional[List[Metadata]],
1029
+ ) -> Tuple[TEST_TURNS_TYPE, TestResult]:
1030
+ """Runs a single test case and returns the test turns and result."""
1031
+ test_turns = await self._run_test_case(
1032
+ sender_id, input_fixtures, input_metadata, test_case
1033
+ )
1034
+
1035
+ if not test_case.uses_assertions():
1036
+ test_result = self.generate_test_result(test_turns, test_case)
1037
+ else:
1038
+ test_result = await self.run_assertions(
1039
+ sender_id, test_case, input_metadata
1040
+ )
1041
+
1042
+ return test_turns, test_result
1043
+
986
1044
  async def run_tests_for_fine_tuning(
987
1045
  self,
988
1046
  input_test_cases: List[TestCase],
@@ -1008,20 +1066,12 @@ class E2ETestRunner:
1008
1066
 
1009
1067
  for i in tqdm(range(len(input_test_cases))):
1010
1068
  test_case = input_test_cases[i]
1011
- # add timestamp suffix to ensure sender_id is unique
1012
- sender_id = f"{test_case.name}_{datetime.datetime.now()}"
1013
- test_turns = await self._run_test_case(
1014
- sender_id, input_fixtures, input_metadata, test_case
1069
+ sender_id = self.generate_sender_id(test_case.name)
1070
+
1071
+ test_turns, test_result = await self._process_test_case(
1072
+ test_case, sender_id, input_fixtures, input_metadata
1015
1073
  )
1016
1074
 
1017
- # check if the e2e test is passing, only convert passing e2e tests into
1018
- # conversations
1019
- if not test_case.uses_assertions():
1020
- test_result = self.generate_test_result(test_turns, test_case)
1021
- else:
1022
- test_result = await self.run_assertions(
1023
- sender_id, test_case, input_metadata
1024
- )
1025
1075
  if not test_result.pass_status:
1026
1076
  structlogger.warning(
1027
1077
  "annotation_module.skip_test_case.failing_e2e_test",
@@ -1040,12 +1090,67 @@ class E2ETestRunner:
1040
1090
 
1041
1091
  return conversations
1042
1092
 
1093
+ async def run_tests_to_convert_tests_to_du_tests(
1094
+ self,
1095
+ input_test_cases: List[TestCase],
1096
+ input_fixtures: List[Fixture],
1097
+ input_metadata: Optional[List[Metadata]],
1098
+ converting_method: Callable[
1099
+ [TEST_TURNS_TYPE, TestCase, bool, bool],
1100
+ Optional[DialogueUnderstandingTestCase],
1101
+ ],
1102
+ ) -> Tuple[
1103
+ List[DialogueUnderstandingTestCase], List[DialogueUnderstandingTestCase]
1104
+ ]:
1105
+ """Runs the test cases to convert them into dialogue understanding tests.
1106
+
1107
+ Converts test cases into dialogue understanding test cases.
1108
+
1109
+ Args:
1110
+ input_test_cases: Input test cases.
1111
+ input_fixtures: Input fixtures.
1112
+ input_metadata: Input metadata.
1113
+ converting_method: The method to convert the e2e test case into a
1114
+ dialogue understanding test case.
1115
+
1116
+ Returns:
1117
+ List of ready dialogue understanding test cases and list of
1118
+ dialogue understanding test cases to review.
1119
+ """
1120
+ ready_du_test_cases = []
1121
+ to_review_du_test_cases = []
1122
+
1123
+ for i in tqdm(range(len(input_test_cases))):
1124
+ test_case = input_test_cases[i]
1125
+ sender_id = self.generate_sender_id(test_case.name)
1126
+
1127
+ test_turns, test_result = await self._process_test_case(
1128
+ test_case, sender_id, input_fixtures, input_metadata
1129
+ )
1130
+
1131
+ du_test_case = converting_method(
1132
+ test_turns,
1133
+ test_case,
1134
+ test_case.uses_assertions(),
1135
+ test_result.pass_status,
1136
+ )
1137
+
1138
+ if du_test_case:
1139
+ if test_result.pass_status:
1140
+ ready_du_test_cases.append(du_test_case)
1141
+ else:
1142
+ to_review_du_test_cases.append(du_test_case)
1143
+
1144
+ return ready_du_test_cases, to_review_du_test_cases
1145
+
1043
1146
  @staticmethod
1044
- def _action_server_is_reachable(endpoints: AvailableEndpoints) -> None:
1147
+ def _action_server_is_reachable(
1148
+ endpoints: AvailableEndpoints, module: str = "e2e_test_runner"
1149
+ ) -> None:
1045
1150
  """Calls the action server health endpoint."""
1046
1151
  if not endpoints.action:
1047
1152
  structlogger.debug(
1048
- "e2e_test_runner._action_server_is_reachable",
1153
+ f"{module}._action_server_is_reachable",
1049
1154
  message="No action endpoint configured. Skipping the health check "
1050
1155
  "of the action server.",
1051
1156
  )
@@ -1053,7 +1158,7 @@ class E2ETestRunner:
1053
1158
 
1054
1159
  if endpoints.action.actions_module:
1055
1160
  structlogger.debug(
1056
- "e2e_test_runner._action_server_is_reachable",
1161
+ f"{module}._action_server_is_reachable",
1057
1162
  message="Rasa server is configured to run custom actions directly. "
1058
1163
  "Skipping the health check of the action server.",
1059
1164
  )
@@ -1061,14 +1166,14 @@ class E2ETestRunner:
1061
1166
 
1062
1167
  if not endpoints.action.url:
1063
1168
  structlogger.debug(
1064
- "e2e_test_runner._action_server_is_reachable",
1169
+ f"{module}._action_server_is_reachable",
1065
1170
  message="Action endpoint URL is not defined in the endpoint "
1066
1171
  "configuration.",
1067
1172
  )
1068
1173
  return
1069
1174
 
1070
1175
  structlogger.debug(
1071
- "e2e_test_runner._action_server_is_reachable",
1176
+ f"{module}._action_server_is_reachable",
1072
1177
  message="Detected action URL in the endpoint configuration.\n"
1073
1178
  f"Action Server URL: {endpoints.action.url}\n"
1074
1179
  "Sending a health request to the action endpoint.",
@@ -1084,7 +1189,7 @@ class E2ETestRunner:
1084
1189
  "Actions server URL is defined in your endpoint configuration as "
1085
1190
  f"'{endpoints.action.url}'.\n"
1086
1191
  "Please make sure your action server is running and properly "
1087
- "configured. Since running e2e tests without a action server may "
1192
+ "configured. Since running tests without a action server may "
1088
1193
  f"lead to unpredictable results.\n{error}"
1089
1194
  )
1090
1195
 
@@ -1096,7 +1201,7 @@ class E2ETestRunner:
1096
1201
  )
1097
1202
 
1098
1203
  structlogger.debug(
1099
- "e2e_test_runner._action_server_is_reachable",
1204
+ f"{module}._action_server_is_reachable",
1100
1205
  message="Action endpoint has responded successfully.\n"
1101
1206
  f"Response message: {response.text}\n"
1102
1207
  f"Response status code: {response.status_code}.",