rasa-pro 3.10.16__py3-none-any.whl → 3.11.0a1__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 (185) hide show
  1. README.md +396 -17
  2. rasa/api.py +9 -3
  3. rasa/cli/arguments/default_arguments.py +23 -2
  4. rasa/cli/arguments/run.py +15 -0
  5. rasa/cli/arguments/train.py +3 -9
  6. rasa/cli/e2e_test.py +1 -1
  7. rasa/cli/evaluate.py +1 -1
  8. rasa/cli/inspect.py +8 -4
  9. rasa/cli/llm_fine_tuning.py +12 -15
  10. rasa/cli/run.py +8 -1
  11. rasa/cli/studio/studio.py +8 -18
  12. rasa/cli/train.py +11 -53
  13. rasa/cli/utils.py +8 -10
  14. rasa/cli/x.py +1 -1
  15. rasa/constants.py +1 -1
  16. rasa/core/actions/action.py +2 -0
  17. rasa/core/actions/action_hangup.py +29 -0
  18. rasa/core/agent.py +2 -2
  19. rasa/core/brokers/kafka.py +3 -1
  20. rasa/core/brokers/pika.py +3 -1
  21. rasa/core/channels/__init__.py +8 -6
  22. rasa/core/channels/channel.py +21 -4
  23. rasa/core/channels/development_inspector.py +143 -46
  24. rasa/core/channels/inspector/README.md +1 -1
  25. rasa/core/channels/inspector/dist/assets/{arc-b6e548fe.js → arc-86942a71.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-fa03ac9e.js → c4Diagram-d0fbc5ce-b0290676.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-ee67392a.js → classDiagram-936ed81e-f6405f6e.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-9b283fae.js → classDiagram-v2-c3cb15f1-ef61ac77.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-8b6fcc2a.js → createText-62fc7601-f0411e58.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-22e77f4f.js → edges-f2ad444c-7dcc4f3b.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-60ffc87f.js → erDiagram-9d236eb7-e0c092d7.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-9dd802e4.js → flowDb-1972c806-fba2e3ce.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-5fa1912f.js → flowDiagram-7ea5b25a-7a70b71a.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-24a5f41a.js +1 -0
  35. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-622a1fd2.js → flowchart-elk-definition-abe16c3d-00a59b68.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-e285a63a.js → ganttDiagram-9b5ea136-293c91fa.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-f237bdca.js → gitGraphDiagram-99d0ae7c-07b2d68c.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-4b03d70e.js → index-2c4b9a3b-bc959fbd.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/index-3a8a5a28.js +1317 -0
  40. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-72a0fa5f.js → infoDiagram-736b4530-4a350f72.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-82218c41.js → journeyDiagram-df861f2b-af464fb7.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{layout-78cff630.js → layout-0071f036.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{line-5038b469.js → line-2f73cc83.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{linear-c4fc4098.js → linear-f014b4cc.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-c33c8ea6.js → mindmap-definition-beec6740-d2426fb6.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-a8d03059.js → pieDiagram-dbbf0591-776f01a2.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-6a0e56b2.js → quadrantDiagram-4d7f4fd6-82e00b57.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-2dc7c7bd.js → requirementDiagram-6fc4c22a-ea13c6bb.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-2360fe39.js → sankeyDiagram-8f13d901-1feca7e9.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-41b9f9ad.js → sequenceDiagram-b655622a-070c61d2.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-0aad326f.js → stateDiagram-59f0c015-24f46263.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-9847d984.js → stateDiagram-v2-2b26beab-c9056051.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-564d890e.js → styles-080da4f6-08abc34a.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-38957613.js → styles-3dcbcfbf-bc74c25a.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-f0fc6921.js → styles-9c745c82-4e5d66de.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-ef3c5a77.js → svgDrawCommon-4835440b-849c4517.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-bf3e91c1.js → timeline-definition-5b62e21b-d0fb1598.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-4d4026c0.js → xychartDiagram-2b33534f-04d115e2.js} +1 -1
  59. rasa/core/channels/inspector/dist/index.html +18 -17
  60. rasa/core/channels/inspector/index.html +17 -16
  61. rasa/core/channels/inspector/package.json +5 -1
  62. rasa/core/channels/inspector/src/App.tsx +117 -67
  63. rasa/core/channels/inspector/src/components/Chat.tsx +95 -0
  64. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +11 -10
  65. rasa/core/channels/inspector/src/components/DialogueStack.tsx +10 -25
  66. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +1 -1
  67. rasa/core/channels/inspector/src/helpers/formatters.test.ts +10 -0
  68. rasa/core/channels/inspector/src/helpers/formatters.ts +107 -41
  69. rasa/core/channels/inspector/src/helpers/utils.ts +92 -7
  70. rasa/core/channels/inspector/src/types.ts +21 -1
  71. rasa/core/channels/inspector/yarn.lock +94 -1
  72. rasa/core/channels/rest.py +51 -46
  73. rasa/core/channels/socketio.py +22 -0
  74. rasa/core/channels/{audiocodes.py → voice_ready/audiocodes.py} +110 -68
  75. rasa/core/channels/{voice_aware → voice_ready}/jambonz.py +11 -4
  76. rasa/core/channels/{voice_aware → voice_ready}/jambonz_protocol.py +57 -5
  77. rasa/core/channels/{twilio_voice.py → voice_ready/twilio_voice.py} +58 -7
  78. rasa/core/channels/{voice_aware → voice_ready}/utils.py +16 -0
  79. rasa/core/channels/voice_stream/asr/__init__.py +0 -0
  80. rasa/core/channels/voice_stream/asr/asr_engine.py +71 -0
  81. rasa/core/channels/voice_stream/asr/asr_event.py +13 -0
  82. rasa/core/channels/voice_stream/asr/deepgram.py +77 -0
  83. rasa/core/channels/voice_stream/audio_bytes.py +7 -0
  84. rasa/core/channels/voice_stream/tts/__init__.py +0 -0
  85. rasa/core/channels/voice_stream/tts/azure.py +100 -0
  86. rasa/core/channels/voice_stream/tts/cartesia.py +114 -0
  87. rasa/core/channels/voice_stream/tts/tts_cache.py +27 -0
  88. rasa/core/channels/voice_stream/tts/tts_engine.py +48 -0
  89. rasa/core/channels/voice_stream/twilio_media_streams.py +164 -0
  90. rasa/core/channels/voice_stream/util.py +57 -0
  91. rasa/core/channels/voice_stream/voice_channel.py +247 -0
  92. rasa/core/featurizers/single_state_featurizer.py +1 -22
  93. rasa/core/featurizers/tracker_featurizers.py +18 -115
  94. rasa/core/nlg/contextual_response_rephraser.py +11 -2
  95. rasa/{nlu → core}/persistor.py +16 -38
  96. rasa/core/policies/enterprise_search_policy.py +12 -15
  97. rasa/core/policies/flows/flow_executor.py +8 -18
  98. rasa/core/policies/intentless_policy.py +10 -15
  99. rasa/core/policies/ted_policy.py +33 -58
  100. rasa/core/policies/unexpected_intent_policy.py +7 -15
  101. rasa/core/processor.py +13 -64
  102. rasa/core/run.py +11 -1
  103. rasa/core/secrets_manager/constants.py +4 -0
  104. rasa/core/secrets_manager/factory.py +8 -0
  105. rasa/core/secrets_manager/vault.py +11 -1
  106. rasa/core/training/interactive.py +1 -1
  107. rasa/core/utils.py +1 -11
  108. rasa/dialogue_understanding/coexistence/llm_based_router.py +10 -10
  109. rasa/dialogue_understanding/commands/__init__.py +2 -0
  110. rasa/dialogue_understanding/commands/change_flow_command.py +0 -6
  111. rasa/dialogue_understanding/commands/session_end_command.py +61 -0
  112. rasa/dialogue_understanding/generator/flow_retrieval.py +0 -7
  113. rasa/dialogue_understanding/generator/llm_based_command_generator.py +12 -3
  114. rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
  115. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -28
  116. rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -19
  117. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +4 -37
  118. rasa/e2e_test/aggregate_test_stats_calculator.py +1 -11
  119. rasa/e2e_test/assertions.py +6 -48
  120. rasa/e2e_test/e2e_test_runner.py +6 -9
  121. rasa/e2e_test/utils/e2e_yaml_utils.py +1 -1
  122. rasa/e2e_test/utils/io.py +1 -3
  123. rasa/engine/graph.py +3 -10
  124. rasa/engine/recipes/config_files/default_config.yml +0 -3
  125. rasa/engine/recipes/default_recipe.py +0 -1
  126. rasa/engine/recipes/graph_recipe.py +0 -1
  127. rasa/engine/runner/dask.py +2 -2
  128. rasa/engine/storage/local_model_storage.py +12 -42
  129. rasa/engine/storage/storage.py +1 -5
  130. rasa/engine/validation.py +1 -78
  131. rasa/keys +1 -0
  132. rasa/model_training.py +13 -16
  133. rasa/nlu/classifiers/diet_classifier.py +25 -38
  134. rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
  135. rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
  136. rasa/nlu/extractors/crf_entity_extractor.py +50 -93
  137. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +16 -45
  138. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +17 -52
  139. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
  140. rasa/server.py +1 -1
  141. rasa/shared/constants.py +3 -12
  142. rasa/shared/core/constants.py +4 -0
  143. rasa/shared/core/domain.py +101 -47
  144. rasa/shared/core/events.py +29 -0
  145. rasa/shared/core/flows/flows_list.py +20 -11
  146. rasa/shared/core/flows/validation.py +25 -0
  147. rasa/shared/core/flows/yaml_flows_io.py +3 -24
  148. rasa/shared/importers/importer.py +40 -39
  149. rasa/shared/importers/multi_project.py +23 -11
  150. rasa/shared/importers/rasa.py +7 -2
  151. rasa/shared/importers/remote_importer.py +196 -0
  152. rasa/shared/importers/utils.py +3 -1
  153. rasa/shared/nlu/training_data/features.py +2 -120
  154. rasa/shared/nlu/training_data/training_data.py +18 -19
  155. rasa/shared/providers/_configs/azure_openai_client_config.py +3 -5
  156. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -6
  157. rasa/shared/providers/llm/_base_litellm_client.py +11 -31
  158. rasa/shared/providers/llm/self_hosted_llm_client.py +3 -15
  159. rasa/shared/utils/common.py +3 -22
  160. rasa/shared/utils/io.py +0 -1
  161. rasa/shared/utils/llm.py +30 -27
  162. rasa/shared/utils/schemas/events.py +2 -0
  163. rasa/shared/utils/schemas/model_config.yml +0 -10
  164. rasa/shared/utils/yaml.py +44 -0
  165. rasa/studio/auth.py +5 -3
  166. rasa/studio/config.py +4 -13
  167. rasa/studio/constants.py +0 -1
  168. rasa/studio/data_handler.py +3 -10
  169. rasa/studio/upload.py +8 -17
  170. rasa/tracing/instrumentation/attribute_extractors.py +1 -1
  171. rasa/utils/io.py +66 -0
  172. rasa/utils/tensorflow/model_data.py +193 -2
  173. rasa/validator.py +0 -12
  174. rasa/version.py +1 -1
  175. rasa_pro-3.11.0a1.dist-info/METADATA +576 -0
  176. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/RECORD +181 -164
  177. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +0 -1
  178. rasa/core/channels/inspector/dist/assets/index-a5d3e69d.js +0 -1040
  179. rasa/utils/tensorflow/feature_array.py +0 -366
  180. rasa_pro-3.10.16.dist-info/METADATA +0 -196
  181. /rasa/core/channels/{voice_aware → voice_ready}/__init__.py +0 -0
  182. /rasa/core/channels/{voice_native → voice_stream}/__init__.py +0 -0
  183. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/NOTICE +0 -0
  184. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/WHEEL +0 -0
  185. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/entry_points.txt +0 -0
@@ -1,9 +1,11 @@
1
1
  from __future__ import annotations
2
-
3
- import logging
4
- from abc import abstractmethod
5
- from collections import defaultdict
6
2
  from pathlib import Path
3
+ from collections import defaultdict
4
+ from abc import abstractmethod
5
+ import jsonpickle
6
+ import logging
7
+
8
+ from tqdm import tqdm
7
9
  from typing import (
8
10
  Tuple,
9
11
  List,
@@ -16,30 +18,25 @@ from typing import (
16
18
  Set,
17
19
  DefaultDict,
18
20
  cast,
19
- Type,
20
- Callable,
21
- ClassVar,
22
21
  )
23
-
24
22
  import numpy as np
25
- from tqdm import tqdm
26
23
 
24
+ from rasa.core.featurizers.single_state_featurizer import SingleStateFeaturizer
25
+ from rasa.core.featurizers.precomputation import MessageContainerForCoreFeaturization
26
+ from rasa.core.exceptions import InvalidTrackerFeaturizerUsageError
27
27
  import rasa.shared.core.trackers
28
28
  import rasa.shared.utils.io
29
- from rasa.core.exceptions import InvalidTrackerFeaturizerUsageError
30
- from rasa.core.featurizers.precomputation import MessageContainerForCoreFeaturization
31
- from rasa.core.featurizers.single_state_featurizer import SingleStateFeaturizer
29
+ from rasa.shared.nlu.constants import TEXT, INTENT, ENTITIES, ACTION_NAME
30
+ from rasa.shared.nlu.training_data.features import Features
31
+ from rasa.shared.core.trackers import DialogueStateTracker
32
+ from rasa.shared.core.domain import State, Domain
33
+ from rasa.shared.core.events import Event, ActionExecuted, UserUttered
32
34
  from rasa.shared.core.constants import (
33
35
  USER,
34
36
  ACTION_UNLIKELY_INTENT_NAME,
35
37
  PREVIOUS_ACTION,
36
38
  )
37
- from rasa.shared.core.domain import State, Domain
38
- from rasa.shared.core.events import Event, ActionExecuted, UserUttered
39
- from rasa.shared.core.trackers import DialogueStateTracker
40
39
  from rasa.shared.exceptions import RasaException
41
- from rasa.shared.nlu.constants import TEXT, INTENT, ENTITIES, ACTION_NAME
42
- from rasa.shared.nlu.training_data.features import Features
43
40
  from rasa.utils.tensorflow.constants import LABEL_PAD_ID
44
41
  from rasa.utils.tensorflow.model_data import ragged_array_to_ndarray
45
42
 
@@ -67,10 +64,6 @@ class InvalidStory(RasaException):
67
64
  class TrackerFeaturizer:
68
65
  """Base class for actual tracker featurizers."""
69
66
 
70
- # Class registry to store all subclasses
71
- _registry: ClassVar[Dict[str, Type["TrackerFeaturizer"]]] = {}
72
- _featurizer_type: str = "TrackerFeaturizer"
73
-
74
67
  def __init__(
75
68
  self, state_featurizer: Optional[SingleStateFeaturizer] = None
76
69
  ) -> None:
@@ -81,36 +74,6 @@ class TrackerFeaturizer:
81
74
  """
82
75
  self.state_featurizer = state_featurizer
83
76
 
84
- @classmethod
85
- def register(cls, featurizer_type: str) -> Callable:
86
- """Decorator to register featurizer subclasses."""
87
-
88
- def wrapper(subclass: Type["TrackerFeaturizer"]) -> Type["TrackerFeaturizer"]:
89
- cls._registry[featurizer_type] = subclass
90
- # Store the type identifier in the class for serialization
91
- subclass._featurizer_type = featurizer_type
92
- return subclass
93
-
94
- return wrapper
95
-
96
- @classmethod
97
- def from_dict(cls, data: Dict[str, Any]) -> "TrackerFeaturizer":
98
- """Create featurizer instance from dictionary."""
99
- featurizer_type = data.pop("type")
100
-
101
- if featurizer_type not in cls._registry:
102
- raise ValueError(f"Unknown featurizer type: {featurizer_type}")
103
-
104
- # Get the correct subclass and instantiate it
105
- subclass = cls._registry[featurizer_type]
106
- return subclass.create_from_dict(data)
107
-
108
- @classmethod
109
- @abstractmethod
110
- def create_from_dict(cls, data: Dict[str, Any]) -> "TrackerFeaturizer":
111
- """Each subclass must implement its own creation from dict method."""
112
- pass
113
-
114
77
  @staticmethod
115
78
  def _create_states(
116
79
  tracker: DialogueStateTracker,
@@ -502,7 +465,9 @@ class TrackerFeaturizer:
502
465
  self.state_featurizer.entity_tag_specs = []
503
466
 
504
467
  # noinspection PyTypeChecker
505
- rasa.shared.utils.io.dump_obj_as_json_to_file(featurizer_file, self.to_dict())
468
+ rasa.shared.utils.io.write_text_file(
469
+ str(jsonpickle.encode(self)), featurizer_file
470
+ )
506
471
 
507
472
  @staticmethod
508
473
  def load(path: Union[Text, Path]) -> Optional[TrackerFeaturizer]:
@@ -516,17 +481,7 @@ class TrackerFeaturizer:
516
481
  """
517
482
  featurizer_file = Path(path) / FEATURIZER_FILE
518
483
  if featurizer_file.is_file():
519
- data = rasa.shared.utils.io.read_json_file(featurizer_file)
520
-
521
- if "type" not in data:
522
- logger.error(
523
- f"Couldn't load featurizer for policy. "
524
- f"File '{featurizer_file}' does not contain all "
525
- f"necessary information. 'type' is missing."
526
- )
527
- return None
528
-
529
- return TrackerFeaturizer.from_dict(data)
484
+ return jsonpickle.decode(rasa.shared.utils.io.read_file(featurizer_file))
530
485
 
531
486
  logger.error(
532
487
  f"Couldn't load featurizer for policy. "
@@ -553,16 +508,7 @@ class TrackerFeaturizer:
553
508
  )
554
509
  ]
555
510
 
556
- def to_dict(self) -> Dict[str, Any]:
557
- return {
558
- "type": self.__class__._featurizer_type,
559
- "state_featurizer": (
560
- self.state_featurizer.to_dict() if self.state_featurizer else None
561
- ),
562
- }
563
-
564
511
 
565
- @TrackerFeaturizer.register("FullDialogueTrackerFeaturizer")
566
512
  class FullDialogueTrackerFeaturizer(TrackerFeaturizer):
567
513
  """Creates full dialogue training data for time distributed architectures.
568
514
 
@@ -700,20 +646,7 @@ class FullDialogueTrackerFeaturizer(TrackerFeaturizer):
700
646
 
701
647
  return trackers_as_states
702
648
 
703
- def to_dict(self) -> Dict[str, Any]:
704
- return super().to_dict()
705
649
 
706
- @classmethod
707
- def create_from_dict(cls, data: Dict[str, Any]) -> "FullDialogueTrackerFeaturizer":
708
- state_featurizer = SingleStateFeaturizer.create_from_dict(
709
- data["state_featurizer"]
710
- )
711
- return cls(
712
- state_featurizer,
713
- )
714
-
715
-
716
- @TrackerFeaturizer.register("MaxHistoryTrackerFeaturizer")
717
650
  class MaxHistoryTrackerFeaturizer(TrackerFeaturizer):
718
651
  """Truncates the tracker history into `max_history` long sequences.
719
652
 
@@ -951,25 +884,7 @@ class MaxHistoryTrackerFeaturizer(TrackerFeaturizer):
951
884
 
952
885
  return trackers_as_states
953
886
 
954
- def to_dict(self) -> Dict[str, Any]:
955
- data = super().to_dict()
956
- data.update(
957
- {
958
- "remove_duplicates": self.remove_duplicates,
959
- "max_history": self.max_history,
960
- }
961
- )
962
- return data
963
-
964
- @classmethod
965
- def create_from_dict(cls, data: Dict[str, Any]) -> "MaxHistoryTrackerFeaturizer":
966
- state_featurizer = SingleStateFeaturizer.create_from_dict(
967
- data["state_featurizer"]
968
- )
969
- return cls(state_featurizer, data["max_history"], data["remove_duplicates"])
970
887
 
971
-
972
- @TrackerFeaturizer.register("IntentMaxHistoryTrackerFeaturizer")
973
888
  class IntentMaxHistoryTrackerFeaturizer(MaxHistoryTrackerFeaturizer):
974
889
  """Truncates the tracker history into `max_history` long sequences.
975
890
 
@@ -1244,18 +1159,6 @@ class IntentMaxHistoryTrackerFeaturizer(MaxHistoryTrackerFeaturizer):
1244
1159
 
1245
1160
  return trackers_as_states
1246
1161
 
1247
- def to_dict(self) -> Dict[str, Any]:
1248
- return super().to_dict()
1249
-
1250
- @classmethod
1251
- def create_from_dict(
1252
- cls, data: Dict[str, Any]
1253
- ) -> "IntentMaxHistoryTrackerFeaturizer":
1254
- state_featurizer = SingleStateFeaturizer.create_from_dict(
1255
- data["state_featurizer"]
1256
- )
1257
- return cls(state_featurizer, data["max_history"], data["remove_duplicates"])
1258
-
1259
1162
 
1260
1163
  def _is_prev_action_unlikely_intent_in_state(state: State) -> bool:
1261
1164
  prev_action_name = state.get(PREVIOUS_ACTION, {}).get(ACTION_NAME)
@@ -1,11 +1,13 @@
1
1
  from typing import Any, Dict, Optional, Text
2
2
 
3
+ import os
3
4
  import structlog
4
5
  from jinja2 import Template
5
6
 
6
7
  from rasa import telemetry
7
8
  from rasa.core.nlg.response import TemplatedNaturalLanguageGenerator
8
9
  from rasa.shared.constants import (
10
+ LLM_API_HEALTH_CHECK_ENV_VAR,
9
11
  LLM_CONFIG_KEY,
10
12
  MODEL_CONFIG_KEY,
11
13
  MODEL_NAME_CONFIG_KEY,
@@ -23,6 +25,7 @@ from rasa.shared.utils.llm import (
23
25
  USER,
24
26
  combine_custom_and_default_config,
25
27
  get_prompt_template,
28
+ llm_api_health_check,
26
29
  llm_factory,
27
30
  try_instantiate_llm_client,
28
31
  )
@@ -97,12 +100,18 @@ class ContextualResponseRephraser(TemplatedNaturalLanguageGenerator):
97
100
  self.trace_prompt_tokens = self.nlg_endpoint.kwargs.get(
98
101
  "trace_prompt_tokens", False
99
102
  )
100
- try_instantiate_llm_client(
103
+ llm_client = try_instantiate_llm_client(
101
104
  self.nlg_endpoint.kwargs.get(LLM_CONFIG_KEY),
102
105
  DEFAULT_LLM_CONFIG,
103
106
  "contextual_response_rephraser.init",
104
- "ContextualResponseRephraser",
107
+ ContextualResponseRephraser.__name__,
105
108
  )
109
+ if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
110
+ llm_api_health_check(
111
+ llm_client,
112
+ "contextual_response_rephraser.init",
113
+ ContextualResponseRephraser.__name__,
114
+ )
106
115
 
107
116
  def _last_message_if_human(self, tracker: DialogueStateTracker) -> Optional[str]:
108
117
  """Returns the latest message from the tracker.
@@ -82,14 +82,16 @@ def get_persistor(storage: StorageType) -> Optional[Persistor]:
82
82
  Currently, `aws`, `gcs`, `azure` and providing module paths are supported remote
83
83
  storages.
84
84
  """
85
- if storage == RemoteStorageType.AWS:
85
+ storage = storage.value if isinstance(storage, RemoteStorageType) else storage
86
+
87
+ if storage == RemoteStorageType.AWS.value:
86
88
  return AWSPersistor(
87
89
  os.environ.get(BUCKET_NAME_ENV), os.environ.get(AWS_ENDPOINT_URL_ENV)
88
90
  )
89
- if storage == RemoteStorageType.GCS:
91
+ if storage == RemoteStorageType.GCS.value:
90
92
  return GCSPersistor(os.environ.get(BUCKET_NAME_ENV))
91
93
 
92
- if storage == RemoteStorageType.AZURE:
94
+ if storage == RemoteStorageType.AZURE.value:
93
95
  return AzurePersistor(
94
96
  os.environ.get(AZURE_CONTAINER_ENV),
95
97
  os.environ.get(AZURE_ACCOUNT_NAME_ENV),
@@ -123,36 +125,24 @@ class Persistor(abc.ABC):
123
125
  """Downloads a model that has been persisted to cloud storage.
124
126
 
125
127
  Downloaded model will be saved to the `target_path`.
126
- If `target_path` is a directory, the model will be downloaded to that directory.
127
- If `target_path` is a file, the model will be downloaded to that file.
128
+ If `target_path` is a directory, the model will be saved to that directory.
129
+ If `target_path` is a file, the model will be saved to that file.
128
130
 
129
131
  Args:
130
132
  model_name: The name of the model to retrieve.
131
- target_path: The path to which the model should be downloaded.
133
+ target_path: The path to which the model should be saved.
132
134
  """
133
135
  tar_name = model_name
134
136
  if not model_name.endswith(MODEL_ARCHIVE_EXTENSION):
135
137
  # ensure backward compatibility
136
138
  tar_name = self._tar_name(model_name)
137
- remote_object_path = self._create_file_key(tar_name)
138
- self._retrieve_tar(remote_object_path)
139
+ tar_name = self._create_file_key(tar_name)
140
+ self._retrieve_tar(tar_name)
141
+ self._copy(os.path.basename(tar_name), target_path)
139
142
 
140
- target_tar_file_name = os.path.basename(tar_name)
141
143
  if os.path.isdir(target_path):
142
- target_path = os.path.join(target_path, target_tar_file_name)
143
-
144
- if not os.path.exists(target_path):
145
- structlogger.debug(
146
- "persistor.retrieve.copy_model",
147
- event_info=f"Copying model '{target_tar_file_name}' to "
148
- f"'{target_path}'.",
149
- )
150
- self._copy(target_tar_file_name, target_path)
144
+ return os.path.join(target_path, model_name)
151
145
 
152
- structlogger.debug(
153
- "persistor.retrieve.model_retrieved",
154
- event_info=f"Model retrieved and saved to '{target_path}'.",
155
- )
156
146
  return target_path
157
147
 
158
148
  @abc.abstractmethod
@@ -175,7 +165,7 @@ class Persistor(abc.ABC):
175
165
  os.path.join(dirpath, base_name),
176
166
  "gztar",
177
167
  root_dir=model_directory,
178
- base_dir=".",
168
+ base_dir="../nlu",
179
169
  )
180
170
  file_key = os.path.basename(tar_name)
181
171
  return file_key, tar_name
@@ -272,11 +262,6 @@ class AWSPersistor(Persistor):
272
262
 
273
263
  def _persist_tar(self, file_key: Text, tar_path: Text) -> None:
274
264
  """Uploads a model persisted in the `target_dir` to s3."""
275
- structlogger.debug(
276
- "aws_persistor.persist_tar.uploading_model",
277
- event_info=f"Uploading tar archive {file_key} to "
278
- f"s3 bucket '{self.bucket_name}'.",
279
- )
280
265
  with open(tar_path, "rb") as f:
281
266
  self.s3.Object(self.bucket_name, file_key).put(Body=f)
282
267
 
@@ -344,7 +329,7 @@ class GCSPersistor(Persistor):
344
329
  def _retrieve_tar(self, target_filename: Text) -> None:
345
330
  """Downloads a model that has previously been persisted to GCS."""
346
331
  blob = self.bucket.blob(target_filename)
347
- blob.download_to_filename(os.path.basename(target_filename))
332
+ blob.download_to_filename(target_filename)
348
333
 
349
334
 
350
335
  class AzurePersistor(Persistor):
@@ -385,19 +370,12 @@ class AzurePersistor(Persistor):
385
370
  def _persist_tar(self, file_key: Text, tar_path: Text) -> None:
386
371
  """Uploads a model persisted in the `target_dir` to Azure."""
387
372
  with open(tar_path, "rb") as data:
388
- self._container_client().upload_blob(
389
- name=file_key,
390
- data=data,
391
- # overwrite is set to True to keep in line with
392
- # how GCS and AWS APIs work this enables easy
393
- # updating of models in the cloud
394
- overwrite=True,
395
- )
373
+ self._container_client().upload_blob(name=file_key, data=data)
396
374
 
397
375
  def _retrieve_tar(self, target_filename: Text) -> None:
398
376
  """Downloads a model that has previously been persisted to Azure."""
399
377
  blob_client = self._container_client().get_blob_client(target_filename)
400
378
 
401
- with open(os.path.basename(target_filename), "wb") as blob:
379
+ with open(target_filename, "wb") as blob:
402
380
  download_stream = blob_client.download_blob()
403
381
  blob.write(download_stream.readall())
@@ -1,5 +1,6 @@
1
1
  import importlib.resources
2
2
  import json
3
+ import os
3
4
  import re
4
5
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text
5
6
 
@@ -47,6 +48,7 @@ from rasa.graph_components.providers.forms_provider import Forms
47
48
  from rasa.graph_components.providers.responses_provider import Responses
48
49
  from rasa.shared.constants import (
49
50
  EMBEDDINGS_CONFIG_KEY,
51
+ LLM_API_HEALTH_CHECK_ENV_VAR,
50
52
  LLM_CONFIG_KEY,
51
53
  MODEL_CONFIG_KEY,
52
54
  MODEL_NAME_CONFIG_KEY,
@@ -72,11 +74,11 @@ from rasa.shared.utils.llm import (
72
74
  DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
73
75
  embedder_factory,
74
76
  get_prompt_template,
77
+ llm_api_health_check,
75
78
  llm_factory,
76
79
  sanitize_message_for_prompt,
77
80
  tracker_as_readable_transcript,
78
81
  try_instantiate_llm_client,
79
- try_instantiate_embedder,
80
82
  )
81
83
  from rasa.core.information_retrieval.faiss import FAISS_Store
82
84
  from rasa.core.information_retrieval import (
@@ -293,12 +295,18 @@ class EnterpriseSearchPolicy(Policy):
293
295
  )
294
296
 
295
297
  # validate llm configuration
296
- try_instantiate_llm_client(
298
+ llm_client = try_instantiate_llm_client(
297
299
  self.config.get(LLM_CONFIG_KEY),
298
300
  DEFAULT_LLM_CONFIG,
299
301
  "enterprise_search_policy.train",
300
- "EnterpriseSearchPolicy",
302
+ EnterpriseSearchPolicy.__name__,
301
303
  )
304
+ if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
305
+ llm_api_health_check(
306
+ llm_client,
307
+ "enterprise_search_policy.train",
308
+ EnterpriseSearchPolicy.__name__,
309
+ )
302
310
 
303
311
  if store_type == DEFAULT_VECTOR_STORE_TYPE:
304
312
  logger.info("enterprise_search_policy.train.faiss")
@@ -662,18 +670,6 @@ class EnterpriseSearchPolicy(Policy):
662
670
  execution_context: ExecutionContext,
663
671
  **kwargs: Any,
664
672
  ) -> "EnterpriseSearchPolicy":
665
- try_instantiate_llm_client(
666
- config.get(LLM_CONFIG_KEY),
667
- DEFAULT_LLM_CONFIG,
668
- "enterprise_search_policy.load",
669
- EnterpriseSearchPolicy.__name__,
670
- )
671
- try_instantiate_embedder(
672
- config.get(EMBEDDINGS_CONFIG_KEY),
673
- DEFAULT_EMBEDDINGS_CONFIG,
674
- "enterprise_search_policy.load",
675
- EnterpriseSearchPolicy.__name__,
676
- )
677
673
  """Loads a trained policy (see parent class for full docstring)."""
678
674
  prompt_template = None
679
675
  store_type = config.get(VECTOR_STORE_PROPERTY, {}).get(
@@ -708,6 +704,7 @@ class EnterpriseSearchPolicy(Policy):
708
704
  logger.warning(
709
705
  "enterprise_search_policy.load.failed", error=e, resource=resource.name
710
706
  )
707
+
711
708
  return cls(
712
709
  config,
713
710
  model_storage,
@@ -484,8 +484,7 @@ def validate_collect_step(
484
484
  step: CollectInformationFlowStep,
485
485
  stack: DialogueStack,
486
486
  available_actions: List[str],
487
- slots: Dict[str, Slot],
488
- flow_name: str,
487
+ slots: Dict[Text, Slot],
489
488
  ) -> bool:
490
489
  """Validate that a collect step can be executed.
491
490
 
@@ -508,12 +507,12 @@ def validate_collect_step(
508
507
  slot_name=step.collect,
509
508
  )
510
509
 
511
- cancel_flow_and_push_internal_error(stack, flow_name)
510
+ cancel_flow_and_push_internal_error(stack)
512
511
 
513
512
  return False
514
513
 
515
514
 
516
- def cancel_flow_and_push_internal_error(stack: DialogueStack, flow_name: str) -> None:
515
+ def cancel_flow_and_push_internal_error(stack: DialogueStack) -> None:
517
516
  """Cancel the top user flow and push the internal error pattern."""
518
517
  top_frame = stack.top()
519
518
 
@@ -525,7 +524,7 @@ def cancel_flow_and_push_internal_error(stack: DialogueStack, flow_name: str) ->
525
524
  canceled_frames = CancelFlowCommand.select_canceled_frames(stack)
526
525
  stack.push(
527
526
  CancelPatternFlowStackFrame(
528
- canceled_name=flow_name,
527
+ canceled_name=top_frame.flow_id,
529
528
  canceled_frames=canceled_frames,
530
529
  )
531
530
  )
@@ -537,7 +536,6 @@ def validate_custom_slot_mappings(
537
536
  stack: DialogueStack,
538
537
  tracker: DialogueStateTracker,
539
538
  available_actions: List[str],
540
- flow_name: str,
541
539
  ) -> bool:
542
540
  """Validate a slot with custom mappings.
543
541
 
@@ -558,7 +556,7 @@ def validate_custom_slot_mappings(
558
556
  action=step.collect_action,
559
557
  collect=step.collect,
560
558
  )
561
- cancel_flow_and_push_internal_error(stack, flow_name)
559
+ cancel_flow_and_push_internal_error(stack)
562
560
  return False
563
561
 
564
562
  return True
@@ -598,12 +596,7 @@ def run_step(
598
596
 
599
597
  if isinstance(step, CollectInformationFlowStep):
600
598
  return _run_collect_information_step(
601
- available_actions,
602
- initial_events,
603
- stack,
604
- step,
605
- tracker,
606
- flow.readable_name(),
599
+ available_actions, initial_events, stack, step, tracker
607
600
  )
608
601
 
609
602
  elif isinstance(step, ActionFlowStep):
@@ -723,18 +716,15 @@ def _run_collect_information_step(
723
716
  stack: DialogueStack,
724
717
  step: CollectInformationFlowStep,
725
718
  tracker: DialogueStateTracker,
726
- flow_name: str,
727
719
  ) -> FlowStepResult:
728
- is_step_valid = validate_collect_step(
729
- step, stack, available_actions, tracker.slots, flow_name
730
- )
720
+ is_step_valid = validate_collect_step(step, stack, available_actions, tracker.slots)
731
721
 
732
722
  if not is_step_valid:
733
723
  # if we return any other FlowStepResult, the assistant will stay silent
734
724
  # instead of triggering the internal error pattern
735
725
  return ContinueFlowWithNextStep(events=initial_events)
736
726
  is_mapping_valid = validate_custom_slot_mappings(
737
- step, stack, tracker, available_actions, flow_name
727
+ step, stack, tracker, available_actions
738
728
  )
739
729
 
740
730
  if not is_mapping_valid:
@@ -1,5 +1,6 @@
1
1
  import importlib.resources
2
2
  import math
3
+ import os
3
4
  from dataclasses import dataclass, field
4
5
  from typing import Any, Dict, List, Optional, Set, TYPE_CHECKING, Text, Tuple
5
6
 
@@ -31,6 +32,7 @@ from rasa.graph_components.providers.responses_provider import Responses
31
32
  from rasa.shared.constants import (
32
33
  REQUIRED_SLOTS_KEY,
33
34
  EMBEDDINGS_CONFIG_KEY,
35
+ LLM_API_HEALTH_CHECK_ENV_VAR,
34
36
  LLM_CONFIG_KEY,
35
37
  MODEL_CONFIG_KEY,
36
38
  MODEL_NAME_CONFIG_KEY,
@@ -67,11 +69,11 @@ from rasa.shared.utils.llm import (
67
69
  combine_custom_and_default_config,
68
70
  embedder_factory,
69
71
  get_prompt_template,
72
+ llm_api_health_check,
70
73
  llm_factory,
71
74
  sanitize_message_for_prompt,
72
75
  tracker_as_readable_transcript,
73
76
  try_instantiate_llm_client,
74
- try_instantiate_embedder,
75
77
  )
76
78
  from rasa.utils.ml_utils import (
77
79
  extract_ai_response_examples,
@@ -488,12 +490,16 @@ class IntentlessPolicy(Policy):
488
490
  A policy must return its resource locator so that potential children nodes
489
491
  can load the policy from the resource.
490
492
  """
491
- try_instantiate_llm_client(
493
+ llm_client = try_instantiate_llm_client(
492
494
  self.config.get(LLM_CONFIG_KEY),
493
495
  DEFAULT_LLM_CONFIG,
494
496
  "intentless_policy.train",
495
- "IntentlessPolicy",
497
+ IntentlessPolicy.__name__,
496
498
  )
499
+ if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
500
+ llm_api_health_check(
501
+ llm_client, "intentless_policy.train", IntentlessPolicy.__name__
502
+ )
497
503
 
498
504
  responses = filter_responses(responses, forms, flows or FlowsList([]))
499
505
  telemetry.track_intentless_policy_train()
@@ -919,18 +925,6 @@ class IntentlessPolicy(Policy):
919
925
  **kwargs: Any,
920
926
  ) -> "IntentlessPolicy":
921
927
  """Loads a trained policy (see parent class for full docstring)."""
922
- try_instantiate_llm_client(
923
- config.get(LLM_CONFIG_KEY),
924
- DEFAULT_LLM_CONFIG,
925
- "intentless_policy.load",
926
- IntentlessPolicy.__name__,
927
- )
928
- try_instantiate_embedder(
929
- config.get(EMBEDDINGS_CONFIG_KEY),
930
- DEFAULT_EMBEDDINGS_CONFIG,
931
- "intentless_policy.load",
932
- IntentlessPolicy.__name__,
933
- )
934
928
  responses_docsearch = None
935
929
  samples_docsearch = None
936
930
  prompt_template = None
@@ -956,6 +950,7 @@ class IntentlessPolicy(Policy):
956
950
  structlogger.warning(
957
951
  "intentless_policy.load.failed", error=e, resource_name=resource.name
958
952
  )
953
+
959
954
  return cls(
960
955
  config,
961
956
  model_storage,