rasa-pro 3.12.0.dev12__py3-none-any.whl → 3.12.0rc1__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 (153) hide show
  1. rasa/anonymization/anonymization_rule_executor.py +16 -10
  2. rasa/cli/data.py +16 -0
  3. rasa/cli/inspect.py +20 -1
  4. rasa/cli/project_templates/calm/config.yml +2 -2
  5. rasa/cli/project_templates/calm/endpoints.yml +2 -2
  6. rasa/cli/shell.py +3 -3
  7. rasa/cli/utils.py +12 -0
  8. rasa/core/actions/action.py +99 -193
  9. rasa/core/actions/action_handle_digressions.py +142 -0
  10. rasa/core/actions/action_run_slot_rejections.py +16 -4
  11. rasa/core/actions/forms.py +10 -5
  12. rasa/core/channels/__init__.py +4 -0
  13. rasa/core/channels/studio_chat.py +19 -0
  14. rasa/core/channels/telegram.py +42 -24
  15. rasa/core/channels/voice_ready/audiocodes.py +42 -23
  16. rasa/core/channels/voice_ready/utils.py +1 -1
  17. rasa/core/channels/voice_stream/asr/asr_engine.py +10 -4
  18. rasa/core/channels/voice_stream/asr/azure.py +14 -1
  19. rasa/core/channels/voice_stream/asr/deepgram.py +20 -4
  20. rasa/core/channels/voice_stream/audiocodes.py +264 -0
  21. rasa/core/channels/voice_stream/browser_audio.py +5 -1
  22. rasa/core/channels/voice_stream/call_state.py +10 -1
  23. rasa/core/channels/voice_stream/genesys.py +335 -0
  24. rasa/core/channels/voice_stream/tts/azure.py +11 -2
  25. rasa/core/channels/voice_stream/tts/cartesia.py +29 -10
  26. rasa/core/channels/voice_stream/twilio_media_streams.py +2 -1
  27. rasa/core/channels/voice_stream/voice_channel.py +25 -3
  28. rasa/core/constants.py +2 -0
  29. rasa/core/migrate.py +2 -2
  30. rasa/core/nlg/contextual_response_rephraser.py +18 -1
  31. rasa/core/nlg/generator.py +83 -15
  32. rasa/core/nlg/response.py +6 -3
  33. rasa/core/nlg/translate.py +55 -0
  34. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +1 -1
  35. rasa/core/policies/flows/flow_executor.py +47 -46
  36. rasa/core/processor.py +72 -9
  37. rasa/core/run.py +4 -3
  38. rasa/dialogue_understanding/commands/can_not_handle_command.py +20 -2
  39. rasa/dialogue_understanding/commands/cancel_flow_command.py +80 -4
  40. rasa/dialogue_understanding/commands/change_flow_command.py +20 -2
  41. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +20 -2
  42. rasa/dialogue_understanding/commands/clarify_command.py +29 -3
  43. rasa/dialogue_understanding/commands/command.py +1 -16
  44. rasa/dialogue_understanding/commands/command_syntax_manager.py +55 -0
  45. rasa/dialogue_understanding/commands/correct_slots_command.py +11 -2
  46. rasa/dialogue_understanding/commands/handle_digressions_command.py +150 -0
  47. rasa/dialogue_understanding/commands/human_handoff_command.py +20 -2
  48. rasa/dialogue_understanding/commands/knowledge_answer_command.py +20 -2
  49. rasa/dialogue_understanding/commands/prompt_command.py +94 -0
  50. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +20 -2
  51. rasa/dialogue_understanding/commands/set_slot_command.py +29 -15
  52. rasa/dialogue_understanding/commands/skip_question_command.py +20 -2
  53. rasa/dialogue_understanding/commands/start_flow_command.py +61 -2
  54. rasa/dialogue_understanding/commands/utils.py +98 -4
  55. rasa/dialogue_understanding/constants.py +1 -0
  56. rasa/dialogue_understanding/generator/__init__.py +2 -0
  57. rasa/dialogue_understanding/generator/command_generator.py +110 -73
  58. rasa/dialogue_understanding/generator/command_parser.py +16 -13
  59. rasa/dialogue_understanding/generator/constants.py +3 -0
  60. rasa/dialogue_understanding/generator/llm_based_command_generator.py +170 -5
  61. rasa/dialogue_understanding/generator/llm_command_generator.py +5 -3
  62. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +26 -4
  63. rasa/dialogue_understanding/generator/nlu_command_adapter.py +44 -3
  64. rasa/dialogue_understanding/generator/prompt_templates/__init__.py +0 -0
  65. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +60 -0
  66. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +77 -0
  67. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_default.jinja2 +68 -0
  68. rasa/dialogue_understanding/generator/{single_step/command_prompt_template.jinja2 → prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2} +1 -1
  69. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +460 -0
  70. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +12 -318
  71. rasa/dialogue_understanding/generator/utils.py +32 -1
  72. rasa/dialogue_understanding/patterns/collect_information.py +1 -1
  73. rasa/dialogue_understanding/patterns/correction.py +13 -1
  74. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +78 -2
  75. rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
  76. rasa/dialogue_understanding/patterns/validate_slot.py +65 -0
  77. rasa/dialogue_understanding/processor/command_processor.py +154 -28
  78. rasa/dialogue_understanding/utils.py +31 -0
  79. rasa/dialogue_understanding_test/README.md +50 -0
  80. rasa/dialogue_understanding_test/du_test_case.py +28 -8
  81. rasa/dialogue_understanding_test/du_test_result.py +13 -9
  82. rasa/dialogue_understanding_test/io.py +14 -0
  83. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +3 -3
  84. rasa/e2e_test/utils/io.py +0 -37
  85. rasa/engine/graph.py +1 -0
  86. rasa/engine/language.py +140 -0
  87. rasa/engine/recipes/config_files/default_config.yml +4 -0
  88. rasa/engine/recipes/default_recipe.py +2 -0
  89. rasa/engine/recipes/graph_recipe.py +2 -0
  90. rasa/engine/storage/local_model_storage.py +1 -0
  91. rasa/engine/storage/storage.py +4 -1
  92. rasa/model_manager/runner_service.py +7 -4
  93. rasa/model_manager/socket_bridge.py +7 -6
  94. rasa/model_manager/warm_rasa_process.py +0 -1
  95. rasa/model_training.py +24 -27
  96. rasa/shared/constants.py +15 -13
  97. rasa/shared/core/constants.py +30 -3
  98. rasa/shared/core/domain.py +13 -20
  99. rasa/shared/core/events.py +13 -2
  100. rasa/shared/core/flows/constants.py +11 -0
  101. rasa/shared/core/flows/flow.py +100 -19
  102. rasa/shared/core/flows/flows_yaml_schema.json +69 -3
  103. rasa/shared/core/flows/steps/collect.py +19 -37
  104. rasa/shared/core/flows/utils.py +43 -4
  105. rasa/shared/core/flows/validation.py +1 -1
  106. rasa/shared/core/slot_mappings.py +350 -111
  107. rasa/shared/core/slots.py +154 -3
  108. rasa/shared/core/trackers.py +77 -2
  109. rasa/shared/importers/importer.py +50 -2
  110. rasa/shared/nlu/constants.py +1 -0
  111. rasa/shared/nlu/training_data/schemas/responses.yml +19 -12
  112. rasa/shared/providers/_configs/azure_entra_id_config.py +541 -0
  113. rasa/shared/providers/_configs/azure_openai_client_config.py +138 -3
  114. rasa/shared/providers/_configs/client_config.py +3 -1
  115. rasa/shared/providers/_configs/default_litellm_client_config.py +3 -1
  116. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +3 -1
  117. rasa/shared/providers/_configs/litellm_router_client_config.py +3 -1
  118. rasa/shared/providers/_configs/model_group_config.py +4 -2
  119. rasa/shared/providers/_configs/oauth_config.py +33 -0
  120. rasa/shared/providers/_configs/openai_client_config.py +3 -1
  121. rasa/shared/providers/_configs/rasa_llm_client_config.py +3 -1
  122. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +3 -1
  123. rasa/shared/providers/constants.py +6 -0
  124. rasa/shared/providers/embedding/azure_openai_embedding_client.py +28 -3
  125. rasa/shared/providers/embedding/litellm_router_embedding_client.py +3 -1
  126. rasa/shared/providers/llm/_base_litellm_client.py +42 -17
  127. rasa/shared/providers/llm/azure_openai_llm_client.py +81 -25
  128. rasa/shared/providers/llm/default_litellm_llm_client.py +3 -1
  129. rasa/shared/providers/llm/litellm_router_llm_client.py +29 -8
  130. rasa/shared/providers/llm/llm_client.py +23 -7
  131. rasa/shared/providers/llm/openai_llm_client.py +9 -3
  132. rasa/shared/providers/llm/rasa_llm_client.py +11 -2
  133. rasa/shared/providers/llm/self_hosted_llm_client.py +30 -11
  134. rasa/shared/providers/router/_base_litellm_router_client.py +3 -1
  135. rasa/shared/providers/router/router_client.py +3 -1
  136. rasa/shared/utils/constants.py +3 -0
  137. rasa/shared/utils/llm.py +31 -8
  138. rasa/shared/utils/pykwalify_extensions.py +24 -0
  139. rasa/shared/utils/schemas/domain.yml +26 -1
  140. rasa/telemetry.py +45 -14
  141. rasa/tracing/config.py +2 -0
  142. rasa/tracing/constants.py +12 -0
  143. rasa/tracing/instrumentation/instrumentation.py +36 -0
  144. rasa/tracing/instrumentation/metrics.py +41 -0
  145. rasa/tracing/metric_instrument_provider.py +40 -0
  146. rasa/utils/common.py +0 -1
  147. rasa/validator.py +561 -89
  148. rasa/version.py +1 -1
  149. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/METADATA +2 -1
  150. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/RECORD +153 -134
  151. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/NOTICE +0 -0
  152. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/WHEEL +0 -0
  153. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0rc1.dist-info}/entry_points.txt +0 -0
