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
@@ -75,3 +75,12 @@ class ClarifyCommand(Command):
75
75
  names = [flow.readable_name() for flow in relevant_flows if flow is not None]
76
76
  stack.push(ClarifyPatternFlowStackFrame(names=names))
77
77
  return tracker.create_stack_updated_events(stack)
78
+
79
+ def __hash__(self) -> int:
80
+ return hash(tuple(self.options))
81
+
82
+ def __eq__(self, other: object) -> bool:
83
+ if not isinstance(other, ClarifyCommand):
84
+ return False
85
+
86
+ return other.options == self.options
@@ -286,3 +286,12 @@ class CorrectSlotsCommand(Command):
286
286
 
287
287
  stack.push(correction_frame, index=insertion_index)
288
288
  return tracker.create_stack_updated_events(stack)
289
+
290
+ def __hash__(self) -> int:
291
+ return hash(self.command())
292
+
293
+ def __eq__(self, other: object) -> bool:
294
+ if not isinstance(other, CorrectSlotsCommand):
295
+ return False
296
+
297
+ return True
@@ -65,3 +65,15 @@ class ErrorCommand(Command):
65
65
  )
66
66
  )
67
67
  return tracker.create_stack_updated_events(stack)
68
+
69
+ def __hash__(self) -> int:
70
+ hashed = hash(self.error_type)
71
+ if self.info:
72
+ hashed += hash(str(self.info))
73
+ return hashed
74
+
75
+ def __eq__(self, other: object) -> bool:
76
+ if not isinstance(other, ErrorCommand):
77
+ return False
78
+
79
+ return other.error_type == self.error_type and other.info == self.info
@@ -62,3 +62,12 @@ class HandleCodeChangeCommand(Command):
62
62
 
63
63
  stack.push(CodeChangeFlowStackFrame())
64
64
  return tracker.create_stack_updated_events(stack)
65
+
66
+ def __hash__(self) -> int:
67
+ return hash(self.command())
68
+
69
+ def __eq__(self, other: object) -> bool:
70
+ if not isinstance(other, HandleCodeChangeCommand):
71
+ return False
72
+
73
+ return True
@@ -55,3 +55,12 @@ class HumanHandoffCommand(Command):
55
55
  "command_executor.human_handoff.pushed_to_stack", command=self
56
56
  )
57
57
  return tracker.create_stack_updated_events(stack)
58
+
59
+ def __hash__(self) -> int:
60
+ return hash(self.command())
61
+
62
+ def __eq__(self, other: object) -> bool:
63
+ if not isinstance(other, HumanHandoffCommand):
64
+ return False
65
+
66
+ return True
@@ -46,3 +46,12 @@ class KnowledgeAnswerCommand(FreeFormAnswerCommand):
46
46
  stack = tracker.stack
47
47
  stack.push(SearchPatternFlowStackFrame())
48
48
  return tracker.create_stack_updated_events(stack)
49
+
50
+ def __hash__(self) -> int:
51
+ return hash(self.command())
52
+
53
+ def __eq__(self, other: object) -> bool:
54
+ if not isinstance(other, KnowledgeAnswerCommand):
55
+ return False
56
+
57
+ return True
@@ -43,3 +43,12 @@ class NoopCommand(Command):
43
43
  The events to apply to the tracker.
44
44
  """
45
45
  return []
46
+
47
+ def __hash__(self) -> int:
48
+ return hash(self.command())
49
+
50
+ def __eq__(self, other: object) -> bool:
51
+ if not isinstance(other, NoopCommand):
52
+ return False
53
+
54
+ return True
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
+ from enum import Enum
4
5
  from typing import Any, Dict, List
5
6
 
6
7
  import structlog
@@ -15,10 +16,22 @@ from rasa.shared.constants import ROUTE_TO_CALM_SLOT
15
16
  from rasa.shared.core.events import Event, SlotSet
16
17
  from rasa.shared.core.flows import FlowsList
17
18
  from rasa.shared.core.trackers import DialogueStateTracker
19
+ from rasa.shared.nlu.constants import SET_SLOT_COMMAND
18
20
 
19
21
  structlogger = structlog.get_logger()
20
22
 
21
23
 
24
+ class SetSlotExtractor(Enum):
25
+ """The extractors that can set a slot."""
26
+
27
+ LLM = "LLM"
28
+ COMMAND_PAYLOAD_READER = "CommandPayloadReader"
29
+ NLU = "NLU"
30
+
31
+ def __str__(self) -> str:
32
+ return self.value
33
+
34
+
22
35
  def get_flows_predicted_to_start_from_tracker(
23
36
  tracker: DialogueStateTracker,
24
37
  ) -> List[str]:
@@ -45,11 +58,12 @@ class SetSlotCommand(Command):
45
58
 
46
59
  name: str
47
60
  value: Any
61
+ extractor: str = SetSlotExtractor.LLM.value
48
62
 
49
63
  @classmethod
50
64
  def command(cls) -> str:
51
65
  """Returns the command type."""
52
- return "set slot"
66
+ return SET_SLOT_COMMAND
53
67
 
54
68
  @classmethod
55
69
  def from_dict(cls, data: Dict[str, Any]) -> SetSlotCommand:
@@ -59,7 +73,11 @@ class SetSlotCommand(Command):
59
73
  The converted dictionary.
60
74
  """
61
75
  try:
62
- return SetSlotCommand(name=data["name"], value=data["value"])
76
+ return SetSlotCommand(
77
+ name=data["name"],
78
+ value=data["value"],
79
+ extractor=data.get("extractor", SetSlotExtractor.LLM.value),
80
+ )
63
81
  except KeyError as e:
64
82
  raise ValueError(f"Missing key when parsing SetSlotCommand: {e}") from e
65
83
 
@@ -106,7 +124,11 @@ class SetSlotCommand(Command):
106
124
  if isinstance(top_frame, CollectInformationPatternFlowStackFrame):
107
125
  slots_of_active_flow.add(top_frame.collect)
108
126
 
109
- if self.name not in slots_of_active_flow and self.name != ROUTE_TO_CALM_SLOT:
127
+ if (
128
+ self.name not in slots_of_active_flow
129
+ and self.name != ROUTE_TO_CALM_SLOT
130
+ and self.extractor == SetSlotExtractor.LLM.value
131
+ ):
110
132
  # Get the other predicted flows from the most recent message on the tracker.
111
133
  predicted_flows = get_flows_predicted_to_start_from_tracker(tracker)
112
134
  use_slot_fill = any(
@@ -123,3 +145,12 @@ class SetSlotCommand(Command):
123
145
 
124
146
  structlogger.debug("command_executor.set_slot", command=self)
125
147
  return [SlotSet(self.name, slot.coerce_value(self.value))]
148
+
149
+ def __hash__(self) -> int:
150
+ return hash(self.value) + hash(self.name)
151
+
152
+ def __eq__(self, other: object) -> bool:
153
+ if not isinstance(other, SetSlotCommand):
154
+ return False
155
+
156
+ return other.value == self.value and other.name == self.name
@@ -64,3 +64,12 @@ class SkipQuestionCommand(Command):
64
64
 
65
65
  stack.push(SkipQuestionPatternFlowStackFrame())
66
66
  return tracker.create_stack_updated_events(stack)
67
+
68
+ def __hash__(self) -> int:
69
+ return hash(self.command())
70
+
71
+ def __eq__(self, other: object) -> bool:
72
+ if not isinstance(other, SkipQuestionCommand):
73
+ return False
74
+
75
+ return True
@@ -96,3 +96,12 @@ class StartFlowCommand(Command):
96
96
  structlogger.debug("command_executor.start_flow", command=self)
97
97
  stack.push(UserFlowStackFrame(flow_id=self.flow, frame_type=frame_type))
98
98
  return applied_events + tracker.create_stack_updated_events(stack)
99
+
100
+ def __hash__(self) -> int:
101
+ return hash(self.flow)
102
+
103
+ def __eq__(self, other: object) -> bool:
104
+ if not isinstance(other, StartFlowCommand):
105
+ return False
106
+
107
+ return other.flow == self.flow
@@ -1,6 +1,21 @@
1
1
  from rasa.dialogue_understanding.generator.command_generator import CommandGenerator
2
+ from rasa.dialogue_understanding.generator.llm_based_command_generator import (
3
+ LLMBasedCommandGenerator,
4
+ )
2
5
  from rasa.dialogue_understanding.generator.llm_command_generator import (
3
6
  LLMCommandGenerator,
4
7
  )
8
+ from rasa.dialogue_understanding.generator.multi_step.multi_step_llm_command_generator import ( # noqa: E501
9
+ MultiStepLLMCommandGenerator,
10
+ )
11
+ from rasa.dialogue_understanding.generator.single_step.single_step_llm_command_generator import ( # noqa: E501
12
+ SingleStepLLMCommandGenerator,
13
+ )
5
14
 
6
- __all__ = ["CommandGenerator", "LLMCommandGenerator"]
15
+ __all__ = [
16
+ "CommandGenerator",
17
+ "LLMBasedCommandGenerator",
18
+ "LLMCommandGenerator",
19
+ "MultiStepLLMCommandGenerator",
20
+ "SingleStepLLMCommandGenerator",
21
+ ]
@@ -3,8 +3,17 @@ from typing import Any, Dict, List, Optional, Text
3
3
 
4
4
  import structlog
5
5
 
6
- from rasa.dialogue_understanding.commands import Command, StartFlowCommand, ErrorCommand
6
+ from rasa.dialogue_understanding.commands import (
7
+ Command,
8
+ SetSlotCommand,
9
+ StartFlowCommand,
10
+ ErrorCommand,
11
+ )
12
+ from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
13
+ from rasa.shared.core.constants import SlotMappingType
14
+ from rasa.shared.core.domain import Domain
7
15
  from rasa.shared.core.flows import FlowsList
16
+ from rasa.shared.core.slot_mappings import SlotFillingManager
8
17
  from rasa.shared.core.trackers import DialogueStateTracker
9
18
  from rasa.shared.nlu.training_data.message import Message
10
19
  from rasa.shared.nlu.constants import COMMANDS, TEXT
@@ -53,6 +62,7 @@ class CommandGenerator:
53
62
  messages: List[Message],
54
63
  flows: FlowsList,
55
64
  tracker: Optional[DialogueStateTracker] = None,
65
+ domain: Optional[Domain] = None,
56
66
  ) -> List[Message]:
57
67
  """Process a list of messages. For each message predict commands.
58
68
 
@@ -63,6 +73,7 @@ class CommandGenerator:
63
73
  messages: The messages to process.
64
74
  tracker: The tracker containing the conversation history up to now.
65
75
  flows: The flows to use for command prediction.
76
+ domain: The domain.
66
77
 
67
78
  Returns:
68
79
  The processed messages (usually this is just one during prediction).
@@ -78,14 +89,13 @@ class CommandGenerator:
78
89
  )
79
90
 
80
91
  for message in messages:
81
-
82
92
  if message.get(COMMANDS):
83
93
  # do not overwrite commands if they are already present
84
94
  # i.e. another command generator already predicted commands
85
95
  continue
86
96
 
87
97
  commands = await self._evaluate_and_predict(
88
- message, available_flows, tracker
98
+ message, available_flows, tracker, domain
89
99
  )
90
100
  # Double check commands for guarded flows. Unlikely but the llm could
91
101
  # have predicted a command for a flow that is not in the startable
@@ -93,6 +103,9 @@ class CommandGenerator:
93
103
  commands = self._check_commands_against_startable_flows(
94
104
  commands, startable_flows
95
105
  )
106
+ commands = self._check_commands_against_slot_mappings(
107
+ commands, tracker, domain
108
+ )
96
109
  commands_dicts = [command.as_dict() for command in commands]
97
110
  message.set(COMMANDS, commands_dicts, add_to_output=True)
98
111
 
@@ -139,6 +152,7 @@ class CommandGenerator:
139
152
  message: Message,
140
153
  startable_flows: FlowsList,
141
154
  tracker: Optional[DialogueStateTracker] = None,
155
+ domain: Optional[Domain] = None,
142
156
  ) -> List[Command]:
143
157
  """Evaluates message for errors and predicts commands if no errors are found.
144
158
 
@@ -156,7 +170,9 @@ class CommandGenerator:
156
170
 
157
171
  # if no errors, try predicting commands
158
172
  try:
159
- return await self.predict_commands(message, startable_flows, tracker)
173
+ return await self.predict_commands(
174
+ message, startable_flows, tracker, domain=domain
175
+ )
160
176
  except NotImplementedError:
161
177
  raise
162
178
  except Exception as e:
@@ -168,6 +184,7 @@ class CommandGenerator:
168
184
  message: Message,
169
185
  flows: FlowsList,
170
186
  tracker: Optional[DialogueStateTracker] = None,
187
+ **kwargs: Any,
171
188
  ) -> List[Command]:
172
189
  """Predict commands for a single message.
173
190
 
@@ -175,7 +192,7 @@ class CommandGenerator:
175
192
  message: The message to predict commands for.
176
193
  flows: The flows to use for command prediction.
177
194
  tracker: The tracker containing the conversation history up to now.
178
-
195
+ **kwargs: Keyword arguments for forward compatibility.
179
196
  Returns:
180
197
  The predicted commands.
181
198
  """
@@ -188,7 +205,7 @@ class CommandGenerator:
188
205
 
189
206
  Args:
190
207
  commands: The commands to check.
191
- startable_flows: The flows which have their starting conditions statisfied.
208
+ startable_flows: The flows which have their starting conditions satisfied.
192
209
 
193
210
  Returns:
194
211
  The commands that are startable.
@@ -255,3 +272,72 @@ class CommandGenerator:
255
272
  def check_if_message_is_empty(self, message: Message) -> bool:
256
273
  """Checks if the given message is empty or whitespace-only."""
257
274
  return len(message.get(TEXT, "").strip()) == 0
