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
@@ -401,8 +401,9 @@ class TrainingDataGenerator:
401
401
 
402
402
  if num_active_trackers:
403
403
  logger.debug(
404
- "Starting {} ... (with {} trackers)"
405
- "".format(phase_name, num_active_trackers)
404
+ "Starting {} ... (with {} trackers)".format(
405
+ phase_name, num_active_trackers
406
+ )
406
407
  )
407
408
  else:
408
409
  logger.debug(f"There are no trackers for {phase_name}")
@@ -516,14 +517,14 @@ class TrainingDataGenerator:
516
517
  phase = 0
517
518
  else:
518
519
  logger.debug(
519
- "Found {} unused checkpoints "
520
- "in current phase."
521
- "".format(len(unused_checkpoints))
520
+ "Found {} unused checkpoints in current phase.".format(
521
+ len(unused_checkpoints)
522
+ )
522
523
  )
523
524
  logger.debug(
524
- "Found {} active trackers "
525
- "for these checkpoints."
526
- "".format(num_active_trackers)
525
+ "Found {} active trackers for these checkpoints.".format(
526
+ num_active_trackers
527
+ )
527
528
  )
528
529
 
529
530
  if everything_reachable_is_reached:
@@ -552,8 +553,9 @@ class TrainingDataGenerator:
552
553
  augmented_trackers, self.config.max_number_of_augmented_trackers
553
554
  )
554
555
  logger.debug(
555
- "Subsampled to {} augmented training trackers."
556
- "".format(len(augmented_trackers))
556
+ "Subsampled to {} augmented training trackers.".format(
557
+ len(augmented_trackers)
558
+ )
557
559
  )
558
560
  logger.debug(
559
561
  "There are {} original trackers.".format(len(original_trackers))
@@ -672,7 +674,6 @@ class TrainingDataGenerator:
672
674
 
673
675
  trackers = []
674
676
  if events: # small optimization
675
-
676
677
  # need to copy the tracker as multiple story steps
677
678
  # might start with the same checkpoint and all of them
678
679
  # will use the same set of incoming trackers
@@ -1,16 +1,24 @@
1
- from typing import Text, Dict, Any, List, Optional, TYPE_CHECKING
1
+ import logging
2
+ from typing import Text, Dict, Any, List, Optional, TYPE_CHECKING, Tuple, cast
2
3
 
3
4
  from rasa.shared.constants import DOCS_URL_NLU_BASED_SLOTS, IGNORED_INTENTS
4
5
  import rasa.shared.utils.io
6
+ from rasa.shared.core.slots import ListSlot, Slot
5
7
  from rasa.shared.nlu.constants import (
8
+ ENTITIES,
6
9
  ENTITY_ATTRIBUTE_TYPE,
7
10
  ENTITY_ATTRIBUTE_ROLE,
8
11
  ENTITY_ATTRIBUTE_GROUP,
12
+ ENTITY_ATTRIBUTE_VALUE,
9
13
  INTENT,
10
14
  NOT_INTENT,
11
15
  INTENT_NAME_KEY,
16
+ TEXT,
12
17
  )
13
18
  from rasa.shared.core.constants import (
19
+ ACTIVE_FLOW,
20
+ ACTIVE_LOOP,
21
+ REQUESTED_SLOT,
14
22
  SLOT_MAPPINGS,
15
23
  MAPPING_TYPE,
16
24
  SlotMappingType,
@@ -20,6 +28,11 @@ from rasa.shared.core.constants import (
20
28
  if TYPE_CHECKING:
21
29
  from rasa.shared.core.trackers import DialogueStateTracker
22
30
  from rasa.shared.core.domain import Domain
31
+ from rasa.shared.nlu.training_data.message import Message
32
+ from rasa.utils.endpoints import EndpointConfig
33
+
34
+
35
+ logger = logging.getLogger(__name__)
23
36
 
24
37
 
25
38
  class SlotMapping:
@@ -60,6 +73,7 @@ class SlotMapping:
60
73
  SlotMappingType.FROM_TRIGGER_INTENT: ["value"],
61
74
  SlotMappingType.FROM_TEXT: [],
62
75
  SlotMappingType.CUSTOM: [],
76
+ SlotMappingType.FROM_LLM: [],
63
77
  }
64
78
 
65
79
  required_keys = validations[mapping_type]
@@ -99,7 +113,10 @@ class SlotMapping:
99
113
 
100
114
  @staticmethod
101
115
  def intent_is_desired(
102
- mapping: Dict[Text, Any], tracker: "DialogueStateTracker", domain: "Domain"
116
+ mapping: Dict[Text, Any],
117
+ tracker: "DialogueStateTracker",
118
+ domain: "Domain",
119
+ message: Optional["Message"] = None,
103
120
  ) -> bool:
104
121
  """Checks whether user intent matches slot mapping intent specifications."""
105
122
  mapping_intents = SlotMapping.to_list(mapping.get(INTENT, []))
@@ -114,7 +131,9 @@ class SlotMapping:
114
131
  )
115
132
  )
