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.
- rasa/cli/e2e_test.py +0 -7
- rasa/cli/export.py +2 -0
- rasa/cli/project_templates/tutorial/config.yml +1 -1
- rasa/cli/project_templates/tutorial/endpoints.yml +1 -1
- rasa/cli/studio/download.py +1 -23
- rasa/cli/studio/link.py +0 -17
- rasa/cli/studio/pull.py +3 -2
- rasa/cli/studio/push.py +1 -1
- rasa/cli/studio/train.py +1 -5
- rasa/cli/studio/upload.py +1 -1
- rasa/core/agent.py +6 -0
- rasa/core/channels/__init__.py +3 -0
- rasa/core/channels/development_inspector.py +1 -1
- rasa/core/channels/facebook.py +1 -4
- rasa/core/channels/inspector/README.md +3 -3
- rasa/core/channels/inspector/dist/assets/{arc-c4b064fc.js → arc-371401b1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-215b5026.js → blockDiagram-38ab4fdb-3f126156.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-2b54a0a3.js → c4Diagram-3d4e48cf-12f22eb7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-daacea5f.js → classDiagram-70f12bd4-03b1d386.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-930d4dc2.js → classDiagram-v2-f2320105-84f69d63.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-83c206ba.js → createText-2e5e7dd3-ca47fd38.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b0eb01d0.js → edges-e0da2a9e-f837ca8a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-17586500.js → erDiagram-9861fffd-8717ac54.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-be2a1776.js → flowDb-956e92f1-94f38b83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c2120ebd.js → flowDiagram-66a62f08-b616f9fb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a6ab5c48.js → flowchart-elk-definition-4a651766-f5d24bb8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-ef613457.js → ganttDiagram-c361ad54-b43ba8d9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-d59185b3.js → gitGraphDiagram-72cf32ee-c3aafaa5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-0f155405.js → graph-0d0a2c10.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-d5f1d1b7.js → index-3862675e-58ea0305.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-47737d3a.js → index-cce6f8a1.js} +3 -3
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b07d141f.js → infoDiagram-f8f76790-b8f60461.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-1936d429.js → journeyDiagram-49397b02-95be5545.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-dde8d0f3.js → layout-da885b9b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-0c2c7ee0.js → line-f1c817d3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-35dd89a4.js → linear-d42801e6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-56192851.js → mindmap-definition-fc14e90a-a38923a6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-fc21ed78.js → pieDiagram-8a3498a8-ca6e71e9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-25e98518.js → quadrantDiagram-120e2f19-b290dae9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-546ff1f5.js → requirementDiagram-deff3bca-03f02ceb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-02d8b82d.js → sankeyDiagram-04a897e0-c49eee40.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3ca5a92e.js → sequenceDiagram-704730f1-b2cd6a3d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-128ea07c.js → stateDiagram-587899a1-e53a2028.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-95f290af.js → stateDiagram-v2-d93cdb3a-e1982a03.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-4984898a.js → styles-6aaf32cf-d0226ca5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1bf266ba.js → styles-9a916d00-0e21dc00.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-60521c63.js → styles-c10674c1-9588494e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-a25b6e12.js → svgDrawCommon-08f97a94-be478d4f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-0fc086bf.js → timeline-definition-85554ec2-74631749.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-44ee592e.js → xychartDiagram-e933f94c-a043552f.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +1 -1
- rasa/core/channels/socketio.py +56 -41
- rasa/core/channels/studio_chat.py +311 -8
- rasa/core/channels/voice_ready/audiocodes.py +1 -1
- rasa/core/channels/voice_ready/jambonz.py +5 -6
- rasa/core/channels/voice_ready/twilio_voice.py +13 -12
- rasa/core/channels/voice_ready/utils.py +22 -0
- rasa/core/channels/voice_stream/asr/azure.py +9 -0
- rasa/core/channels/voice_stream/audiocodes.py +5 -11
- rasa/core/channels/voice_stream/browser_audio.py +1 -1
- rasa/core/channels/voice_stream/genesys.py +35 -16
- rasa/core/channels/voice_stream/jambonz.py +232 -0
- rasa/core/channels/voice_stream/tts/__init__.py +8 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +12 -7
- rasa/core/channels/voice_stream/voice_channel.py +53 -15
- rasa/core/exporter.py +36 -0
- rasa/core/information_retrieval/faiss.py +18 -11
- rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
- rasa/core/nlg/contextual_response_rephraser.py +10 -1
- rasa/core/policies/enterprise_search_policy.py +189 -263
- rasa/core/policies/enterprise_search_policy_config.py +241 -0
- rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +6 -5
- rasa/core/policies/intentless_policy.py +47 -10
- rasa/core/processor.py +6 -0
- rasa/core/utils.py +11 -2
- rasa/dialogue_understanding/coexistence/llm_based_router.py +13 -11
- rasa/dialogue_understanding/commands/__init__.py +4 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -2
- rasa/dialogue_understanding/commands/clarify_command.py +2 -2
- rasa/dialogue_understanding/commands/correct_slots_command.py +5 -6
- rasa/dialogue_understanding/commands/error_command.py +1 -1
- rasa/dialogue_understanding/commands/human_handoff_command.py +1 -3
- rasa/dialogue_understanding/commands/set_slot_command.py +4 -4
- rasa/dialogue_understanding/commands/skip_question_command.py +1 -3
- rasa/dialogue_understanding/commands/start_flow_command.py +3 -3
- rasa/dialogue_understanding/generator/command_generator.py +11 -1
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -2
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +0 -2
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +79 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +2 -2
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -18
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +17 -11
- rasa/dialogue_understanding/patterns/cancel.py +1 -2
- rasa/dialogue_understanding/patterns/clarify.py +1 -1
- rasa/dialogue_understanding/patterns/correction.py +2 -2
- rasa/dialogue_understanding/processor/command_processor.py +11 -12
- rasa/dialogue_understanding/stack/utils.py +3 -1
- rasa/e2e_test/constants.py +1 -1
- rasa/e2e_test/e2e_test_coverage_report.py +1 -1
- rasa/engine/graph.py +2 -2
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +2 -6
- rasa/model_manager/runner_service.py +20 -4
- rasa/model_manager/trainer_service.py +6 -0
- rasa/privacy/privacy_manager.py +26 -11
- rasa/shared/constants.py +14 -0
- rasa/shared/core/command_payload_reader.py +1 -5
- rasa/shared/core/events.py +1 -3
- rasa/shared/core/flows/constants.py +2 -0
- rasa/shared/core/flows/flow.py +126 -12
- rasa/shared/core/flows/flows_list.py +18 -1
- rasa/shared/core/flows/steps/link.py +7 -2
- rasa/shared/core/flows/validation.py +25 -5
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
- rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
- rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
- rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
- rasa/shared/providers/_configs/openai_client_config.py +1 -1
- rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
- rasa/shared/providers/_configs/utils.py +0 -99
- rasa/shared/utils/common.py +1 -1
- rasa/shared/utils/configs.py +110 -0
- rasa/shared/utils/constants.py +0 -3
- rasa/shared/utils/llm.py +123 -8
- rasa/shared/utils/pykwalify_extensions.py +0 -9
- rasa/studio/constants.py +1 -0
- rasa/studio/data_handler.py +30 -9
- rasa/studio/download.py +171 -0
- rasa/studio/link.py +13 -2
- rasa/studio/prompts.py +221 -0
- rasa/studio/pull/__init__.py +0 -0
- rasa/studio/{download/flows.py → pull/data.py} +2 -131
- rasa/studio/{download → pull}/domains.py +1 -1
- rasa/studio/pull/pull.py +239 -0
- rasa/studio/push.py +7 -0
- rasa/studio/train.py +1 -1
- rasa/studio/upload.py +61 -5
- rasa/studio/utils.py +33 -0
- rasa/tracing/instrumentation/attribute_extractors.py +21 -7
- rasa/utils/common.py +11 -0
- rasa/version.py +1 -1
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/METADATA +4 -4
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/RECORD +155 -147
- rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-e847561e.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +0 -1
- rasa/studio/download/download.py +0 -416
- rasa/studio/pull.py +0 -94
- /rasa/{studio/download → core/information_retrieval/ingestion}/__init__.py +0 -0
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/entry_points.txt +0 -0
rasa/studio/prompts.py
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Dict, List, Optional, Text
|
|
3
|
+
|
|
4
|
+
import structlog
|
|
5
|
+
|
|
6
|
+
from rasa.core.policies.enterprise_search_policy import EnterpriseSearchPolicy
|
|
7
|
+
from rasa.dialogue_understanding.generator.llm_based_command_generator import (
|
|
8
|
+
LLMBasedCommandGenerator,
|
|
9
|
+
)
|
|
10
|
+
from rasa.shared.constants import (
|
|
11
|
+
CONFIG_NAME_KEY,
|
|
12
|
+
CONFIG_PIPELINE_KEY,
|
|
13
|
+
CONFIG_POLICIES_KEY,
|
|
14
|
+
DEFAULT_CONFIG_PATH,
|
|
15
|
+
DEFAULT_ENDPOINTS_PATH,
|
|
16
|
+
DEFAULT_PROMPTS_PATH,
|
|
17
|
+
PROMPT_CONFIG_KEY,
|
|
18
|
+
PROMPT_TEMPLATE_CONFIG_KEY,
|
|
19
|
+
)
|
|
20
|
+
from rasa.shared.utils.common import all_subclasses
|
|
21
|
+
from rasa.shared.utils.llm import get_system_default_prompts
|
|
22
|
+
from rasa.shared.utils.yaml import read_yaml, write_yaml
|
|
23
|
+
|
|
24
|
+
structlogger = structlog.get_logger()
|
|
25
|
+
|
|
26
|
+
CONTEXTUAL_RESPONSE_REPHRASER_NAME = "contextual_response_rephraser"
|
|
27
|
+
COMMAND_GENERATOR_NAME = "command_generator"
|
|
28
|
+
ENTERPRISE_SEARCH_NAME = "enterprise_search"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def handle_prompts(prompts: Dict[Text, Text], root: Path) -> None:
|
|
32
|
+
"""Handle prompts for the assistant.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
prompts: A dict containing prompt names as keys and their content as values.
|
|
36
|
+
root: The root directory where the prompts should be saved.
|
|
37
|
+
"""
|
|
38
|
+
if not prompts:
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
config_path = root / DEFAULT_CONFIG_PATH
|
|
42
|
+
endpoints_path = root / DEFAULT_ENDPOINTS_PATH
|
|
43
|
+
config: Dict = read_yaml(config_path)
|
|
44
|
+
endpoints: Dict = read_yaml(endpoints_path)
|
|
45
|
+
|
|
46
|
+
system_prompts = get_system_default_prompts(config, endpoints)
|
|
47
|
+
|
|
48
|
+
_handle_contextual_response_rephraser(
|
|
49
|
+
root,
|
|
50
|
+
prompts.get(CONTEXTUAL_RESPONSE_REPHRASER_NAME),
|
|
51
|
+
system_prompts.contextual_response_rephraser,
|
|
52
|
+
endpoints,
|
|
53
|
+
)
|
|
54
|
+
_handle_command_generator(
|
|
55
|
+
root,
|
|
56
|
+
prompts.get(COMMAND_GENERATOR_NAME),
|
|
57
|
+
system_prompts.command_generator,
|
|
58
|
+
config,
|
|
59
|
+
)
|
|
60
|
+
_handle_enterprise_search(
|
|
61
|
+
root,
|
|
62
|
+
prompts.get(ENTERPRISE_SEARCH_NAME),
|
|
63
|
+
system_prompts.enterprise_search,
|
|
64
|
+
config,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _handle_contextual_response_rephraser(
|
|
69
|
+
root: Path,
|
|
70
|
+
prompt_content: Optional[Text],
|
|
71
|
+
system_prompt: Optional[Text],
|
|
72
|
+
endpoints: Dict,
|
|
73
|
+
) -> None:
|
|
74
|
+
"""Handles the contextual response rephraser prompt.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
root: The root directory where the prompt file will be saved.
|
|
78
|
+
prompt_content: The content of the contextual response rephraser prompt.
|
|
79
|
+
system_prompt: The system prompt for comparison.
|
|
80
|
+
endpoints: The endpoints configuration to update with the prompt path.
|
|
81
|
+
"""
|
|
82
|
+
if not _is_custom_prompt(prompt_content, system_prompt):
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
prompt_path = _save_prompt_file(
|
|
86
|
+
root, f"{CONTEXTUAL_RESPONSE_REPHRASER_NAME}.jinja2", prompt_content
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
endpoints["nlg"] = endpoints.get("nlg") or {}
|
|
90
|
+
endpoints["nlg"]["prompt"] = str(prompt_path)
|
|
91
|
+
|
|
92
|
+
endpoints_path = root / DEFAULT_ENDPOINTS_PATH
|
|
93
|
+
write_yaml(data=endpoints, target=endpoints_path, should_preserve_key_order=True)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _handle_command_generator(
|
|
97
|
+
root: Path,
|
|
98
|
+
prompt_content: Optional[Text],
|
|
99
|
+
system_prompt: Optional[Text],
|
|
100
|
+
config: Dict,
|
|
101
|
+
) -> None:
|
|
102
|
+
"""Handles the command generator prompt.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
root: The root directory where the prompt file will be saved.
|
|
106
|
+
prompt_content: The content of the command generator prompt.
|
|
107
|
+
system_prompt: The system prompt for comparison.
|
|
108
|
+
config: The configuration dictionary to update with the prompt path.
|
|
109
|
+
"""
|
|
110
|
+
if not _is_custom_prompt(prompt_content, system_prompt):
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
prompt_path = _save_prompt_file(
|
|
114
|
+
root, f"{COMMAND_GENERATOR_NAME}.jinja2", prompt_content
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
command_generator_names: List[str] = [
|
|
118
|
+
cls.__name__ for cls in all_subclasses(LLMBasedCommandGenerator)
|
|
119
|
+
]
|
|
120
|
+
_add_prompt_to_config(
|
|
121
|
+
config=config,
|
|
122
|
+
section_key=CONFIG_PIPELINE_KEY,
|
|
123
|
+
component_names=command_generator_names,
|
|
124
|
+
prompt_key=PROMPT_TEMPLATE_CONFIG_KEY,
|
|
125
|
+
prompt_path=str(prompt_path),
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
config_path = root / DEFAULT_CONFIG_PATH
|
|
129
|
+
write_yaml(data=config, target=config_path, should_preserve_key_order=True)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _handle_enterprise_search(
|
|
133
|
+
root: Path,
|
|
134
|
+
prompt_content: Optional[Text],
|
|
135
|
+
system_prompt: Optional[Text],
|
|
136
|
+
config: Dict,
|
|
137
|
+
) -> None:
|
|
138
|
+
"""Handles the enterprise search prompt.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
root: The root directory where the prompt file will be saved.
|
|
142
|
+
prompt_content: The content of the enterprise search prompt.
|
|
143
|
+
system_prompt: The system prompt for comparison.
|
|
144
|
+
config: The configuration dictionary to update with the prompt path.
|
|
145
|
+
"""
|
|
146
|
+
if not _is_custom_prompt(prompt_content, system_prompt):
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
prompt_path = _save_prompt_file(
|
|
150
|
+
root, f"{ENTERPRISE_SEARCH_NAME}.jinja2", prompt_content
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
_add_prompt_to_config(
|
|
154
|
+
config=config,
|
|
155
|
+
section_key=CONFIG_POLICIES_KEY,
|
|
156
|
+
component_names=[EnterpriseSearchPolicy.__name__],
|
|
157
|
+
prompt_key=PROMPT_CONFIG_KEY,
|
|
158
|
+
prompt_path=str(prompt_path),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
config_path = root / DEFAULT_CONFIG_PATH
|
|
162
|
+
write_yaml(data=config, target=config_path, should_preserve_key_order=True)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _is_custom_prompt(
|
|
166
|
+
studio_prompt: Optional[Text], system_prompt: Optional[Text]
|
|
167
|
+
) -> bool:
|
|
168
|
+
"""Check if the prompt has been customized in Studio.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
studio_prompt: The prompt content from the Studio.
|
|
172
|
+
system_prompt: The default system prompt content.
|
|
173
|
+
"""
|
|
174
|
+
return bool(studio_prompt and studio_prompt != system_prompt)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _save_prompt_file(root: Path, filename: str, content: str) -> Path:
|
|
178
|
+
"""Save a prompt file to the specified root directory.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
root: The root directory where the prompt file will be saved.
|
|
182
|
+
filename: The name of the prompt file.
|
|
183
|
+
content: The content of the prompt.
|
|
184
|
+
"""
|
|
185
|
+
prompts_dir = root / DEFAULT_PROMPTS_PATH
|
|
186
|
+
prompts_dir.mkdir(parents=True, exist_ok=True)
|
|
187
|
+
|
|
188
|
+
file_path = prompts_dir / filename
|
|
189
|
+
file_path.write_text(content, encoding="utf-8")
|
|
190
|
+
|
|
191
|
+
return file_path.relative_to(root)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _add_prompt_to_config(
|
|
195
|
+
*,
|
|
196
|
+
config: Dict,
|
|
197
|
+
section_key: str,
|
|
198
|
+
component_names: List[str],
|
|
199
|
+
prompt_key: str,
|
|
200
|
+
prompt_path: str,
|
|
201
|
+
) -> None:
|
|
202
|
+
"""Add a prompt path to the specified section of the configuration."""
|
|
203
|
+
matches = [
|
|
204
|
+
component
|
|
205
|
+
for component in config.get(section_key, [])
|
|
206
|
+
if component.get(CONFIG_NAME_KEY) in component_names
|
|
207
|
+
]
|
|
208
|
+
|
|
209
|
+
if not matches:
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
# Update the first occurrence of the component.
|
|
213
|
+
matches[0][prompt_key] = prompt_path
|
|
214
|
+
|
|
215
|
+
if len(matches) > 1:
|
|
216
|
+
structlogger.warning(
|
|
217
|
+
"rasa.studio.prompts.add_prompt_to_config.multiple_components",
|
|
218
|
+
event_info=(
|
|
219
|
+
"Multiple components found in the configuration for the same prompt."
|
|
220
|
+
),
|
|
221
|
+
)
|
|
File without changes
|
|
@@ -3,101 +3,16 @@ from pathlib import Path
|
|
|
3
3
|
from typing import Any, Dict, List, Set, Text
|
|
4
4
|
|
|
5
5
|
from rasa.shared.core.flows import Flow
|
|
6
|
-
from rasa.shared.core.flows.flow_step_links import StaticFlowStepLink
|
|
7
6
|
from rasa.shared.core.flows.flows_list import FlowsList
|
|
8
7
|
from rasa.shared.core.flows.yaml_flows_io import YAMLFlowsReader, YamlFlowsWriter
|
|
9
8
|
from rasa.shared.importers.importer import TrainingDataImporter
|
|
10
9
|
from rasa.shared.utils.yaml import read_yaml
|
|
11
10
|
from rasa.studio.constants import STUDIO_NLU_FILENAME
|
|
12
|
-
from rasa.studio.data_handler import StudioDataHandler
|
|
13
11
|
from rasa.utils.mapper import RasaPrimitiveStorageMapper
|
|
14
12
|
|
|
15
13
|
logger = logging.getLogger(__name__)
|
|
16
14
|
|
|
17
|
-
STUDIO_FLOWS_DIR_NAME = "
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def merge_flows_with_overwrite(
|
|
21
|
-
data_path: Path,
|
|
22
|
-
handler: Any,
|
|
23
|
-
data_from_studio: TrainingDataImporter,
|
|
24
|
-
data_local: TrainingDataImporter,
|
|
25
|
-
mapper: RasaPrimitiveStorageMapper,
|
|
26
|
-
) -> None:
|
|
27
|
-
"""
|
|
28
|
-
Merges flows data from a file or directory when overwrite is enabled.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
data_path: List of paths to the training data.
|
|
32
|
-
handler: The StudioDataHandler instance.
|
|
33
|
-
data_from_studio: The TrainingDataImporter instance for Studio data.
|
|
34
|
-
data_local: The TrainingDataImporter instance for local data.
|
|
35
|
-
mapper: The RasaPrimitiveStorageMapper instance for mapping.
|
|
36
|
-
"""
|
|
37
|
-
if data_path.is_file():
|
|
38
|
-
merge_training_data_file(handler, data_from_studio, data_local, data_path)
|
|
39
|
-
elif data_path.is_dir():
|
|
40
|
-
merge_training_data_dir(
|
|
41
|
-
handler, data_from_studio, data_local, data_path, mapper
|
|
42
|
-
)
|
|
43
|
-
else:
|
|
44
|
-
raise ValueError("Provided data path is neither a file nor a directory.")
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def merge_training_data_file(
|
|
48
|
-
handler: StudioDataHandler,
|
|
49
|
-
data_from_studio: TrainingDataImporter,
|
|
50
|
-
data_local: TrainingDataImporter,
|
|
51
|
-
file_path: Path,
|
|
52
|
-
) -> None:
|
|
53
|
-
"""
|
|
54
|
-
Merges NLU and flows data when training data is stored in a single file.
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
handler: The StudioDataHandler instance.
|
|
58
|
-
data_from_studio: The TrainingDataImporter instance for Studio data.
|
|
59
|
-
data_local: The TrainingDataImporter instance for local data.
|
|
60
|
-
file_path: The path to the training data file.
|
|
61
|
-
"""
|
|
62
|
-
if handler.has_nlu():
|
|
63
|
-
nlu_data_merged = data_from_studio.get_nlu_data().merge(
|
|
64
|
-
data_local.get_nlu_data()
|
|
65
|
-
)
|
|
66
|
-
nlu_data_merged.persist_nlu(file_path)
|
|
67
|
-
|
|
68
|
-
if handler.has_flows():
|
|
69
|
-
flows_data_merged = data_from_studio.get_user_flows().merge(
|
|
70
|
-
data_local.get_user_flows()
|
|
71
|
-
)
|
|
72
|
-
YamlFlowsWriter.dump(
|
|
73
|
-
flows=flows_data_merged.underlying_flows,
|
|
74
|
-
filename=file_path,
|
|
75
|
-
should_clean_json=True,
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def merge_training_data_dir(
|
|
80
|
-
handler: StudioDataHandler,
|
|
81
|
-
data_from_studio: TrainingDataImporter,
|
|
82
|
-
data_local: TrainingDataImporter,
|
|
83
|
-
data_path: Path,
|
|
84
|
-
mapper: RasaPrimitiveStorageMapper,
|
|
85
|
-
) -> None:
|
|
86
|
-
"""
|
|
87
|
-
Merges NLU and flows data when training data is stored in a directory.
|
|
88
|
-
|
|
89
|
-
Args:
|
|
90
|
-
handler: The StudioDataHandler instance.
|
|
91
|
-
data_from_studio: The TrainingDataImporter instance for Studio data.
|
|
92
|
-
data_local: The TrainingDataImporter instance for local data.
|
|
93
|
-
data_path: The path to the training data directory.
|
|
94
|
-
mapper: The RasaPrimitiveStorageMapper instance for mapping.
|
|
95
|
-
"""
|
|
96
|
-
if handler.has_nlu():
|
|
97
|
-
merge_nlu_in_directory(data_from_studio, data_local, data_path, mapper)
|
|
98
|
-
|
|
99
|
-
if handler.has_flows():
|
|
100
|
-
merge_flows_in_directory(data_from_studio, data_path, mapper)
|
|
15
|
+
STUDIO_FLOWS_DIR_NAME = "flows"
|
|
101
16
|
|
|
102
17
|
|
|
103
18
|
def merge_nlu_in_directory(
|
|
@@ -116,7 +31,7 @@ def merge_nlu_in_directory(
|
|
|
116
31
|
data_path: The path to the training data directory.
|
|
117
32
|
mapper: The RasaPrimitiveStorageMapper instance for mapping.
|
|
118
33
|
"""
|
|
119
|
-
from rasa.studio.download
|
|
34
|
+
from rasa.studio.download import pretty_write_nlu_yaml
|
|
120
35
|
|
|
121
36
|
nlu_data = data_from_studio.get_nlu_data()
|
|
122
37
|
nlu_file_path = get_nlu_path(data_path, data_local, mapper)
|
|
@@ -154,29 +69,6 @@ def get_nlu_path(
|
|
|
154
69
|
return _select_path(nlu_paths, "nlu", base_path, STUDIO_NLU_FILENAME)
|
|
155
70
|
|
|
156
71
|
|
|
157
|
-
def get_flows_path(
|
|
158
|
-
base_path: Path,
|
|
159
|
-
data_local: TrainingDataImporter,
|
|
160
|
-
mapper: RasaPrimitiveStorageMapper,
|
|
161
|
-
) -> Path:
|
|
162
|
-
"""Determines where flows data should be stored.
|
|
163
|
-
|
|
164
|
-
Args:
|
|
165
|
-
base_path: The base path for the training data.
|
|
166
|
-
data_local: The TrainingDataImporter instance for local data.
|
|
167
|
-
mapper: The RasaPrimitiveStorageMapper instance for mapping.
|
|
168
|
-
|
|
169
|
-
Returns:
|
|
170
|
-
The path where flows data should be stored.
|
|
171
|
-
"""
|
|
172
|
-
flow_paths = set()
|
|
173
|
-
for flow in data_local.get_user_flows().underlying_flows:
|
|
174
|
-
for p in mapper.get_file(flow.id, "flows").get("training", []):
|
|
175
|
-
flow_paths.add(p)
|
|
176
|
-
|
|
177
|
-
return _select_path(flow_paths, "flows", base_path, "flows.yml")
|
|
178
|
-
|
|
179
|
-
|
|
180
72
|
def merge_flows_in_directory(
|
|
181
73
|
data_from_studio: TrainingDataImporter,
|
|
182
74
|
data_path: Path,
|
|
@@ -298,27 +190,6 @@ def _dump_flows_as_separate_files(flows: List[Any], data_path: Path) -> None:
|
|
|
298
190
|
)
|
|
299
191
|
|
|
300
192
|
|
|
301
|
-
def strip_default_next_references(flows: FlowsList) -> FlowsList:
|
|
302
|
-
"""Strips default next references from flows.
|
|
303
|
-
|
|
304
|
-
Args:
|
|
305
|
-
flows: The FlowsList instance containing the flows.
|
|
306
|
-
|
|
307
|
-
Returns:
|
|
308
|
-
An updated FlowsList instance with default next references removed.
|
|
309
|
-
"""
|
|
310
|
-
default_step_ids = [step.default_id for flow in flows for step in flow.steps]
|
|
311
|
-
for flow in flows:
|
|
312
|
-
for step in flow.steps:
|
|
313
|
-
if (
|
|
314
|
-
step.next.links
|
|
315
|
-
and isinstance(step.next.links[0], StaticFlowStepLink)
|
|
316
|
-
and step.next.links[0].target in default_step_ids
|
|
317
|
-
):
|
|
318
|
-
step.next.links = []
|
|
319
|
-
return flows
|
|
320
|
-
|
|
321
|
-
|
|
322
193
|
def _select_path(
|
|
323
194
|
paths: Set[Path], primitive_type: str, default_path: Path, default: str
|
|
324
195
|
) -> Path:
|
|
@@ -10,7 +10,7 @@ from rasa.studio.constants import STUDIO_DOMAIN_FILENAME
|
|
|
10
10
|
logger = logging.getLogger(__name__)
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def
|
|
13
|
+
def merge_domain(
|
|
14
14
|
data_from_studio: TrainingDataImporter,
|
|
15
15
|
data_local: TrainingDataImporter,
|
|
16
16
|
domain_path: Path,
|
rasa/studio/pull/pull.py
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, Tuple
|
|
6
|
+
|
|
7
|
+
import structlog
|
|
8
|
+
|
|
9
|
+
import rasa.cli.utils
|
|
10
|
+
import rasa.shared.utils.cli
|
|
11
|
+
from rasa.shared.constants import (
|
|
12
|
+
DEFAULT_CONFIG_PATH,
|
|
13
|
+
DEFAULT_DATA_PATH,
|
|
14
|
+
DEFAULT_DOMAIN_PATH,
|
|
15
|
+
DEFAULT_DOMAIN_PATHS,
|
|
16
|
+
DEFAULT_ENDPOINTS_PATH,
|
|
17
|
+
)
|
|
18
|
+
from rasa.shared.importers.importer import TrainingDataImporter
|
|
19
|
+
from rasa.shared.utils.io import write_text_file
|
|
20
|
+
from rasa.studio.config import StudioConfig
|
|
21
|
+
from rasa.studio.data_handler import StudioDataHandler, import_data_from_studio
|
|
22
|
+
from rasa.studio.link import read_assistant_name
|
|
23
|
+
from rasa.studio.pull.data import merge_flows_in_directory, merge_nlu_in_directory
|
|
24
|
+
from rasa.studio.pull.domains import merge_domain
|
|
25
|
+
from rasa.studio.utils import validate_argument_paths
|
|
26
|
+
from rasa.utils.mapper import RasaPrimitiveStorageMapper
|
|
27
|
+
|
|
28
|
+
structlogger = structlog.get_logger(__name__)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def handle_pull(args: argparse.Namespace) -> None:
|
|
32
|
+
"""Pull the complete assistant and overwrite all local files.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
args: The command line arguments.
|
|
36
|
+
"""
|
|
37
|
+
validate_argument_paths(args)
|
|
38
|
+
handler = _create_studio_handler()
|
|
39
|
+
handler.request_all_data()
|
|
40
|
+
|
|
41
|
+
_pull_config_file(handler, args.config or DEFAULT_CONFIG_PATH)
|
|
42
|
+
_pull_endpoints_file(handler, args.endpoints or DEFAULT_ENDPOINTS_PATH)
|
|
43
|
+
|
|
44
|
+
domain_path, data_path = _prepare_data_and_domain_paths(args)
|
|
45
|
+
_merge_domain_and_data(handler, domain_path, data_path)
|
|
46
|
+
|
|
47
|
+
structlogger.info(
|
|
48
|
+
"studio.push.success",
|
|
49
|
+
event_info="Pulled assistant data from Studio.",
|
|
50
|
+
)
|
|
51
|
+
rasa.shared.utils.cli.print_success("Pulled assistant data from Studio.")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def handle_pull_config(args: argparse.Namespace) -> None:
|
|
55
|
+
"""Pull nothing but the assistant's `config.yml`.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
args: The command line arguments.
|
|
59
|
+
"""
|
|
60
|
+
validate_argument_paths(args)
|
|
61
|
+
handler = _create_studio_handler()
|
|
62
|
+
handler.request_all_data()
|
|
63
|
+
|
|
64
|
+
_pull_config_file(handler, args.config or DEFAULT_CONFIG_PATH)
|
|
65
|
+
|
|
66
|
+
structlogger.info(
|
|
67
|
+
"studio.push.success",
|
|
68
|
+
event_info="Pulled assistant data from Studio.",
|
|
69
|
+
)
|
|
70
|
+
rasa.shared.utils.cli.print_success("Pulled assistant data from Studio.")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def handle_pull_endpoints(args: argparse.Namespace) -> None:
|
|
74
|
+
"""Pull nothing but the assistant's `endpoints.yml`.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
args: The command line arguments.
|
|
78
|
+
"""
|
|
79
|
+
validate_argument_paths(args)
|
|
80
|
+
handler = _create_studio_handler()
|
|
81
|
+
handler.request_all_data()
|
|
82
|
+
|
|
83
|
+
_pull_endpoints_file(handler, args.endpoints or DEFAULT_ENDPOINTS_PATH)
|
|
84
|
+
structlogger.info(
|
|
85
|
+
"studio.push.success",
|
|
86
|
+
event_info="Pulled assistant data from Studio.",
|
|
87
|
+
)
|
|
88
|
+
rasa.shared.utils.cli.print_success("Pulled assistant data from Studio.")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _create_studio_handler() -> StudioDataHandler:
|
|
92
|
+
"""Return an initialised StudioDataHandler for the linked assistant.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
An instance of `StudioDataHandler` for the linked assistant.
|
|
96
|
+
"""
|
|
97
|
+
assistant_name = read_assistant_name()
|
|
98
|
+
return StudioDataHandler(
|
|
99
|
+
studio_config=StudioConfig.read_config(), assistant_name=assistant_name
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _pull_config_file(handler: StudioDataHandler, target_path: str | Path) -> None:
|
|
104
|
+
"""Pull the assistant's `config.yml` file and write it to the specified path.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
handler: The data handler to retrieve the config from.
|
|
108
|
+
target_path: The path where the config file should be written.
|
|
109
|
+
"""
|
|
110
|
+
config_yaml = handler.get_config()
|
|
111
|
+
if not config_yaml:
|
|
112
|
+
rasa.shared.utils.cli.print_error_and_exit("No config data found in assistant.")
|
|
113
|
+
|
|
114
|
+
_write_text(config_yaml, target_path)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _pull_endpoints_file(handler: StudioDataHandler, target_path: str | Path) -> None:
|
|
118
|
+
"""Pull the assistant's `endpoints.yml` file and write it to the specified path.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
handler: The data handler to retrieve the endpoints from.
|
|
122
|
+
target_path: The path where the endpoints file should be written.
|
|
123
|
+
"""
|
|
124
|
+
endpoints_yaml = handler.get_endpoints()
|
|
125
|
+
if not endpoints_yaml:
|
|
126
|
+
rasa.shared.utils.cli.print_error_and_exit(
|
|
127
|
+
"No endpoints data found in assistant."
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
_write_text(endpoints_yaml, target_path)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _prepare_data_and_domain_paths(args: argparse.Namespace) -> Tuple[Path, Path]:
|
|
134
|
+
"""Prepars the domain and data paths based on the provided arguments.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
args: The command line arguments.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
A tuple containing the domain path and a data path.
|
|
141
|
+
"""
|
|
142
|
+
# Prepare domain path.
|
|
143
|
+
domain_path = rasa.cli.utils.get_validated_path(
|
|
144
|
+
args.domain, "domain", DEFAULT_DOMAIN_PATHS, none_is_valid=True
|
|
145
|
+
)
|
|
146
|
+
domain_or_default_path = args.domain or DEFAULT_DOMAIN_PATH
|
|
147
|
+
|
|
148
|
+
if domain_path is None:
|
|
149
|
+
domain_path = Path(domain_or_default_path)
|
|
150
|
+
domain_path.touch()
|
|
151
|
+
|
|
152
|
+
if isinstance(domain_path, str):
|
|
153
|
+
domain_path = Path(domain_path)
|
|
154
|
+
|
|
155
|
+
data_path = rasa.cli.utils.get_validated_path(
|
|
156
|
+
args.data, "data", DEFAULT_DATA_PATH, none_is_valid=True
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
data_path = Path(data_path or args.data)
|
|
160
|
+
if not (data_path.is_file() or data_path.is_dir()):
|
|
161
|
+
data_path.mkdir(parents=True, exist_ok=True)
|
|
162
|
+
|
|
163
|
+
return domain_path, data_path
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _merge_domain_and_data(
|
|
167
|
+
handler: StudioDataHandler, domain_path: Path, data_path: Path
|
|
168
|
+
) -> None:
|
|
169
|
+
"""Merge local assistant data with Studio assistant data.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
handler: The data handler to retrieve the assistant data from.
|
|
173
|
+
domain_path: The path to the local domain file or directory.
|
|
174
|
+
data_path: The path to the local training data file or directory.
|
|
175
|
+
"""
|
|
176
|
+
data_from_studio, data_local = import_data_from_studio(
|
|
177
|
+
handler, domain_path, data_path
|
|
178
|
+
)
|
|
179
|
+
mapper = RasaPrimitiveStorageMapper(
|
|
180
|
+
domain_path=domain_path, training_data_paths=[data_path]
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
merge_domain(data_from_studio, data_local, domain_path)
|
|
184
|
+
merge_data(data_path, handler, data_from_studio, data_local, mapper)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def merge_data(
|
|
188
|
+
data_path: Path,
|
|
189
|
+
handler: Any,
|
|
190
|
+
data_from_studio: TrainingDataImporter,
|
|
191
|
+
data_local: TrainingDataImporter,
|
|
192
|
+
mapper: RasaPrimitiveStorageMapper,
|
|
193
|
+
) -> None:
|
|
194
|
+
"""
|
|
195
|
+
Merges flows data from a file or directory.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
data_path: List of paths to the training data.
|
|
199
|
+
handler: The StudioDataHandler instance.
|
|
200
|
+
data_from_studio: The TrainingDataImporter instance for Studio data.
|
|
201
|
+
data_local: The TrainingDataImporter instance for local data.
|
|
202
|
+
mapper: The RasaPrimitiveStorageMapper instance for mapping.
|
|
203
|
+
"""
|
|
204
|
+
if not data_path.is_file() and not data_path.is_dir():
|
|
205
|
+
raise ValueError("Provided data path is neither a file nor a directory.")
|
|
206
|
+
|
|
207
|
+
if handler.has_nlu():
|
|
208
|
+
if data_path.is_file():
|
|
209
|
+
nlu_data_merged = data_from_studio.get_nlu_data().merge(
|
|
210
|
+
data_local.get_nlu_data()
|
|
211
|
+
)
|
|
212
|
+
nlu_data_merged.persist_nlu(data_path)
|
|
213
|
+
else:
|
|
214
|
+
merge_nlu_in_directory(
|
|
215
|
+
data_from_studio,
|
|
216
|
+
data_local,
|
|
217
|
+
data_path,
|
|
218
|
+
mapper,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
if handler.has_flows():
|
|
222
|
+
flows_root = data_path.parent if data_path.is_file() else data_path
|
|
223
|
+
merge_flows_in_directory(
|
|
224
|
+
data_from_studio,
|
|
225
|
+
flows_root,
|
|
226
|
+
mapper,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _write_text(content: str, target: str | Path) -> None:
|
|
231
|
+
"""Write `content` to `target`, ensuring parent directories exist.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
content: The content to write to the file.
|
|
235
|
+
target: The path where the content should be written.
|
|
236
|
+
"""
|
|
237
|
+
path = Path(target)
|
|
238
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
239
|
+
write_text_file(content, path, encoding="utf-8")
|
rasa/studio/push.py
CHANGED
|
@@ -19,6 +19,7 @@ from rasa.studio.upload import (
|
|
|
19
19
|
make_request,
|
|
20
20
|
run_validation,
|
|
21
21
|
)
|
|
22
|
+
from rasa.studio.utils import validate_argument_paths
|
|
22
23
|
|
|
23
24
|
structlogger = structlog.get_logger(__name__)
|
|
24
25
|
|
|
@@ -48,6 +49,11 @@ def _send_to_studio(
|
|
|
48
49
|
if not result.was_successful:
|
|
49
50
|
rasa.shared.utils.cli.print_error_and_exit(result.message)
|
|
50
51
|
|
|
52
|
+
structlogger.info(
|
|
53
|
+
"studio.push.success",
|
|
54
|
+
event_info=f"Pushed data to assistant '{assistant_name}'.",
|
|
55
|
+
assistant_name=assistant_name,
|
|
56
|
+
)
|
|
51
57
|
rasa.shared.utils.cli.print_success(f"Pushed data to assistant '{assistant_name}'.")
|
|
52
58
|
|
|
53
59
|
|
|
@@ -57,6 +63,7 @@ def handle_push(args: argparse.Namespace) -> None:
|
|
|
57
63
|
Args:
|
|
58
64
|
args: The command line arguments.
|
|
59
65
|
"""
|
|
66
|
+
validate_argument_paths(args)
|
|
60
67
|
studio_cfg = get_studio_config()
|
|
61
68
|
|
|
62
69
|
run_validation(args)
|
rasa/studio/train.py
CHANGED
|
@@ -34,7 +34,7 @@ def handle_train(args: argparse.Namespace) -> Optional[str]:
|
|
|
34
34
|
from rasa.api import train as train_all
|
|
35
35
|
|
|
36
36
|
handler = StudioDataHandler(
|
|
37
|
-
studio_config=StudioConfig.read_config(), assistant_name=args.assistant_name
|
|
37
|
+
studio_config=StudioConfig.read_config(), assistant_name=args.assistant_name
|
|
38
38
|
)
|
|
39
39
|
if args.entities or args.intents:
|
|
40
40
|
handler.request_data(args.intents, args.entities)
|