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/engine/validation.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import inspect
|
|
3
|
-
import re
|
|
4
3
|
import logging
|
|
4
|
+
import re
|
|
5
5
|
import sys
|
|
6
6
|
import typing
|
|
7
7
|
from typing import (
|
|
@@ -16,14 +16,12 @@ from typing import (
|
|
|
16
16
|
Union,
|
|
17
17
|
TypeVar,
|
|
18
18
|
List,
|
|
19
|
-
Literal,
|
|
20
19
|
)
|
|
21
20
|
|
|
21
|
+
import rasa.utils.common
|
|
22
22
|
import structlog
|
|
23
23
|
import typing_utils
|
|
24
|
-
|
|
25
|
-
import rasa.utils.common
|
|
26
|
-
from rasa.core import IntentlessPolicy
|
|
24
|
+
from rasa.core import IntentlessPolicy, ContextualResponseRephraser
|
|
27
25
|
from rasa.core.policies.policy import PolicyPrediction
|
|
28
26
|
from rasa.core.utils import AvailableEndpoints
|
|
29
27
|
from rasa.dialogue_understanding.coexistence.constants import (
|
|
@@ -32,10 +30,17 @@ from rasa.dialogue_understanding.coexistence.constants import (
|
|
|
32
30
|
STICKY,
|
|
33
31
|
NON_STICKY,
|
|
34
32
|
)
|
|
33
|
+
from rasa.dialogue_understanding.coexistence.intent_based_router import (
|
|
34
|
+
IntentBasedRouter,
|
|
35
|
+
)
|
|
36
|
+
from rasa.dialogue_understanding.coexistence.llm_based_router import LLMBasedRouter
|
|
35
37
|
from rasa.dialogue_understanding.generator import (
|
|
36
38
|
LLMBasedCommandGenerator,
|
|
37
39
|
)
|
|
38
|
-
from rasa.dialogue_understanding.generator.constants import
|
|
40
|
+
from rasa.dialogue_understanding.generator.constants import (
|
|
41
|
+
LLM_CONFIG_KEY,
|
|
42
|
+
FLOW_RETRIEVAL_KEY,
|
|
43
|
+
)
|
|
39
44
|
from rasa.dialogue_understanding.patterns.chitchat import FLOW_PATTERN_CHITCHAT
|
|
40
45
|
from rasa.engine.constants import RESERVED_PLACEHOLDERS
|
|
41
46
|
from rasa.engine.exceptions import GraphSchemaValidationException
|
|
@@ -47,16 +52,31 @@ from rasa.engine.graph import (
|
|
|
47
52
|
GraphModelConfiguration,
|
|
48
53
|
)
|
|
49
54
|
from rasa.engine.storage.resource import Resource
|
|
50
|
-
from rasa.engine.storage.storage import ModelStorage
|
|
55
|
+
from rasa.engine.storage.storage import ModelStorage, ModelMetadata
|
|
51
56
|
from rasa.engine.training.fingerprinting import Fingerprintable
|
|
52
57
|
from rasa.shared.constants import (
|
|
53
58
|
DOCS_URL_GRAPH_COMPONENTS,
|
|
54
59
|
ROUTE_TO_CALM_SLOT,
|
|
55
|
-
API_TYPE_CONFIG_KEY,
|
|
56
|
-
VALID_PROVIDERS_FOR_API_TYPE_CONFIG_KEY,
|
|
57
|
-
PROVIDER_CONFIG_KEY,
|
|
58
|
-
LLM_CONFIG_KEY,
|
|
59
60
|
EMBEDDINGS_CONFIG_KEY,
|
|
61
|
+
API_BASE_CONFIG_KEY,
|
|
62
|
+
DEPLOYMENT_CONFIG_KEY,
|
|
63
|
+
API_VERSION_CONFIG_KEY,
|
|
64
|
+
API_KEY,
|
|
65
|
+
AWS_REGION_NAME_CONFIG_KEY,
|
|
66
|
+
MODEL_GROUP_ID_CONFIG_KEY,
|
|
67
|
+
ROUTER_CONFIG_KEY,
|
|
68
|
+
MODELS_CONFIG_KEY,
|
|
69
|
+
MODEL_GROUP_CONFIG_KEY,
|
|
70
|
+
ROUTING_STRATEGY_CONFIG_KEY,
|
|
71
|
+
VALID_ROUTING_STRATEGIES,
|
|
72
|
+
ROUTING_STRATEGIES_REQUIRING_REDIS_CACHE,
|
|
73
|
+
ROUTING_STRATEGIES_NOT_REQUIRING_CACHE,
|
|
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,
|
|
60
80
|
)
|
|
61
81
|
from rasa.shared.core.constants import ACTION_RESET_ROUTING, ACTION_TRIGGER_CHITCHAT
|
|
62
82
|
from rasa.shared.core.domain import Domain
|
|
@@ -65,11 +85,6 @@ from rasa.shared.core.slots import Slot
|
|
|
65
85
|
from rasa.shared.exceptions import RasaException
|
|
66
86
|
from rasa.shared.nlu.training_data.message import Message
|
|
67
87
|
|
|
68
|
-
from rasa.dialogue_understanding.coexistence.intent_based_router import (
|
|
69
|
-
IntentBasedRouter,
|
|
70
|
-
)
|
|
71
|
-
from rasa.dialogue_understanding.coexistence.llm_based_router import LLMBasedRouter
|
|
72
|
-
|
|
73
88
|
TypeAnnotation = Union[TypeVar, Text, Type, Optional[AvailableEndpoints]]
|
|
74
89
|
|
|
75
90
|
structlogger = structlog.get_logger()
|
|
@@ -855,96 +870,534 @@ def validate_coexistance_routing_setup(
|
|
|
855
870
|
)
|
|
856
871
|
|
|
857
872
|
|
|
858
|
-
def
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
873
|
+
def _validate_component_model_client_config(
|
|
874
|
+
component_config: Dict[str, Any],
|
|
875
|
+
key: str,
|
|
876
|
+
model_group_syntax_used: List[bool],
|
|
877
|
+
model_group_ids: List[str],
|
|
878
|
+
component_name: Optional[str] = None,
|
|
879
|
+
) -> None:
|
|
880
|
+
"""Validate the LLM configuration of a component.
|
|
863
881
|
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
)
|
|
882
|
+
Checks if the llm is defined using the new syntax or the old syntax.
|
|
883
|
+
If the new syntax is used, it checks that no other parameters are present.
|
|
867
884
|
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
885
|
+
Args:
|
|
886
|
+
component_config: The config of the component
|
|
887
|
+
key: either 'llm' or 'embeddings'
|
|
888
|
+
model_group_syntax_used:
|
|
889
|
+
list of booleans indicating whether the new syntax is used
|
|
890
|
+
model_group_ids: list of model group ids
|
|
891
|
+
component_name: the name of the component
|
|
892
|
+
"""
|
|
893
|
+
if key not in component_config:
|
|
894
|
+
# no llm configuration present
|
|
895
|
+
return
|
|
877
896
|
|
|
897
|
+
if MODEL_GROUP_CONFIG_KEY in component_config[key]:
|
|
898
|
+
model_group_syntax_used.append(True)
|
|
899
|
+
model_group_ids.append(component_config[key][MODEL_GROUP_CONFIG_KEY])
|
|
878
900
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
901
|
+
if len(component_config[key]) > 1:
|
|
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,
|
|
914
|
+
)
|
|
915
|
+
sys.exit(1)
|
|
916
|
+
else:
|
|
917
|
+
model_group_syntax_used.append(False)
|
|
918
|
+
|
|
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)
|
|
884
936
|
|
|
885
937
|
|
|
886
|
-
def
|
|
938
|
+
def validate_model_client_configuration_setup_during_training_time(
|
|
939
|
+
config: Dict[str, Any],
|
|
940
|
+
) -> None:
|
|
887
941
|
"""Validates the model client configuration setup.
|
|
888
942
|
|
|
943
|
+
Checks the model configuration of the components in the pipeline.
|
|
889
944
|
Validation fails, if
|
|
890
|
-
- the LLM/embeddings
|
|
891
|
-
|
|
945
|
+
- the LLM/embeddings is/are defined using the old and the new syntax at
|
|
946
|
+
the same time (either at component level itself or across different components)
|
|
947
|
+
- the LLM/embeddings is/are defined using the new syntax, but no model
|
|
948
|
+
group is defined or the referenced model group does not exist
|
|
892
949
|
|
|
893
950
|
Args:
|
|
894
951
|
config: The config dictionary
|
|
895
952
|
"""
|
|
953
|
+
|
|
954
|
+
def is_uniform_bool_list(bool_list: List[bool]) -> bool:
|
|
955
|
+
# check if list contains only True or False
|
|
956
|
+
return all(bool_list) or not any(bool_list)
|
|
957
|
+
|
|
958
|
+
model_group_syntax_used: List[bool] = []
|
|
959
|
+
model_group_ids: List[str] = []
|
|
960
|
+
|
|
896
961
|
for outer_key in ["pipeline", "policies"]:
|
|
897
962
|
if outer_key not in config or config[outer_key] is None:
|
|
898
963
|
continue
|
|
899
964
|
|
|
900
|
-
for
|
|
965
|
+
for component in config[outer_key]:
|
|
901
966
|
for key in [LLM_CONFIG_KEY, EMBEDDINGS_CONFIG_KEY]:
|
|
902
|
-
|
|
967
|
+
_validate_component_model_client_config(
|
|
968
|
+
component, key, model_group_syntax_used, model_group_ids
|
|
969
|
+
)
|
|
903
970
|
|
|
904
971
|
# as flow retrieval is not a component itself, we need to
|
|
905
972
|
# check it separately
|
|
906
|
-
if
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
973
|
+
if FLOW_RETRIEVAL_KEY in component:
|
|
974
|
+
if EMBEDDINGS_CONFIG_KEY in component[FLOW_RETRIEVAL_KEY]:
|
|
975
|
+
_validate_component_model_client_config(
|
|
976
|
+
component[FLOW_RETRIEVAL_KEY],
|
|
977
|
+
EMBEDDINGS_CONFIG_KEY,
|
|
978
|
+
model_group_syntax_used,
|
|
979
|
+
model_group_ids,
|
|
980
|
+
component["name"] + "." + FLOW_RETRIEVAL_KEY,
|
|
981
|
+
)
|
|
982
|
+
|
|
983
|
+
# also include the ContextualResponseRephraser component
|
|
984
|
+
endpoints = AvailableEndpoints.get_instance()
|
|
985
|
+
if endpoints.nlg is not None:
|
|
986
|
+
_validate_component_model_client_config(
|
|
987
|
+
endpoints.nlg.kwargs,
|
|
988
|
+
LLM_CONFIG_KEY,
|
|
989
|
+
model_group_syntax_used,
|
|
990
|
+
model_group_ids,
|
|
991
|
+
ContextualResponseRephraser.__name__,
|
|
992
|
+
)
|
|
915
993
|
|
|
994
|
+
if not is_uniform_bool_list(model_group_syntax_used):
|
|
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
|
+
),
|
|
1006
|
+
)
|
|
1007
|
+
sys.exit(1)
|
|
916
1008
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1009
|
+
# Print a deprecation warning in case the old syntax is used.
|
|
1010
|
+
if len(model_group_syntax_used) > 0 and model_group_syntax_used[0] is False:
|
|
1011
|
+
structlogger.warning(
|
|
1012
|
+
"validate_llm_configuration_setup",
|
|
1013
|
+
event_info=(
|
|
1014
|
+
"Defining the LLM configuration in the config.yml file itself is"
|
|
1015
|
+
" deprecated and will be removed in Rasa 4.0.0. "
|
|
1016
|
+
"Please use the new syntax and define your LLM configuration"
|
|
1017
|
+
"in the endpoints.yml file."
|
|
1018
|
+
),
|
|
1019
|
+
)
|
|
1020
|
+
|
|
1021
|
+
endpoints = AvailableEndpoints.get_instance()
|
|
1022
|
+
if len(model_group_ids) > 0 and endpoints.model_groups is None:
|
|
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
|
+
),
|
|
1032
|
+
)
|
|
1033
|
+
sys.exit(1)
|
|
1034
|
+
|
|
1035
|
+
if endpoints.model_groups is None:
|
|
1036
|
+
return
|
|
1037
|
+
|
|
1038
|
+
existing_model_group_ids = [
|
|
1039
|
+
model_group[MODEL_GROUP_ID_CONFIG_KEY] for model_group in endpoints.model_groups
|
|
1040
|
+
]
|
|
1041
|
+
|
|
1042
|
+
for model_group_id in model_group_ids:
|
|
1043
|
+
if model_group_id not in existing_model_group_ids:
|
|
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,
|
|
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,
|
|
921
1064
|
) -> None:
|
|
922
|
-
"""
|
|
1065
|
+
"""Validates that the specified client configuration references a valid model group
|
|
1066
|
+
defined in the `endpoints.yml` file.
|
|
923
1067
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
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.
|
|
927
1071
|
|
|
928
1072
|
Args:
|
|
929
|
-
component_config: The
|
|
930
|
-
|
|
931
|
-
|
|
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.
|
|
932
1081
|
"""
|
|
933
|
-
if
|
|
1082
|
+
if key not in component_config:
|
|
1083
|
+
# no llm/embeddings configuration present
|
|
934
1084
|
return
|
|
935
1085
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
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
|
+
)
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
def _validate_unique_model_group_ids(model_groups: List[Dict[str, Any]]) -> None:
|
|
1173
|
+
# Each model id must be unique within the model_groups
|
|
1174
|
+
model_ids = [model_group[MODEL_GROUP_ID_CONFIG_KEY] for model_group in model_groups]
|
|
1175
|
+
if len(model_ids) != len(set(model_ids)):
|
|
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
|
+
),
|
|
1182
|
+
)
|
|
1183
|
+
sys.exit(1)
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
def _validate_model_group_with_multiple_models(
|
|
1187
|
+
model_groups: List[Dict[str, Any]],
|
|
1188
|
+
) -> None:
|
|
1189
|
+
# You cannot define multiple models within a model group, when no router is defined.
|
|
1190
|
+
for model_group in model_groups:
|
|
1191
|
+
if (
|
|
1192
|
+
len(model_group[MODELS_CONFIG_KEY]) > 1
|
|
1193
|
+
and ROUTER_CONFIG_KEY not in model_group
|
|
1194
|
+
):
|
|
939
1195
|
structlogger.error(
|
|
940
|
-
"
|
|
1196
|
+
"validate_model_group_configuration_setup.router_not_present",
|
|
941
1197
|
event_info=(
|
|
942
|
-
f"You
|
|
943
|
-
f"'{
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
f"
|
|
947
|
-
f"For other providers, please use the '{PROVIDER_CONFIG_KEY}' key."
|
|
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]}'."
|
|
948
1203
|
),
|
|
1204
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
949
1205
|
)
|
|
950
1206
|
sys.exit(1)
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
def _validate_model_group_router_setting(
|
|
1210
|
+
model_groups: List[Dict[str, Any]],
|
|
1211
|
+
) -> None:
|
|
1212
|
+
# You cannot define multiple models within a model group, when no router is defined.
|
|
1213
|
+
for model_group in model_groups:
|
|
1214
|
+
if ROUTER_CONFIG_KEY not in model_group:
|
|
1215
|
+
continue
|
|
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
|
+
|
|
1235
|
+
router_config = model_group[ROUTER_CONFIG_KEY]
|
|
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
|
+
),
|
|
1260
|
+
)
|
|
1261
|
+
sys.exit(1)
|
|
1262
|
+
if (
|
|
1263
|
+
routing_strategy in ROUTING_STRATEGIES_REQUIRING_REDIS_CACHE
|
|
1264
|
+
and REDIS_HOST_CONFIG_KEY not in router_config
|
|
1265
|
+
):
|
|
1266
|
+
structlogger.warning(
|
|
1267
|
+
"validation.routing_strategy.redis_host_not_defined",
|
|
1268
|
+
event_info=(
|
|
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]}'."
|
|
1274
|
+
),
|
|
1275
|
+
model_group_id=model_group[MODEL_GROUP_ID_CONFIG_KEY],
|
|
1276
|
+
)
|
|
1277
|
+
|
|
1278
|
+
|
|
1279
|
+
def _validate_usage_of_environment_variables_in_model_group_config(
|
|
1280
|
+
model_groups: List[Dict[str, Any]],
|
|
1281
|
+
) -> None:
|
|
1282
|
+
# Limit the use of ${env_var} in the model_groups config to the following variables:
|
|
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
|
|
1286
|
+
allowed_env_vars = {
|
|
1287
|
+
DEPLOYMENT_CONFIG_KEY,
|
|
1288
|
+
API_BASE_CONFIG_KEY,
|
|
1289
|
+
API_KEY,
|
|
1290
|
+
API_VERSION_CONFIG_KEY,
|
|
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,
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
for model_group in model_groups:
|
|
1298
|
+
for model_config in model_group[MODELS_CONFIG_KEY]:
|
|
1299
|
+
for key, value in model_config.items():
|
|
1300
|
+
if isinstance(value, str):
|
|
1301
|
+
if re.match(r"\${(\w+)}", value) and key not in allowed_env_vars:
|
|
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,
|
|
1316
|
+
)
|
|
1317
|
+
sys.exit(1)
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
def _validate_sensitive_keys_are_an_environment_variables_for_model_groups(
|
|
1321
|
+
model_groups: List[Dict[str, Any]],
|
|
1322
|
+
) -> None:
|
|
1323
|
+
# the api key can only be set as an environment variable
|
|
1324
|
+
for model_group in model_groups:
|
|
1325
|
+
for model_config in model_group[MODELS_CONFIG_KEY]:
|
|
1326
|
+
for key, value in model_config.items():
|
|
1327
|
+
if key in SENSITIVE_DATA:
|
|
1328
|
+
if isinstance(value, str):
|
|
1329
|
+
if not re.match(r"\${(\w+)}", value):
|
|
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],
|
|
1341
|
+
)
|
|
1342
|
+
sys.exit(1)
|
|
1343
|
+
else:
|
|
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],
|
|
1356
|
+
)
|
|
1357
|
+
sys.exit(1)
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
def validate_model_group_configuration_setup() -> None:
|
|
1361
|
+
"""Validates the model group configuration setup in endpoints.yml."""
|
|
1362
|
+
endpoints = AvailableEndpoints.get_instance()
|
|
1363
|
+
|
|
1364
|
+
if endpoints.model_groups is None:
|
|
1365
|
+
return
|
|
1366
|
+
|
|
1367
|
+
_validate_unique_model_group_ids(endpoints.model_groups)
|
|
1368
|
+
_validate_model_group_with_multiple_models(endpoints.model_groups)
|
|
1369
|
+
_validate_usage_of_environment_variables_in_model_group_config(
|
|
1370
|
+
endpoints.model_groups
|
|
1371
|
+
)
|
|
1372
|
+
_validate_sensitive_keys_are_an_environment_variables_for_model_groups(
|
|
1373
|
+
endpoints.model_groups
|
|
1374
|
+
)
|
|
1375
|
+
_validate_model_group_router_setting(endpoints.model_groups)
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
def validate_command_generator_exclusivity(schema: GraphSchema) -> None:
|
|
1379
|
+
"""Validate that multiple command generators are not defined at same time."""
|
|
1380
|
+
from rasa.dialogue_understanding.generator import (
|
|
1381
|
+
LLMBasedCommandGenerator,
|
|
1382
|
+
)
|
|
1383
|
+
|
|
1384
|
+
count = schema.count_nodes_of_a_given_type(
|
|
1385
|
+
LLMBasedCommandGenerator, include_subtypes=True
|
|
1386
|
+
)
|
|
1387
|
+
|
|
1388
|
+
if count > 1:
|
|
1389
|
+
structlogger.error(
|
|
1390
|
+
"validation.command_generator.multiple_command_generator_defined",
|
|
1391
|
+
event_info=(
|
|
1392
|
+
"Multiple LLM based command generators are defined in the config. "
|
|
1393
|
+
"Please use only one LLM based command generator."
|
|
1394
|
+
),
|
|
1395
|
+
)
|
|
1396
|
+
sys.exit(1)
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
def validate_command_generator_setup(
|
|
1400
|
+
model_configuration: GraphModelConfiguration,
|
|
1401
|
+
) -> None:
|
|
1402
|
+
schema = model_configuration.predict_schema
|
|
1403
|
+
validate_command_generator_exclusivity(schema)
|