116
133
 
117
- if tracker.latest_message:
134
+ if message is not None:
135
+ intent = message.get(INTENT, {}).get("name")
136
+ elif tracker.latest_message:
118
137
  intent = tracker.latest_message.intent.get(INTENT_NAME_KEY)
119
138
  else:
120
139
  intent = None
@@ -138,40 +157,44 @@ class SlotMapping:
138
157
 
139
158
  @staticmethod
140
159
  def entity_is_desired(
141
- mapping: Dict[Text, Any], tracker: "DialogueStateTracker"
142
- ) -> bool:
160
+ mapping: Dict[Text, Any],
161
+ tracker: "DialogueStateTracker",
162
+ message: Optional["Message"] = None,
163
+ ) -> List[str]:
143
164
  """Checks whether slot should be filled by an entity in the input or not.
144
165
 
145
166
  Args:
146
167
  mapping: Slot mapping.
147
168
  tracker: The tracker.
169
+ message: The message being processed.
148
170
 
149
171
  Returns:
150
- True, if slot should be filled, false otherwise.
172
+ A list of matching values.
151
173
  """
152
- slot_fulfils_entity_mapping = False
153
- if tracker.latest_message:
154
- extracted_entities = tracker.latest_message.entities
155
- else:
156
- extracted_entities = []
157
-
158
- for entity in extracted_entities:
159
- if (
160
- mapping.get(ENTITY_ATTRIBUTE_TYPE) == entity[ENTITY_ATTRIBUTE_TYPE]
161
- and mapping.get(ENTITY_ATTRIBUTE_ROLE)
162
- == entity.get(ENTITY_ATTRIBUTE_ROLE)
163
- and mapping.get(ENTITY_ATTRIBUTE_GROUP)
164
- == entity.get(ENTITY_ATTRIBUTE_GROUP)
165
- ):
166
- matching_values = tracker.get_latest_entity_values(
174
+ if message is not None:
175
+ extracted_entities = message.get(ENTITIES, [])
176
+ matching_values = [
177
+ cast(Text, entity[ENTITY_ATTRIBUTE_VALUE])
178
+ for entity in extracted_entities
179
+ if entity.get(ENTITY_ATTRIBUTE_TYPE)
180
+ == mapping.get(ENTITY_ATTRIBUTE_TYPE)
181
+ and entity.get(ENTITY_ATTRIBUTE_GROUP)
182
+ == mapping.get(ENTITY_ATTRIBUTE_GROUP)
183
+ and entity.get(ENTITY_ATTRIBUTE_ROLE)
184
+ == mapping.get(ENTITY_ATTRIBUTE_ROLE)
185
+ ]
186
+ elif tracker.latest_message and tracker.latest_message.text is not None:
187
+ matching_values = list(
188
+ tracker.get_latest_entity_values(
167
189
  mapping.get(ENTITY_ATTRIBUTE_TYPE),
168
190
  mapping.get(ENTITY_ATTRIBUTE_ROLE),
169
191
  mapping.get(ENTITY_ATTRIBUTE_GROUP),
170
192
  )
171
- slot_fulfils_entity_mapping = matching_values is not None
172
- break
193
+ )
194
+ else:
195
+ matching_values = []
173
196
 
174
- return slot_fulfils_entity_mapping
197
+ return matching_values
175
198
 
176
199
  @staticmethod
177
200
  def check_mapping_validity(
@@ -233,3 +256,271 @@ def validate_slot_mappings(domain_slots: Dict[Text, Any]) -> None:
233
256
 
234
257
  for slot_mapping in mappings:
235
258
  SlotMapping.validate(slot_mapping, slot_name)
259
+
260
+
261
+ class SlotFillingManager:
262
+ """Manages slot filling based on conversation context."""
263
+
264
+ def __init__(
265
+ self,
266
+ domain: "Domain",
267
+ tracker: "DialogueStateTracker",
268
+ message: Optional["Message"] = None,
269
+ action_endpoint: Optional["EndpointConfig"] = None,
270
+ ) -> None:
271
+ self.domain = domain
272
+ self.tracker = tracker
273
+ self.message = message
274
+ self._action_endpoint = action_endpoint
275
+
276
+ def is_slot_mapping_valid(
277
+ self,
278
+ slot_name: str,
279
+ mapping_type: SlotMappingType,
280
+ mapping: Dict[str, Any],
281
+ ) -> bool:
282
+ """Check if a slot mapping is valid."""
283
+ return SlotMapping.check_mapping_validity(
284
+ slot_name=slot_name,
285
+ mapping_type=mapping_type,
286
+ mapping=mapping,
287
+ domain=self.domain,
288
+ )
289
+
290
+ def is_intent_desired(self, mapping: Dict[str, Any]) -> bool:
291
+ """Check if the intent matches the one indicated in the slot mapping."""
292
+ return SlotMapping.intent_is_desired(
293
+ mapping=mapping,
294
+ tracker=self.tracker,
295
+ domain=self.domain,
296
+ message=self.message,
297
+ )
298
+
299
+ def _verify_mapping_conditions(
300
+ self, mapping: Dict[Text, Any], slot_name: Text
301
+ ) -> bool:
302
+ if mapping.get(MAPPING_CONDITIONS) and mapping[MAPPING_TYPE] != str(
303
+ SlotMappingType.FROM_TRIGGER_INTENT
304
+ ):
305
+ if not self._matches_mapping_conditions(mapping, slot_name):
306
+ return False
307
+
308
+ return True
309
+
310
+ def _matches_mapping_conditions(
311
+ self, mapping: Dict[Text, Any], slot_name: Text
312
+ ) -> bool:
313
+ slot_mapping_conditions = mapping.get(MAPPING_CONDITIONS)
314
+
315
+ if not slot_mapping_conditions:
316
+ return True
317
+
318
+ active_flow = self.tracker.active_flow
319
+
320
+ if active_flow:
321
+ return self._mapping_conditions_match_flow(
322
+ active_flow, slot_mapping_conditions
323
+ )
324
+
325
+ # if we are not in a flow, we could be in a form
326
+ return self._mapping_conditions_match_form(slot_name, slot_mapping_conditions)
327
+
328
+ @staticmethod
329
+ def _mapping_conditions_match_flow(
330
+ active_flow: str,
331
+ slot_mapping_conditions: List[Dict[str, str]],
332
+ ) -> bool:
333
+ active_flow_conditions = list(
334
+ filter(lambda x: x.get(ACTIVE_FLOW) is not None, slot_mapping_conditions)
335
+ )
336
+ return any(
337
+ [
338
+ condition.get(ACTIVE_FLOW) == active_flow
339
+ for condition in active_flow_conditions
340
+ ]
341
+ )
342
+
343
+ def _mapping_conditions_match_form(
344
+ self, slot_name: str, slot_mapping_conditions: List[Dict[str, str]]
345
+ ) -> bool:
346
+ if (
347
+ self.tracker.is_active_loop_rejected
348
+ and self.tracker.get_slot(REQUESTED_SLOT) == slot_name
349
+ ):
350
+ return False
351
+
352
+ # check if found mapping conditions matches form
353
+ for condition in slot_mapping_conditions:
354
+ # we allow None as a valid value for active_loop
355
+ # therefore we need to set a different default value
356
+ active_loop = condition.get(ACTIVE_LOOP, "")
357
+
358
+ if active_loop and active_loop == self.tracker.active_loop_name:
359
+ condition_requested_slot = condition.get(REQUESTED_SLOT)
360
+ if not condition_requested_slot:
361
+ return True
362
+ if condition_requested_slot == self.tracker.get_slot(REQUESTED_SLOT):
363
+ return True
364
+
365
+ if active_loop is None and self.tracker.active_loop_name is None:
366
+ return True
367
+
368
+ return False
369
+
370
+ def _fails_unique_entity_mapping_check(
371
+ self,
372
+ slot_name: Text,
373
+ mapping: Dict[Text, Any],
374
+ ) -> bool:
375
+ from rasa.core.actions.forms import FormAction
376
+
377
+ if mapping[MAPPING_TYPE] != str(SlotMappingType.FROM_ENTITY):
378
+ return False
379
+
380
+ form_name = self.tracker.active_loop_name
381
+
382
+ if not form_name:
383
+ return False
384
+
385
+ if self.tracker.get_slot(REQUESTED_SLOT) == slot_name:
386
+ return False
387
+
388
+ form = FormAction(form_name, self._action_endpoint)
389
+
390
+ if slot_name not in form.required_slots(self.domain):
391
+ return False
392
+
393
+ if form.entity_mapping_is_unique(mapping, self.domain):
394
+ return False
395
+
396
+ return True
397
+
398
+ def _is_trigger_intent_mapping_condition_met(
399
+ self, mapping: Dict[Text, Any]
400
+ ) -> bool:
401
+ active_loops_in_mapping_conditions = [
402
+ condition.get(ACTIVE_LOOP)
403
+ for condition in mapping.get(MAPPING_CONDITIONS, [])
404
+ ]
405
+
406
+ trigger_mapping_condition_met = True
407
+
408
+ if self.tracker.active_loop_name is None:
409
+ trigger_mapping_condition_met = False
410
+ elif (
411
+ active_loops_in_mapping_conditions
412
+ and self.tracker.active_loop_name is not None
413
+ and (
414
+ self.tracker.active_loop_name not in active_loops_in_mapping_conditions
415
+ )
416
+ ):
417
+ trigger_mapping_condition_met = False
418
+
419
+ return trigger_mapping_condition_met
420
+
421
+ def extract_slot_value_from_predefined_mapping(
422
+ self,
423
+ mapping_type: SlotMappingType,
424
+ mapping: Dict[Text, Any],
425
+ ) -> List[Any]:
426
+ """Extracts slot value if slot has an applicable predefined mapping."""
427
+ if (
428
+ self.message is None
429
+ and self.tracker.has_bot_message_after_latest_user_message()
430
+ ):
431
+ # TODO: this needs further validation - not sure if this breaks something!!!
432
+
433
+ # If the bot sent a message after the user sent a message, we can't
434
+ # extract any slots from the user message. We assume that the user
435
+ # message was already processed by the bot and the slot value was
436
+ # already extracted (e.g. for a prior form slot).
437
+ return []
438
+
439
+ should_fill_entity_slot = mapping_type == SlotMappingType.FROM_ENTITY
440
+
441
+ should_fill_intent_slot = mapping_type == SlotMappingType.FROM_INTENT
442
+
443
+ should_fill_text_slot = mapping_type == SlotMappingType.FROM_TEXT
444
+
445
+ trigger_mapping_condition_met = self._is_trigger_intent_mapping_condition_met(
446
+ mapping
447
+ )
448
+
449
+ should_fill_trigger_slot = (
450
+ mapping_type == SlotMappingType.FROM_TRIGGER_INTENT
451
+ and trigger_mapping_condition_met
452
+ )
453
+
454
+ value: List[Any] = []
455
+
456
+ if should_fill_entity_slot:
457
+ value = SlotMapping.entity_is_desired(mapping, self.tracker, self.message)
458
+ elif should_fill_intent_slot or should_fill_trigger_slot:
459
+ value = [mapping.get("value")]
460
+ elif should_fill_text_slot:
461
+ value = [self.message.get(TEXT)] if self.message is not None else []
462
+ if not value:
463
+ value = [
464
+ self.tracker.latest_message.text
465
+ if self.tracker.latest_message is not None
466
+ else None
467
+ ]
468
+
469
+ return value
470
+
471
+ def should_fill_slot(
472
+ self, slot_name: str, mapping_type: SlotMappingType, mapping: Dict[Text, Any]
473
+ ) -> bool:
474
+ """Checks if a slot should be filled based on the conversation context."""
475
+ if not self.is_slot_mapping_valid(slot_name, mapping_type, mapping):
476
+ return False
477
+
478
+ if not self.is_intent_desired(mapping):
479
+ return False
480
+
481
+ if not self._verify_mapping_conditions(mapping, slot_name):
482
+ return False
483
+
484
+ if self._fails_unique_entity_mapping_check(slot_name, mapping):
485
+ return False
486
+
487
+ return True
488
+
489
+
490
+ def extract_slot_value(
491
+ slot: Slot, slot_filling_manager: SlotFillingManager
492
+ ) -> Tuple[Any, bool]:
493
+ """Extracts the value of a slot based on the conversation context."""
494
+ is_extracted = False
495
+
496
+ for mapping in slot.mappings:
497
+ mapping_type = SlotMappingType(
498
+ mapping.get(MAPPING_TYPE, SlotMappingType.FROM_LLM.value)
499
+ )
500
+
501
+ if mapping_type in [SlotMappingType.FROM_LLM, SlotMappingType.CUSTOM]:
502
+ continue
503
+
504
+ if not slot_filling_manager.should_fill_slot(slot.name, mapping_type, mapping):
505
+ continue
506
+
507
+ value: List[Any] = (
508
+ slot_filling_manager.extract_slot_value_from_predefined_mapping(
509
+ mapping_type, mapping
510
+ )
511
+ )
512
+
513
+ if value:
514
+ if not isinstance(slot, ListSlot):
515
+ value = value[-1]
516
+
517
+ if (
518
+ value is not None
519
+ or slot_filling_manager.tracker.get_slot(slot.name) is not None
520
+ ):
521
+ logger.debug(f"Extracted value '{value}' for slot '{slot.name}'.")
522
+
523
+ is_extracted = True
524
+ return value, is_extracted
525
+
526
+ return None, is_extracted
rasa/shared/core/slots.py CHANGED
@@ -364,7 +364,7 @@ class ListSlot(Slot):
364
364
  """Sets the slot's value."""
365
365
  # Call property setter of superclass
366
366
  # FIXME: https://github.com/python/mypy/issues/8085
367
- super(ListSlot, self.__class__).value.fset(self, self.coerce_value(value)) # type: ignore[attr-defined] # noqa: E501
367
+ super(ListSlot, self.__class__).value.fset(self, self.coerce_value(value)) # type: ignore[attr-defined]
368
368
 
369
369
 
370
370
  class CategoricalSlot(Slot):
@@ -579,7 +579,9 @@ class CategoricalSlot(Slot):
579
579
  """
580
580
  # Call property setter of superclass
581
581
  # FIXME: https://github.com/python/mypy/issues/8085
582
- super(CategoricalSlot, self.__class__).value.fset(self, self.coerce_value(value)) # type: ignore[attr-defined] # noqa: E501
582
+ super(CategoricalSlot, self.__class__).value.fset( # type: ignore[attr-defined]
583
+ self, self.coerce_value(value)
584
+ )
583
585
 
584
586
 
585
587
  class AnySlot(Slot):
@@ -289,7 +289,7 @@ class DialogueStateTracker:
289
289
  parse_data_with_nlu_state = self.latest_message.parse_data.copy()
290
290
  # Combine entities predicted by NLU with entities predicted by policies so that
291
291
  # users can access them together via `latest_message` (e.g. in custom actions)
292
- parse_data_with_nlu_state[ENTITIES] = self.latest_message.entities # type: ignore[literal-required] # noqa: E501
292
+ parse_data_with_nlu_state[ENTITIES] = self.latest_message.entities # type: ignore[literal-required]
293
293
 
294
294
  return parse_data_with_nlu_state
295
295
 
@@ -443,6 +443,12 @@ class DialogueStateTracker:
443
443
  """
444
444
  return self._underlying_stack.copy()
445
445
 
446
+ @property
447
+ def active_flow(self) -> Optional[Text]:
448
+ """Returns the name of the active flow."""
449
+ current_context = self.stack.current_context()
450
+ return current_context.get("flow_id")
451
+
446
452
  @property
447
453
  def has_coexistence_routing_slot(self) -> bool:
448
454
  """Returns whether the coexistence routing slot is present."""
@@ -482,8 +488,10 @@ class DialogueStateTracker:
482
488
  entity_role: Optional[Text] = None,
483
489
  entity_group: Optional[Text] = None,
484
490
  ) -> Iterator[Text]:
485
- """Get entity values found for the passed entity type and optional role and
486
- group in latest message.
491
+ """Get entity values for latest message.
492
+
493
+ Returns entity values found for the passed entity type and
494
+ optional role and group in latest message.
487
495
 
488
496
  If you are only interested in the first entity of a given type use
489
497
  `next(tracker.get_latest_entity_values(`"`my_entity_name`"`), None)`.
@@ -556,7 +564,6 @@ class DialogueStateTracker:
556
564
  tracker = self.init_copy()
557
565
 
558
566
  for event in self.applied_events(True):
559
-
560
567
  if isinstance(event, ActionExecuted):
561
568
  yield tracker, event.hide_rule_turn
562
569
 
@@ -718,7 +725,7 @@ class DialogueStateTracker:
718
725
 
719
726
  def copy(self) -> "DialogueStateTracker":
720
727
  """Creates a duplicate of this tracker."""
721
- return self.travel_back_in_time(float("inf"))
728
+ return copy.deepcopy(self)
722
729
 
723
730
  def travel_back_in_time(self, target_time: float) -> "DialogueStateTracker":
724
731
  """Creates a new tracker with a state at a specific timestamp.
@@ -999,8 +1006,9 @@ class DialogueStateTracker:
999
1006
  flows: FlowsList,
1000
1007
  max_turns: Optional[int] = 20,
1001
1008
  ) -> FlowsList:
1002
- """
1003
- Retrieves a list of flows that have been started in the past within a given
1009
+ """Retrieves a list of previously started flows.
1010
+
1011
+ Returned flows have been started in the past within a given
1004
1012
  number of conversation turns.
1005
1013
 
1006
1014
  Args:
@@ -1015,7 +1023,6 @@ class DialogueStateTracker:
1015
1023
 
1016
1024
  # cycle through events in reverse order (newest events are appended at the end)
1017
1025
  for event in reversed(self.events):
1018
-
1019
1026
  # check for FlowStarted event and append flow if it's in the flows lists
1020
1027
  if (
1021
1028
  isinstance(event, FlowStarted)
@@ -1033,8 +1040,9 @@ class DialogueStateTracker:
1033
1040
  return FlowsList(underlying_flows=list(previously_started_flows.values()))
1034
1041
 
1035
1042
  def get_startable_flows(self, flows: FlowsList) -> FlowsList:
1036
- """
1037
- Retrieves a list of flows that are startable given the current
1043
+ """Retrieves a list of flows that can be started.
1044
+
1045
+ Returned flows are startable given the current
1038
1046
  state (context and slot values) of the tracker.
1039
1047
 
1040
1048
  Args:
@@ -1048,9 +1056,15 @@ class DialogueStateTracker:
1048
1056
  slots = self.slots
1049
1057
  return flows.get_startable_flows(context, slots)
1050
1058
 
1059
+ @property
1060
+ def has_active_user_flow(self) -> bool:
1061
+ from rasa.dialogue_understanding.stack.utils import top_user_flow_frame
1062
+
1063
+ top_relevant_frame = top_user_flow_frame(self.stack)
1064
+ return bool(top_relevant_frame and top_relevant_frame.flow_id)
1065
+
1051
1066
  def get_active_flows(self, flows: FlowsList) -> FlowsList:
1052
- """
1053
- Retrieve a list of all currently active flows.
1067
+ """Retrieve a list of all currently active flows.
1054
1068
 
1055
1069
  Args:
1056
1070
  flows: list of flows to check against for active flows.
@@ -1083,11 +1097,15 @@ class TrackerEventDiffEngine:
1083
1097
  def event_difference(
1084
1098
  original: DialogueStateTracker, tracker: DialogueStateTracker
1085
1099
  ) -> List[Event]:
1086
- """Returns all events from the new tracker which are not present
1087
- in the original tracker.
1100
+ """Find all events in the tracker not present in the original tracker.
1088
1101
 
1089
1102
  Args:
1103
+ original: Original tracker to compare against.
1090
1104
  tracker: Tracker containing events from the current conversation session.
1105
+
1106
+ Returns:
1107
+ List of events from the new tracker which are not present
1108
+ in the original tracker.
1091
1109
  """
1092
1110
  offset = len(original.events) if original else 0
1093
1111
  events = tracker.events
@@ -74,7 +74,6 @@ def load_data_from_files(
74
74
  story_steps = []
75
75
 
76
76
  for story_file in story_files:
77
-
78
77
  reader = _get_reader(story_file, domain)
79
78
 
80
79
  steps = reader.read_from_file(story_file)
@@ -83,8 +83,9 @@ class StoryReader:
83
83
  )
84
84
  if parsed_events is None:
85
85
  raise StoryParseError(
86
- "Unknown event '{}'. It is Neither an event "
87
- "nor an action).".format(event_name)
86
+ "Unknown event '{}'. It is Neither an event nor an action).".format(
87
+ event_name
88
+ )
88
89
  )
89
90
 
90
91
  return parsed_events
@@ -110,7 +111,6 @@ class StoryReader:
110
111
  def _add_checkpoint(
111
112
  self, name: Text, conditions: Optional[Dict[Text, Any]]
112
113
  ) -> None:
113
-
114
114
  # Ensure story part already has a name
115
115
  if not self.current_step_builder:
116
116
  raise StoryParseError(
@@ -87,6 +87,14 @@ CORE_SCHEMA_FILE = "shared/utils/schemas/stories.yml"
87
87
  DEFAULT_VALUE_TEXT_SLOTS = "filled"
88
88
  DEFAULT_VALUE_LIST_SLOTS = [DEFAULT_VALUE_TEXT_SLOTS]
89
89
 
90
+ INTENT_ENTITIES_PATTERN = (
91
+ f"^{INTENT_MESSAGE_PREFIX}"
92
+ f"(?P<{INTENT_NAME_KEY}>[^{{@]+)" # "{{" is a masked "{" in an f-string
93
+ f"(?P<{PREDICTED_CONFIDENCE_KEY}>@[0-9.]+)?"
94
+ f"(?P<{ENTITIES}>{{.+}})?" # "{{" is a masked "{" in an f-string
95
+ f"(?P<rest>.*)"
96
+ )
97
+
90
98
 
91
99
  class YAMLStoryReader(StoryReader):
92
100
  """Class that reads Core training data and rule data in YAML format."""
@@ -444,7 +452,7 @@ class YAMLStoryReader(StoryReader):
444
452
  f"{self._get_item_title()}:\n"
445
453
  f"User intent '{user_intent}' is a full retrieval intent. "
446
454
  f"Stories shouldn't contain full retrieval intents. "
447
- f"Rasa Open Source will only use base intent '{base_intent}' "
455
+ f"Rasa Pro will only use base intent '{base_intent}' "
448
456
  f"for training.",
449
457
  docs=self._get_docs_link(),
450
458
  )
@@ -482,7 +490,7 @@ class YAMLStoryReader(StoryReader):
482
490
 
483
491
  @staticmethod
484
492
  def _parse_raw_entities(
485
- raw_entities: Union[List[Dict[Text, Text]], List[Text]]
493
+ raw_entities: Union[List[Dict[Text, Text]], List[Text]],
486
494
  ) -> List[Dict[Text, Optional[Text]]]:
487
495
  final_entities = []
488
496
  for entity in raw_entities:
@@ -556,7 +564,6 @@ class YAMLStoryReader(StoryReader):
556
564
  return default_value
557
565
 
558
566
  def _parse_action(self, step: Dict[Text, Any]) -> None:
559
-
560
567
  action_name = step.get(KEY_ACTION, "")
561
568
  if not action_name:
562
569
  rasa.shared.utils.io.raise_warning(
@@ -582,7 +589,6 @@ class YAMLStoryReader(StoryReader):
582
589
  self._add_event(ActiveLoop.type_name, {LOOP_NAME: active_loop_name})
583
590
 
584
591
  def _parse_checkpoint(self, step: Dict[Text, Any]) -> None:
585
-
586
592
  checkpoint_name = step.get(KEY_CHECKPOINT, "")
587
593
  slots = step.get(KEY_CHECKPOINT_SLOTS, [])
588
594
 
@@ -611,13 +617,7 @@ class YAMLStoryReader(StoryReader):
611
617
  Returns:
612
618
  pattern with named groups
613
619
  """
614
- return re.compile(
615
- f"^{INTENT_MESSAGE_PREFIX}"
616
- f"(?P<{INTENT_NAME_KEY}>[^{{@]+)" # "{{" is a masked "{" in an f-string
617
- f"(?P<{PREDICTED_CONFIDENCE_KEY}>@[0-9.]+)?"
618
- f"(?P<{ENTITIES}>{{.+}})?" # "{{" is a masked "{" in an f-string
619
- f"(?P<rest>.*)"
620
- )
620
+ return re.compile(INTENT_ENTITIES_PATTERN)
621
621
 
622
622
  @staticmethod
623
623
  def unpack_regex_message(