rasa-pro 3.13.0.dev20250612__py3-none-any.whl → 3.13.0.dev20250613__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 (156) hide show
  1. rasa/__main__.py +0 -3
  2. rasa/api.py +1 -1
  3. rasa/cli/dialogue_understanding_test.py +1 -1
  4. rasa/cli/e2e_test.py +1 -1
  5. rasa/cli/evaluate.py +1 -1
  6. rasa/cli/export.py +1 -1
  7. rasa/cli/llm_fine_tuning.py +12 -11
  8. rasa/cli/project_templates/defaults.py +133 -0
  9. rasa/cli/run.py +1 -1
  10. rasa/cli/studio/link.py +53 -0
  11. rasa/cli/studio/pull.py +78 -0
  12. rasa/cli/studio/push.py +78 -0
  13. rasa/cli/studio/studio.py +12 -0
  14. rasa/cli/studio/upload.py +8 -0
  15. rasa/cli/train.py +1 -1
  16. rasa/cli/utils.py +1 -1
  17. rasa/cli/x.py +1 -1
  18. rasa/constants.py +2 -0
  19. rasa/core/__init__.py +0 -16
  20. rasa/core/actions/action.py +5 -1
  21. rasa/core/actions/action_repeat_bot_messages.py +18 -22
  22. rasa/core/actions/action_run_slot_rejections.py +0 -1
  23. rasa/core/agent.py +16 -1
  24. rasa/core/available_endpoints.py +146 -0
  25. rasa/core/brokers/pika.py +1 -2
  26. rasa/core/channels/botframework.py +2 -2
  27. rasa/core/channels/channel.py +2 -2
  28. rasa/core/channels/hangouts.py +8 -5
  29. rasa/core/channels/mattermost.py +1 -1
  30. rasa/core/channels/rasa_chat.py +2 -4
  31. rasa/core/channels/rest.py +5 -4
  32. rasa/core/channels/studio_chat.py +3 -2
  33. rasa/core/channels/vier_cvg.py +1 -2
  34. rasa/core/channels/voice_ready/audiocodes.py +1 -8
  35. rasa/core/channels/voice_stream/audiocodes.py +7 -4
  36. rasa/core/channels/voice_stream/genesys.py +2 -2
  37. rasa/core/channels/voice_stream/twilio_media_streams.py +10 -5
  38. rasa/core/channels/voice_stream/voice_channel.py +33 -22
  39. rasa/core/http_interpreter.py +3 -7
  40. rasa/core/jobs.py +2 -1
  41. rasa/core/nlg/contextual_response_rephraser.py +38 -11
  42. rasa/core/nlg/generator.py +0 -1
  43. rasa/core/nlg/interpolator.py +2 -3
  44. rasa/core/nlg/summarize.py +39 -5
  45. rasa/core/policies/enterprise_search_policy.py +290 -66
  46. rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +63 -0
  47. rasa/core/policies/flow_policy.py +1 -1
  48. rasa/core/policies/flows/flow_executor.py +96 -17
  49. rasa/core/policies/intentless_policy.py +24 -16
  50. rasa/core/processor.py +104 -51
  51. rasa/core/run.py +33 -11
  52. rasa/core/tracker_stores/tracker_store.py +1 -1
  53. rasa/core/training/interactive.py +1 -1
  54. rasa/core/utils.py +24 -97
  55. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -1
  56. rasa/dialogue_understanding/coexistence/llm_based_router.py +8 -3
  57. rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -0
  58. rasa/dialogue_understanding/commands/cancel_flow_command.py +2 -0
  59. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -0
  60. rasa/dialogue_understanding/commands/clarify_command.py +5 -1
  61. rasa/dialogue_understanding/commands/command_syntax_manager.py +1 -0
  62. rasa/dialogue_understanding/commands/human_handoff_command.py +2 -0
  63. rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -0
  64. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -0
  65. rasa/dialogue_understanding/commands/set_slot_command.py +11 -1
  66. rasa/dialogue_understanding/commands/skip_question_command.py +2 -0
  67. rasa/dialogue_understanding/commands/start_flow_command.py +4 -0
  68. rasa/dialogue_understanding/commands/utils.py +26 -2
  69. rasa/dialogue_understanding/generator/__init__.py +7 -1
  70. rasa/dialogue_understanding/generator/command_generator.py +4 -2
  71. rasa/dialogue_understanding/generator/command_parser.py +2 -2
  72. rasa/dialogue_understanding/generator/command_parser_validator.py +63 -0
  73. rasa/dialogue_understanding/generator/constants.py +2 -2
  74. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +78 -0
  75. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +28 -463
  76. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +147 -0
  77. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +477 -0
  78. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +8 -58
  79. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +37 -25
  80. rasa/dialogue_understanding/patterns/domain_for_patterns.py +190 -0
  81. rasa/dialogue_understanding/processor/command_processor.py +3 -3
  82. rasa/dialogue_understanding/processor/command_processor_component.py +3 -3
  83. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +17 -4
  84. rasa/dialogue_understanding/utils.py +68 -12
  85. rasa/dialogue_understanding_test/du_test_case.py +1 -1
  86. rasa/dialogue_understanding_test/du_test_runner.py +4 -22
  87. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +2 -6
  88. rasa/e2e_test/e2e_test_runner.py +1 -1
  89. rasa/engine/constants.py +1 -1
  90. rasa/engine/recipes/default_recipe.py +26 -2
  91. rasa/engine/validation.py +3 -2
  92. rasa/hooks.py +0 -28
  93. rasa/llm_fine_tuning/annotation_module.py +39 -9
  94. rasa/llm_fine_tuning/conversations.py +3 -0
  95. rasa/llm_fine_tuning/llm_data_preparation_module.py +66 -49
  96. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -2
  97. rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +52 -44
  98. rasa/llm_fine_tuning/paraphrasing_module.py +10 -12
  99. rasa/llm_fine_tuning/storage.py +4 -4
  100. rasa/llm_fine_tuning/utils.py +63 -1
  101. rasa/model_manager/model_api.py +88 -0
  102. rasa/model_manager/trainer_service.py +4 -4
  103. rasa/plugin.py +1 -11
  104. rasa/privacy/__init__.py +0 -0
  105. rasa/privacy/constants.py +83 -0
  106. rasa/privacy/event_broker_utils.py +77 -0
  107. rasa/privacy/privacy_config.py +281 -0
  108. rasa/privacy/privacy_config_schema.json +86 -0
  109. rasa/privacy/privacy_filter.py +340 -0
  110. rasa/privacy/privacy_manager.py +576 -0
  111. rasa/server.py +23 -2
  112. rasa/shared/constants.py +6 -0
  113. rasa/shared/core/constants.py +4 -3
  114. rasa/shared/core/domain.py +7 -0
  115. rasa/shared/core/events.py +37 -7
  116. rasa/shared/core/flows/flow.py +1 -2
  117. rasa/shared/core/flows/flows_yaml_schema.json +3 -0
  118. rasa/shared/core/flows/steps/collect.py +46 -2
  119. rasa/shared/core/slots.py +28 -0
  120. rasa/shared/exceptions.py +4 -0
  121. rasa/shared/providers/_configs/azure_openai_client_config.py +4 -0
  122. rasa/shared/providers/_configs/openai_client_config.py +4 -0
  123. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +3 -0
  124. rasa/shared/providers/llm/_base_litellm_client.py +5 -2
  125. rasa/shared/utils/llm.py +161 -6
  126. rasa/shared/utils/yaml.py +32 -0
  127. rasa/studio/data_handler.py +3 -3
  128. rasa/studio/download/download.py +37 -60
  129. rasa/studio/download/flows.py +23 -31
  130. rasa/studio/link.py +200 -0
  131. rasa/studio/pull.py +94 -0
  132. rasa/studio/push.py +131 -0
  133. rasa/studio/upload.py +117 -67
  134. rasa/telemetry.py +82 -25
  135. rasa/tracing/config.py +3 -4
  136. rasa/tracing/constants.py +19 -1
  137. rasa/tracing/instrumentation/attribute_extractors.py +10 -2
  138. rasa/tracing/instrumentation/instrumentation.py +53 -2
  139. rasa/tracing/instrumentation/metrics.py +98 -15
  140. rasa/tracing/metric_instrument_provider.py +75 -3
  141. rasa/utils/common.py +1 -27
  142. rasa/utils/log_utils.py +1 -45
  143. rasa/validator.py +2 -8
  144. rasa/version.py +1 -1
  145. {rasa_pro-3.13.0.dev20250612.dist-info → rasa_pro-3.13.0.dev20250613.dist-info}/METADATA +5 -6
  146. {rasa_pro-3.13.0.dev20250612.dist-info → rasa_pro-3.13.0.dev20250613.dist-info}/RECORD +149 -135
  147. rasa/anonymization/__init__.py +0 -2
  148. rasa/anonymization/anonymisation_rule_yaml_reader.py +0 -91
  149. rasa/anonymization/anonymization_pipeline.py +0 -286
  150. rasa/anonymization/anonymization_rule_executor.py +0 -266
  151. rasa/anonymization/anonymization_rule_orchestrator.py +0 -119
  152. rasa/anonymization/schemas/config.yml +0 -47
  153. rasa/anonymization/utils.py +0 -118
  154. {rasa_pro-3.13.0.dev20250612.dist-info → rasa_pro-3.13.0.dev20250613.dist-info}/NOTICE +0 -0
  155. {rasa_pro-3.13.0.dev20250612.dist-info → rasa_pro-3.13.0.dev20250613.dist-info}/WHEEL +0 -0
  156. {rasa_pro-3.13.0.dev20250612.dist-info → rasa_pro-3.13.0.dev20250613.dist-info}/entry_points.txt +0 -0
