rasa-pro 3.10.7.dev4__py3-none-any.whl → 3.10.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rasa-pro might be problematic. Click here for more details.
- README.md +37 -1
- rasa/api.py +2 -8
- rasa/cli/arguments/default_arguments.py +2 -23
- rasa/cli/arguments/run.py +0 -2
- rasa/cli/e2e_test.py +8 -10
- rasa/cli/inspect.py +2 -5
- rasa/cli/run.py +0 -7
- rasa/cli/studio/studio.py +21 -1
- rasa/cli/train.py +4 -9
- rasa/cli/utils.py +3 -3
- rasa/core/agent.py +2 -2
- rasa/core/brokers/kafka.py +1 -3
- rasa/core/brokers/pika.py +1 -3
- rasa/core/channels/socketio.py +1 -5
- rasa/core/channels/voice_aware/utils.py +5 -6
- rasa/core/nlg/contextual_response_rephraser.py +2 -11
- rasa/core/policies/enterprise_search_policy.py +2 -11
- rasa/core/policies/intentless_policy.py +2 -9
- rasa/core/run.py +1 -2
- rasa/core/secrets_manager/constants.py +0 -4
- rasa/core/secrets_manager/factory.py +0 -8
- rasa/core/secrets_manager/vault.py +1 -11
- rasa/core/utils.py +19 -30
- rasa/dialogue_understanding/coexistence/llm_based_router.py +2 -9
- rasa/dialogue_understanding/commands/__init__.py +2 -0
- rasa/dialogue_understanding/commands/restart_command.py +58 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +5 -1
- rasa/dialogue_understanding/commands/utils.py +3 -1
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +2 -11
- rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +15 -15
- rasa/dialogue_understanding/patterns/restart.py +37 -0
- rasa/e2e_test/e2e_test_runner.py +1 -1
- rasa/engine/graph.py +1 -0
- rasa/engine/recipes/config_files/default_config.yml +3 -0
- rasa/engine/recipes/default_recipe.py +1 -0
- rasa/engine/recipes/graph_recipe.py +1 -0
- rasa/engine/storage/local_model_storage.py +1 -0
- rasa/engine/storage/storage.py +5 -1
- rasa/model_training.py +6 -11
- rasa/{core → nlu}/persistor.py +1 -1
- rasa/server.py +1 -1
- rasa/shared/constants.py +3 -2
- rasa/shared/core/domain.py +47 -101
- rasa/shared/core/flows/flows_list.py +6 -19
- rasa/shared/core/flows/validation.py +0 -25
- rasa/shared/core/flows/yaml_flows_io.py +24 -3
- rasa/shared/importers/importer.py +32 -32
- rasa/shared/importers/multi_project.py +11 -23
- rasa/shared/importers/rasa.py +2 -7
- rasa/shared/importers/remote_importer.py +2 -2
- rasa/shared/importers/utils.py +1 -3
- rasa/shared/nlu/training_data/training_data.py +19 -18
- rasa/shared/providers/_configs/azure_openai_client_config.py +5 -3
- rasa/shared/providers/llm/_base_litellm_client.py +26 -10
- rasa/shared/providers/llm/self_hosted_llm_client.py +15 -3
- rasa/shared/utils/common.py +22 -3
- rasa/shared/utils/llm.py +5 -29
- rasa/shared/utils/schemas/model_config.yml +10 -0
- rasa/studio/auth.py +4 -0
- rasa/tracing/instrumentation/attribute_extractors.py +1 -1
- rasa/validator.py +5 -2
- rasa/version.py +1 -1
- {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/METADATA +43 -7
- {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/RECORD +68 -74
- rasa/model_manager/__init__.py +0 -0
- rasa/model_manager/config.py +0 -12
- rasa/model_manager/model_api.py +0 -464
- rasa/model_manager/runner_service.py +0 -185
- rasa/model_manager/socket_bridge.py +0 -44
- rasa/model_manager/trainer_service.py +0 -240
- rasa/model_manager/utils.py +0 -27
- rasa/model_service.py +0 -66
- {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/NOTICE +0 -0
- {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/WHEEL +0 -0
- {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/entry_points.txt +0 -0
|
@@ -15,7 +15,6 @@ from rasa.utils.endpoints import EndpointConfig
|
|
|
15
15
|
from rasa.core.secrets_manager.constants import (
|
|
16
16
|
TRACKER_STORE_ENDPOINT_TYPE,
|
|
17
17
|
TRANSIT_KEY_FOR_ENCRYPTION_LABEL,
|
|
18
|
-
VAULT_MOUNT_POINT_DEFAULT_VALUE,
|
|
19
18
|
VAULT_SECRET_MANAGER_NAME,
|
|
20
19
|
)
|
|
21
20
|
from rasa.core.secrets_manager.endpoints import (
|
|
@@ -182,7 +181,6 @@ class VaultSecretsManager(SecretsManager):
|
|
|
182
181
|
secrets_path: Text,
|
|
183
182
|
transit_mount_point: Optional[Text] = None,
|
|
184
183
|
namespace: Optional[Text] = None,
|
|
185
|
-
mount_point: Optional[Text] = None,
|
|
186
184
|
):
|
|
187
185
|
"""Initialise the VaultSecretsManager.
|
|
188
186
|
|
|
@@ -192,13 +190,11 @@ class VaultSecretsManager(SecretsManager):
|
|
|
192
190
|
secrets_path: The path to the secrets in the vault server.
|
|
193
191
|
transit_mount_point: The mount point of the transit engine.
|
|
194
192
|
namespace: The namespace in which secrets reside in.
|
|
195
|
-
mount_point: The mount point of the kv engine.
|
|
196
193
|
"""
|
|
197
194
|
self.host = host
|
|
198
195
|
self.transit_mount_point = transit_mount_point
|
|
199
196
|
self.token = token
|
|
200
197
|
self.secrets_path = secrets_path
|
|
201
|
-
self.mount_point = mount_point or VAULT_MOUNT_POINT_DEFAULT_VALUE
|
|
202
198
|
self.namespace = namespace
|
|
203
199
|
|
|
204
200
|
# Create client
|
|
@@ -240,7 +236,7 @@ class VaultSecretsManager(SecretsManager):
|
|
|
240
236
|
"""
|
|
241
237
|
logger.info(f"Loading secrets from vault server at {self.host}.")
|
|
242
238
|
read_response = self.client.secrets.kv.read_secret_version(
|
|
243
|
-
mount_point=
|
|
239
|
+
mount_point="secret", path=self.secrets_path
|
|
244
240
|
)
|
|
245
241
|
|
|
246
242
|
secrets = read_response["data"]["data"]
|
|
@@ -459,7 +455,6 @@ class VaultSecretManagerConfig(SecretManagerConfig):
|
|
|
459
455
|
secrets_path: Text,
|
|
460
456
|
transit_mount_point: Text = "transit",
|
|
461
457
|
namespace: Optional[Text] = None,
|
|
462
|
-
mount_point: Optional[Text] = None,
|
|
463
458
|
) -> None:
|
|
464
459
|
"""Initialise the VaultSecretManagerConfig.
|
|
465
460
|
|
|
@@ -476,7 +471,6 @@ class VaultSecretManagerConfig(SecretManagerConfig):
|
|
|
476
471
|
self.secrets_path = secrets_path
|
|
477
472
|
self.transit_mount_point = transit_mount_point
|
|
478
473
|
self.namespace = namespace
|
|
479
|
-
self.mount_point = mount_point
|
|
480
474
|
|
|
481
475
|
|
|
482
476
|
@dataclass
|
|
@@ -492,7 +486,6 @@ class VaultSecretManagerNonStrictConfig:
|
|
|
492
486
|
secrets_path: Optional[Text]
|
|
493
487
|
transit_mount_point: Optional[Text]
|
|
494
488
|
namespace: Optional[Text] = None
|
|
495
|
-
mount_point: Optional[Text] = None
|
|
496
489
|
|
|
497
490
|
def is_empty(self) -> bool:
|
|
498
491
|
"""Check if all the values are empty."""
|
|
@@ -502,7 +495,6 @@ class VaultSecretManagerNonStrictConfig:
|
|
|
502
495
|
and (self.secrets_path is None or self.secrets_path == "")
|
|
503
496
|
and (self.transit_mount_point is None or self.transit_mount_point == "")
|
|
504
497
|
and (self.namespace is None or self.namespace == "")
|
|
505
|
-
and (self.mount_point is None or self.mount_point == "")
|
|
506
498
|
)
|
|
507
499
|
|
|
508
500
|
def is_valid(self) -> bool:
|
|
@@ -524,7 +516,6 @@ class VaultSecretManagerNonStrictConfig:
|
|
|
524
516
|
and self.secrets_path != ""
|
|
525
517
|
and self._is_optional_value_valid(self.transit_mount_point)
|
|
526
518
|
and self._is_optional_value_valid(self.namespace)
|
|
527
|
-
and self._is_optional_value_valid(self.mount_point)
|
|
528
519
|
)
|
|
529
520
|
|
|
530
521
|
@staticmethod
|
|
@@ -556,7 +547,6 @@ class VaultSecretManagerNonStrictConfig:
|
|
|
556
547
|
secrets_path=self.secrets_path or other.secrets_path,
|
|
557
548
|
transit_mount_point=self.transit_mount_point or other.transit_mount_point,
|
|
558
549
|
namespace=self.namespace or other.namespace,
|
|
559
|
-
mount_point=self.mount_point or other.mount_point,
|
|
560
550
|
)
|
|
561
551
|
|
|
562
552
|
|
rasa/core/utils.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import structlog
|
|
2
1
|
import logging
|
|
3
2
|
import os
|
|
4
3
|
from pathlib import Path
|
|
@@ -27,7 +26,7 @@ if TYPE_CHECKING:
|
|
|
27
26
|
from rasa.core.nlg import NaturalLanguageGenerator
|
|
28
27
|
from rasa.shared.core.domain import Domain
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
def configure_file_logging(
|
|
@@ -125,17 +124,15 @@ def list_routes(app: Sanic) -> Dict[Text, Text]:
|
|
|
125
124
|
for arg in route._params:
|
|
126
125
|
options[arg] = f"[{arg}]"
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
methods = ",".join(route.methods)
|
|
127
|
+
handlers = [(next(iter(route.methods)), route.name.replace("rasa_server.", ""))]
|
|
130
128
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
for method, name in handlers:
|
|
130
|
+
full_endpoint = "/" + "/".join(endpoint)
|
|
131
|
+
line = unquote(f"{full_endpoint:50s} {method:30s} {name}")
|
|
132
|
+
output[name] = line
|
|
134
133
|
|
|
135
134
|
url_table = "\n".join(output[url] for url in sorted(output))
|
|
136
|
-
|
|
137
|
-
"server.routes", event_info=f"Available web server routes: \n{url_table}"
|
|
138
|
-
)
|
|
135
|
+
logger.debug(f"Available web server routes: \n{url_table}")
|
|
139
136
|
|
|
140
137
|
return output
|
|
141
138
|
|
|
@@ -266,22 +263,17 @@ def number_of_sanic_workers(lock_store: Union[EndpointConfig, LockStore, None])
|
|
|
266
263
|
"""
|
|
267
264
|
|
|
268
265
|
def _log_and_get_default_number_of_workers() -> int:
|
|
269
|
-
|
|
270
|
-
"
|
|
271
|
-
number_of_workers=DEFAULT_SANIC_WORKERS,
|
|
272
|
-
event_info=f"Using the default number of Sanic workers "
|
|
273
|
-
f"({DEFAULT_SANIC_WORKERS}).",
|
|
266
|
+
logger.debug(
|
|
267
|
+
f"Using the default number of Sanic workers ({DEFAULT_SANIC_WORKERS})."
|
|
274
268
|
)
|
|
275
269
|
return DEFAULT_SANIC_WORKERS
|
|
276
270
|
|
|
277
271
|
try:
|
|
278
272
|
env_value = int(os.environ.get(ENV_SANIC_WORKERS, DEFAULT_SANIC_WORKERS))
|
|
279
273
|
except ValueError:
|
|
280
|
-
|
|
281
|
-
"
|
|
282
|
-
|
|
283
|
-
event_info=f"Cannot convert environment variable `{ENV_SANIC_WORKERS}` "
|
|
284
|
-
f"to int ('{os.environ[ENV_SANIC_WORKERS]}').",
|
|
274
|
+
logger.error(
|
|
275
|
+
f"Cannot convert environment variable `{ENV_SANIC_WORKERS}` "
|
|
276
|
+
f"to int ('{os.environ[ENV_SANIC_WORKERS]}')."
|
|
285
277
|
)
|
|
286
278
|
return _log_and_get_default_number_of_workers()
|
|
287
279
|
|
|
@@ -289,23 +281,20 @@ def number_of_sanic_workers(lock_store: Union[EndpointConfig, LockStore, None])
|
|
|
289
281
|
return _log_and_get_default_number_of_workers()
|
|
290
282
|
|
|
291
283
|
if env_value < 1:
|
|
292
|
-
|
|
293
|
-
"
|
|
294
|
-
|
|
295
|
-
event_info=f"Cannot set number of Sanic workers to the desired value "
|
|
296
|
-
f"({env_value}). The number of workers must be at least 1.",
|
|
284
|
+
logger.debug(
|
|
285
|
+
f"Cannot set number of Sanic workers to the desired value "
|
|
286
|
+
f"({env_value}). The number of workers must be at least 1."
|
|
297
287
|
)
|
|
298
288
|
return _log_and_get_default_number_of_workers()
|
|
299
289
|
|
|
300
290
|
if _lock_store_is_multi_worker_compatible(lock_store):
|
|
301
|
-
|
|
291
|
+
logger.debug(f"Using {env_value} Sanic workers.")
|
|
302
292
|
return env_value
|
|
303
293
|
|
|
304
|
-
|
|
305
|
-
"
|
|
306
|
-
event_info=f"Unable to assign desired number of Sanic workers ({env_value}) as "
|
|
294
|
+
logger.debug(
|
|
295
|
+
f"Unable to assign desired number of Sanic workers ({env_value}) as "
|
|
307
296
|
f"no `RedisLockStore` or custom `LockStore` endpoint "
|
|
308
|
-
f"configuration has been found."
|
|
297
|
+
f"configuration has been found."
|
|
309
298
|
)
|
|
310
299
|
return _log_and_get_default_number_of_workers()
|
|
311
300
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
|
-
import os
|
|
5
4
|
from typing import Any, Dict, List, Optional
|
|
6
5
|
|
|
7
6
|
import structlog
|
|
@@ -22,7 +21,6 @@ from rasa.engine.recipes.default_recipe import DefaultV1Recipe
|
|
|
22
21
|
from rasa.engine.storage.resource import Resource
|
|
23
22
|
from rasa.engine.storage.storage import ModelStorage
|
|
24
23
|
from rasa.shared.constants import (
|
|
25
|
-
LLM_API_HEALTH_CHECK_ENV_VAR,
|
|
26
24
|
ROUTE_TO_CALM_SLOT,
|
|
27
25
|
PROMPT_CONFIG_KEY,
|
|
28
26
|
PROVIDER_CONFIG_KEY,
|
|
@@ -38,7 +36,6 @@ from rasa.shared.nlu.training_data.training_data import TrainingData
|
|
|
38
36
|
from rasa.shared.utils.llm import (
|
|
39
37
|
DEFAULT_OPENAI_CHAT_MODEL_NAME,
|
|
40
38
|
get_prompt_template,
|
|
41
|
-
llm_api_health_check,
|
|
42
39
|
llm_factory,
|
|
43
40
|
try_instantiate_llm_client,
|
|
44
41
|
)
|
|
@@ -133,16 +130,12 @@ class LLMBasedRouter(GraphComponent):
|
|
|
133
130
|
def train(self, training_data: TrainingData) -> Resource:
|
|
134
131
|
"""Train the intent classifier on a data set."""
|
|
135
132
|
# Validate llm configuration
|
|
136
|
-
|
|
133
|
+
try_instantiate_llm_client(
|
|
137
134
|
self.config.get(LLM_CONFIG_KEY),
|
|
138
135
|
DEFAULT_LLM_CONFIG,
|
|
139
136
|
"llm_based_router.train",
|
|
140
|
-
LLMBasedRouter
|
|
137
|
+
"LLMBasedRouter",
|
|
141
138
|
)
|
|
142
|
-
if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
|
|
143
|
-
llm_api_health_check(
|
|
144
|
-
llm_client, "llm_based_router.train", LLMBasedRouter.__name__
|
|
145
|
-
)
|
|
146
139
|
|
|
147
140
|
self.persist()
|
|
148
141
|
return self._resource
|
|
@@ -9,6 +9,7 @@ from rasa.dialogue_understanding.commands.knowledge_answer_command import (
|
|
|
9
9
|
from rasa.dialogue_understanding.commands.chit_chat_answer_command import (
|
|
10
10
|
ChitChatAnswerCommand,
|
|
11
11
|
)
|
|
12
|
+
from rasa.dialogue_understanding.commands.restart_command import RestartCommand
|
|
12
13
|
from rasa.dialogue_understanding.commands.skip_question_command import (
|
|
13
14
|
SkipQuestionCommand,
|
|
14
15
|
)
|
|
@@ -50,4 +51,5 @@ __all__ = [
|
|
|
50
51
|
"NoopCommand",
|
|
51
52
|
"ChangeFlowCommand",
|
|
52
53
|
"SessionStartCommand",
|
|
54
|
+
"RestartCommand",
|
|
53
55
|
]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Dict, List
|
|
5
|
+
|
|
6
|
+
from rasa.dialogue_understanding.commands import Command
|
|
7
|
+
from rasa.dialogue_understanding.patterns.restart import RestartPatternFlowStackFrame
|
|
8
|
+
from rasa.shared.core.events import Event
|
|
9
|
+
from rasa.shared.core.flows import FlowsList
|
|
10
|
+
from rasa.shared.core.trackers import DialogueStateTracker
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class RestartCommand(Command):
|
|
15
|
+
"""A command to restart a session."""
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def command(cls) -> str:
|
|
19
|
+
"""Returns the command type."""
|
|
20
|
+
return "restart"
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def from_dict(cls, data: Dict[str, Any]) -> RestartCommand:
|
|
24
|
+
"""Converts the dictionary to a command.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
The converted dictionary.
|
|
28
|
+
"""
|
|
29
|
+
return RestartCommand()
|
|
30
|
+
|
|
31
|
+
def run_command_on_tracker(
|
|
32
|
+
self,
|
|
33
|
+
tracker: DialogueStateTracker,
|
|
34
|
+
all_flows: FlowsList,
|
|
35
|
+
original_tracker: DialogueStateTracker,
|
|
36
|
+
) -> List[Event]:
|
|
37
|
+
"""Runs the command on the tracker.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
tracker: The tracker to run the command on.
|
|
41
|
+
all_flows: All flows in the assistant.
|
|
42
|
+
original_tracker: The tracker before any command was executed.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
The events to apply to the tracker.
|
|
46
|
+
"""
|
|
47
|
+
stack = tracker.stack
|
|
48
|
+
stack.push(RestartPatternFlowStackFrame())
|
|
49
|
+
return tracker.create_stack_updated_events(stack)
|
|
50
|
+
|
|
51
|
+
def __hash__(self) -> int:
|
|
52
|
+
return hash(self.command())
|
|
53
|
+
|
|
54
|
+
def __eq__(self, other: object) -> bool:
|
|
55
|
+
if not isinstance(other, RestartCommand):
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
return True
|
|
@@ -127,7 +127,11 @@ class SetSlotCommand(Command):
|
|
|
127
127
|
if (
|
|
128
128
|
self.name not in slots_of_active_flow
|
|
129
129
|
and self.name != ROUTE_TO_CALM_SLOT
|
|
130
|
-
and self.extractor
|
|
130
|
+
and self.extractor
|
|
131
|
+
in {
|
|
132
|
+
SetSlotExtractor.LLM.value,
|
|
133
|
+
SetSlotExtractor.COMMAND_PAYLOAD_READER.value,
|
|
134
|
+
}
|
|
131
135
|
):
|
|
132
136
|
# Get the other predicted flows from the most recent message on the tracker.
|
|
133
137
|
predicted_flows = get_flows_predicted_to_start_from_tracker(tracker)
|
|
@@ -9,6 +9,7 @@ from rasa.dialogue_understanding.commands import (
|
|
|
9
9
|
KnowledgeAnswerCommand,
|
|
10
10
|
SessionStartCommand,
|
|
11
11
|
SkipQuestionCommand,
|
|
12
|
+
RestartCommand,
|
|
12
13
|
)
|
|
13
14
|
from rasa.dialogue_understanding.patterns.cancel import CancelPatternFlowStackFrame
|
|
14
15
|
from rasa.dialogue_understanding.patterns.cannot_handle import (
|
|
@@ -18,6 +19,7 @@ from rasa.dialogue_understanding.patterns.chitchat import ChitchatPatternFlowSta
|
|
|
18
19
|
from rasa.dialogue_understanding.patterns.human_handoff import (
|
|
19
20
|
HumanHandoffPatternFlowStackFrame,
|
|
20
21
|
)
|
|
22
|
+
from rasa.dialogue_understanding.patterns.restart import RestartPatternFlowStackFrame
|
|
21
23
|
from rasa.dialogue_understanding.patterns.search import SearchPatternFlowStackFrame
|
|
22
24
|
from rasa.dialogue_understanding.patterns.session_start import (
|
|
23
25
|
SessionStartPatternFlowStackFrame,
|
|
@@ -26,7 +28,6 @@ from rasa.dialogue_understanding.patterns.skip_question import (
|
|
|
26
28
|
SkipQuestionPatternFlowStackFrame,
|
|
27
29
|
)
|
|
28
30
|
|
|
29
|
-
|
|
30
31
|
triggerable_pattern_to_command_class: Dict[str, Type[Command]] = {
|
|
31
32
|
SessionStartPatternFlowStackFrame.flow_id: SessionStartCommand,
|
|
32
33
|
CancelPatternFlowStackFrame.flow_id: CancelFlowCommand,
|
|
@@ -35,4 +36,5 @@ triggerable_pattern_to_command_class: Dict[str, Type[Command]] = {
|
|
|
35
36
|
SearchPatternFlowStackFrame.flow_id: KnowledgeAnswerCommand,
|
|
36
37
|
SkipQuestionPatternFlowStackFrame.flow_id: SkipQuestionCommand,
|
|
37
38
|
CannotHandlePatternFlowStackFrame.flow_id: CannotHandleCommand,
|
|
39
|
+
RestartPatternFlowStackFrame.flow_id: RestartCommand,
|
|
38
40
|
}
|
|
@@ -2,7 +2,6 @@ from abc import ABC, abstractmethod
|
|
|
2
2
|
from functools import lru_cache
|
|
3
3
|
from typing import Dict, Any, List, Optional, Tuple, Union, Text
|
|
4
4
|
|
|
5
|
-
import os
|
|
6
5
|
import structlog
|
|
7
6
|
from jinja2 import Template
|
|
8
7
|
|
|
@@ -23,7 +22,6 @@ from rasa.engine.graph import GraphComponent, ExecutionContext
|
|
|
23
22
|
from rasa.engine.recipes.default_recipe import DefaultV1Recipe
|
|
24
23
|
from rasa.engine.storage.resource import Resource
|
|
25
24
|
from rasa.engine.storage.storage import ModelStorage
|
|
26
|
-
from rasa.shared.constants import LLM_API_HEALTH_CHECK_ENV_VAR
|
|
27
25
|
from rasa.shared.core.domain import Domain
|
|
28
26
|
from rasa.shared.core.flows import FlowStep, Flow, FlowsList
|
|
29
27
|
from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
|
|
@@ -35,7 +33,6 @@ from rasa.shared.nlu.training_data.message import Message
|
|
|
35
33
|
from rasa.shared.nlu.training_data.training_data import TrainingData
|
|
36
34
|
from rasa.shared.utils.llm import (
|
|
37
35
|
allowed_values_for_slot,
|
|
38
|
-
llm_api_health_check,
|
|
39
36
|
llm_factory,
|
|
40
37
|
try_instantiate_llm_client,
|
|
41
38
|
)
|
|
@@ -172,18 +169,12 @@ class LLMBasedCommandGenerator(GraphComponent, CommandGenerator, ABC):
|
|
|
172
169
|
store.
|
|
173
170
|
"""
|
|
174
171
|
# Validate llm configuration
|
|
175
|
-
|
|
172
|
+
try_instantiate_llm_client(
|
|
176
173
|
self.config.get(LLM_CONFIG_KEY),
|
|
177
174
|
DEFAULT_LLM_CONFIG,
|
|
178
175
|
"llm_based_command_generator.train",
|
|
179
|
-
LLMBasedCommandGenerator
|
|
176
|
+
"LLMBasedCommandGenerator",
|
|
180
177
|
)
|
|
181
|
-
if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
|
|
182
|
-
llm_api_health_check(
|
|
183
|
-
llm_client,
|
|
184
|
-
"llm_based_command_generator.train",
|
|
185
|
-
LLMBasedCommandGenerator.__name__,
|
|
186
|
-
)
|
|
187
178
|
|
|
188
179
|
# flow retrieval is populated with only user-defined flows
|
|
189
180
|
try:
|
|
@@ -55,7 +55,7 @@ responses:
|
|
|
55
55
|
template: jinja
|
|
56
56
|
|
|
57
57
|
utter_free_chitchat_response:
|
|
58
|
-
- text:
|
|
58
|
+
- text: "Sorry, I'm not able to answer that right now."
|
|
59
59
|
metadata:
|
|
60
60
|
rephrase: True
|
|
61
61
|
rephrase_prompt: |
|
|
@@ -160,9 +160,9 @@ flows:
|
|
|
160
160
|
action: action_run_slot_rejections
|
|
161
161
|
- action: validate_{{context.collect}}
|
|
162
162
|
next:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
- if: "slots.{{context.collect}} is not null"
|
|
164
|
+
then: END
|
|
165
|
+
- else: ask_collect
|
|
166
166
|
- id: ask_collect
|
|
167
167
|
action: "{{context.utter}}"
|
|
168
168
|
- action: "{{context.collect_action}}"
|
|
@@ -205,17 +205,17 @@ flows:
|
|
|
205
205
|
steps:
|
|
206
206
|
- noop: true
|
|
207
207
|
next:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
208
|
+
- if: "'{{context.error_type}}' = 'rasa_internal_error_user_input_too_long'"
|
|
209
|
+
then:
|
|
210
|
+
- action: utter_user_input_too_long_error_rasa
|
|
211
|
+
next: END
|
|
212
|
+
- if: "'{{context.error_type}}' = 'rasa_internal_error_user_input_empty'"
|
|
213
|
+
then:
|
|
214
|
+
- action: utter_user_input_empty_error_rasa
|
|
215
|
+
next: END
|
|
216
|
+
- else:
|
|
217
|
+
- action: utter_internal_error_rasa
|
|
218
|
+
next: END
|
|
219
219
|
|
|
220
220
|
|
|
221
221
|
pattern_restart:
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Dict
|
|
5
|
+
|
|
6
|
+
from rasa.dialogue_understanding.stack.frames import PatternFlowStackFrame
|
|
7
|
+
from rasa.shared.constants import RASA_DEFAULT_FLOW_PATTERN_PREFIX
|
|
8
|
+
|
|
9
|
+
FLOW_PATTERN_RESTART = RASA_DEFAULT_FLOW_PATTERN_PREFIX + "restart"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class RestartPatternFlowStackFrame(PatternFlowStackFrame):
|
|
14
|
+
"""A flow stack frame that can get added at the beginning of the conversation."""
|
|
15
|
+
|
|
16
|
+
flow_id: str = FLOW_PATTERN_RESTART
|
|
17
|
+
"""The ID of the flow."""
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def type(cls) -> str:
|
|
21
|
+
"""Returns the type of the frame."""
|
|
22
|
+
return FLOW_PATTERN_RESTART
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def from_dict(data: Dict[str, Any]) -> RestartPatternFlowStackFrame:
|
|
26
|
+
"""Creates a `DialogueStackFrame` from a dictionary.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
data: The dictionary to create the `DialogueStackFrame` from.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
The created `DialogueStackFrame`.
|
|
33
|
+
"""
|
|
34
|
+
return RestartPatternFlowStackFrame(
|
|
35
|
+
frame_id=data["frame_id"],
|
|
36
|
+
step_id=data["step_id"],
|
|
37
|
+
)
|
rasa/e2e_test/e2e_test_runner.py
CHANGED
|
@@ -16,7 +16,6 @@ import rasa.shared.utils.io
|
|
|
16
16
|
from rasa.core.channels import CollectingOutputChannel, UserMessage
|
|
17
17
|
from rasa.core.constants import ACTIVE_FLOW_METADATA_KEY, STEP_ID_METADATA_KEY
|
|
18
18
|
from rasa.core.exceptions import AgentNotReady
|
|
19
|
-
from rasa.core.persistor import StorageType
|
|
20
19
|
from rasa.core.utils import AvailableEndpoints
|
|
21
20
|
from rasa.e2e_test.constants import TEST_CASE_NAME, TEST_FILE_NAME
|
|
22
21
|
from rasa.e2e_test.e2e_config import create_llm_judge_config
|
|
@@ -35,6 +34,7 @@ from rasa.e2e_test.e2e_test_result import (
|
|
|
35
34
|
TestResult,
|
|
36
35
|
)
|
|
37
36
|
from rasa.llm_fine_tuning.conversations import Conversation
|
|
37
|
+
from rasa.nlu.persistor import StorageType
|
|
38
38
|
from rasa.shared.constants import RASA_DEFAULT_FLOW_PATTERN_PREFIX
|
|
39
39
|
from rasa.shared.core.events import (
|
|
40
40
|
ActionExecuted,
|
rasa/engine/graph.py
CHANGED
|
@@ -233,6 +233,7 @@ class DefaultV1Recipe(Recipe):
|
|
|
233
233
|
training_type=training_type,
|
|
234
234
|
assistant_id=config.get(ASSISTANT_ID_KEY),
|
|
235
235
|
language=config.get("language"),
|
|
236
|
+
spaces=config.get("spaces"),
|
|
236
237
|
core_target=core_target,
|
|
237
238
|
nlu_target=f"run_{RegexMessageHandler.__name__}",
|
|
238
239
|
)
|
|
@@ -238,6 +238,7 @@ class LocalModelStorage(ModelStorage):
|
|
|
238
238
|
predict_schema=model_configuration.predict_schema,
|
|
239
239
|
training_type=model_configuration.training_type,
|
|
240
240
|
project_fingerprint=rasa.model.project_fingerprint(),
|
|
241
|
+
spaces=model_configuration.spaces,
|
|
241
242
|
language=model_configuration.language,
|
|
242
243
|
core_target=model_configuration.core_target,
|
|
243
244
|
nlu_target=model_configuration.nlu_target,
|
rasa/engine/storage/storage.py
CHANGED
|
@@ -6,7 +6,7 @@ from contextlib import contextmanager
|
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from datetime import datetime
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import Tuple, Union, Text, Generator, Dict, Any, Optional
|
|
9
|
+
from typing import List, Tuple, Union, Text, Generator, Dict, Any, Optional
|
|
10
10
|
from packaging import version
|
|
11
11
|
|
|
12
12
|
from rasa.constants import MINIMUM_COMPATIBLE_VERSION
|
|
@@ -140,6 +140,7 @@ class ModelMetadata:
|
|
|
140
140
|
core_target: Optional[Text]
|
|
141
141
|
nlu_target: Text
|
|
142
142
|
language: Optional[Text]
|
|
143
|
+
spaces: Optional[List[Dict[Text, Any]]] = None
|
|
143
144
|
training_type: TrainingType = TrainingType.BOTH
|
|
144
145
|
|
|
145
146
|
def __post_init__(self) -> None:
|
|
@@ -169,6 +170,7 @@ class ModelMetadata:
|
|
|
169
170
|
"core_target": self.core_target,
|
|
170
171
|
"nlu_target": self.nlu_target,
|
|
171
172
|
"language": self.language,
|
|
173
|
+
"spaces": self.spaces,
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
@classmethod
|
|
@@ -196,4 +198,6 @@ class ModelMetadata:
|
|
|
196
198
|
core_target=serialized["core_target"],
|
|
197
199
|
nlu_target=serialized["nlu_target"],
|
|
198
200
|
language=serialized["language"],
|
|
201
|
+
# optional, since introduced later
|
|
202
|
+
spaces=serialized.get("spaces"),
|
|
199
203
|
)
|
rasa/model_training.py
CHANGED
|
@@ -15,7 +15,6 @@ import rasa.shared.utils.common
|
|
|
15
15
|
import rasa.shared.utils.io
|
|
16
16
|
import rasa.utils.common
|
|
17
17
|
from rasa import telemetry
|
|
18
|
-
from rasa.core.persistor import StorageType
|
|
19
18
|
from rasa.engine.caching import LocalTrainingCache
|
|
20
19
|
from rasa.engine.recipes.recipe import Recipe
|
|
21
20
|
from rasa.engine.runner.dask import DaskGraphRunner
|
|
@@ -23,6 +22,7 @@ from rasa.engine.storage.local_model_storage import LocalModelStorage
|
|
|
23
22
|
from rasa.engine.storage.storage import ModelStorage
|
|
24
23
|
from rasa.engine.training.components import FingerprintStatus
|
|
25
24
|
from rasa.engine.training.graph_trainer import GraphTrainer
|
|
25
|
+
from rasa.nlu.persistor import StorageType
|
|
26
26
|
from rasa.shared.core.domain import Domain
|
|
27
27
|
from rasa.shared.core.events import SlotSet
|
|
28
28
|
from rasa.shared.core.training_data.structures import StoryGraph
|
|
@@ -156,7 +156,6 @@ async def train(
|
|
|
156
156
|
model_to_finetune: Optional[Text] = None,
|
|
157
157
|
finetuning_epoch_fraction: float = 1.0,
|
|
158
158
|
remote_storage: Optional[StorageType] = None,
|
|
159
|
-
file_importer: Optional[TrainingDataImporter] = None,
|
|
160
159
|
) -> TrainingResult:
|
|
161
160
|
"""Trains a Rasa model (Core and NLU).
|
|
162
161
|
|
|
@@ -178,18 +177,14 @@ async def train(
|
|
|
178
177
|
a directory in case the latest trained model should be used.
|
|
179
178
|
finetuning_epoch_fraction: The fraction currently specified training epochs
|
|
180
179
|
in the model configuration which should be used for finetuning.
|
|
181
|
-
remote_storage:
|
|
182
|
-
use for storing the model.
|
|
183
|
-
file_importer: Instance of `TrainingDataImporter` to use for training.
|
|
184
|
-
If it is not provided, a new instance will be created.
|
|
180
|
+
remote_storage: The remote storage which should be used to store the model.
|
|
185
181
|
|
|
186
182
|
Returns:
|
|
187
183
|
An instance of `TrainingResult`.
|
|
188
184
|
"""
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
)
|
|
185
|
+
file_importer = TrainingDataImporter.load_from_config(
|
|
186
|
+
config, domain, training_files, core_additional_arguments
|
|
187
|
+
)
|
|
193
188
|
|
|
194
189
|
stories = file_importer.get_stories()
|
|
195
190
|
flows = file_importer.get_flows()
|
|
@@ -560,7 +555,7 @@ async def train_nlu(
|
|
|
560
555
|
|
|
561
556
|
def push_model_to_remote_storage(model_path: Path, remote_storage: StorageType) -> None:
|
|
562
557
|
"""push model to remote storage"""
|
|
563
|
-
from rasa.
|
|
558
|
+
from rasa.nlu.persistor import get_persistor
|
|
564
559
|
|
|
565
560
|
persistor = get_persistor(remote_storage)
|
|
566
561
|
|
rasa/{core → nlu}/persistor.py
RENAMED
rasa/server.py
CHANGED
|
@@ -50,11 +50,11 @@ from rasa.core.channels.channel import (
|
|
|
50
50
|
UserMessage,
|
|
51
51
|
)
|
|
52
52
|
from rasa.core.constants import DEFAULT_RESPONSE_TIMEOUT
|
|
53
|
-
from rasa.core.persistor import parse_remote_storage
|
|
54
53
|
from rasa.core.test import test
|
|
55
54
|
from rasa.core.utils import AvailableEndpoints
|
|
56
55
|
from rasa.nlu.emulators.emulator import Emulator
|
|
57
56
|
from rasa.nlu.emulators.no_emulator import NoEmulator
|
|
57
|
+
from rasa.nlu.persistor import parse_remote_storage
|
|
58
58
|
from rasa.nlu.test import CVEvaluationResult
|
|
59
59
|
from rasa.shared.constants import (
|
|
60
60
|
DEFAULT_MODELS_PATH,
|