rasa-pro 3.13.0.dev20250613__py3-none-any.whl → 3.13.0rc2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rasa-pro might be problematic. Click here for more details.

Files changed (160) hide show
  1. rasa/cli/e2e_test.py +0 -7
  2. rasa/cli/export.py +2 -0
  3. rasa/cli/project_templates/tutorial/config.yml +1 -1
  4. rasa/cli/project_templates/tutorial/endpoints.yml +1 -1
  5. rasa/cli/studio/download.py +1 -23
  6. rasa/cli/studio/link.py +0 -17
  7. rasa/cli/studio/pull.py +3 -2
  8. rasa/cli/studio/push.py +1 -1
  9. rasa/cli/studio/train.py +1 -5
  10. rasa/cli/studio/upload.py +1 -1
  11. rasa/core/agent.py +6 -0
  12. rasa/core/channels/__init__.py +3 -0
  13. rasa/core/channels/development_inspector.py +1 -1
  14. rasa/core/channels/facebook.py +1 -4
  15. rasa/core/channels/inspector/README.md +3 -3
  16. rasa/core/channels/inspector/dist/assets/{arc-c4b064fc.js → arc-371401b1.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-215b5026.js → blockDiagram-38ab4fdb-3f126156.js} +1 -1
  18. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-2b54a0a3.js → c4Diagram-3d4e48cf-12f22eb7.js} +1 -1
  19. rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +1 -0
  20. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-daacea5f.js → classDiagram-70f12bd4-03b1d386.js} +1 -1
  21. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-930d4dc2.js → classDiagram-v2-f2320105-84f69d63.js} +1 -1
  22. rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +1 -0
  23. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-83c206ba.js → createText-2e5e7dd3-ca47fd38.js} +1 -1
  24. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b0eb01d0.js → edges-e0da2a9e-f837ca8a.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-17586500.js → erDiagram-9861fffd-8717ac54.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-be2a1776.js → flowDb-956e92f1-94f38b83.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c2120ebd.js → flowDiagram-66a62f08-b616f9fb.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +1 -0
  29. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a6ab5c48.js → flowchart-elk-definition-4a651766-f5d24bb8.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-ef613457.js → ganttDiagram-c361ad54-b43ba8d9.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-d59185b3.js → gitGraphDiagram-72cf32ee-c3aafaa5.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{graph-0f155405.js → graph-0d0a2c10.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{index-3862675e-d5f1d1b7.js → index-3862675e-58ea0305.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{index-47737d3a.js → index-cce6f8a1.js} +3 -3
  35. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b07d141f.js → infoDiagram-f8f76790-b8f60461.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-1936d429.js → journeyDiagram-49397b02-95be5545.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{layout-dde8d0f3.js → layout-da885b9b.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{line-0c2c7ee0.js → line-f1c817d3.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{linear-35dd89a4.js → linear-d42801e6.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-56192851.js → mindmap-definition-fc14e90a-a38923a6.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-fc21ed78.js → pieDiagram-8a3498a8-ca6e71e9.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-25e98518.js → quadrantDiagram-120e2f19-b290dae9.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-546ff1f5.js → requirementDiagram-deff3bca-03f02ceb.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-02d8b82d.js → sankeyDiagram-04a897e0-c49eee40.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3ca5a92e.js → sequenceDiagram-704730f1-b2cd6a3d.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-128ea07c.js → stateDiagram-587899a1-e53a2028.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-95f290af.js → stateDiagram-v2-d93cdb3a-e1982a03.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-4984898a.js → styles-6aaf32cf-d0226ca5.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1bf266ba.js → styles-9a916d00-0e21dc00.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-60521c63.js → styles-c10674c1-9588494e.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-a25b6e12.js → svgDrawCommon-08f97a94-be478d4f.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-0fc086bf.js → timeline-definition-85554ec2-74631749.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-44ee592e.js → xychartDiagram-e933f94c-a043552f.js} +1 -1
  54. rasa/core/channels/inspector/dist/index.html +1 -1
  55. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +1 -1
  56. rasa/core/channels/socketio.py +56 -41
  57. rasa/core/channels/studio_chat.py +311 -8
  58. rasa/core/channels/voice_ready/audiocodes.py +1 -1
  59. rasa/core/channels/voice_ready/jambonz.py +5 -6
  60. rasa/core/channels/voice_ready/twilio_voice.py +13 -12
  61. rasa/core/channels/voice_ready/utils.py +22 -0
  62. rasa/core/channels/voice_stream/asr/azure.py +9 -0
  63. rasa/core/channels/voice_stream/audiocodes.py +5 -11
  64. rasa/core/channels/voice_stream/browser_audio.py +1 -1
  65. rasa/core/channels/voice_stream/genesys.py +35 -16
  66. rasa/core/channels/voice_stream/jambonz.py +232 -0
  67. rasa/core/channels/voice_stream/tts/__init__.py +8 -0
  68. rasa/core/channels/voice_stream/twilio_media_streams.py +12 -7
  69. rasa/core/channels/voice_stream/voice_channel.py +53 -15
  70. rasa/core/exporter.py +36 -0
  71. rasa/core/information_retrieval/faiss.py +18 -11
  72. rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
  73. rasa/core/nlg/contextual_response_rephraser.py +10 -1
  74. rasa/core/policies/enterprise_search_policy.py +189 -263
  75. rasa/core/policies/enterprise_search_policy_config.py +241 -0
  76. rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +6 -5
  77. rasa/core/policies/intentless_policy.py +47 -10
  78. rasa/core/processor.py +6 -0
  79. rasa/core/utils.py +11 -2
  80. rasa/dialogue_understanding/coexistence/llm_based_router.py +13 -11
  81. rasa/dialogue_understanding/commands/__init__.py +4 -0
  82. rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -2
  83. rasa/dialogue_understanding/commands/clarify_command.py +2 -2
  84. rasa/dialogue_understanding/commands/correct_slots_command.py +5 -6
  85. rasa/dialogue_understanding/commands/error_command.py +1 -1
  86. rasa/dialogue_understanding/commands/human_handoff_command.py +1 -3
  87. rasa/dialogue_understanding/commands/set_slot_command.py +4 -4
  88. rasa/dialogue_understanding/commands/skip_question_command.py +1 -3
  89. rasa/dialogue_understanding/commands/start_flow_command.py +3 -3
  90. rasa/dialogue_understanding/generator/command_generator.py +11 -1
  91. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -2
  92. rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
  93. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +0 -2
  94. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -0
  95. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +1 -0
  96. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +79 -0
  97. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +1 -0
  98. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +2 -2
  99. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -18
  100. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +17 -11
  101. rasa/dialogue_understanding/patterns/cancel.py +1 -2
  102. rasa/dialogue_understanding/patterns/clarify.py +1 -1
  103. rasa/dialogue_understanding/patterns/correction.py +2 -2
  104. rasa/dialogue_understanding/processor/command_processor.py +11 -12
  105. rasa/dialogue_understanding/stack/utils.py +3 -1
  106. rasa/e2e_test/constants.py +1 -1
  107. rasa/e2e_test/e2e_test_coverage_report.py +1 -1
  108. rasa/engine/graph.py +2 -2
  109. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +2 -6
  110. rasa/model_manager/runner_service.py +20 -4
  111. rasa/model_manager/trainer_service.py +6 -0
  112. rasa/privacy/privacy_manager.py +26 -11
  113. rasa/shared/constants.py +14 -0
  114. rasa/shared/core/command_payload_reader.py +1 -5
  115. rasa/shared/core/events.py +1 -3
  116. rasa/shared/core/flows/constants.py +2 -0
  117. rasa/shared/core/flows/flow.py +126 -12
  118. rasa/shared/core/flows/flows_list.py +18 -1
  119. rasa/shared/core/flows/steps/link.py +7 -2
  120. rasa/shared/core/flows/validation.py +25 -5
  121. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
  122. rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
  123. rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
  124. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
  125. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  126. rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
  127. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
  128. rasa/shared/providers/_configs/utils.py +0 -99
  129. rasa/shared/utils/common.py +1 -1
  130. rasa/shared/utils/configs.py +110 -0
  131. rasa/shared/utils/constants.py +0 -3
  132. rasa/shared/utils/llm.py +123 -8
  133. rasa/shared/utils/pykwalify_extensions.py +0 -9
  134. rasa/studio/constants.py +1 -0
  135. rasa/studio/data_handler.py +30 -9
  136. rasa/studio/download.py +171 -0
  137. rasa/studio/link.py +13 -2
  138. rasa/studio/prompts.py +221 -0
  139. rasa/studio/pull/__init__.py +0 -0
  140. rasa/studio/{download/flows.py → pull/data.py} +2 -131
  141. rasa/studio/{download → pull}/domains.py +1 -1
  142. rasa/studio/pull/pull.py +239 -0
  143. rasa/studio/push.py +7 -0
  144. rasa/studio/train.py +1 -1
  145. rasa/studio/upload.py +61 -5
  146. rasa/studio/utils.py +33 -0
  147. rasa/tracing/instrumentation/attribute_extractors.py +21 -7
  148. rasa/utils/common.py +11 -0
  149. rasa/version.py +1 -1
  150. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/METADATA +4 -4
  151. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/RECORD +155 -147
  152. rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +0 -1
  153. rasa/core/channels/inspector/dist/assets/clone-e847561e.js +0 -1
  154. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +0 -1
  155. rasa/studio/download/download.py +0 -416
  156. rasa/studio/pull.py +0 -94
  157. /rasa/{studio/download → core/information_retrieval/ingestion}/__init__.py +0 -0
  158. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/NOTICE +0 -0
  159. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/WHEEL +0 -0
  160. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/entry_points.txt +0 -0
@@ -1 +0,0 @@
1
- import{aI as o,aJ as r}from"./index-47737d3a.js";const s=(a,n)=>o.lang.round(r.parse(a)[n]),e=s;export{e as c};
@@ -1 +0,0 @@
1
- import{c as r}from"./graph-0f155405.js";var e=4;function a(o){return r(o,e)}export{a as c};
@@ -1 +0,0 @@
1
- import{p as e,f as o}from"./flowDb-956e92f1-be2a1776.js";import{f as t,g as a}from"./styles-c10674c1-60521c63.js";import{u as i}from"./index-47737d3a.js";import"./graph-0f155405.js";import"./layout-dde8d0f3.js";import"./index-3862675e-d5f1d1b7.js";import"./clone-e847561e.js";import"./edges-e0da2a9e-b0eb01d0.js";import"./createText-2e5e7dd3-83c206ba.js";import"./line-0c2c7ee0.js";import"./array-9f3ba611.js";import"./path-53f90ab3.js";import"./channel-3730f5fd.js";const M={parser:e,db:o,renderer:t,styles:a,init:r=>{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,i({flowchart:{arrowMarkerAbsolute:r.arrowMarkerAbsolute}}),t.setConf(r.flowchart),o.clear(),o.setGen("gen-2")}};export{M as diagram};
@@ -1,416 +0,0 @@
1
- import argparse
2
- from pathlib import Path
3
- from typing import Dict, Optional, Tuple
4
-
5
- import questionary
6
- import structlog
7
- from ruamel import yaml
8
- from ruamel.yaml.scalarstring import LiteralScalarString
9
-
10
- import rasa.cli.utils
11
- import rasa.shared.utils.cli
12
- from rasa.shared.constants import (
13
- DEFAULT_CONFIG_PATH,
14
- DEFAULT_DATA_PATH,
15
- DEFAULT_DOMAIN_PATH,
16
- DEFAULT_DOMAIN_PATHS,
17
- DEFAULT_ENDPOINTS_PATH,
18
- )
19
- from rasa.shared.core.flows.yaml_flows_io import YamlFlowsWriter
20
- from rasa.shared.importers.importer import TrainingDataImporter
21
- from rasa.shared.utils.yaml import read_yaml
22
- from rasa.studio import data_handler
23
- from rasa.studio.config import StudioConfig
24
- from rasa.studio.constants import (
25
- STUDIO_DOMAIN_FILENAME,
26
- STUDIO_FLOWS_FILENAME,
27
- STUDIO_NLU_FILENAME,
28
- )
29
- from rasa.studio.data_handler import StudioDataHandler, import_data_from_studio
30
- from rasa.studio.download.domains import merge_domain_with_overwrite
31
- from rasa.studio.download.flows import merge_flows_with_overwrite
32
- from rasa.utils.mapper import RasaPrimitiveStorageMapper
33
-
34
- structlogger = structlog.getLogger(__name__)
35
-
36
-
37
- def handle_download(args: argparse.Namespace) -> None:
38
- """Main function to handle downloading and merging data.
39
-
40
- Args:
41
- args: The command line arguments.
42
- """
43
- handler = StudioDataHandler(
44
- studio_config=StudioConfig.read_config(),
45
- assistant_name=args.assistant_name[0],
46
- )
47
- handler.request_all_data()
48
-
49
- domain_path, data_path = _prepare_data_and_domain_paths(args)
50
-
51
- # Handle config and endpoints.
52
- config_path, write_config = _handle_file_overwrite(
53
- args.config, DEFAULT_CONFIG_PATH, "config"
54
- )
55
- endpoints_path, write_endpoints = _handle_file_overwrite(
56
- args.endpoints, DEFAULT_ENDPOINTS_PATH, "endpoints"
57
- )
58
- message_parts = []
59
- config_path = config_path if write_config else None
60
- endpoints_path = endpoints_path if write_endpoints else None
61
-
62
- if config_path:
63
- config_data = handler.get_config()
64
- if not config_data:
65
- rasa.shared.utils.cli.print_error_and_exit("No config data found.")
66
- with open(config_path, "w") as f:
67
- f.write(config_data)
68
- message_parts.append(f"config to '{config_path}'")
69
- if endpoints_path:
70
- endpoints_data = handler.get_endpoints()
71
- if not endpoints_data:
72
- raise ValueError("No endpoints data found.")
73
- with open(endpoints_path, "w") as f:
74
- f.write(endpoints_data)
75
- message_parts.append(f"endpoints to '{endpoints_path}'")
76
- if message_parts:
77
- message = "Downloaded " + " and ".join(message_parts)
78
- structlogger.info("studio.download.config_endpoints", event_info=message)
79
-
80
- if not args.overwrite:
81
- _handle_download_no_overwrite(handler, domain_path, data_path)
82
- else:
83
- _handle_download_with_overwrite(handler, domain_path, data_path)
84
-
85
-
86
- def _prepare_data_and_domain_paths(args: argparse.Namespace) -> Tuple[Path, Path]:
87
- """Prepars the domain and data paths based on the provided arguments.
88
-
89
- Args:
90
- args: The command line arguments.
91
-
92
- Returns:
93
- A tuple containing the domain path and a list of data paths.
94
- """
95
- # Prepare domain path.
96
- domain_path = rasa.cli.utils.get_validated_path(
97
- args.domain, "domain", DEFAULT_DOMAIN_PATHS, none_is_valid=True
98
- )
99
- domain_or_default_path = args.domain or DEFAULT_DOMAIN_PATH
100
-
101
- if domain_path is None:
102
- domain_path = Path(domain_or_default_path)
103
- domain_path.touch()
104
-
105
- if isinstance(domain_path, str):
106
- domain_path = Path(domain_path)
107
-
108
- if domain_path.is_file():
109
- if not args.overwrite:
110
- domain_path.unlink()
111
- domain_path.touch()
112
-
113
- if domain_path.is_dir():
114
- if not args.overwrite:
115
- domain_path = domain_path / STUDIO_DOMAIN_FILENAME
116
- domain_path.touch()
117
-
118
- data_path = rasa.cli.utils.get_validated_path(
119
- args.data[0], "data", DEFAULT_DATA_PATH, none_is_valid=True
120
- )
121
-
122
- data_path = Path(data_path or args.data[0])
123
- if not (data_path.is_file() or data_path.is_dir()):
124
- data_path.mkdir(parents=True, exist_ok=True)
125
-
126
- return domain_path, data_path
127
-
128
-
129
- def _handle_file_overwrite(
130
- file_path: Optional[str], default_path: str, file_type: str
131
- ) -> Tuple[Optional[Path], bool]:
132
- """Determines whether to overwrite an existing file or create a new one.
133
-
134
- Works for config and endpoints at this moment.
135
-
136
- Args:
137
- file_path: The path to the file.
138
- default_path: The default path to use if no file path is provided.
139
- file_type: The type of the file (e.g., config, endpoints).
140
-
141
- Returns:
142
- A tuple of the file path and a boolean indicating overwrite status.
143
- """
144
- file_already_exists = rasa.cli.utils.get_validated_path(
145
- file_path, file_type, default_path, none_is_valid=True
146
- )
147
- write_file = False
148
- path = None
149
- file_or_default_path = file_path or default_path
150
-
151
- if file_already_exists is None:
152
- path = Path(file_or_default_path)
153
- if path.is_dir():
154
- path = path / default_path
155
- return path, True
156
-
157
- if questionary.confirm(
158
- f"{file_type.capitalize()} file '{file_or_default_path}' already exists. "
159
- f"Do you want to overwrite it?"
160
- ).ask():
161
- write_file = True
162
- path = Path(file_or_default_path)
163
- return path, write_file
164
-
165
-
166
- def _handle_download_no_overwrite(
167
- handler: StudioDataHandler, domain_path: Path, data_path: Path
168
- ) -> None:
169
- """Handles downloading without overwriting existing files.
170
-
171
- Args:
172
- handler: The StudioDataHandler instance.
173
- domain_path: The path to the domain file or directory.
174
- data_paths: The paths to the data files or directories.
175
- """
176
- data_from_studio, data_local = import_data_from_studio(
177
- handler, domain_path, data_path
178
- )
179
- _merge_domain_no_overwrite(domain_path, data_from_studio, data_local)
180
- _merge_data_no_overwrite(data_path, handler, data_from_studio, data_local)
181
-
182
-
183
- def _merge_domain_no_overwrite(
184
- domain_path: Path,
185
- data_from_studio: TrainingDataImporter,
186
- data_local: TrainingDataImporter,
187
- ) -> None:
188
- """
189
- Merges the domain data without overwriting.
190
-
191
- If the domain path is a directory, a new domain file is created under that folder.
192
- If the domain path is a file, it merges both domains into that file.
193
-
194
- Args:
195
- domain_path: The path to the domain file or directory.
196
- data_from_studio: The Studio data importer.
197
- data_local: The local data importer.
198
- """
199
- if domain_path.is_dir():
200
- _merge_directory_domain(domain_path, data_from_studio, data_local)
201
- elif domain_path.is_file():
202
- _merge_file_domain(domain_path, data_from_studio, data_local)
203
-
204
-
205
- def _merge_directory_domain(
206
- domain_path: Path,
207
- data_from_studio: TrainingDataImporter,
208
- data_local: TrainingDataImporter,
209
- ) -> None:
210
- """Merges domain data without overwriting when the domain is a directory.
211
-
212
- Args:
213
- domain_path: The path to the domain directory.
214
- data_from_studio: The Studio data importer.
215
- data_local: The local data importer.
216
- """
217
- from rasa.shared.core.domain import Domain
218
-
219
- studio_domain_path = domain_path / STUDIO_NLU_FILENAME
220
- new_domain_data = data_handler.combine_domains(
221
- data_from_studio.get_user_domain().as_dict(),
222
- data_local.get_user_domain().as_dict(),
223
- )
224
- studio_domain = Domain.from_dict(new_domain_data)
225
-
226
- if not studio_domain.is_empty():
227
- studio_domain.persist(studio_domain_path)
228
- else:
229
- structlogger.warning(
230
- "studio.download.merge_directory_domain",
231
- event_info="No additional domain data found in Studio assistant.",
232
- )
233
-
234
-
235
- def _merge_file_domain(
236
- domain_path: Path,
237
- data_from_studio: TrainingDataImporter,
238
- data_local: TrainingDataImporter,
239
- ) -> None:
240
- """Merges domain data without overwriting when the domain is a file.
241
-
242
- Args:
243
- domain_path: The path to the domain file.
244
- data_from_studio: The Studio data importer.
245
- data_local: The local data importer.
246
- """
247
- domain_merged = data_local.get_user_domain().merge(
248
- data_from_studio.get_user_domain()
249
- )
250
- domain_merged.persist(domain_path)
251
-
252
-
253
- def _merge_data_no_overwrite(
254
- data_path: Path,
255
- handler: StudioDataHandler,
256
- data_from_studio: TrainingDataImporter,
257
- data_local: TrainingDataImporter,
258
- ) -> None:
259
- """Merges NLU and flow data without overwriting existing data.
260
-
261
- Args:
262
- data_path: The paths to the data files or directories.
263
- handler: The StudioDataHandler instance.
264
- data_from_studio: The Studio data importer.
265
- data_local: The local data importer.
266
- """
267
- if not data_path:
268
- structlogger.warning(
269
- "studio.download.merge_data_no_overwrite.no_path",
270
- event_info="No data paths provided. Skipping data merge.",
271
- )
272
- return
273
-
274
- if data_path.is_file():
275
- _merge_file_data_no_overwrite(data_path, handler, data_from_studio, data_local)
276
- elif data_path.is_dir():
277
- _merge_dir_data_no_overwrite(data_path, handler, data_from_studio, data_local)
278
- else:
279
- structlogger.warning(
280
- "studio.download.merge_data_no_overwrite.invalid_path",
281
- event_info=(
282
- f"Provided path '{data_path}' is neither a file nor a directory."
283
- ),
284
- )
285
-
286
-
287
- def _merge_file_data_no_overwrite(
288
- data_path: Path,
289
- handler: StudioDataHandler,
290
- data_from_studio: TrainingDataImporter,
291
- data_local: TrainingDataImporter,
292
- ) -> None:
293
- """Merges NLU and flows data into a single file without overwriting.
294
-
295
- Args:
296
- data_path: Path to the single data file.
297
- handler: The StudioDataHandler instance.
298
- data_from_studio: The Studio data importer.
299
- data_local: The local data importer.
300
- """
301
- if handler.has_nlu():
302
- merged_nlu = data_local.get_nlu_data().merge(data_from_studio.get_nlu_data())
303
- merged_nlu.persist_nlu(str(data_path))
304
- if handler.has_flows():
305
- merged_flows = data_local.get_user_flows().merge(
306
- data_from_studio.get_user_flows()
307
- )
308
- YamlFlowsWriter.dump(merged_flows.underlying_flows, data_path)
309
-
310
-
311
- def _merge_dir_data_no_overwrite(
312
- dir_path: Path,
313
- handler: StudioDataHandler,
314
- data_from_studio: TrainingDataImporter,
315
- data_local: TrainingDataImporter,
316
- ) -> None:
317
- """Merges NLU and flows data into a single directory without overwriting.
318
-
319
- Args:
320
- dir_path: Path to the data directory.
321
- handler: The StudioDataHandler instance.
322
- data_from_studio: The Studio data importer.
323
- data_local: The local data importer.
324
- """
325
- if handler.has_nlu():
326
- nlu_path = dir_path / Path(STUDIO_NLU_FILENAME)
327
- _persist_nlu_diff(data_local, data_from_studio, nlu_path)
328
- if handler.has_flows():
329
- flows_path = dir_path / Path(STUDIO_FLOWS_FILENAME)
330
- _persist_flows_diff(data_local, data_from_studio, flows_path)
331
-
332
-
333
- def _handle_download_with_overwrite(
334
- handler: StudioDataHandler, domain_path: Path, data_path: Path
335
- ) -> None:
336
- """Handles downloading and merging data when the user opts for overwrite.
337
-
338
- Args:
339
- handler: The StudioDataHandler instance.
340
- domain_path: The path to the domain file or directory.
341
- data_path: The paths to the data files or directories.
342
- """
343
- data_from_studio, data_local = import_data_from_studio(
344
- handler, domain_path, data_path
345
- )
346
- mapper = RasaPrimitiveStorageMapper(
347
- domain_path=domain_path, training_data_paths=[data_path]
348
- )
349
- merge_domain_with_overwrite(data_from_studio, data_local, domain_path)
350
- merge_flows_with_overwrite(data_path, handler, data_from_studio, data_local, mapper)
351
-
352
-
353
- def _persist_nlu_diff(
354
- data_local: TrainingDataImporter,
355
- data_from_studio: TrainingDataImporter,
356
- data_path: Path,
357
- ) -> None:
358
- """Creates a new NLU file from the diff of local and studio data.
359
-
360
- Args:
361
- data_local: The local training data.
362
- data_from_studio: The training data from Rasa Studio.
363
- data_path: The path to the NLU file.
364
- """
365
- new_nlu_data = data_handler.create_new_nlu_from_diff(
366
- read_yaml(data_from_studio.get_nlu_data().nlu_as_yaml()),
367
- read_yaml(data_local.get_nlu_data().nlu_as_yaml()),
368
- )
369
- if new_nlu_data["nlu"]:
370
- pretty_write_nlu_yaml(new_nlu_data, data_path)
371
- else:
372
- structlogger.warning(
373
- "studio.download.persist_nlu_diff",
374
- event_info="No additional nlu data found.",
375
- )
376
-
377
-
378
- def _persist_flows_diff(
379
- data_local: TrainingDataImporter,
380
- data_from_studio: TrainingDataImporter,
381
- data_path: Path,
382
- ) -> None:
383
- """Creates a new flows file from the diff of local and studio data.
384
-
385
- Args:
386
- data_local: The local training data.
387
- data_from_studio: The training data from Rasa Studio.
388
- data_path: The path to the flows file.
389
- """
390
- new_flows_data = data_handler.create_new_flows_from_diff(
391
- data_from_studio.get_user_flows().underlying_flows,
392
- data_local.get_user_flows().underlying_flows,
393
- )
394
- if new_flows_data:
395
- YamlFlowsWriter.dump(new_flows_data, data_path)
396
- else:
397
- structlogger.warning(
398
- "studio.download.persist_flows_diff",
399
- event_info="No additional flows data found.",
400
- )
401
-
402
-
403
- def pretty_write_nlu_yaml(data: Dict, file: Path) -> None:
404
- """Writes the NLU YAML in a pretty way.
405
-
406
- Args:
407
- data: The data to write.
408
- file: The file to write to.
409
- """
410
- dumper = yaml.YAML()
411
- if nlu_data := data.get("nlu"):
412
- for item in nlu_data:
413
- if item.get("examples"):
414
- item["examples"] = LiteralScalarString(item["examples"])
415
- with file.open("w", encoding="utf-8") as outfile:
416
- dumper.dump(data, outfile)
rasa/studio/pull.py DELETED
@@ -1,94 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import argparse
4
- from pathlib import Path
5
- from typing import Text, Union
6
-
7
- import structlog
8
-
9
- import rasa.cli.utils
10
- import rasa.shared.utils.cli
11
- from rasa.shared.constants import DEFAULT_CONFIG_PATH, DEFAULT_ENDPOINTS_PATH
12
- from rasa.shared.utils.io import write_text_file
13
- from rasa.studio.data_handler import StudioDataHandler
14
- from rasa.studio.download.download import handle_download
15
- from rasa.studio.link import get_studio_config, read_assistant_name
16
-
17
- structlogger = structlog.get_logger(__name__)
18
-
19
-
20
- def _write_to_file(
21
- content: Text, file_type: Text, file_path: Text, default_path: Text
22
- ) -> None:
23
- """Write the content to a file.
24
-
25
- Args:
26
- content: The content to write.
27
- file_type: The type of file (e.g., "config" or "endpoints".).
28
- file_path: The path to the file.
29
- default_path: The default path to use file_path is not valid.
30
- """
31
- path: Union[Path, str, None] = rasa.cli.utils.get_validated_path(
32
- file_path, file_type, default_path, none_is_valid=True
33
- )
34
- write_text_file(content, path, encoding="utf-8")
35
- rasa.shared.utils.cli.print_success(f"Pulled {file_type} data from assistant.")
36
-
37
-
38
- def handle_pull(args: argparse.Namespace) -> None:
39
- """Pull all data and overwrite the local assistant.
40
-
41
- Args:
42
- args: The parsed arguments.
43
- """
44
- assistant_name = read_assistant_name()
45
-
46
- # Use the CLI command logic to download with overwrite
47
- download_args = argparse.Namespace(**vars(args))
48
- download_args.assistant_name = [assistant_name]
49
- download_args.overwrite = True
50
-
51
- handle_download(download_args)
52
- rasa.shared.utils.cli.print_success("Pulled the data from assistant.")
53
-
54
-
55
- def handle_pull_config(args: argparse.Namespace) -> None:
56
- """Pull just the assistant's `config.yml`.
57
-
58
- Args:
59
- args: The parsed arguments.
60
- """
61
- studio_cfg = get_studio_config()
62
- assistant_name = read_assistant_name()
63
-
64
- handler = StudioDataHandler(studio_cfg, assistant_name)
65
- handler.request_all_data()
66
-
67
- config_yaml = handler.get_config()
68
- if not config_yaml:
69
- rasa.shared.utils.cli.print_error_and_exit(
70
- "No configuration data was found in the Studio assistant."
71
- )
72
-
73
- _write_to_file(config_yaml, "config", args.config, DEFAULT_CONFIG_PATH)
74
-
75
-
76
- def handle_pull_endpoints(args: argparse.Namespace) -> None:
77
- """Pull just the assistant's `endpoints.yml`.
78
-
79
- Args:
80
- args: The parsed arguments.
81
- """
82
- studio_cfg = get_studio_config()
83
- assistant_name = read_assistant_name()
84
-
85
- handler = StudioDataHandler(studio_cfg, assistant_name)
86
- handler.request_all_data()
87
-
88
- endpoints_yaml = handler.get_endpoints()
89
- if not endpoints_yaml:
90
- rasa.shared.utils.cli.print_error_and_exit(
91
- "No endpoints data was found in the Studio assistant."
92
- )
93
-
94
- _write_to_file(endpoints_yaml, "endpoints", args.endpoints, DEFAULT_ENDPOINTS_PATH)