rasa-pro 3.8.17__py3-none-any.whl → 3.9.14__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 (272) hide show
  1. README.md +5 -5
  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/core/actions/action.py +90 -315
  43. rasa/core/actions/action_exceptions.py +24 -0
  44. rasa/core/actions/constants.py +3 -0
  45. rasa/core/actions/custom_action_executor.py +188 -0
  46. rasa/core/actions/forms.py +11 -7
  47. rasa/core/actions/grpc_custom_action_executor.py +251 -0
  48. rasa/core/actions/http_custom_action_executor.py +140 -0
  49. rasa/core/actions/loops.py +3 -0
  50. rasa/core/actions/two_stage_fallback.py +1 -1
  51. rasa/core/agent.py +2 -4
  52. rasa/core/brokers/pika.py +1 -2
  53. rasa/core/channels/audiocodes.py +1 -1
  54. rasa/core/channels/botframework.py +0 -1
  55. rasa/core/channels/callback.py +0 -1
  56. rasa/core/channels/console.py +6 -8
  57. rasa/core/channels/development_inspector.py +1 -1
  58. rasa/core/channels/facebook.py +0 -3
  59. rasa/core/channels/hangouts.py +0 -6
  60. rasa/core/channels/inspector/dist/assets/{arc-5623b6dc.js → arc-b6e548fe.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-685c106a.js → c4Diagram-d0fbc5ce-fa03ac9e.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-8cbed007.js → classDiagram-936ed81e-ee67392a.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-5889cf12.js → classDiagram-v2-c3cb15f1-9b283fae.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-24c249d7.js → createText-62fc7601-8b6fcc2a.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-7dd06a75.js → edges-f2ad444c-22e77f4f.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-62c1e54c.js → erDiagram-9d236eb7-60ffc87f.js} +1 -1
  67. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-ce49b86f.js → flowDb-1972c806-9dd802e4.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4067e48f.js → flowDiagram-7ea5b25a-5fa1912f.js} +1 -1
  69. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +1 -0
  70. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-59fe4051.js → flowchart-elk-definition-abe16c3d-622a1fd2.js} +1 -1
  71. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-47e3a43b.js → ganttDiagram-9b5ea136-e285a63a.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-5a2ac0d9.js → gitGraphDiagram-99d0ae7c-f237bdca.js} +1 -1
  73. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-dfb8efc4.js → index-2c4b9a3b-4b03d70e.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/{index-268a75c0.js → index-a5d3e69d.js} +4 -4
  75. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-b0c470f2.js → infoDiagram-736b4530-72a0fa5f.js} +1 -1
  76. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-2edb829a.js → journeyDiagram-df861f2b-82218c41.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/{layout-b6873d69.js → layout-78cff630.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/{line-1efc5781.js → line-5038b469.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{linear-661e9b94.js → linear-c4fc4098.js} +1 -1
  80. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2d2e727f.js → mindmap-definition-beec6740-c33c8ea6.js} +1 -1
  81. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-9d3ea93d.js → pieDiagram-dbbf0591-a8d03059.js} +1 -1
  82. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-06a178a2.js → quadrantDiagram-4d7f4fd6-6a0e56b2.js} +1 -1
  83. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-0bfedffc.js → requirementDiagram-6fc4c22a-2dc7c7bd.js} +1 -1
  84. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-d76d0a04.js → sankeyDiagram-8f13d901-2360fe39.js} +1 -1
  85. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-37bb4341.js → sequenceDiagram-b655622a-41b9f9ad.js} +1 -1
  86. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-f52f7f57.js → stateDiagram-59f0c015-0aad326f.js} +1 -1
  87. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-4a986a20.js → stateDiagram-v2-2b26beab-9847d984.js} +1 -1
  88. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-7dd9ae12.js → styles-080da4f6-564d890e.js} +1 -1
  89. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-46e1ca14.js → styles-3dcbcfbf-38957613.js} +1 -1
  90. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-4a97439a.js → styles-9c745c82-f0fc6921.js} +1 -1
  91. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-823917a3.js → svgDrawCommon-4835440b-ef3c5a77.js} +1 -1
  92. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-9ea72896.js → timeline-definition-5b62e21b-bf3e91c1.js} +1 -1
  93. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-b631a8b6.js → xychartDiagram-2b33534f-4d4026c0.js} +1 -1
  94. rasa/core/channels/inspector/dist/index.html +1 -1
  95. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +10 -0
  96. rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -7
  97. rasa/core/channels/inspector/src/helpers/formatters.ts +3 -2
  98. rasa/core/channels/rest.py +36 -21
  99. rasa/core/channels/rocketchat.py +0 -1
  100. rasa/core/channels/socketio.py +1 -1
  101. rasa/core/channels/telegram.py +3 -3
  102. rasa/core/channels/webexteams.py +0 -1
  103. rasa/core/concurrent_lock_store.py +1 -1
  104. rasa/core/evaluation/marker_base.py +1 -3
  105. rasa/core/evaluation/marker_stats.py +1 -2
  106. rasa/core/featurizers/single_state_featurizer.py +2 -4
  107. rasa/core/featurizers/tracker_featurizers.py +0 -7
  108. rasa/core/information_retrieval/__init__.py +7 -0
  109. rasa/core/information_retrieval/faiss.py +9 -4
  110. rasa/core/information_retrieval/information_retrieval.py +64 -7
  111. rasa/core/information_retrieval/milvus.py +7 -14
  112. rasa/core/information_retrieval/qdrant.py +8 -15
  113. rasa/core/lock_store.py +0 -1
  114. rasa/core/migrate.py +1 -2
  115. rasa/core/nlg/callback.py +3 -4
  116. rasa/core/policies/enterprise_search_policy.py +86 -22
  117. rasa/core/policies/enterprise_search_prompt_template.jinja2 +4 -41
  118. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +60 -0
  119. rasa/core/policies/flows/flow_executor.py +104 -2
  120. rasa/core/policies/intentless_policy.py +7 -9
  121. rasa/core/policies/memoization.py +3 -3
  122. rasa/core/policies/policy.py +18 -9
  123. rasa/core/policies/rule_policy.py +8 -11
  124. rasa/core/policies/ted_policy.py +28 -30
  125. rasa/core/policies/unexpected_intent_policy.py +1 -2
  126. rasa/core/processor.py +136 -47
  127. rasa/core/run.py +41 -25
  128. rasa/core/secrets_manager/endpoints.py +2 -2
  129. rasa/core/secrets_manager/vault.py +6 -8
  130. rasa/core/test.py +3 -5
  131. rasa/core/tracker_store.py +49 -14
  132. rasa/core/train.py +1 -3
  133. rasa/core/training/interactive.py +9 -6
  134. rasa/core/utils.py +5 -10
  135. rasa/dialogue_understanding/coexistence/intent_based_router.py +11 -4
  136. rasa/dialogue_understanding/coexistence/llm_based_router.py +2 -3
  137. rasa/dialogue_understanding/commands/__init__.py +4 -0
  138. rasa/dialogue_understanding/commands/can_not_handle_command.py +9 -0
  139. rasa/dialogue_understanding/commands/cancel_flow_command.py +9 -0
  140. rasa/dialogue_understanding/commands/change_flow_command.py +38 -0
  141. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +9 -0
  142. rasa/dialogue_understanding/commands/clarify_command.py +9 -0
  143. rasa/dialogue_understanding/commands/correct_slots_command.py +9 -0
  144. rasa/dialogue_understanding/commands/error_command.py +12 -0
  145. rasa/dialogue_understanding/commands/handle_code_change_command.py +9 -0
  146. rasa/dialogue_understanding/commands/human_handoff_command.py +9 -0
  147. rasa/dialogue_understanding/commands/knowledge_answer_command.py +9 -0
  148. rasa/dialogue_understanding/commands/noop_command.py +9 -0
  149. rasa/dialogue_understanding/commands/set_slot_command.py +34 -3
  150. rasa/dialogue_understanding/commands/skip_question_command.py +9 -0
  151. rasa/dialogue_understanding/commands/start_flow_command.py +9 -0
  152. rasa/dialogue_understanding/generator/__init__.py +16 -1
  153. rasa/dialogue_understanding/generator/command_generator.py +92 -6
  154. rasa/dialogue_understanding/generator/constants.py +18 -0
  155. rasa/dialogue_understanding/generator/flow_retrieval.py +7 -5
  156. rasa/dialogue_understanding/generator/llm_based_command_generator.py +467 -0
  157. rasa/dialogue_understanding/generator/llm_command_generator.py +39 -609
  158. rasa/dialogue_understanding/generator/multi_step/__init__.py +0 -0
  159. rasa/dialogue_understanding/generator/multi_step/fill_slots_prompt.jinja2 +62 -0
  160. rasa/dialogue_understanding/generator/multi_step/handle_flows_prompt.jinja2 +38 -0
  161. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +827 -0
  162. rasa/dialogue_understanding/generator/nlu_command_adapter.py +69 -8
  163. rasa/dialogue_understanding/generator/single_step/__init__.py +0 -0
  164. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +345 -0
  165. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +44 -39
  166. rasa/dialogue_understanding/processor/command_processor.py +111 -3
  167. rasa/e2e_test/constants.py +1 -0
  168. rasa/e2e_test/e2e_test_case.py +44 -0
  169. rasa/e2e_test/e2e_test_runner.py +114 -11
  170. rasa/e2e_test/e2e_test_schema.yml +18 -0
  171. rasa/engine/caching.py +0 -1
  172. rasa/engine/graph.py +18 -6
  173. rasa/engine/recipes/config_files/default_config.yml +3 -3
  174. rasa/engine/recipes/default_components.py +1 -1
  175. rasa/engine/recipes/default_recipe.py +4 -5
  176. rasa/engine/recipes/recipe.py +1 -1
  177. rasa/engine/runner/dask.py +3 -9
  178. rasa/engine/storage/local_model_storage.py +0 -2
  179. rasa/engine/validation.py +179 -145
  180. rasa/exceptions.py +2 -2
  181. rasa/graph_components/validators/default_recipe_validator.py +3 -5
  182. rasa/hooks.py +0 -1
  183. rasa/model.py +1 -1
  184. rasa/model_training.py +1 -0
  185. rasa/nlu/classifiers/diet_classifier.py +8 -14
  186. rasa/nlu/extractors/crf_entity_extractor.py +4 -4
  187. rasa/nlu/extractors/duckling_entity_extractor.py +1 -1
  188. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +1 -5
  189. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +0 -4
  190. rasa/nlu/featurizers/featurizer.py +1 -1
  191. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +2 -4
  192. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +9 -12
  193. rasa/nlu/persistor.py +68 -26
  194. rasa/nlu/selectors/response_selector.py +7 -10
  195. rasa/nlu/test.py +0 -3
  196. rasa/nlu/utils/hugging_face/registry.py +1 -1
  197. rasa/nlu/utils/spacy_utils.py +1 -3
  198. rasa/server.py +22 -7
  199. rasa/shared/constants.py +12 -1
  200. rasa/shared/core/command_payload_reader.py +109 -0
  201. rasa/shared/core/constants.py +4 -5
  202. rasa/shared/core/domain.py +57 -56
  203. rasa/shared/core/events.py +4 -7
  204. rasa/shared/core/flows/flow.py +9 -0
  205. rasa/shared/core/flows/flows_list.py +12 -0
  206. rasa/shared/core/flows/steps/action.py +7 -2
  207. rasa/shared/core/generator.py +12 -11
  208. rasa/shared/core/slot_mappings.py +315 -24
  209. rasa/shared/core/slots.py +4 -2
  210. rasa/shared/core/trackers.py +32 -14
  211. rasa/shared/core/training_data/loading.py +0 -1
  212. rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
  213. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +11 -11
  214. rasa/shared/core/training_data/story_writer/yaml_story_writer.py +5 -3
  215. rasa/shared/core/training_data/structures.py +1 -1
  216. rasa/shared/core/training_data/visualization.py +1 -1
  217. rasa/shared/data.py +58 -1
  218. rasa/shared/exceptions.py +36 -2
  219. rasa/shared/importers/importer.py +1 -2
  220. rasa/shared/importers/rasa.py +0 -1
  221. rasa/shared/nlu/constants.py +2 -0
  222. rasa/shared/nlu/training_data/entities_parser.py +1 -2
  223. rasa/shared/nlu/training_data/formats/dialogflow.py +3 -2
  224. rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -5
  225. rasa/shared/nlu/training_data/formats/readerwriter.py +0 -1
  226. rasa/shared/nlu/training_data/message.py +13 -0
  227. rasa/shared/nlu/training_data/training_data.py +0 -2
  228. rasa/shared/providers/openai/session_handler.py +2 -2
  229. rasa/shared/utils/constants.py +3 -0
  230. rasa/shared/utils/io.py +11 -0
  231. rasa/shared/utils/llm.py +1 -2
  232. rasa/shared/utils/pykwalify_extensions.py +1 -0
  233. rasa/shared/utils/schemas/domain.yml +3 -0
  234. rasa/shared/utils/yaml.py +44 -35
  235. rasa/studio/auth.py +26 -10
  236. rasa/studio/constants.py +2 -0
  237. rasa/studio/data_handler.py +114 -107
  238. rasa/studio/download.py +160 -27
  239. rasa/studio/results_logger.py +137 -0
  240. rasa/studio/train.py +6 -7
  241. rasa/studio/upload.py +159 -134
  242. rasa/telemetry.py +188 -34
  243. rasa/tracing/config.py +18 -3
  244. rasa/tracing/constants.py +26 -2
  245. rasa/tracing/instrumentation/attribute_extractors.py +50 -41
  246. rasa/tracing/instrumentation/instrumentation.py +290 -44
  247. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +7 -5
  248. rasa/tracing/instrumentation/metrics.py +109 -21
  249. rasa/tracing/metric_instrument_provider.py +83 -3
  250. rasa/utils/cli.py +2 -1
  251. rasa/utils/common.py +1 -1
  252. rasa/utils/endpoints.py +1 -2
  253. rasa/utils/io.py +6 -6
  254. rasa/utils/licensing.py +246 -31
  255. rasa/utils/ml_utils.py +1 -1
  256. rasa/utils/tensorflow/data_generator.py +1 -1
  257. rasa/utils/tensorflow/environment.py +1 -1
  258. rasa/utils/tensorflow/model_data.py +9 -11
  259. rasa/utils/tensorflow/model_data_utils.py +499 -500
  260. rasa/utils/tensorflow/models.py +5 -6
  261. rasa/utils/tensorflow/rasa_layers.py +15 -15
  262. rasa/utils/train_utils.py +1 -1
  263. rasa/utils/url_tools.py +53 -0
  264. rasa/validator.py +305 -3
  265. rasa/version.py +1 -1
  266. {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/METADATA +22 -22
  267. {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/RECORD +271 -253
  268. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-85583a23.js +0 -1
  269. /rasa/dialogue_understanding/generator/{command_prompt_template.jinja2 → single_step/command_prompt_template.jinja2} +0 -0
  270. {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/NOTICE +0 -0
  271. {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/WHEEL +0 -0
  272. {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, List, Text
1
+ from typing import Text, Any, Dict
2
2
 
3
3
  import structlog
4
4
  from langchain.vectorstores.qdrant import Qdrant
@@ -6,15 +6,12 @@ from pydantic import ValidationError
6
6
  from qdrant_client import QdrantClient
7
7
  from rasa.utils.endpoints import EndpointConfig
8
8
 
9
- from rasa.core.information_retrieval.information_retrieval import (
9
+ from rasa.core.information_retrieval import (
10
+ SearchResultList,
10
11
  InformationRetrieval,
11
12
  InformationRetrievalException,
12
13
  )
13
14
 
14
- if TYPE_CHECKING:
15
- from langchain.schema import Document
16
- from langchain.schema.embeddings import Embeddings
17
-
18
15
  logger = structlog.get_logger()
19
16
 
20
17
 
@@ -41,12 +38,6 @@ class QdrantInformationRetrievalException(InformationRetrievalException):
41
38
 
42
39
 
43
40
  class Qdrant_Store(InformationRetrieval):
44
- def __init__(
45
- self,
46
- embeddings: "Embeddings",
47
- ) -> None:
48
- self.embeddings = embeddings
49
-
50
41
  def connect(
51
42
  self,
52
43
  config: EndpointConfig,
@@ -73,7 +64,9 @@ class Qdrant_Store(InformationRetrieval):
73
64
  metadata_payload_key=params.get("metadata_payload_key", "metadata"),
74
65
  )
75
66
 
76
- async def search(self, query: Text, threshold: float = 0.0) -> List["Document"]:
67
+ async def search(
68
+ self, query: Text, tracker_state: Dict[str, Any], threshold: float = 0.0
69
+ ) -> SearchResultList:
77
70
  """Search for a document in the Qdrant vector store.
78
71
 
79
72
  Args:
@@ -83,7 +76,7 @@ class Qdrant_Store(InformationRetrieval):
83
76
  Returns:
84
77
  A list of documents that match the query.
85
78
  """
86
- logger.info("information_retrieval.qdrant_store.search", query=query)
79
+ logger.debug("information_retrieval.qdrant_store.search", query=query)
87
80
  try:
88
81
  hits = await self.client.asimilarity_search(
89
82
  query, k=4, score_threshold=threshold
@@ -99,4 +92,4 @@ class Qdrant_Store(InformationRetrieval):
99
92
  raise QdrantInformationRetrievalException(
100
93
  f"Failed to search the Qdrant vector store. Encountered error: {e}"
101
94
  ) from e
102
- return hits
95
+ return SearchResultList.from_document_list(hits)
rasa/core/lock_store.py CHANGED
@@ -100,7 +100,6 @@ class LockStore:
100
100
  """
101
101
  ticket = self.issue_ticket(conversation_id, lock_lifetime)
102
102
  try:
103
-
104
103
  yield await self._acquire_lock(
105
104
  conversation_id, ticket, wait_time_in_seconds
106
105
  )
rasa/core/migrate.py CHANGED
@@ -84,7 +84,7 @@ def _get_updated_or_new_mappings(
84
84
 
85
85
 
86
86
  def _migrate_form_slots(
87
- domain: Dict[Text, Any]
87
+ domain: Dict[Text, Any],
88
88
  ) -> Tuple[Dict[Any, Dict[str, Any]], Optional[Any]]:
89
89
  updated_slots = domain.get(KEY_SLOTS, {})
90
90
  forms = domain.get(KEY_FORMS, {})
@@ -228,7 +228,6 @@ def _migrate_domain_files(
228
228
  )
229
229
 
230
230
  for file in domain_files:
231
-
232
231
  backup = backup_location / file.name
233
232
  original_content = _create_back_up(file, backup)
234
233
 
rasa/core/nlg/callback.py CHANGED
@@ -62,7 +62,6 @@ class CallbackNaturalLanguageGenerator(NaturalLanguageGenerator):
62
62
  """
63
63
 
64
64
  def __init__(self, endpoint_config: EndpointConfig) -> None:
65
-
66
65
  self.nlg_endpoint = endpoint_config
67
66
 
68
67
  async def generate(
@@ -82,9 +81,9 @@ class CallbackNaturalLanguageGenerator(NaturalLanguageGenerator):
82
81
  body = nlg_request_format(utter_action, tracker, output_channel, **kwargs)
83
82
 
84
83
  logger.debug(
85
- "Requesting NLG for {} from {}."
86
- "The request body is {}."
87
- "".format(utter_action, self.nlg_endpoint.url, json.dumps(body))
84
+ "Requesting NLG for {} from {}. The request body is {}.".format(
85
+ utter_action, self.nlg_endpoint.url, json.dumps(body)
86
+ )
88
87
  )
89
88
 
90
89
  response = await self.nlg_endpoint.request(
@@ -4,10 +4,16 @@ import re
4
4
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text
5
5
 
6
6
  import dotenv
7
- import rasa.shared.utils.io
8
7
  import structlog
9
8
  from jinja2 import Template
10
- from pydantic.error_wrappers import ValidationError
9
+ from pydantic import ValidationError
10
+
11
+ import rasa.shared.utils.io
12
+ from rasa.telemetry import (
13
+ track_enterprise_search_policy_predict,
14
+ track_enterprise_search_policy_train_completed,
15
+ track_enterprise_search_policy_train_started,
16
+ )
11
17
  from rasa.shared.exceptions import RasaException
12
18
  from rasa.core.constants import (
13
19
  POLICY_MAX_HISTORY,
@@ -41,7 +47,7 @@ from rasa.shared.core.constants import (
41
47
  from rasa.shared.core.domain import Domain
42
48
  from rasa.shared.core.events import Event
43
49
  from rasa.shared.core.generator import TrackerWithCachedStates
44
- from rasa.shared.core.trackers import DialogueStateTracker
50
+ from rasa.shared.core.trackers import DialogueStateTracker, EventVerbosity
45
51
  from rasa.shared.nlu.training_data.training_data import TrainingData
46
52
  from rasa.shared.utils.cli import print_error_and_exit
47
53
  from rasa.shared.utils.io import deep_container_fingerprint
@@ -54,16 +60,15 @@ from rasa.shared.utils.llm import (
54
60
  sanitize_message_for_prompt,
55
61
  tracker_as_readable_transcript,
56
62
  )
57
-
58
63
  from rasa.core.information_retrieval.faiss import FAISS_Store
59
- from rasa.core.information_retrieval.information_retrieval import (
64
+ from rasa.core.information_retrieval import (
60
65
  InformationRetrieval,
66
+ SearchResult,
61
67
  InformationRetrievalException,
62
68
  create_from_endpoint_config,
63
69
  )
64
70
 
65
71
  if TYPE_CHECKING:
66
- from langchain.schema import Document
67
72
  from langchain.schema.embeddings import Embeddings
68
73
  from langchain.llms.base import BaseLLM
69
74
  from rasa.core.featurizers.tracker_featurizers import TrackerFeaturizer
@@ -78,6 +83,9 @@ SOURCE_PROPERTY = "source"
78
83
  VECTOR_STORE_TYPE_PROPERTY = "type"
79
84
  VECTOR_STORE_PROPERTY = "vector_store"
80
85
  VECTOR_STORE_THRESHOLD_PROPERTY = "threshold"
86
+ TRACE_TOKENS_PROPERTY = "trace_prompt_tokens"
87
+ CITATION_ENABLED_PROPERTY = "citation_enabled"
88
+ USE_LLM_PROPERTY = "use_generative_llm"
81
89
 
82
90
  DEFAULT_VECTOR_STORE_TYPE = "faiss"
83
91
  DEFAULT_VECTOR_STORE_THRESHOLD = 0.0
@@ -109,6 +117,10 @@ DEFAULT_ENTERPRISE_SEARCH_PROMPT_TEMPLATE = importlib.resources.read_text(
109
117
  "rasa.core.policies", "enterprise_search_prompt_template.jinja2"
110
118
  )
111
119
 
120
+ DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_CITATION_TEMPLATE = importlib.resources.read_text(
121
+ "rasa.core.policies", "enterprise_search_prompt_with_citation_template.jinja2"
122
+ )
123
+
112
124
 
113
125
  class VectorStoreConnectionError(RasaException):
114
126
  """Exception raised for errors in connecting to the vector store."""
@@ -171,13 +183,24 @@ class EnterpriseSearchPolicy(Policy):
171
183
  self.vector_store_config = config.get(
172
184
  VECTOR_STORE_PROPERTY, DEFAULT_VECTOR_STORE
173
185
  )
186
+ self.llm_config = self.config.get(LLM_CONFIG_KEY, DEFAULT_LLM_CONFIG)
187
+ self.embeddings_config = self.config.get(
188
+ EMBEDDINGS_CONFIG_KEY, DEFAULT_EMBEDDINGS_CONFIG
189
+ )
174
190
  self.max_history = self.config.get(POLICY_MAX_HISTORY)
175
191
  self.prompt_template = prompt_template or get_prompt_template(
176
192
  self.config.get("prompt"),
177
193
  DEFAULT_ENTERPRISE_SEARCH_PROMPT_TEMPLATE,
178
194
  )
179
- self.trace_prompt_tokens = self.config.get("trace_prompt_tokens", False)
180
- self.citation_enabled = self.config.get("citation_enabled", False)
195
+ self.trace_prompt_tokens = self.config.get(TRACE_TOKENS_PROPERTY, False)
196
+ self.use_llm = self.config.get(USE_LLM_PROPERTY, True)
197
+ self.citation_enabled = self.config.get(CITATION_ENABLED_PROPERTY, False)
198
+ self.citation_prompt_template = get_prompt_template(
199
+ self.config.get("prompt"),
200
+ DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_CITATION_TEMPLATE,
201
+ )
202
+ if self.citation_enabled:
203
+ self.prompt_template = self.citation_prompt_template
181
204
 
182
205
  @classmethod
183
206
  def _create_plain_embedder(cls, config: Dict[Text, Any]) -> "Embeddings":
@@ -216,6 +239,9 @@ class EnterpriseSearchPolicy(Policy):
216
239
  """
217
240
  store_type = self.vector_store_config.get(VECTOR_STORE_TYPE_PROPERTY)
218
241
 
242
+ # telemetry call to track training start
243
+ track_enterprise_search_policy_train_started()
244
+
219
245
  # validate embedding configuration
220
246
  try:
221
247
  embeddings = self._create_plain_embedder(self.config)
@@ -246,6 +272,16 @@ class EnterpriseSearchPolicy(Policy):
246
272
  else:
247
273
  logger.info("enterprise_search_policy.train.custom", store_type=store_type)
248
274
 
275
+ # telemetry call to track training completion
276
+ track_enterprise_search_policy_train_completed(
277
+ vector_store_type=store_type,
278
+ embeddings_type=self.embeddings_config.get("_type"),
279
+ embeddings_model=self.embeddings_config.get("model")
280
+ or self.embeddings_config.get("model_name"),
281
+ llm_type=self.llm_config.get("_type"),
282
+ llm_model=self.llm_config.get("model") or self.llm_config.get("model_name"),
283
+ citation_enabled=self.citation_enabled,
284
+ )
249
285
  self.persist()
250
286
  return self._resource
251
287
 
@@ -353,7 +389,9 @@ class EnterpriseSearchPolicy(Policy):
353
389
  VECTOR_STORE_THRESHOLD_PROPERTY, DEFAULT_VECTOR_STORE_THRESHOLD
354
390
  )
355
391
  llm = llm_factory(self.config.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG)
356
- if not self.supports_current_stack_frame(tracker, False, False):
392
+ if not self.supports_current_stack_frame(
393
+ tracker, False, False
394
+ ) or self.should_abstain_in_coexistence(tracker, True):
357
395
  return self._prediction(self._default_predictions(domain))
358
396
 
359
397
  if not self.vector_store:
@@ -367,48 +405,74 @@ class EnterpriseSearchPolicy(Policy):
367
405
  return self._create_prediction_internal_error(domain, tracker)
368
406
 
369
407
  search_query = self._get_last_user_message(tracker)
408
+ tracker_state = tracker.current_state(EventVerbosity.AFTER_RESTART)
370
409
 
371
410
  try:
372
411
  documents = await self.vector_store.search(
373
412
  query=search_query,
413
+ tracker_state=tracker_state,
374
414
  threshold=vector_search_threshold,
375
415
  )
376
416
  except InformationRetrievalException as e:
377
417
  logger.error(f"{logger_key}.search_error", error=e)
378
418
  return self._create_prediction_internal_error(domain, tracker)
379
419
 
380
- if not documents:
420
+ if not documents.results:
381
421
  logger.info(f"{logger_key}.no_documents")
382
422
  return self._create_prediction_cannot_handle(domain, tracker)
383
423
 
384
- logger.debug(f"{logger_key}.documents", num_documents=len(documents))
385
- prompt = self._render_prompt(tracker, documents)
386
- llm_answer = await self._generate_llm_answer(llm, prompt)
387
- if llm_answer is None:
388
- return self._create_prediction_internal_error(domain, tracker)
424
+ if self.use_llm:
425
+ prompt = self._render_prompt(tracker, documents.results)
426
+ llm_answer = await self._generate_llm_answer(llm, prompt)
389
427
 
390
- if self.citation_enabled:
391
- llm_answer = self.post_process_citations(llm_answer)
428
+ if self.citation_enabled:
429
+ llm_answer = self.post_process_citations(llm_answer)
430
+
431
+ logger.debug(f"{logger_key}.llm_answer", llm_answer=llm_answer)
432
+ response = llm_answer
433
+ else:
434
+ response = documents.results[0].metadata.get("answer", None)
435
+ if not response:
436
+ logger.error(
437
+ f"{logger_key}.answer_key_missing_in_metadata",
438
+ search_results=documents.results,
439
+ )
440
+ logger.debug(
441
+ "enterprise_search_policy.predict_action_probabilities.no_llm",
442
+ search_results=documents,
443
+ )
444
+
445
+ if response is None:
446
+ return self._create_prediction_internal_error(domain, tracker)
392
447
 
393
- logger.debug(f"{logger_key}.llm_answer", llm_answer=llm_answer)
394
448
  action_metadata = {
395
449
  "message": {
396
- "text": llm_answer,
450
+ "text": response,
397
451
  }
398
452
  }
399
453
 
454
+ # telemetry call to track policy prediction
455
+ track_enterprise_search_policy_predict(
456
+ vector_store_type=self.vector_store_config.get(VECTOR_STORE_TYPE_PROPERTY),
457
+ embeddings_type=self.embeddings_config.get("_type"),
458
+ embeddings_model=self.embeddings_config.get("model")
459
+ or self.embeddings_config.get("model_name"),
460
+ llm_type=self.llm_config.get("_type"),
461
+ llm_model=self.llm_config.get("model") or self.llm_config.get("model_name"),
462
+ citation_enabled=self.citation_enabled,
463
+ )
400
464
  return self._create_prediction(
401
465
  domain=domain, tracker=tracker, action_metadata=action_metadata
402
466
  )
403
467
 
404
468
  def _render_prompt(
405
- self, tracker: DialogueStateTracker, documents: List["Document"]
469
+ self, tracker: DialogueStateTracker, documents: List[SearchResult]
406
470
  ) -> Text:
407
471
  """Renders the prompt from the template.
408
472
 
409
473
  Args:
410
474
  tracker: The tracker containing the conversation history up to now.
411
- documents: The documents retrieved from the vector store.
475
+ documents: The documents retrieved from search
412
476
 
413
477
  Returns:
414
478
  The rendered prompt.
@@ -529,7 +593,7 @@ class EnterpriseSearchPolicy(Policy):
529
593
  """
530
594
  result = self._default_predictions(domain)
531
595
  if action_name:
532
- result[domain.index_for_action(action_name)] = score # type: ignore[assignment] # noqa: E501
596
+ result[domain.index_for_action(action_name)] = score # type: ignore[assignment]
533
597
  return result
534
598
 
535
599
  @classmethod
@@ -4,39 +4,10 @@ If the answer is not known or cannot be determined from the provided documents o
4
4
  ### Relevant Documents
5
5
  Use the following documents to answer the question:
6
6
  {% for doc in docs %}
7
- {{ loop.cycle("*")}}. {{ doc.metadata }}
8
- {{ doc.page_content }}
7
+ {{ loop.index }}. {{ doc.metadata }}
8
+ {{ doc.text }}
9
9
  {% endfor %}
10
10
 
11
- {% if citation_enabled %}
12
- ### Citing Sources
13
- Find the sources from the documents that are most relevant to answering the question.
14
- The sources must be extracted from the given document metadata source property and not from the conversation context.
15
- If there are no relevant sources, write "No relevant sources" instead.
16
-
17
- For each source you cite, follow a 1-based numbering system for citations.
18
- Start with [1] for the first source you refer to, regardless of its index in the provided list of documents.
19
- If you cite another source, use the next number in sequence, [2], and so on.
20
- Ensure each source is only assigned one number, even if referenced multiple times.
21
- If you refer back to a previously cited source, use its originally assigned number.
22
-
23
- For example, if you first cite the third source in the list, refer to it as [1].
24
- If you then cite the first source in the list, refer to it as [2].
25
- If you mention the third source again, still refer to it as [1].
26
-
27
- Don't say "According to Source [1]" when answering. Instead, make references to sources relevant to each section of the answer solely by adding the bracketed number at the end of the relevant sentence.
28
- #### Formatting
29
- First print the answer with in-text citations which follow a numbered order starting with index 1, then add the sources section.
30
- The format of your overall answer must look like what's shown between the <example></example> tags.
31
- Make sure to follow the formatting exactly and remove any line breaks or whitespaces between the answer and the Sources section.
32
- <example>
33
- You can use flows to model business logic in Rasa assistants. [1] You can use the Enterprise Search Policy to search vector stores for relevant knowledge base documents. [2]
34
- Sources:
35
- [1] https://rasa.com/docs/rasa-pro/concepts/flows
36
- [2] https://rasa.com/docs/rasa-pro/concepts/policies/enterprise-search-policy
37
- </example>
38
- {% endif %}
39
-
40
11
  {% if slots|length > 0 %}
41
12
  ### Slots or Variables
42
13
  Here are the variables of the currently active conversation which may be used to answer the question:
@@ -49,14 +20,6 @@ Here are the variables of the currently active conversation which may be used to
49
20
  Transcript of the current conversation, use it to determine the context of the question:
50
21
  {{ current_conversation }}
51
22
 
52
-
53
- ## Answering the Question
54
- Based on the above sections, please formulate an answer to the question or request in the user's last message.
55
- It is important that you ensure the answer is grounded in the provided documents and conversation context.
23
+ Based on the above, please formulate an answer to the question or request in the user's last message.
24
+ It is important that you ensure the answer is grounded in the provided documents and conversation context.
56
25
  Avoid speculating or making assumptions beyond the given information and keep your answers short, 2 to 3 sentences at most.
57
-
58
- {% if citation_enabled %}
59
- If you are unable to find an answer in the given relevant documents, do not cite sources from elsewhere in the conversation context.
60
- {% endif %}
61
-
62
- Your answer:
@@ -0,0 +1,60 @@
1
+ Given the following information, please provide an answer based on the provided documents and the context of the recent conversation.
2
+ If the answer is not known or cannot be determined from the provided documents or context, please state that you do not know to the user.
3
+ ### Relevant Documents
4
+ Use the following documents to answer the question:
5
+ {% for doc in docs %}
6
+ {{ loop.cycle("*")}}. {{ doc.metadata }}
7
+ {{ doc.page_content }}
8
+ {% endfor %}
9
+
10
+ {% if citation_enabled %}
11
+ ### Citing Sources
12
+ Find the sources from the documents that are most relevant to answering the question.
13
+ The sources must be extracted from the given document metadata source property and not from the conversation context.
14
+ If there are no relevant sources, write "No relevant sources" instead.
15
+
16
+ For each source you cite, follow a 1-based numbering system for citations.
17
+ Start with [1] for the first source you refer to, regardless of its index in the provided list of documents.
18
+ If you cite another source, use the next number in sequence, [2], and so on.
19
+ Ensure each source is only assigned one number, even if referenced multiple times.
20
+ If you refer back to a previously cited source, use its originally assigned number.
21
+
22
+ For example, if you first cite the third source in the list, refer to it as [1].
23
+ If you then cite the first source in the list, refer to it as [2].
24
+ If you mention the third source again, still refer to it as [1].
25
+
26
+ Don't say "According to Source [1]" when answering. Instead, make references to sources relevant to each section of the answer solely by adding the bracketed number at the end of the relevant sentence.
27
+ #### Formatting
28
+ First print the answer with in-text citations which follow a numbered order starting with index 1, then add the sources section.
29
+ The format of your overall answer must look like what's shown between the <example></example> tags.
30
+ Make sure to follow the formatting exactly and remove any line breaks or whitespaces between the answer and the Sources section.
31
+ <example>
32
+ You can use flows to model business logic in Rasa assistants. [1] You can use the Enterprise Search Policy to search vector stores for relevant knowledge base documents. [2]
33
+ Sources:
34
+ [1] https://rasa.com/docs/rasa-pro/concepts/flows
35
+ [2] https://rasa.com/docs/rasa-pro/concepts/policies/enterprise-search-policy
36
+ </example>
37
+ {% endif %}
38
+
39
+ {% if slots|length > 0 %}
40
+ ### Slots or Variables
41
+ Here are the variables of the currently active conversation which may be used to answer the question:
42
+ {% for slot in slots -%}
43
+ - name: {{ slot.name }}, value: {{ slot.value }}, type: {{ slot.type }}
44
+ {% endfor %}
45
+ {% endif %}
46
+ ### Current Conversation
47
+ Transcript of the current conversation, use it to determine the context of the question:
48
+ {{ current_conversation }}
49
+
50
+
51
+ ## Answering the Question
52
+ Based on the above sections, please formulate an answer to the question or request in the user's last message.
53
+ It is important that you ensure the answer is grounded in the provided documents and conversation context.
54
+ Avoid speculating or making assumptions beyond the given information and keep your answers short, 2 to 3 sentences at most.
55
+
56
+ {% if citation_enabled %}
57
+ If you are unable to find an answer in the given relevant documents, do not cite sources from elsewhere in the conversation context.
58
+ {% endif %}
59
+
60
+ Your answer:
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  from typing import Any, Dict, Text, List, Optional
4
4
 
5
5
  from jinja2 import Template
6
+ from rasa.dialogue_understanding.commands import CancelFlowCommand
7
+ from rasa.dialogue_understanding.patterns.cancel import CancelPatternFlowStackFrame
6
8
  from structlog.contextvars import (
7
9
  bound_contextvars,
8
10
  )
@@ -17,6 +19,9 @@ from rasa.core.policies.flows.flow_step_result import (
17
19
  FlowStepResult,
18
20
  PauseFlowReturnPrediction,
19
21
  )
22
+ from rasa.dialogue_understanding.patterns.internal_error import (
23
+ InternalErrorPatternFlowStackFrame,
24
+ )
20
25
  from rasa.dialogue_understanding.patterns.search import SearchPatternFlowStackFrame
21
26
  from rasa.dialogue_understanding.stack.dialogue_stack import DialogueStack
22
27
  from rasa.dialogue_understanding.stack.frames import (
@@ -42,7 +47,7 @@ from rasa.dialogue_understanding.stack.utils import (
42
47
 
43
48
  from pypred import Predicate
44
49
 
45
- from rasa.shared.core.constants import ACTION_LISTEN_NAME
50
+ from rasa.shared.core.constants import ACTION_LISTEN_NAME, SlotMappingType
46
51
  from rasa.shared.core.events import (
47
52
  Event,
48
53
  FlowCompleted,
@@ -72,6 +77,7 @@ from rasa.shared.core.flows.flow import (
72
77
  FlowStep,
73
78
  )
74
79
  from rasa.shared.core.flows.steps.collect import SlotRejection
80
+ from rasa.shared.core.slots import Slot
75
81
  from rasa.shared.core.trackers import (
76
82
  DialogueStateTracker,
77
83
  )
@@ -397,7 +403,6 @@ def advance_flows_until_next_action(
397
403
  number_of_steps_taken = 0
398
404
 
399
405
  while isinstance(step_result, ContinueFlowWithNextStep):
400
-
401
406
  number_of_steps_taken += 1
402
407
  if number_of_steps_taken > MAX_NUMBER_OF_STEPS:
403
408
  raise FlowCircuitBreakerTrippedException(
@@ -467,6 +472,87 @@ def advance_flows_until_next_action(
467
472
  return FlowActionPrediction(None, 0.0, events=gathered_events)
468
473
 
469
474
 
475
+ def validate_collect_step(
476
+ step: CollectInformationFlowStep,
477
+ stack: DialogueStack,
478
+ available_actions: List[str],
479
+ slots: Dict[Text, Slot],
480
+ ) -> bool:
481
+ """Validate that a collect step can be executed.
482
+
483
+ A collect step can be executed if either the `utter_ask` or the `action_ask` is
484
+ defined in the domain. If neither is defined, the collect step can still be
485
+ executed if the slot has an initial value defined in the domain, which would cause
486
+ the step to be skipped."""
487
+ slot = slots.get(step.collect)
488
+ slot_has_initial_value_defined = slot and slot.initial_value is not None
489
+ if (
490
+ slot_has_initial_value_defined
491
+ or step.utter in available_actions
492
+ or step.collect_action in available_actions
493
+ ):
494
+ return True
495
+
496
+ structlogger.error(
497
+ "flow.step.run.collect_missing_utter_or_collect_action",
498
+ slot_name=step.collect,
499
+ )
500
+
501
+ cancel_flow_and_push_internal_error(stack)
502
+
503
+ return False
504
+
505
+
506
+ def cancel_flow_and_push_internal_error(stack: DialogueStack) -> None:
507
+ """Cancel the top user flow and push the internal error pattern."""
508
+ top_frame = stack.top()
509
+
510
+ if isinstance(top_frame, BaseFlowStackFrame):
511
+ # we need to first cancel the top user flow
512
+ # because we cannot collect one of its slots
513
+ # and therefore should not proceed with the flow
514
+ # after triggering pattern_internal_error
515
+ canceled_frames = CancelFlowCommand.select_canceled_frames(stack)
516
+ stack.push(
517
+ CancelPatternFlowStackFrame(
518
+ canceled_name=top_frame.flow_id,
519
+ canceled_frames=canceled_frames,
520
+ )
521
+ )
522
+ stack.push(InternalErrorPatternFlowStackFrame())
523
+
524
+
525
+ def validate_custom_slot_mappings(
526
+ step: CollectInformationFlowStep,
527
+ stack: DialogueStack,
528
+ tracker: DialogueStateTracker,
529
+ available_actions: List[str],
530
+ ) -> bool:
531
+ """Validate a slot with custom mappings.
532
+
533
+ If invalid, trigger pattern_internal_error and return False.
534
+ """
535
+ slot = tracker.slots.get(step.collect, None)
536
+ slot_mappings = slot.mappings if slot else []
537
+ for mapping in slot_mappings:
538
+ if (
539
+ mapping.get("type") == SlotMappingType.CUSTOM.value
540
+ and mapping.get("action") is None
541
+ ):
542
+ # this is a slot that must be filled by a custom action
543
+ # check if collect_action exists
544
+ if step.collect_action not in available_actions:
545
+ structlogger.error(
546
+ "flow.step.run.collect_action_not_found_for_custom_slot_mapping",
547
+ action=step.collect_action,
548
+ collect=step.collect,
549
+ )
550
+ cancel_flow_and_push_internal_error(stack)
551
+ return False
552
+
553
+ return True
554
+
555
+
470
556
  def run_step(
471
557
  step: FlowStep,
472
558
  flow: Flow,
@@ -500,6 +586,22 @@ def run_step(
500
586
  initial_events.append(FlowStarted(flow.id))
501
587
 
502
588
  if isinstance(step, CollectInformationFlowStep):
589
+ is_step_valid = validate_collect_step(
590
+ step, stack, available_actions, tracker.slots
591
+ )
592
+ if not is_step_valid:
593
+ # if we return any other FlowStepResult, the assistant will stay silent
594
+ # instead of triggering the internal error pattern
595
+ return ContinueFlowWithNextStep(events=initial_events)
596
+
597
+ is_mapping_valid = validate_custom_slot_mappings(
598
+ step, stack, tracker, available_actions
599
+ )
600
+ if not is_mapping_valid:
601
+ # if we return any other FlowStepResult, the assistant will stay silent
602
+ # instead of triggering the internal error pattern
603
+ return ContinueFlowWithNextStep(events=initial_events)
604
+
503
605
  structlogger.debug("flow.step.run.collect")
504
606
  trigger_pattern_ask_collect_information(
505
607
  step.collect, stack, step.rejections, step.utter, step.collect_action
@@ -3,7 +3,6 @@ import math
3
3
  from dataclasses import dataclass, field
4
4
  from typing import Any, Dict, List, Optional, Set, TYPE_CHECKING, Text, Tuple
5
5
 
6
- import rasa.shared.utils.io
7
6
  import structlog
8
7
  import tiktoken
9
8
  from jinja2 import Template
@@ -11,6 +10,7 @@ from langchain.docstore.document import Document
11
10
  from langchain.schema.embeddings import Embeddings
12
11
  from langchain.vectorstores import FAISS
13
12
 
13
+ import rasa.shared.utils.io
14
14
  from rasa import telemetry
15
15
  from rasa.core.constants import (
16
16
  CHAT_POLICY_PRIORITY,
@@ -56,7 +56,6 @@ from rasa.shared.utils.llm import (
56
56
  sanitize_message_for_prompt,
57
57
  tracker_as_readable_transcript,
58
58
  )
59
-
60
59
  from rasa.utils.ml_utils import (
61
60
  extract_ai_response_examples,
62
61
  extract_participant_messages_from_transcript,
@@ -65,7 +64,6 @@ from rasa.utils.ml_utils import (
65
64
  persist_faiss_vector_store,
66
65
  response_for_template,
67
66
  )
68
-
69
67
  from rasa.utils.log_utils import log_llm
70
68
 
71
69
  if TYPE_CHECKING:
@@ -543,7 +541,9 @@ class IntentlessPolicy(Policy):
543
541
  Returns:
544
542
  The prediction.
545
543
  """
546
- if not self.supports_current_stack_frame(tracker):
544
+ if not self.supports_current_stack_frame(
545
+ tracker
546
+ ) or self.should_abstain_in_coexistence(tracker, True):
547
547
  return self._prediction(self._default_predictions(domain))
548
548
 
549
549
  if tracker.has_bot_message_after_latest_user_message():
@@ -670,7 +670,7 @@ class IntentlessPolicy(Policy):
670
670
  if tracker.latest_message.text.startswith("/"):
671
671
  # we don't want to generate a response if the user is trying to
672
672
  # execute a "command" - this should be handled by the regex
673
- # intent classifier in rasa open source.
673
+ # intent classifier in rasa pro.
674
674
  structlogger.debug("intentless_policy.prediction.skip_slash")
675
675
  return None, 0.0
676
676
 
@@ -863,7 +863,7 @@ class IntentlessPolicy(Policy):
863
863
  """
864
864
  result = self._default_predictions(domain)
865
865
  if action_name:
866
- result[domain.index_for_action(action_name)] = score # type: ignore[assignment] # noqa: E501
866
+ result[domain.index_for_action(action_name)] = score # type: ignore[assignment]
867
867
  return result
868
868
 
869
869
  @classmethod
@@ -892,9 +892,7 @@ class IntentlessPolicy(Policy):
892
892
  # normalized. unfortunatley langchain doesn't persist / load
893
893
  # this parameter.
894
894
  if responses_docsearch:
895
- responses_docsearch._normalize_L2 = (
896
- True # pylint: disable=protected-access
897
- )
895
+ responses_docsearch._normalize_L2 = True # pylint: disable=protected-access
898
896
  prompt_template = rasa.shared.utils.io.read_file(
899
897
  path / INTENTLESS_PROMPT_TEMPLATE_FILE_NAME
900
898
  )