275
+
276
+ @staticmethod
277
+ def _check_commands_against_slot_mappings(
278
+ commands: List[Command],
279
+ tracker: DialogueStateTracker,
280
+ domain: Optional[Domain] = None,
281
+ ) -> List[Command]:
282
+ """Check if the LLM-issued slot commands are fillable.
283
+
284
+ The LLM-issued slot commands are fillable if the slot
285
+ mappings are satisfied.
286
+ """
287
+ if not domain:
288
+ return commands
289
+
290
+ llm_fillable_slot_names = [
291
+ command.name
292
+ for command in commands
293
+ if isinstance(command, SetSlotCommand)
294
+ and command.extractor == SetSlotExtractor.LLM.value
295
+ ]
296
+
297
+ if not llm_fillable_slot_names:
298
+ return commands
299
+
300
+ llm_fillable_slots = [
301
+ slot for slot in domain.slots if slot.name in llm_fillable_slot_names
302
+ ]
303
+
304
+ slot_filling_manager = SlotFillingManager(domain, tracker)
305
+ slots_to_be_removed = []
306
+
307
+ structlogger.debug(
308
+ "command_processor.check_commands_against_slot_mappings.active_flow",
309
+ active_flow=tracker.active_flow,
310
+ )
311
+
312
+ for slot in llm_fillable_slots:
313
+ should_fill_slot = False
314
+ for mapping in slot.mappings:
315
+ mapping_type = SlotMappingType(mapping.get("type"))
316
+
317
+ should_fill_slot = slot_filling_manager.should_fill_slot(
318
+ slot.name, mapping_type, mapping
319
+ )
320
+
321
+ if should_fill_slot:
322
+ break
323
+
324
+ if not should_fill_slot:
325
+ structlogger.debug(
326
+ "command_processor.check_commands_against_slot_mappings.slot_not_fillable",
327
+ slot_name=slot.name,
328
+ )
329
+ slots_to_be_removed.append(slot.name)
330
+
331
+ if not slots_to_be_removed:
332
+ return commands
333
+
334
+ filtered_commands = [
335
+ command
336
+ for command in commands
337
+ if not (
338
+ isinstance(command, SetSlotCommand)
339
+ and command.name in slots_to_be_removed
340
+ )
341
+ ]
342
+
343
+ return filtered_commands
@@ -0,0 +1,18 @@
1
+ from rasa.shared.utils.llm import (
2
+ DEFAULT_OPENAI_CHAT_MODEL_NAME_ADVANCED,
3
+ DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
4
+ )
5
+
6
+ DEFAULT_LLM_CONFIG = {
7
+ "_type": "openai",
8
+ "request_timeout": 7,
9
+ "temperature": 0.0,
10
+ "model_name": DEFAULT_OPENAI_CHAT_MODEL_NAME_ADVANCED,
11
+ "max_tokens": DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
12
+ }
13
+
14
+ LLM_CONFIG_KEY = "llm"
15
+ USER_INPUT_CONFIG_KEY = "user_input"
16
+
17
+ FLOW_RETRIEVAL_KEY = "flow_retrieval"
18
+ FLOW_RETRIEVAL_ACTIVE_KEY = "active"
@@ -34,6 +34,7 @@ from rasa.shared.core.flows import FlowsList
34
34
  from rasa.shared.core.trackers import DialogueStateTracker
35
35
  from rasa.shared.nlu.constants import TEXT, FLOWS_FROM_SEMANTIC_SEARCH
36
36
  from rasa.shared.nlu.training_data.message import Message
37
+ from rasa.shared.exceptions import ProviderClientAPIException
37
38
  from rasa.shared.utils.llm import (
38
39
  tracker_as_readable_transcript,
39
40
  embedder_factory,
@@ -93,11 +94,10 @@ class FlowRetrieval:
93
94
 
94
95
  @classmethod
95
96
  def validate_config(cls, config: Dict[Text, Any]) -> Dict[Text, Any]:
96
-
97
97
  if config[MAX_FLOWS_FROM_SEMANTIC_SEARCH_KEY] < 0:
98
- config[
99
- MAX_FLOWS_FROM_SEMANTIC_SEARCH_KEY
100
- ] = DEFAULT_MAX_FLOWS_FROM_SEMANTIC_SEARCH
98
+ config[MAX_FLOWS_FROM_SEMANTIC_SEARCH_KEY] = (
99
+ DEFAULT_MAX_FLOWS_FROM_SEMANTIC_SEARCH
100
+ )
101
101
  structlogger.error(
102
102
  f"flow_retrieval.validate_config.{MAX_FLOWS_FROM_SEMANTIC_SEARCH_KEY}.set_as_negative",
103
103
  event_info=(
@@ -407,4 +407,6 @@ class FlowRetrieval:
407
407
  error=e,
408
408
  query=query,
409
409
  )
410
- raise
410
+ raise ProviderClientAPIException(
411
+ message="Cannot fetch flows from vector store", original_exception=e
412
+ )