rasa-pro 3.11.0rc2__py3-none-any.whl → 3.11.1__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 +9 -3
- rasa/cli/studio/upload.py +0 -15
- rasa/cli/utils.py +1 -1
- rasa/core/channels/development_inspector.py +8 -2
- rasa/core/channels/voice_ready/audiocodes.py +3 -4
- rasa/core/channels/voice_stream/asr/asr_engine.py +19 -1
- rasa/core/channels/voice_stream/asr/asr_event.py +1 -1
- rasa/core/channels/voice_stream/asr/azure.py +16 -9
- rasa/core/channels/voice_stream/asr/deepgram.py +17 -14
- rasa/core/channels/voice_stream/tts/azure.py +3 -1
- rasa/core/channels/voice_stream/tts/cartesia.py +3 -3
- rasa/core/channels/voice_stream/tts/tts_engine.py +10 -1
- rasa/core/channels/voice_stream/voice_channel.py +48 -18
- rasa/core/information_retrieval/qdrant.py +1 -0
- rasa/core/nlg/contextual_response_rephraser.py +2 -2
- rasa/core/persistor.py +93 -49
- rasa/core/policies/enterprise_search_policy.py +5 -5
- rasa/core/policies/flows/flow_executor.py +18 -8
- rasa/core/policies/intentless_policy.py +9 -5
- rasa/core/processor.py +7 -5
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +2 -1
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +9 -0
- rasa/e2e_test/aggregate_test_stats_calculator.py +11 -1
- rasa/e2e_test/assertions.py +133 -16
- rasa/e2e_test/assertions_schema.yml +23 -0
- rasa/e2e_test/e2e_test_runner.py +2 -2
- rasa/engine/loader.py +12 -0
- rasa/engine/validation.py +310 -86
- rasa/model_manager/config.py +8 -0
- rasa/model_manager/model_api.py +166 -61
- rasa/model_manager/runner_service.py +31 -26
- rasa/model_manager/trainer_service.py +14 -23
- rasa/model_manager/warm_rasa_process.py +187 -0
- rasa/model_service.py +3 -5
- rasa/model_training.py +3 -1
- rasa/shared/constants.py +27 -5
- rasa/shared/core/constants.py +1 -1
- rasa/shared/core/domain.py +8 -31
- rasa/shared/core/flows/yaml_flows_io.py +13 -4
- rasa/shared/importers/importer.py +19 -2
- rasa/shared/importers/rasa.py +5 -1
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +18 -3
- rasa/shared/providers/_configs/litellm_router_client_config.py +29 -9
- rasa/shared/providers/_utils.py +79 -0
- rasa/shared/providers/embedding/default_litellm_embedding_client.py +24 -0
- rasa/shared/providers/embedding/litellm_router_embedding_client.py +1 -1
- rasa/shared/providers/llm/_base_litellm_client.py +26 -0
- rasa/shared/providers/llm/default_litellm_llm_client.py +24 -0
- rasa/shared/providers/llm/litellm_router_llm_client.py +56 -1
- rasa/shared/providers/llm/self_hosted_llm_client.py +4 -28
- rasa/shared/providers/router/_base_litellm_router_client.py +35 -1
- rasa/shared/utils/common.py +30 -3
- rasa/shared/utils/health_check/health_check.py +26 -24
- rasa/shared/utils/yaml.py +116 -31
- rasa/studio/data_handler.py +3 -1
- rasa/studio/upload.py +119 -57
- rasa/telemetry.py +3 -1
- rasa/tracing/config.py +1 -1
- rasa/validator.py +40 -4
- rasa/version.py +1 -1
- {rasa_pro-3.11.0rc2.dist-info → rasa_pro-3.11.1.dist-info}/METADATA +2 -2
- {rasa_pro-3.11.0rc2.dist-info → rasa_pro-3.11.1.dist-info}/RECORD +65 -63
- {rasa_pro-3.11.0rc2.dist-info → rasa_pro-3.11.1.dist-info}/NOTICE +0 -0
- {rasa_pro-3.11.0rc2.dist-info → rasa_pro-3.11.1.dist-info}/WHEEL +0 -0
- {rasa_pro-3.11.0rc2.dist-info → rasa_pro-3.11.1.dist-info}/entry_points.txt +0 -0
|
@@ -83,6 +83,29 @@ schema;assertions:
|
|
|
83
83
|
text_matches:
|
|
84
84
|
type: str
|
|
85
85
|
nullable: false
|
|
86
|
+
bot_did_not_utter:
|
|
87
|
+
type: map
|
|
88
|
+
nullable: false
|
|
89
|
+
mapping:
|
|
90
|
+
utter_name:
|
|
91
|
+
type: str
|
|
92
|
+
nullable: false
|
|
93
|
+
buttons:
|
|
94
|
+
type: seq
|
|
95
|
+
nullable: false
|
|
96
|
+
matching: "all"
|
|
97
|
+
sequence:
|
|
98
|
+
- type: map
|
|
99
|
+
mapping:
|
|
100
|
+
title:
|
|
101
|
+
type: str
|
|
102
|
+
nullable: false
|
|
103
|
+
payload:
|
|
104
|
+
type: str
|
|
105
|
+
nullable: false
|
|
106
|
+
text_matches:
|
|
107
|
+
type: str
|
|
108
|
+
nullable: false
|
|
86
109
|
generative_response_is_relevant:
|
|
87
110
|
type: map
|
|
88
111
|
mapping:
|
rasa/e2e_test/e2e_test_runner.py
CHANGED
|
@@ -136,7 +136,7 @@ class E2ETestRunner:
|
|
|
136
136
|
return turns
|
|
137
137
|
|
|
138
138
|
tracker = await self.agent.processor.fetch_tracker_with_initial_session(
|
|
139
|
-
sender_id
|
|
139
|
+
sender_id, output_channel=collector
|
|
140
140
|
)
|
|
141
141
|
# turn -1 i used to contain events that happen during
|
|
142
142
|
# the start of the session and before the first user message
|
|
@@ -826,7 +826,7 @@ class E2ETestRunner:
|
|
|
826
826
|
return
|
|
827
827
|
|
|
828
828
|
tracker = await self.agent.processor.fetch_tracker_with_initial_session(
|
|
829
|
-
sender_id
|
|
829
|
+
sender_id, output_channel=CollectingOutputChannel()
|
|
830
830
|
)
|
|
831
831
|
|
|
832
832
|
for fixture in fixtures:
|
rasa/engine/loader.py
CHANGED
|
@@ -4,6 +4,10 @@ from typing import Tuple, Type
|
|
|
4
4
|
from rasa.engine.graph import ExecutionContext
|
|
5
5
|
from rasa.engine.runner.interface import GraphRunner
|
|
6
6
|
from rasa.engine.storage.storage import ModelMetadata, ModelStorage
|
|
7
|
+
from rasa.engine.validation import (
|
|
8
|
+
validate_model_client_configuration_setup_during_inference_time,
|
|
9
|
+
validate_model_group_configuration_setup,
|
|
10
|
+
)
|
|
7
11
|
|
|
8
12
|
|
|
9
13
|
def load_predict_graph_runner(
|
|
@@ -26,6 +30,14 @@ def load_predict_graph_runner(
|
|
|
26
30
|
model_storage, model_metadata = model_storage_class.from_model_archive(
|
|
27
31
|
storage_path=storage_path, model_archive_path=model_archive_path
|
|
28
32
|
)
|
|
33
|
+
|
|
34
|
+
# Components using LLMs or embeddings can reference model groups defined in
|
|
35
|
+
# the endpoints.yml file for their client configurations. To ensure they will work
|
|
36
|
+
# properly validate model group references before loading
|
|
37
|
+
# the components.
|
|
38
|
+
validate_model_group_configuration_setup()
|
|
39
|
+
validate_model_client_configuration_setup_during_inference_time(model_metadata)
|
|
40
|
+
|
|
29
41
|
runner = graph_runner_class.create(
|
|
30
42
|
graph_schema=model_metadata.predict_schema,
|
|
31
43
|
model_storage=model_storage,
|
rasa/engine/validation.py
CHANGED
|
@@ -52,7 +52,7 @@ from rasa.engine.graph import (
|
|
|
52
52
|
GraphModelConfiguration,
|
|
53
53
|
)
|
|
54
54
|
from rasa.engine.storage.resource import Resource
|
|
55
|
-
from rasa.engine.storage.storage import ModelStorage
|
|
55
|
+
from rasa.engine.storage.storage import ModelStorage, ModelMetadata
|
|
56
56
|
from rasa.engine.training.fingerprinting import Fingerprintable
|
|
57
57
|
from rasa.shared.constants import (
|
|
58
58
|
DOCS_URL_GRAPH_COMPONENTS,
|
|
@@ -67,11 +67,16 @@ from rasa.shared.constants import (
|
|
|
67
67
|
ROUTER_CONFIG_KEY,
|
|
68
68
|
MODELS_CONFIG_KEY,
|
|
69
69
|
MODEL_GROUP_CONFIG_KEY,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
ROUTING_STRATEGY_CONFIG_KEY,
|
|
71
|
+
VALID_ROUTING_STRATEGIES,
|
|
72
|
+
ROUTING_STRATEGIES_REQUIRING_REDIS_CACHE,
|
|
73
|
+
ROUTING_STRATEGIES_NOT_REQUIRING_CACHE,
|
|
74
74
|
REDIS_HOST_CONFIG_KEY,
|
|
75
|
+
AWS_ACCESS_KEY_ID_CONFIG_KEY,
|
|
76
|
+
AWS_SECRET_ACCESS_KEY_CONFIG_KEY,
|
|
77
|
+
AWS_SESSION_TOKEN_CONFIG_KEY,
|
|
78
|
+
SENSITIVE_DATA,
|
|
79
|
+
USE_CHAT_COMPLETIONS_ENDPOINT_CONFIG_KEY,
|
|
75
80
|
)
|
|
76
81
|
from rasa.shared.core.constants import ACTION_RESET_ROUTING, ACTION_TRIGGER_CHITCHAT
|
|
77
82
|
from rasa.shared.core.domain import Domain
|
|
@@ -79,7 +84,6 @@ from rasa.shared.core.flows import FlowsList, Flow
|
|
|
79
84
|
from rasa.shared.core.slots import Slot
|
|
80
85
|
from rasa.shared.exceptions import RasaException
|
|
81
86
|
from rasa.shared.nlu.training_data.message import Message
|
|
82
|
-
from rasa.shared.utils.cli import print_error_and_exit
|
|
83
87
|
|
|
84
88
|
TypeAnnotation = Union[TypeVar, Text, Type, Optional[AvailableEndpoints]]
|
|
85
89
|
|
|
@@ -895,26 +899,45 @@ def _validate_component_model_client_config(
|
|
|
895
899
|
model_group_ids.append(component_config[key][MODEL_GROUP_CONFIG_KEY])
|
|
896
900
|
|
|
897
901
|
if len(component_config[key]) > 1:
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
902
|
+
structlogger.error(
|
|
903
|
+
"validation.validate_model_client_configuration_setup"
|
|
904
|
+
".only_model_group_reference_key_is_allowed",
|
|
905
|
+
event_info=(
|
|
906
|
+
f"You specified a '{MODEL_GROUP_CONFIG_KEY}' for the '{key}' "
|
|
907
|
+
f"config key for the component "
|
|
908
|
+
f"'{component_name or component_config['name']}'. "
|
|
909
|
+
"No other parameters are allowed under the "
|
|
910
|
+
f"'{key}' key in that case. Please update your config."
|
|
911
|
+
),
|
|
912
|
+
component_name=component_name or component_config["name"],
|
|
913
|
+
component_client_config_key=key,
|
|
904
914
|
)
|
|
915
|
+
sys.exit(1)
|
|
905
916
|
else:
|
|
906
917
|
model_group_syntax_used.append(False)
|
|
907
918
|
|
|
908
|
-
# check that
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
919
|
+
# check that any of the sensitive data keys is not set in config
|
|
920
|
+
for secret_key in SENSITIVE_DATA:
|
|
921
|
+
if secret_key in component_config[key]:
|
|
922
|
+
structlogger.error(
|
|
923
|
+
"validation.validate_model_client_configuration_setup"
|
|
924
|
+
".secret_key_not_allowed_in_the_config",
|
|
925
|
+
event_info=(
|
|
926
|
+
f"You specified '{secret_key}' in the config for "
|
|
927
|
+
f"'{component_name or component_config['name']}', "
|
|
928
|
+
f"which is not allowed. "
|
|
929
|
+
"Set secret keys through environment variables."
|
|
930
|
+
),
|
|
931
|
+
component_name=component_name or component_config["name"],
|
|
932
|
+
component_client_config_key=key,
|
|
933
|
+
secret_key=secret_key,
|
|
934
|
+
)
|
|
935
|
+
sys.exit(1)
|
|
915
936
|
|
|
916
937
|
|
|
917
|
-
def
|
|
938
|
+
def validate_model_client_configuration_setup_during_training_time(
|
|
939
|
+
config: Dict[str, Any],
|
|
940
|
+
) -> None:
|
|
918
941
|
"""Validates the model client configuration setup.
|
|
919
942
|
|
|
920
943
|
Checks the model configuration of the components in the pipeline.
|
|
@@ -969,14 +992,19 @@ def validate_model_client_configuration_setup(config: Dict[str, Any]) -> None:
|
|
|
969
992
|
)
|
|
970
993
|
|
|
971
994
|
if not is_uniform_bool_list(model_group_syntax_used):
|
|
972
|
-
|
|
973
|
-
"
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
995
|
+
structlogger.error(
|
|
996
|
+
"validation.validate_model_client_configuration_setup"
|
|
997
|
+
".inconsistent_use_of_model_group_syntax",
|
|
998
|
+
event_info=(
|
|
999
|
+
"Some of your components refer to an LLM using the "
|
|
1000
|
+
f"'{MODEL_GROUP_CONFIG_KEY}' parameter, other components directly"
|
|
1001
|
+
f" define the LLM under the '{LLM_CONFIG_KEY}' or the "
|
|
1002
|
+
f"'{EMBEDDINGS_CONFIG_KEY}' key. You cannot use"
|
|
1003
|
+
" both types of definitions. Please chose one syntax "
|
|
1004
|
+
"and update your config."
|
|
1005
|
+
),
|
|
979
1006
|
)
|
|
1007
|
+
sys.exit(1)
|
|
980
1008
|
|
|
981
1009
|
# Print a deprecation warning in case the old syntax is used.
|
|
982
1010
|
if len(model_group_syntax_used) > 0 and model_group_syntax_used[0] is False:
|
|
@@ -992,12 +1020,17 @@ def validate_model_client_configuration_setup(config: Dict[str, Any]) -> None:
|
|
|
992
1020
|
|
|
993
1021
|
endpoints = AvailableEndpoints.get_instance()
|
|
994
1022
|
if len(model_group_ids) > 0 and endpoints.model_groups is None:
|
|
995
|
-
|
|
996
|
-
"
|
|
997
|
-
"
|
|
998
|
-
|
|
999
|
-
|
|
1023
|
+
structlogger.error(
|
|
1024
|
+
"validation.validate_model_client_configuration_setup"
|
|
1025
|
+
".referencing_model_group_but_none_are_defined",
|
|
1026
|
+
event_info=(
|
|
1027
|
+
"You are referring to (a) model group(s) in your "
|
|
1028
|
+
"config.yml file, but no model group was defined in "
|
|
1029
|
+
"the endpoints.yml file. Please define the model "
|
|
1030
|
+
"group(s)."
|
|
1031
|
+
),
|
|
1000
1032
|
)
|
|
1033
|
+
sys.exit(1)
|
|
1001
1034
|
|
|
1002
1035
|
if endpoints.model_groups is None:
|
|
1003
1036
|
return
|
|
@@ -1008,23 +1041,146 @@ def validate_model_client_configuration_setup(config: Dict[str, Any]) -> None:
|
|
|
1008
1041
|
|
|
1009
1042
|
for model_group_id in model_group_ids:
|
|
1010
1043
|
if model_group_id not in existing_model_group_ids:
|
|
1011
|
-
|
|
1012
|
-
"
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1044
|
+
structlogger.error(
|
|
1045
|
+
"validation.validate_model_client_configuration_setup"
|
|
1046
|
+
".referencing_undefined_model_group",
|
|
1047
|
+
event_info=(
|
|
1048
|
+
"One of your components is referring to the model group "
|
|
1049
|
+
f"'{model_group_id}', but this model group does not exist in the "
|
|
1050
|
+
f"endpoints.yml file. Please chose one of the existing "
|
|
1051
|
+
f"model groups ({existing_model_group_ids}) or define "
|
|
1052
|
+
f"the model group for '{model_group_id}'."
|
|
1053
|
+
),
|
|
1054
|
+
referencing_model_group_id=model_group_id,
|
|
1055
|
+
existing_model_group_ids=existing_model_group_ids,
|
|
1017
1056
|
)
|
|
1057
|
+
sys.exit(1)
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
def _validate_component_model_client_config_has_references_to_endpoints(
|
|
1061
|
+
component_config: Dict[Text, Any],
|
|
1062
|
+
key: str,
|
|
1063
|
+
component_name: Optional[Text] = None,
|
|
1064
|
+
) -> None:
|
|
1065
|
+
"""Validates that the specified client configuration references a valid model group
|
|
1066
|
+
defined in the `endpoints.yml` file.
|
|
1067
|
+
|
|
1068
|
+
This function ensures that when the client configuration for a component uses the
|
|
1069
|
+
`model_group` key, the referenced model group exists in the `endpoints.yml` file.
|
|
1070
|
+
If the referenced model group is missing or invalid, an error is raised.
|
|
1071
|
+
|
|
1072
|
+
Args:
|
|
1073
|
+
component_config: The configuration dictionary for the component being
|
|
1074
|
+
validated.
|
|
1075
|
+
key: 'llm' or 'embeddings'
|
|
1076
|
+
component_name: Optional; the name of the component being validated, used for
|
|
1077
|
+
error messages.
|
|
1078
|
+
|
|
1079
|
+
Raises:
|
|
1080
|
+
SystemExit: If the referenced model group is missing or invalid.
|
|
1081
|
+
"""
|
|
1082
|
+
if key not in component_config:
|
|
1083
|
+
# no llm/embeddings configuration present
|
|
1084
|
+
return
|
|
1085
|
+
|
|
1086
|
+
endpoints = AvailableEndpoints.get_instance()
|
|
1087
|
+
|
|
1088
|
+
if MODEL_GROUP_CONFIG_KEY in component_config[key]:
|
|
1089
|
+
referencing_model_group_id = component_config[key][MODEL_GROUP_CONFIG_KEY]
|
|
1090
|
+
|
|
1091
|
+
if endpoints.model_groups is None:
|
|
1092
|
+
structlogger.error(
|
|
1093
|
+
"validation.validate_model_client_config_correctly_references_endpoints"
|
|
1094
|
+
".no_model_groups_defined",
|
|
1095
|
+
event_info=(
|
|
1096
|
+
f"Your {component_name or component_config.get('name') or ''} "
|
|
1097
|
+
f"component's '{key}' configuration of the trained model "
|
|
1098
|
+
f"references the model group '{referencing_model_group_id}', "
|
|
1099
|
+
f"but NO MODEL GROUPS ARE DEFINED in the endpoints.yml file. "
|
|
1100
|
+
f"Please add a definition for the required model group in the "
|
|
1101
|
+
f"endpoints.yml file."
|
|
1102
|
+
),
|
|
1103
|
+
component_name=component_name or component_config.get("name"),
|
|
1104
|
+
model_group_id=referencing_model_group_id,
|
|
1105
|
+
component_client_config_key=key,
|
|
1106
|
+
)
|
|
1107
|
+
sys.exit(1)
|
|
1108
|
+
|
|
1109
|
+
existing_model_group_ids = [
|
|
1110
|
+
model_group[MODEL_GROUP_ID_CONFIG_KEY]
|
|
1111
|
+
for model_group in endpoints.model_groups
|
|
1112
|
+
]
|
|
1113
|
+
|
|
1114
|
+
if referencing_model_group_id not in existing_model_group_ids:
|
|
1115
|
+
structlogger.error(
|
|
1116
|
+
"validation.validate_model_client_config_correctly_references_endpoints"
|
|
1117
|
+
".referenced_model_group_does_not_exist",
|
|
1118
|
+
event_info=(
|
|
1119
|
+
f"Your {component_name or component_config.get('name') or ''} "
|
|
1120
|
+
f"component's '{key}' configuration of the trained model "
|
|
1121
|
+
f"references the model group '{referencing_model_group_id}', "
|
|
1122
|
+
f"but this model group DOES NOT EXIST in the endpoints.yml file. "
|
|
1123
|
+
f"The endpoints.yml defines the following model groups: "
|
|
1124
|
+
f"{existing_model_group_ids}. "
|
|
1125
|
+
f"Please add a definition for the required model group in the "
|
|
1126
|
+
f"endpoints.yml file."
|
|
1127
|
+
),
|
|
1128
|
+
model_group_id=referencing_model_group_id,
|
|
1129
|
+
existing_model_group_ids=existing_model_group_ids,
|
|
1130
|
+
component_client_config_key=key,
|
|
1131
|
+
)
|
|
1132
|
+
sys.exit(1)
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
def validate_model_client_configuration_setup_during_inference_time(
|
|
1136
|
+
model_metadata: ModelMetadata,
|
|
1137
|
+
) -> None:
|
|
1138
|
+
for (
|
|
1139
|
+
component_node_name,
|
|
1140
|
+
component_node,
|
|
1141
|
+
) in model_metadata.predict_schema.nodes.items():
|
|
1142
|
+
for client_config_key in [EMBEDDINGS_CONFIG_KEY, LLM_CONFIG_KEY]:
|
|
1143
|
+
if client_config_key not in component_node.config:
|
|
1144
|
+
continue
|
|
1145
|
+
|
|
1146
|
+
_validate_component_model_client_config_has_references_to_endpoints(
|
|
1147
|
+
component_config=component_node.config,
|
|
1148
|
+
key=client_config_key,
|
|
1149
|
+
component_name=component_node_name,
|
|
1150
|
+
)
|
|
1151
|
+
|
|
1152
|
+
# as flow retrieval is not a component itself, we need to
|
|
1153
|
+
# check it separately
|
|
1154
|
+
if FLOW_RETRIEVAL_KEY in component_node.config:
|
|
1155
|
+
if EMBEDDINGS_CONFIG_KEY in component_node.config[FLOW_RETRIEVAL_KEY]:
|
|
1156
|
+
_validate_component_model_client_config_has_references_to_endpoints(
|
|
1157
|
+
component_config=component_node.config[FLOW_RETRIEVAL_KEY],
|
|
1158
|
+
key=EMBEDDINGS_CONFIG_KEY,
|
|
1159
|
+
component_name=component_node_name + "." + FLOW_RETRIEVAL_KEY,
|
|
1160
|
+
)
|
|
1161
|
+
|
|
1162
|
+
# also include the ContextualResponseRephraser component
|
|
1163
|
+
endpoints = AvailableEndpoints.get_instance()
|
|
1164
|
+
if endpoints.nlg is not None:
|
|
1165
|
+
_validate_component_model_client_config_has_references_to_endpoints(
|
|
1166
|
+
component_config=endpoints.nlg.kwargs,
|
|
1167
|
+
key=LLM_CONFIG_KEY,
|
|
1168
|
+
component_name=ContextualResponseRephraser.__name__,
|
|
1169
|
+
)
|
|
1018
1170
|
|
|
1019
1171
|
|
|
1020
1172
|
def _validate_unique_model_group_ids(model_groups: List[Dict[str, Any]]) -> None:
|
|
1021
1173
|
# Each model id must be unique within the model_groups
|
|
1022
1174
|
model_ids = [model_group[MODEL_GROUP_ID_CONFIG_KEY] for model_group in model_groups]
|
|
1023
1175
|
if len(model_ids) != len(set(model_ids)):
|
|
1024
|
-
|
|
1025
|
-
"
|
|
1026
|
-
|
|
1176
|
+
structlogger.error(
|
|
1177
|
+
"validate_model_group_configuration_setup.non_unique_model_group_ids",
|
|
1178
|
+
event_info=(
|
|
1179
|
+
"Each model group id must be unique. Please make sure that "
|
|
1180
|
+
"the model group ids are unique in your endpoints.yml file."
|
|
1181
|
+
),
|
|
1027
1182
|
)
|
|
1183
|
+
sys.exit(1)
|
|
1028
1184
|
|
|
1029
1185
|
|
|
1030
1186
|
def _validate_model_group_with_multiple_models(
|
|
@@ -1036,13 +1192,18 @@ def _validate_model_group_with_multiple_models(
|
|
|
1036
1192
|
len(model_group[MODELS_CONFIG_KEY]) > 1
|
|
1037
1193
|
and ROUTER_CONFIG_KEY not in model_group
|
|
1038
1194
|
):
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1195
|
+
structlogger.error(
|
|
1196
|
+
"validate_model_group_configuration_setup.router_not_present",
|
|
1197
|
+
event_info=(
|
|
1198
|
+
f"You defined multiple models for the model group "
|
|
1199
|
+
f"'{model_group[MODEL_GROUP_ID_CONFIG_KEY]}', but no router. "
|
|
1200
|
+
"If a model group contains multiple models, a router must be "
|
|
1201
|
+
"defined. Please define a router for the model group "
|
|
1202
|
+
f"'{model_group[MODEL_GROUP_ID_CONFIG_KEY]}'."
|
|
1203
|
+
),
|
|
1204
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1045
1205
|
)
|
|
1206
|
+
sys.exit(1)
|
|
1046
1207
|
|
|
1047
1208
|
|
|
1048
1209
|
def _validate_model_group_router_setting(
|
|
@@ -1053,32 +1214,65 @@ def _validate_model_group_router_setting(
|
|
|
1053
1214
|
if ROUTER_CONFIG_KEY not in model_group:
|
|
1054
1215
|
continue
|
|
1055
1216
|
|
|
1217
|
+
for model_config in model_group.get(MODELS_CONFIG_KEY, []):
|
|
1218
|
+
if USE_CHAT_COMPLETIONS_ENDPOINT_CONFIG_KEY in model_config:
|
|
1219
|
+
structlogger.error(
|
|
1220
|
+
"validation.validate_model_group_configuration_setup"
|
|
1221
|
+
f".{USE_CHAT_COMPLETIONS_ENDPOINT_CONFIG_KEY}_set_incorrectly",
|
|
1222
|
+
event_info=(
|
|
1223
|
+
f"You defined the '{USE_CHAT_COMPLETIONS_ENDPOINT_CONFIG_KEY}' "
|
|
1224
|
+
f"in the model group "
|
|
1225
|
+
f"'{model_group[MODEL_GROUP_ID_CONFIG_KEY]}'. This key is not "
|
|
1226
|
+
f"allowed in the model configuration as the router is defined. "
|
|
1227
|
+
f"Please remove this key from your model configuration and "
|
|
1228
|
+
f"update it in the '{ROUTER_CONFIG_KEY} configuration, as it "
|
|
1229
|
+
f"is a router level setting."
|
|
1230
|
+
),
|
|
1231
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1232
|
+
)
|
|
1233
|
+
sys.exit(1)
|
|
1234
|
+
|
|
1056
1235
|
router_config = model_group[ROUTER_CONFIG_KEY]
|
|
1057
|
-
if
|
|
1058
|
-
|
|
1059
|
-
if
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1236
|
+
if ROUTING_STRATEGY_CONFIG_KEY in router_config:
|
|
1237
|
+
routing_strategy = router_config.get(ROUTING_STRATEGY_CONFIG_KEY)
|
|
1238
|
+
if routing_strategy and routing_strategy not in VALID_ROUTING_STRATEGIES:
|
|
1239
|
+
structlogger.error(
|
|
1240
|
+
"validation.validate_model_group_configuration_setup"
|
|
1241
|
+
".invalid_routing_strategy",
|
|
1242
|
+
event_info=(
|
|
1243
|
+
f"The routing strategy '{routing_strategy}' you defined for "
|
|
1244
|
+
f"the model group '{model_group[MODEL_GROUP_ID_CONFIG_KEY]}' "
|
|
1245
|
+
f"is not valid. Valid routing strategies are categorized as "
|
|
1246
|
+
f"follows:\n"
|
|
1247
|
+
f"- Strategies requiring Redis caching: "
|
|
1248
|
+
f"{', '.join(ROUTING_STRATEGIES_REQUIRING_REDIS_CACHE)}\n"
|
|
1249
|
+
f"- Strategies not requiring caching: "
|
|
1250
|
+
f"{', '.join(ROUTING_STRATEGIES_NOT_REQUIRING_CACHE)}"
|
|
1251
|
+
),
|
|
1252
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1253
|
+
invalid_routing_strategy=routing_strategy,
|
|
1254
|
+
supported_routing_strategies_requiring_redis_cache=(
|
|
1255
|
+
ROUTING_STRATEGIES_REQUIRING_REDIS_CACHE
|
|
1256
|
+
),
|
|
1257
|
+
supported_routing_strategies_not_requiring_redis_cache=(
|
|
1258
|
+
ROUTING_STRATEGIES_NOT_REQUIRING_CACHE
|
|
1259
|
+
),
|
|
1068
1260
|
)
|
|
1261
|
+
sys.exit(1)
|
|
1069
1262
|
if (
|
|
1070
|
-
|
|
1263
|
+
routing_strategy in ROUTING_STRATEGIES_REQUIRING_REDIS_CACHE
|
|
1071
1264
|
and REDIS_HOST_CONFIG_KEY not in router_config
|
|
1072
1265
|
):
|
|
1073
1266
|
structlogger.warning(
|
|
1074
|
-
"validation.
|
|
1267
|
+
"validation.routing_strategy.redis_host_not_defined",
|
|
1075
1268
|
event_info=(
|
|
1076
|
-
f"The
|
|
1077
|
-
f" to be defined. Without a Redis host, the system
|
|
1078
|
-
f"'in-memory' caching. Please add the
|
|
1079
|
-
f" to the router configuration for
|
|
1080
|
-
f"'{model_group[MODEL_GROUP_ID_CONFIG_KEY]}'."
|
|
1269
|
+
f"The routing strategy '{routing_strategy}' requires a Redis "
|
|
1270
|
+
f"host to be defined. Without a Redis host, the system "
|
|
1271
|
+
f"defaults to 'in-memory' caching. Please add the "
|
|
1272
|
+
f"'{REDIS_HOST_CONFIG_KEY}' to the router configuration for "
|
|
1273
|
+
f"the model group '{model_group[MODEL_GROUP_ID_CONFIG_KEY]}'."
|
|
1081
1274
|
),
|
|
1275
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1082
1276
|
)
|
|
1083
1277
|
|
|
1084
1278
|
|
|
@@ -1086,13 +1280,18 @@ def _validate_usage_of_environment_variables_in_model_group_config(
|
|
|
1086
1280
|
model_groups: List[Dict[str, Any]],
|
|
1087
1281
|
) -> None:
|
|
1088
1282
|
# Limit the use of ${env_var} in the model_groups config to the following variables:
|
|
1089
|
-
# deployment,
|
|
1283
|
+
# - deployment,
|
|
1284
|
+
# - api_base, api_version and api_key,
|
|
1285
|
+
# - aws_region_name, aws_access_key_id, aws_secret_access_key, and aws_session_token
|
|
1090
1286
|
allowed_env_vars = {
|
|
1091
1287
|
DEPLOYMENT_CONFIG_KEY,
|
|
1092
1288
|
API_BASE_CONFIG_KEY,
|
|
1093
1289
|
API_KEY,
|
|
1094
1290
|
API_VERSION_CONFIG_KEY,
|
|
1095
1291
|
AWS_REGION_NAME_CONFIG_KEY,
|
|
1292
|
+
AWS_ACCESS_KEY_ID_CONFIG_KEY,
|
|
1293
|
+
AWS_SECRET_ACCESS_KEY_CONFIG_KEY,
|
|
1294
|
+
AWS_SESSION_TOKEN_CONFIG_KEY,
|
|
1096
1295
|
}
|
|
1097
1296
|
|
|
1098
1297
|
for model_group in model_groups:
|
|
@@ -1100,39 +1299,62 @@ def _validate_usage_of_environment_variables_in_model_group_config(
|
|
|
1100
1299
|
for key, value in model_config.items():
|
|
1101
1300
|
if isinstance(value, str):
|
|
1102
1301
|
if re.match(r"\${(\w+)}", value) and key not in allowed_env_vars:
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1302
|
+
structlogger.error(
|
|
1303
|
+
"validation.validate_model_group_configuration_setup"
|
|
1304
|
+
".invalid_use_of_environment_variables",
|
|
1305
|
+
event_info=(
|
|
1306
|
+
f"You defined '{key}' as environment variable in model "
|
|
1307
|
+
f"group '{model_group[MODEL_GROUP_ID_CONFIG_KEY]}', "
|
|
1308
|
+
f"which is not allowed. "
|
|
1309
|
+
f"You can only use environment variables for the "
|
|
1310
|
+
f"following keys: {', '.join(allowed_env_vars)}. "
|
|
1311
|
+
f"Please update your config."
|
|
1312
|
+
),
|
|
1313
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1314
|
+
key=key,
|
|
1315
|
+
allowed_keys_for_env_vars=allowed_env_vars,
|
|
1110
1316
|
)
|
|
1317
|
+
sys.exit(1)
|
|
1111
1318
|
|
|
1112
1319
|
|
|
1113
|
-
def
|
|
1320
|
+
def _validate_sensitive_keys_are_an_environment_variables_for_model_groups(
|
|
1114
1321
|
model_groups: List[Dict[str, Any]],
|
|
1115
1322
|
) -> None:
|
|
1116
1323
|
# the api key can only be set as an environment variable
|
|
1117
1324
|
for model_group in model_groups:
|
|
1118
1325
|
for model_config in model_group[MODELS_CONFIG_KEY]:
|
|
1119
1326
|
for key, value in model_config.items():
|
|
1120
|
-
if key
|
|
1327
|
+
if key in SENSITIVE_DATA:
|
|
1121
1328
|
if isinstance(value, str):
|
|
1122
1329
|
if not re.match(r"\${(\w+)}", value):
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1330
|
+
structlogger.error(
|
|
1331
|
+
"validation.validate_model_group_configuration_setup"
|
|
1332
|
+
".sensitive_key_string_value_must_be_set_as_env_var",
|
|
1333
|
+
event_info=(
|
|
1334
|
+
f"You defined the '{key}' in model group "
|
|
1335
|
+
f"'{model_group[MODEL_GROUP_ID_CONFIG_KEY]}' as a "
|
|
1336
|
+
f"string. The '{key}' must be set as an "
|
|
1337
|
+
f"environment variable. Please update your config."
|
|
1338
|
+
),
|
|
1339
|
+
key=key,
|
|
1340
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1128
1341
|
)
|
|
1342
|
+
sys.exit(1)
|
|
1129
1343
|
else:
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1344
|
+
structlogger.error(
|
|
1345
|
+
"validation.validate_model_group_configuration_setup"
|
|
1346
|
+
".sensitive_key_must_be_set_as_env_var",
|
|
1347
|
+
event_info=(
|
|
1348
|
+
f"You should define the '{key}' in model group "
|
|
1349
|
+
f"'{model_group[MODEL_GROUP_ID_CONFIG_KEY]}' using the "
|
|
1350
|
+
f"environment variable syntax - "
|
|
1351
|
+
f"${{ENV_VARIABLE_NAME}}. "
|
|
1352
|
+
f"Please update your config."
|
|
1353
|
+
),
|
|
1354
|
+
key=key,
|
|
1355
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1135
1356
|
)
|
|
1357
|
+
sys.exit(1)
|
|
1136
1358
|
|
|
1137
1359
|
|
|
1138
1360
|
def validate_model_group_configuration_setup() -> None:
|
|
@@ -1147,7 +1369,9 @@ def validate_model_group_configuration_setup() -> None:
|
|
|
1147
1369
|
_validate_usage_of_environment_variables_in_model_group_config(
|
|
1148
1370
|
endpoints.model_groups
|
|
1149
1371
|
)
|
|
1150
|
-
|
|
1372
|
+
_validate_sensitive_keys_are_an_environment_variables_for_model_groups(
|
|
1373
|
+
endpoints.model_groups
|
|
1374
|
+
)
|
|
1151
1375
|
_validate_model_group_router_setting(endpoints.model_groups)
|
|
1152
1376
|
|
|
1153
1377
|
|
rasa/model_manager/config.py
CHANGED
|
@@ -7,6 +7,8 @@ SERVER_BASE_WORKING_DIRECTORY = os.environ.get(
|
|
|
7
7
|
"RASA_MODEL_SERVER_BASE_DIRECTORY", DEFAULT_SERVER_BASE_WORKING_DIRECTORY
|
|
8
8
|
)
|
|
9
9
|
|
|
10
|
+
SERVER_PORT = os.environ.get("RASA_MODEL_SERVER_PORT", 8000)
|
|
11
|
+
|
|
10
12
|
SERVER_BASE_URL = os.environ.get("RASA_MODEL_SERVER_BASE_URL", None)
|
|
11
13
|
|
|
12
14
|
# defaults to storing on the local hard drive
|
|
@@ -30,3 +32,9 @@ MAX_PARALLEL_BOT_RUNS = os.getenv(
|
|
|
30
32
|
)
|
|
31
33
|
|
|
32
34
|
DEFAULT_SERVER_PATH_PREFIX = "talk"
|
|
35
|
+
|
|
36
|
+
DEFAULT_MIN_REQUIRED_DISCSPACE_MB = 1
|
|
37
|
+
|
|
38
|
+
MIN_REQUIRED_DISCSPACE_MB = int(
|
|
39
|
+
os.getenv("MIN_REQUIRED_DISCSPACE_MB", DEFAULT_MIN_REQUIRED_DISCSPACE_MB)
|
|
40
|
+
)
|