rasa-pro 3.8.17__py3-none-any.whl → 3.9.14__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.
- README.md +5 -5
- rasa/__main__.py +14 -9
- rasa/anonymization/anonymization_pipeline.py +0 -1
- rasa/anonymization/anonymization_rule_executor.py +3 -3
- rasa/anonymization/utils.py +4 -3
- rasa/api.py +2 -2
- rasa/cli/arguments/default_arguments.py +1 -1
- rasa/cli/arguments/run.py +2 -2
- rasa/cli/arguments/test.py +1 -1
- rasa/cli/arguments/train.py +10 -10
- rasa/cli/e2e_test.py +27 -7
- rasa/cli/export.py +0 -1
- rasa/cli/license.py +3 -3
- rasa/cli/project_templates/calm/actions/action_template.py +1 -1
- rasa/cli/project_templates/calm/config.yml +1 -1
- rasa/cli/project_templates/calm/credentials.yml +1 -1
- rasa/cli/project_templates/calm/data/flows/add_contact.yml +1 -1
- rasa/cli/project_templates/calm/data/flows/remove_contact.yml +1 -1
- rasa/cli/project_templates/calm/domain/add_contact.yml +8 -2
- rasa/cli/project_templates/calm/domain/list_contacts.yml +3 -0
- rasa/cli/project_templates/calm/domain/remove_contact.yml +9 -2
- rasa/cli/project_templates/calm/domain/shared.yml +5 -0
- rasa/cli/project_templates/calm/endpoints.yml +4 -4
- rasa/cli/project_templates/default/actions/actions.py +1 -1
- rasa/cli/project_templates/default/config.yml +5 -5
- rasa/cli/project_templates/default/credentials.yml +1 -1
- rasa/cli/project_templates/default/endpoints.yml +4 -4
- rasa/cli/project_templates/default/tests/test_stories.yml +1 -1
- rasa/cli/project_templates/tutorial/config.yml +1 -1
- rasa/cli/project_templates/tutorial/credentials.yml +1 -1
- rasa/cli/project_templates/tutorial/data/patterns.yml +6 -0
- rasa/cli/project_templates/tutorial/domain.yml +4 -0
- rasa/cli/project_templates/tutorial/endpoints.yml +6 -6
- rasa/cli/run.py +0 -1
- rasa/cli/scaffold.py +3 -2
- rasa/cli/studio/download.py +11 -0
- rasa/cli/studio/studio.py +180 -24
- rasa/cli/studio/upload.py +0 -8
- rasa/cli/telemetry.py +18 -6
- rasa/cli/utils.py +21 -10
- rasa/cli/x.py +3 -2
- rasa/core/actions/action.py +90 -315
- rasa/core/actions/action_exceptions.py +24 -0
- rasa/core/actions/constants.py +3 -0
- rasa/core/actions/custom_action_executor.py +188 -0
- rasa/core/actions/forms.py +11 -7
- rasa/core/actions/grpc_custom_action_executor.py +251 -0
- rasa/core/actions/http_custom_action_executor.py +140 -0
- rasa/core/actions/loops.py +3 -0
- rasa/core/actions/two_stage_fallback.py +1 -1
- rasa/core/agent.py +2 -4
- rasa/core/brokers/pika.py +1 -2
- rasa/core/channels/audiocodes.py +1 -1
- rasa/core/channels/botframework.py +0 -1
- rasa/core/channels/callback.py +0 -1
- rasa/core/channels/console.py +6 -8
- rasa/core/channels/development_inspector.py +1 -1
- rasa/core/channels/facebook.py +0 -3
- rasa/core/channels/hangouts.py +0 -6
- rasa/core/channels/inspector/dist/assets/{arc-5623b6dc.js → arc-b6e548fe.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-685c106a.js → c4Diagram-d0fbc5ce-fa03ac9e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-8cbed007.js → classDiagram-936ed81e-ee67392a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-5889cf12.js → classDiagram-v2-c3cb15f1-9b283fae.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{createText-62fc7601-24c249d7.js → createText-62fc7601-8b6fcc2a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-7dd06a75.js → edges-f2ad444c-22e77f4f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-62c1e54c.js → erDiagram-9d236eb7-60ffc87f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-ce49b86f.js → flowDb-1972c806-9dd802e4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4067e48f.js → flowDiagram-7ea5b25a-5fa1912f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-59fe4051.js → flowchart-elk-definition-abe16c3d-622a1fd2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-47e3a43b.js → ganttDiagram-9b5ea136-e285a63a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-5a2ac0d9.js → gitGraphDiagram-99d0ae7c-f237bdca.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-dfb8efc4.js → index-2c4b9a3b-4b03d70e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-268a75c0.js → index-a5d3e69d.js} +4 -4
- rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-b0c470f2.js → infoDiagram-736b4530-72a0fa5f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-2edb829a.js → journeyDiagram-df861f2b-82218c41.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-b6873d69.js → layout-78cff630.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-1efc5781.js → line-5038b469.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-661e9b94.js → linear-c4fc4098.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2d2e727f.js → mindmap-definition-beec6740-c33c8ea6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-9d3ea93d.js → pieDiagram-dbbf0591-a8d03059.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-06a178a2.js → quadrantDiagram-4d7f4fd6-6a0e56b2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-0bfedffc.js → requirementDiagram-6fc4c22a-2dc7c7bd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-d76d0a04.js → sankeyDiagram-8f13d901-2360fe39.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-37bb4341.js → sequenceDiagram-b655622a-41b9f9ad.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-f52f7f57.js → stateDiagram-59f0c015-0aad326f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-4a986a20.js → stateDiagram-v2-2b26beab-9847d984.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-080da4f6-7dd9ae12.js → styles-080da4f6-564d890e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-46e1ca14.js → styles-3dcbcfbf-38957613.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9c745c82-4a97439a.js → styles-9c745c82-f0fc6921.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-823917a3.js → svgDrawCommon-4835440b-ef3c5a77.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-9ea72896.js → timeline-definition-5b62e21b-bf3e91c1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-b631a8b6.js → xychartDiagram-2b33534f-4d4026c0.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +10 -0
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -7
- rasa/core/channels/inspector/src/helpers/formatters.ts +3 -2
- rasa/core/channels/rest.py +36 -21
- rasa/core/channels/rocketchat.py +0 -1
- rasa/core/channels/socketio.py +1 -1
- rasa/core/channels/telegram.py +3 -3
- rasa/core/channels/webexteams.py +0 -1
- rasa/core/concurrent_lock_store.py +1 -1
- rasa/core/evaluation/marker_base.py +1 -3
- rasa/core/evaluation/marker_stats.py +1 -2
- rasa/core/featurizers/single_state_featurizer.py +2 -4
- rasa/core/featurizers/tracker_featurizers.py +0 -7
- rasa/core/information_retrieval/__init__.py +7 -0
- rasa/core/information_retrieval/faiss.py +9 -4
- rasa/core/information_retrieval/information_retrieval.py +64 -7
- rasa/core/information_retrieval/milvus.py +7 -14
- rasa/core/information_retrieval/qdrant.py +8 -15
- rasa/core/lock_store.py +0 -1
- rasa/core/migrate.py +1 -2
- rasa/core/nlg/callback.py +3 -4
- rasa/core/policies/enterprise_search_policy.py +86 -22
- rasa/core/policies/enterprise_search_prompt_template.jinja2 +4 -41
- rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +60 -0
- rasa/core/policies/flows/flow_executor.py +104 -2
- rasa/core/policies/intentless_policy.py +7 -9
- rasa/core/policies/memoization.py +3 -3
- rasa/core/policies/policy.py +18 -9
- rasa/core/policies/rule_policy.py +8 -11
- rasa/core/policies/ted_policy.py +28 -30
- rasa/core/policies/unexpected_intent_policy.py +1 -2
- rasa/core/processor.py +136 -47
- rasa/core/run.py +41 -25
- rasa/core/secrets_manager/endpoints.py +2 -2
- rasa/core/secrets_manager/vault.py +6 -8
- rasa/core/test.py +3 -5
- rasa/core/tracker_store.py +49 -14
- rasa/core/train.py +1 -3
- rasa/core/training/interactive.py +9 -6
- rasa/core/utils.py +5 -10
- rasa/dialogue_understanding/coexistence/intent_based_router.py +11 -4
- rasa/dialogue_understanding/coexistence/llm_based_router.py +2 -3
- rasa/dialogue_understanding/commands/__init__.py +4 -0
- rasa/dialogue_understanding/commands/can_not_handle_command.py +9 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +9 -0
- rasa/dialogue_understanding/commands/change_flow_command.py +38 -0
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +9 -0
- rasa/dialogue_understanding/commands/clarify_command.py +9 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +9 -0
- rasa/dialogue_understanding/commands/error_command.py +12 -0
- rasa/dialogue_understanding/commands/handle_code_change_command.py +9 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +9 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +9 -0
- rasa/dialogue_understanding/commands/noop_command.py +9 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +34 -3
- rasa/dialogue_understanding/commands/skip_question_command.py +9 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +9 -0
- rasa/dialogue_understanding/generator/__init__.py +16 -1
- rasa/dialogue_understanding/generator/command_generator.py +92 -6
- rasa/dialogue_understanding/generator/constants.py +18 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +7 -5
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +467 -0
- rasa/dialogue_understanding/generator/llm_command_generator.py +39 -609
- rasa/dialogue_understanding/generator/multi_step/__init__.py +0 -0
- rasa/dialogue_understanding/generator/multi_step/fill_slots_prompt.jinja2 +62 -0
- rasa/dialogue_understanding/generator/multi_step/handle_flows_prompt.jinja2 +38 -0
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +827 -0
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +69 -8
- rasa/dialogue_understanding/generator/single_step/__init__.py +0 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +345 -0
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +44 -39
- rasa/dialogue_understanding/processor/command_processor.py +111 -3
- rasa/e2e_test/constants.py +1 -0
- rasa/e2e_test/e2e_test_case.py +44 -0
- rasa/e2e_test/e2e_test_runner.py +114 -11
- rasa/e2e_test/e2e_test_schema.yml +18 -0
- rasa/engine/caching.py +0 -1
- rasa/engine/graph.py +18 -6
- rasa/engine/recipes/config_files/default_config.yml +3 -3
- rasa/engine/recipes/default_components.py +1 -1
- rasa/engine/recipes/default_recipe.py +4 -5
- rasa/engine/recipes/recipe.py +1 -1
- rasa/engine/runner/dask.py +3 -9
- rasa/engine/storage/local_model_storage.py +0 -2
- rasa/engine/validation.py +179 -145
- rasa/exceptions.py +2 -2
- rasa/graph_components/validators/default_recipe_validator.py +3 -5
- rasa/hooks.py +0 -1
- rasa/model.py +1 -1
- rasa/model_training.py +1 -0
- rasa/nlu/classifiers/diet_classifier.py +8 -14
- rasa/nlu/extractors/crf_entity_extractor.py +4 -4
- rasa/nlu/extractors/duckling_entity_extractor.py +1 -1
- rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +1 -5
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +0 -4
- rasa/nlu/featurizers/featurizer.py +1 -1
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +2 -4
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +9 -12
- rasa/nlu/persistor.py +68 -26
- rasa/nlu/selectors/response_selector.py +7 -10
- rasa/nlu/test.py +0 -3
- rasa/nlu/utils/hugging_face/registry.py +1 -1
- rasa/nlu/utils/spacy_utils.py +1 -3
- rasa/server.py +22 -7
- rasa/shared/constants.py +12 -1
- rasa/shared/core/command_payload_reader.py +109 -0
- rasa/shared/core/constants.py +4 -5
- rasa/shared/core/domain.py +57 -56
- rasa/shared/core/events.py +4 -7
- rasa/shared/core/flows/flow.py +9 -0
- rasa/shared/core/flows/flows_list.py +12 -0
- rasa/shared/core/flows/steps/action.py +7 -2
- rasa/shared/core/generator.py +12 -11
- rasa/shared/core/slot_mappings.py +315 -24
- rasa/shared/core/slots.py +4 -2
- rasa/shared/core/trackers.py +32 -14
- rasa/shared/core/training_data/loading.py +0 -1
- rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +11 -11
- rasa/shared/core/training_data/story_writer/yaml_story_writer.py +5 -3
- rasa/shared/core/training_data/structures.py +1 -1
- rasa/shared/core/training_data/visualization.py +1 -1
- rasa/shared/data.py +58 -1
- rasa/shared/exceptions.py +36 -2
- rasa/shared/importers/importer.py +1 -2
- rasa/shared/importers/rasa.py +0 -1
- rasa/shared/nlu/constants.py +2 -0
- rasa/shared/nlu/training_data/entities_parser.py +1 -2
- rasa/shared/nlu/training_data/formats/dialogflow.py +3 -2
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -5
- rasa/shared/nlu/training_data/formats/readerwriter.py +0 -1
- rasa/shared/nlu/training_data/message.py +13 -0
- rasa/shared/nlu/training_data/training_data.py +0 -2
- rasa/shared/providers/openai/session_handler.py +2 -2
- rasa/shared/utils/constants.py +3 -0
- rasa/shared/utils/io.py +11 -0
- rasa/shared/utils/llm.py +1 -2
- rasa/shared/utils/pykwalify_extensions.py +1 -0
- rasa/shared/utils/schemas/domain.yml +3 -0
- rasa/shared/utils/yaml.py +44 -35
- rasa/studio/auth.py +26 -10
- rasa/studio/constants.py +2 -0
- rasa/studio/data_handler.py +114 -107
- rasa/studio/download.py +160 -27
- rasa/studio/results_logger.py +137 -0
- rasa/studio/train.py +6 -7
- rasa/studio/upload.py +159 -134
- rasa/telemetry.py +188 -34
- rasa/tracing/config.py +18 -3
- rasa/tracing/constants.py +26 -2
- rasa/tracing/instrumentation/attribute_extractors.py +50 -41
- rasa/tracing/instrumentation/instrumentation.py +290 -44
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +7 -5
- rasa/tracing/instrumentation/metrics.py +109 -21
- rasa/tracing/metric_instrument_provider.py +83 -3
- rasa/utils/cli.py +2 -1
- rasa/utils/common.py +1 -1
- rasa/utils/endpoints.py +1 -2
- rasa/utils/io.py +6 -6
- rasa/utils/licensing.py +246 -31
- rasa/utils/ml_utils.py +1 -1
- rasa/utils/tensorflow/data_generator.py +1 -1
- rasa/utils/tensorflow/environment.py +1 -1
- rasa/utils/tensorflow/model_data.py +9 -11
- rasa/utils/tensorflow/model_data_utils.py +499 -500
- rasa/utils/tensorflow/models.py +5 -6
- rasa/utils/tensorflow/rasa_layers.py +15 -15
- rasa/utils/train_utils.py +1 -1
- rasa/utils/url_tools.py +53 -0
- rasa/validator.py +305 -3
- rasa/version.py +1 -1
- {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/METADATA +22 -22
- {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/RECORD +271 -253
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-85583a23.js +0 -1
- /rasa/dialogue_understanding/generator/{command_prompt_template.jinja2 → single_step/command_prompt_template.jinja2} +0 -0
- {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/NOTICE +0 -0
- {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/WHEEL +0 -0
- {rasa_pro-3.8.17.dist-info → rasa_pro-3.9.14.dist-info}/entry_points.txt +0 -0
rasa/shared/data.py
CHANGED
|
@@ -4,12 +4,33 @@ import tempfile
|
|
|
4
4
|
import uuid
|
|
5
5
|
from enum import Enum
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import
|
|
7
|
+
from typing import (
|
|
8
|
+
Any,
|
|
9
|
+
Protocol,
|
|
10
|
+
TYPE_CHECKING,
|
|
11
|
+
Text,
|
|
12
|
+
Optional,
|
|
13
|
+
Union,
|
|
14
|
+
List,
|
|
15
|
+
Callable,
|
|
16
|
+
Set,
|
|
17
|
+
Iterable,
|
|
18
|
+
runtime_checkable,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
import structlog
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from rasa.core.channels import UserMessage
|
|
25
|
+
from rasa.shared.core.domain import Domain
|
|
26
|
+
from rasa.shared.nlu.training_data.message import Message
|
|
8
27
|
|
|
9
28
|
YAML_FILE_EXTENSIONS = [".yml", ".yaml"]
|
|
10
29
|
JSON_FILE_EXTENSIONS = [".json"]
|
|
11
30
|
TRAINING_DATA_EXTENSIONS = set(JSON_FILE_EXTENSIONS + YAML_FILE_EXTENSIONS)
|
|
12
31
|
|
|
32
|
+
structlogger = structlog.get_logger()
|
|
33
|
+
|
|
13
34
|
|
|
14
35
|
def yaml_file_extension() -> Text:
|
|
15
36
|
"""Return YAML file extension."""
|
|
@@ -190,3 +211,39 @@ class TrainingType(Enum):
|
|
|
190
211
|
if self == TrainingType.CORE:
|
|
191
212
|
return "core"
|
|
192
213
|
return "rasa"
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@runtime_checkable
|
|
217
|
+
class RegexReader(Protocol):
|
|
218
|
+
def unpack_regex_message(self, message: "Message", **kwargs: Any) -> "Message": ...
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def create_regex_pattern_reader(
|
|
222
|
+
message: "UserMessage", domain: "Domain"
|
|
223
|
+
) -> Optional[RegexReader]:
|
|
224
|
+
"""Create a new instance of a class to unpack regex patterns.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
message: The user message to unpack.
|
|
228
|
+
domain: The domain of the assistant.
|
|
229
|
+
"""
|
|
230
|
+
from rasa.shared.core.command_payload_reader import CommandPayloadReader
|
|
231
|
+
from rasa.shared.core.training_data.story_reader.yaml_story_reader import (
|
|
232
|
+
YAMLStoryReader,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
if message.text is None:
|
|
236
|
+
structlogger.warning(
|
|
237
|
+
"empty.user.message",
|
|
238
|
+
user_text="None",
|
|
239
|
+
)
|
|
240
|
+
return None
|
|
241
|
+
|
|
242
|
+
reader: Union[CommandPayloadReader, YAMLStoryReader, None] = None
|
|
243
|
+
|
|
244
|
+
if message.text.startswith("/SetSlots"):
|
|
245
|
+
reader = CommandPayloadReader()
|
|
246
|
+
elif message.text.startswith("/"):
|
|
247
|
+
reader = YAMLStoryReader(domain)
|
|
248
|
+
|
|
249
|
+
return reader if isinstance(reader, RegexReader) else None
|
rasa/shared/exceptions.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import Optional, Text
|
|
2
|
+
from typing import Optional, Text, Dict, Any
|
|
3
3
|
|
|
4
4
|
import jsonschema
|
|
5
5
|
from ruamel.yaml.error import (
|
|
@@ -10,7 +10,7 @@ from ruamel.yaml.error import (
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class RasaException(Exception):
|
|
13
|
-
"""Base exception class for all errors raised by Rasa
|
|
13
|
+
"""Base exception class for all errors raised by Rasa Pro.
|
|
14
14
|
|
|
15
15
|
These exceptions result from invalid use cases and will be reported
|
|
16
16
|
to the users, but will be ignored in telemetry.
|
|
@@ -127,3 +127,37 @@ class ConnectionException(RasaException):
|
|
|
127
127
|
It's used by our broker and tracker store classes, when
|
|
128
128
|
they can't connect to services like postgres, dynamoDB, mongo.
|
|
129
129
|
"""
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ProviderClientAPIException(RasaException):
|
|
133
|
+
"""Raised for errors that occur during API interactions
|
|
134
|
+
with LLM / embedding providers.
|
|
135
|
+
|
|
136
|
+
Attributes:
|
|
137
|
+
original_exception (Exception): The original exception that was
|
|
138
|
+
caught and led to this custom exception.
|
|
139
|
+
message: (Optional[str]): Optional explanation of the error.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
def __init__(
|
|
143
|
+
self,
|
|
144
|
+
original_exception: Exception,
|
|
145
|
+
message: Optional[str] = None,
|
|
146
|
+
info: Optional[Dict[Text, Any]] = None,
|
|
147
|
+
):
|
|
148
|
+
super().__init__(
|
|
149
|
+
f"{message if message is not None else ''}"
|
|
150
|
+
f"\nOriginal error: {original_exception})"
|
|
151
|
+
)
|
|
152
|
+
self.message = message
|
|
153
|
+
self.original_exception = original_exception
|
|
154
|
+
self.info = info
|
|
155
|
+
|
|
156
|
+
def __str__(self) -> Text:
|
|
157
|
+
s = f"{self.__class__.__name__}:"
|
|
158
|
+
if self.message is not None:
|
|
159
|
+
s += f"\n{self.message}"
|
|
160
|
+
s += f"\nOriginal error: {self.original_exception}\n"
|
|
161
|
+
if self.info:
|
|
162
|
+
s += f"\nInfo: \n{self.info}\n"
|
|
163
|
+
return s
|
|
@@ -581,7 +581,7 @@ class ResponsesSyncImporter(PassThroughImporter):
|
|
|
581
581
|
|
|
582
582
|
@staticmethod
|
|
583
583
|
def _get_nlu_data_with_responses(
|
|
584
|
-
responses: Dict[Text, List[Dict[Text, Any]]]
|
|
584
|
+
responses: Dict[Text, List[Dict[Text, Any]]],
|
|
585
585
|
) -> TrainingData:
|
|
586
586
|
"""Construct training data object with only the responses supplied.
|
|
587
587
|
|
|
@@ -611,7 +611,6 @@ class E2EImporter(PassThroughImporter):
|
|
|
611
611
|
return original.merge(e2e_domain)
|
|
612
612
|
|
|
613
613
|
def _get_domain_with_e2e_actions(self) -> Domain:
|
|
614
|
-
|
|
615
614
|
stories = self.get_stories()
|
|
616
615
|
|
|
617
616
|
additional_e2e_action_names = set()
|
rasa/shared/importers/rasa.py
CHANGED
rasa/shared/nlu/constants.py
CHANGED
|
@@ -24,7 +24,7 @@ GROUP_COMPLETE_MATCH = 0
|
|
|
24
24
|
|
|
25
25
|
# regex for: `[entity_text]((entity_type(:entity_synonym)?)|{entity_dict}|[list_entity_dicts])` # noqa: E501
|
|
26
26
|
ENTITY_REGEX = re.compile(
|
|
27
|
-
r"\[(?P<entity_text>[^\]]+?)\](\((?P<entity>[^:)]+?)(?:\:(?P<value>[^)]+))?\)|\{(?P<entity_dict>[^}]+?)\}|\[(?P<list_entity_dicts>.*?)\])"
|
|
27
|
+
r"\[(?P<entity_text>[^\]]+?)\](\((?P<entity>[^:)]+?)(?:\:(?P<value>[^)]+))?\)|\{(?P<entity_dict>[^}]+?)\}|\[(?P<list_entity_dicts>.*?)\])"
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
SINGLE_ENTITY_DICT = re.compile(r"{(?P<entity_dict>[^}]+?)\}")
|
|
@@ -84,7 +84,6 @@ def find_entities_in_training_example(example: Text) -> List[Dict[Text, Any]]:
|
|
|
84
84
|
for match_inner in re.finditer(
|
|
85
85
|
SINGLE_ENTITY_DICT, match.groupdict()[GROUP_ENTITY_DICT_LIST]
|
|
86
86
|
):
|
|
87
|
-
|
|
88
87
|
entity_attributes = extract_entity_attributes_from_dict(
|
|
89
88
|
entity_text=entity_text, match=match_inner
|
|
90
89
|
)
|
|
@@ -34,8 +34,9 @@ class DialogflowReader(TrainingDataReader):
|
|
|
34
34
|
|
|
35
35
|
if fformat not in {DIALOGFLOW_INTENT, DIALOGFLOW_ENTITIES}:
|
|
36
36
|
raise ValueError(
|
|
37
|
-
"fformat must be either {}, or {}"
|
|
38
|
-
|
|
37
|
+
"fformat must be either {}, or {}".format(
|
|
38
|
+
DIALOGFLOW_INTENT, DIALOGFLOW_ENTITIES
|
|
39
|
+
)
|
|
39
40
|
)
|
|
40
41
|
|
|
41
42
|
root_js = rasa.shared.utils.io.read_json_file(filename)
|
|
@@ -108,7 +108,6 @@ class RasaYAMLReader(TrainingDataReader):
|
|
|
108
108
|
)
|
|
109
109
|
|
|
110
110
|
def _parse_nlu(self, nlu_data: Optional[List[Dict[Text, Any]]]) -> None:
|
|
111
|
-
|
|
112
111
|
if not nlu_data:
|
|
113
112
|
return
|
|
114
113
|
|
|
@@ -162,7 +161,6 @@ class RasaYAMLReader(TrainingDataReader):
|
|
|
162
161
|
for example, entities, metadata in self._parse_training_examples(
|
|
163
162
|
examples, intent
|
|
164
163
|
):
|
|
165
|
-
|
|
166
164
|
plain_text = entities_parser.replace_entities(example)
|
|
167
165
|
|
|
168
166
|
synonyms_parser.add_synonyms_from_entities(
|
|
@@ -534,9 +532,9 @@ class RasaYAMLWriter(TrainingDataWriter):
|
|
|
534
532
|
)
|
|
535
533
|
|
|
536
534
|
if examples_have_metadata or example_texts_have_escape_chars:
|
|
537
|
-
intent[
|
|
538
|
-
|
|
539
|
-
|
|
535
|
+
intent[key_examples] = (
|
|
536
|
+
RasaYAMLWriter._render_training_examples_as_objects(converted)
|
|
537
|
+
)
|
|
540
538
|
else:
|
|
541
539
|
intent[key_examples] = RasaYAMLWriter._render_training_examples_as_text(
|
|
542
540
|
converted
|
|
@@ -122,7 +122,6 @@ class TrainingDataWriter:
|
|
|
122
122
|
# format (e.g. `/greet{"name": "Rasa"}) and we don't have to add the NLU
|
|
123
123
|
# entity annotation
|
|
124
124
|
if not text.startswith(INTENT_MESSAGE_PREFIX):
|
|
125
|
-
|
|
126
125
|
entities = message.get("entities", [])
|
|
127
126
|
entities_with_start_and_end = [
|
|
128
127
|
e for e in entities if "start" in e and "end" in e
|
|
@@ -6,6 +6,7 @@ import copy
|
|
|
6
6
|
import rasa.shared.utils.io
|
|
7
7
|
from rasa.shared.exceptions import RasaException
|
|
8
8
|
from rasa.shared.nlu.constants import (
|
|
9
|
+
COMMANDS,
|
|
9
10
|
TEXT,
|
|
10
11
|
INTENT,
|
|
11
12
|
RESPONSE,
|
|
@@ -475,3 +476,15 @@ class Message:
|
|
|
475
476
|
else:
|
|
476
477
|
break
|
|
477
478
|
return overlapping_pairs
|
|
479
|
+
|
|
480
|
+
def has_intent(self) -> bool:
|
|
481
|
+
"""Checks if the message has an intent."""
|
|
482
|
+
return self.data.get(INTENT) is not None
|
|
483
|
+
|
|
484
|
+
def has_commands(self) -> bool:
|
|
485
|
+
"""Checks if the message has any commands."""
|
|
486
|
+
return self.data.get(COMMANDS) is not None
|
|
487
|
+
|
|
488
|
+
def starts_with_slash_syntax(self) -> bool:
|
|
489
|
+
"""Checks if the message text starts with a slash syntax."""
|
|
490
|
+
return self.data.get(TEXT, "").strip().startswith("/")
|
|
@@ -47,7 +47,6 @@ class TrainingData:
|
|
|
47
47
|
lookup_tables: Optional[List[Dict[Text, Any]]] = None,
|
|
48
48
|
responses: Optional[Dict[Text, List[Dict[Text, Any]]]] = None,
|
|
49
49
|
) -> None:
|
|
50
|
-
|
|
51
50
|
if training_examples:
|
|
52
51
|
self.training_examples = self.sanitize_examples(training_examples)
|
|
53
52
|
else:
|
|
@@ -339,7 +338,6 @@ class TrainingData:
|
|
|
339
338
|
)
|
|
340
339
|
assistant_utterances = self.responses.get(story_lookup_key, [])
|
|
341
340
|
if assistant_utterances:
|
|
342
|
-
|
|
343
341
|
# Use the first response text as training label if needed downstream
|
|
344
342
|
for assistant_utterance in assistant_utterances:
|
|
345
343
|
if assistant_utterance.get(TEXT):
|
|
@@ -6,7 +6,7 @@ from typing import Text
|
|
|
6
6
|
import certifi
|
|
7
7
|
import openai
|
|
8
8
|
import structlog
|
|
9
|
-
from aiohttp import
|
|
9
|
+
from aiohttp import ClientSession, TCPConnector
|
|
10
10
|
|
|
11
11
|
structlogger = structlog.get_logger()
|
|
12
12
|
|
|
@@ -58,7 +58,7 @@ class OpenAISessionHandler:
|
|
|
58
58
|
def _create_session(self) -> ClientSession:
|
|
59
59
|
"""
|
|
60
60
|
Create client session with an SSL context
|
|
61
|
-
created from the certificate path
|
|
61
|
+
created from the certificate path
|
|
62
62
|
"""
|
|
63
63
|
ssl_context = self._create_ssl_context()
|
|
64
64
|
conn = TCPConnector(ssl=ssl_context)
|
rasa/shared/utils/constants.py
CHANGED
rasa/shared/utils/io.py
CHANGED
|
@@ -401,3 +401,14 @@ def handle_print_blocking(output: Text) -> None:
|
|
|
401
401
|
lock = AnsiToWin32(lock).stream
|
|
402
402
|
|
|
403
403
|
print(output, file=lock, flush=True)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def file_as_bytes(file_path: Text) -> bytes:
|
|
407
|
+
"""Read in a file as a byte array."""
|
|
408
|
+
try:
|
|
409
|
+
with open(file_path, "rb") as f:
|
|
410
|
+
return f.read()
|
|
411
|
+
except FileNotFoundError:
|
|
412
|
+
raise FileNotFoundException(
|
|
413
|
+
f"Failed to read file, " f"'{os.path.abspath(file_path)}' does not exist."
|
|
414
|
+
)
|
rasa/shared/utils/llm.py
CHANGED
|
@@ -106,7 +106,6 @@ def tracker_as_readable_transcript(
|
|
|
106
106
|
# using `applied_events` rather than `events` means that only events after the
|
|
107
107
|
# most recent `Restart` or `SessionStarted` are included in the transcript
|
|
108
108
|
for event in tracker.applied_events():
|
|
109
|
-
|
|
110
109
|
if isinstance(event, UserUttered):
|
|
111
110
|
if event.has_triggered_error:
|
|
112
111
|
first_error = event.error_commands[0]
|
|
@@ -273,7 +272,7 @@ def llm_factory(
|
|
|
273
272
|
# packages/langchain/llms/openai.py:189: UserWarning: You are trying to
|
|
274
273
|
# use a chat model. This way of initializing it is no longer supported.
|
|
275
274
|
# Instead, please use: `from langchain.chat_models import ChatOpenAI
|
|
276
|
-
with
|
|
275
|
+
with warnings.catch_warnings():
|
|
277
276
|
warnings.simplefilter("ignore", category=UserWarning)
|
|
278
277
|
if is_azure_config(config):
|
|
279
278
|
# Azure deployments are treated differently. This is done as the
|
rasa/shared/utils/yaml.py
CHANGED
|
@@ -1,40 +1,25 @@
|
|
|
1
|
-
from io import StringIO
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
import re
|
|
4
|
-
from collections import OrderedDict
|
|
5
1
|
import logging
|
|
6
2
|
import os
|
|
3
|
+
import re
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from dataclasses import field
|
|
7
|
+
from functools import lru_cache
|
|
8
|
+
from io import StringIO
|
|
9
|
+
from pathlib import Path
|
|
7
10
|
from typing import Dict, List, Optional, Any, Callable, Tuple, Union
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
import jsonschema
|
|
10
13
|
from importlib_resources import files
|
|
11
14
|
from packaging import version
|
|
12
15
|
from packaging.version import LegacyVersion
|
|
13
16
|
from pykwalify.core import Core
|
|
14
17
|
from pykwalify.errors import SchemaError
|
|
15
|
-
from
|
|
16
|
-
import jsonschema
|
|
17
|
-
from dataclasses import field
|
|
18
|
+
from ruamel import yaml as yaml
|
|
18
19
|
from ruamel.yaml import RoundTripRepresenter, YAMLError
|
|
19
20
|
from ruamel.yaml.constructor import DuplicateKeyError, BaseConstructor, ScalarNode
|
|
20
|
-
from ruamel import yaml as yaml
|
|
21
21
|
from ruamel.yaml.comments import CommentedSeq, CommentedMap
|
|
22
22
|
|
|
23
|
-
from rasa.shared.utils.constants import DEFAULT_ENCODING
|
|
24
|
-
from rasa.shared.utils.io import (
|
|
25
|
-
read_file,
|
|
26
|
-
convert_to_ordered_dict,
|
|
27
|
-
raise_warning,
|
|
28
|
-
read_json_file,
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
from rasa.shared.exceptions import (
|
|
32
|
-
YamlException,
|
|
33
|
-
YamlSyntaxException,
|
|
34
|
-
SchemaValidationError,
|
|
35
|
-
RasaException,
|
|
36
|
-
FileNotFoundException,
|
|
37
|
-
)
|
|
38
23
|
from rasa.shared.constants import (
|
|
39
24
|
MODEL_CONFIG_SCHEMA_FILE,
|
|
40
25
|
CONFIG_SCHEMA_FILE,
|
|
@@ -44,11 +29,32 @@ from rasa.shared.constants import (
|
|
|
44
29
|
SCHEMA_EXTENSIONS_FILE,
|
|
45
30
|
RESPONSES_SCHEMA_FILE,
|
|
46
31
|
)
|
|
32
|
+
from rasa.shared.exceptions import (
|
|
33
|
+
YamlException,
|
|
34
|
+
YamlSyntaxException,
|
|
35
|
+
SchemaValidationError,
|
|
36
|
+
RasaException,
|
|
37
|
+
FileNotFoundException,
|
|
38
|
+
)
|
|
39
|
+
from rasa.shared.utils.constants import (
|
|
40
|
+
DEFAULT_ENCODING,
|
|
41
|
+
READ_YAML_FILE_CACHE_MAXSIZE_ENV_VAR,
|
|
42
|
+
DEFAULT_READ_YAML_FILE_CACHE_MAXSIZE,
|
|
43
|
+
)
|
|
44
|
+
from rasa.shared.utils.io import (
|
|
45
|
+
read_file,
|
|
46
|
+
convert_to_ordered_dict,
|
|
47
|
+
raise_warning,
|
|
48
|
+
read_json_file,
|
|
49
|
+
)
|
|
47
50
|
|
|
48
51
|
logger = logging.getLogger(__name__)
|
|
49
52
|
|
|
50
53
|
KEY_TRAINING_DATA_FORMAT_VERSION = "version"
|
|
51
54
|
YAML_VERSION = (1, 2)
|
|
55
|
+
READ_YAML_FILE_CACHE_MAXSIZE = os.environ.get(
|
|
56
|
+
READ_YAML_FILE_CACHE_MAXSIZE_ENV_VAR, DEFAULT_READ_YAML_FILE_CACHE_MAXSIZE
|
|
57
|
+
)
|
|
52
58
|
|
|
53
59
|
|
|
54
60
|
@dataclass
|
|
@@ -437,8 +443,9 @@ def _is_ascii(text: str) -> bool:
|
|
|
437
443
|
return all(ord(character) < 128 for character in text)
|
|
438
444
|
|
|
439
445
|
|
|
446
|
+
@lru_cache(maxsize=READ_YAML_FILE_CACHE_MAXSIZE)
|
|
440
447
|
def read_yaml_file(
|
|
441
|
-
filename: Union[str, Path], reader_type: Union[str,
|
|
448
|
+
filename: Union[str, Path], reader_type: Union[str, Tuple[str]] = "safe"
|
|
442
449
|
) -> Union[List[Any], Dict[str, Any]]:
|
|
443
450
|
"""Parses a yaml file.
|
|
444
451
|
|
|
@@ -452,7 +459,10 @@ def read_yaml_file(
|
|
|
452
459
|
Parsed content of the file.
|
|
453
460
|
"""
|
|
454
461
|
try:
|
|
455
|
-
|
|
462
|
+
fixed_reader_type = (
|
|
463
|
+
list(reader_type) if isinstance(reader_type, tuple) else reader_type
|
|
464
|
+
)
|
|
465
|
+
return read_yaml(read_file(filename, DEFAULT_ENCODING), fixed_reader_type)
|
|
456
466
|
except (YAMLError, DuplicateKeyError) as e:
|
|
457
467
|
raise YamlSyntaxException(filename, e)
|
|
458
468
|
|
|
@@ -635,14 +645,14 @@ def validate_training_data_format_version(
|
|
|
635
645
|
"""Validates version on the training data content using `version` field.
|
|
636
646
|
|
|
637
647
|
Warns users if the file is not compatible with the current version of
|
|
638
|
-
Rasa
|
|
648
|
+
Rasa Pro.
|
|
639
649
|
|
|
640
650
|
Args:
|
|
641
651
|
yaml_file_content: Raw content of training data file as a dictionary.
|
|
642
652
|
filename: Name of the validated file.
|
|
643
653
|
|
|
644
654
|
Returns:
|
|
645
|
-
`True` if the file can be processed by current version of Rasa
|
|
655
|
+
`True` if the file can be processed by current version of Rasa Pro,
|
|
646
656
|
`False` otherwise.
|
|
647
657
|
"""
|
|
648
658
|
if filename:
|
|
@@ -662,7 +672,7 @@ def validate_training_data_format_version(
|
|
|
662
672
|
logger.info(
|
|
663
673
|
f"The '{KEY_TRAINING_DATA_FORMAT_VERSION}' key is missing in "
|
|
664
674
|
f"the training data file {filename}. "
|
|
665
|
-
f"Rasa
|
|
675
|
+
f"Rasa Pro will read the file as a "
|
|
666
676
|
f"version '{LATEST_TRAINING_DATA_FORMAT_VERSION}' file. "
|
|
667
677
|
f"See {DOCS_URL_TRAINING_DATA}."
|
|
668
678
|
)
|
|
@@ -680,9 +690,9 @@ def validate_training_data_format_version(
|
|
|
680
690
|
if parsed_version < latest_version:
|
|
681
691
|
raise_warning(
|
|
682
692
|
f"Training data file {filename} has a lower "
|
|
683
|
-
f"format version than your Rasa
|
|
693
|
+
f"format version than your Rasa Pro installation: "
|
|
684
694
|
f"{version_value} < {LATEST_TRAINING_DATA_FORMAT_VERSION}. "
|
|
685
|
-
f"Rasa
|
|
695
|
+
f"Rasa Pro will read the file as a version "
|
|
686
696
|
f"{LATEST_TRAINING_DATA_FORMAT_VERSION} file. "
|
|
687
697
|
f"Please update your version key to "
|
|
688
698
|
f"{LATEST_TRAINING_DATA_FORMAT_VERSION}. "
|
|
@@ -690,7 +700,6 @@ def validate_training_data_format_version(
|
|
|
690
700
|
)
|
|
691
701
|
|
|
692
702
|
if latest_version >= parsed_version:
|
|
693
|
-
|
|
694
703
|
return True
|
|
695
704
|
|
|
696
705
|
except TypeError:
|
|
@@ -699,7 +708,7 @@ def validate_training_data_format_version(
|
|
|
699
708
|
f"'{KEY_TRAINING_DATA_FORMAT_VERSION}' as string, for example:\n"
|
|
700
709
|
f"{KEY_TRAINING_DATA_FORMAT_VERSION}: "
|
|
701
710
|
f"'{LATEST_TRAINING_DATA_FORMAT_VERSION}'\n"
|
|
702
|
-
f"Rasa
|
|
711
|
+
f"Rasa Pro will read the file as a "
|
|
703
712
|
f"version '{LATEST_TRAINING_DATA_FORMAT_VERSION}' file.",
|
|
704
713
|
docs=DOCS_URL_TRAINING_DATA,
|
|
705
714
|
)
|
|
@@ -707,9 +716,9 @@ def validate_training_data_format_version(
|
|
|
707
716
|
|
|
708
717
|
raise_warning(
|
|
709
718
|
f"Training data file {filename} has a greater "
|
|
710
|
-
f"format version than your Rasa
|
|
719
|
+
f"format version than your Rasa Pro installation: "
|
|
711
720
|
f"{version_value} > {LATEST_TRAINING_DATA_FORMAT_VERSION}. "
|
|
712
|
-
f"Please consider updating to the latest version of Rasa
|
|
721
|
+
f"Please consider updating to the latest version of Rasa Pro."
|
|
713
722
|
f"This file will be skipped.",
|
|
714
723
|
docs=DOCS_URL_TRAINING_DATA,
|
|
715
724
|
)
|
rasa/studio/auth.py
CHANGED
|
@@ -6,7 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Any, Dict, List, Optional, Text, Union
|
|
7
7
|
|
|
8
8
|
import jwt
|
|
9
|
-
from keycloak import KeycloakOpenID
|
|
9
|
+
from keycloak import KeycloakOpenID, KeycloakError
|
|
10
10
|
from rasa.shared.exceptions import RasaException
|
|
11
11
|
from rasa.shared.utils.yaml import read_yaml_file, write_yaml
|
|
12
12
|
|
|
@@ -17,6 +17,7 @@ from rasa.studio.constants import (
|
|
|
17
17
|
KEYCLOAK_REFRESH_EXPIRES_IN_KEY,
|
|
18
18
|
KEYCLOAK_REFRESH_TOKEN,
|
|
19
19
|
)
|
|
20
|
+
from rasa.studio.results_logger import with_studio_error_handler, StudioResult
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class StudioAuth:
|
|
@@ -31,26 +32,39 @@ class StudioAuth:
|
|
|
31
32
|
realm_name=studio_config.realm_name,
|
|
32
33
|
)
|
|
33
34
|
|
|
34
|
-
def
|
|
35
|
+
def health_check(self) -> bool:
|
|
36
|
+
"""Check if the Keycloak server is reachable.
|
|
35
37
|
|
|
38
|
+
Returns:
|
|
39
|
+
True if the server is reachable, False otherwise.
|
|
40
|
+
"""
|
|
36
41
|
try:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
self.keycloak_openid.well_known()
|
|
43
|
+
return True
|
|
44
|
+
except Exception:
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
@with_studio_error_handler
|
|
48
|
+
def login(
|
|
49
|
+
self, username: Text, password: Text, totp: Optional[int] = None
|
|
50
|
+
) -> StudioResult:
|
|
51
|
+
token_dict = self.keycloak_openid.token(
|
|
52
|
+
username=username, password=password, totp=totp
|
|
53
|
+
)
|
|
43
54
|
keycloak_token = self._resolve_token(token_dict)
|
|
44
55
|
|
|
45
56
|
KeycloakTokenWriter.write_token_to_file(
|
|
46
57
|
keycloak_token, token_file_location=DEFAULT_TOKEN_FILE_PATH
|
|
47
58
|
)
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
return StudioResult.success("Login successful.")
|
|
61
|
+
|
|
62
|
+
@with_studio_error_handler
|
|
63
|
+
def refresh_token(self, refresh_token: Text) -> StudioResult:
|
|
50
64
|
try:
|
|
51
65
|
token_dict = self.keycloak_openid.refresh_token(refresh_token)
|
|
52
66
|
except Exception as e:
|
|
53
|
-
raise
|
|
67
|
+
raise KeycloakError(f"Could not refresh token. Error: {e}")
|
|
54
68
|
|
|
55
69
|
keycloak_token = self._resolve_token(token_dict)
|
|
56
70
|
|
|
@@ -58,6 +72,8 @@ class StudioAuth:
|
|
|
58
72
|
keycloak_token, token_file_location=DEFAULT_TOKEN_FILE_PATH
|
|
59
73
|
)
|
|
60
74
|
|
|
75
|
+
return StudioResult.success("Token refreshed successfully.")
|
|
76
|
+
|
|
61
77
|
@staticmethod
|
|
62
78
|
def _resolve_token(token_dict: Dict[Text, Any]) -> KeycloakToken:
|
|
63
79
|
return KeycloakToken(
|
rasa/studio/constants.py
CHANGED
|
@@ -14,3 +14,5 @@ RASA_STUDIO_CLI_CLIENT_ID_KEY_ENV = "RASA_STUDIO_CLI_CLIENT_ID_KEY"
|
|
|
14
14
|
STUDIO_NLU_FILENAME = "studio_nlu.yml"
|
|
15
15
|
STUDIO_DOMAIN_FILENAME = "studio_domain.yml"
|
|
16
16
|
STUDIO_FLOWS_FILENAME = "studio_flows.yml"
|
|
17
|
+
STUDIO_CONFIG_FILENAME = "studio_config.yml"
|
|
18
|
+
STUDIO_ENDPOINTS_FILENAME = "studio_endpoints.yml"
|