rasa-pro 3.11.0__py3-none-any.whl → 3.11.0a2__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 (217) hide show
  1. README.md +396 -17
  2. rasa/__main__.py +15 -31
  3. rasa/api.py +1 -5
  4. rasa/cli/arguments/default_arguments.py +2 -1
  5. rasa/cli/arguments/shell.py +1 -5
  6. rasa/cli/arguments/train.py +0 -14
  7. rasa/cli/e2e_test.py +1 -1
  8. rasa/cli/evaluate.py +8 -8
  9. rasa/cli/inspect.py +5 -7
  10. rasa/cli/interactive.py +0 -1
  11. rasa/cli/llm_fine_tuning.py +1 -1
  12. rasa/cli/project_templates/calm/config.yml +7 -5
  13. rasa/cli/project_templates/calm/endpoints.yml +2 -15
  14. rasa/cli/project_templates/tutorial/config.yml +5 -8
  15. rasa/cli/project_templates/tutorial/data/flows.yml +1 -1
  16. rasa/cli/project_templates/tutorial/data/patterns.yml +0 -5
  17. rasa/cli/project_templates/tutorial/domain.yml +0 -14
  18. rasa/cli/project_templates/tutorial/endpoints.yml +0 -5
  19. rasa/cli/run.py +1 -1
  20. rasa/cli/scaffold.py +2 -4
  21. rasa/cli/studio/studio.py +8 -18
  22. rasa/cli/studio/upload.py +15 -0
  23. rasa/cli/train.py +0 -3
  24. rasa/cli/utils.py +1 -6
  25. rasa/cli/x.py +8 -8
  26. rasa/constants.py +1 -3
  27. rasa/core/actions/action.py +33 -75
  28. rasa/core/actions/e2e_stub_custom_action_executor.py +1 -5
  29. rasa/core/actions/http_custom_action_executor.py +0 -4
  30. rasa/core/channels/channel.py +0 -20
  31. rasa/core/channels/development_inspector.py +2 -8
  32. rasa/core/channels/inspector/dist/assets/{arc-bc141fb2.js → arc-6852c607.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-be2db283.js → c4Diagram-d0fbc5ce-acc952b2.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-55366915.js → classDiagram-936ed81e-848a7597.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-bb529518.js → classDiagram-v2-c3cb15f1-a73d3e68.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-b0ec81d6.js → createText-62fc7601-e5ee049d.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-6166330c.js → edges-f2ad444c-771e517e.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-5ccc6a8e.js → erDiagram-9d236eb7-aa347178.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-fca3bfe4.js → flowDb-1972c806-651fc57d.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4739080f.js → flowDiagram-7ea5b25a-ca67804f.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-587d82d8.js +1 -0
  42. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-7c1b0e0f.js → flowchart-elk-definition-abe16c3d-2dbc568d.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-772fd050.js → ganttDiagram-9b5ea136-25a65bd8.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-8eae1dc9.js → gitGraphDiagram-99d0ae7c-fdc7378d.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-f55afcdf.js → index-2c4b9a3b-6f1fd606.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{index-e7cef9de.js → index-efdd30c1.js} +68 -68
  47. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-124d4a14.js → infoDiagram-736b4530-cb1a041a.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-7c4fae44.js → journeyDiagram-df861f2b-14609879.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{layout-b9885fb6.js → layout-2490f52b.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{line-7c59abb6.js → line-40186f1f.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{linear-4776f780.js → linear-08814e93.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2332c46c.js → mindmap-definition-beec6740-1a534584.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-8fb39303.js → pieDiagram-dbbf0591-72397b61.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-3c7180a2.js → quadrantDiagram-4d7f4fd6-3bb0b6a3.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-e910bcb8.js → requirementDiagram-6fc4c22a-57334f61.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-ead16c89.js → sankeyDiagram-8f13d901-111e1297.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-29a02a19.js → sequenceDiagram-b655622a-10bcfe62.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-042b3137.js → stateDiagram-59f0c015-acaf7513.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-2178c0f3.js → stateDiagram-v2-2b26beab-3ec2a235.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-23ffa4fc.js → styles-080da4f6-62730289.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-94f59763.js → styles-3dcbcfbf-5284ee76.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-78a6bebc.js → styles-9c745c82-642435e3.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-eae2a6f6.js → svgDrawCommon-4835440b-b250a350.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-5c968d92.js → timeline-definition-5b62e21b-c2b147ed.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-fd3db0d5.js → xychartDiagram-2b33534f-f92cfea9.js} +1 -1
  66. rasa/core/channels/inspector/dist/index.html +1 -1
  67. rasa/core/channels/inspector/src/App.tsx +1 -1
  68. rasa/core/channels/inspector/src/helpers/audiostream.ts +16 -77
  69. rasa/core/channels/socketio.py +2 -7
  70. rasa/core/channels/telegram.py +1 -1
  71. rasa/core/channels/twilio.py +1 -1
  72. rasa/core/channels/voice_ready/audiocodes.py +4 -15
  73. rasa/core/channels/voice_ready/jambonz.py +4 -15
  74. rasa/core/channels/voice_ready/twilio_voice.py +21 -6
  75. rasa/core/channels/voice_ready/utils.py +5 -6
  76. rasa/core/channels/voice_stream/asr/asr_engine.py +1 -19
  77. rasa/core/channels/voice_stream/asr/asr_event.py +0 -5
  78. rasa/core/channels/voice_stream/asr/deepgram.py +15 -28
  79. rasa/core/channels/voice_stream/audio_bytes.py +0 -1
  80. rasa/core/channels/voice_stream/browser_audio.py +9 -32
  81. rasa/core/channels/voice_stream/tts/azure.py +3 -9
  82. rasa/core/channels/voice_stream/tts/cartesia.py +8 -12
  83. rasa/core/channels/voice_stream/tts/tts_engine.py +1 -11
  84. rasa/core/channels/voice_stream/twilio_media_streams.py +19 -28
  85. rasa/core/channels/voice_stream/util.py +4 -4
  86. rasa/core/channels/voice_stream/voice_channel.py +42 -222
  87. rasa/core/featurizers/single_state_featurizer.py +1 -22
  88. rasa/core/featurizers/tracker_featurizers.py +18 -115
  89. rasa/core/information_retrieval/qdrant.py +0 -1
  90. rasa/core/nlg/contextual_response_rephraser.py +25 -44
  91. rasa/core/persistor.py +34 -191
  92. rasa/core/policies/enterprise_search_policy.py +60 -119
  93. rasa/core/policies/flows/flow_executor.py +4 -7
  94. rasa/core/policies/intentless_policy.py +22 -82
  95. rasa/core/policies/ted_policy.py +33 -58
  96. rasa/core/policies/unexpected_intent_policy.py +7 -15
  97. rasa/core/processor.py +5 -32
  98. rasa/core/training/interactive.py +35 -34
  99. rasa/core/utils.py +22 -58
  100. rasa/dialogue_understanding/coexistence/llm_based_router.py +12 -39
  101. rasa/dialogue_understanding/commands/__init__.py +0 -4
  102. rasa/dialogue_understanding/commands/change_flow_command.py +0 -6
  103. rasa/dialogue_understanding/commands/utils.py +0 -5
  104. rasa/dialogue_understanding/generator/constants.py +0 -2
  105. rasa/dialogue_understanding/generator/flow_retrieval.py +4 -49
  106. rasa/dialogue_understanding/generator/llm_based_command_generator.py +23 -37
  107. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +10 -57
  108. rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -19
  109. rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +0 -3
  110. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +10 -90
  111. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +0 -53
  112. rasa/dialogue_understanding/processor/command_processor.py +1 -21
  113. rasa/e2e_test/assertions.py +16 -133
  114. rasa/e2e_test/assertions_schema.yml +0 -23
  115. rasa/e2e_test/e2e_test_case.py +6 -85
  116. rasa/e2e_test/e2e_test_runner.py +4 -6
  117. rasa/e2e_test/utils/io.py +1 -3
  118. rasa/engine/loader.py +0 -12
  119. rasa/engine/validation.py +11 -541
  120. rasa/keys +1 -0
  121. rasa/llm_fine_tuning/notebooks/unsloth_finetuning.ipynb +407 -0
  122. rasa/model_training.py +7 -29
  123. rasa/nlu/classifiers/diet_classifier.py +25 -38
  124. rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
  125. rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
  126. rasa/nlu/extractors/crf_entity_extractor.py +50 -93
  127. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +16 -45
  128. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +17 -52
  129. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
  130. rasa/nlu/tokenizers/whitespace_tokenizer.py +14 -3
  131. rasa/server.py +1 -3
  132. rasa/shared/constants.py +0 -61
  133. rasa/shared/core/constants.py +0 -9
  134. rasa/shared/core/domain.py +5 -8
  135. rasa/shared/core/flows/flow.py +0 -5
  136. rasa/shared/core/flows/flows_list.py +1 -5
  137. rasa/shared/core/flows/flows_yaml_schema.json +0 -10
  138. rasa/shared/core/flows/validation.py +0 -96
  139. rasa/shared/core/flows/yaml_flows_io.py +4 -13
  140. rasa/shared/core/slots.py +0 -5
  141. rasa/shared/importers/importer.py +2 -19
  142. rasa/shared/importers/rasa.py +1 -5
  143. rasa/shared/nlu/training_data/features.py +2 -120
  144. rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -18
  145. rasa/shared/providers/_configs/azure_openai_client_config.py +3 -5
  146. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  147. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +0 -1
  148. rasa/shared/providers/_configs/utils.py +0 -16
  149. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +29 -18
  150. rasa/shared/providers/embedding/azure_openai_embedding_client.py +21 -54
  151. rasa/shared/providers/embedding/default_litellm_embedding_client.py +0 -24
  152. rasa/shared/providers/llm/_base_litellm_client.py +31 -63
  153. rasa/shared/providers/llm/azure_openai_llm_client.py +29 -50
  154. rasa/shared/providers/llm/default_litellm_llm_client.py +0 -24
  155. rasa/shared/providers/llm/self_hosted_llm_client.py +29 -17
  156. rasa/shared/providers/mappings.py +0 -19
  157. rasa/shared/utils/common.py +2 -37
  158. rasa/shared/utils/io.py +6 -28
  159. rasa/shared/utils/llm.py +46 -353
  160. rasa/shared/utils/yaml.py +82 -181
  161. rasa/studio/auth.py +5 -3
  162. rasa/studio/config.py +4 -13
  163. rasa/studio/constants.py +0 -1
  164. rasa/studio/data_handler.py +4 -13
  165. rasa/studio/upload.py +80 -175
  166. rasa/telemetry.py +17 -94
  167. rasa/tracing/config.py +1 -3
  168. rasa/tracing/instrumentation/attribute_extractors.py +17 -94
  169. rasa/tracing/instrumentation/instrumentation.py +0 -121
  170. rasa/utils/common.py +0 -5
  171. rasa/utils/endpoints.py +1 -27
  172. rasa/utils/io.py +81 -7
  173. rasa/utils/log_utils.py +2 -9
  174. rasa/utils/tensorflow/model_data.py +193 -2
  175. rasa/validator.py +4 -110
  176. rasa/version.py +1 -1
  177. rasa_pro-3.11.0a2.dist-info/METADATA +576 -0
  178. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/RECORD +181 -213
  179. rasa/core/actions/action_repeat_bot_messages.py +0 -89
  180. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +0 -1
  181. rasa/core/channels/voice_stream/asr/azure.py +0 -129
  182. rasa/core/channels/voice_stream/call_state.py +0 -23
  183. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +0 -60
  184. rasa/dialogue_understanding/commands/user_silence_command.py +0 -59
  185. rasa/dialogue_understanding/patterns/repeat.py +0 -37
  186. rasa/dialogue_understanding/patterns/user_silence.py +0 -37
  187. rasa/model_manager/__init__.py +0 -0
  188. rasa/model_manager/config.py +0 -40
  189. rasa/model_manager/model_api.py +0 -559
  190. rasa/model_manager/runner_service.py +0 -286
  191. rasa/model_manager/socket_bridge.py +0 -146
  192. rasa/model_manager/studio_jwt_auth.py +0 -86
  193. rasa/model_manager/trainer_service.py +0 -325
  194. rasa/model_manager/utils.py +0 -87
  195. rasa/model_manager/warm_rasa_process.py +0 -187
  196. rasa/model_service.py +0 -112
  197. rasa/shared/core/flows/utils.py +0 -39
  198. rasa/shared/providers/_configs/litellm_router_client_config.py +0 -220
  199. rasa/shared/providers/_configs/model_group_config.py +0 -167
  200. rasa/shared/providers/_configs/rasa_llm_client_config.py +0 -73
  201. rasa/shared/providers/_utils.py +0 -79
  202. rasa/shared/providers/embedding/litellm_router_embedding_client.py +0 -135
  203. rasa/shared/providers/llm/litellm_router_llm_client.py +0 -182
  204. rasa/shared/providers/llm/rasa_llm_client.py +0 -112
  205. rasa/shared/providers/router/__init__.py +0 -0
  206. rasa/shared/providers/router/_base_litellm_router_client.py +0 -183
  207. rasa/shared/providers/router/router_client.py +0 -73
  208. rasa/shared/utils/health_check/__init__.py +0 -0
  209. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +0 -31
  210. rasa/shared/utils/health_check/health_check.py +0 -258
  211. rasa/shared/utils/health_check/llm_health_check_mixin.py +0 -31
  212. rasa/utils/sanic_error_handler.py +0 -32
  213. rasa/utils/tensorflow/feature_array.py +0 -366
  214. rasa_pro-3.11.0.dist-info/METADATA +0 -198
  215. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/NOTICE +0 -0
  216. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/WHEEL +0 -0
  217. {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a2.dist-info}/entry_points.txt +0 -0
@@ -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
6
+
5
7
  from rasa import telemetry
6
8
  from rasa.core.nlg.response import TemplatedNaturalLanguageGenerator
7
- from rasa.core.nlg.summarize import summarize_conversation
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,
@@ -13,25 +15,24 @@ from rasa.shared.constants import (
13
15
  PROVIDER_CONFIG_KEY,
14
16
  OPENAI_PROVIDER,
15
17
  TIMEOUT_CONFIG_KEY,
16
- MODEL_GROUP_ID_CONFIG_KEY,
17
18
  )
18
19
  from rasa.shared.core.domain import KEY_RESPONSES_TEXT, Domain
19
20
  from rasa.shared.core.events import BotUttered, UserUttered
20
21
  from rasa.shared.core.trackers import DialogueStateTracker
21
- from rasa.shared.utils.health_check.llm_health_check_mixin import LLMHealthCheckMixin
22
22
  from rasa.shared.utils.llm import (
23
23
  DEFAULT_OPENAI_GENERATE_MODEL_NAME,
24
24
  DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
25
25
  USER,
26
26
  combine_custom_and_default_config,
27
27
  get_prompt_template,
28
+ llm_api_health_check,
28
29
  llm_factory,
29
- resolve_model_client_config,
30
- )
31
- from rasa.shared.utils.llm import (
32
- tracker_as_readable_transcript,
30
+ try_instantiate_llm_client,
33
31
  )
34
32
  from rasa.utils.endpoints import EndpointConfig
33
+
34
+ from rasa.core.nlg.summarize import summarize_conversation
35
+
35
36
  from rasa.utils.log_utils import log_llm
36
37
 
37
38
  structlogger = structlog.get_logger()
@@ -40,11 +41,7 @@ RESPONSE_REPHRASING_KEY = "rephrase"
40
41
 
41
42
  RESPONSE_REPHRASING_TEMPLATE_KEY = "rephrase_prompt"
42
43
 
43
- RESPONSE_SUMMARISE_CONVERSATION_KEY = "summarize_conversation"
44
-
45
44
  DEFAULT_REPHRASE_ALL = False
46
- DEFAULT_SUMMARIZE_HISTORY = True
47
- DEFAULT_MAX_HISTORICAL_TURNS = 5
48
45
 
49
46
  DEFAULT_LLM_CONFIG = {
50
47
  PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
@@ -69,9 +66,7 @@ Suggested AI Response: {{suggested_response}}
69
66
  Rephrased AI Response:"""
70
67
 
71
68
 
72
- class ContextualResponseRephraser(
73
- LLMHealthCheckMixin, TemplatedNaturalLanguageGenerator
74
- ):
69
+ class ContextualResponseRephraser(TemplatedNaturalLanguageGenerator):
75
70
  """Generates responses based on modified templates.
76
71
 
77
72
  The templates are filled with the entities and slots that are available in the
@@ -105,24 +100,18 @@ class ContextualResponseRephraser(
105
100
  self.trace_prompt_tokens = self.nlg_endpoint.kwargs.get(
106
101
  "trace_prompt_tokens", False
107
102
  )
108
- self.summarize_history = self.nlg_endpoint.kwargs.get(
109
- "summarize_history", DEFAULT_SUMMARIZE_HISTORY
110
- )
111
- self.max_historical_turns = self.nlg_endpoint.kwargs.get(
112
- "max_historical_turns", DEFAULT_MAX_HISTORICAL_TURNS
113
- )
114
-
115
- self.llm_config = resolve_model_client_config(
103
+ llm_client = try_instantiate_llm_client(
116
104
  self.nlg_endpoint.kwargs.get(LLM_CONFIG_KEY),
117
- ContextualResponseRephraser.__name__,
118
- )
119
-
120
- self.perform_llm_health_check(
121
- self.llm_config,
122
105
  DEFAULT_LLM_CONFIG,
123
106
  "contextual_response_rephraser.init",
124
107
  ContextualResponseRephraser.__name__,
125
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
+ )
126
115
 
127
116
  def _last_message_if_human(self, tracker: DialogueStateTracker) -> Optional[str]:
128
117
  """Returns the latest message from the tracker.
@@ -151,7 +140,9 @@ class ContextualResponseRephraser(
151
140
  Returns:
152
141
  generated text
153
142
  """
154
- llm = llm_factory(self.llm_config, DEFAULT_LLM_CONFIG)
143
+ llm = llm_factory(
144
+ self.nlg_endpoint.kwargs.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG
145
+ )
155
146
 
156
147
  try:
157
148
  llm_response = await llm.acompletion(prompt)
@@ -165,7 +156,7 @@ class ContextualResponseRephraser(
165
156
  def llm_property(self, prop: str) -> Optional[str]:
166
157
  """Returns a property of the LLM provider."""
167
158
  return combine_custom_and_default_config(
168
- self.llm_config, DEFAULT_LLM_CONFIG
159
+ self.nlg_endpoint.kwargs.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG
169
160
  ).get(prop)
170
161
 
171
162
  def custom_prompt_template(self, prompt_template: str) -> Optional[str]:
@@ -198,7 +189,9 @@ class ContextualResponseRephraser(
198
189
  Returns:
199
190
  The history for the prompt.
200
191
  """
201
- llm = llm_factory(self.llm_config, DEFAULT_LLM_CONFIG)
192
+ llm = llm_factory(
193
+ self.nlg_endpoint.kwargs.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG
194
+ )
202
195
  return await summarize_conversation(tracker, llm, max_turns=5)
203
196
 
204
197
  async def rephrase(
@@ -219,24 +212,13 @@ class ContextualResponseRephraser(
219
212
  if not (response_text := response.get(KEY_RESPONSES_TEXT)):
220
213
  return response
221
214
 
222
- prompt_template_text = self._template_for_response_rephrasing(response)
223
-
224
- # Retrieve inputs for the dynamic prompt
225
215
  latest_message = self._last_message_if_human(tracker)
226
216
  current_input = f"{USER}: {latest_message}" if latest_message else ""
227
217
 
228
- # Only summarise conversation history if flagged
229
- if self.summarize_history:
230
- history = await self._create_history(tracker)
231
- else:
232
- # make sure the transcript/history contains the last user utterance
233
- max_turns = max(self.max_historical_turns, 1)
234
- history = tracker_as_readable_transcript(tracker, max_turns=max_turns)
235
- # the history already contains the current input
236
- current_input = ""
218
+ prompt_template_text = self._template_for_response_rephrasing(response)
237
219
 
238
220
  prompt = Template(prompt_template_text).render(
239
- history=history,
221
+ history=await self._create_history(tracker),
240
222
  suggested_response=response_text,
241
223
  current_input=current_input,
242
224
  slots=tracker.current_slot_values(),
@@ -253,7 +235,6 @@ class ContextualResponseRephraser(
253
235
  llm_type=self.llm_property(PROVIDER_CONFIG_KEY),
254
236
  llm_model=self.llm_property(MODEL_CONFIG_KEY)
255
237
  or self.llm_property(MODEL_NAME_CONFIG_KEY),
256
- llm_model_group_id=self.llm_property(MODEL_GROUP_ID_CONFIG_KEY),
257
238
  )
258
239
  if not (updated_text := await self._generate_llm_response(prompt)):
259
240
  # If the LLM fails to generate a response, we
rasa/core/persistor.py CHANGED
@@ -4,19 +4,16 @@ import abc
4
4
  import os
5
5
  import shutil
6
6
  from enum import Enum
7
- from pathlib import Path
8
7
  from typing import TYPE_CHECKING, List, Optional, Text, Tuple, Union
9
8
 
10
9
  import structlog
11
10
 
12
- from rasa.exceptions import ModelNotFound
13
11
  import rasa.shared.utils.common
14
12
  import rasa.utils.common
15
13
  from rasa.constants import (
16
14
  HTTP_STATUS_FORBIDDEN,
17
15
  HTTP_STATUS_NOT_FOUND,
18
16
  MODEL_ARCHIVE_EXTENSION,
19
- DEFAULT_BUCKET_NAME,
20
17
  )
21
18
  from rasa.env import (
22
19
  AWS_ENDPOINT_URL_ENV,
@@ -31,7 +28,6 @@ from rasa.shared.utils.io import raise_warning
31
28
 
32
29
  if TYPE_CHECKING:
33
30
  from azure.storage.blob import ContainerClient
34
- from botocore.exceptions import ClientError
35
31
 
36
32
  structlogger = structlog.get_logger()
37
33
 
@@ -90,15 +86,14 @@ def get_persistor(storage: StorageType) -> Optional[Persistor]:
90
86
 
91
87
  if storage == RemoteStorageType.AWS.value:
92
88
  return AWSPersistor(
93
- os.environ.get(BUCKET_NAME_ENV, DEFAULT_BUCKET_NAME),
94
- os.environ.get(AWS_ENDPOINT_URL_ENV),
89
+ os.environ.get(BUCKET_NAME_ENV), os.environ.get(AWS_ENDPOINT_URL_ENV)
95
90
  )
96
91
  if storage == RemoteStorageType.GCS.value:
97
- return GCSPersistor(os.environ.get(BUCKET_NAME_ENV, DEFAULT_BUCKET_NAME))
92
+ return GCSPersistor(os.environ.get(BUCKET_NAME_ENV))
98
93
 
99
94
  if storage == RemoteStorageType.AZURE.value:
100
95
  return AzurePersistor(
101
- os.environ.get(AZURE_CONTAINER_ENV, DEFAULT_BUCKET_NAME),
96
+ os.environ.get(AZURE_CONTAINER_ENV),
102
97
  os.environ.get(AZURE_ACCOUNT_NAME_ENV),
103
98
  os.environ.get(AZURE_ACCOUNT_KEY_ENV),
104
99
  )
@@ -123,8 +118,7 @@ class Persistor(abc.ABC):
123
118
 
124
119
  def persist(self, trained_model: str) -> None:
125
120
  """Uploads a trained model persisted in the `target_dir` to cloud storage."""
126
- absolute_file_key = self._create_file_key(trained_model)
127
- file_key = Path(absolute_file_key).name
121
+ file_key = self._create_file_key(trained_model)
128
122
  self._persist_tar(file_key, trained_model)
129
123
 
130
124
  def retrieve(self, model_name: Text, target_path: Text) -> Text:
@@ -143,8 +137,7 @@ class Persistor(abc.ABC):
143
137
  # ensure backward compatibility
144
138
  tar_name = self._tar_name(model_name)
145
139
  tar_name = self._create_file_key(tar_name)
146
- target_filename = os.path.basename(tar_name)
147
- self._retrieve_tar(target_filename)
140
+ self._retrieve_tar(tar_name)
148
141
  self._copy(os.path.basename(tar_name), target_path)
149
142
 
150
143
  if os.path.isdir(target_path):
@@ -152,36 +145,6 @@ class Persistor(abc.ABC):
152
145
 
153
146
  return target_path
154
147
 
155
- def size_of_persisted_model(self, model_name: Text) -> int:
156
- """Returns the size of the model that has been persisted to cloud storage.
157
-
158
- Args:
159
- model_name: The name of the model to retrieve.
160
- """
161
- tar_name = model_name
162
- if not model_name.endswith(MODEL_ARCHIVE_EXTENSION):
163
- # ensure backward compatibility
164
- tar_name = self._tar_name(model_name)
165
- tar_name = self._create_file_key(tar_name)
166
- target_filename = os.path.basename(tar_name)
167
- return self._retrieve_tar_size(target_filename)
168
-
169
- def _retrieve_tar_size(self, filename: Text) -> int:
170
- """Returns the size of the model that has been persisted to cloud storage."""
171
- structlogger.warning(
172
- "persistor.retrieve_tar_size.not_implemented",
173
- filename=filename,
174
- event_info=(
175
- "This method should be implemented in the persistor. "
176
- "The default implementation will download the model "
177
- "to calculate the size. Most persistors should override "
178
- "this method to avoid downloading the model and get the "
179
- "size directly from the cloud storage."
180
- ),
181
- )
182
- self._retrieve_tar(filename)
183
- return os.path.getsize(os.path.basename(filename))
184
-
185
148
  @abc.abstractmethod
186
149
  def _retrieve_tar(self, filename: Text) -> None:
187
150
  """Downloads a model previously persisted to cloud storage."""
@@ -218,7 +181,7 @@ class Persistor(abc.ABC):
218
181
 
219
182
  @staticmethod
220
183
  def _create_file_key(model_path: str) -> Text:
221
- """Appends remote storage folders when provided to upload or retrieve file."""
184
+ """Appends remote storage folders when provided to upload or retrieve file"""
222
185
  bucket_object_path = os.environ.get(REMOTE_STORAGE_PATH_ENV)
223
186
 
224
187
  # To keep the backward compatibility, if REMOTE_STORAGE_PATH is not provided,
@@ -230,7 +193,10 @@ class Persistor(abc.ABC):
230
193
  f"{REMOTE_STORAGE_PATH_ENV} is deprecated and will be "
231
194
  "removed in future versions. "
232
195
  "Please use the -m path/to/model.tar.gz option to "
233
- "specify the model path when loading a model.",
196
+ "specify the model path when loading a model."
197
+ "Or use --output and --fixed-model-name to specify the "
198
+ "output directory and the model name when saving a "
199
+ "trained model to remote storage.",
234
200
  )
235
201
 
236
202
  file_key = os.path.basename(model_path)
@@ -263,13 +229,14 @@ class AWSPersistor(Persistor):
263
229
  def _ensure_bucket_exists(
264
230
  self, bucket_name: Text, region_name: Optional[Text] = None
265
231
  ) -> None:
266
- from botocore import exceptions
232
+ import botocore
267
233
 
268
234
  # noinspection PyUnresolvedReferences
269
235
  try:
270
236
  self.s3.meta.client.head_bucket(Bucket=bucket_name)
271
- except exceptions.ClientError as exc:
272
- if self._error_code(exc) == HTTP_STATUS_FORBIDDEN:
237
+ except botocore.exceptions.ClientError as e:
238
+ error_code = int(e.response["Error"]["Code"])
239
+ if error_code == HTTP_STATUS_FORBIDDEN:
273
240
  log = (
274
241
  f"Access to the specified bucket '{bucket_name}' is forbidden. "
275
242
  "Please make sure you have the necessary "
@@ -281,7 +248,7 @@ class AWSPersistor(Persistor):
281
248
  event_info=log,
282
249
  )
283
250
  raise RasaException(log)
284
- elif self._error_code(exc) == HTTP_STATUS_NOT_FOUND:
251
+ elif error_code == HTTP_STATUS_NOT_FOUND:
285
252
  log = (
286
253
  f"The specified bucket '{bucket_name}' does not exist. "
287
254
  "Please make sure to create the bucket first."
@@ -293,57 +260,16 @@ class AWSPersistor(Persistor):
293
260
  )
294
261
  raise RasaException(log)
295
262
 
296
- @staticmethod
297
- def _error_code(e: "ClientError") -> int:
298
- return int(e.response["Error"]["Code"])
299
-
300
263
  def _persist_tar(self, file_key: Text, tar_path: Text) -> None:
301
264
  """Uploads a model persisted in the `target_dir` to s3."""
302
265
  with open(tar_path, "rb") as f:
303
266
  self.s3.Object(self.bucket_name, file_key).put(Body=f)
304
267
 
305
- def _retrieve_tar_size(self, model_path: Text) -> int:
306
- """Returns the size of the model that has been persisted to s3."""
307
- try:
308
- obj = self.s3.Object(self.bucket_name, model_path)
309
- return obj.content_length
310
- except Exception:
311
- raise ModelNotFound()
312
-
313
- def _retrieve_tar(self, target_filename: str) -> None:
268
+ def _retrieve_tar(self, model_path: Text) -> None:
314
269
  """Downloads a model that has previously been persisted to s3."""
315
- from botocore import exceptions
316
-
317
- log = (
318
- f"Model '{target_filename}' not found in the specified bucket "
319
- f"'{self.bucket_name}'. Please make sure the model exists "
320
- f"in the bucket."
321
- )
322
-
323
- try:
324
- with open(target_filename, "wb") as f:
325
- self.bucket.download_fileobj(target_filename, f)
326
-
327
- structlogger.debug(
328
- "aws_persistor.retrieve_tar.object_found", object_key=target_filename
329
- )
330
- except exceptions.ClientError as exc:
331
- if self._error_code(exc) == HTTP_STATUS_NOT_FOUND:
332
- structlogger.error(
333
- "aws_persistor.retrieve_tar.model_not_found",
334
- bucket_name=self.bucket_name,
335
- target_filename=target_filename,
336
- event_info=log,
337
- )
338
- raise ModelNotFound() from exc
339
- except exceptions.BotoCoreError as exc:
340
- structlogger.error(
341
- "aws_persistor.retrieve_tar.model_download_error",
342
- bucket_name=self.bucket_name,
343
- target_filename=target_filename,
344
- event_info=log,
345
- )
346
- raise ModelNotFound() from exc
270
+ tar_name = os.path.basename(model_path)
271
+ with open(tar_name, "wb") as f:
272
+ self.bucket.download_fileobj(model_path, f)
347
273
 
348
274
 
349
275
  class GCSPersistor(Persistor):
@@ -368,95 +294,42 @@ class GCSPersistor(Persistor):
368
294
 
369
295
  def _ensure_bucket_exists(self, bucket_name: Text) -> None:
370
296
  from google.cloud import exceptions
371
- from google.auth import exceptions as auth_exceptions
372
297
 
373
298
  try:
374
299
  self.storage_client.get_bucket(bucket_name)
375
- except auth_exceptions.GoogleAuthError as exc:
300
+ except exceptions.NotFound:
376
301
  log = (
377
- f"An error occurred while authenticating with Google Cloud "
378
- f"Storage. Please make sure you have the necessary credentials "
379
- f"to access the bucket '{bucket_name}'."
380
- )
381
- structlogger.error(
382
- "gcp_persistor.ensure_bucket_exists.authentication_error",
383
- bucket_name=bucket_name,
384
- event_info=log,
385
- )
386
- raise RasaException(log) from exc
387
- except exceptions.NotFound as exc:
388
- log = (
389
- f"The specified Google Cloud Storage bucket '{bucket_name}' "
390
- f"does not exist. Please make sure to create the bucket first or "
391
- f"provide an alternative valid bucket name."
302
+ f"The specified bucket '{bucket_name}' does not exist. "
303
+ "Please make sure to create the bucket first."
392
304
  )
393
305
  structlogger.error(
394
306
  "gcp_persistor.ensure_bucket_exists.bucket_not_found",
395
307
  bucket_name=bucket_name,
396
308
  event_info=log,
397
309
  )
398
- raise RasaException(log) from exc
399
- except exceptions.Forbidden as exc:
310
+ raise RasaException(log)
311
+ except exceptions.Forbidden:
400
312
  log = (
401
- f"Access to the specified Google Cloud storage bucket '{bucket_name}' "
402
- f"is forbidden. Please make sure you have the necessary "
403
- f"permissions to access the bucket. "
313
+ f"Access to the specified bucket '{bucket_name}' is forbidden. "
314
+ "Please make sure you have the necessary "
315
+ "permission to access the bucket. "
404
316
  )
405
317
  structlogger.error(
406
318
  "gcp_persistor.ensure_bucket_exists.bucket_access_forbidden",
407
319
  bucket_name=bucket_name,
408
320
  event_info=log,
409
321
  )
410
- raise RasaException(log) from exc
411
- except ValueError as exc:
412
- # bucket_name is None
413
- log = (
414
- "The specified Google Cloud Storage bucket name is None. Please "
415
- "make sure to provide a valid bucket name."
416
- )
417
- structlogger.error(
418
- "gcp_persistor.ensure_bucket_exists.bucket_name_none",
419
- event_info=log,
420
- )
421
- raise RasaException(log) from exc
322
+ raise RasaException(log)
422
323
 
423
324
  def _persist_tar(self, file_key: Text, tar_path: Text) -> None:
424
325
  """Uploads a model persisted in the `target_dir` to GCS."""
425
326
  blob = self.bucket.blob(file_key)
426
327
  blob.upload_from_filename(tar_path)
427
328
 
428
- def _retrieve_tar_size(self, target_filename: Text) -> int:
429
- """Returns the size of the model that has been persisted to GCS."""
430
- try:
431
- blob = self.bucket.blob(target_filename)
432
- return blob.size
433
- except Exception:
434
- raise ModelNotFound()
435
-
436
329
  def _retrieve_tar(self, target_filename: Text) -> None:
437
330
  """Downloads a model that has previously been persisted to GCS."""
438
- from google.api_core import exceptions
439
-
440
331
  blob = self.bucket.blob(target_filename)
441
- try:
442
- blob.download_to_filename(target_filename)
443
-
444
- structlogger.debug(
445
- "gcs_persistor.retrieve_tar.object_found", object_key=target_filename
446
- )
447
- except exceptions.NotFound as exc:
448
- log = (
449
- f"Model '{target_filename}' not found in the specified bucket "
450
- f"'{self.bucket_name}'. Please make sure the model exists "
451
- f"in the bucket."
452
- )
453
- structlogger.error(
454
- "gcp_persistor.retrieve_tar.model_not_found",
455
- bucket_name=self.bucket_name,
456
- target_filename=target_filename,
457
- event_info=log,
458
- )
459
- raise ModelNotFound() from exc
332
+ blob.download_to_filename(target_filename)
460
333
 
461
334
 
462
335
  class AzurePersistor(Persistor):
@@ -482,8 +355,7 @@ class AzurePersistor(Persistor):
482
355
  else:
483
356
  log = (
484
357
  f"The specified container '{self.container_name}' does not exist."
485
- "Please make sure to create the bucket first or "
486
- f"provide an alternative valid bucket name."
358
+ "Please make sure to create the container first."
487
359
  )
488
360
  structlogger.error(
489
361
  "azure_persistor.ensure_container_exists.container_not_found",
@@ -500,39 +372,10 @@ class AzurePersistor(Persistor):
500
372
  with open(tar_path, "rb") as data:
501
373
  self._container_client().upload_blob(name=file_key, data=data)
502
374
 
503
- def _retrieve_tar_size(self, target_filename: Text) -> int:
504
- """Returns the size of the model that has been persisted to Azure."""
505
- try:
506
- blob_client = self._container_client().get_blob_client(target_filename)
507
- properties = blob_client.get_blob_properties()
508
- return properties.size
509
- except Exception:
510
- raise ModelNotFound()
511
-
512
375
  def _retrieve_tar(self, target_filename: Text) -> None:
513
376
  """Downloads a model that has previously been persisted to Azure."""
514
- from azure.core.exceptions import AzureError
377
+ blob_client = self._container_client().get_blob_client(target_filename)
515
378
 
516
- try:
517
- with open(target_filename, "wb") as model_file:
518
- blob_client = self._container_client().get_blob_client(target_filename)
519
- download_stream = blob_client.download_blob()
520
- model_file.write(download_stream.readall())
521
- structlogger.debug(
522
- "azure_persistor.retrieve_tar.blob_found", blob_name=target_filename
523
- )
524
- except AzureError as exc:
525
- log = (
526
- f"An exception occurred while trying to download "
527
- f"the model '{target_filename}' in the specified container "
528
- f"'{self.container_name}'. Please make sure the model exists "
529
- f"in the container."
530
- )
531
- structlogger.error(
532
- "azure_persistor.retrieve_tar.model_download_error",
533
- container_name=self.container_name,
534
- target_filename=target_filename,
535
- event_info=log,
536
- exception=exc,
537
- )
538
- raise ModelNotFound() from exc
379
+ with open(target_filename, "wb") as blob:
380
+ download_stream = blob_client.download_blob()
381
+ blob.write(download_stream.readall())