rasa-pro 3.8.18__py3-none-any.whl → 3.9.15__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 (278) hide show
  1. README.md +6 -42
  2. rasa/__main__.py +14 -9
  3. rasa/anonymization/anonymization_pipeline.py +0 -1
  4. rasa/anonymization/anonymization_rule_executor.py +3 -3
  5. rasa/anonymization/utils.py +4 -3
  6. rasa/api.py +2 -2
  7. rasa/cli/arguments/default_arguments.py +1 -1
  8. rasa/cli/arguments/run.py +2 -2
  9. rasa/cli/arguments/test.py +1 -1
  10. rasa/cli/arguments/train.py +10 -10
  11. rasa/cli/e2e_test.py +27 -7
  12. rasa/cli/export.py +0 -1
  13. rasa/cli/license.py +3 -3
  14. rasa/cli/project_templates/calm/actions/action_template.py +1 -1
  15. rasa/cli/project_templates/calm/config.yml +1 -1
  16. rasa/cli/project_templates/calm/credentials.yml +1 -1
  17. rasa/cli/project_templates/calm/data/flows/add_contact.yml +1 -1
  18. rasa/cli/project_templates/calm/data/flows/remove_contact.yml +1 -1
  19. rasa/cli/project_templates/calm/domain/add_contact.yml +8 -2
  20. rasa/cli/project_templates/calm/domain/list_contacts.yml +3 -0
  21. rasa/cli/project_templates/calm/domain/remove_contact.yml +9 -2
  22. rasa/cli/project_templates/calm/domain/shared.yml +5 -0
  23. rasa/cli/project_templates/calm/endpoints.yml +4 -4
  24. rasa/cli/project_templates/default/actions/actions.py +1 -1
  25. rasa/cli/project_templates/default/config.yml +5 -5
  26. rasa/cli/project_templates/default/credentials.yml +1 -1
  27. rasa/cli/project_templates/default/endpoints.yml +4 -4
  28. rasa/cli/project_templates/default/tests/test_stories.yml +1 -1
  29. rasa/cli/project_templates/tutorial/config.yml +1 -1
  30. rasa/cli/project_templates/tutorial/credentials.yml +1 -1
  31. rasa/cli/project_templates/tutorial/data/patterns.yml +6 -0
  32. rasa/cli/project_templates/tutorial/domain.yml +4 -0
  33. rasa/cli/project_templates/tutorial/endpoints.yml +6 -6
  34. rasa/cli/run.py +0 -1
  35. rasa/cli/scaffold.py +3 -2
  36. rasa/cli/studio/download.py +11 -0
  37. rasa/cli/studio/studio.py +180 -24
  38. rasa/cli/studio/upload.py +0 -8
  39. rasa/cli/telemetry.py +18 -6
  40. rasa/cli/utils.py +21 -10
  41. rasa/cli/x.py +3 -2
  42. rasa/constants.py +1 -1
  43. rasa/core/actions/action.py +90 -315
  44. rasa/core/actions/action_exceptions.py +24 -0
  45. rasa/core/actions/constants.py +3 -0
  46. rasa/core/actions/custom_action_executor.py +188 -0
  47. rasa/core/actions/forms.py +11 -7
  48. rasa/core/actions/grpc_custom_action_executor.py +251 -0
  49. rasa/core/actions/http_custom_action_executor.py +140 -0
  50. rasa/core/actions/loops.py +3 -0
  51. rasa/core/actions/two_stage_fallback.py +1 -1
  52. rasa/core/agent.py +2 -4
  53. rasa/core/brokers/pika.py +1 -2
  54. rasa/core/channels/audiocodes.py +1 -1
  55. rasa/core/channels/botframework.py +0 -1
  56. rasa/core/channels/callback.py +0 -1
  57. rasa/core/channels/console.py +6 -8
  58. rasa/core/channels/development_inspector.py +1 -1
  59. rasa/core/channels/facebook.py +0 -3
  60. rasa/core/channels/hangouts.py +0 -6
  61. rasa/core/channels/inspector/dist/assets/{arc-5623b6dc.js → arc-b6e548fe.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-685c106a.js → c4Diagram-d0fbc5ce-fa03ac9e.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-8cbed007.js → classDiagram-936ed81e-ee67392a.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-5889cf12.js → classDiagram-v2-c3cb15f1-9b283fae.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-24c249d7.js → createText-62fc7601-8b6fcc2a.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-7dd06a75.js → edges-f2ad444c-22e77f4f.js} +1 -1
  67. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-62c1e54c.js → erDiagram-9d236eb7-60ffc87f.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-ce49b86f.js → flowDb-1972c806-9dd802e4.js} +1 -1
  69. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4067e48f.js → flowDiagram-7ea5b25a-5fa1912f.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +1 -0
  71. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-59fe4051.js → flowchart-elk-definition-abe16c3d-622a1fd2.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-47e3a43b.js → ganttDiagram-9b5ea136-e285a63a.js} +1 -1
  73. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-5a2ac0d9.js → gitGraphDiagram-99d0ae7c-f237bdca.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-dfb8efc4.js → index-2c4b9a3b-4b03d70e.js} +1 -1
  75. rasa/core/channels/inspector/dist/assets/{index-268a75c0.js → index-a5d3e69d.js} +4 -4
  76. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-b0c470f2.js → infoDiagram-736b4530-72a0fa5f.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-2edb829a.js → journeyDiagram-df861f2b-82218c41.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/{layout-b6873d69.js → layout-78cff630.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{line-1efc5781.js → line-5038b469.js} +1 -1
  80. rasa/core/channels/inspector/dist/assets/{linear-661e9b94.js → linear-c4fc4098.js} +1 -1
  81. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2d2e727f.js → mindmap-definition-beec6740-c33c8ea6.js} +1 -1
  82. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-9d3ea93d.js → pieDiagram-dbbf0591-a8d03059.js} +1 -1
  83. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-06a178a2.js → quadrantDiagram-4d7f4fd6-6a0e56b2.js} +1 -1
  84. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-0bfedffc.js → requirementDiagram-6fc4c22a-2dc7c7bd.js} +1 -1
  85. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-d76d0a04.js → sankeyDiagram-8f13d901-2360fe39.js} +1 -1
  86. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-37bb4341.js → sequenceDiagram-b655622a-41b9f9ad.js} +1 -1
  87. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-f52f7f57.js → stateDiagram-59f0c015-0aad326f.js} +1 -1
  88. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-4a986a20.js → stateDiagram-v2-2b26beab-9847d984.js} +1 -1
  89. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-7dd9ae12.js → styles-080da4f6-564d890e.js} +1 -1
  90. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-46e1ca14.js → styles-3dcbcfbf-38957613.js} +1 -1
  91. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-4a97439a.js → styles-9c745c82-f0fc6921.js} +1 -1
  92. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-823917a3.js → svgDrawCommon-4835440b-ef3c5a77.js} +1 -1
  93. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-9ea72896.js → timeline-definition-5b62e21b-bf3e91c1.js} +1 -1
  94. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-b631a8b6.js → xychartDiagram-2b33534f-4d4026c0.js} +1 -1
  95. rasa/core/channels/inspector/dist/index.html +1 -1
  96. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +10 -0
  97. rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -7
  98. rasa/core/channels/inspector/src/helpers/formatters.ts +3 -2
  99. rasa/core/channels/rest.py +36 -21
  100. rasa/core/channels/rocketchat.py +0 -1
  101. rasa/core/channels/socketio.py +1 -1
  102. rasa/core/channels/telegram.py +3 -3
  103. rasa/core/channels/webexteams.py +0 -1
  104. rasa/core/concurrent_lock_store.py +1 -1
  105. rasa/core/evaluation/marker_base.py +1 -3
  106. rasa/core/evaluation/marker_stats.py +1 -2
  107. rasa/core/featurizers/single_state_featurizer.py +3 -26
  108. rasa/core/featurizers/tracker_featurizers.py +18 -122
  109. rasa/core/information_retrieval/__init__.py +7 -0
  110. rasa/core/information_retrieval/faiss.py +9 -4
  111. rasa/core/information_retrieval/information_retrieval.py +64 -7
  112. rasa/core/information_retrieval/milvus.py +7 -14
  113. rasa/core/information_retrieval/qdrant.py +8 -15
  114. rasa/core/lock_store.py +0 -1
  115. rasa/core/migrate.py +1 -2
  116. rasa/core/nlg/callback.py +3 -4
  117. rasa/core/policies/enterprise_search_policy.py +86 -22
  118. rasa/core/policies/enterprise_search_prompt_template.jinja2 +4 -41
  119. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +60 -0
  120. rasa/core/policies/flows/flow_executor.py +104 -2
  121. rasa/core/policies/intentless_policy.py +7 -9
  122. rasa/core/policies/memoization.py +3 -3
  123. rasa/core/policies/policy.py +18 -9
  124. rasa/core/policies/rule_policy.py +8 -11
  125. rasa/core/policies/ted_policy.py +61 -88
  126. rasa/core/policies/unexpected_intent_policy.py +8 -17
  127. rasa/core/processor.py +136 -47
  128. rasa/core/run.py +41 -25
  129. rasa/core/secrets_manager/endpoints.py +2 -2
  130. rasa/core/secrets_manager/vault.py +6 -8
  131. rasa/core/test.py +3 -5
  132. rasa/core/tracker_store.py +49 -14
  133. rasa/core/train.py +1 -3
  134. rasa/core/training/interactive.py +9 -6
  135. rasa/core/utils.py +5 -10
  136. rasa/dialogue_understanding/coexistence/intent_based_router.py +11 -4
  137. rasa/dialogue_understanding/coexistence/llm_based_router.py +2 -3
  138. rasa/dialogue_understanding/commands/__init__.py +4 -0
  139. rasa/dialogue_understanding/commands/can_not_handle_command.py +9 -0
  140. rasa/dialogue_understanding/commands/cancel_flow_command.py +9 -0
  141. rasa/dialogue_understanding/commands/change_flow_command.py +38 -0
  142. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +9 -0
  143. rasa/dialogue_understanding/commands/clarify_command.py +9 -0
  144. rasa/dialogue_understanding/commands/correct_slots_command.py +9 -0
  145. rasa/dialogue_understanding/commands/error_command.py +12 -0
  146. rasa/dialogue_understanding/commands/handle_code_change_command.py +9 -0
  147. rasa/dialogue_understanding/commands/human_handoff_command.py +9 -0
  148. rasa/dialogue_understanding/commands/knowledge_answer_command.py +9 -0
  149. rasa/dialogue_understanding/commands/noop_command.py +9 -0
  150. rasa/dialogue_understanding/commands/set_slot_command.py +38 -3
  151. rasa/dialogue_understanding/commands/skip_question_command.py +9 -0
  152. rasa/dialogue_understanding/commands/start_flow_command.py +9 -0
  153. rasa/dialogue_understanding/generator/__init__.py +16 -1
  154. rasa/dialogue_understanding/generator/command_generator.py +92 -6
  155. rasa/dialogue_understanding/generator/constants.py +18 -0
  156. rasa/dialogue_understanding/generator/flow_retrieval.py +7 -5
  157. rasa/dialogue_understanding/generator/llm_based_command_generator.py +467 -0
  158. rasa/dialogue_understanding/generator/llm_command_generator.py +39 -609
  159. rasa/dialogue_understanding/generator/multi_step/__init__.py +0 -0
  160. rasa/dialogue_understanding/generator/multi_step/fill_slots_prompt.jinja2 +62 -0
  161. rasa/dialogue_understanding/generator/multi_step/handle_flows_prompt.jinja2 +38 -0
  162. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +827 -0
  163. rasa/dialogue_understanding/generator/nlu_command_adapter.py +69 -8
  164. rasa/dialogue_understanding/generator/single_step/__init__.py +0 -0
  165. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +345 -0
  166. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +36 -31
  167. rasa/dialogue_understanding/processor/command_processor.py +112 -3
  168. rasa/e2e_test/constants.py +1 -0
  169. rasa/e2e_test/e2e_test_case.py +44 -0
  170. rasa/e2e_test/e2e_test_runner.py +114 -11
  171. rasa/e2e_test/e2e_test_schema.yml +18 -0
  172. rasa/engine/caching.py +0 -1
  173. rasa/engine/graph.py +18 -6
  174. rasa/engine/recipes/config_files/default_config.yml +3 -3
  175. rasa/engine/recipes/default_components.py +1 -1
  176. rasa/engine/recipes/default_recipe.py +4 -5
  177. rasa/engine/recipes/recipe.py +1 -1
  178. rasa/engine/runner/dask.py +3 -9
  179. rasa/engine/storage/local_model_storage.py +0 -2
  180. rasa/engine/validation.py +179 -145
  181. rasa/exceptions.py +2 -2
  182. rasa/graph_components/validators/default_recipe_validator.py +3 -5
  183. rasa/hooks.py +0 -1
  184. rasa/model.py +1 -1
  185. rasa/model_training.py +1 -0
  186. rasa/nlu/classifiers/diet_classifier.py +33 -52
  187. rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
  188. rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
  189. rasa/nlu/extractors/crf_entity_extractor.py +54 -97
  190. rasa/nlu/extractors/duckling_entity_extractor.py +1 -1
  191. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +1 -5
  192. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +0 -4
  193. rasa/nlu/featurizers/featurizer.py +1 -1
  194. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +18 -49
  195. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +26 -64
  196. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
  197. rasa/nlu/persistor.py +68 -26
  198. rasa/nlu/selectors/response_selector.py +7 -10
  199. rasa/nlu/test.py +0 -3
  200. rasa/nlu/utils/hugging_face/registry.py +1 -1
  201. rasa/nlu/utils/spacy_utils.py +1 -3
  202. rasa/server.py +22 -7
  203. rasa/shared/constants.py +12 -1
  204. rasa/shared/core/command_payload_reader.py +109 -0
  205. rasa/shared/core/constants.py +4 -5
  206. rasa/shared/core/domain.py +57 -56
  207. rasa/shared/core/events.py +4 -7
  208. rasa/shared/core/flows/flow.py +9 -0
  209. rasa/shared/core/flows/flows_list.py +12 -0
  210. rasa/shared/core/flows/steps/action.py +7 -2
  211. rasa/shared/core/generator.py +12 -11
  212. rasa/shared/core/slot_mappings.py +315 -24
  213. rasa/shared/core/slots.py +4 -2
  214. rasa/shared/core/trackers.py +32 -14
  215. rasa/shared/core/training_data/loading.py +0 -1
  216. rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
  217. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +11 -11
  218. rasa/shared/core/training_data/story_writer/yaml_story_writer.py +5 -3
  219. rasa/shared/core/training_data/structures.py +1 -1
  220. rasa/shared/core/training_data/visualization.py +1 -1
  221. rasa/shared/data.py +58 -1
  222. rasa/shared/exceptions.py +36 -2
  223. rasa/shared/importers/importer.py +1 -2
  224. rasa/shared/importers/rasa.py +0 -1
  225. rasa/shared/nlu/constants.py +2 -0
  226. rasa/shared/nlu/training_data/entities_parser.py +1 -2
  227. rasa/shared/nlu/training_data/features.py +2 -120
  228. rasa/shared/nlu/training_data/formats/dialogflow.py +3 -2
  229. rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -5
  230. rasa/shared/nlu/training_data/formats/readerwriter.py +0 -1
  231. rasa/shared/nlu/training_data/message.py +13 -0
  232. rasa/shared/nlu/training_data/training_data.py +0 -2
  233. rasa/shared/providers/openai/session_handler.py +2 -2
  234. rasa/shared/utils/constants.py +3 -0
  235. rasa/shared/utils/io.py +11 -1
  236. rasa/shared/utils/llm.py +1 -2
  237. rasa/shared/utils/pykwalify_extensions.py +1 -0
  238. rasa/shared/utils/schemas/domain.yml +3 -0
  239. rasa/shared/utils/yaml.py +44 -35
  240. rasa/studio/auth.py +26 -10
  241. rasa/studio/constants.py +2 -0
  242. rasa/studio/data_handler.py +114 -107
  243. rasa/studio/download.py +160 -27
  244. rasa/studio/results_logger.py +137 -0
  245. rasa/studio/train.py +6 -7
  246. rasa/studio/upload.py +159 -134
  247. rasa/telemetry.py +188 -34
  248. rasa/tracing/config.py +18 -3
  249. rasa/tracing/constants.py +26 -2
  250. rasa/tracing/instrumentation/attribute_extractors.py +50 -41
  251. rasa/tracing/instrumentation/instrumentation.py +290 -44
  252. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +7 -5
  253. rasa/tracing/instrumentation/metrics.py +109 -21
  254. rasa/tracing/metric_instrument_provider.py +83 -3
  255. rasa/utils/cli.py +2 -1
  256. rasa/utils/common.py +1 -1
  257. rasa/utils/endpoints.py +1 -2
  258. rasa/utils/io.py +72 -6
  259. rasa/utils/licensing.py +246 -31
  260. rasa/utils/ml_utils.py +1 -1
  261. rasa/utils/tensorflow/data_generator.py +1 -1
  262. rasa/utils/tensorflow/environment.py +1 -1
  263. rasa/utils/tensorflow/model_data.py +201 -12
  264. rasa/utils/tensorflow/model_data_utils.py +499 -500
  265. rasa/utils/tensorflow/models.py +5 -6
  266. rasa/utils/tensorflow/rasa_layers.py +15 -15
  267. rasa/utils/train_utils.py +1 -1
  268. rasa/utils/url_tools.py +53 -0
  269. rasa/validator.py +305 -3
  270. rasa/version.py +1 -1
  271. {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/METADATA +25 -61
  272. {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/RECORD +276 -259
  273. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-85583a23.js +0 -1
  274. rasa/utils/tensorflow/feature_array.py +0 -370
  275. /rasa/dialogue_understanding/generator/{command_prompt_template.jinja2 → single_step/command_prompt_template.jinja2} +0 -0
  276. {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/NOTICE +0 -0
  277. {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/WHEEL +0 -0
  278. {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/entry_points.txt +0 -0
@@ -16,6 +16,7 @@ from rasa.dialogue_understanding.commands import (
16
16
  from rasa.dialogue_understanding.commands.handle_code_change_command import (
17
17
  HandleCodeChangeCommand,
18
18
  )
19
+ from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
19
20
  from rasa.dialogue_understanding.patterns.chitchat import FLOW_PATTERN_CHITCHAT
20
21
  from rasa.dialogue_understanding.patterns.collect_information import (
21
22
  CollectInformationPatternFlowStackFrame,
@@ -36,16 +37,23 @@ from rasa.shared.constants import (
36
37
  ROUTE_TO_CALM_SLOT,
37
38
  RASA_PATTERN_CANNOT_HANDLE_CHITCHAT,
38
39
  )
39
- from rasa.shared.core.constants import ACTION_TRIGGER_CHITCHAT
40
+ from rasa.shared.core.constants import ACTION_TRIGGER_CHITCHAT, SlotMappingType
40
41
  from rasa.shared.core.constants import FLOW_HASHES_SLOT
41
42
  from rasa.shared.core.events import Event, SlotSet
42
43
  from rasa.shared.core.flows import FlowsList
43
44
  from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
45
+ from rasa.shared.core.slots import Slot
44
46
  from rasa.shared.core.trackers import DialogueStateTracker
45
47
  from rasa.shared.nlu.constants import COMMANDS
46
48
 
47
49
  structlogger = structlog.get_logger()
48
50
 
51
+ CANNOT_HANDLE_REASON = (
52
+ "A command generator attempted to set a slot "
53
+ "with a value extracted by an extractor "
54
+ "that is incompatible with the slot mapping type."
55
+ )
56
+
49
57
 
50
58
  def contains_command(commands: List[Command], typ: Type[Command]) -> bool:
51
59
  """Check if a list of commands contains a command of a given type.
@@ -118,7 +126,7 @@ def validate_state_of_commands(commands: List[Command]) -> None:
118
126
  ]
119
127
  if free_form_answer_commands != commands[: len(free_form_answer_commands)]:
120
128
  structlogger.error(
121
- "command_processor.validate_state_of_commands.free_form_answer_commands_not_at_beginning", # noqa: E501
129
+ "command_processor.validate_state_of_commands.free_form_answer_commands_not_at_beginning",
122
130
  commands=commands,
123
131
  )
124
132
  raise ValueError(
@@ -341,7 +349,6 @@ def clean_up_commands(
341
349
  clean_commands: List[Command] = []
342
350
 
343
351
  for command in commands:
344
-
345
352
  if isinstance(command, SetSlotCommand):
346
353
  clean_commands = clean_up_slot_command(
347
354
  clean_commands, command, tracker, all_flows, slots_so_far
@@ -355,6 +362,19 @@ def clean_up_commands(
355
362
  ".skip_command_flow_already_cancelled",
356
363
  command=command,
357
364
  )
365
+
366
+ # if there is a cannot handle command after the previous step,
367
+ # we don't want to add another one
368
+ elif isinstance(command, CannotHandleCommand) and contains_command(
369
+ clean_commands, CannotHandleCommand
370
+ ):
371
+ structlogger.debug(
372
+ "command_processor"
373
+ ".clean_up_commands"
374
+ ".skip_command_already_has_cannot_handle",
375
+ command=command,
376
+ )
377
+
358
378
  elif isinstance(command, StartFlowCommand) and command.flow == active_flow:
359
379
  # drop a start flow command if the starting flow is equal to the currently
360
380
  # active flow
@@ -388,6 +408,13 @@ def clean_up_commands(
388
408
  else:
389
409
  clean_commands.append(command)
390
410
 
411
+ # when coexistence is enabled, by default there will be a SetSlotCommand
412
+ # for the ROUTE_TO_CALM_SLOT slot.
413
+ if tracker.has_coexistence_routing_slot and len(clean_commands) > 2:
414
+ clean_commands = filter_cannot_handle_command_for_skipped_slots(clean_commands)
415
+ elif not tracker.has_coexistence_routing_slot and len(clean_commands) > 1:
416
+ clean_commands = filter_cannot_handle_command_for_skipped_slots(clean_commands)
417
+
391
418
  structlogger.debug(
392
419
  "command_processor.clean_up_commands.final_commands",
393
420
  command=clean_commands,
@@ -460,6 +487,22 @@ def clean_up_slot_command(
460
487
  stack = tracker.stack
461
488
 
462
489
  resulting_commands = commands_so_far[:]
490
+
491
+ slot = tracker.slots.get(command.name)
492
+ if slot is None:
493
+ structlogger.debug(
494
+ "command_processor.clean_up_slot_command.skip_command_slot_not_in_domain",
495
+ command=command,
496
+ )
497
+ return resulting_commands
498
+
499
+ if not should_slot_be_set(slot, command):
500
+ cannot_handle = CannotHandleCommand(reason=CANNOT_HANDLE_REASON)
501
+ if cannot_handle not in resulting_commands:
502
+ resulting_commands.append(cannot_handle)
503
+
504
+ return resulting_commands
505
+
463
506
  if command.name in slots_so_far and command.name != ROUTE_TO_CALM_SLOT:
464
507
  current_collect_info = get_current_collect_step(stack, all_flows)
465
508
 
@@ -576,3 +619,69 @@ def clean_up_chitchat_command(
576
619
  )
577
620
 
578
621
  return resulting_commands
622
+
623
+
624
+ def should_slot_be_set(slot: Slot, command: SetSlotCommand) -> bool:
625
+ """Check if a slot should be set by a command."""
626
+ if command.extractor == SetSlotExtractor.COMMAND_PAYLOAD_READER.value:
627
+ # if the command is issued by the command payload reader, it means the slot
628
+ # was set deterministically via a response button. In this case,
629
+ # we can always set it
630
+ return True
631
+
632
+ slot_mappings = slot.mappings
633
+
634
+ if not slot_mappings:
635
+ slot_mappings = [{"type": SlotMappingType.FROM_LLM.value}]
636
+
637
+ for mapping in slot_mappings:
638
+ mapping_type = SlotMappingType(
639
+ mapping.get("type", SlotMappingType.FROM_LLM.value)
640
+ )
641
+
642
+ should_be_set_by_llm = (
643
+ command.extractor == SetSlotExtractor.LLM.value
644
+ and mapping_type == SlotMappingType.FROM_LLM
645
+ )
646
+ should_be_set_by_nlu = (
647
+ command.extractor == SetSlotExtractor.NLU.value
648
+ and mapping_type.is_predefined_type()
649
+ )
650
+
651
+ if should_be_set_by_llm or should_be_set_by_nlu:
652
+ # if the extractor matches the mapping type, we can continue
653
+ # setting the slot
654
+ break
655
+
656
+ structlogger.debug(
657
+ "command_processor.clean_up_slot_command.skip_command.extractor_"
658
+ "does_not_match_slot_mapping",
659
+ extractor=command.extractor,
660
+ slot_name=slot.name,
661
+ mapping_type=mapping_type.value,
662
+ )
663
+ return False
664
+
665
+ return True
666
+
667
+
668
+ def filter_cannot_handle_command_for_skipped_slots(
669
+ clean_commands: List[Command],
670
+ ) -> List[Command]:
671
+ """Filter out a 'cannot handle' command for skipped slots.
672
+
673
+ This is used to filter out a 'cannot handle' command for skipped slots
674
+ in case other commands are present.
675
+
676
+ Returns:
677
+ The filtered commands.
678
+ """
679
+ return [
680
+ command
681
+ for command in clean_commands
682
+ if not (
683
+ isinstance(command, CannotHandleCommand)
684
+ and command.reason
685
+ and CANNOT_HANDLE_REASON == command.reason
686
+ )
687
+ ]
@@ -8,3 +8,4 @@ KEY_SLOT_SET = "slot_was_set"
8
8
  KEY_SLOT_NOT_SET = "slot_was_not_set"
9
9
  KEY_STEPS = "steps"
10
10
  KEY_TEST_CASE = "test_case"
11
+ KEY_METADATA = "metadata"
@@ -8,6 +8,7 @@ from rasa.e2e_test.constants import (
8
8
  KEY_BOT_INPUT,
9
9
  KEY_BOT_UTTERED,
10
10
  KEY_FIXTURES,
11
+ KEY_METADATA,
11
12
  KEY_SLOT_NOT_SET,
12
13
  KEY_SLOT_SET,
13
14
  KEY_STEPS,
@@ -63,6 +64,7 @@ class TestStep:
63
64
  slot_was_not_set: bool = False
64
65
  _slot_instance: Optional[Union[Text, Dict[Text, Any]]] = None
65
66
  _underlying: Optional[Dict[Text, Any]] = None
67
+ metadata_name: Optional[Text] = None
66
68
 
67
69
  @staticmethod
68
70
  def from_dict(test_step_dict: Dict[Text, Any]) -> "TestStep":
@@ -71,6 +73,8 @@ class TestStep:
71
73
  Example:
72
74
  >>> TestStep.from_dict({"user": "hello"})
73
75
  TestStep(text="hello", actor="user")
76
+ >>> TestStep.from_dict({"user": "hello", metadata: "some_metadata"})
77
+ TestStep(text="hello", actor="user", metadata_name="some_metadata")
74
78
  >>> TestStep.from_dict({"bot": "hello world"})
75
79
  TestStep(text="hello world", actor="bot")
76
80
 
@@ -94,6 +98,7 @@ class TestStep:
94
98
  slot_was_not_set=bool(test_step_dict.get(KEY_SLOT_NOT_SET)),
95
99
  _slot_instance=slot_instance,
96
100
  _underlying=test_step_dict,
101
+ metadata_name=test_step_dict.get(KEY_METADATA, ""),
97
102
  )
98
103
 
99
104
  @staticmethod
@@ -269,6 +274,7 @@ class TestCase:
269
274
  file: Optional[Text] = None
270
275
  line: Optional[int] = None
271
276
  fixture_names: Optional[List[Text]] = None
277
+ metadata_name: Optional[Text] = None
272
278
 
273
279
  @staticmethod
274
280
  def from_dict(
@@ -311,6 +317,7 @@ class TestCase:
311
317
  if hasattr(input_test_case, "lc")
312
318
  else None,
313
319
  fixture_names=input_test_case.get(KEY_FIXTURES),
320
+ metadata_name=input_test_case.get(KEY_METADATA),
314
321
  )
315
322
 
316
323
  def file_with_line(self) -> Text:
@@ -320,3 +327,40 @@ class TestCase:
320
327
 
321
328
  line = str(self.line) if self.line is not None else ""
322
329
  return f"{self.file}:{line}"
330
+
331
+
332
+ @dataclass(frozen=True)
333
+ class Metadata:
334
+ """Class for storing an input metadata."""
335
+
336
+ name: Text
337
+ metadata: Dict[Text, Any]
338
+
339
+ @staticmethod
340
+ def from_dict(metadata_dict: Dict[Text, Any]) -> "Metadata":
341
+ """Creates a metadata from a dictionary.
342
+
343
+ Example:
344
+ >>> Metadata.from_dict({"some_metadata": {"room": "test_room"}})
345
+ Metadata(name="some_metadata", metadata={"room": "test_room"})
346
+
347
+ Args:
348
+ metadata_dict: Dictionary containing the metadata.
349
+ """
350
+ return Metadata(
351
+ name=next(iter(metadata_dict.keys())),
352
+ metadata={
353
+ metadata_name: metadata_value
354
+ for metadata in metadata_dict.values()
355
+ for metadata_name, metadata_value in metadata.items()
356
+ },
357
+ )
358
+
359
+
360
+ @dataclass(frozen=True)
361
+ class TestSuite:
362
+ """Class for representing all top level test suite keys."""
363
+
364
+ test_cases: List[TestCase]
365
+ fixtures: List[Fixture]
366
+ metadata: List[Metadata]
@@ -1,9 +1,10 @@
1
1
  import asyncio
2
+ import copy
2
3
  import datetime
3
4
  import difflib
4
5
  import logging
5
6
  from asyncio import CancelledError
6
- from typing import Dict, List, Optional, Text, Tuple, Union
7
+ from typing import Any, Dict, List, Optional, Text, Tuple, Union
7
8
  from urllib.parse import urlparse
8
9
 
9
10
  import rasa.shared.utils.io
@@ -19,6 +20,7 @@ from rasa.utils.endpoints import EndpointConfig
19
20
  from rasa.e2e_test.e2e_test_case import (
20
21
  ActualStepOutput,
21
22
  Fixture,
23
+ Metadata,
22
24
  TestCase,
23
25
  TestStep,
24
26
  )
@@ -85,6 +87,8 @@ class E2ETestRunner:
85
87
  collector: CollectingOutputChannel,
86
88
  steps: List[TestStep],
87
89
  sender_id: Text,
90
+ test_case_metadata: Optional[Metadata] = None,
91
+ input_metadata: Optional[List[Metadata]] = None,
88
92
  ) -> TEST_TURNS_TYPE:
89
93
  """Runs dialogue prediction.
90
94
 
@@ -94,12 +98,12 @@ class E2ETestRunner:
94
98
  sender_id: The test case name with added timestamp suffix.
95
99
 
96
100
  Returns:
97
- Test turns: {turn_sequence (int) : TestStep or ActualStepOutput}.
101
+ Test turns: {turn_sequence (int) : TestStep or ActualStepOutput}.
98
102
  """
99
103
  turns: TEST_TURNS_TYPE = {}
100
104
  event_cursor = 0
101
105
 
102
- tracker = await self.agent.processor.fetch_tracker_with_initial_session( # type: ignore[union-attr] # noqa: E501
106
+ tracker = await self.agent.processor.fetch_tracker_with_initial_session( # type: ignore[union-attr]
103
107
  sender_id
104
108
  )
105
109
  # turn -1 i used to contain events that happen during
@@ -123,12 +127,24 @@ class E2ETestRunner:
123
127
  )
124
128
  continue
125
129
 
130
+ metadata = test_case_metadata.metadata if test_case_metadata else {}
131
+
132
+ if input_metadata:
133
+ step_metadata = self.filter_metadata_for_input(
134
+ step.metadata_name, input_metadata
135
+ )
136
+ step_metadata_dict = step_metadata.metadata if step_metadata else {}
137
+ metadata = self.merge_metadata(
138
+ sender_id, step.text, metadata, step_metadata_dict
139
+ )
140
+
126
141
  try:
127
142
  await self.agent.handle_message(
128
143
  UserMessage(
129
144
  step.text,
130
145
  collector,
131
146
  sender_id,
147
+ metadata=metadata,
132
148
  )
133
149
  )
134
150
  except CancelledError:
@@ -147,6 +163,49 @@ class E2ETestRunner:
147
163
  )
148
164
  return turns
149
165
 
166
+ @staticmethod
167
+ def merge_metadata(
168
+ sender_id: Text,
169
+ step_text: Text,
170
+ test_case_metadata: Dict[Text, Text],
171
+ step_metadata: Dict[Text, Text],
172
+ ) -> Dict[Text, Text]:
173
+ """Merges the test case and user step metadata.
174
+
175
+ Args:
176
+ sender_id: The test case name with added timestamp suffix.
177
+ step_text: The user step text.
178
+ test_case_metadata: The test case metadata dict.
179
+ step_metadata: The user step metadata dict.
180
+
181
+ Returns:
182
+ A dictionary with the merged metadata.
183
+ """
184
+ if not test_case_metadata:
185
+ return step_metadata
186
+ if not step_metadata:
187
+ return test_case_metadata
188
+
189
+ keys_to_overwrite = []
190
+
191
+ for key in step_metadata.keys():
192
+ if key in test_case_metadata.keys():
193
+ keys_to_overwrite.append(key)
194
+
195
+ if keys_to_overwrite:
196
+ test_case_name = sender_id.rsplit("_", 1)[0]
197
+ logger.warning(
198
+ f"Metadata {keys_to_overwrite} exist in both the test case "
199
+ f"'{test_case_name}' and the user step '{step_text}'. "
200
+ "The user step metadata takes precedence and will "
201
+ "override the test case metadata."
202
+ )
203
+
204
+ merged_metadata = copy.deepcopy(test_case_metadata)
205
+ merged_metadata.update(step_metadata)
206
+
207
+ return merged_metadata
208
+
150
209
  @staticmethod
151
210
  def get_actual_step_output(
152
211
  tracker: DialogueStateTracker,
@@ -310,10 +369,10 @@ class E2ETestRunner:
310
369
  if failed_step.text is not None:
311
370
  diff_test_text = f"{failed_step.actor}: {failed_step.text}"
312
371
  diff_actual_text = NO_RESPONSE
313
- event: Optional[
314
- Union[BotUttered, SlotSet]
315
- ] = cls._find_first_non_matched_utterance(
316
- test_response, bot_utter_test_steps
372
+ event: Optional[Union[BotUttered, SlotSet]] = (
373
+ cls._find_first_non_matched_utterance(
374
+ test_response, bot_utter_test_steps
375
+ )
317
376
  )
318
377
  if event and isinstance(event, BotUttered):
319
378
  test_response.remove_bot_uttered_event(event)
@@ -533,7 +592,7 @@ class E2ETestRunner:
533
592
  """
534
593
  if not fixtures:
535
594
  return
536
- tracker = await self.agent.processor.fetch_tracker_with_initial_session( # type: ignore[union-attr] # noqa: E501
595
+ tracker = await self.agent.processor.fetch_tracker_with_initial_session( # type: ignore[union-attr]
537
596
  sender_id
538
597
  )
539
598
 
@@ -564,11 +623,43 @@ class E2ETestRunner:
564
623
  )
565
624
  )
566
625
 
626
+ @staticmethod
627
+ def filter_metadata_for_input(
628
+ metadata_name: Optional[Text], test_suite_metadata: List[Metadata]
629
+ ) -> Optional[Metadata]:
630
+ """Filters the test suite metadata for a metadata name.
631
+
632
+ Args:
633
+ metadata_name: The test case or user step metadata name.
634
+ test_suite_metadata: The top level list of all metadata definitions.
635
+
636
+ Returns:
637
+ The filtered metadata.
638
+ """
639
+ if not metadata_name:
640
+ return None
641
+
642
+ filtered_metadata = list(
643
+ filter(
644
+ lambda metadata: metadata_name and metadata.name == metadata_name,
645
+ test_suite_metadata,
646
+ )
647
+ )
648
+
649
+ if not filtered_metadata:
650
+ logger.warning(
651
+ f"Metadata '{metadata_name}' is not defined in the input metadata."
652
+ )
653
+ return None
654
+
655
+ return filtered_metadata[0]
656
+
567
657
  async def run_tests(
568
658
  self,
569
659
  input_test_cases: List[TestCase],
570
660
  input_fixtures: List[Fixture],
571
661
  fail_fast: bool = False,
662
+ **kwargs: Any,
572
663
  ) -> List["TestResult"]:
573
664
  """Runs the test cases.
574
665
 
@@ -576,14 +667,16 @@ class E2ETestRunner:
576
667
  input_test_cases: Input test cases.
577
668
  input_fixtures: Input fixtures.
578
669
  fail_fast: Whether to fail fast.
670
+ **kwargs: Additional arguments which are passed here.
579
671
 
580
672
  Returns:
581
- List of test results.
673
+ List of test results.
582
674
  """
583
675
  results = []
676
+ input_metadata = kwargs.get("input_metadata", None)
584
677
 
585
678
  # telemetry call for tracking test runs
586
- track_e2e_test_run(input_test_cases, input_fixtures)
679
+ track_e2e_test_run(input_test_cases, input_fixtures, input_metadata)
587
680
 
588
681
  for test_case in input_test_cases:
589
682
  collector = CollectingOutputChannel()
@@ -597,8 +690,18 @@ class E2ETestRunner:
597
690
  )
598
691
  await self.set_up_fixtures(test_fixtures, sender_id)
599
692
 
693
+ test_case_metadata = None
694
+ if input_metadata:
695
+ test_case_metadata = self.filter_metadata_for_input(
696
+ test_case.metadata_name, input_metadata
697
+ )
698
+
600
699
  tracker = await self.run_prediction_loop(
601
- collector, test_case.steps, sender_id
700
+ collector,
701
+ test_case.steps,
702
+ sender_id,
703
+ test_case_metadata,
704
+ input_metadata,
602
705
  )
603
706
 
604
707
  test_result = self.generate_test_result(tracker, test_case)
@@ -13,6 +13,18 @@ mapping:
13
13
  regex;(^[a-zA-Z_]+[a-zA-Z0-9_]*$):
14
14
  type: any
15
15
 
16
+ metadata:
17
+ allowempty: True
18
+ type: "seq"
19
+ sequence:
20
+ - type: map
21
+ mapping:
22
+ regex;(^[a-zA-Z_]+[a-zA-Z0-9_]*$):
23
+ type: map
24
+ mapping:
25
+ regex;(^[a-zA-Z_]+[a-zA-Z0-9_]*$):
26
+ type: any
27
+
16
28
  test_cases:
17
29
  type: "seq"
18
30
  sequence:
@@ -27,6 +39,9 @@ mapping:
27
39
  sequence:
28
40
  - type: "str"
29
41
  pattern: ^[a-zA-Z_]+[a-zA-Z0-9_]*$
42
+ metadata:
43
+ type: "str"
44
+ pattern: ^[a-zA-Z_]+[a-zA-Z0-9_]*$
30
45
  steps:
31
46
  type: "seq"
32
47
  matching: "any"
@@ -34,7 +49,10 @@ mapping:
34
49
  - type: map
35
50
  mapping:
36
51
  user:
52
+ type: str
53
+ metadata:
37
54
  type: "str"
55
+ pattern: ^[a-zA-Z_]+[a-zA-Z0-9_]*$
38
56
  - type: map
39
57
  mapping:
40
58
  utter:
rasa/engine/caching.py CHANGED
@@ -305,7 +305,6 @@ class LocalTrainingCache(TrainingCache):
305
305
  with rasa.utils.common.TempDirectoryPath(tempdir_name) as temp_dir:
306
306
  tmp_path = Path(temp_dir)
307
307
  try:
308
-
309
308
  output.to_cache(tmp_path, model_storage)
310
309
 
311
310
  logger.debug(
rasa/engine/graph.py CHANGED
@@ -108,10 +108,10 @@ class GraphSchema:
108
108
  nodes = {}
109
109
  for node_name, serialized_node in serialized_graph_schema["nodes"].items():
110
110
  try:
111
- serialized_node[
112
- "uses"
113
- ] = rasa.shared.utils.common.class_from_module_path(
114
- serialized_node["uses"]
111
+ serialized_node["uses"] = (
112
+ rasa.shared.utils.common.class_from_module_path(
113
+ serialized_node["uses"]
114
+ )
115
115
  )
116
116
 
117
117
  resource = serialized_node["resource"]
@@ -172,6 +172,18 @@ class GraphSchema:
172
172
  return True
173
173
  return False
174
174
 
175
+ def count_nodes_of_a_given_type(
176
+ self, node_type: Type, include_subtypes: bool = True
177
+ ) -> int:
178
+ """Counts the number of the nodes of specified class"""
179
+ counter = 0
180
+ for node in self.nodes.values():
181
+ if (node.uses is node_type) or (
182
+ include_subtypes and issubclass(node.uses, node_type)
183
+ ):
184
+ counter += 1
185
+ return counter
186
+
175
187
 
176
188
  class GraphComponent(ABC):
177
189
  """Interface for any component which will run in a graph."""
@@ -206,7 +218,7 @@ class GraphComponent(ABC):
206
218
 
207
219
  @classmethod
208
220
  def load(
209
- cls,
221
+ cls: Any,
210
222
  config: Dict[Text, Any],
211
223
  model_storage: ModelStorage,
212
224
  resource: Resource,
@@ -267,7 +279,7 @@ class GraphComponent(ABC):
267
279
  return []
268
280
 
269
281
  @classmethod
270
- def fingerprint_addon(cls, config: Dict[str, Any]) -> Optional[str]:
282
+ def fingerprint_addon(cls: Any, config: Dict[str, Any]) -> Optional[str]:
271
283
  """Adds additional data to the fingerprint calculation.
272
284
 
273
285
  This is useful if a component uses external data that is not provided
@@ -1,5 +1,5 @@
1
1
  # The config recipe.
2
- # https://rasa.com/docs/rasa/model-configuration/
2
+ # https://rasa.com/docs/rasa-pro/nlu-based-assistants/model-configuration/
3
3
  recipe: default.v1
4
4
 
5
5
  # The assistant project unique identifier
@@ -7,7 +7,7 @@ recipe: default.v1
7
7
  assistant_id: placeholder_default
8
8
 
9
9
  # Configuration for the Rasa NLU components.
10
- # https://rasa.com/docs/rasa/components
10
+ # https://rasa.com/docs/rasa-pro/nlu-based-assistants/components
11
11
  language: en
12
12
 
13
13
  pipeline:
@@ -31,7 +31,7 @@ pipeline:
31
31
  ambiguity_threshold: 0.1
32
32
 
33
33
  # Configuration for the Rasa Core policies.
34
- # https://rasa.com/docs/rasa/policies
34
+ # https://rasa.com/docs/rasa-pro/concepts/policies/policy-overview/
35
35
  policies:
36
36
  - name: MemoizationPolicy
37
37
  - name: RulePolicy
@@ -9,7 +9,7 @@ from rasa.dialogue_understanding.generator.nlu_command_adapter import NLUCommand
9
9
  from rasa.nlu.classifiers.diet_classifier import DIETClassifier
10
10
  from rasa.nlu.classifiers.fallback_classifier import FallbackClassifier
11
11
  from rasa.nlu.classifiers.keyword_intent_classifier import KeywordIntentClassifier
12
- from rasa.dialogue_understanding.generator.llm_command_generator import (
12
+ from rasa.dialogue_understanding.generator import (
13
13
  LLMCommandGenerator,
14
14
  )
15
15
  from rasa.nlu.classifiers.llm_intent_classifier import LLMIntentClassifier
@@ -157,10 +157,10 @@ class DefaultV1Recipe(Recipe):
157
157
  else:
158
158
  unique_types = set(component_types)
159
159
 
160
- cls._registered_components[
161
- registered_class.__name__
162
- ] = cls.RegisteredComponent(
163
- registered_class, unique_types, is_trainable, model_from
160
+ cls._registered_components[registered_class.__name__] = (
161
+ cls.RegisteredComponent(
162
+ registered_class, unique_types, is_trainable, model_from
163
+ )
164
164
  )
165
165
  return registered_class
166
166
 
@@ -699,7 +699,6 @@ class DefaultV1Recipe(Recipe):
699
699
  preprocessors: List[Text],
700
700
  train_nodes: Dict[Text, SchemaNode],
701
701
  ) -> Dict[Text, SchemaNode]:
702
-
703
702
  predict_config = copy.deepcopy(config)
704
703
  predict_nodes = {}
705
704
 
@@ -33,7 +33,7 @@ class Recipe(abc.ABC):
33
33
 
34
34
  if name is None:
35
35
  rasa.shared.utils.io.raise_deprecation_warning(
36
- "From Rasa Open Source 4.0.0 onwards it will be required to specify "
36
+ "From Rasa Pro 4.0.0 onwards it will be required to specify "
37
37
  "a recipe in your model configuration. Defaulting to recipe "
38
38
  f"'{DefaultV1Recipe.name}'."
39
39
  )
@@ -222,9 +222,7 @@ async def execute_dask_graph(dsk: Dict[str, Any], result: List[str]) -> Any:
222
222
  state = {}
223
223
  keyorder = dask.local.order(dsk) # type:ignore[no-untyped-call]
224
224
 
225
- state = dask.local.start_state_from_dask(
226
- dsk, cache=cache, sortkey=keyorder.get
227
- ) # type:ignore[no-untyped-call]
225
+ state = dask.local.start_state_from_dask(dsk, cache=cache, sortkey=keyorder.get) # type:ignore[no-untyped-call]
228
226
 
229
227
  if state["waiting"] and not state["ready"]:
230
228
  raise ValueError("Found no accessible jobs in dask")
@@ -237,17 +235,13 @@ async def execute_dask_graph(dsk: Dict[str, Any], result: List[str]) -> Any:
237
235
  # Notify task is running
238
236
  state["running"].add(key)
239
237
 
240
- dependencies = dask.local.get_dependencies(
241
- dsk, key
242
- ) # type:ignore[no-untyped-call]
238
+ dependencies = dask.local.get_dependencies(dsk, key) # type:ignore[no-untyped-call]
243
239
  # Prep args to send
244
240
  data = {dep: state["cache"][dep] for dep in dependencies}
245
241
 
246
242
  task_result = await _execute_task(dsk[key], data)
247
243
  state["cache"][key] = task_result
248
- dask.local.finish_task(
249
- dsk, key, state, results, keyorder.get
250
- ) # type:ignore[no-untyped-call]
244
+ dask.local.finish_task(dsk, key, state, results, keyorder.get) # type:ignore[no-untyped-call]
251
245
 
252
246
  # Main loop, wait on tasks to finish, insert new ones
253
247
  while state["ready"]: