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
@@ -2,20 +2,27 @@ from typing import Dict, Text, Any, Optional, List
2
2
 
3
3
  import structlog
4
4
 
5
+
5
6
  from rasa.dialogue_understanding.commands import (
6
7
  Command,
7
8
  StartFlowCommand,
8
9
  SetSlotCommand,
9
10
  )
11
+ from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
10
12
  from rasa.dialogue_understanding.generator import CommandGenerator
11
13
  from rasa.engine.graph import GraphComponent, ExecutionContext
12
14
  from rasa.engine.recipes.default_recipe import DefaultV1Recipe
13
15
  from rasa.engine.storage.resource import Resource
14
16
  from rasa.engine.storage.storage import ModelStorage
15
17
  from rasa.shared.constants import ROUTE_TO_CALM_SLOT
18
+ from rasa.shared.core.domain import Domain
16
19
  from rasa.shared.core.flows.flows_list import FlowsList
20
+ from rasa.shared.core.slot_mappings import (
21
+ SlotFillingManager,
22
+ extract_slot_value,
23
+ )
17
24
  from rasa.shared.core.trackers import DialogueStateTracker
18
- from rasa.shared.nlu.constants import INTENT
25
+ from rasa.shared.nlu.constants import ENTITIES, INTENT
19
26
  from rasa.shared.nlu.training_data.message import Message
20
27
  from rasa.shared.nlu.training_data.training_data import TrainingData
21
28
 
@@ -76,6 +83,7 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
76
83
  message: Message,
77
84
  flows: FlowsList,
78
85
  tracker: Optional[DialogueStateTracker] = None,
86
+ **kwargs: Any,
79
87
  ) -> List[Command]:
80
88
  """Creates commands using the predicted intents.
81
89
 
@@ -83,6 +91,7 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
83
91
  message: The message from the user.
84
92
  flows: The flows available to the user.
85
93
  tracker: The tracker containing the current state of the conversation.
94
+ **kwargs: Keyword arguments for forward compatibility.
86
95
 
87
96
  Returns:
88
97
  The commands triggered by NLU.
@@ -91,9 +100,18 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
91
100
  # cannot do anything if there are no flows or no tracker
92
101
  return []
93
102
 
94
- commands = self.convert_nlu_to_commands(message, tracker, flows)
103
+ domain = kwargs.get("domain", None)
104
+ commands = self.convert_nlu_to_commands(message, tracker, flows, domain)
105
+
106
+ commands_contain_start_flow = any(
107
+ isinstance(command, StartFlowCommand) for command in commands
108
+ )
95
109
 
96
- if commands and len(commands) >= 1 and tracker.has_coexistence_routing_slot:
110
+ if (
111
+ commands
112
+ and commands_contain_start_flow
113
+ and tracker.has_coexistence_routing_slot
114
+ ):
97
115
  # if the nlu command adapter will start a flow and the coexistence feature
98
116
  # is used, make sure to set the routing slot
99
117
  commands += [SetSlotCommand(ROUTE_TO_CALM_SLOT, True)]
@@ -121,15 +139,22 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
121
139
 
122
140
  @staticmethod
123
141
  def convert_nlu_to_commands(
124
- message: Message, tracker: DialogueStateTracker, flows: FlowsList
142
+ message: Message,
143
+ tracker: DialogueStateTracker,
144
+ flows: FlowsList,
145
+ domain: Optional[Domain] = None,
125
146
  ) -> List[Command]:
126
147
  """Converts the predicted intent to a command."""
127
148
  if tracker is None or flows.is_empty():
128
149
  # cannot do anything if there are no flows or no tracker
129
150
  return []
130
151
 
131
- if not message.get(INTENT) or not message.get(INTENT)["name"]:
132
- # if the message does not have an intent set,
152
+ if not (
153
+ message.get(INTENT)
154
+ or message.get(INTENT, {}).get("name")
155
+ or message.get(ENTITIES)
156
+ ):
157
+ # if the message does not have an intent or entities set
133
158
  # no commands can be predicted
134
159
  return []
135
160
 
@@ -139,8 +164,6 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
139
164
  if flow.nlu_triggers and flow.nlu_triggers.is_triggered(message):
140
165
  commands.append(StartFlowCommand(flow.id))
141
166
 
142
- structlogger.info("nlu_command_adapter.predict_commands", commands=commands)
143
-
144
167
  # there should be just one flow that can be triggered by the predicted intent
145
168
  # this is checked when loading the flows
146
169
  # however we just doublecheck here and return the first command if there are
@@ -154,4 +177,42 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
154
177
  )
155
178
  commands = [commands[0]]
156
179
 
180
+ set_slot_commands = _issue_set_slot_commands(message, tracker, flows, domain)
181
+ commands.extend(set_slot_commands)
182
+
183
+ structlogger.info("nlu_command_adapter.predict_commands", commands=commands)
184
+
157
185
  return commands
186
+
187
+
188
+ def _issue_set_slot_commands(
189
+ message: Message,
190
+ tracker: DialogueStateTracker,
191
+ flows: FlowsList,
192
+ domain: Optional[Domain] = None,
193
+ ) -> List[Command]:
194
+ """Issue SetSlotCommand for each slot that can be filled with NLU properties."""
195
+ commands: List[Command] = []
196
+ domain = domain if domain else Domain.empty()
197
+ slot_filling_manager = SlotFillingManager(domain, tracker, message)
198
+ available_slot_names = flows.available_slot_names()
199
+
200
+ for _, slot in tracker.slots.items():
201
+ # if a slot is not collected in available flows,
202
+ # it means that it is not a slot that can be filled by CALM,
203
+ # so we skip it
204
+ if slot.name not in available_slot_names:
205
+ structlogger.debug("nlu_command_adapter.skip_slot", slot=slot.name)
206
+ continue
207
+
208
+ slot_value, is_extracted = extract_slot_value(slot, slot_filling_manager)
209
+ if is_extracted:
210
+ commands.append(
211
+ SetSlotCommand(
212
+ name=slot.name,
213
+ value=slot_value,
214
+ extractor=SetSlotExtractor.NLU.value,
215
+ )
216
+ )
217
+
218
+ return commands
@@ -0,0 +1,345 @@
1
+ import importlib.resources
2
+ import re
3
+ import structlog
4
+ from typing import Dict, Any, List, Optional, Text
5
+
6
+ import rasa.shared.utils.io
7
+ from rasa.dialogue_understanding.commands import (
8
+ Command,
9
+ ErrorCommand,
10
+ SetSlotCommand,
11
+ CancelFlowCommand,
12
+ HumanHandoffCommand,
13
+ ChitChatAnswerCommand,
14
+ SkipQuestionCommand,
15
+ KnowledgeAnswerCommand,
16
+ ClarifyCommand,
17
+ CannotHandleCommand,
18
+ )
19
+ from rasa.dialogue_understanding.generator.llm_based_command_generator import (
20
+ LLMBasedCommandGenerator,
21
+ )
22
+ from rasa.dialogue_understanding.generator.constants import (
23
+ LLM_CONFIG_KEY,
24
+ USER_INPUT_CONFIG_KEY,
25
+ FLOW_RETRIEVAL_KEY,
26
+ )
27
+ from rasa.dialogue_understanding.generator.flow_retrieval import (
28
+ FlowRetrieval,
29
+ )
30
+ from rasa.dialogue_understanding.stack.utils import top_flow_frame
31
+ from rasa.engine.graph import ExecutionContext
32
+ from rasa.engine.recipes.default_recipe import DefaultV1Recipe
33
+ from rasa.engine.storage.resource import Resource
34
+ from rasa.engine.storage.storage import ModelStorage
35
+ from rasa.shared.constants import ROUTE_TO_CALM_SLOT
36
+ from rasa.shared.core.flows import FlowsList
37
+ from rasa.shared.core.trackers import DialogueStateTracker
38
+ from rasa.shared.nlu.constants import TEXT
39
+ from rasa.shared.nlu.training_data.message import Message
40
+ from rasa.shared.exceptions import ProviderClientAPIException
41
+ from rasa.shared.utils.io import deep_container_fingerprint
42
+ from rasa.shared.utils.llm import (
43
+ get_prompt_template,
44
+ tracker_as_readable_transcript,
45
+ sanitize_message_for_prompt,
46
+ )
47
+ from rasa.utils.log_utils import log_llm
48
+
49
+ COMMAND_PROMPT_FILE_NAME = "command_prompt.jinja2"
50
+
51
+ DEFAULT_COMMAND_PROMPT_TEMPLATE = importlib.resources.read_text(
52
+ "rasa.dialogue_understanding.generator.single_step",
53
+ "command_prompt_template.jinja2",
54
+ )
55
+
56
+ structlogger = structlog.get_logger()
57
+
58
+
59
+ @DefaultV1Recipe.register(
60
+ [
61
+ DefaultV1Recipe.ComponentType.COMMAND_GENERATOR,
62
+ ],
63
+ is_trainable=True,
64
+ )
65
+ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
66
+ """A single step LLM-based command generator."""
67
+
68
+ def __init__(
69
+ self,
70
+ config: Dict[str, Any],
71
+ model_storage: ModelStorage,
72
+ resource: Resource,
73
+ prompt_template: Optional[Text] = None,
74
+ **kwargs: Any,
75
+ ) -> None:
76
+ super().__init__(
77
+ config,
78
+ model_storage,
79
+ resource,
80
+ prompt_template=prompt_template,
81
+ **kwargs,
82
+ )
83
+
84
+ # Set the prompt template
85
+ if config.get("prompt"):
86
+ structlogger.warning(
87
+ "single_step_llm_command_generator.init",
88
+ event_info=(
89
+ "The config parameter 'prompt' is deprecated "
90
+ "and will be removed in Rasa 4.0.0. "
91
+ "Please use the config parameter 'prompt_template' instead. "
92
+ ),
93
+ )
94
+ config_prompt = config.get("prompt") or config.get("prompt_template") or None
95
+ self.prompt_template = prompt_template or get_prompt_template(
96
+ config_prompt,
97
+ DEFAULT_COMMAND_PROMPT_TEMPLATE,
98
+ )
99
+
100
+ self.trace_prompt_tokens = self.config.get("trace_prompt_tokens", False)
101
+
102
+ ### Implementations of LLMBasedCommandGenerator parent
103
+ @staticmethod
104
+ def get_default_config() -> Dict[str, Any]:
105
+ """The component's default config (see parent class for full docstring)."""
106
+ return {
107
+ "prompt": None, # Legacy
108
+ "prompt_template": None,
109
+ USER_INPUT_CONFIG_KEY: None,
110
+ LLM_CONFIG_KEY: None,
111
+ FLOW_RETRIEVAL_KEY: FlowRetrieval.get_default_config(),
112
+ }
113
+
114
+ @classmethod
115
+ def load(
116
+ cls: Any,
117
+ config: Dict[str, Any],
118
+ model_storage: ModelStorage,
119
+ resource: Resource,
120
+ execution_context: ExecutionContext,
121
+ **kwargs: Any,
122
+ ) -> "SingleStepLLMCommandGenerator":
123
+ """Loads trained component (see parent class for full docstring)."""
124
+ # load prompt template from the model storage.
125
+ prompt_template = cls.load_prompt_template_from_model_storage(
126
+ model_storage, resource, COMMAND_PROMPT_FILE_NAME
127
+ )
128
+ # init base command generator
129
+ command_generator = cls(config, model_storage, resource, prompt_template)
130
+ # load flow retrieval if enabled
131
+ if command_generator.enabled_flow_retrieval:
132
+ command_generator.flow_retrieval = cls.load_flow_retrival(
133
+ command_generator.config, model_storage, resource
134
+ )
135
+ return command_generator
136
+
137
+ def persist(self) -> None:
138
+ """Persist this component to disk for future loading."""
139
+ # persist prompt template
140
+ with self._model_storage.write_to(self._resource) as path:
141
+ rasa.shared.utils.io.write_text_file(
142
+ self.prompt_template, path / COMMAND_PROMPT_FILE_NAME
143
+ )
144
+ # persist flow retrieval
145
+ if self.flow_retrieval is not None:
146
+ self.flow_retrieval.persist()
147
+
148
+ async def predict_commands(
149
+ self,
150
+ message: Message,
151
+ flows: FlowsList,
152
+ tracker: Optional[DialogueStateTracker] = None,
153
+ **kwargs: Any,
154
+ ) -> List[Command]:
155
+ """Predict commands using the LLM.
156
+
157
+ Args:
158
+ message: The message from the user.
159
+ flows: The flows available to the user.
160
+ tracker: The tracker containing the current state of the conversation.
161
+ **kwargs: Keyword arguments for forward compatibility.
162
+
163
+ Returns:
164
+ The commands generated by the llm.
165
+ """
166
+ if tracker is None or flows.is_empty():
167
+ # cannot do anything if there are no flows or no tracker
168
+ return []
169
+
170
+ # retrieve flows
171
+ try:
172
+ filtered_flows = await self.filter_flows(message, flows, tracker)
173
+ except ProviderClientAPIException:
174
+ return [ErrorCommand()]
175
+
176
+ flow_prompt = self.render_template(message, tracker, filtered_flows, flows)
177
+ log_llm(
178
+ logger=structlogger,
179
+ log_module="SingleStepLLMCommandGenerator",
180
+ log_event="llm_command_generator.predict_commands.prompt_rendered",
181
+ prompt=flow_prompt,
182
+ )
183
+
184
+ try:
185
+ action_list = await self.invoke_llm(flow_prompt)
186
+ # The check for 'None' maintains compatibility with older versions
187
+ # of LLMCommandGenerator. In previous implementations, 'invoke_llm'
188
+ # might return 'None' to indicate a failure to generate actions.
189
+ if action_list is None:
190
+ return [ErrorCommand()]
191
+ except ProviderClientAPIException:
192
+ return [ErrorCommand()]
193
+
194
+ log_llm(
195
+ logger=structlogger,
196
+ log_module="SingleStepLLMCommandGenerator",
197
+ log_event="llm_command_generator.predict_commands.actions_generated",
198
+ action_list=action_list,
199
+ )
200
+
201
+ commands = self.parse_commands(action_list, tracker, flows)
202
+
203
+ if not commands:
204
+ # no commands are parsed or there's an invalid command
205
+ commands = [CannotHandleCommand()]
206
+ else:
207
+ # if the LLM command generator predicted valid commands and the
208
+ # coexistence feature is used, set the routing slot
209
+ if tracker.has_coexistence_routing_slot:
210
+ commands += [SetSlotCommand(ROUTE_TO_CALM_SLOT, True)]
211
+
212
+ log_llm(
213
+ logger=structlogger,
214
+ log_module="SingleStepLLMCommandGenerator",
215
+ log_event="llm_command_generator.predict_commands.finished",
216
+ commands=commands,
217
+ )
218
+ return commands
219
+
220
+ @classmethod
221
+ def parse_commands(
222
+ cls, actions: Optional[str], tracker: DialogueStateTracker, flows: FlowsList
223
+ ) -> List[Command]:
224
+ """Parse the actions returned by the llm into intent and entities.
225
+
226
+ Args:
227
+ actions: The actions returned by the llm.
228
+ tracker: The tracker containing the current state of the conversation.
229
+ flows: the list of flows
230
+
231
+ Returns:
232
+ The parsed commands.
233
+ """
234
+ if actions is None:
235
+ return []
236
+
237
+ commands: List[Command] = []
238
+
239
+ slot_set_re = re.compile(r"""SetSlot\(([a-zA-Z_][a-zA-Z0-9_-]*?), ?(.*)\)""")
240
+ start_flow_re = re.compile(r"StartFlow\(([a-zA-Z0-9_-]+?)\)")
241
+ cancel_flow_re = re.compile(r"CancelFlow\(\)")
242
+ chitchat_re = re.compile(r"ChitChat\(\)")
243
+ skip_question_re = re.compile(r"SkipQuestion\(\)")
244
+ knowledge_re = re.compile(r"SearchAndReply\(\)")
245
+ humand_handoff_re = re.compile(r"HumanHandoff\(\)")
246
+ clarify_re = re.compile(r"Clarify\(([a-zA-Z0-9_, ]+)\)")
247
+
248
+ for action in actions.strip().splitlines():
249
+ if match := slot_set_re.search(action):
250
+ slot_name = match.group(1).strip()
251
+ slot_value = cls.clean_extracted_value(match.group(2))
252
+ # error case where the llm tries to start a flow using a slot set
253
+ if slot_name == "flow_name":
254
+ commands.extend(cls.start_flow_by_name(slot_value, flows))
255
+ else:
256
+ typed_slot_value = cls.get_nullable_slot_value(slot_value)
257
+ commands.append(
258
+ SetSlotCommand(name=slot_name, value=typed_slot_value)
259
+ )
260
+ elif match := start_flow_re.search(action):
261
+ flow_name = match.group(1).strip()
262
+ commands.extend(cls.start_flow_by_name(flow_name, flows))
263
+ elif cancel_flow_re.search(action):
264
+ commands.append(CancelFlowCommand())
265
+ elif chitchat_re.search(action):
266
+ commands.append(ChitChatAnswerCommand())
267
+ elif skip_question_re.search(action):
268
+ commands.append(SkipQuestionCommand())
269
+ elif knowledge_re.search(action):
270
+ commands.append(KnowledgeAnswerCommand())
271
+ elif humand_handoff_re.search(action):
272
+ commands.append(HumanHandoffCommand())
273
+ elif match := clarify_re.search(action):
274
+ options = sorted([opt.strip() for opt in match.group(1).split(",")])
275
+ valid_options = [
276
+ flow for flow in options if flow in flows.user_flow_ids
277
+ ]
278
+ if len(set(valid_options)) == 1:
279
+ commands.extend(cls.start_flow_by_name(valid_options[0], flows))
280
+ elif len(valid_options) > 1:
281
+ commands.append(ClarifyCommand(valid_options))
282
+
283
+ return commands
284
+
285
+ @classmethod
286
+ def fingerprint_addon(cls: Any, config: Dict[str, Any]) -> Optional[str]:
287
+ """Add a fingerprint of the knowledge base for the graph."""
288
+ config_prompt = config.get("prompt") or config.get("prompt_template") or None
289
+ prompt_template = get_prompt_template(
290
+ config_prompt,
291
+ DEFAULT_COMMAND_PROMPT_TEMPLATE,
292
+ )
293
+ return deep_container_fingerprint(prompt_template)
294
+
295
+ ### Helper methods
296
+ def render_template(
297
+ self,
298
+ message: Message,
299
+ tracker: DialogueStateTracker,
300
+ startable_flows: FlowsList,
301
+ all_flows: FlowsList,
302
+ ) -> str:
303
+ """Render the jinja template to create the prompt for the LLM.
304
+
305
+ Args:
306
+ message: The current message from the user.
307
+ tracker: The tracker containing the current state of the conversation.
308
+ startable_flows: The flows startable at this point in time by the user.
309
+ all_flows: all flows present in the assistant
310
+
311
+ Returns:
312
+ The rendered prompt template.
313
+ """
314
+ # need to make this distinction here because current step of the
315
+ # top_calling_frame would be the call step, but we need the collect step from
316
+ # the called frame. If no call is active calling and called frame are the same.
317
+ top_calling_frame = top_flow_frame(tracker.stack)
318
+ top_called_frame = top_flow_frame(tracker.stack, ignore_call_frames=False)
319
+
320
+ top_flow = top_calling_frame.flow(all_flows) if top_calling_frame else None
321
+ current_step = top_called_frame.step(all_flows) if top_called_frame else None
322
+
323
+ flow_slots = self.prepare_current_flow_slots_for_template(
324
+ top_flow, current_step, tracker
325
+ )
326
+ current_slot, current_slot_description = self.prepare_current_slot_for_template(
327
+ current_step
328
+ )
329
+ current_conversation = tracker_as_readable_transcript(tracker)
330
+ latest_user_message = sanitize_message_for_prompt(message.get(TEXT))
331
+ current_conversation += f"\nUSER: {latest_user_message}"
332
+
333
+ inputs = {
334
+ "available_flows": self.prepare_flows_for_template(
335
+ startable_flows, tracker
336
+ ),
337
+ "current_conversation": current_conversation,
338
+ "flow_slots": flow_slots,
339
+ "current_flow": top_flow.id if top_flow is not None else None,
340
+ "current_slot": current_slot,
341
+ "current_slot_description": current_slot_description,
342
+ "user_message": latest_user_message,
343
+ }
344
+
345
+ return self.compile_template(self.prompt_template).render(**inputs)
@@ -11,7 +11,7 @@ responses:
11
11
  template: jinja
12
12
 
13
13
  utter_can_do_something_else:
14
- - text: "What else I can help you with?"
14
+ - text: "What else can I help you with?"
15
15
  metadata:
16
16
  rephrase: True
17
17
 
@@ -100,11 +100,11 @@ slots:
100
100
  confirm_correction:
101
101
  type: bool
102
102
  mappings:
103
- - type: custom
103
+ - type: from_llm
104
104
 
105
105
  flows:
106
106
  pattern_cancel_flow:
107
- description: A meta flow that's started when a flow is cancelled.
107
+ description: Conversation repair flow that starts when a flow is cancelled
108
108
  name: pattern_cancel_flow
109
109
  steps:
110
110
  - action: action_cancel_flow
@@ -112,72 +112,77 @@ flows:
112
112
 
113
113
  pattern_cannot_handle:
114
114
  description: |
115
- pattern that is triggered when the command generators fail to create (any) valid commands
115
+ Conversation repair flow for addressing failed command generation scenarios
116
116
  name: pattern cannot handle
117
117
  steps:
118
118
  - noop: true
119
119
  next:
120
120
  # chitchat fallback
121
- - if: "'{{context.reason}}' == 'cannot_handle_chitchat'"
121
+ - if: "'{{context.reason}}' = 'cannot_handle_chitchat'"
122
122
  then:
123
123
  - action: utter_cannot_handle
124
124
  next: "END"
125
+ # fallback for things that are not supported
126
+ - if: "'{{context.reason}}' = 'cannot_handle_not_supported'"
127
+ then:
128
+ - action: utter_cannot_handle
129
+ next: END
125
130
  # default
126
131
  - else:
127
132
  - action: utter_ask_rephrase
128
- next: "END"
133
+ next: END
129
134
 
130
135
  pattern_chitchat:
131
- description: handle interactions with the user that are not task-oriented
136
+ description: Conversation repair flow for off-topic interactions that won't disrupt the main conversation
132
137
  name: pattern chitchat
133
138
  steps:
134
139
  - action: action_trigger_chitchat
135
140
 
136
141
  pattern_clarification:
137
- description: handle clarifications with the user
142
+ description: Conversation repair flow for handling ambiguous requests that could match multiple flows
138
143
  name: pattern clarification
139
144
  steps:
140
145
  - action: action_clarify_flows
141
146
  - action: utter_clarification_options_rasa
142
147
 
143
148
  pattern_code_change:
144
- description: flow used to clean the stack after a bot update
149
+ description: Conversation repair flow for cleaning the stack after an assistant update
145
150
  name: pattern code change
146
151
  steps:
147
152
  - action: utter_inform_code_change
148
153
  - action: action_clean_stack
149
154
 
150
155
  pattern_collect_information:
151
- description: flow used to fill a slot
156
+ description: Flow for collecting information from users
152
157
  name: pattern collect information
153
158
  steps:
154
- - id: "start"
159
+ - id: start
155
160
  action: action_run_slot_rejections
156
161
  - action: validate_{{context.collect}}
157
162
  next:
158
163
  - if: "slots.{{context.collect}} is not null"
159
- then: "END"
160
- - else: "ask_collect"
161
- - id: "ask_collect"
164
+ then: END
165
+ - else: ask_collect
166
+ - id: ask_collect
162
167
  action: "{{context.utter}}"
163
168
  - action: "{{context.collect_action}}"
164
169
  - action: action_listen
165
- next: "start"
170
+ next: start
166
171
 
167
172
  pattern_completed:
168
- description: a flow has been completed and there is nothing else to be done
173
+ description: Flow that asks if the user needs more help after completing their initiated use cases
169
174
  name: pattern completed
170
175
  steps:
171
176
  - action: utter_can_do_something_else
172
177
 
173
178
  pattern_continue_interrupted:
174
- description: A flow that should will be started to continue an interrupted flow.
179
+ description: Conversation repair flow for managing when users switch between different flows
175
180
  name: pattern continue interrupted
176
181
  steps:
177
182
  - action: utter_flow_continue_interrupted
178
183
 
179
184
  pattern_correction:
180
- description: Handle a correction of a slot value.
185
+ description: Conversation repair flow for managing user input changes or error corrections
181
186
  name: pattern correction
182
187
  steps:
183
188
  - action: action_correct_flow_slot
@@ -185,36 +190,36 @@ flows:
185
190
  - if: not context.is_reset_only
186
191
  then:
187
192
  - action: utter_corrected_previous_input
188
- next: "END"
189
- - else: "END"
193
+ next: END
194
+ - else: END
190
195
 
191
196
  pattern_human_handoff:
192
- description: human handoff
197
+ description: Conversation repair flow for switching users to a human agent if their request can't be handled
193
198
  name: pattern human handoff
194
199
  steps:
195
200
  - action: utter_human_handoff_not_available
196
201
 
197
202
  pattern_internal_error:
198
- description: internal error
203
+ description: Conversation repair flow for informing users about internal errors
199
204
  name: pattern internal error
200
205
  steps:
201
206
  - noop: true
202
207
  next:
203
- - if: "'{{context.error_type}}' == 'rasa_internal_error_user_input_too_long'"
208
+ - if: "'{{context.error_type}}' = 'rasa_internal_error_user_input_too_long'"
204
209
  then:
205
210
  - action: utter_user_input_too_long_error_rasa
206
- next: "END"
207
- - if: "'{{context.error_type}}' == 'rasa_internal_error_user_input_empty'"
211
+ next: END
212
+ - if: "'{{context.error_type}}' = 'rasa_internal_error_user_input_empty'"
208
213
  then:
209
214
  - action: utter_user_input_empty_error_rasa
210
- next: "END"
215
+ next: END
211
216
  - else:
212
217
  - action: utter_internal_error_rasa
213
- next: "END"
218
+ next: END
214
219
 
215
220
 
216
221
  pattern_restart:
217
- description: flow used to restart the conversation
222
+ description: Flow for restarting the conversation
218
223
  name: pattern restart
219
224
  nlu_trigger:
220
225
  - intent: restart
@@ -222,14 +227,14 @@ flows:
222
227
  - action: action_restart
223
228
 
224
229
  pattern_search:
225
- description: handle a knowledge-based question or request
230
+ description: Flow for handling knowledge-based questions
226
231
  name: pattern search
227
232
  steps:
228
233
  - action: utter_no_knowledge_base
229
234
  # - action: action_trigger_search to use doc search policy if present
230
235
 
231
236
  pattern_session_start:
232
- description: flow used to start the conversation
237
+ description: Flow for starting the conversation
233
238
  name: pattern session start
234
239
  nlu_trigger:
235
240
  - intent: session_start
@@ -237,7 +242,7 @@ flows:
237
242
  - action: action_session_start
238
243
 
239
244
  pattern_skip_question:
240
- description: flow used to handle users intent to skip questions (steps)
245
+ description: Conversation repair flow for managing user intents to skip questions (steps)
241
246
  name: pattern skip question
242
247
  steps:
243
248
  - action: utter_skip_question_answer