rasa-pro 3.11.0a4.dev3__py3-none-any.whl → 3.11.0rc2__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 (184) hide show
  1. rasa/__main__.py +22 -12
  2. rasa/api.py +1 -1
  3. rasa/cli/arguments/default_arguments.py +1 -2
  4. rasa/cli/arguments/shell.py +5 -1
  5. rasa/cli/e2e_test.py +1 -1
  6. rasa/cli/evaluate.py +8 -8
  7. rasa/cli/inspect.py +6 -4
  8. rasa/cli/llm_fine_tuning.py +1 -1
  9. rasa/cli/project_templates/calm/config.yml +5 -7
  10. rasa/cli/project_templates/calm/endpoints.yml +8 -0
  11. rasa/cli/project_templates/tutorial/config.yml +8 -5
  12. rasa/cli/project_templates/tutorial/data/flows.yml +1 -1
  13. rasa/cli/project_templates/tutorial/data/patterns.yml +5 -0
  14. rasa/cli/project_templates/tutorial/domain.yml +14 -0
  15. rasa/cli/project_templates/tutorial/endpoints.yml +7 -7
  16. rasa/cli/run.py +1 -1
  17. rasa/cli/scaffold.py +4 -2
  18. rasa/cli/studio/studio.py +18 -8
  19. rasa/cli/utils.py +5 -0
  20. rasa/cli/x.py +8 -8
  21. rasa/constants.py +1 -1
  22. rasa/core/actions/action_repeat_bot_messages.py +17 -0
  23. rasa/core/channels/channel.py +20 -0
  24. rasa/core/channels/inspector/dist/assets/{arc-6852c607.js → arc-bc141fb2.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-acc952b2.js → c4Diagram-d0fbc5ce-be2db283.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-848a7597.js → classDiagram-936ed81e-55366915.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-a73d3e68.js → classDiagram-v2-c3cb15f1-bb529518.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-e5ee049d.js → createText-62fc7601-b0ec81d6.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-771e517e.js → edges-f2ad444c-6166330c.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-aa347178.js → erDiagram-9d236eb7-5ccc6a8e.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-651fc57d.js → flowDb-1972c806-fca3bfe4.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-ca67804f.js → flowDiagram-7ea5b25a-4739080f.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +1 -0
  34. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-2dbc568d.js → flowchart-elk-definition-abe16c3d-7c1b0e0f.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-25a65bd8.js → ganttDiagram-9b5ea136-772fd050.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-fdc7378d.js → gitGraphDiagram-99d0ae7c-8eae1dc9.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-6f1fd606.js → index-2c4b9a3b-f55afcdf.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{index-efdd30c1.js → index-e7cef9de.js} +68 -68
  39. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-cb1a041a.js → infoDiagram-736b4530-124d4a14.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-14609879.js → journeyDiagram-df861f2b-7c4fae44.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{layout-2490f52b.js → layout-b9885fb6.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{line-40186f1f.js → line-7c59abb6.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{linear-08814e93.js → linear-4776f780.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-1a534584.js → mindmap-definition-beec6740-2332c46c.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-72397b61.js → pieDiagram-dbbf0591-8fb39303.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-3bb0b6a3.js → quadrantDiagram-4d7f4fd6-3c7180a2.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-57334f61.js → requirementDiagram-6fc4c22a-e910bcb8.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-111e1297.js → sankeyDiagram-8f13d901-ead16c89.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-10bcfe62.js → sequenceDiagram-b655622a-29a02a19.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-acaf7513.js → stateDiagram-59f0c015-042b3137.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-3ec2a235.js → stateDiagram-v2-2b26beab-2178c0f3.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-62730289.js → styles-080da4f6-23ffa4fc.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-5284ee76.js → styles-3dcbcfbf-94f59763.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-642435e3.js → styles-9c745c82-78a6bebc.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-b250a350.js → svgDrawCommon-4835440b-eae2a6f6.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-c2b147ed.js → timeline-definition-5b62e21b-5c968d92.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-f92cfea9.js → xychartDiagram-2b33534f-fd3db0d5.js} +1 -1
  58. rasa/core/channels/inspector/dist/index.html +1 -1
  59. rasa/core/channels/inspector/src/App.tsx +1 -1
  60. rasa/core/channels/inspector/src/helpers/audiostream.ts +77 -16
  61. rasa/core/channels/socketio.py +2 -1
  62. rasa/core/channels/telegram.py +1 -1
  63. rasa/core/channels/twilio.py +1 -1
  64. rasa/core/channels/voice_ready/audiocodes.py +12 -0
  65. rasa/core/channels/voice_ready/jambonz.py +15 -4
  66. rasa/core/channels/voice_ready/twilio_voice.py +6 -21
  67. rasa/core/channels/voice_stream/asr/asr_event.py +5 -0
  68. rasa/core/channels/voice_stream/asr/azure.py +122 -0
  69. rasa/core/channels/voice_stream/asr/deepgram.py +16 -6
  70. rasa/core/channels/voice_stream/audio_bytes.py +1 -0
  71. rasa/core/channels/voice_stream/browser_audio.py +31 -8
  72. rasa/core/channels/voice_stream/call_state.py +23 -0
  73. rasa/core/channels/voice_stream/tts/azure.py +6 -2
  74. rasa/core/channels/voice_stream/tts/cartesia.py +10 -6
  75. rasa/core/channels/voice_stream/tts/tts_engine.py +1 -0
  76. rasa/core/channels/voice_stream/twilio_media_streams.py +27 -18
  77. rasa/core/channels/voice_stream/util.py +4 -4
  78. rasa/core/channels/voice_stream/voice_channel.py +189 -39
  79. rasa/core/featurizers/single_state_featurizer.py +22 -1
  80. rasa/core/featurizers/tracker_featurizers.py +115 -18
  81. rasa/core/nlg/contextual_response_rephraser.py +32 -30
  82. rasa/core/persistor.py +86 -39
  83. rasa/core/policies/enterprise_search_policy.py +119 -60
  84. rasa/core/policies/flows/flow_executor.py +7 -4
  85. rasa/core/policies/intentless_policy.py +78 -22
  86. rasa/core/policies/ted_policy.py +58 -33
  87. rasa/core/policies/unexpected_intent_policy.py +15 -7
  88. rasa/core/processor.py +25 -0
  89. rasa/core/training/interactive.py +34 -35
  90. rasa/core/utils.py +8 -3
  91. rasa/dialogue_understanding/coexistence/llm_based_router.py +39 -12
  92. rasa/dialogue_understanding/commands/change_flow_command.py +6 -0
  93. rasa/dialogue_understanding/commands/user_silence_command.py +59 -0
  94. rasa/dialogue_understanding/commands/utils.py +5 -0
  95. rasa/dialogue_understanding/generator/constants.py +2 -0
  96. rasa/dialogue_understanding/generator/flow_retrieval.py +49 -4
  97. rasa/dialogue_understanding/generator/llm_based_command_generator.py +37 -23
  98. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +57 -10
  99. rasa/dialogue_understanding/generator/nlu_command_adapter.py +19 -1
  100. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +71 -11
  101. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +39 -0
  102. rasa/dialogue_understanding/patterns/user_silence.py +37 -0
  103. rasa/dialogue_understanding/processor/command_processor.py +21 -1
  104. rasa/e2e_test/e2e_test_case.py +85 -6
  105. rasa/e2e_test/e2e_test_runner.py +4 -2
  106. rasa/e2e_test/utils/io.py +1 -1
  107. rasa/engine/validation.py +316 -10
  108. rasa/model_manager/config.py +15 -3
  109. rasa/model_manager/model_api.py +15 -7
  110. rasa/model_manager/runner_service.py +8 -6
  111. rasa/model_manager/socket_bridge.py +6 -3
  112. rasa/model_manager/trainer_service.py +7 -5
  113. rasa/model_manager/utils.py +28 -7
  114. rasa/model_service.py +9 -2
  115. rasa/model_training.py +2 -0
  116. rasa/nlu/classifiers/diet_classifier.py +38 -25
  117. rasa/nlu/classifiers/logistic_regression_classifier.py +22 -9
  118. rasa/nlu/classifiers/sklearn_intent_classifier.py +37 -16
  119. rasa/nlu/extractors/crf_entity_extractor.py +93 -50
  120. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +45 -16
  121. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +52 -17
  122. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +5 -3
  123. rasa/nlu/tokenizers/whitespace_tokenizer.py +3 -14
  124. rasa/server.py +3 -1
  125. rasa/shared/constants.py +36 -3
  126. rasa/shared/core/constants.py +7 -0
  127. rasa/shared/core/domain.py +26 -0
  128. rasa/shared/core/flows/flow.py +5 -0
  129. rasa/shared/core/flows/flows_list.py +5 -1
  130. rasa/shared/core/flows/flows_yaml_schema.json +10 -0
  131. rasa/shared/core/flows/utils.py +39 -0
  132. rasa/shared/core/flows/validation.py +96 -0
  133. rasa/shared/core/slots.py +5 -0
  134. rasa/shared/nlu/training_data/features.py +120 -2
  135. rasa/shared/providers/_configs/azure_openai_client_config.py +5 -3
  136. rasa/shared/providers/_configs/litellm_router_client_config.py +200 -0
  137. rasa/shared/providers/_configs/model_group_config.py +167 -0
  138. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  139. rasa/shared/providers/_configs/rasa_llm_client_config.py +73 -0
  140. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -0
  141. rasa/shared/providers/_configs/utils.py +16 -0
  142. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +18 -29
  143. rasa/shared/providers/embedding/azure_openai_embedding_client.py +54 -21
  144. rasa/shared/providers/embedding/litellm_router_embedding_client.py +135 -0
  145. rasa/shared/providers/llm/_base_litellm_client.py +37 -31
  146. rasa/shared/providers/llm/azure_openai_llm_client.py +50 -29
  147. rasa/shared/providers/llm/litellm_router_llm_client.py +127 -0
  148. rasa/shared/providers/llm/rasa_llm_client.py +112 -0
  149. rasa/shared/providers/llm/self_hosted_llm_client.py +1 -1
  150. rasa/shared/providers/mappings.py +19 -0
  151. rasa/shared/providers/router/__init__.py +0 -0
  152. rasa/shared/providers/router/_base_litellm_router_client.py +149 -0
  153. rasa/shared/providers/router/router_client.py +73 -0
  154. rasa/shared/utils/common.py +8 -0
  155. rasa/shared/utils/health_check/__init__.py +0 -0
  156. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +31 -0
  157. rasa/shared/utils/health_check/health_check.py +256 -0
  158. rasa/shared/utils/health_check/llm_health_check_mixin.py +31 -0
  159. rasa/shared/utils/io.py +28 -6
  160. rasa/shared/utils/llm.py +353 -46
  161. rasa/shared/utils/yaml.py +111 -73
  162. rasa/studio/auth.py +3 -5
  163. rasa/studio/config.py +13 -4
  164. rasa/studio/constants.py +1 -0
  165. rasa/studio/data_handler.py +10 -3
  166. rasa/studio/upload.py +81 -26
  167. rasa/telemetry.py +92 -17
  168. rasa/tracing/config.py +2 -0
  169. rasa/tracing/instrumentation/attribute_extractors.py +94 -17
  170. rasa/tracing/instrumentation/instrumentation.py +121 -0
  171. rasa/utils/common.py +5 -0
  172. rasa/utils/io.py +7 -81
  173. rasa/utils/log_utils.py +9 -2
  174. rasa/utils/sanic_error_handler.py +32 -0
  175. rasa/utils/tensorflow/feature_array.py +366 -0
  176. rasa/utils/tensorflow/model_data.py +2 -193
  177. rasa/validator.py +70 -0
  178. rasa/version.py +1 -1
  179. {rasa_pro-3.11.0a4.dev3.dist-info → rasa_pro-3.11.0rc2.dist-info}/METADATA +11 -10
  180. {rasa_pro-3.11.0a4.dev3.dist-info → rasa_pro-3.11.0rc2.dist-info}/RECORD +183 -163
  181. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-587d82d8.js +0 -1
  182. {rasa_pro-3.11.0a4.dev3.dist-info → rasa_pro-3.11.0rc2.dist-info}/NOTICE +0 -0
  183. {rasa_pro-3.11.0a4.dev3.dist-info → rasa_pro-3.11.0rc2.dist-info}/WHEEL +0 -0
  184. {rasa_pro-3.11.0a4.dev3.dist-info → rasa_pro-3.11.0rc2.dist-info}/entry_points.txt +0 -0
@@ -1,15 +1,15 @@
1
1
  from __future__ import annotations
2
- import logging
3
2
 
4
- from rasa.engine.recipes.default_recipe import DefaultV1Recipe
3
+ import logging
5
4
  from pathlib import Path
6
5
  from collections import defaultdict
7
6
  import contextlib
7
+ from typing import Any, List, Optional, Text, Dict, Tuple, Union, Type
8
8
 
9
9
  import numpy as np
10
10
  import tensorflow as tf
11
- from typing import Any, List, Optional, Text, Dict, Tuple, Union, Type
12
11
 
12
+ from rasa.engine.recipes.default_recipe import DefaultV1Recipe
13
13
  from rasa.engine.graph import ExecutionContext
14
14
  from rasa.engine.storage.resource import Resource
15
15
  from rasa.engine.storage.storage import ModelStorage
@@ -49,18 +49,22 @@ from rasa.shared.core.generator import TrackerWithCachedStates
49
49
  from rasa.shared.core.events import EntitiesAdded, Event
50
50
  from rasa.shared.core.domain import Domain
51
51
  from rasa.shared.nlu.training_data.message import Message
52
- from rasa.shared.nlu.training_data.features import Features
52
+ from rasa.shared.nlu.training_data.features import (
53
+ Features,
54
+ save_features,
55
+ load_features,
56
+ )
53
57
  import rasa.shared.utils.io
54
58
  import rasa.utils.io
55
59
  from rasa.utils import train_utils
56
- from rasa.utils.tensorflow.models import RasaModel, TransformerRasaModel
57
- from rasa.utils.tensorflow import rasa_layers
58
- from rasa.utils.tensorflow.model_data import (
59
- RasaModelData,
60
- FeatureSignature,
60
+ from rasa.utils.tensorflow.feature_array import (
61
61
  FeatureArray,
62
- Data,
62
+ serialize_nested_feature_arrays,
63
+ deserialize_nested_feature_arrays,
63
64
  )
65
+ from rasa.utils.tensorflow.models import RasaModel, TransformerRasaModel
66
+ from rasa.utils.tensorflow import rasa_layers
67
+ from rasa.utils.tensorflow.model_data import RasaModelData, FeatureSignature, Data
64
68
  from rasa.utils.tensorflow.model_data_utils import convert_to_data_format
65
69
  from rasa.utils.tensorflow.constants import (
66
70
  LABEL,
@@ -961,22 +965,32 @@ class TEDPolicy(Policy):
961
965
  model_path: Path where model is to be persisted
962
966
  """
963
967
  model_filename = self._metadata_filename()
964
- rasa.utils.io.json_pickle(
965
- model_path / f"{model_filename}.priority.pkl", self.priority
966
- )
967
- rasa.utils.io.pickle_dump(
968
- model_path / f"{model_filename}.meta.pkl", self.config
968
+ rasa.shared.utils.io.dump_obj_as_json_to_file(
969
+ model_path / f"{model_filename}.priority.json", self.priority
969
970
  )
970
- rasa.utils.io.pickle_dump(
971
- model_path / f"{model_filename}.data_example.pkl", self.data_example
971
+ rasa.shared.utils.io.dump_obj_as_json_to_file(
972
+ model_path / f"{model_filename}.meta.json", self.config
972
973
  )
973
- rasa.utils.io.pickle_dump(
974
- model_path / f"{model_filename}.fake_features.pkl", self.fake_features
974
+ # save data example
975
+ serialize_nested_feature_arrays(
976
+ self.data_example,
977
+ str(model_path / f"{model_filename}.data_example.st"),
978
+ str(model_path / f"{model_filename}.data_example_metadata.json"),
975
979
  )
976
- rasa.utils.io.pickle_dump(
977
- model_path / f"{model_filename}.label_data.pkl",
980
+ # save label data
981
+ serialize_nested_feature_arrays(
978
982
  dict(self._label_data.data) if self._label_data is not None else {},
983
+ str(model_path / f"{model_filename}.label_data.st"),
984
+ str(model_path / f"{model_filename}.label_data_metadata.json"),
985
+ )
986
+ # save fake features
987
+ metadata = save_features(
988
+ self.fake_features, str(model_path / f"{model_filename}.fake_features.st")
989
+ )
990
+ rasa.shared.utils.io.dump_obj_as_json_to_file(
991
+ model_path / f"{model_filename}.fake_features_metadata.json", metadata
979
992
  )
993
+
980
994
  entity_tag_specs = (
981
995
  [tag_spec._asdict() for tag_spec in self._entity_tag_specs]
982
996
  if self._entity_tag_specs
@@ -994,18 +1008,29 @@ class TEDPolicy(Policy):
994
1008
  model_path: Path where model is to be persisted.
995
1009
  """
996
1010
  tf_model_file = model_path / f"{cls._metadata_filename()}.tf_model"
997
- loaded_data = rasa.utils.io.pickle_load(
998
- model_path / f"{cls._metadata_filename()}.data_example.pkl"
1011
+
1012
+ # load data example
1013
+ loaded_data = deserialize_nested_feature_arrays(
1014
+ str(model_path / f"{cls._metadata_filename()}.data_example.st"),
1015
+ str(model_path / f"{cls._metadata_filename()}.data_example_metadata.json"),
999
1016
  )
1000
- label_data = rasa.utils.io.pickle_load(
1001
- model_path / f"{cls._metadata_filename()}.label_data.pkl"
1017
+ # load label data
1018
+ loaded_label_data = deserialize_nested_feature_arrays(
1019
+ str(model_path / f"{cls._metadata_filename()}.label_data.st"),
1020
+ str(model_path / f"{cls._metadata_filename()}.label_data_metadata.json"),
1002
1021
  )
1003
- fake_features = rasa.utils.io.pickle_load(
1004
- model_path / f"{cls._metadata_filename()}.fake_features.pkl"
1022
+ label_data = RasaModelData(data=loaded_label_data)
1023
+
1024
+ # load fake features
1025
+ metadata = rasa.shared.utils.io.read_json_file(
1026
+ model_path / f"{cls._metadata_filename()}.fake_features_metadata.json"
1005
1027
  )
1006
- label_data = RasaModelData(data=label_data)
1007
- priority = rasa.utils.io.json_unpickle(
1008
- model_path / f"{cls._metadata_filename()}.priority.pkl"
1028
+ fake_features = load_features(
1029
+ str(model_path / f"{cls._metadata_filename()}.fake_features.st"), metadata
1030
+ )
1031
+
1032
+ priority = rasa.shared.utils.io.read_json_file(
1033
+ model_path / f"{cls._metadata_filename()}.priority.json"
1009
1034
  )
1010
1035
  entity_tag_specs = rasa.shared.utils.io.read_json_file(
1011
1036
  model_path / f"{cls._metadata_filename()}.entity_tag_specs.json"
@@ -1023,8 +1048,8 @@ class TEDPolicy(Policy):
1023
1048
  )
1024
1049
  for tag_spec in entity_tag_specs
1025
1050
  ]
1026
- model_config = rasa.utils.io.pickle_load(
1027
- model_path / f"{cls._metadata_filename()}.meta.pkl"
1051
+ model_config = rasa.shared.utils.io.read_json_file(
1052
+ model_path / f"{cls._metadata_filename()}.meta.json"
1028
1053
  )
1029
1054
 
1030
1055
  return {
@@ -1070,7 +1095,7 @@ class TEDPolicy(Policy):
1070
1095
  ) -> TEDPolicy:
1071
1096
  featurizer = TrackerFeaturizer.load(model_path)
1072
1097
 
1073
- if not (model_path / f"{cls._metadata_filename()}.data_example.pkl").is_file():
1098
+ if not (model_path / f"{cls._metadata_filename()}.data_example.st").is_file():
1074
1099
  return cls(
1075
1100
  config,
1076
1101
  model_storage,
@@ -5,6 +5,7 @@ from typing import Any, List, Optional, Text, Dict, Type, Union
5
5
 
6
6
  import numpy as np
7
7
  import tensorflow as tf
8
+
8
9
  import rasa.utils.common
9
10
  from rasa.engine.graph import ExecutionContext
10
11
  from rasa.engine.recipes.default_recipe import DefaultV1Recipe
@@ -16,6 +17,7 @@ from rasa.shared.core.domain import Domain
16
17
  from rasa.shared.core.trackers import DialogueStateTracker
17
18
  from rasa.shared.core.constants import SLOTS, ACTIVE_LOOP, ACTION_UNLIKELY_INTENT_NAME
18
19
  from rasa.shared.core.events import UserUttered, ActionExecuted
20
+ import rasa.shared.utils.io
19
21
  from rasa.shared.nlu.constants import (
20
22
  INTENT,
21
23
  TEXT,
@@ -103,8 +105,6 @@ from rasa.utils.tensorflow.constants import (
103
105
  )
104
106
  from rasa.utils.tensorflow import layers
105
107
  from rasa.utils.tensorflow.model_data import RasaModelData, FeatureArray, Data
106
-
107
- import rasa.utils.io as io_utils
108
108
  from rasa.core.exceptions import RasaCoreException
109
109
  from rasa.shared.utils import common
110
110
 
@@ -881,9 +881,12 @@ class UnexpecTEDIntentPolicy(TEDPolicy):
881
881
  model_path: Path where model is to be persisted
882
882
  """
883
883
  super().persist_model_utilities(model_path)
884
- io_utils.pickle_dump(
885
- model_path / f"{self._metadata_filename()}.label_quantiles.pkl",
886
- self.label_quantiles,
884
+
885
+ from safetensors.numpy import save_file
886
+
887
+ save_file(
888
+ {str(k): np.array(v) for k, v in self.label_quantiles.items()},
889
+ model_path / f"{self._metadata_filename()}.label_quantiles.st",
887
890
  )
888
891
 
889
892
  @classmethod
@@ -894,9 +897,14 @@ class UnexpecTEDIntentPolicy(TEDPolicy):
894
897
  model_path: Path where model is to be persisted.
895
898
  """
896
899
  model_utilties = super()._load_model_utilities(model_path)
897
- label_quantiles = io_utils.pickle_load(
898
- model_path / f"{cls._metadata_filename()}.label_quantiles.pkl"
900
+
901
+ from safetensors.numpy import load_file
902
+
903
+ loaded_label_quantiles = load_file(
904
+ model_path / f"{cls._metadata_filename()}.label_quantiles.st"
899
905
  )
906
+ label_quantiles = {int(k): list(v) for k, v in loaded_label_quantiles.items()}
907
+
900
908
  model_utilties.update({"label_quantiles": label_quantiles})
901
909
  return model_utilties
902
910
 
rasa/core/processor.py CHANGED
@@ -46,12 +46,15 @@ from rasa.engine.runner.interface import GraphRunner
46
46
  from rasa.exceptions import ActionLimitReached, ModelNotFound
47
47
  from rasa.shared.core.constants import (
48
48
  ACTION_CORRECT_FLOW_SLOT,
49
+ SLOT_CONSECUTIVE_SILENCE_TIMEOUTS,
50
+ SLOT_SILENCE_TIMEOUT,
49
51
  USER_INTENT_RESTART,
50
52
  ACTION_LISTEN_NAME,
51
53
  ACTION_SESSION_START_NAME,
52
54
  FOLLOWUP_ACTION,
53
55
  SESSION_START_METADATA_SLOT,
54
56
  ACTION_EXTRACT_SLOTS,
57
+ USER_INTENT_SILENCE_TIMEOUT,
55
58
  )
56
59
  from rasa.shared.core.events import (
57
60
  ActionExecutionRejected,
@@ -789,6 +792,28 @@ class MessageProcessor:
789
792
  )
790
793
 
791
794
  self._check_for_unseen_features(parse_data)
795
+ # resetting timeouts variables whenever something that is not a timeout occurs
796
+ if (
797
+ parse_data.get(INTENT, {}).get(INTENT_NAME_KEY)
798
+ != USER_INTENT_SILENCE_TIMEOUT
799
+ and tracker
800
+ ):
801
+ if (
802
+ SLOT_CONSECUTIVE_SILENCE_TIMEOUTS in tracker.slots
803
+ and tracker.slots[SLOT_CONSECUTIVE_SILENCE_TIMEOUTS].value != 0.0
804
+ ):
805
+ tracker.update(SlotSet(SLOT_CONSECUTIVE_SILENCE_TIMEOUTS, 0.0))
806
+ if (
807
+ SLOT_SILENCE_TIMEOUT in tracker.slots
808
+ and tracker.slots[SLOT_SILENCE_TIMEOUT].value
809
+ != tracker.slots[SLOT_SILENCE_TIMEOUT].initial_value
810
+ ):
811
+ tracker.update(
812
+ SlotSet(
813
+ SLOT_SILENCE_TIMEOUT,
814
+ tracker.slots[SLOT_SILENCE_TIMEOUT].initial_value,
815
+ )
816
+ )
792
817
 
793
818
  return parse_data
794
819
 
@@ -20,25 +20,41 @@ from typing import (
20
20
  cast,
21
21
  )
22
22
 
23
+ import numpy as np
24
+ import questionary
25
+ import terminaltables.width_and_alignment
26
+ from aiohttp import ClientError
27
+ from colorclass import Color
28
+ from questionary import Choice, Form, Question
23
29
  from sanic import Sanic, response
24
30
  from sanic.exceptions import NotFound
25
31
  from sanic.request import Request
26
32
  from sanic.response import HTTPResponse
27
33
  from terminaltables import AsciiTable, SingleTable
28
- import terminaltables.width_and_alignment
29
- import numpy as np
30
- from aiohttp import ClientError
31
- from colorclass import Color
32
- import questionary
33
- from questionary import Choice, Form, Question
34
34
 
35
- from rasa import telemetry
36
- import rasa.shared.utils.cli
37
- import rasa.shared.utils.io
38
35
  import rasa.cli.utils
36
+ import rasa.core.train
37
+ import rasa.shared.core.events
39
38
  import rasa.shared.data
40
- from rasa.shared.nlu.constants import TEXT, INTENT_NAME_KEY
41
- from rasa.shared.nlu.training_data.loading import RASA, RASA_YAML
39
+ import rasa.shared.utils.cli
40
+ import rasa.shared.utils.io
41
+
42
+ # WARNING: This command line UI is using an external library
43
+ # communicating with the shell - these functions are hard to test
44
+ # automatically. If you change anything in here, please make sure to
45
+ # run the interactive learning and check if your part of the "ui"
46
+ # still works.
47
+ import rasa.utils.io as io_utils
48
+ from rasa import telemetry
49
+ from rasa.core import run, utils
50
+ from rasa.core.constants import DEFAULT_SERVER_FORMAT, DEFAULT_SERVER_PORT
51
+ from rasa.core.utils import AvailableEndpoints
52
+ from rasa.shared.constants import (
53
+ INTENT_MESSAGE_PREFIX,
54
+ DEFAULT_SENDER_ID,
55
+ UTTER_PREFIX,
56
+ DOCS_URL_NLU_BASED_POLICIES,
57
+ )
42
58
  from rasa.shared.core.constants import (
43
59
  USER_INTENT_RESTART,
44
60
  ACTION_LISTEN_NAME,
@@ -49,9 +65,6 @@ from rasa.shared.core.constants import (
49
65
  LOOP_INTERRUPTED,
50
66
  ACTION_UNLIKELY_INTENT_NAME,
51
67
  )
52
- from rasa.core import run, utils
53
- import rasa.core.train
54
- from rasa.core.constants import DEFAULT_SERVER_FORMAT, DEFAULT_SERVER_PORT
55
68
  from rasa.shared.core.domain import (
56
69
  Domain,
57
70
  KEY_INTENTS,
@@ -60,7 +73,6 @@ from rasa.shared.core.domain import (
60
73
  KEY_ACTIONS,
61
74
  KEY_RESPONSES_TEXT,
62
75
  )
63
- import rasa.shared.core.events
64
76
  from rasa.shared.core.events import (
65
77
  ActionExecuted,
66
78
  ActionReverted,
@@ -70,36 +82,23 @@ from rasa.shared.core.events import (
70
82
  UserUttered,
71
83
  UserUtteranceReverted,
72
84
  )
73
- from rasa.shared.constants import (
74
- INTENT_MESSAGE_PREFIX,
75
- DEFAULT_SENDER_ID,
76
- UTTER_PREFIX,
77
- DOCS_URL_NLU_BASED_POLICIES,
78
- )
85
+ from rasa.shared.core.generator import TrackerWithCachedStates
79
86
  from rasa.shared.core.trackers import EventVerbosity, DialogueStateTracker
80
87
  from rasa.shared.core.training_data import visualization
81
88
  from rasa.shared.core.training_data.visualization import (
82
89
  VISUALIZATION_TEMPLATE_PATH,
83
90
  visualize_neighborhood,
84
91
  )
85
- from rasa.core.utils import AvailableEndpoints
86
- from rasa.shared.importers.rasa import TrainingDataImporter
87
- from rasa.utils.common import update_sanic_log_level
88
- from rasa.utils.endpoints import EndpointConfig
89
92
  from rasa.shared.exceptions import InvalidConfigException
93
+ from rasa.shared.importers.rasa import TrainingDataImporter
94
+ from rasa.shared.nlu.constants import TEXT, INTENT_NAME_KEY
90
95
 
91
96
  # noinspection PyProtectedMember
92
97
  from rasa.shared.nlu.training_data import loading
98
+ from rasa.shared.nlu.training_data.loading import RASA, RASA_YAML
93
99
  from rasa.shared.nlu.training_data.message import Message
94
-
95
- # WARNING: This command line UI is using an external library
96
- # communicating with the shell - these functions are hard to test
97
- # automatically. If you change anything in here, please make sure to
98
- # run the interactive learning and check if your part of the "ui"
99
- # still works.
100
- import rasa.utils.io as io_utils
101
-
102
- from rasa.shared.core.generator import TrackerWithCachedStates
100
+ from rasa.utils.common import update_sanic_log_level
101
+ from rasa.utils.endpoints import EndpointConfig
103
102
 
104
103
  logger = logging.getLogger(__name__)
105
104
 
@@ -1688,7 +1687,7 @@ def run_interactive_learning(
1688
1687
  p = None
1689
1688
 
1690
1689
  app = run.configure_app(port=port, conversation_id="default", enable_api=True)
1691
- endpoints = AvailableEndpoints.read_endpoints(server_args.get("endpoints"))
1690
+ endpoints = AvailableEndpoints.get_instance(server_args.get("endpoints"))
1692
1691
 
1693
1692
  # before_server_start handlers make sure the agent is loaded before the
1694
1693
  # interactive learning IO starts
rasa/core/utils.py CHANGED
@@ -309,7 +309,7 @@ def number_of_sanic_workers(lock_store: Union[EndpointConfig, LockStore, None])
309
309
  return _log_and_get_default_number_of_workers()
310
310
 
311
311
  if env_value < 1:
312
- structlogger.debug(
312
+ structlogger.warning(
313
313
  "server.worker.set_count.error_less_than_one",
314
314
  number_of_workers=env_value,
315
315
  event_info=f"Cannot set number of Sanic workers to the desired value "
@@ -318,14 +318,19 @@ def number_of_sanic_workers(lock_store: Union[EndpointConfig, LockStore, None])
318
318
  return _log_and_get_default_number_of_workers()
319
319
 
320
320
  if _lock_store_is_multi_worker_compatible(lock_store):
321
- structlogger.debug(f"Using {env_value} Sanic workers.")
321
+ structlogger.debug(
322
+ "server.worker.set_count.success",
323
+ event_info=f"Using {env_value} Sanic workers.",
324
+ num_workers=env_value,
325
+ )
322
326
  return env_value
323
327
 
324
- structlogger.debug(
328
+ structlogger.warning(
325
329
  "server.worker.set_count.error_no_lock_store",
326
330
  event_info=f"Unable to assign desired number of Sanic workers ({env_value}) as "
327
331
  f"no `RedisLockStore` or custom `LockStore` endpoint "
328
332
  f"configuration has been found.",
333
+ num_workers=env_value,
329
334
  )
330
335
  return _log_and_get_default_number_of_workers()
331
336
 
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import importlib
4
- import os
5
4
  from typing import Any, Dict, List, Optional
6
5
 
7
6
  import structlog
@@ -16,13 +15,14 @@ from rasa.dialogue_understanding.coexistence.constants import (
16
15
  )
17
16
  from rasa.dialogue_understanding.commands import Command, SetSlotCommand
18
17
  from rasa.dialogue_understanding.commands.noop_command import NoopCommand
19
- from rasa.dialogue_understanding.generator.constants import LLM_CONFIG_KEY
18
+ from rasa.dialogue_understanding.generator.constants import (
19
+ LLM_CONFIG_KEY,
20
+ )
20
21
  from rasa.engine.graph import ExecutionContext, GraphComponent
21
22
  from rasa.engine.recipes.default_recipe import DefaultV1Recipe
22
23
  from rasa.engine.storage.resource import Resource
23
24
  from rasa.engine.storage.storage import ModelStorage
24
25
  from rasa.shared.constants import (
25
- LLM_API_HEALTH_CHECK_ENV_VAR,
26
26
  ROUTE_TO_CALM_SLOT,
27
27
  PROMPT_CONFIG_KEY,
28
28
  PROVIDER_CONFIG_KEY,
@@ -35,12 +35,13 @@ from rasa.shared.exceptions import InvalidConfigException, FileIOException
35
35
  from rasa.shared.nlu.constants import COMMANDS, TEXT
36
36
  from rasa.shared.nlu.training_data.message import Message
37
37
  from rasa.shared.nlu.training_data.training_data import TrainingData
38
+ from rasa.shared.utils.health_check.llm_health_check_mixin import LLMHealthCheckMixin
39
+ from rasa.shared.utils.io import deep_container_fingerprint
38
40
  from rasa.shared.utils.llm import (
39
41
  DEFAULT_OPENAI_CHAT_MODEL_NAME,
40
42
  get_prompt_template,
41
- llm_api_health_check,
42
43
  llm_factory,
43
- try_instantiate_llm_client,
44
+ resolve_model_client_config,
44
45
  )
45
46
  from rasa.utils.log_utils import log_llm
46
47
 
@@ -48,6 +49,7 @@ LLM_BASED_ROUTER_PROMPT_FILE_NAME = "llm_based_router_prompt.jinja2"
48
49
  DEFAULT_COMMAND_PROMPT_TEMPLATE = importlib.resources.read_text(
49
50
  "rasa.dialogue_understanding.coexistence", "router_template.jinja2"
50
51
  )
52
+ LLM_BASED_ROUTER_CONFIG_FILE_NAME = "config.json"
51
53
 
52
54
  # Token ids for gpt 3.5 and gpt 4 corresponding to space + capitalized Letter
53
55
  A_TO_C_TOKEN_IDS_CHATGPT = [
@@ -74,7 +76,7 @@ structlogger = structlog.get_logger()
74
76
  ],
75
77
  is_trainable=True,
76
78
  )
77
- class LLMBasedRouter(GraphComponent):
79
+ class LLMBasedRouter(LLMHealthCheckMixin, GraphComponent):
78
80
  @staticmethod
79
81
  def get_default_config() -> Dict[str, Any]:
80
82
  """The component's default config (see parent class for full docstring)."""
@@ -96,6 +98,9 @@ class LLMBasedRouter(GraphComponent):
96
98
  prompt_template: Optional[str] = None,
97
99
  ) -> None:
98
100
  self.config = {**self.get_default_config(), **config}
101
+ self.config[LLM_CONFIG_KEY] = resolve_model_client_config(
102
+ self.config.get(LLM_CONFIG_KEY), LLMBasedRouter.__name__
103
+ )
99
104
 
100
105
  self.prompt_template = (
101
106
  prompt_template
@@ -129,20 +134,18 @@ class LLMBasedRouter(GraphComponent):
129
134
  rasa.shared.utils.io.write_text_file(
130
135
  self.prompt_template, path / LLM_BASED_ROUTER_PROMPT_FILE_NAME
131
136
  )
137
+ rasa.shared.utils.io.dump_obj_as_json_to_file(
138
+ path / LLM_BASED_ROUTER_CONFIG_FILE_NAME, self.config
139
+ )
132
140
 
133
141
  def train(self, training_data: TrainingData) -> Resource:
134
142
  """Train the intent classifier on a data set."""
135
- # Validate llm configuration
136
- llm_client = try_instantiate_llm_client(
143
+ self.perform_llm_health_check(
137
144
  self.config.get(LLM_CONFIG_KEY),
138
145
  DEFAULT_LLM_CONFIG,
139
146
  "llm_based_router.train",
140
147
  LLMBasedRouter.__name__,
141
148
  )
142
- if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
143
- llm_api_health_check(
144
- llm_client, "llm_based_router.train", LLMBasedRouter.__name__
145
- )
146
149
 
147
150
  self.persist()
148
151
  return self._resource
@@ -157,6 +160,16 @@ class LLMBasedRouter(GraphComponent):
157
160
  **kwargs: Any,
158
161
  ) -> "LLMBasedRouter":
159
162
  """Loads trained component (see parent class for full docstring)."""
163
+
164
+ # Perform health check on the resolved LLM client config
165
+ llm_config = resolve_model_client_config(config.get(LLM_CONFIG_KEY, {}))
166
+ cls.perform_llm_health_check(
167
+ llm_config,
168
+ DEFAULT_LLM_CONFIG,
169
+ "llm_based_router.load",
170
+ LLMBasedRouter.__name__,
171
+ )
172
+
160
173
  prompt_template = None
161
174
  try:
162
175
  with model_storage.read_from(resource) as path:
@@ -298,3 +311,17 @@ class LLMBasedRouter(GraphComponent):
298
311
  # we have to catch all exceptions here
299
312
  structlogger.error("llm_based_router.llm.error", error=e)
300
313
  return None
314
+
315
+ @classmethod
316
+ def fingerprint_addon(cls, config: Dict[str, Any]) -> Optional[str]:
317
+ """Add a fingerprint of llm based router for the graph."""
318
+ prompt_template = get_prompt_template(
319
+ config.get(PROMPT_CONFIG_KEY),
320
+ DEFAULT_COMMAND_PROMPT_TEMPLATE,
321
+ )
322
+
323
+ llm_config = resolve_model_client_config(
324
+ config.get(LLM_CONFIG_KEY), LLMBasedRouter.__name__
325
+ )
326
+
327
+ return deep_container_fingerprint([prompt_template, llm_config])
@@ -36,3 +36,9 @@ class ChangeFlowCommand(Command):
36
36
  # the change flow command is not actually pushing anything to the tracker,
37
37
  # but it is predicted by the MultiStepLLMCommandGenerator and used internally
38
38
  return []
39
+
40
+ def __eq__(self, other: Any) -> bool:
41
+ return isinstance(other, ChangeFlowCommand)
42
+
43
+ def __hash__(self) -> int:
44
+ return hash(self.command())
@@ -0,0 +1,59 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, Dict, List
5
+ from rasa.dialogue_understanding.commands import Command
6
+ from rasa.dialogue_understanding.patterns.user_silence import (
7
+ UserSilencePatternFlowStackFrame,
8
+ )
9
+ from rasa.shared.core.events import Event
10
+ from rasa.shared.core.flows import FlowsList
11
+ from rasa.shared.core.trackers import DialogueStateTracker
12
+
13
+
14
+ @dataclass
15
+ class UserSilenceCommand(Command):
16
+ """A command to indicate user silence."""
17
+
18
+ @classmethod
19
+ def command(cls) -> str:
20
+ """Returns the command type."""
21
+ return "user silence"
22
+
23
+ @classmethod
24
+ def from_dict(cls, data: Dict[str, Any]) -> UserSilenceCommand:
25
+ """Converts the dictionary to a command.
26
+
27
+ Returns:
28
+ The converted dictionary.
29
+ """
30
+ return UserSilenceCommand()
31
+
32
+ def run_command_on_tracker(
33
+ self,
34
+ tracker: DialogueStateTracker,
35
+ all_flows: FlowsList,
36
+ original_tracker: DialogueStateTracker,
37
+ ) -> List[Event]:
38
+ """Runs the command on the tracker.
39
+
40
+ Args:
41
+ tracker: The tracker to run the command on.
42
+ all_flows: All flows in the assistant.
43
+ original_tracker: The tracker before any command was executed.
44
+
45
+ Returns:
46
+ The events to apply to the tracker.
47
+ """
48
+ stack = tracker.stack
49
+ stack.push(UserSilencePatternFlowStackFrame())
50
+ return tracker.create_stack_updated_events(stack)
51
+
52
+ def __hash__(self) -> int:
53
+ return hash(self.command())
54
+
55
+ def __eq__(self, other: object) -> bool:
56
+ if not isinstance(other, UserSilenceCommand):
57
+ return False
58
+
59
+ return True
@@ -11,6 +11,7 @@ from rasa.dialogue_understanding.commands import (
11
11
  SkipQuestionCommand,
12
12
  RestartCommand,
13
13
  )
14
+ from rasa.dialogue_understanding.commands.user_silence_command import UserSilenceCommand
14
15
  from rasa.dialogue_understanding.patterns.cancel import CancelPatternFlowStackFrame
15
16
  from rasa.dialogue_understanding.patterns.cannot_handle import (
16
17
  CannotHandlePatternFlowStackFrame,
@@ -27,9 +28,13 @@ from rasa.dialogue_understanding.patterns.session_start import (
27
28
  from rasa.dialogue_understanding.patterns.skip_question import (
28
29
  SkipQuestionPatternFlowStackFrame,
29
30
  )
31
+ from rasa.dialogue_understanding.patterns.user_silence import (
32
+ UserSilencePatternFlowStackFrame,
33
+ )
30
34
 
31
35
  triggerable_pattern_to_command_class: Dict[str, Type[Command]] = {
32
36
  SessionStartPatternFlowStackFrame.flow_id: SessionStartCommand,
37
+ UserSilencePatternFlowStackFrame.flow_id: UserSilenceCommand,
33
38
  CancelPatternFlowStackFrame.flow_id: CancelFlowCommand,
34
39
  ChitchatPatternFlowStackFrame.flow_id: ChitChatAnswerCommand,
35
40
  HumanHandoffPatternFlowStackFrame.flow_id: HumanHandoffCommand,
@@ -23,3 +23,5 @@ USER_INPUT_CONFIG_KEY = "user_input"
23
23
  FLOW_RETRIEVAL_KEY = "flow_retrieval"
24
24
  FLOW_RETRIEVAL_ACTIVE_KEY = "active"
25
25
  FLOW_RETRIEVAL_EMBEDDINGS_CONFIG_KEY = "embeddings"
26
+
27
+ FLOW_RETRIEVAL_FLOW_THRESHOLD = 20