rasa-pro 3.12.0.dev13__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 (128) hide show
  1. rasa/anonymization/anonymization_rule_executor.py +16 -10
  2. rasa/cli/data.py +16 -0
  3. rasa/cli/project_templates/calm/config.yml +2 -2
  4. rasa/cli/project_templates/calm/endpoints.yml +2 -2
  5. rasa/cli/utils.py +12 -0
  6. rasa/core/actions/action.py +84 -191
  7. rasa/core/actions/action_run_slot_rejections.py +16 -4
  8. rasa/core/channels/__init__.py +2 -0
  9. rasa/core/channels/studio_chat.py +19 -0
  10. rasa/core/channels/telegram.py +42 -24
  11. rasa/core/channels/voice_ready/utils.py +1 -1
  12. rasa/core/channels/voice_stream/asr/asr_engine.py +10 -4
  13. rasa/core/channels/voice_stream/asr/azure.py +14 -1
  14. rasa/core/channels/voice_stream/asr/deepgram.py +20 -4
  15. rasa/core/channels/voice_stream/audiocodes.py +264 -0
  16. rasa/core/channels/voice_stream/browser_audio.py +4 -1
  17. rasa/core/channels/voice_stream/call_state.py +3 -0
  18. rasa/core/channels/voice_stream/genesys.py +6 -2
  19. rasa/core/channels/voice_stream/tts/azure.py +9 -1
  20. rasa/core/channels/voice_stream/tts/cartesia.py +14 -8
  21. rasa/core/channels/voice_stream/voice_channel.py +23 -2
  22. rasa/core/constants.py +2 -0
  23. rasa/core/nlg/contextual_response_rephraser.py +18 -1
  24. rasa/core/nlg/generator.py +83 -15
  25. rasa/core/nlg/response.py +6 -3
  26. rasa/core/nlg/translate.py +55 -0
  27. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +1 -1
  28. rasa/core/policies/flows/flow_executor.py +12 -5
  29. rasa/core/processor.py +72 -9
  30. rasa/dialogue_understanding/commands/can_not_handle_command.py +20 -2
  31. rasa/dialogue_understanding/commands/cancel_flow_command.py +24 -6
  32. rasa/dialogue_understanding/commands/change_flow_command.py +20 -2
  33. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +20 -2
  34. rasa/dialogue_understanding/commands/clarify_command.py +29 -3
  35. rasa/dialogue_understanding/commands/command.py +1 -16
  36. rasa/dialogue_understanding/commands/command_syntax_manager.py +55 -0
  37. rasa/dialogue_understanding/commands/human_handoff_command.py +20 -2
  38. rasa/dialogue_understanding/commands/knowledge_answer_command.py +20 -2
  39. rasa/dialogue_understanding/commands/prompt_command.py +94 -0
  40. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +20 -2
  41. rasa/dialogue_understanding/commands/set_slot_command.py +24 -2
  42. rasa/dialogue_understanding/commands/skip_question_command.py +20 -2
  43. rasa/dialogue_understanding/commands/start_flow_command.py +20 -2
  44. rasa/dialogue_understanding/commands/utils.py +98 -4
  45. rasa/dialogue_understanding/generator/__init__.py +2 -0
  46. rasa/dialogue_understanding/generator/command_parser.py +15 -12
  47. rasa/dialogue_understanding/generator/constants.py +3 -0
  48. rasa/dialogue_understanding/generator/llm_based_command_generator.py +12 -5
  49. rasa/dialogue_understanding/generator/llm_command_generator.py +5 -3
  50. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +16 -2
  51. rasa/dialogue_understanding/generator/prompt_templates/__init__.py +0 -0
  52. rasa/dialogue_understanding/generator/{single_step → prompt_templates}/command_prompt_template.jinja2 +2 -0
  53. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +77 -0
  54. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_default.jinja2 +68 -0
  55. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +84 -0
  56. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +460 -0
  57. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +12 -310
  58. rasa/dialogue_understanding/patterns/collect_information.py +1 -1
  59. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +16 -0
  60. rasa/dialogue_understanding/patterns/validate_slot.py +65 -0
  61. rasa/dialogue_understanding/processor/command_processor.py +39 -0
  62. rasa/dialogue_understanding_test/du_test_case.py +28 -8
  63. rasa/dialogue_understanding_test/du_test_result.py +13 -9
  64. rasa/dialogue_understanding_test/io.py +14 -0
  65. rasa/e2e_test/utils/io.py +0 -37
  66. rasa/engine/graph.py +1 -0
  67. rasa/engine/language.py +140 -0
  68. rasa/engine/recipes/config_files/default_config.yml +4 -0
  69. rasa/engine/recipes/default_recipe.py +2 -0
  70. rasa/engine/recipes/graph_recipe.py +2 -0
  71. rasa/engine/storage/local_model_storage.py +1 -0
  72. rasa/engine/storage/storage.py +4 -1
  73. rasa/model_manager/runner_service.py +7 -4
  74. rasa/model_manager/socket_bridge.py +7 -6
  75. rasa/shared/constants.py +15 -13
  76. rasa/shared/core/constants.py +2 -0
  77. rasa/shared/core/flows/constants.py +11 -0
  78. rasa/shared/core/flows/flow.py +83 -19
  79. rasa/shared/core/flows/flows_yaml_schema.json +31 -3
  80. rasa/shared/core/flows/steps/collect.py +1 -36
  81. rasa/shared/core/flows/utils.py +28 -4
  82. rasa/shared/core/flows/validation.py +1 -1
  83. rasa/shared/core/slot_mappings.py +208 -5
  84. rasa/shared/core/slots.py +131 -1
  85. rasa/shared/core/trackers.py +74 -1
  86. rasa/shared/importers/importer.py +50 -2
  87. rasa/shared/nlu/training_data/schemas/responses.yml +19 -12
  88. rasa/shared/providers/_configs/azure_entra_id_config.py +541 -0
  89. rasa/shared/providers/_configs/azure_openai_client_config.py +138 -3
  90. rasa/shared/providers/_configs/client_config.py +3 -1
  91. rasa/shared/providers/_configs/default_litellm_client_config.py +3 -1
  92. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +3 -1
  93. rasa/shared/providers/_configs/litellm_router_client_config.py +3 -1
  94. rasa/shared/providers/_configs/model_group_config.py +4 -2
  95. rasa/shared/providers/_configs/oauth_config.py +33 -0
  96. rasa/shared/providers/_configs/openai_client_config.py +3 -1
  97. rasa/shared/providers/_configs/rasa_llm_client_config.py +3 -1
  98. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +3 -1
  99. rasa/shared/providers/constants.py +6 -0
  100. rasa/shared/providers/embedding/azure_openai_embedding_client.py +28 -3
  101. rasa/shared/providers/embedding/litellm_router_embedding_client.py +3 -1
  102. rasa/shared/providers/llm/_base_litellm_client.py +42 -17
  103. rasa/shared/providers/llm/azure_openai_llm_client.py +81 -25
  104. rasa/shared/providers/llm/default_litellm_llm_client.py +3 -1
  105. rasa/shared/providers/llm/litellm_router_llm_client.py +29 -8
  106. rasa/shared/providers/llm/llm_client.py +23 -7
  107. rasa/shared/providers/llm/openai_llm_client.py +9 -3
  108. rasa/shared/providers/llm/rasa_llm_client.py +11 -2
  109. rasa/shared/providers/llm/self_hosted_llm_client.py +30 -11
  110. rasa/shared/providers/router/_base_litellm_router_client.py +3 -1
  111. rasa/shared/providers/router/router_client.py +3 -1
  112. rasa/shared/utils/constants.py +3 -0
  113. rasa/shared/utils/llm.py +30 -7
  114. rasa/shared/utils/pykwalify_extensions.py +24 -0
  115. rasa/shared/utils/schemas/domain.yml +26 -0
  116. rasa/telemetry.py +2 -1
  117. rasa/tracing/config.py +2 -0
  118. rasa/tracing/constants.py +12 -0
  119. rasa/tracing/instrumentation/instrumentation.py +36 -0
  120. rasa/tracing/instrumentation/metrics.py +41 -0
  121. rasa/tracing/metric_instrument_provider.py +40 -0
  122. rasa/validator.py +372 -7
  123. rasa/version.py +1 -1
  124. {rasa_pro-3.12.0.dev13.dist-info → rasa_pro-3.12.0rc1.dist-info}/METADATA +2 -1
  125. {rasa_pro-3.12.0.dev13.dist-info → rasa_pro-3.12.0rc1.dist-info}/RECORD +128 -113
  126. {rasa_pro-3.12.0.dev13.dist-info → rasa_pro-3.12.0rc1.dist-info}/NOTICE +0 -0
  127. {rasa_pro-3.12.0.dev13.dist-info → rasa_pro-3.12.0rc1.dist-info}/WHEEL +0 -0
  128. {rasa_pro-3.12.0.dev13.dist-info → rasa_pro-3.12.0rc1.dist-info}/entry_points.txt +0 -0