rasa/e2e_test/utils/io.py CHANGED
@@ -49,7 +49,6 @@ if TYPE_CHECKING:
49
49
  from rasa.e2e_test.e2e_test_result import TestResult
50
50
 
51
51
 
52
- RASA_PRO_BETA_E2E_ASSERTIONS_ENV_VAR_NAME = "RASA_PRO_BETA_E2E_ASSERTIONS"
53
52
  RASA_PRO_BETA_STUB_CUSTOM_ACTION_ENV_VAR_NAME = "RASA_PRO_BETA_STUB_CUSTOM_ACTION"
54
53
 
55
54
  structlogger = structlog.get_logger()
@@ -278,16 +277,6 @@ def split_into_passed_failed(
278
277
  return passed_cases, failed_cases
279
278
 
280
279
 
281
- def has_test_case_with_assertions(test_cases: List[TestCase]) -> bool:
282
- """Check if the test cases contain assertions."""
283
- try:
284
- next(test_case for test_case in test_cases if test_case.uses_assertions())
285
- except StopIteration:
286
- return False
287
-
288
- return True
289
-
290
-
291
280
  @lru_cache(maxsize=1)
292
281
  def extract_test_case_from_path(path: str) -> Tuple[str, str]:
293
282
  """Extract test case from path if specified.
@@ -442,7 +431,6 @@ def read_test_cases(path: str) -> TestSuite:
442
431
  fixtures: Dict[str, Fixture] = {}
443
432
  metadata: Dict[str, Metadata] = {}
444
433
  stub_custom_actions: Dict[str, StubCustomAction] = {}
445
- beta_flag_verified = False
446
434
 
447
435
  # Process each test file
448
436
  for test_file in test_files:
@@ -460,10 +448,6 @@ def read_test_cases(path: str) -> TestSuite:
460
448
  stub_custom_actions.update(
461
449
  extract_stub_custom_actions(test_file_content, test_file)
462
450
  )
463
-
464
- beta_flag_verified = verify_beta_feature_flag_for_assertions(
465
- test_cases, beta_flag_verified
466
- )
467
451
  input_test_cases.extend(test_cases)
468
452
 
469
453
  validate_test_case(test_case_name, input_test_cases, fixtures, metadata)
@@ -489,27 +473,6 @@ def check_beta_feature_flag_for_custom_actions_stubs() -> None:
489
473
  rasa.shared.utils.cli.print_error_and_exit(str(exc))
490
474
 
491
475
 
492
- def verify_beta_feature_flag_for_assertions(
493
- test_cases: List[TestCase], beta_flag_verified: bool
494
- ) -> bool:
495
- """Verify the beta feature flag for assertions."""
496
- if beta_flag_verified:
497
- return True
498
-
499
- if not has_test_case_with_assertions(test_cases):
500
- return beta_flag_verified
501
-
502
- try:
503
- ensure_beta_feature_is_enabled(
504
- "end-to-end testing with assertions",
505
- RASA_PRO_BETA_E2E_ASSERTIONS_ENV_VAR_NAME,
506
- )
507
- except BetaNotEnabledException as exc:
508
- rasa.shared.utils.cli.print_error_and_exit(str(exc))
509
-
510
- return True
511
-
512
-
513
476
  def _save_coverage_report(
514
477
  report: Optional[pd.DataFrame], test_status: str, output_dir: str
515
478
  ) -> None:
rasa/engine/graph.py CHANGED
@@ -640,3 +640,4 @@ class GraphModelConfiguration:
640
640
  language: Optional[Text]
641
641
  core_target: Optional[Text]
642
642
  nlu_target: Optional[Text]
643
+ additional_languages: Optional[List[Text]]
@@ -0,0 +1,140 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any, Dict, Text
3
+
4
+ from langcodes import Language as LangcodesLanguage
5
+
6
+ from rasa.shared.exceptions import RasaException
7
+
8
+ CUSTOM_LANGUAGE_CODE_PREFIX = "x-"
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class Language:
13
+ code: str
14
+ label: str
15
+ is_default: bool
16
+
17
+ @classmethod
18
+ def from_language_code(
19
+ cls, language_code: str, is_default: bool = False
20
+ ) -> "Language":
21
+ """Creates a Language object from a language code.
22
+
23
+ Args:
24
+ language_code: The language code.
25
+ is_default: Whether the language is the default language.
26
+
27
+ Returns:
28
+ A Language object.
29
+
30
+ Raises:
31
+ RasaException: If the language code or custom language code is invalid.
32
+ """
33
+ language = LangcodesLanguage.make(language_code)
34
+ cls.validate_language(language)
35
+
36
+ return cls(
37
+ code=language_code,
38
+ label=cls.get_language_label(language),
39
+ is_default=is_default,
40
+ )
41
+
42
+ @staticmethod
43
+ def get_language_label(language: LangcodesLanguage) -> str:
44
+ """Gets the display name of a language.
45
+
46
+ For custom languages (in the format "x-<base_lang>-<custom_label>"),
47
+ the label is derived from the base language code.
48
+ This method considers that the language code has previously been validated.
49
+
50
+ Args:
51
+ language: The language code.
52
+
53
+ Returns:
54
+ The display name of the language.
55
+ """
56
+ language_code = str(language)
57
+
58
+ if language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX):
59
+ # If it's a custom language, derive the label from the base language code.
60
+ parts = language_code.split("-")
61
+ base_language_code = parts[1]
62
+ base_language = LangcodesLanguage.make(base_language_code)
63
+ return base_language.display_name()
64
+ else:
65
+ return language.display_name()
66
+
67
+ @classmethod
68
+ def validate_language(cls, language: LangcodesLanguage) -> None:
69
+ """Validates a language code.
70
+
71
+ Args:
72
+ language: The language object to validate.
73
+
74
+ Raises:
75
+ RasaException: If the language validation fails.
76
+ """
77
+ if not language.is_valid():
78
+ raise RasaException(f"Language '{language}' is not a valid language code.")
79
+
80
+ language_code = str(language)
81
+ if language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX):
82
+ cls.validate_custom_language(language_code)
83
+
84
+ @staticmethod
85
+ def validate_custom_language(custom_language_code: str) -> None:
86
+ """Validates a custom language code.
87
+
88
+ A valid custom language code should adhere to the format:
89
+ "x-<existing_language_code>-<custom_label>"
90
+ Example: x-en-formal
91
+
92
+ Args:
93
+ custom_language_code: The custom language code to validate.
94
+
95
+ Raises:
96
+ RasaException: If the custom language code validation fails.
97
+ """
98
+ # Ensure the custom language code starts with the custom prefix.
99
+ if not custom_language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX):
100
+ raise RasaException(
101
+ f"Custom language '{custom_language_code}' must "
102
+ f"start with '{CUSTOM_LANGUAGE_CODE_PREFIX}'."
103
+ )
104
+
105
+ # Split the language code into parts.
106
+ parts = custom_language_code.split("-")
107
+ if len(parts) != 3:
108
+ raise RasaException(
109
+ f"Custom language '{custom_language_code}' must be in the format "
110
+ f"'{CUSTOM_LANGUAGE_CODE_PREFIX}<language_code>-<custom_label>'."
111
+ )
112
+
113
+ # Validate the base language code using langcodes.
114
+ base_language_code = parts[1]
115
+ base_language = LangcodesLanguage.make(base_language_code)
116
+ if not base_language.is_valid():
117
+ raise RasaException(
118
+ f"Base language '{base_language_code}' in custom language "
119
+ f"'{custom_language_code}' is not a valid language code."
120
+ )
121
+
122
+ # Ensure the custom label is not empty.
123
+ custom_label = parts[2]
124
+ if not custom_label:
125
+ raise RasaException(
126
+ f"Custom label in custom language "
127
+ f"'{custom_language_code}' cannot be empty."
128
+ )
129
+
130
+ def as_dict(self) -> Dict[Text, Any]:
131
+ """Converts the Language dataclass instance into a dictionary.
132
+
133
+ Returns:
134
+ A dictionary representing the Language object.
135
+ """
136
+ return {
137
+ "code": self.code,
138
+ "label": self.label,
139
+ "is_default": self.is_default,
140
+ }
@@ -9,6 +9,10 @@ assistant_id: placeholder_default
9
9
  # Configuration for the Rasa NLU components.
10
10
  # https://rasa.com/docs/rasa-pro/nlu-based-assistants/components
11
11
  language: en
12
+ additional_languages:
13
+ - it
14
+ - de
15
+ - es
12
16
 
13
17
  pipeline:
14
18
  - name: WhitespaceTokenizer
@@ -49,6 +49,7 @@ from rasa.graph_components.providers.training_tracker_provider import (
49
49
  )
50
50
  from rasa.shared.constants import (
51
51
  ASSISTANT_ID_KEY,
52
+ CONFIG_ADDITIONAL_LANGUAGES_KEY,
52
53
  CONFIG_LANGUAGE_KEY,
53
54
  CONFIG_NAME_KEY,
54
55
  CONFIG_PIPELINE_KEY,
@@ -247,6 +248,7 @@ class DefaultV1Recipe(Recipe):
247
248
  language=config.get(CONFIG_LANGUAGE_KEY),
248
249
  core_target=core_target,
249
250
  nlu_target=f"{GRAPH_NODE_RUN_PREFIX}{RegexMessageHandler.__name__}",
251
+ additional_languages=config.get(CONFIG_ADDITIONAL_LANGUAGES_KEY),
250
252
  )
251
253
 
252
254
  def _create_train_nodes(
@@ -5,6 +5,7 @@ from rasa.engine.graph import GraphModelConfiguration, GraphSchema
5
5
  from rasa.engine.recipes.recipe import Recipe
6
6
  from rasa.shared.constants import (
7
7
  ASSISTANT_ID_KEY,
8
+ CONFIG_ADDITIONAL_LANGUAGES_KEY,
8
9
  CONFIG_LANGUAGE_KEY,
9
10
  DOCS_URL_GRAPH_RECIPE,
10
11
  )
@@ -76,4 +77,5 @@ class GraphV1Recipe(Recipe):
76
77
  language=config.get(CONFIG_LANGUAGE_KEY),
77
78
  core_target=core_target,
78
79
  nlu_target=nlu_target,
80
+ additional_languages=config.get(CONFIG_ADDITIONAL_LANGUAGES_KEY),
79
81
  )
@@ -240,6 +240,7 @@ class LocalModelStorage(ModelStorage):
240
240
  training_type=model_configuration.training_type,
241
241
  project_fingerprint=rasa.model.project_fingerprint(),
242
242
  language=model_configuration.language,
243
+ additional_languages=model_configuration.additional_languages,
243
244
  core_target=model_configuration.core_target,
244
245
  nlu_target=model_configuration.nlu_target,
245
246
  )
@@ -7,7 +7,7 @@ from contextlib import contextmanager
7
7
  from dataclasses import dataclass
8
8
  from datetime import datetime
9
9
  from pathlib import Path
10
- from typing import Any, Dict, Generator, Optional, Text, Tuple, Union
10
+ from typing import Any, Dict, Generator, List, Optional, Text, Tuple, Union
11
11
 
12
12
  from packaging import version
13
13
 
@@ -142,6 +142,7 @@ class ModelMetadata:
142
142
  core_target: Optional[Text]
143
143
  nlu_target: Text
144
144
  language: Optional[Text]
145
+ additional_languages: Optional[List[Text]]
145
146
  training_type: TrainingType = TrainingType.BOTH
146
147
 
147
148
  def __post_init__(self) -> None:
@@ -171,6 +172,7 @@ class ModelMetadata:
171
172
  "core_target": self.core_target,
172
173
  "nlu_target": self.nlu_target,
173
174
  "language": self.language,
175
+ "additional_languages": self.additional_languages,
174
176
  }
175
177
 
176
178
  @classmethod
@@ -198,4 +200,5 @@ class ModelMetadata:
198
200
  core_target=serialized["core_target"],
199
201
  nlu_target=serialized["nlu_target"],
200
202
  language=serialized["language"],
203
+ additional_languages=serialized.get("additional_languages"),
201
204
  )
@@ -258,10 +258,13 @@ def run_bot(
258
258
 
259
259
  async def update_bot_status(bot: BotSession) -> None:
260
260
  """Update the status of a bot based on the process return code."""
261
- if bot.has_died_recently():
262
- set_bot_status_to_stopped(bot)
263
- elif await bot.completed_startup_recently():
264
- set_bot_status_to_running(bot)
261
+ try:
262
+ if bot.has_died_recently():
263
+ set_bot_status_to_stopped(bot)
264
+ elif await bot.completed_startup_recently():
265
+ set_bot_status_to_running(bot)
266
+ except Exception as e:
267
+ structlogger.error("model_runner.update_bot_status.error", error=str(e))
265
268
 
266
269
 
267
270
  def terminate_bot(bot: BotSession) -> None:
@@ -4,6 +4,7 @@ from typing import Any, Dict, Optional
4
4
  import structlog
5
5
  from socketio import AsyncServer
6
6
  from socketio.asyncio_client import AsyncClient
7
+ from socketio.exceptions import ConnectionRefusedError
7
8
 
8
9
  from rasa.model_manager.runner_service import BotSession
9
10
  from rasa.model_manager.studio_jwt_auth import (
@@ -29,7 +30,7 @@ async def socketio_websocket_traffic_wrapper(
29
30
 
30
31
  if auth_token is None:
31
32
  structlogger.error("model_runner.user_no_token", sid=sid)
32
- return False
33
+ raise ConnectionRefusedError("model_runner.user_no_token")
33
34
 
34
35
  try:
35
36
  authenticate_user_to_service(auth_token)
@@ -38,22 +39,22 @@ async def socketio_websocket_traffic_wrapper(
38
39
  structlogger.error(
39
40
  "model_runner.user_authentication_failed", sid=sid, error=str(error)
40
41
  )
41
- return False
42
+ raise ConnectionRefusedError("model_runner.user_authentication_failed")
42
43
 
43
44
  deployment_id = auth.get("deployment_id") if auth else None
44
45
 
45
46
  if deployment_id is None:
46
47
  structlogger.error("model_runner.bot_no_deployment_id", sid=sid)
47
- return False
48
+ raise ConnectionRefusedError("model_runner.bot_no_deployment_id")
48
49
 
49
50
  bot = running_bots.get(deployment_id)
50
51
  if bot is None:
51
52
  structlogger.error("model_runner.bot_not_found", deployment_id=deployment_id)
52
- return False
53
+ raise ConnectionRefusedError("model_runner.bot_not_found")
53
54
 
54
55
  if not bot.is_alive():
55
56
  structlogger.error("model_runner.bot_not_alive", deployment_id=deployment_id)
56
- return False
57
+ raise ConnectionRefusedError("model_runner.bot_not_alive")
57
58
 
58
59
  client = await create_bridge_client(sio, bot.internal_url, sid, deployment_id)
59
60
 
@@ -67,7 +68,7 @@ async def socketio_websocket_traffic_wrapper(
67
68
  structlogger.error(
68
69
  "model_runner.bot_connection_failed", deployment_id=deployment_id
69
70
  )
70
- return False
71
+ raise ConnectionRefusedError("model_runner.bot_connection_failed")
71
72
 
72
73
 
73
74
  def create_bridge_server(sio: AsyncServer, running_bots: Dict[str, BotSession]) -> None:
@@ -46,7 +46,6 @@ def _create_warm_rasa_process() -> WarmRasaProcess:
46
46
  ]
47
47
 
48
48
  envs = os.environ.copy()
49
- envs["RASA_TELEMETRY_ENABLED"] = "false"
50
49
  envs[RASA_RECORD_COMMANDS_AND_PROMPTS_ENV_VAR_NAME] = "true"
51
50
 
52
51
  log_id = uuid.uuid4().hex
rasa/model_training.py CHANGED
@@ -352,34 +352,31 @@ async def _train_graph(
352
352
  model_name = determine_model_name(fixed_model_name, training_type)
353
353
  full_model_path = Path(output_path, model_name)
354
354
 
355
- with telemetry.track_model_training(
356
- file_importer, model_type=training_type.model_type
357
- ):
358
- await trainer.train(
359
- model_configuration,
360
- file_importer,
361
- full_model_path,
362
- force_retraining=force_full_training,
363
- is_finetuning=is_finetuning,
355
+ await trainer.train(
356
+ model_configuration,
357
+ file_importer,
358
+ full_model_path,
359
+ force_retraining=force_full_training,
360
+ is_finetuning=is_finetuning,
361
+ )
362
+ if remote_storage:
363
+ push_model_to_remote_storage(full_model_path, remote_storage)
364
+ if not keep_local_model_copy:
365
+ full_model_path.unlink()
366
+ structlogger.info(
367
+ "model_training.train.finished_training",
368
+ event_info=(
369
+ f"Your Rasa model {model_name} is trained "
370
+ f"and saved at remote storage provider '{remote_storage}'."
371
+ ),
372
+ )
373
+ else:
374
+ structlogger.info(
375
+ "model_training.train.finished_training",
376
+ event_info=(
377
+ f"Your Rasa model is trained and saved at '{full_model_path}'."
378
+ ),
364
379
  )
365
- if remote_storage:
366
- push_model_to_remote_storage(full_model_path, remote_storage)
367
- if not keep_local_model_copy:
368
- full_model_path.unlink()
369
- structlogger.info(
370
- "model_training.train.finished_training",
371
- event_info=(
372
- f"Your Rasa model {model_name} is trained "
373
- f"and saved at remote storage provider '{remote_storage}'."
374
- ),
375
- )
376
- else:
377
- structlogger.info(
378
- "model_training.train.finished_training",
379
- event_info=(
380
- f"Your Rasa model is trained and saved at '{full_model_path}'."
381
- ),
382
- )
383
380
 
384
381
  return TrainingResult(str(full_model_path), 0)
385
382
 
rasa/shared/constants.py CHANGED
@@ -83,6 +83,7 @@ ENV_LOG_LEVEL_LLM = "LOG_LEVEL_LLM"
83
83
  ENV_LOG_LEVEL_LLM_MODULE_NAMES = {
84
84
  "LLMCommandGenerator": "LOG_LEVEL_LLM_COMMAND_GENERATOR",
85
85
  "SingleStepLLMCommandGenerator": "LOG_LEVEL_LLM_COMMAND_GENERATOR",
86
+ "CompactLLMCommandGenerator": "LOG_LEVEL_LLM_COMMAND_GENERATOR",
86
87
  "MultiStepLLMCommandGenerator": "LOG_LEVEL_LLM_COMMAND_GENERATOR",
87
88
  "EnterpriseSearchPolicy": "LOG_LEVEL_LLM_ENTERPRISE_SEARCH",
88
89
  "IntentlessPolicy": "LOG_LEVEL_LLM_INTENTLESS_POLICY",
@@ -106,6 +107,7 @@ CONFIG_NAME_KEY = "name"
106
107
  CONFIG_POLICIES_KEY = "policies"
107
108
  CONFIG_PIPELINE_KEY = "pipeline"
108
109
  CONFIG_LANGUAGE_KEY = "language"
110
+ CONFIG_ADDITIONAL_LANGUAGES_KEY = "additional_languages"
109
111
  CONFIG_RECIPE_KEY = "recipe"
110
112
  CONFIG_LLM_KEY = "llm"
111
113
  CONFIG_MODEL_NAME_KEY = "model_name"
@@ -150,6 +152,8 @@ DEFAULT_MARKERS_CONFIG_PATH = "markers/config"
150
152
  DEFAULT_MARKERS_OUTPUT_PATH = "markers/output"
151
153
  DEFAULT_MARKERS_STATS_PATH = "markers/stats"
152
154
 
155
+ DEFAULT_PROMPT_PACKAGE_NAME = "rasa.dialogue_understanding.generator.prompt_templates"
156
+
153
157
  DIAGNOSTIC_DATA = "diagnostic_data"
154
158
 
155
159
  RESPONSE_CONDITION = "condition"
@@ -162,6 +166,7 @@ AZURE_AD_TOKEN_ENV_VAR = "AZURE_AD_TOKEN"
162
166
  AZURE_API_BASE_ENV_VAR = "AZURE_API_BASE"
163
167
  AZURE_API_VERSION_ENV_VAR = "AZURE_API_VERSION"
164
168
  AZURE_API_TYPE_ENV_VAR = "AZURE_API_TYPE"
169
+ AZURE_AD_SCOPES_ENV_VAR = "AZURE_AD_SCOPES"
165
170
  AZURE_SPEECH_API_KEY_ENV_VAR = "AZURE_SPEECH_API_KEY"
166
171
 
167
172
  DEEPGRAM_API_KEY_ENV_VAR = "DEEPGRAM_API_KEY"
@@ -198,7 +203,6 @@ MODEL_CONFIG_KEY = "model"
198
203
  MODEL_NAME_CONFIG_KEY = "model_name"
199
204
  PROMPT_CONFIG_KEY = "prompt"
200
205
  PROMPT_TEMPLATE_CONFIG_KEY = "prompt_template"
201
-
202
206
  STREAM_CONFIG_KEY = "stream"
203
207
  N_REPHRASES_CONFIG_KEY = "n"
204
208
  USE_CHAT_COMPLETIONS_ENDPOINT_CONFIG_KEY = "use_chat_completions_endpoint"
@@ -232,12 +236,6 @@ LITELLM_PARAMS_KEY = "litellm_params"
232
236
  LLM_API_HEALTH_CHECK_ENV_VAR = "LLM_API_HEALTH_CHECK"
233
237
  LLM_API_HEALTH_CHECK_DEFAULT_VALUE = "false"
234
238
 
235
- AZURE_API_KEY_ENV_VAR = "AZURE_API_KEY"
236
- AZURE_AD_TOKEN_ENV_VAR = "AZURE_AD_TOKEN"
237
- AZURE_API_BASE_ENV_VAR = "AZURE_API_BASE"
238
- AZURE_API_VERSION_ENV_VAR = "AZURE_API_VERSION"
239
- AZURE_API_TYPE_ENV_VAR = "AZURE_API_TYPE"
240
-
241
239
  AWS_REGION_NAME_CONFIG_KEY = "aws_region_name"
242
240
  AWS_ACCESS_KEY_ID_CONFIG_KEY = "aws_access_key_id"
243
241
  AWS_SECRET_ACCESS_KEY_CONFIG_KEY = "aws_secret_access_key"
@@ -273,17 +271,11 @@ RASA_PROVIDER = "rasa"
273
271
  SELF_HOSTED_VLLM_PREFIX = "hosted_vllm"
274
272
  SELF_HOSTED_VLLM_API_KEY_ENV_VAR = "HOSTED_VLLM_API_KEY"
275
273
 
276
- SELF_HOSTED_VLLM_PREFIX = "hosted_vllm"
277
- SELF_HOSTED_VLLM_API_KEY_ENV_VAR = "HOSTED_VLLM_API_KEY"
278
-
279
274
  VALID_PROVIDERS_FOR_API_TYPE_CONFIG_KEY = [
280
275
  OPENAI_PROVIDER,
281
276
  AZURE_OPENAI_PROVIDER,
282
277
  ]
283
278
 
284
- SELF_HOSTED_VLLM_PREFIX = "hosted_vllm"
285
- SELF_HOSTED_VLLM_API_KEY_ENV_VAR = "HOSTED_VLLM_API_KEY"
286
-
287
279
  AZURE_API_TYPE = "azure"
288
280
  OPENAI_API_TYPE = "openai"
289
281
 
@@ -329,3 +321,13 @@ BUTTONS = "buttons"
329
321
  ATTACHMENT = "attachment"
330
322
  IMAGE = "image"
331
323
  CUSTOM = "custom"
324
+ TITLE = "title"
325
+ PAYLOAD = "payload"
326
+
327
+ # Used for LLM command generation
328
+ ROLE_USER = "user"
329
+ ROLE_SYSTEM = "system"
330
+
331
+ # Used for key values in ValidateSlotPatternFlowStackFrame
332
+ REFILL_UTTER = "refill_utter"
333
+ REJECTIONS = "rejections"
@@ -13,6 +13,7 @@ USER_INTENT_SESSION_START = "session_start"
13
13
  USER_INTENT_SESSION_END = "session_end"
14
14
  USER_INTENT_SILENCE_TIMEOUT = "silence_timeout"
15
15
  SESSION_START_METADATA_SLOT = "session_started_metadata"
16
+ LANGUAGE_SLOT = "language"
16
17
 
17
18
  DEFAULT_INTENTS = [
18
19
  USER_INTENT_RESTART,
@@ -51,6 +52,8 @@ ACTION_TRIGGER_CHITCHAT = "action_trigger_chitchat"
51
52
  ACTION_RESET_ROUTING = "action_reset_routing"
52
53
  ACTION_HANGUP = "action_hangup"
53
54
  ACTION_REPEAT_BOT_MESSAGES = "action_repeat_bot_messages"
55
+ ACTION_BLOCK_DIGRESSION = "action_block_digression"
56
+ ACTION_CONTINUE_DIGRESSION = "action_continue_digression"
54
57
 
55
58
  ACTION_METADATA_EXECUTION_SUCCESS = "execution_success"
56
59
  ACTION_METADATA_EXECUTION_ERROR_MESSAGE = "execution_error_message"
@@ -81,6 +84,8 @@ DEFAULT_ACTION_NAMES = [
81
84
  ACTION_RESET_ROUTING,
82
85
  ACTION_HANGUP,
83
86
  ACTION_REPEAT_BOT_MESSAGES,
87
+ ACTION_BLOCK_DIGRESSION,
88
+ ACTION_CONTINUE_DIGRESSION,
84
89
  ]
85
90
 
86
91
  ACTION_SHOULD_SEND_DOMAIN = "send_domain"
@@ -137,7 +142,11 @@ DEFAULT_SLOT_NAMES = {
137
142
 
138
143
  SLOT_MAPPINGS = "mappings"
139
144
  MAPPING_CONDITIONS = "conditions"
140
- MAPPING_TYPE = "type"
145
+ KEY_MAPPING_TYPE = "type"
146
+ KEY_ALLOW_NLU_CORRECTION = "allow_nlu_correction"
147
+ KEY_ACTION = "action"
148
+ KEY_RUN_ACTION_EVERY_TURN = "run_action_every_turn"
149
+ KEY_COEXISTENCE_SYSTEM = "coexistence_system"
141
150
 
142
151
 
143
152
  class SlotMappingType(Enum):
@@ -148,7 +157,7 @@ class SlotMappingType(Enum):
148
157
  FROM_TRIGGER_INTENT = "from_trigger_intent"
149
158
  FROM_TEXT = "from_text"
150
159
  FROM_LLM = "from_llm"
151
- CUSTOM = "custom"
160
+ CONTROLLED = "controlled"
152
161
 
153
162
  def __str__(self) -> str:
154
163
  """Returns the string representation that should be used in config files."""
@@ -156,7 +165,21 @@ class SlotMappingType(Enum):
156
165
 
157
166
  def is_predefined_type(self) -> bool:
158
167
  """Returns True if the mapping type is NLU-predefined."""
159
- return not (self == SlotMappingType.CUSTOM or self == SlotMappingType.FROM_LLM)
168
+ return not (
169
+ self == SlotMappingType.CONTROLLED or self == SlotMappingType.FROM_LLM
170
+ )
171
+
172
+
173
+ class SetSlotExtractor(Enum):
174
+ """The extractors that can set a slot."""
175
+
176
+ LLM = "LLM"
177
+ COMMAND_PAYLOAD_READER = "CommandPayloadReader"
178
+ NLU = "NLU"
179
+ CUSTOM = "CUSTOM"
180
+
181
+ def __str__(self) -> str:
182
+ return self.value
160
183
 
161
184
 
162
185
  # the keys for `State` (USER, PREVIOUS_ACTION, SLOTS, ACTIVE_LOOP)
@@ -181,3 +204,7 @@ POLICY_NAME_RULE = "RulePolicy"
181
204
  CLASSIFIER_NAME_FALLBACK = "FallbackClassifier"
182
205
 
183
206
  POLICIES_THAT_EXTRACT_ENTITIES = {"TEDPolicy"}
207
+
208
+ # digression constants
209
+ KEY_ASK_CONFIRM_DIGRESSIONS = "ask_confirm_digressions"
210
+ KEY_BLOCK_DIGRESSIONS = "block_digressions"