rasa/__main__.py CHANGED
@@ -143,9 +143,6 @@ def main(raw_arguments: Optional[List[str]] = None) -> None:
143
143
  if not is_studio_command:
144
144
  plugin_manager().hook.init_telemetry(endpoints_file=endpoints_file)
145
145
  plugin_manager().hook.init_managers(endpoints_file=endpoints_file)
146
- plugin_manager().hook.init_anonymization_pipeline(
147
- endpoints_file=endpoints_file
148
- )
149
146
 
150
147
  cmdline_arguments.func(cmdline_arguments)
151
148
  elif hasattr(cmdline_arguments, "version"):
rasa/api.py CHANGED
@@ -38,7 +38,7 @@ def run(
38
38
  """
39
39
  import rasa.core.run
40
40
  import rasa.shared.utils.common
41
- from rasa.core.utils import AvailableEndpoints
41
+ from rasa.core.available_endpoints import AvailableEndpoints
42
42
  from rasa.shared.constants import DOCS_BASE_URL
43
43
  from rasa.shared.utils.cli import print_warning
44
44
 
@@ -16,9 +16,9 @@ from rasa.cli.arguments.default_arguments import (
16
16
  add_remote_storage_param,
17
17
  )
18
18
  from rasa.core.agent import Agent
19
+ from rasa.core.available_endpoints import AvailableEndpoints
19
20
  from rasa.core.exceptions import AgentNotReady
20
21
  from rasa.core.processor import MessageProcessor
21
- from rasa.core.utils import AvailableEndpoints
22
22
  from rasa.dialogue_understanding.commands import Command
23
23
  from rasa.dialogue_understanding.generator import LLMBasedCommandGenerator
24
24
  from rasa.dialogue_understanding.generator.command_parser import DEFAULT_COMMANDS
rasa/cli/e2e_test.py CHANGED
@@ -18,8 +18,8 @@ from rasa.cli.arguments.default_arguments import (
18
18
  add_model_param,
19
19
  add_remote_storage_param,
20
20
  )
21
+ from rasa.core.available_endpoints import AvailableEndpoints
21
22
  from rasa.core.exceptions import AgentNotReady
22
- from rasa.core.utils import AvailableEndpoints
23
23
  from rasa.e2e_test.aggregate_test_stats_calculator import (
24
24
  AggregateTestStatsCalculator,
25
25
  )
rasa/cli/evaluate.py CHANGED
@@ -6,10 +6,10 @@ import rasa.cli.arguments.evaluate as arguments
6
6
  import rasa.shared.utils.cli
7
7
  from rasa import telemetry
8
8
  from rasa.cli import SubParsersAction
9
+ from rasa.core.available_endpoints import AvailableEndpoints
9
10
  from rasa.core.evaluation.marker_base import Marker, OperatorMarker
10
11
  from rasa.core.evaluation.marker_tracker_loader import MarkerTrackerLoader
11
12
  from rasa.core.tracker_stores.tracker_store import TrackerStore
12
- from rasa.core.utils import AvailableEndpoints
13
13
  from rasa.shared.core.domain import Domain
14
14
 
15
15
  STATS_OVERALL_SUFFIX = "-overall.csv"
rasa/cli/export.py CHANGED
@@ -16,10 +16,10 @@ from rasa.shared.constants import DOCS_URL_EVENT_BROKERS, DOCS_URL_TRACKER_STORE
16
16
  from rasa.shared.exceptions import RasaException
17
17
 
18
18
  if typing.TYPE_CHECKING:
19
+ from rasa.core.available_endpoints import AvailableEndpoints
19
20
  from rasa.core.brokers.broker import EventBroker
20
21
  from rasa.core.exporter import Exporter
21
22
  from rasa.core.tracker_stores.tracker_store import TrackerStore
22
- from rasa.core.utils import AvailableEndpoints
23
23
 
24
24
  logger = logging.getLogger(__name__)
25
25
 
@@ -20,8 +20,8 @@ from rasa.cli.e2e_test import (
20
20
  read_test_cases,
21
21
  validate_model_path,
22
22
  )
23
+ from rasa.core.available_endpoints import AvailableEndpoints
23
24
  from rasa.core.exceptions import AgentNotReady
24
- from rasa.core.utils import AvailableEndpoints
25
25
  from rasa.dialogue_understanding.generator.llm_based_command_generator import (
26
26
  LLMBasedCommandGenerator,
27
27
  )
@@ -208,10 +208,7 @@ def prepare_llm_fine_tuning_data(args: argparse.Namespace) -> None:
208
208
  sys.exit(0)
209
209
 
210
210
  flows = asyncio.run(e2e_test_runner.agent.processor.get_flows())
211
- llm_command_generator_config = _get_llm_command_generator_config(e2e_test_runner)
212
- llm_command_generator: Type[LLMBasedCommandGenerator] = _get_llm_command_generator(
213
- e2e_test_runner
214
- )
211
+ _validate_llm_command_generator_present(e2e_test_runner)
215
212
 
216
213
  # set up storage context
217
214
  storage_context = create_storage_context(StorageType.FILE, output_dir)
@@ -242,11 +239,11 @@ def prepare_llm_fine_tuning_data(args: argparse.Namespace) -> None:
242
239
  rephrase_config,
243
240
  args.num_rephrases,
244
241
  flows,
245
- llm_command_generator,
246
- llm_command_generator_config,
242
+ e2e_test_runner.agent,
247
243
  storage_context,
248
244
  )
249
245
  )
246
+
250
247
  statistics["num_passing_rephrased_user_messages"] = sum(
251
248
  [conversation.get_number_of_rephrases(True) for conversation in conversations]
252
249
  )
@@ -257,7 +254,11 @@ def prepare_llm_fine_tuning_data(args: argparse.Namespace) -> None:
257
254
 
258
255
  # 3. create fine-tuning dataset
259
256
  log_start_of_module("LLM Data Preparation")
260
- llm_fine_tuning_data = convert_to_fine_tuning_data(conversations, storage_context)
257
+ llm_fine_tuning_data = asyncio.run(
258
+ convert_to_fine_tuning_data(
259
+ conversations, storage_context, e2e_test_runner.agent
260
+ )
261
+ )
261
262
  statistics["num_ft_data_points"] = len(llm_fine_tuning_data)
262
263
  log_end_of_module("LLM Data Preparation", statistics)
263
264
 
@@ -311,9 +312,9 @@ def _get_llm_command_generator_config(e2e_test_runner: E2ETestRunner) -> Dict[st
311
312
  sys.exit(1)
312
313
 
313
314
 
314
- def _get_llm_command_generator(
315
+ def _validate_llm_command_generator_present(
315
316
  e2e_test_runner: E2ETestRunner,
316
- ) -> Type[LLMBasedCommandGenerator]:
317
+ ) -> None:
317
318
  train_schema = e2e_test_runner.agent.processor.model_metadata.train_schema # type: ignore
318
319
 
319
320
  for _, node in train_schema.nodes.items():
@@ -322,7 +323,7 @@ def _get_llm_command_generator(
322
323
  ) and not node.matches_type(
323
324
  MultiStepLLMCommandGenerator, include_subtypes=True
324
325
  ):
325
- return cast(Type[LLMBasedCommandGenerator], node.uses)
326
+ return
326
327
 
327
328
  rasa.shared.utils.cli.print_error(
328
329
  "The provided model is not trained using 'SingleStepLLMCommandGenerator' or "
@@ -0,0 +1,133 @@
1
+ from __future__ import annotations
2
+
3
+ import tempfile
4
+ from typing import Any, Dict, List, Optional, Text
5
+
6
+ from pydantic import BaseModel, ConfigDict, Field
7
+
8
+ from rasa.dialogue_understanding.patterns.domain_for_patterns import (
9
+ ContextField,
10
+ generate_domain_for_default_patterns,
11
+ )
12
+ from rasa.shared.core.domain import Domain
13
+ from rasa.shared.importers.importer import FlowSyncImporter, TrainingDataImporter
14
+ from rasa.shared.utils.llm import SystemPrompts, get_system_default_prompts
15
+ from rasa.shared.utils.yaml import read_yaml, write_yaml
16
+
17
+
18
+ class Response(BaseModel):
19
+ text: str = Field(..., description="The human-readable response string.")
20
+ metadata: Optional[Dict[str, Any]] = Field(
21
+ None, description="Optional metadata used by Rasa at runtime."
22
+ )
23
+
24
+
25
+ class Slot(BaseModel):
26
+ name: Text = Field(..., description="Name of the slot.")
27
+ type: Text = Field(..., description="Type of the slot.")
28
+ mappings: Optional[List[Dict[str, Any]]] = Field(
29
+ None, description="Mappings for the slot."
30
+ )
31
+ model_config = ConfigDict(extra="allow")
32
+
33
+
34
+ class PatternFlow(BaseModel):
35
+ description: str = Field(..., description="Description of the flow.")
36
+ name: Text = Field(..., description="Name of the flow.")
37
+ steps: List[Any] = Field(..., description="List of steps in the flow.")
38
+ nlu_trigger: Optional[Any] = Field(None, description="NLU trigger for the flow.")
39
+ persisted_slots: Optional[List[Text]] = Field(None, description="Slots to persist.")
40
+
41
+
42
+ class PatternDefaults(BaseModel):
43
+ """Content of `default_flows_for_patterns.yml` after it is loaded from disk."""
44
+
45
+ responses: Dict[Text, List[Response]] = Field(
46
+ default_factory=dict,
47
+ description="Response templates available out-of-the-box.",
48
+ )
49
+ slots: Dict[Text, Slot] = Field(
50
+ default_factory=dict, description="Slot definitions used by the default flows."
51
+ )
52
+ flows: Dict[Text, PatternFlow] = Field(
53
+ default_factory=dict, description="Default flows (conversation patterns)."
54
+ )
55
+
56
+
57
+ class RasaDefaults(PatternDefaults):
58
+ """Full set of defaults that Rasa injects when a project is created."""
59
+
60
+ prompts: SystemPrompts = Field(..., description="Built-in system prompts.")
61
+ actions: List[Text] = Field(..., description="Default actions shipped by Rasa.")
62
+ intents: List[Text] = Field(..., description="Default intents shipped by Rasa.")
63
+ contexts: Dict[Text, ContextField] = Field(
64
+ ..., description="Context fields that can appear on the conversation stack."
65
+ )
66
+
67
+ class Config:
68
+ extra = "forbid"
69
+ validate_assignment = True
70
+
71
+
72
+ def _get_domain_from_importer(config: Dict[Text, Any]) -> Domain:
73
+ """Get the domain from the TrainingDataImporter.
74
+
75
+ Args:
76
+ config: The config.yml file data.
77
+
78
+ Returns:
79
+ A Domain object .
80
+ """
81
+ with tempfile.NamedTemporaryFile("w+", suffix=".yml") as tmp:
82
+ write_yaml(config, tmp.name)
83
+ importer = TrainingDataImporter.load_from_config(
84
+ domain_path=FlowSyncImporter.default_pattern_path(),
85
+ config_path=tmp.name,
86
+ )
87
+ return importer.get_domain()
88
+
89
+
90
+ def get_pattern_defaults(config: Dict[Text, Any]) -> PatternDefaults:
91
+ """Get the default flows, responses and slots for patterns.
92
+
93
+ Args:
94
+ config: The config.yml file data.
95
+
96
+ Returns:
97
+ A PatternDefaults object containing the defaults.
98
+ """
99
+ domain = _get_domain_from_importer(config)
100
+ domain_dict = domain.as_dict()
101
+
102
+ # Make sure all the slots are exported, including the builtin slots
103
+ domain_dict["slots"] = {slot.name: slot.to_dict() for slot in domain.slots}
104
+
105
+ return PatternDefaults(**domain_dict)
106
+
107
+
108
+ def get_rasa_defaults(config_yaml: Text, endpoints_yaml: Text) -> RasaDefaults:
109
+ """Get the default values for a Rasa project.
110
+
111
+ Args:
112
+ config_yaml: The content of the config.yml file.
113
+ endpoints_yaml: The content of the endpoints.yml file.
114
+
115
+ Returns:
116
+ A RasaDefaults object containing the default values for the project.
117
+ """
118
+ config = read_yaml(config_yaml)
119
+ endpoints = read_yaml(endpoints_yaml)
120
+
121
+ prompts = get_system_default_prompts(config, endpoints)
122
+ pattern_domain = generate_domain_for_default_patterns()
123
+ pattern_defaults = get_pattern_defaults(config)
124
+
125
+ return RasaDefaults(
126
+ prompts=prompts,
127
+ actions=pattern_domain.actions,
128
+ intents=pattern_domain.intents,
129
+ contexts=pattern_domain.contexts,
130
+ responses=pattern_defaults.responses,
131
+ slots=pattern_defaults.slots,
132
+ flows=pattern_defaults.flows,
133
+ )
rasa/cli/run.py CHANGED
@@ -109,7 +109,7 @@ def run(args: argparse.Namespace) -> None:
109
109
  # configured
110
110
 
111
111
  import rasa.model
112
- from rasa.core.utils import AvailableEndpoints
112
+ from rasa.core.available_endpoints import AvailableEndpoints
113
113
 
114
114
  # start server if remote storage is configured
115
115
  if args.remote_storage is not None:
@@ -0,0 +1,53 @@
1
+ import argparse
2
+ from typing import List, Text
3
+
4
+ from rasa.cli import SubParsersAction
5
+ from rasa.cli.studio.upload import (
6
+ add_config_param,
7
+ add_data_param,
8
+ add_domain_param,
9
+ add_endpoint_param,
10
+ )
11
+ from rasa.shared.constants import (
12
+ DEFAULT_DOMAIN_PATH,
13
+ DEFAULT_ENDPOINTS_PATH,
14
+ )
15
+ from rasa.studio.link import handle_link
16
+
17
+
18
+ def add_subparser(
19
+ subparsers: SubParsersAction,
20
+ parents: List[argparse.ArgumentParser],
21
+ domain: Text = DEFAULT_DOMAIN_PATH,
22
+ ) -> None:
23
+ """Register the `rasa studio link` command with the main CLI.
24
+
25
+ Args:
26
+ subparsers: subparser we are going to attach to
27
+ parents: Parent parsers, needed to ensure tree structure in argparse
28
+ domain: Path to the assistant's domain file.
29
+ """
30
+ link_parser = subparsers.add_parser(
31
+ "link",
32
+ parents=parents,
33
+ conflict_handler="resolve",
34
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
35
+ help="Link the current project to an existing Rasa Studio assistant.",
36
+ )
37
+
38
+ link_parser.add_argument(
39
+ "assistant_name",
40
+ nargs=1,
41
+ type=str,
42
+ help="Name of the assistant in Rasa Studio.",
43
+ )
44
+
45
+ add_domain_param(link_parser, domain)
46
+ add_data_param(link_parser)
47
+ add_config_param(link_parser)
48
+ add_endpoint_param(
49
+ link_parser,
50
+ "Configuration file for the model endpoints.",
51
+ default=DEFAULT_ENDPOINTS_PATH,
52
+ )
53
+ link_parser.set_defaults(func=handle_link)
@@ -0,0 +1,78 @@
1
+ import argparse
2
+ from typing import List, Text
3
+
4
+ from rasa.cli import SubParsersAction
5
+ from rasa.cli.arguments.default_arguments import (
6
+ add_config_param,
7
+ add_endpoint_param,
8
+ )
9
+ from rasa.cli.studio.upload import add_data_param, add_domain_param
10
+ from rasa.shared.constants import (
11
+ DEFAULT_CONFIG_PATH,
12
+ DEFAULT_DOMAIN_PATH,
13
+ DEFAULT_ENDPOINTS_PATH,
14
+ )
15
+ from rasa.studio.pull import (
16
+ handle_pull,
17
+ handle_pull_config,
18
+ handle_pull_endpoints,
19
+ )
20
+
21
+
22
+ def add_subparser(
23
+ subparsers: SubParsersAction,
24
+ parents: List[argparse.ArgumentParser],
25
+ domain: Text = DEFAULT_DOMAIN_PATH,
26
+ ) -> None:
27
+ """Register `rasa studio pull` and its sub-commands.
28
+
29
+ Args:
30
+ subparsers: subparser we are going to attach to
31
+ parents: Parent parsers, needed to ensure tree structure in argparse
32
+ domain: Path to the assistant's domain file.
33
+ """
34
+ pull_parser = subparsers.add_parser(
35
+ "pull",
36
+ parents=parents,
37
+ conflict_handler="resolve",
38
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
39
+ help="Pull assistant data from Rasa Studio.",
40
+ )
41
+ pull_subparsers = pull_parser.add_subparsers()
42
+
43
+ # Arguments for pulling configuration only
44
+ config_parser = pull_subparsers.add_parser(
45
+ "config",
46
+ parents=parents,
47
+ conflict_handler="resolve",
48
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
49
+ help="Pull only the assistant configuration file.",
50
+ )
51
+ add_config_param(config_parser, default=DEFAULT_CONFIG_PATH)
52
+ config_parser.set_defaults(func=handle_pull_config)
53
+
54
+ # Arguments for pulling endpoints only
55
+ endpoints_parser = pull_subparsers.add_parser(
56
+ "endpoints",
57
+ parents=parents,
58
+ conflict_handler="resolve",
59
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
60
+ help="Pull only the endpoints configuration file.",
61
+ )
62
+ add_endpoint_param(
63
+ endpoints_parser,
64
+ "Configuration file for the model endpoints.",
65
+ default=DEFAULT_ENDPOINTS_PATH,
66
+ )
67
+ endpoints_parser.set_defaults(func=handle_pull_endpoints)
68
+
69
+ # Arguments for pulling the whole assistant data
70
+ add_domain_param(pull_parser, domain)
71
+ add_data_param(pull_parser)
72
+ add_config_param(pull_parser, default=DEFAULT_CONFIG_PATH)
73
+ add_endpoint_param(
74
+ pull_parser,
75
+ "Configuration file for the model endpoints.",
76
+ default=DEFAULT_ENDPOINTS_PATH,
77
+ )
78
+ pull_parser.set_defaults(func=handle_pull)
@@ -0,0 +1,78 @@
1
+ import argparse
2
+ from typing import List, Text
3
+
4
+ from rasa.cli import SubParsersAction
5
+ from rasa.cli.studio.upload import (
6
+ add_config_param,
7
+ add_data_param,
8
+ add_domain_param,
9
+ add_endpoint_param,
10
+ )
11
+ from rasa.shared.constants import (
12
+ DEFAULT_DOMAIN_PATH,
13
+ DEFAULT_ENDPOINTS_PATH,
14
+ )
15
+ from rasa.studio.push import (
16
+ handle_push,
17
+ handle_push_config,
18
+ handle_push_endpoints,
19
+ )
20
+
21
+
22
+ def add_subparser(
23
+ subparsers: SubParsersAction,
24
+ parents: List[argparse.ArgumentParser],
25
+ domain: Text = DEFAULT_DOMAIN_PATH,
26
+ ) -> None:
27
+ """Register the `rasa studio push` command and its sub-commands.
28
+
29
+ Args:
30
+ subparsers: The subparsers to add the command to.
31
+ parents: Parent parsers, needed to ensure tree structure in argparse
32
+ domain: Path to the assistant's domain file.
33
+ """
34
+ push_parser = subparsers.add_parser(
35
+ "push",
36
+ parents=parents,
37
+ conflict_handler="resolve",
38
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
39
+ help="Push assistant data to Rasa Studio.",
40
+ )
41
+ push_subparsers = push_parser.add_subparsers()
42
+
43
+ # Arguments for pushing configuration only
44
+ config_parser = push_subparsers.add_parser(
45
+ "config",
46
+ parents=parents,
47
+ conflict_handler="resolve",
48
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
49
+ help="Push only the assistant configuration file.",
50
+ )
51
+ add_config_param(config_parser)
52
+ config_parser.set_defaults(func=handle_push_config)
53
+
54
+ # Arguments for pushing endpoints only
55
+ endpoints_parser = push_subparsers.add_parser(
56
+ "endpoints",
57
+ parents=parents,
58
+ conflict_handler="resolve",
59
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
60
+ help="Push ONLY the endpoints configuration file.",
61
+ )
62
+ add_endpoint_param(
63
+ endpoints_parser,
64
+ "Configuration file for the model endpoints.",
65
+ default=DEFAULT_ENDPOINTS_PATH,
66
+ )
67
+ endpoints_parser.set_defaults(func=handle_push_endpoints)
68
+
69
+ # Arguments for pushing the whole assistant data
70
+ add_domain_param(push_parser, domain)
71
+ add_data_param(push_parser)
72
+ add_config_param(push_parser)
73
+ add_endpoint_param(
74
+ push_parser,
75
+ "Configuration file for the model endpoints.",
76
+ default=DEFAULT_ENDPOINTS_PATH,
77
+ )
78
+ push_parser.set_defaults(func=handle_push)
rasa/cli/studio/studio.py CHANGED
@@ -5,10 +5,15 @@ from urllib.parse import ParseResult, urlparse
5
5
  import questionary
6
6
 
7
7
  import rasa.cli.studio.download
8
+ import rasa.cli.studio.link
9
+ import rasa.cli.studio.pull
10
+ import rasa.cli.studio.push
8
11
  import rasa.cli.studio.train
9
12
  import rasa.cli.studio.upload
10
13
  import rasa.shared.utils.cli
11
14
  from rasa.cli import SubParsersAction
15
+ from rasa.cli.utils import get_validated_path
16
+ from rasa.shared.constants import DEFAULT_DOMAIN_PATH, DEFAULT_DOMAIN_PATHS
12
17
  from rasa.studio.auth import StudioAuth
13
18
  from rasa.studio.config import StudioConfig
14
19
 
@@ -33,6 +38,13 @@ def add_subparser(
33
38
  rasa.cli.studio.upload.add_subparser(studio_subparsers, parents)
34
39
  rasa.cli.studio.download.add_subparser(studio_subparsers, parents)
35
40
 
41
+ domain = get_validated_path(
42
+ DEFAULT_DOMAIN_PATH, "domain", DEFAULT_DOMAIN_PATHS, none_is_valid=True
43
+ )
44
+ rasa.cli.studio.link.add_subparser(studio_subparsers, parents, domain)
45
+ rasa.cli.studio.push.add_subparser(studio_subparsers, parents, domain)
46
+ rasa.cli.studio.pull.add_subparser(studio_subparsers, parents, domain)
47
+
36
48
  _add_config_subparser(studio_subparsers, parents)
37
49
  _add_login_subparser(studio_subparsers, parents)
38
50
 
rasa/cli/studio/upload.py CHANGED
@@ -54,3 +54,11 @@ def set_upload_arguments(parser: argparse.ArgumentParser) -> None:
54
54
  type=str,
55
55
  help="Name of intents to upload to Rasa Studio",
56
56
  )
57
+
58
+ parser.add_argument(
59
+ "assistant_name",
60
+ default=None,
61
+ nargs="?",
62
+ type=str,
63
+ help="Name of the assistant on Rasa Studio",
64
+ )
rasa/cli/train.py CHANGED
@@ -11,7 +11,7 @@ import rasa.cli.utils
11
11
  import rasa.core.utils
12
12
  import rasa.utils.common
13
13
  from rasa.cli import SubParsersAction
14
- from rasa.core import ContextualResponseRephraser
14
+ from rasa.core.nlg.contextual_response_rephraser import ContextualResponseRephraser
15
15
  from rasa.core.nlg.generator import NaturalLanguageGenerator
16
16
  from rasa.core.train import do_compare_training
17
17
  from rasa.engine.validation import validate_api_type_config_key_usage
rasa/cli/utils.py CHANGED
@@ -104,7 +104,7 @@ def get_validated_path(
104
104
  parameter=parameter,
105
105
  event_info=(f"Parameter '{parameter}' was not set. {shared_info}"),
106
106
  )
107
- else:
107
+ elif current not in default_options:
108
108
  structlogger.warn(
109
109
  "cli.get_validated_path.path_does_not_exists",
110
110
  path=current,
rasa/cli/x.py CHANGED
@@ -15,7 +15,7 @@ import rasa.utils.common
15
15
  import rasa.utils.io
16
16
  from rasa.cli import SubParsersAction
17
17
  from rasa.cli.arguments import x as arguments
18
- from rasa.core.utils import AvailableEndpoints
18
+ from rasa.core.available_endpoints import AvailableEndpoints
19
19
  from rasa.shared.constants import (
20
20
  DEFAULT_CREDENTIALS_PATH,
21
21
  DEFAULT_ENDPOINTS_PATH,
rasa/constants.py CHANGED
@@ -44,3 +44,5 @@ HTTP_STATUS_FORBIDDEN = 403
44
44
  HTTP_STATUS_NOT_FOUND = 404
45
45
 
46
46
  RASA_REMOTE_STORAGE_ENV_VAR_NAME = "RASA_REMOTE_STORAGE"
47
+
48
+ RASA_DIR_NAME = ".rasa"
rasa/core/__init__.py CHANGED
@@ -1,16 +0,0 @@
1
- import logging
2
-
3
- import rasa
4
- from rasa.core.nlg.contextual_response_rephraser import ContextualResponseRephraser
5
- from rasa.core.policies.enterprise_search_policy import EnterpriseSearchPolicy
6
- from rasa.core.policies.intentless_policy import IntentlessPolicy
7
-
8
- logging.getLogger(__name__).addHandler(logging.NullHandler())
9
-
10
- __version__ = rasa.__version__
11
-
12
- __all__ = [
13
- "EnterpriseSearchPolicy",
14
- "IntentlessPolicy",
15
- "ContextualResponseRephraser",
16
- ]
@@ -1152,7 +1152,11 @@ class ActionSendText(Action):
1152
1152
  fallback = {"text": ""}
1153
1153
  metadata_copy = copy.deepcopy(metadata) if metadata else {}
1154
1154
  message = metadata_copy.get("message", fallback)
1155
- return [create_bot_utterance(message, tracker.current_language)]
1155
+
1156
+ should_send_text = metadata_copy.get("should_send_text", True)
1157
+ if should_send_text:
1158
+ return [create_bot_utterance(message, tracker.current_language)]
1159
+ return []
1156
1160
 
1157
1161
 
1158
1162
  class ActionExtractSlots(Action):
@@ -25,7 +25,7 @@ class ActionRepeatBotMessages(Action):
25
25
  """Return the name of the action."""
26
26
  return ACTION_REPEAT_BOT_MESSAGES
27
27
 
28
- def _get_last_bot_events(self, tracker: DialogueStateTracker) -> List[Event]:
28
+ def _get_last_bot_events(self, tracker: DialogueStateTracker) -> List[BotUttered]:
29
29
  """Get the last consecutive bot events before the most recent user message.
30
30
 
31
31
  This function scans the dialogue history in reverse to find the last sequence of
@@ -48,33 +48,21 @@ class ActionRepeatBotMessages(Action):
48
48
  The elif condition doesn't break when it sees User3 event.
49
49
  But it does at User2 event.
50
50
  """
51
- # Skip action if we are in a collect information step whose
52
- # default behavior is to repeat anyways
53
- top_frame = tracker.stack.top(
54
- lambda frame: isinstance(frame, RepeatBotMessagesPatternFlowStackFrame)
55
- or isinstance(frame, UserSilencePatternFlowStackFrame)
56
- )
57
- if isinstance(top_frame, CollectInformationPatternFlowStackFrame):
58
- return []
59
51
  # filter user and bot events
60
- filtered = [
52
+ user_and_bot_events = [
61
53
  e for e in tracker.events if isinstance(e, (BotUttered, UserUttered))
62
54
  ]
63
- bot_events: List[Event] = []
55
+ last_bot_events: List[BotUttered] = []
64
56
 
65
57
  # find the last BotUttered events
66
- for e in reversed(filtered):
67
- if isinstance(e, BotUttered):
68
- # insert instead of append because the list is reversed
69
- bot_events.insert(0, e)
70
-
71
- # stop if a UserUttered event is found
72
- # only if we have collected some bot events already
73
- # this condition skips the first N UserUttered events
74
- elif bot_events:
58
+ for e in reversed(user_and_bot_events):
59
+ # stop when seeing a user event after having seen bot events already
60
+ if isinstance(e, UserUttered) and len(last_bot_events) > 0:
75
61
  break
62
+ elif isinstance(e, BotUttered):
63
+ last_bot_events.append(e)
76
64
 
77
- return bot_events
65
+ return list(reversed(last_bot_events))
78
66
 
79
67
  async def run(
80
68
  self,
@@ -85,5 +73,13 @@ class ActionRepeatBotMessages(Action):
85
73
  metadata: Optional[Dict[str, Any]] = None,
86
74
  ) -> List[Event]:
87
75
  """Send the last bot messages to the channel again"""
88
- bot_events = self._get_last_bot_events(tracker)
76
+ top_frame = tracker.stack.top(
77
+ lambda frame: isinstance(frame, RepeatBotMessagesPatternFlowStackFrame)
78
+ or isinstance(frame, UserSilencePatternFlowStackFrame)
79
+ )
80
+
81
+ bot_events: List[Event] = list(self._get_last_bot_events(tracker))
82
+ # drop the last bot event in a collect step as that part will be repeated anyway
83
+ if isinstance(top_frame, CollectInformationPatternFlowStackFrame):
84
+ bot_events = bot_events[:-1]
89
85
  return bot_events