rasa-pro 3.13.0.dev7__py3-none-any.whl → 3.13.0.dev9__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/__main__.py +0 -3
- rasa/api.py +1 -1
- rasa/cli/dialogue_understanding_test.py +1 -1
- rasa/cli/e2e_test.py +1 -1
- rasa/cli/evaluate.py +1 -1
- rasa/cli/export.py +1 -1
- rasa/cli/llm_fine_tuning.py +12 -11
- rasa/cli/project_templates/defaults.py +133 -0
- rasa/cli/run.py +1 -1
- rasa/cli/studio/link.py +53 -0
- rasa/cli/studio/pull.py +78 -0
- rasa/cli/studio/push.py +78 -0
- rasa/cli/studio/studio.py +12 -0
- rasa/cli/studio/upload.py +8 -0
- rasa/cli/train.py +1 -1
- rasa/cli/utils.py +1 -1
- rasa/cli/x.py +1 -1
- rasa/constants.py +2 -0
- rasa/core/__init__.py +0 -16
- rasa/core/actions/action.py +5 -1
- rasa/core/actions/action_repeat_bot_messages.py +18 -22
- rasa/core/actions/action_run_slot_rejections.py +0 -1
- rasa/core/agent.py +16 -1
- rasa/core/available_endpoints.py +146 -0
- rasa/core/brokers/pika.py +1 -2
- rasa/core/channels/botframework.py +2 -2
- rasa/core/channels/channel.py +2 -2
- rasa/core/channels/development_inspector.py +1 -1
- rasa/core/channels/facebook.py +1 -4
- rasa/core/channels/hangouts.py +8 -5
- rasa/core/channels/inspector/README.md +3 -3
- rasa/core/channels/inspector/dist/assets/{arc-c4b064fc.js → arc-02053cc1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-215b5026.js → blockDiagram-38ab4fdb-008b6289.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-2b54a0a3.js → c4Diagram-3d4e48cf-fb2597be.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-078dada8.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-daacea5f.js → classDiagram-70f12bd4-7f847e00.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-930d4dc2.js → classDiagram-v2-f2320105-ba1d689b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-5b4516de.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-83c206ba.js → createText-2e5e7dd3-dd8e67c4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b0eb01d0.js → edges-e0da2a9e-10784939.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-17586500.js → erDiagram-9861fffd-24947ae6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-be2a1776.js → flowDb-956e92f1-a9ced505.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c2120ebd.js → flowDiagram-66a62f08-afda9c7c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-f9613071.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a6ab5c48.js → flowchart-elk-definition-4a651766-6ef530b8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-ef613457.js → ganttDiagram-c361ad54-0c7dd39a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-d59185b3.js → gitGraphDiagram-72cf32ee-b57239d6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-0f155405.js → graph-9ed57cec.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-d5f1d1b7.js → index-3862675e-233090de.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-47737d3a.js → index-72184470.js} +3 -3
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b07d141f.js → infoDiagram-f8f76790-aa116649.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-1936d429.js → journeyDiagram-49397b02-e51877cc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-dde8d0f3.js → layout-3ca3798c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-0c2c7ee0.js → line-26ee10d3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-35dd89a4.js → linear-aedded32.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-56192851.js → mindmap-definition-fc14e90a-d8957261.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-fc21ed78.js → pieDiagram-8a3498a8-d771f885.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-25e98518.js → quadrantDiagram-120e2f19-09fdf50c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-546ff1f5.js → requirementDiagram-deff3bca-9f0af02e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-02d8b82d.js → sankeyDiagram-04a897e0-84415b37.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3ca5a92e.js → sequenceDiagram-704730f1-8dec4055.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-128ea07c.js → stateDiagram-587899a1-c5431d07.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-95f290af.js → stateDiagram-v2-d93cdb3a-274e77d9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-4984898a.js → styles-6aaf32cf-e364a1d7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1bf266ba.js → styles-9a916d00-0dae36f6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-60521c63.js → styles-c10674c1-c4641675.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-a25b6e12.js → svgDrawCommon-08f97a94-831fe9a1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-0fc086bf.js → timeline-definition-85554ec2-c3304b3a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-44ee592e.js → xychartDiagram-e933f94c-da799369.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/mattermost.py +1 -1
- rasa/core/channels/rasa_chat.py +2 -4
- rasa/core/channels/rest.py +5 -4
- rasa/core/channels/socketio.py +56 -41
- rasa/core/channels/studio_chat.py +314 -10
- rasa/core/channels/vier_cvg.py +1 -2
- rasa/core/channels/voice_ready/audiocodes.py +2 -9
- rasa/core/channels/voice_stream/audiocodes.py +8 -5
- rasa/core/channels/voice_stream/browser_audio.py +1 -1
- rasa/core/channels/voice_stream/genesys.py +2 -2
- rasa/core/channels/voice_stream/tts/__init__.py +8 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +10 -5
- rasa/core/channels/voice_stream/voice_channel.py +39 -23
- rasa/core/http_interpreter.py +3 -7
- rasa/core/information_retrieval/faiss.py +18 -11
- rasa/core/information_retrieval/ingestion/__init__.py +0 -0
- rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
- rasa/core/jobs.py +2 -1
- rasa/core/nlg/contextual_response_rephraser.py +44 -10
- rasa/core/nlg/generator.py +0 -1
- rasa/core/nlg/interpolator.py +2 -3
- rasa/core/nlg/summarize.py +39 -5
- rasa/core/policies/enterprise_search_policy.py +262 -62
- rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +63 -0
- rasa/core/policies/flow_policy.py +1 -1
- rasa/core/policies/flows/flow_executor.py +96 -17
- rasa/core/policies/intentless_policy.py +56 -17
- rasa/core/processor.py +104 -51
- rasa/core/run.py +33 -11
- rasa/core/tracker_stores/tracker_store.py +1 -1
- rasa/core/training/interactive.py +1 -1
- rasa/core/utils.py +24 -97
- rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -1
- rasa/dialogue_understanding/coexistence/llm_based_router.py +9 -6
- rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +5 -1
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -0
- rasa/dialogue_understanding/commands/clarify_command.py +5 -1
- rasa/dialogue_understanding/commands/command_syntax_manager.py +1 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +1 -3
- rasa/dialogue_understanding/commands/human_handoff_command.py +2 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +4 -2
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +11 -1
- rasa/dialogue_understanding/commands/skip_question_command.py +2 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +4 -0
- rasa/dialogue_understanding/commands/utils.py +26 -2
- rasa/dialogue_understanding/generator/__init__.py +7 -1
- rasa/dialogue_understanding/generator/command_generator.py +4 -2
- rasa/dialogue_understanding/generator/command_parser.py +2 -2
- rasa/dialogue_understanding/generator/command_parser_validator.py +63 -0
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +12 -33
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +78 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +26 -461
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +147 -0
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +477 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +11 -64
- 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/patterns/default_flows_for_patterns.yml +37 -25
- rasa/dialogue_understanding/patterns/domain_for_patterns.py +190 -0
- rasa/dialogue_understanding/processor/command_processor.py +6 -7
- rasa/dialogue_understanding/processor/command_processor_component.py +3 -3
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +17 -4
- rasa/dialogue_understanding/stack/utils.py +3 -1
- rasa/dialogue_understanding/utils.py +68 -12
- rasa/dialogue_understanding_test/du_test_case.py +1 -1
- rasa/dialogue_understanding_test/du_test_runner.py +4 -22
- rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +2 -6
- rasa/e2e_test/e2e_test_runner.py +1 -1
- rasa/engine/constants.py +1 -1
- rasa/engine/graph.py +2 -2
- rasa/engine/recipes/default_recipe.py +26 -2
- rasa/engine/validation.py +3 -2
- rasa/hooks.py +0 -28
- rasa/llm_fine_tuning/annotation_module.py +39 -9
- rasa/llm_fine_tuning/conversations.py +3 -0
- rasa/llm_fine_tuning/llm_data_preparation_module.py +66 -49
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +1 -5
- rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +52 -44
- rasa/llm_fine_tuning/paraphrasing_module.py +10 -12
- rasa/llm_fine_tuning/storage.py +4 -4
- rasa/llm_fine_tuning/utils.py +63 -1
- rasa/model_manager/model_api.py +88 -0
- rasa/model_manager/trainer_service.py +4 -4
- rasa/plugin.py +1 -11
- rasa/privacy/__init__.py +0 -0
- rasa/privacy/constants.py +83 -0
- rasa/privacy/event_broker_utils.py +77 -0
- rasa/privacy/privacy_config.py +281 -0
- rasa/privacy/privacy_config_schema.json +86 -0
- rasa/privacy/privacy_filter.py +340 -0
- rasa/privacy/privacy_manager.py +576 -0
- rasa/server.py +23 -2
- rasa/shared/constants.py +14 -0
- rasa/shared/core/command_payload_reader.py +1 -5
- rasa/shared/core/constants.py +4 -3
- rasa/shared/core/domain.py +7 -0
- rasa/shared/core/events.py +38 -10
- rasa/shared/core/flows/flow.py +1 -2
- rasa/shared/core/flows/flows_yaml_schema.json +3 -0
- rasa/shared/core/flows/steps/collect.py +46 -2
- rasa/shared/core/flows/validation.py +16 -3
- rasa/shared/core/slots.py +28 -0
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
- rasa/shared/exceptions.py +4 -0
- rasa/shared/utils/common.py +1 -1
- rasa/shared/utils/llm.py +191 -6
- rasa/shared/utils/yaml.py +32 -0
- rasa/studio/data_handler.py +3 -3
- rasa/studio/download/download.py +37 -60
- rasa/studio/download/flows.py +23 -31
- rasa/studio/link.py +200 -0
- rasa/studio/pull.py +94 -0
- rasa/studio/push.py +131 -0
- rasa/studio/upload.py +117 -67
- rasa/telemetry.py +82 -25
- rasa/tracing/config.py +3 -4
- rasa/tracing/constants.py +19 -1
- rasa/tracing/instrumentation/attribute_extractors.py +10 -2
- rasa/tracing/instrumentation/instrumentation.py +53 -2
- rasa/tracing/instrumentation/metrics.py +98 -15
- rasa/tracing/metric_instrument_provider.py +75 -3
- rasa/utils/common.py +1 -27
- rasa/utils/log_utils.py +1 -45
- rasa/validator.py +2 -8
- rasa/version.py +1 -1
- {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev9.dist-info}/METADATA +7 -8
- {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev9.dist-info}/RECORD +205 -189
- rasa/anonymization/__init__.py +0 -2
- rasa/anonymization/anonymisation_rule_yaml_reader.py +0 -91
- rasa/anonymization/anonymization_pipeline.py +0 -286
- rasa/anonymization/anonymization_rule_executor.py +0 -266
- rasa/anonymization/anonymization_rule_orchestrator.py +0 -119
- rasa/anonymization/schemas/config.yml +0 -47
- rasa/anonymization/utils.py +0 -118
- 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_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev9.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev9.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev9.dist-info}/entry_points.txt +0 -0
rasa/studio/link.py
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import datetime
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any, Dict, List, Optional, Text, Union
|
|
8
|
+
|
|
9
|
+
import questionary
|
|
10
|
+
import structlog
|
|
11
|
+
from pydantic import BaseModel, Field
|
|
12
|
+
|
|
13
|
+
import rasa.shared.utils.cli
|
|
14
|
+
from rasa.constants import RASA_DIR_NAME
|
|
15
|
+
from rasa.shared.utils.yaml import read_yaml_file, write_yaml
|
|
16
|
+
from rasa.studio.config import StudioConfig
|
|
17
|
+
from rasa.studio.upload import (
|
|
18
|
+
check_if_assistant_already_exists,
|
|
19
|
+
handle_upload,
|
|
20
|
+
is_auth_working,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
structlogger = structlog.get_logger(__name__)
|
|
24
|
+
|
|
25
|
+
_LINK_FILE_NAME: Text = "studio.yml"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AssistantLinkPayload(BaseModel):
|
|
29
|
+
assistant_name: Text
|
|
30
|
+
studio_url: Text
|
|
31
|
+
linked_at: Text = Field(
|
|
32
|
+
default_factory=lambda: datetime.datetime.utcnow().isoformat() + "Z"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _link_file(project_root: Path) -> Path:
|
|
37
|
+
"""Return `<project-root>/.rasa/studio.yml`.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
project_root: The path to the project root.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
The path to the link file.
|
|
44
|
+
"""
|
|
45
|
+
return project_root / RASA_DIR_NAME / _LINK_FILE_NAME
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _write_link_file(
|
|
49
|
+
project_root: Path, assistant_name: Text, studio_url: Text
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Persist assistant information inside the project.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
project_root: The path to the project root.
|
|
55
|
+
assistant_name: The name of the assistant.
|
|
56
|
+
studio_url: The URL of the Rasa Studio instance.
|
|
57
|
+
"""
|
|
58
|
+
file_path = _link_file(project_root)
|
|
59
|
+
file_path.parent.mkdir(exist_ok=True, parents=True)
|
|
60
|
+
|
|
61
|
+
payload = AssistantLinkPayload(
|
|
62
|
+
assistant_name=assistant_name,
|
|
63
|
+
studio_url=studio_url,
|
|
64
|
+
)
|
|
65
|
+
write_yaml(payload.model_dump(), file_path)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _read_link_file(
|
|
69
|
+
project_root: Path = Path.cwd(),
|
|
70
|
+
) -> Optional[Union[List[Any], Dict[Text, Any]]]:
|
|
71
|
+
"""Reads the link configuration file.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
project_root: The path to the project root.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
The assistant information if the file exists, otherwise None.
|
|
78
|
+
"""
|
|
79
|
+
file_path = _link_file(project_root)
|
|
80
|
+
if not file_path.is_file():
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
return read_yaml_file(file_path)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def read_assistant_name(project_root: Path = Path.cwd()) -> Optional[Text]:
|
|
87
|
+
"""Reads the assistant_name from the linked configuration file.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
project_root: The path to the project root.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
The assistant name if the file exists, otherwise None.
|
|
94
|
+
"""
|
|
95
|
+
linked = _read_link_file(project_root)
|
|
96
|
+
assistant_name = (
|
|
97
|
+
linked.get("assistant_name") if linked and isinstance(linked, dict) else None
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if not assistant_name:
|
|
101
|
+
rasa.shared.utils.cli.print_error_and_exit(
|
|
102
|
+
"This project is not linked to any Rasa Studio assistant.\n"
|
|
103
|
+
"Run `rasa studio link <assistant-name>` first."
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return assistant_name
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def get_studio_config() -> StudioConfig:
|
|
110
|
+
"""Get the StudioConfig object or exit with an error message.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
A valid StudioConfig object.
|
|
114
|
+
"""
|
|
115
|
+
config = StudioConfig.read_config()
|
|
116
|
+
if not config.is_valid():
|
|
117
|
+
rasa.shared.utils.cli.print_error_and_exit(
|
|
118
|
+
"Rasa Studio is not configured correctly. Run `rasa studio config` first."
|
|
119
|
+
)
|
|
120
|
+
if not is_auth_working(config.studio_url, not config.disable_verify):
|
|
121
|
+
rasa.shared.utils.cli.print_error_and_exit(
|
|
122
|
+
"Authentication invalid or expired. Please run `rasa studio login`."
|
|
123
|
+
)
|
|
124
|
+
return config
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _ensure_assistant_exists(
|
|
128
|
+
assistant_name: Text,
|
|
129
|
+
studio_cfg: StudioConfig,
|
|
130
|
+
args: argparse.Namespace,
|
|
131
|
+
) -> bool:
|
|
132
|
+
"""Create the assistant on Studio if it does not yet exist.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
assistant_name: The name the user provided on the CLI.
|
|
136
|
+
studio_cfg: The validated Studio configuration.
|
|
137
|
+
args: The original CLI args (needed for `handle_upload`).
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
True if the assistant already exists or was created, False otherwise.
|
|
141
|
+
"""
|
|
142
|
+
verify_ssl = not studio_cfg.disable_verify
|
|
143
|
+
assistant_already_exists = check_if_assistant_already_exists(
|
|
144
|
+
assistant_name, studio_cfg.studio_url, verify_ssl
|
|
145
|
+
)
|
|
146
|
+
if not assistant_already_exists:
|
|
147
|
+
should_create_assistant = questionary.confirm(
|
|
148
|
+
f"Assistant '{assistant_name}' was not found on Rasa Studio. "
|
|
149
|
+
f"Do you want to create it?"
|
|
150
|
+
).ask()
|
|
151
|
+
if should_create_assistant:
|
|
152
|
+
# `handle_upload` expects the name to live in `args.assistant_name`
|
|
153
|
+
args.assistant_name = assistant_name
|
|
154
|
+
handle_upload(args)
|
|
155
|
+
|
|
156
|
+
rasa.shared.utils.cli.print_info(
|
|
157
|
+
f"Assistant {assistant_name} successfully created."
|
|
158
|
+
)
|
|
159
|
+
return should_create_assistant
|
|
160
|
+
|
|
161
|
+
return assistant_already_exists
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def handle_link(args: argparse.Namespace) -> None:
|
|
165
|
+
"""Implementation of `rasa studio link <assistant-name>` CLI command.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
args: The command line arguments.
|
|
169
|
+
"""
|
|
170
|
+
assistant_name: Text = args.assistant_name[0]
|
|
171
|
+
studio_cfg = get_studio_config()
|
|
172
|
+
assistant_exists = _ensure_assistant_exists(assistant_name, studio_cfg, args)
|
|
173
|
+
if not assistant_exists:
|
|
174
|
+
rasa.shared.utils.cli.print_error_and_exit(
|
|
175
|
+
"Project has not been linked with Studio assistant."
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
project_root = Path.cwd()
|
|
179
|
+
link_file = _link_file(project_root)
|
|
180
|
+
|
|
181
|
+
if link_file.exists():
|
|
182
|
+
overwrite = questionary.confirm(
|
|
183
|
+
f"This project is already linked " f"(link file '{link_file}').\nOverwrite?"
|
|
184
|
+
).ask()
|
|
185
|
+
if not overwrite:
|
|
186
|
+
rasa.shared.utils.cli.print_info(
|
|
187
|
+
"Existing link kept – nothing was changed."
|
|
188
|
+
)
|
|
189
|
+
sys.exit(0)
|
|
190
|
+
|
|
191
|
+
_write_link_file(project_root, assistant_name, studio_cfg.studio_url)
|
|
192
|
+
|
|
193
|
+
structlogger.info(
|
|
194
|
+
"studio.link.success",
|
|
195
|
+
event_info=f"Project linked to Studio assistant '{assistant_name}'.",
|
|
196
|
+
assistant_name=assistant_name,
|
|
197
|
+
)
|
|
198
|
+
rasa.shared.utils.cli.print_success(
|
|
199
|
+
f"Project successfully linked to assistant '{assistant_name}'."
|
|
200
|
+
)
|
rasa/studio/pull.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
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)
|
rasa/studio/push.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Dict, Text
|
|
6
|
+
|
|
7
|
+
import structlog
|
|
8
|
+
|
|
9
|
+
import rasa.shared.utils.cli
|
|
10
|
+
from rasa.shared.core.flows.yaml_flows_io import YamlFlowsWriter
|
|
11
|
+
from rasa.shared.importers.importer import TrainingDataImporter
|
|
12
|
+
from rasa.shared.nlu.training_data.formats.rasa_yaml import RasaYAMLWriter
|
|
13
|
+
from rasa.shared.utils.io import read_file
|
|
14
|
+
from rasa.shared.utils.yaml import dump_obj_as_yaml_to_string
|
|
15
|
+
from rasa.studio.config import StudioConfig
|
|
16
|
+
from rasa.studio.link import get_studio_config, read_assistant_name
|
|
17
|
+
from rasa.studio.upload import (
|
|
18
|
+
build_import_request,
|
|
19
|
+
make_request,
|
|
20
|
+
run_validation,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
structlogger = structlog.get_logger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _send_to_studio(
|
|
27
|
+
assistant_name: Text,
|
|
28
|
+
payload_parts: Dict[Text, Text],
|
|
29
|
+
studio_cfg: StudioConfig,
|
|
30
|
+
) -> None:
|
|
31
|
+
"""Build the GraphQL request and send it.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
assistant_name: The name of the assistant.
|
|
35
|
+
payload_parts: The parts of the payload to send.
|
|
36
|
+
studio_cfg: The StudioConfig object.
|
|
37
|
+
"""
|
|
38
|
+
graphql_req = build_import_request(
|
|
39
|
+
assistant_name=assistant_name,
|
|
40
|
+
flows_yaml=payload_parts.get("flows"),
|
|
41
|
+
domain_yaml=payload_parts.get("domain"),
|
|
42
|
+
config_yaml=payload_parts.get("config"),
|
|
43
|
+
endpoints=payload_parts.get("endpoints"),
|
|
44
|
+
nlu_yaml=payload_parts.get("nlu"),
|
|
45
|
+
)
|
|
46
|
+
verify = not studio_cfg.disable_verify
|
|
47
|
+
result = make_request(studio_cfg.studio_url, graphql_req, verify)
|
|
48
|
+
if not result.was_successful:
|
|
49
|
+
rasa.shared.utils.cli.print_error_and_exit(result.message)
|
|
50
|
+
|
|
51
|
+
rasa.shared.utils.cli.print_success(f"Pushed data to assistant '{assistant_name}'.")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def handle_push(args: argparse.Namespace) -> None:
|
|
55
|
+
"""Push the entire assistant.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
args: The command line arguments.
|
|
59
|
+
"""
|
|
60
|
+
studio_cfg = get_studio_config()
|
|
61
|
+
|
|
62
|
+
run_validation(args)
|
|
63
|
+
|
|
64
|
+
importer = TrainingDataImporter.load_from_dict(
|
|
65
|
+
domain_path=args.domain,
|
|
66
|
+
config_path=args.config,
|
|
67
|
+
expand_env_vars=False,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
domain_yaml = dump_obj_as_yaml_to_string(importer.get_user_domain().as_dict())
|
|
71
|
+
config_yaml = read_file(Path(args.config))
|
|
72
|
+
endpoints_yaml = read_file(Path(args.endpoints))
|
|
73
|
+
|
|
74
|
+
flow_importer = TrainingDataImporter.load_from_dict(
|
|
75
|
+
training_data_paths=args.data, expand_env_vars=False
|
|
76
|
+
)
|
|
77
|
+
flows_yaml = YamlFlowsWriter().dumps(flow_importer.get_user_flows())
|
|
78
|
+
|
|
79
|
+
nlu_importer = TrainingDataImporter.load_from_dict(
|
|
80
|
+
training_data_paths=args.data, expand_env_vars=False
|
|
81
|
+
)
|
|
82
|
+
nlu_yaml = RasaYAMLWriter().dumps(nlu_importer.get_nlu_data())
|
|
83
|
+
|
|
84
|
+
assistant_name = read_assistant_name()
|
|
85
|
+
_send_to_studio(
|
|
86
|
+
assistant_name,
|
|
87
|
+
{
|
|
88
|
+
"flows": flows_yaml,
|
|
89
|
+
"domain": domain_yaml,
|
|
90
|
+
"config": config_yaml,
|
|
91
|
+
"endpoints": endpoints_yaml,
|
|
92
|
+
"nlu": nlu_yaml,
|
|
93
|
+
},
|
|
94
|
+
studio_cfg,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def handle_push_config(args: argparse.Namespace) -> None:
|
|
99
|
+
"""Push only the assistant configuration (config.yml).
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
args: The command line arguments.
|
|
103
|
+
"""
|
|
104
|
+
studio_cfg = get_studio_config()
|
|
105
|
+
assistant_name = read_assistant_name()
|
|
106
|
+
|
|
107
|
+
config_yaml = read_file(Path(args.config))
|
|
108
|
+
if not config_yaml:
|
|
109
|
+
rasa.shared.utils.cli.print_error_and_exit(
|
|
110
|
+
"No configuration data was found in the assistant."
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
_send_to_studio(assistant_name, {"config": config_yaml}, studio_cfg)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def handle_push_endpoints(args: argparse.Namespace) -> None:
|
|
117
|
+
"""Push only the endpoints configuration (endpoints.yml).
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
args: The command line arguments.
|
|
121
|
+
"""
|
|
122
|
+
studio_cfg = get_studio_config()
|
|
123
|
+
assistant_name = read_assistant_name()
|
|
124
|
+
|
|
125
|
+
endpoints_yaml = read_file(Path(args.endpoints))
|
|
126
|
+
if not endpoints_yaml:
|
|
127
|
+
rasa.shared.utils.cli.print_error_and_exit(
|
|
128
|
+
"No endpoints data was found in the assistant."
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
_send_to_studio(assistant_name, {"endpoints": endpoints_yaml}, studio_cfg)
|
rasa/studio/upload.py
CHANGED
|
@@ -2,11 +2,12 @@ import argparse
|
|
|
2
2
|
import base64
|
|
3
3
|
import re
|
|
4
4
|
import sys
|
|
5
|
-
from typing import Any, Dict, Iterable, List, Set, Text, Tuple, Union
|
|
5
|
+
from typing import Any, Dict, Iterable, List, Optional, Set, Text, Tuple, Union
|
|
6
6
|
|
|
7
7
|
import questionary
|
|
8
8
|
import requests
|
|
9
9
|
import structlog
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
10
11
|
|
|
11
12
|
import rasa.cli.telemetry
|
|
12
13
|
import rasa.cli.utils
|
|
@@ -32,6 +33,7 @@ from rasa.shared.nlu.training_data.formats.rasa_yaml import (
|
|
|
32
33
|
)
|
|
33
34
|
from rasa.shared.utils.yaml import (
|
|
34
35
|
dump_obj_as_yaml_to_string,
|
|
36
|
+
read_yaml,
|
|
35
37
|
read_yaml_file,
|
|
36
38
|
)
|
|
37
39
|
from rasa.studio import results_logger
|
|
@@ -64,6 +66,16 @@ DOMAIN_KEYS = [
|
|
|
64
66
|
]
|
|
65
67
|
|
|
66
68
|
|
|
69
|
+
class CALMImportParts(BaseModel):
|
|
70
|
+
"""All pieces that will be uploaded to Rasa Studio."""
|
|
71
|
+
|
|
72
|
+
flows: Dict[str, Any]
|
|
73
|
+
domain: Dict[str, Any]
|
|
74
|
+
config: Dict[str, Any]
|
|
75
|
+
endpoints: Dict[str, Any]
|
|
76
|
+
nlu: Dict[str, Any] = Field(default_factory=dict)
|
|
77
|
+
|
|
78
|
+
|
|
67
79
|
def _get_selected_entities_and_intents(
|
|
68
80
|
args: argparse.Namespace,
|
|
69
81
|
intents_from_files: Set[Text],
|
|
@@ -208,79 +220,93 @@ def _get_assistant_name(config: Dict[Text, Any]) -> str:
|
|
|
208
220
|
return assistant_name
|
|
209
221
|
|
|
210
222
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
223
|
+
def build_calm_import_parts(
|
|
224
|
+
data_path: Union[Text, List[Text]],
|
|
225
|
+
domain_path: Text,
|
|
226
|
+
config_path: Text,
|
|
227
|
+
endpoints_path: Optional[Text] = None,
|
|
228
|
+
assistant_name: Optional[Text] = None,
|
|
229
|
+
) -> Tuple[str, CALMImportParts]:
|
|
230
|
+
"""Builds the parts of the assistant to be uploaded to Studio.
|
|
216
231
|
|
|
217
232
|
Args:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
endpoint: The studio endpoint
|
|
225
|
-
verify: Whether to verify SSL
|
|
233
|
+
data_path: The path to the training data
|
|
234
|
+
domain_path: The path to the domain
|
|
235
|
+
config_path: The path to the config
|
|
236
|
+
endpoints_path: The path to the endpoints
|
|
237
|
+
assistant_name: The name of the assistant
|
|
238
|
+
|
|
226
239
|
Returns:
|
|
227
|
-
|
|
240
|
+
The assistant name and the parts to be uploaded
|
|
228
241
|
"""
|
|
229
|
-
run_validation(args)
|
|
230
|
-
|
|
231
|
-
structlogger.info(
|
|
232
|
-
"rasa.studio.upload.loading_data", event_info="Parsing CALM assistant data..."
|
|
233
|
-
)
|
|
234
|
-
|
|
235
242
|
importer = TrainingDataImporter.load_from_dict(
|
|
236
|
-
domain_path=
|
|
237
|
-
config_path=
|
|
243
|
+
domain_path=domain_path,
|
|
244
|
+
config_path=config_path,
|
|
238
245
|
expand_env_vars=False,
|
|
239
246
|
)
|
|
240
247
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
assistant_name = _get_assistant_name(config)
|
|
248
|
+
config = read_yaml_file(config_path, expand_env_vars=False)
|
|
249
|
+
endpoints = read_yaml_file(endpoints_path, expand_env_vars=False)
|
|
250
|
+
assistant_name = assistant_name or _get_assistant_name(config)
|
|
244
251
|
|
|
245
|
-
config_from_files = read_yaml_file(args.config, expand_env_vars=False)
|
|
246
252
|
domain_from_files = importer.get_user_domain().as_dict()
|
|
247
|
-
|
|
248
|
-
# Extract domain and config values
|
|
249
253
|
domain = extract_values(domain_from_files, DOMAIN_KEYS)
|
|
250
254
|
|
|
251
|
-
# Prepare flows
|
|
252
255
|
flow_importer = FlowSyncImporter.load_from_dict(
|
|
253
|
-
training_data_paths=
|
|
256
|
+
training_data_paths=data_path, expand_env_vars=False
|
|
254
257
|
)
|
|
258
|
+
|
|
255
259
|
flows = list(flow_importer.get_user_flows())
|
|
260
|
+
flows_yaml = YamlFlowsWriter().dumps(flows)
|
|
261
|
+
flows = read_yaml(flows_yaml, expand_env_vars=False)
|
|
256
262
|
|
|
257
|
-
# We instantiate the TrainingDataImporter again on purpose to avoid
|
|
258
|
-
# adding patterns to domain's actions. More info https://t.ly/W8uuc
|
|
259
263
|
nlu_importer = TrainingDataImporter.load_from_dict(
|
|
260
|
-
training_data_paths=
|
|
264
|
+
training_data_paths=data_path, expand_env_vars=False
|
|
261
265
|
)
|
|
262
266
|
nlu_data = nlu_importer.get_nlu_data()
|
|
263
267
|
nlu_examples = nlu_data.filter_training_examples(
|
|
264
268
|
lambda ex: ex.get("intent") in nlu_data.intents
|
|
265
269
|
)
|
|
266
270
|
nlu_examples_yaml = RasaYAMLWriter().dumps(nlu_examples)
|
|
271
|
+
nlu = read_yaml(nlu_examples_yaml, expand_env_vars=False)
|
|
272
|
+
|
|
273
|
+
parts = CALMImportParts(
|
|
274
|
+
flows=flows,
|
|
275
|
+
domain=domain,
|
|
276
|
+
config=config,
|
|
277
|
+
endpoints=endpoints,
|
|
278
|
+
nlu=nlu,
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
return assistant_name, parts
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
@with_studio_error_handler
|
|
285
|
+
def upload_calm_assistant(
|
|
286
|
+
args: argparse.Namespace, endpoint: str, verify: bool = True
|
|
287
|
+
) -> StudioResult:
|
|
288
|
+
def yaml_or_empty(part: Dict[Text, Any]) -> Optional[str]:
|
|
289
|
+
return dump_obj_as_yaml_to_string(part) if part else None
|
|
267
290
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
291
|
+
run_validation(args)
|
|
292
|
+
structlogger.info(
|
|
293
|
+
"rasa.studio.upload.loading_data", event_info="Parsing CALM assistant data..."
|
|
294
|
+
)
|
|
295
|
+
assistant_name, parts = build_calm_import_parts(
|
|
296
|
+
data_path=args.data,
|
|
297
|
+
domain_path=args.domain,
|
|
298
|
+
config_path=args.config,
|
|
299
|
+
endpoints_path=args.endpoints,
|
|
272
300
|
)
|
|
273
301
|
|
|
274
|
-
# Build GraphQL request
|
|
275
302
|
graphql_req = build_import_request(
|
|
276
303
|
assistant_name,
|
|
277
|
-
flows_yaml=
|
|
278
|
-
domain_yaml=
|
|
279
|
-
config_yaml=
|
|
280
|
-
endpoints=
|
|
281
|
-
nlu_yaml=
|
|
304
|
+
flows_yaml=yaml_or_empty(parts.flows),
|
|
305
|
+
domain_yaml=yaml_or_empty(parts.domain),
|
|
306
|
+
config_yaml=yaml_or_empty(parts.config),
|
|
307
|
+
endpoints=yaml_or_empty(parts.endpoints),
|
|
308
|
+
nlu_yaml=yaml_or_empty(parts.nlu),
|
|
282
309
|
)
|
|
283
|
-
|
|
284
310
|
structlogger.info(
|
|
285
311
|
"rasa.studio.upload.calm", event_info="Uploading to Rasa Studio..."
|
|
286
312
|
)
|
|
@@ -393,7 +419,6 @@ def make_request(endpoint: str, graphql_req: Dict, verify: bool = True) -> Studi
|
|
|
393
419
|
},
|
|
394
420
|
verify=verify,
|
|
395
421
|
)
|
|
396
|
-
|
|
397
422
|
if results_logger.response_has_errors(res.json()):
|
|
398
423
|
track_upload_to_studio_failed(res.json())
|
|
399
424
|
return StudioResult.error(res.json())
|
|
@@ -421,39 +446,64 @@ def _add_missing_entities(
|
|
|
421
446
|
|
|
422
447
|
def build_import_request(
|
|
423
448
|
assistant_name: str,
|
|
424
|
-
flows_yaml: str,
|
|
425
|
-
domain_yaml: str,
|
|
426
|
-
config_yaml: str,
|
|
427
|
-
endpoints: str,
|
|
428
|
-
nlu_yaml: str =
|
|
449
|
+
flows_yaml: Optional[str] = None,
|
|
450
|
+
domain_yaml: Optional[str] = None,
|
|
451
|
+
config_yaml: Optional[str] = None,
|
|
452
|
+
endpoints: Optional[str] = None,
|
|
453
|
+
nlu_yaml: Optional[str] = None,
|
|
429
454
|
) -> Dict:
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
455
|
+
"""Builds the GraphQL request for uploading a modern assistant.
|
|
456
|
+
|
|
457
|
+
Args:
|
|
458
|
+
assistant_name: The name of the assistant
|
|
459
|
+
flows_yaml: The YAML representation of the flows
|
|
460
|
+
domain_yaml: The YAML representation of the domain
|
|
461
|
+
config_yaml: The YAML representation of the config
|
|
462
|
+
endpoints: The YAML representation of the endpoints
|
|
463
|
+
nlu_yaml: The YAML representation of the NLU data
|
|
464
|
+
|
|
465
|
+
Returns:
|
|
466
|
+
A dictionary representing the GraphQL request for uploading the assistant.
|
|
467
|
+
"""
|
|
468
|
+
inputs_map = {
|
|
469
|
+
"domain": domain_yaml,
|
|
470
|
+
"flows": flows_yaml,
|
|
471
|
+
"config": config_yaml,
|
|
472
|
+
"endpoints": endpoints,
|
|
473
|
+
"nlu": nlu_yaml,
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
payload = {
|
|
477
|
+
field: convert_string_to_base64(value)
|
|
478
|
+
for field, value in inputs_map.items()
|
|
479
|
+
if value is not None
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
variables_input = {"assistantName": assistant_name, **payload}
|
|
436
483
|
|
|
437
484
|
graphql_req = {
|
|
438
485
|
"query": (
|
|
439
486
|
"mutation UploadModernAssistant($input: UploadModernAssistantInput!)"
|
|
440
487
|
"{\n uploadModernAssistant(input: $input)\n}"
|
|
441
488
|
),
|
|
442
|
-
"variables": {
|
|
443
|
-
"input": {
|
|
444
|
-
"assistantName": assistant_name,
|
|
445
|
-
"domain": base64_domain,
|
|
446
|
-
"flows": base64_flows,
|
|
447
|
-
"nlu": base64_nlu,
|
|
448
|
-
"config": base64_config,
|
|
449
|
-
"endpoints": base64_endpoints,
|
|
450
|
-
}
|
|
451
|
-
},
|
|
489
|
+
"variables": {"input": variables_input},
|
|
452
490
|
}
|
|
453
491
|
|
|
454
492
|
return graphql_req
|
|
455
493
|
|
|
456
494
|
|
|
495
|
+
def convert_string_to_base64(string: str) -> str:
|
|
496
|
+
"""Converts a string to base64.
|
|
497
|
+
|
|
498
|
+
Args:
|
|
499
|
+
string: The string to convert
|
|
500
|
+
|
|
501
|
+
Returns:
|
|
502
|
+
The base64 encoded string
|
|
503
|
+
"""
|
|
504
|
+
return base64.b64encode(string.encode("utf-8")).decode("utf-8")
|
|
505
|
+
|
|
506
|
+
|
|
457
507
|
def build_request(
|
|
458
508
|
assistant_name: str, nlu_examples_yaml: str, domain_yaml: str
|
|
459
509
|
) -> Dict:
|