@@ -5,16 +5,13 @@ from typing import Any, Dict, List, Optional, Text
5
5
  import numpy as np
6
6
  from pydantic import BaseModel
7
7
 
8
- from rasa.dialogue_understanding.commands import Command
8
+ from rasa.dialogue_understanding.commands.prompt_command import PromptCommand
9
9
  from rasa.dialogue_understanding_test.du_test_case import (
10
10
  DialogueUnderstandingTestCase,
11
11
  DialogueUnderstandingTestStep,
12
12
  )
13
13
  from rasa.dialogue_understanding_test.utils import get_command_comparison
14
- from rasa.shared.nlu.constants import (
15
- KEY_SYSTEM_PROMPT,
16
- KEY_USER_PROMPT,
17
- )
14
+ from rasa.shared.nlu.constants import KEY_SYSTEM_PROMPT, KEY_USER_PROMPT
18
15
 
19
16
  if typing.TYPE_CHECKING:
20
17
  from rasa.dialogue_understanding_test.command_metric_calculation import (
@@ -46,7 +43,7 @@ class DialogueUnderstandingTestResult(BaseModel):
46
43
  passed: bool
47
44
  error_line: Optional[int] = None
48
45
 
49
- def get_expected_commands(self) -> List[Command]:
46
+ def get_expected_commands(self) -> List[PromptCommand]:
50
47
  return self.test_case.get_expected_commands()
51
48
 
52
49
 
@@ -60,10 +57,17 @@ class FailedTestStep(BaseModel):
60
57
  pass_status: bool
61
58
  command_generators: List[str]
62
59
  prompts: Optional[Dict[str, List[Dict[str, Any]]]] = None
63
- expected_commands: List[Command]
64
- predicted_commands: Dict[str, List[Command]]
60
+ expected_commands: List[PromptCommand]
61
+ predicted_commands: Dict[str, List[PromptCommand]]
65
62
  conversation_with_diff: List[str]
66
63
 
64
+ class Config:
65
+ """Skip validation for PromptCommand protocol as pydantic does not know how to
66
+ serialize or handle instances of a protocol.
67
+ """
68
+
69
+ arbitrary_types_allowed = True
70
+
67
71
  @classmethod
68
72
  def from_dialogue_understanding_test_step(
69
73
  cls,
@@ -74,7 +78,7 @@ class FailedTestStep(BaseModel):
74
78
  user_utterance = step.text or ""
75
79
  line_number = step.line or -1
76
80
 
77
- predicted_commands: Dict[str, List[Command]] = {}
81
+ predicted_commands: Dict[str, List[PromptCommand]] = {}
78
82
  prompts: Optional[Dict[str, List[Dict[str, Any]]]] = None
79
83
  command_generators: List[str] = []
80
84
 
@@ -8,6 +8,7 @@ import rasa.shared.data
8
8
  from rasa.dialogue_understanding_test.command_metric_calculation import CommandMetrics
9
9
  from rasa.dialogue_understanding_test.constants import SCHEMA_FILE_PATH
10
10
  from rasa.dialogue_understanding_test.du_test_case import (
11
+ KEY_CHOICES,
11
12
  KEY_COMPLETION_TOKENS,
12
13
  KEY_PROMPT_TOKENS,
13
14
  )
@@ -309,6 +310,7 @@ def print_failed_cases(
309
310
  print_prompt(step)
310
311
  rich.print("\n[red3]-- CONVERSATION --[/red3]")
311
312
  rich.print("\n".join(step.conversation_with_diff))
313
+ print_llm_output(step)
312
314
 
313
315
 
314
316
  def print_prompt(step: FailedTestStep) -> None:
@@ -341,6 +343,18 @@ def print_prompt(step: FailedTestStep) -> None:
341
343
  )
342
344
 
343
345
 
346
+ def print_llm_output(step: FailedTestStep) -> None:
347
+ if not step.prompts:
348
+ return
349
+
350
+ for component, component_prompts in step.prompts.items():
351
+ for prompt_data in component_prompts:
352
+ if KEY_CHOICES in prompt_data:
353
+ rich.print("\n[red3]-- CHOICES --[/red3]")
354
+ rich.print(prompt_data.get(KEY_CHOICES))
355
+ rich.print("[red3]-------------[/red3]")
356
+
357
+
344
358
  def print_command_summary(metrics: Dict[str, CommandMetrics]) -> None:
345
359
  """Print the command summary.
346
360
 
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:
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,
@@ -145,6 +146,7 @@ KEY_MAPPING_TYPE = "type"
145
146
  KEY_ALLOW_NLU_CORRECTION = "allow_nlu_correction"
146
147
  KEY_ACTION = "action"
147
148
  KEY_RUN_ACTION_EVERY_TURN = "run_action_every_turn"
149
+ KEY_COEXISTENCE_SYSTEM = "coexistence_system"
148
150
 
149
151
 
150
152
  class SlotMappingType(Enum):
@@ -0,0 +1,11 @@
1
+ KEY_ID = "id"
2
+ KEY_STEPS = "steps"
3
+ KEY_NAME = "name"
4
+ KEY_DESCRIPTION = "description"
5
+ KEY_IF = "if"
6
+ KEY_ALWAYS_INCLUDE_IN_PROMPT = "always_include_in_prompt"
7
+ KEY_NLU_TRIGGER = "nlu_trigger"
8
+ KEY_FILE_PATH = "file_path"
9
+ KEY_PERSISTED_SLOTS = "persisted_slots"
10
+ KEY_RUN_PATTERN_COMPLETED = "run_pattern_completed"
11
+ KEY_TRANSLATION = "translation"