rasa-pro 3.10.15__py3-none-any.whl → 3.11.0__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 +31 -15
- rasa/api.py +12 -2
- rasa/cli/arguments/default_arguments.py +24 -4
- rasa/cli/arguments/run.py +15 -0
- rasa/cli/arguments/shell.py +5 -1
- rasa/cli/arguments/train.py +17 -9
- rasa/cli/evaluate.py +7 -7
- rasa/cli/inspect.py +19 -7
- rasa/cli/interactive.py +1 -0
- rasa/cli/project_templates/calm/config.yml +5 -7
- rasa/cli/project_templates/calm/endpoints.yml +15 -2
- rasa/cli/project_templates/tutorial/config.yml +8 -5
- rasa/cli/project_templates/tutorial/data/flows.yml +1 -1
- rasa/cli/project_templates/tutorial/data/patterns.yml +5 -0
- rasa/cli/project_templates/tutorial/domain.yml +14 -0
- rasa/cli/project_templates/tutorial/endpoints.yml +5 -0
- rasa/cli/run.py +7 -0
- rasa/cli/scaffold.py +4 -2
- rasa/cli/studio/upload.py +0 -15
- rasa/cli/train.py +14 -53
- rasa/cli/utils.py +14 -11
- rasa/cli/x.py +7 -7
- rasa/constants.py +3 -1
- rasa/core/actions/action.py +77 -33
- rasa/core/actions/action_hangup.py +29 -0
- rasa/core/actions/action_repeat_bot_messages.py +89 -0
- rasa/core/actions/e2e_stub_custom_action_executor.py +5 -1
- rasa/core/actions/http_custom_action_executor.py +4 -0
- rasa/core/agent.py +2 -2
- rasa/core/brokers/kafka.py +3 -1
- rasa/core/brokers/pika.py +3 -1
- rasa/core/channels/__init__.py +10 -6
- rasa/core/channels/channel.py +41 -4
- rasa/core/channels/development_inspector.py +150 -46
- rasa/core/channels/inspector/README.md +1 -1
- rasa/core/channels/inspector/dist/assets/{arc-b6e548fe.js → arc-bc141fb2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-fa03ac9e.js → c4Diagram-d0fbc5ce-be2db283.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-ee67392a.js → classDiagram-936ed81e-55366915.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-9b283fae.js → classDiagram-v2-c3cb15f1-bb529518.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{createText-62fc7601-8b6fcc2a.js → createText-62fc7601-b0ec81d6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-22e77f4f.js → edges-f2ad444c-6166330c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-60ffc87f.js → erDiagram-9d236eb7-5ccc6a8e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-9dd802e4.js → flowDb-1972c806-fca3bfe4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-5fa1912f.js → flowDiagram-7ea5b25a-4739080f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-622a1fd2.js → flowchart-elk-definition-abe16c3d-7c1b0e0f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-e285a63a.js → ganttDiagram-9b5ea136-772fd050.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-f237bdca.js → gitGraphDiagram-99d0ae7c-8eae1dc9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-4b03d70e.js → index-2c4b9a3b-f55afcdf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-e7cef9de.js +1317 -0
- rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-72a0fa5f.js → infoDiagram-736b4530-124d4a14.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-82218c41.js → journeyDiagram-df861f2b-7c4fae44.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-78cff630.js → layout-b9885fb6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-5038b469.js → line-7c59abb6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-c4fc4098.js → linear-4776f780.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-c33c8ea6.js → mindmap-definition-beec6740-2332c46c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-a8d03059.js → pieDiagram-dbbf0591-8fb39303.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-6a0e56b2.js → quadrantDiagram-4d7f4fd6-3c7180a2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-2dc7c7bd.js → requirementDiagram-6fc4c22a-e910bcb8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-2360fe39.js → sankeyDiagram-8f13d901-ead16c89.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-41b9f9ad.js → sequenceDiagram-b655622a-29a02a19.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-0aad326f.js → stateDiagram-59f0c015-042b3137.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-9847d984.js → stateDiagram-v2-2b26beab-2178c0f3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-080da4f6-564d890e.js → styles-080da4f6-23ffa4fc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-38957613.js → styles-3dcbcfbf-94f59763.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9c745c82-f0fc6921.js → styles-9c745c82-78a6bebc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-ef3c5a77.js → svgDrawCommon-4835440b-eae2a6f6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-bf3e91c1.js → timeline-definition-5b62e21b-5c968d92.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-4d4026c0.js → xychartDiagram-2b33534f-fd3db0d5.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +18 -15
- rasa/core/channels/inspector/index.html +17 -14
- rasa/core/channels/inspector/package.json +5 -1
- rasa/core/channels/inspector/src/App.tsx +118 -68
- rasa/core/channels/inspector/src/components/Chat.tsx +95 -0
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +11 -10
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +10 -25
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +6 -3
- rasa/core/channels/inspector/src/helpers/audiostream.ts +165 -0
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +10 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +107 -41
- rasa/core/channels/inspector/src/helpers/utils.ts +92 -7
- rasa/core/channels/inspector/src/types.ts +21 -1
- rasa/core/channels/inspector/yarn.lock +94 -1
- rasa/core/channels/rest.py +51 -46
- rasa/core/channels/socketio.py +28 -1
- rasa/core/channels/telegram.py +1 -1
- rasa/core/channels/twilio.py +1 -1
- rasa/core/channels/{audiocodes.py → voice_ready/audiocodes.py} +122 -69
- rasa/core/channels/{voice_aware → voice_ready}/jambonz.py +26 -8
- rasa/core/channels/{voice_aware → voice_ready}/jambonz_protocol.py +57 -5
- rasa/core/channels/{twilio_voice.py → voice_ready/twilio_voice.py} +64 -28
- rasa/core/channels/voice_ready/utils.py +37 -0
- rasa/core/channels/voice_stream/asr/__init__.py +0 -0
- rasa/core/channels/voice_stream/asr/asr_engine.py +89 -0
- rasa/core/channels/voice_stream/asr/asr_event.py +18 -0
- rasa/core/channels/voice_stream/asr/azure.py +129 -0
- rasa/core/channels/voice_stream/asr/deepgram.py +90 -0
- rasa/core/channels/voice_stream/audio_bytes.py +8 -0
- rasa/core/channels/voice_stream/browser_audio.py +107 -0
- rasa/core/channels/voice_stream/call_state.py +23 -0
- rasa/core/channels/voice_stream/tts/__init__.py +0 -0
- rasa/core/channels/voice_stream/tts/azure.py +106 -0
- rasa/core/channels/voice_stream/tts/cartesia.py +118 -0
- rasa/core/channels/voice_stream/tts/tts_cache.py +27 -0
- rasa/core/channels/voice_stream/tts/tts_engine.py +58 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +173 -0
- rasa/core/channels/voice_stream/util.py +57 -0
- rasa/core/channels/voice_stream/voice_channel.py +427 -0
- rasa/core/information_retrieval/qdrant.py +1 -0
- rasa/core/nlg/contextual_response_rephraser.py +45 -17
- rasa/{nlu → core}/persistor.py +203 -68
- rasa/core/policies/enterprise_search_policy.py +119 -63
- rasa/core/policies/flows/flow_executor.py +15 -22
- rasa/core/policies/intentless_policy.py +83 -28
- rasa/core/processor.py +25 -0
- rasa/core/run.py +12 -2
- rasa/core/secrets_manager/constants.py +4 -0
- rasa/core/secrets_manager/factory.py +8 -0
- rasa/core/secrets_manager/vault.py +11 -1
- rasa/core/training/interactive.py +33 -34
- rasa/core/utils.py +47 -21
- rasa/dialogue_understanding/coexistence/llm_based_router.py +41 -14
- rasa/dialogue_understanding/commands/__init__.py +6 -0
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +60 -0
- rasa/dialogue_understanding/commands/session_end_command.py +61 -0
- rasa/dialogue_understanding/commands/user_silence_command.py +59 -0
- rasa/dialogue_understanding/commands/utils.py +5 -0
- rasa/dialogue_understanding/generator/constants.py +2 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +47 -9
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +38 -15
- rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +35 -13
- rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +3 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +60 -13
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +53 -0
- rasa/dialogue_understanding/patterns/repeat.py +37 -0
- rasa/dialogue_understanding/patterns/user_silence.py +37 -0
- rasa/dialogue_understanding/processor/command_processor.py +21 -1
- rasa/e2e_test/aggregate_test_stats_calculator.py +1 -11
- rasa/e2e_test/assertions.py +136 -61
- rasa/e2e_test/assertions_schema.yml +23 -0
- rasa/e2e_test/e2e_test_case.py +85 -6
- rasa/e2e_test/e2e_test_runner.py +2 -3
- rasa/engine/graph.py +0 -1
- rasa/engine/loader.py +12 -0
- rasa/engine/recipes/config_files/default_config.yml +0 -3
- rasa/engine/recipes/default_recipe.py +0 -1
- rasa/engine/recipes/graph_recipe.py +0 -1
- rasa/engine/runner/dask.py +2 -2
- rasa/engine/storage/local_model_storage.py +12 -42
- rasa/engine/storage/storage.py +1 -5
- rasa/engine/validation.py +527 -74
- rasa/model_manager/__init__.py +0 -0
- rasa/model_manager/config.py +40 -0
- rasa/model_manager/model_api.py +559 -0
- rasa/model_manager/runner_service.py +286 -0
- rasa/model_manager/socket_bridge.py +146 -0
- rasa/model_manager/studio_jwt_auth.py +86 -0
- rasa/model_manager/trainer_service.py +325 -0
- rasa/model_manager/utils.py +87 -0
- rasa/model_manager/warm_rasa_process.py +187 -0
- rasa/model_service.py +112 -0
- rasa/model_training.py +42 -23
- rasa/nlu/tokenizers/whitespace_tokenizer.py +3 -14
- rasa/server.py +4 -2
- rasa/shared/constants.py +60 -8
- rasa/shared/core/constants.py +13 -0
- rasa/shared/core/domain.py +107 -50
- rasa/shared/core/events.py +29 -0
- rasa/shared/core/flows/flow.py +5 -0
- rasa/shared/core/flows/flows_list.py +19 -6
- rasa/shared/core/flows/flows_yaml_schema.json +10 -0
- rasa/shared/core/flows/utils.py +39 -0
- rasa/shared/core/flows/validation.py +121 -0
- rasa/shared/core/flows/yaml_flows_io.py +15 -27
- rasa/shared/core/slots.py +5 -0
- rasa/shared/importers/importer.py +59 -41
- rasa/shared/importers/multi_project.py +23 -11
- rasa/shared/importers/rasa.py +12 -3
- rasa/shared/importers/remote_importer.py +196 -0
- rasa/shared/importers/utils.py +3 -1
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +18 -3
- rasa/shared/nlu/training_data/training_data.py +18 -19
- rasa/shared/providers/_configs/litellm_router_client_config.py +220 -0
- rasa/shared/providers/_configs/model_group_config.py +167 -0
- rasa/shared/providers/_configs/openai_client_config.py +1 -1
- rasa/shared/providers/_configs/rasa_llm_client_config.py +73 -0
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -0
- rasa/shared/providers/_configs/utils.py +16 -0
- rasa/shared/providers/_utils.py +79 -0
- rasa/shared/providers/embedding/_base_litellm_embedding_client.py +13 -29
- rasa/shared/providers/embedding/azure_openai_embedding_client.py +54 -21
- rasa/shared/providers/embedding/default_litellm_embedding_client.py +24 -0
- rasa/shared/providers/embedding/litellm_router_embedding_client.py +135 -0
- rasa/shared/providers/llm/_base_litellm_client.py +34 -22
- rasa/shared/providers/llm/azure_openai_llm_client.py +50 -29
- rasa/shared/providers/llm/default_litellm_llm_client.py +24 -0
- rasa/shared/providers/llm/litellm_router_llm_client.py +182 -0
- rasa/shared/providers/llm/rasa_llm_client.py +112 -0
- rasa/shared/providers/llm/self_hosted_llm_client.py +5 -29
- rasa/shared/providers/mappings.py +19 -0
- rasa/shared/providers/router/__init__.py +0 -0
- rasa/shared/providers/router/_base_litellm_router_client.py +183 -0
- rasa/shared/providers/router/router_client.py +73 -0
- rasa/shared/utils/common.py +40 -24
- rasa/shared/utils/health_check/__init__.py +0 -0
- rasa/shared/utils/health_check/embeddings_health_check_mixin.py +31 -0
- rasa/shared/utils/health_check/health_check.py +258 -0
- rasa/shared/utils/health_check/llm_health_check_mixin.py +31 -0
- rasa/shared/utils/io.py +27 -6
- rasa/shared/utils/llm.py +353 -43
- rasa/shared/utils/schemas/events.py +2 -0
- rasa/shared/utils/schemas/model_config.yml +0 -10
- rasa/shared/utils/yaml.py +181 -38
- rasa/studio/data_handler.py +3 -1
- rasa/studio/upload.py +160 -74
- rasa/telemetry.py +94 -17
- rasa/tracing/config.py +3 -1
- rasa/tracing/instrumentation/attribute_extractors.py +95 -18
- rasa/tracing/instrumentation/instrumentation.py +121 -0
- rasa/utils/common.py +5 -0
- rasa/utils/endpoints.py +27 -1
- rasa/utils/io.py +8 -16
- rasa/utils/log_utils.py +9 -2
- rasa/utils/sanic_error_handler.py +32 -0
- rasa/validator.py +110 -4
- rasa/version.py +1 -1
- {rasa_pro-3.10.15.dist-info → rasa_pro-3.11.0.dist-info}/METADATA +14 -12
- {rasa_pro-3.10.15.dist-info → rasa_pro-3.11.0.dist-info}/RECORD +234 -183
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-a5d3e69d.js +0 -1040
- rasa/core/channels/voice_aware/utils.py +0 -20
- rasa/llm_fine_tuning/notebooks/unsloth_finetuning.ipynb +0 -407
- /rasa/core/channels/{voice_aware → voice_ready}/__init__.py +0 -0
- /rasa/core/channels/{voice_native → voice_stream}/__init__.py +0 -0
- {rasa_pro-3.10.15.dist-info → rasa_pro-3.11.0.dist-info}/NOTICE +0 -0
- {rasa_pro-3.10.15.dist-info → rasa_pro-3.11.0.dist-info}/WHEEL +0 -0
- {rasa_pro-3.10.15.dist-info → rasa_pro-3.11.0.dist-info}/entry_points.txt +0 -0
rasa/shared/core/domain.py
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import collections
|
|
2
4
|
import copy
|
|
3
5
|
import json
|
|
4
6
|
import os
|
|
5
7
|
from dataclasses import dataclass
|
|
8
|
+
from functools import cached_property
|
|
6
9
|
from pathlib import Path
|
|
7
10
|
from typing import (
|
|
8
11
|
TYPE_CHECKING,
|
|
9
12
|
Any,
|
|
10
13
|
Callable,
|
|
14
|
+
ClassVar,
|
|
11
15
|
Dict,
|
|
12
16
|
Iterable,
|
|
13
17
|
List,
|
|
18
|
+
MutableMapping,
|
|
14
19
|
NamedTuple,
|
|
15
20
|
NoReturn,
|
|
16
21
|
Optional,
|
|
@@ -19,7 +24,6 @@ from typing import (
|
|
|
19
24
|
Tuple,
|
|
20
25
|
Union,
|
|
21
26
|
cast,
|
|
22
|
-
MutableMapping,
|
|
23
27
|
)
|
|
24
28
|
|
|
25
29
|
import structlog
|
|
@@ -51,11 +55,11 @@ from rasa.shared.core.constants import (
|
|
|
51
55
|
)
|
|
52
56
|
from rasa.shared.core.events import SlotSet, UserUttered
|
|
53
57
|
from rasa.shared.core.slots import (
|
|
54
|
-
Slot,
|
|
55
|
-
CategoricalSlot,
|
|
56
|
-
TextSlot,
|
|
57
58
|
AnySlot,
|
|
59
|
+
CategoricalSlot,
|
|
58
60
|
ListSlot,
|
|
61
|
+
Slot,
|
|
62
|
+
TextSlot,
|
|
59
63
|
)
|
|
60
64
|
from rasa.shared.exceptions import (
|
|
61
65
|
RasaException,
|
|
@@ -63,21 +67,21 @@ from rasa.shared.exceptions import (
|
|
|
63
67
|
YamlSyntaxException,
|
|
64
68
|
)
|
|
65
69
|
from rasa.shared.nlu.constants import (
|
|
66
|
-
|
|
67
|
-
ENTITY_ATTRIBUTE_ROLE,
|
|
70
|
+
ENTITIES,
|
|
68
71
|
ENTITY_ATTRIBUTE_GROUP,
|
|
69
|
-
|
|
72
|
+
ENTITY_ATTRIBUTE_ROLE,
|
|
73
|
+
ENTITY_ATTRIBUTE_TYPE,
|
|
70
74
|
INTENT_NAME_KEY,
|
|
71
|
-
|
|
75
|
+
RESPONSE_IDENTIFIER_DELIMITER,
|
|
72
76
|
)
|
|
73
77
|
from rasa.shared.utils.cli import print_error_and_exit
|
|
74
78
|
from rasa.shared.utils.yaml import (
|
|
75
79
|
KEY_TRAINING_DATA_FORMAT_VERSION,
|
|
80
|
+
dump_obj_as_yaml_to_string,
|
|
76
81
|
read_yaml,
|
|
77
|
-
validate_training_data_format_version,
|
|
78
82
|
read_yaml_file,
|
|
79
|
-
dump_obj_as_yaml_to_string,
|
|
80
83
|
validate_raw_yaml_using_schema_file_with_responses,
|
|
84
|
+
validate_training_data_format_version,
|
|
81
85
|
)
|
|
82
86
|
|
|
83
87
|
if TYPE_CHECKING:
|
|
@@ -155,7 +159,7 @@ class SessionConfig(NamedTuple):
|
|
|
155
159
|
carry_over_slots: bool
|
|
156
160
|
|
|
157
161
|
@staticmethod
|
|
158
|
-
def default() ->
|
|
162
|
+
def default() -> SessionConfig:
|
|
159
163
|
"""Returns the SessionConfig with the default values."""
|
|
160
164
|
return SessionConfig(
|
|
161
165
|
DEFAULT_SESSION_EXPIRATION_TIME_IN_MINUTES,
|
|
@@ -191,13 +195,16 @@ class Domain:
|
|
|
191
195
|
and entities it can recognise.
|
|
192
196
|
"""
|
|
193
197
|
|
|
198
|
+
validate_yaml: ClassVar[bool] = True
|
|
199
|
+
expand_env_vars: ClassVar[bool] = True
|
|
200
|
+
|
|
194
201
|
@classmethod
|
|
195
|
-
def empty(cls) ->
|
|
202
|
+
def empty(cls) -> Domain:
|
|
196
203
|
"""Returns empty Domain."""
|
|
197
204
|
return Domain.from_dict({})
|
|
198
205
|
|
|
199
206
|
@classmethod
|
|
200
|
-
def load(cls, paths: Union[List[Union[Path, Text]], Text, Path]) ->
|
|
207
|
+
def load(cls, paths: Union[List[Union[Path, Text]], Text, Path]) -> Domain:
|
|
201
208
|
"""Returns loaded Domain after merging all domain files."""
|
|
202
209
|
if not paths:
|
|
203
210
|
raise InvalidDomain(
|
|
@@ -215,8 +222,15 @@ class Domain:
|
|
|
215
222
|
return domain
|
|
216
223
|
|
|
217
224
|
@classmethod
|
|
218
|
-
def from_path(cls, path: Union[Text, Path]) ->
|
|
219
|
-
"""Loads the `Domain` from a path.
|
|
225
|
+
def from_path(cls, path: Union[Text, Path]) -> Domain:
|
|
226
|
+
"""Loads the `Domain` from a path.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
path: Path to the domain file.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
The instantiated `Domain` object.
|
|
233
|
+
"""
|
|
220
234
|
path = os.path.abspath(path)
|
|
221
235
|
|
|
222
236
|
if os.path.isfile(path):
|
|
@@ -232,17 +246,30 @@ class Domain:
|
|
|
232
246
|
return domain
|
|
233
247
|
|
|
234
248
|
@classmethod
|
|
235
|
-
def from_file(cls, path: Text) ->
|
|
236
|
-
"""Loads the `Domain` from a YAML file.
|
|
249
|
+
def from_file(cls, path: Text) -> Domain:
|
|
250
|
+
"""Loads the `Domain` from a YAML file.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
path: Path to the domain file.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
The instantiated `Domain` object.
|
|
257
|
+
"""
|
|
237
258
|
return cls.from_yaml(rasa.shared.utils.io.read_file(path), path)
|
|
238
259
|
|
|
239
260
|
@classmethod
|
|
240
|
-
def from_yaml(cls, yaml: Text, original_filename: Text = "") ->
|
|
241
|
-
"""Loads the `Domain` from YAML text after validating it.
|
|
242
|
-
try:
|
|
243
|
-
validate_raw_yaml_using_schema_file_with_responses(yaml, DOMAIN_SCHEMA_FILE)
|
|
261
|
+
def from_yaml(cls, yaml: Text, original_filename: Text = "") -> Domain:
|
|
262
|
+
"""Loads the `Domain` from YAML text after validating it.
|
|
244
263
|
|
|
245
|
-
|
|
264
|
+
Args:
|
|
265
|
+
yaml: The YAML string to load the domain from.
|
|
266
|
+
original_filename: The filename of the original YAML file.
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
The instantiated `Domain` object.
|
|
270
|
+
"""
|
|
271
|
+
try:
|
|
272
|
+
data = cls._dict_from_raw_yaml_content(yaml)
|
|
246
273
|
if not validate_training_data_format_version(data, original_filename):
|
|
247
274
|
return Domain.empty()
|
|
248
275
|
return cls.from_dict(data)
|
|
@@ -251,7 +278,7 @@ class Domain:
|
|
|
251
278
|
raise e
|
|
252
279
|
|
|
253
280
|
@classmethod
|
|
254
|
-
def from_dict(cls, data: Dict) ->
|
|
281
|
+
def from_dict(cls, data: Dict) -> Domain:
|
|
255
282
|
"""Deserializes and creates domain.
|
|
256
283
|
|
|
257
284
|
Args:
|
|
@@ -282,8 +309,8 @@ class Domain:
|
|
|
282
309
|
_validate_forms(forms)
|
|
283
310
|
|
|
284
311
|
return cls(
|
|
285
|
-
intents=intents,
|
|
286
|
-
entities=data.get(KEY_ENTITIES,
|
|
312
|
+
intents=intents or [],
|
|
313
|
+
entities=data.get(KEY_ENTITIES, []),
|
|
287
314
|
slots=slots,
|
|
288
315
|
responses=responses,
|
|
289
316
|
action_names=actions,
|
|
@@ -308,8 +335,15 @@ class Domain:
|
|
|
308
335
|
return SessionConfig(session_expiration_time_min, carry_over_slots)
|
|
309
336
|
|
|
310
337
|
@classmethod
|
|
311
|
-
def from_directory(cls, path: Text) ->
|
|
312
|
-
"""Loads and merges multiple domain files recursively from a directory tree.
|
|
338
|
+
def from_directory(cls, path: Text) -> Domain:
|
|
339
|
+
"""Loads and merges multiple domain files recursively from a directory tree.
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
path: Path to the root directory.
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
The instantiated `Domain` object.
|
|
346
|
+
"""
|
|
313
347
|
combined: Dict[Text, Any] = {}
|
|
314
348
|
duplicates: List[Dict[Text, List[Text]]] = []
|
|
315
349
|
|
|
@@ -319,10 +353,10 @@ class Domain:
|
|
|
319
353
|
if not Domain.is_domain_file(full_path):
|
|
320
354
|
continue
|
|
321
355
|
|
|
322
|
-
|
|
323
|
-
|
|
356
|
+
other_dict = cls._dict_from_raw_yaml_content(
|
|
357
|
+
rasa.shared.utils.io.read_file(full_path)
|
|
358
|
+
)
|
|
324
359
|
|
|
325
|
-
other_dict = read_yaml(rasa.shared.utils.io.read_file(full_path))
|
|
326
360
|
combined = Domain.merge_domain_dicts(other_dict, combined)
|
|
327
361
|
duplicates.append(combined.pop("duplicates", {}))
|
|
328
362
|
|
|
@@ -368,10 +402,10 @@ class Domain:
|
|
|
368
402
|
|
|
369
403
|
def merge(
|
|
370
404
|
self,
|
|
371
|
-
domain: Optional[
|
|
405
|
+
domain: Optional[Domain],
|
|
372
406
|
override: bool = False,
|
|
373
407
|
ignore_warnings_about_duplicates: bool = False,
|
|
374
|
-
) ->
|
|
408
|
+
) -> Domain:
|
|
375
409
|
"""Merges this domain dict with another one, combining their attributes.
|
|
376
410
|
|
|
377
411
|
This method merges domain dicts, and ensures all attributes (like ``intents``,
|
|
@@ -674,7 +708,7 @@ class Domain:
|
|
|
674
708
|
|
|
675
709
|
return intent
|
|
676
710
|
|
|
677
|
-
@
|
|
711
|
+
@cached_property
|
|
678
712
|
def retrieval_intents(self) -> List[Text]:
|
|
679
713
|
"""List retrieval intents present in the domain."""
|
|
680
714
|
return [
|
|
@@ -899,7 +933,7 @@ class Domain:
|
|
|
899
933
|
self.store_entities_as_slots = store_entities_as_slots
|
|
900
934
|
self._check_domain_sanity()
|
|
901
935
|
|
|
902
|
-
def __deepcopy__(self, memo: Optional[Dict[int, Any]]) ->
|
|
936
|
+
def __deepcopy__(self, memo: Optional[Dict[int, Any]]) -> Domain:
|
|
903
937
|
"""Enables making a deep copy of the `Domain` using `copy.deepcopy`.
|
|
904
938
|
|
|
905
939
|
See https://docs.python.org/3/library/copy.html#copy.deepcopy
|
|
@@ -1003,23 +1037,23 @@ class Domain:
|
|
|
1003
1037
|
sorted_intents = sorted(intents, key=sort)
|
|
1004
1038
|
return sorted_intents
|
|
1005
1039
|
|
|
1006
|
-
@
|
|
1040
|
+
@cached_property
|
|
1007
1041
|
def user_actions_and_forms(self) -> List[Text]:
|
|
1008
1042
|
"""Returns combination of user actions and forms."""
|
|
1009
1043
|
return self.user_actions + self.form_names
|
|
1010
1044
|
|
|
1011
|
-
@
|
|
1045
|
+
@cached_property
|
|
1012
1046
|
def num_actions(self) -> int:
|
|
1013
1047
|
"""Returns the number of available actions."""
|
|
1014
1048
|
# noinspection PyTypeChecker
|
|
1015
1049
|
return len(self.action_names_or_texts)
|
|
1016
1050
|
|
|
1017
|
-
@
|
|
1051
|
+
@cached_property
|
|
1018
1052
|
def num_states(self) -> int:
|
|
1019
1053
|
"""Number of used input states for the action prediction."""
|
|
1020
1054
|
return len(self.input_states)
|
|
1021
1055
|
|
|
1022
|
-
@
|
|
1056
|
+
@cached_property
|
|
1023
1057
|
def retrieval_intent_responses(self) -> Dict[Text, List[Dict[Text, Any]]]:
|
|
1024
1058
|
"""Return only the responses which are defined for retrieval intents."""
|
|
1025
1059
|
return dict(
|
|
@@ -1171,8 +1205,7 @@ class Domain:
|
|
|
1171
1205
|
f"Available actions are: \n{action_names}"
|
|
1172
1206
|
)
|
|
1173
1207
|
|
|
1174
|
-
|
|
1175
|
-
@rasa.shared.utils.common.lazy_property
|
|
1208
|
+
@cached_property
|
|
1176
1209
|
def slot_states(self) -> List[Text]:
|
|
1177
1210
|
"""Returns all available slot state strings."""
|
|
1178
1211
|
return [
|
|
@@ -1181,8 +1214,7 @@ class Domain:
|
|
|
1181
1214
|
for feature_index in range(0, slot.feature_dimensionality())
|
|
1182
1215
|
]
|
|
1183
1216
|
|
|
1184
|
-
|
|
1185
|
-
@rasa.shared.utils.common.lazy_property
|
|
1217
|
+
@cached_property
|
|
1186
1218
|
def entity_states(self) -> List[Text]:
|
|
1187
1219
|
"""Returns all available entity state strings."""
|
|
1188
1220
|
entity_states = copy.deepcopy(self.entities)
|
|
@@ -1230,12 +1262,12 @@ class Domain:
|
|
|
1230
1262
|
for entity_sub_label in entity_sub_labels
|
|
1231
1263
|
]
|
|
1232
1264
|
|
|
1233
|
-
@
|
|
1265
|
+
@cached_property
|
|
1234
1266
|
def input_state_map(self) -> Dict[Text, int]:
|
|
1235
1267
|
"""Provide a mapping from state names to indices."""
|
|
1236
1268
|
return {f: i for i, f in enumerate(self.input_states)}
|
|
1237
1269
|
|
|
1238
|
-
@
|
|
1270
|
+
@cached_property
|
|
1239
1271
|
def input_states(self) -> List[Text]:
|
|
1240
1272
|
"""Returns all available states."""
|
|
1241
1273
|
return (
|
|
@@ -1465,7 +1497,7 @@ class Domain:
|
|
|
1465
1497
|
ignore_rule_only_turns: bool = False,
|
|
1466
1498
|
rule_only_data: Optional[Dict[Text, Any]] = None,
|
|
1467
1499
|
) -> List[State]:
|
|
1468
|
-
"""List of states for each state of the
|
|
1500
|
+
"""List of states for each state of the tracker's history.
|
|
1469
1501
|
|
|
1470
1502
|
Args:
|
|
1471
1503
|
tracker: Dialogue state tracker containing the dialogue so far.
|
|
@@ -1682,12 +1714,12 @@ class Domain:
|
|
|
1682
1714
|
"""Return the configuration for an intent."""
|
|
1683
1715
|
return self.intent_properties.get(intent_name, {})
|
|
1684
1716
|
|
|
1685
|
-
@
|
|
1717
|
+
@cached_property
|
|
1686
1718
|
def intents(self) -> List[Text]:
|
|
1687
1719
|
"""Returns sorted list of intents."""
|
|
1688
1720
|
return sorted(self.intent_properties.keys())
|
|
1689
1721
|
|
|
1690
|
-
@
|
|
1722
|
+
@cached_property
|
|
1691
1723
|
def entities(self) -> List[Text]:
|
|
1692
1724
|
"""Returns sorted list of entities."""
|
|
1693
1725
|
return sorted(self.entity_properties.entities)
|
|
@@ -1924,8 +1956,8 @@ class Domain:
|
|
|
1924
1956
|
"""Check whether the domain is empty."""
|
|
1925
1957
|
return self.as_dict() == Domain.empty().as_dict()
|
|
1926
1958
|
|
|
1927
|
-
@
|
|
1928
|
-
def is_domain_file(filename: Union[Text, Path]) -> bool:
|
|
1959
|
+
@classmethod
|
|
1960
|
+
def is_domain_file(cls, filename: Union[Text, Path]) -> bool:
|
|
1929
1961
|
"""Checks whether the given file path is a Rasa domain file.
|
|
1930
1962
|
|
|
1931
1963
|
Args:
|
|
@@ -1944,7 +1976,7 @@ class Domain:
|
|
|
1944
1976
|
return False
|
|
1945
1977
|
|
|
1946
1978
|
try:
|
|
1947
|
-
content = read_yaml_file(filename)
|
|
1979
|
+
content = read_yaml_file(filename, expand_env_vars=cls.expand_env_vars)
|
|
1948
1980
|
except (RasaException, YamlSyntaxException):
|
|
1949
1981
|
structlogger.warning(
|
|
1950
1982
|
"domain.cannot_load_domain_file",
|
|
@@ -2055,6 +2087,31 @@ class Domain:
|
|
|
2055
2087
|
def is_custom_action(self, action_name: str) -> bool:
|
|
2056
2088
|
return action_name in self._custom_actions
|
|
2057
2089
|
|
|
2090
|
+
@classmethod
|
|
2091
|
+
def _dict_from_raw_yaml_content(cls, raw_yaml_content: Text) -> Any:
|
|
2092
|
+
"""Loads the Domain dict from raw YAML content.
|
|
2093
|
+
|
|
2094
|
+
Validates the raw YAML content using the schema file if `validate_yaml` is set
|
|
2095
|
+
to `True`.
|
|
2096
|
+
|
|
2097
|
+
Args:
|
|
2098
|
+
raw_yaml_content: The raw YAML content of the domain file.
|
|
2099
|
+
|
|
2100
|
+
Returns:
|
|
2101
|
+
The Domain dict.
|
|
2102
|
+
"""
|
|
2103
|
+
if cls.validate_yaml:
|
|
2104
|
+
structlogger.info(
|
|
2105
|
+
"domain.from_yaml.validating",
|
|
2106
|
+
)
|
|
2107
|
+
validate_raw_yaml_using_schema_file_with_responses(
|
|
2108
|
+
raw_yaml_content,
|
|
2109
|
+
DOMAIN_SCHEMA_FILE,
|
|
2110
|
+
expand_env_vars=cls.expand_env_vars,
|
|
2111
|
+
)
|
|
2112
|
+
|
|
2113
|
+
return read_yaml(raw_yaml_content, expand_env_vars=cls.expand_env_vars)
|
|
2114
|
+
|
|
2058
2115
|
|
|
2059
2116
|
def warn_about_duplicates_found_during_domain_merging(
|
|
2060
2117
|
duplicates: Dict[Text, List[Text]],
|
rasa/shared/core/events.py
CHANGED
|
@@ -2528,3 +2528,32 @@ class FlowCancelled(SkipEventInMDStoryMixin):
|
|
|
2528
2528
|
)
|
|
2529
2529
|
except KeyError as e:
|
|
2530
2530
|
raise ValueError(f"Failed to parse flow_cancelled event. {e}")
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
class SessionEnded(AlwaysEqualEventMixin):
|
|
2534
|
+
"""Mark the end of a conversation session."""
|
|
2535
|
+
|
|
2536
|
+
type_name = "session_ended"
|
|
2537
|
+
|
|
2538
|
+
def __hash__(self) -> int:
|
|
2539
|
+
"""Returns unique hash for event."""
|
|
2540
|
+
return hash(32143124321)
|
|
2541
|
+
|
|
2542
|
+
def __repr__(self) -> Text:
|
|
2543
|
+
"""Returns event as string for debugging."""
|
|
2544
|
+
return f"SessionEnded(type_name: {self.type_name})"
|
|
2545
|
+
|
|
2546
|
+
def __str__(self) -> Text:
|
|
2547
|
+
"""Returns event as human-readable string."""
|
|
2548
|
+
return f"{self.__class__.__name__}({self.type_name})"
|
|
2549
|
+
|
|
2550
|
+
def as_story_string(self) -> None:
|
|
2551
|
+
"""Skips representing event in stories."""
|
|
2552
|
+
logger.warning(
|
|
2553
|
+
f"'{self.type_name}' events cannot be serialised as story strings."
|
|
2554
|
+
)
|
|
2555
|
+
|
|
2556
|
+
def apply_to(self, tracker: "DialogueStateTracker") -> None:
|
|
2557
|
+
"""Applies event to current conversation state."""
|
|
2558
|
+
# noinspection PyProtectedMember
|
|
2559
|
+
tracker._reset()
|
rasa/shared/core/flows/flow.py
CHANGED
|
@@ -60,6 +60,8 @@ class Flow:
|
|
|
60
60
|
"""
|
|
61
61
|
file_path: Optional[str] = None
|
|
62
62
|
"""The path to the file where the flow is stored."""
|
|
63
|
+
persisted_slots: List[str] = field(default_factory=list)
|
|
64
|
+
"""The list of slots that should be persisted after the flow ends."""
|
|
63
65
|
|
|
64
66
|
@staticmethod
|
|
65
67
|
def from_json(
|
|
@@ -95,6 +97,7 @@ class Flow:
|
|
|
95
97
|
# If we are reading the flows in after training the file_path is part of
|
|
96
98
|
# data. When the model is trained, take the provided file_path.
|
|
97
99
|
file_path=data.get("file_path") if "file_path" in data else file_path,
|
|
100
|
+
persisted_slots=data.get("persisted_slots", []),
|
|
98
101
|
)
|
|
99
102
|
|
|
100
103
|
def get_full_name(self) -> str:
|
|
@@ -167,6 +170,8 @@ class Flow:
|
|
|
167
170
|
data["nlu_trigger"] = self.nlu_triggers.as_json()
|
|
168
171
|
if self.file_path:
|
|
169
172
|
data["file_path"] = self.file_path
|
|
173
|
+
if self.persisted_slots:
|
|
174
|
+
data["persisted_slots"] = self.persisted_slots
|
|
170
175
|
|
|
171
176
|
return data
|
|
172
177
|
|
|
@@ -16,6 +16,7 @@ from rasa.shared.core.flows.validation import (
|
|
|
16
16
|
validate_patterns_are_not_called_or_linked,
|
|
17
17
|
validate_patterns_are_not_calling_or_linking_other_flows,
|
|
18
18
|
validate_step_ids_are_unique,
|
|
19
|
+
DuplicatedFlowIdException,
|
|
19
20
|
)
|
|
20
21
|
from rasa.shared.core.slots import Slot
|
|
21
22
|
|
|
@@ -49,21 +50,31 @@ class FlowsList:
|
|
|
49
50
|
return len(self.underlying_flows) == 0
|
|
50
51
|
|
|
51
52
|
@classmethod
|
|
52
|
-
def from_multiple_flows_lists(
|
|
53
|
+
def from_multiple_flows_lists(
|
|
54
|
+
cls, *other: FlowsList, ignore_duplicates: bool = True
|
|
55
|
+
) -> FlowsList:
|
|
53
56
|
"""Merges multiple lists of flows into a single flow ensuring each flow is
|
|
54
57
|
unique, based on its ID.
|
|
55
58
|
|
|
56
59
|
Args:
|
|
57
60
|
other: Variable number of flow lists instances to be merged.
|
|
61
|
+
ignore_duplicates: Whether to ignore duplicate flow ids, or raise an error.
|
|
58
62
|
|
|
59
63
|
Returns:
|
|
60
64
|
Merged flow list.
|
|
61
65
|
"""
|
|
62
|
-
merged_flows = dict()
|
|
66
|
+
merged_flows: Dict[Text, Flow] = dict()
|
|
63
67
|
for flow_list in other:
|
|
64
68
|
for flow in flow_list:
|
|
65
|
-
if flow.id
|
|
66
|
-
|
|
69
|
+
if flow.id in merged_flows:
|
|
70
|
+
if ignore_duplicates:
|
|
71
|
+
continue
|
|
72
|
+
current_flow_path = flow.file_path
|
|
73
|
+
other_flow_path = merged_flows[flow.id].file_path
|
|
74
|
+
raise DuplicatedFlowIdException(
|
|
75
|
+
flow.id, current_flow_path, other_flow_path
|
|
76
|
+
)
|
|
77
|
+
merged_flows[flow.id] = flow
|
|
67
78
|
return FlowsList(list(merged_flows.values()))
|
|
68
79
|
|
|
69
80
|
@classmethod
|
|
@@ -118,9 +129,11 @@ class FlowsList:
|
|
|
118
129
|
flow_dicts = [flow.as_json() for flow in self.underlying_flows]
|
|
119
130
|
return rasa.shared.utils.io.get_list_fingerprint(flow_dicts)
|
|
120
131
|
|
|
121
|
-
def merge(self, other: FlowsList) -> FlowsList:
|
|
132
|
+
def merge(self, other: FlowsList, ignore_duplicates: bool = True) -> FlowsList:
|
|
122
133
|
"""Merges two lists of flows together."""
|
|
123
|
-
return FlowsList.from_multiple_flows_lists(
|
|
134
|
+
return FlowsList.from_multiple_flows_lists(
|
|
135
|
+
self, other, ignore_duplicates=ignore_duplicates
|
|
136
|
+
)
|
|
124
137
|
|
|
125
138
|
def flow_by_id(self, flow_id: Text) -> Optional[Flow]:
|
|
126
139
|
"""Return the flow with the given id."""
|
|
@@ -279,6 +279,9 @@
|
|
|
279
279
|
},
|
|
280
280
|
"steps": {
|
|
281
281
|
"$ref": "#/$defs/steps"
|
|
282
|
+
},
|
|
283
|
+
"persisted_slots": {
|
|
284
|
+
"$ref": "#/$defs/persisted_slots"
|
|
282
285
|
}
|
|
283
286
|
}
|
|
284
287
|
},
|
|
@@ -288,6 +291,13 @@
|
|
|
288
291
|
"items": {
|
|
289
292
|
"type": "object"
|
|
290
293
|
}
|
|
294
|
+
},
|
|
295
|
+
"persisted_slots": {
|
|
296
|
+
"type": "array",
|
|
297
|
+
"schema_name": "list of slots",
|
|
298
|
+
"items": {
|
|
299
|
+
"type": "string"
|
|
300
|
+
}
|
|
291
301
|
}
|
|
292
302
|
}
|
|
293
303
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from typing import Set
|
|
2
|
+
from rasa.shared.utils.io import raise_deprecation_warning
|
|
3
|
+
|
|
4
|
+
RESET_PROPERTY_NAME = "reset_after_flow_ends"
|
|
5
|
+
PERSIST_PROPERTY_NAME = "persisted_slots"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def warn_deprecated_collect_step_config(flow_id: str, collect_step: str) -> None:
|
|
9
|
+
"""Warns about deprecated reset_after_flow_ends usage in collect steps."""
|
|
10
|
+
raise_deprecation_warning(
|
|
11
|
+
f"Configuring '{RESET_PROPERTY_NAME}' in collect step '{collect_step}' is "
|
|
12
|
+
f"deprecated and will be removed in Rasa Pro 4.0.0. In flow id '{flow_id}', "
|
|
13
|
+
f"please use the '{PERSIST_PROPERTY_NAME}' "
|
|
14
|
+
"property at the flow level instead."
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_duplicate_slot_persistence_config_error_message(
|
|
19
|
+
flow_id: str, collect_step: str
|
|
20
|
+
) -> str:
|
|
21
|
+
"""Returns an error message for duplicate slot persistence configuration."""
|
|
22
|
+
return (
|
|
23
|
+
f"Flow with id '{flow_id}' uses the '{RESET_PROPERTY_NAME}' property "
|
|
24
|
+
f"in collect step '{collect_step}' and also the "
|
|
25
|
+
f"'{PERSIST_PROPERTY_NAME}' property at the flow level. "
|
|
26
|
+
"Please use only one of the two configuration methods."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_invalid_slot_persistence_config_error_message(
|
|
31
|
+
flow_id: str, invalid_slots: Set[str]
|
|
32
|
+
) -> str:
|
|
33
|
+
"""Returns an error message for invalid slot persistence configuration."""
|
|
34
|
+
return (
|
|
35
|
+
f"Flow with id '{flow_id}' lists slot(s) '{invalid_slots}' in the "
|
|
36
|
+
f"'{PERSIST_PROPERTY_NAME}' property. However these slots "
|
|
37
|
+
f"are neither used in a collect step nor a set_slot step of the flow. "
|
|
38
|
+
f"Please remove such slots from the '{PERSIST_PROPERTY_NAME}' property."
|
|
39
|
+
)
|