rasa-pro 3.10.7.dev5__py3-none-any.whl → 3.10.9__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/processor.py +57 -8
- 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/e2e_test/utils/io.py +3 -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.dev5.dist-info → rasa_pro-3.10.9.dist-info}/METADATA +43 -7
- {rasa_pro-3.10.7.dev5.dist-info → rasa_pro-3.10.9.dist-info}/RECORD +70 -77
- rasa/keys +0 -1
- rasa/model_manager/__init__.py +0 -0
- rasa/model_manager/config.py +0 -12
- rasa/model_manager/model_api.py +0 -467
- 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.dev5.dist-info → rasa_pro-3.10.9.dist-info}/NOTICE +0 -0
- {rasa_pro-3.10.7.dev5.dist-info → rasa_pro-3.10.9.dist-info}/WHEEL +0 -0
- {rasa_pro-3.10.7.dev5.dist-info → rasa_pro-3.10.9.dist-info}/entry_points.txt +0 -0
README.md
CHANGED
|
@@ -236,6 +236,39 @@ To check the types execute
|
|
|
236
236
|
make types
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
+
### Backporting
|
|
240
|
+
|
|
241
|
+
In order to port changes to `main` and across release branches, we use the `backport` workflow located at
|
|
242
|
+
the `.github/workflows/backport.yml` path.
|
|
243
|
+
This workflow is triggered by the `backport-to-<release-branch>` label applied to a PR, for example `backport-to-3.8.x`.
|
|
244
|
+
Current available target branches are `main` and maintained release branches.
|
|
245
|
+
|
|
246
|
+
When a PR gets labelled `backport-to-<release-branch>`, a PR is opened by the `backport-github-action` as soon as the
|
|
247
|
+
source PR gets closed (by merging). If you want to close the PR without merging changes, make sure to remove the `backport-to-<release-branch>` label.
|
|
248
|
+
|
|
249
|
+
The PR author which the action assigns to the backporting PR has to resolve any conflicts before approving and merging.
|
|
250
|
+
Release PRs should also be labelled with `backport-to-main` to backport the `CHANGELOG.md` updates to `main`.
|
|
251
|
+
Backporting version updates should be accepted to the `main` branch from the latest release branch only.
|
|
252
|
+
|
|
253
|
+
Here are some guidelines to follow when backporting changes and resolving conflicts:
|
|
254
|
+
|
|
255
|
+
a) for conflicts in `version.py`: accept only the version from the latest release branch. Do not merge version changes
|
|
256
|
+
from earlier release branches into `main` because this could cause issues when trying to make the next minor release.
|
|
257
|
+
|
|
258
|
+
b) for conflicts in `pyproject.toml`: if related to the `rasa-pro` version, accept only the latest release branch;
|
|
259
|
+
if related to other dependencies, accept `main` or whichever is the higher upgrade (main usually has the updated
|
|
260
|
+
dependencies because we only do housekeeping on `main`, apart from vulnerability updates). Be mindful of dependencies that
|
|
261
|
+
are removed from `main` but still exist in former release branches (for example `langchain`).
|
|
262
|
+
|
|
263
|
+
c) for conflicts in `poetry.lock`: accept changes which were already present on the target branch, then run
|
|
264
|
+
`poetry lock --no-update` so that the lock file contains your changes from `pyproject.toml` too.
|
|
265
|
+
|
|
266
|
+
d) for conflicts in `CHANGELOG.md`: Manually place the changelog in their allocated section (e.g. 3.8.10 will go under the
|
|
267
|
+
3.8 section with the other releases, rather than go at the top of the file)
|
|
268
|
+
|
|
269
|
+
If the backporting workflow fails, you are encouraged to cherry-pick the commits manually and create a PR to
|
|
270
|
+
the target branch. Alternatively, you can install the backporting CLI tool as described [here](https://github.com/sorenlouv/backport?tab=readme-ov-file#install).
|
|
271
|
+
|
|
239
272
|
## Releases
|
|
240
273
|
Rasa has implemented robust policies governing version naming, as well as release pace for major, minor, and patch releases.
|
|
241
274
|
|
|
@@ -318,9 +351,12 @@ Releasing a new version is quite simple, as the packages are build and distribut
|
|
|
318
351
|
9. If however an error occurs in the build, then we should see a failure message automatically posted in the company's Slack (`dev-tribe` channel) like this [one](https://rasa-hq.slack.com/archives/C01M5TAHDHA/p1701444735622919)
|
|
319
352
|
(In this case do the following checks):
|
|
320
353
|
- Check the workflows in [Github Actions](https://github.com/RasaHQ/rasa-private/actions) and make sure that the merged PR of the current release is completed successfully. To easily find your PR you can use the filters `event: push` and `branch: <version number>` (example on release 2.4 you can see [here](https://github.com/RasaHQ/rasa/actions/runs/643344876))
|
|
321
|
-
- If the workflow is not completed, then try to re
|
|
354
|
+
- If the workflow is not completed, then try to re-run the workflow in case that solves the problem
|
|
322
355
|
- If the problem persists, check also the log files and try to find the root cause of the issue
|
|
323
356
|
- If you still cannot resolve the error, contact the infrastructure team by providing any helpful information from your investigation
|
|
357
|
+
10. If the release is successful, add the newly created release branch to the backporting configuration in the `.backportrc.json` file to
|
|
358
|
+
the `targetBranchesChoices` list. This is necessary for the backporting workflow to work correctly with new release branches.
|
|
359
|
+
|
|
324
360
|
|
|
325
361
|
### Cutting a Patch release
|
|
326
362
|
|
rasa/api.py
CHANGED
|
@@ -2,7 +2,7 @@ import asyncio
|
|
|
2
2
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text, Union
|
|
3
3
|
|
|
4
4
|
import rasa.shared.constants
|
|
5
|
-
from rasa.
|
|
5
|
+
from rasa.nlu.persistor import StorageType
|
|
6
6
|
|
|
7
7
|
# WARNING: Be careful about adding any top level imports at this place!
|
|
8
8
|
# These functions are imported in `rasa.__init__` and any top level import
|
|
@@ -14,7 +14,6 @@ from rasa.core.persistor import StorageType
|
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
16
|
from rasa.model_training import TrainingResult
|
|
17
|
-
from rasa.shared.importers.importer import TrainingDataImporter
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
def run(
|
|
@@ -79,7 +78,6 @@ def train(
|
|
|
79
78
|
model_to_finetune: Optional[Text] = None,
|
|
80
79
|
finetuning_epoch_fraction: float = 1.0,
|
|
81
80
|
remote_storage: Optional[StorageType] = None,
|
|
82
|
-
file_importer: Optional["TrainingDataImporter"] = None,
|
|
83
81
|
) -> "TrainingResult":
|
|
84
82
|
"""Runs Rasa Core and NLU training in `async` loop.
|
|
85
83
|
|
|
@@ -101,10 +99,7 @@ def train(
|
|
|
101
99
|
a directory in case the latest trained model should be used.
|
|
102
100
|
finetuning_epoch_fraction: The fraction currently specified training epochs
|
|
103
101
|
in the model configuration which should be used for finetuning.
|
|
104
|
-
remote_storage:
|
|
105
|
-
use for storing the model.
|
|
106
|
-
file_importer: Instance of `TrainingDataImporter` to use for training.
|
|
107
|
-
If it is not provided, a new instance will be created.
|
|
102
|
+
remote_storage: Remote storage to use for model storage.
|
|
108
103
|
|
|
109
104
|
Returns:
|
|
110
105
|
An instance of `TrainingResult`.
|
|
@@ -126,7 +121,6 @@ def train(
|
|
|
126
121
|
model_to_finetune=model_to_finetune,
|
|
127
122
|
finetuning_epoch_fraction=finetuning_epoch_fraction,
|
|
128
123
|
remote_storage=remote_storage,
|
|
129
|
-
file_importer=file_importer,
|
|
130
124
|
)
|
|
131
125
|
)
|
|
132
126
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
|
-
from
|
|
4
|
-
from typing import List, Optional, Text, Union
|
|
3
|
+
from typing import Optional, Text, Union
|
|
5
4
|
|
|
6
|
-
from rasa.
|
|
5
|
+
from rasa.nlu.persistor import RemoteStorageType, StorageType, parse_remote_storage
|
|
7
6
|
from rasa.shared.constants import (
|
|
8
7
|
DEFAULT_CONFIG_PATH,
|
|
9
8
|
DEFAULT_DATA_PATH,
|
|
@@ -186,23 +185,3 @@ def parse_remote_storage_arg(value: str) -> StorageType:
|
|
|
186
185
|
return parse_remote_storage(value)
|
|
187
186
|
except ValueError as e:
|
|
188
187
|
raise argparse.ArgumentTypeError(str(e))
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
class SkipYamlValidation(Enum):
|
|
192
|
-
DOMAIN = "domain"
|
|
193
|
-
|
|
194
|
-
@classmethod
|
|
195
|
-
def list(cls) -> List[str]:
|
|
196
|
-
return [e.value for e in SkipYamlValidation]
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
def add_skip_validation_flag(
|
|
200
|
-
parser: Union[argparse.ArgumentParser, argparse._ActionsContainer],
|
|
201
|
-
) -> None:
|
|
202
|
-
parser.add_argument(
|
|
203
|
-
"--skip-yaml-validation",
|
|
204
|
-
default=[],
|
|
205
|
-
choices=SkipYamlValidation.list(),
|
|
206
|
-
action="append",
|
|
207
|
-
help="Skip YAML validation for selected parts of the training data.",
|
|
208
|
-
)
|
rasa/cli/arguments/run.py
CHANGED
|
@@ -5,7 +5,6 @@ from typing import Union
|
|
|
5
5
|
from rasa.cli.arguments.default_arguments import (
|
|
6
6
|
add_endpoint_param,
|
|
7
7
|
add_model_param,
|
|
8
|
-
add_skip_validation_flag,
|
|
9
8
|
add_remote_storage_param,
|
|
10
9
|
)
|
|
11
10
|
from rasa.core import constants
|
|
@@ -22,7 +21,6 @@ def set_run_arguments(parser: argparse.ArgumentParser) -> None:
|
|
|
22
21
|
"""Arguments for running Rasa directly using `rasa run`."""
|
|
23
22
|
add_model_param(parser)
|
|
24
23
|
add_server_arguments(parser)
|
|
25
|
-
add_skip_validation_flag(parser)
|
|
26
24
|
|
|
27
25
|
|
|
28
26
|
def set_run_action_arguments(parser: argparse.ArgumentParser) -> None:
|
rasa/cli/e2e_test.py
CHANGED
|
@@ -221,17 +221,15 @@ def execute_e2e_tests(args: argparse.Namespace) -> None:
|
|
|
221
221
|
if args.e2e_results is not None:
|
|
222
222
|
results_path = Path(args.e2e_results)
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
write_test_results_to_file(passed, passed_file)
|
|
224
|
+
passed_file = rasa.cli.utils.get_e2e_results_file_name(
|
|
225
|
+
results_path, STATUS_PASSED
|
|
226
|
+
)
|
|
227
|
+
write_test_results_to_file(passed, passed_file)
|
|
229
228
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
write_test_results_to_file(failed, failed_file)
|
|
229
|
+
failed_file = rasa.cli.utils.get_e2e_results_file_name(
|
|
230
|
+
results_path, STATUS_FAILED
|
|
231
|
+
)
|
|
232
|
+
write_test_results_to_file(failed, failed_file)
|
|
235
233
|
|
|
236
234
|
aggregate_stats_calculator = AggregateTestStatsCalculator(
|
|
237
235
|
passed_results=passed, failed_results=failed, test_cases=test_suite.test_cases
|
rasa/cli/inspect.py
CHANGED
|
@@ -3,12 +3,11 @@ import webbrowser
|
|
|
3
3
|
from asyncio import AbstractEventLoop
|
|
4
4
|
from typing import List, Text
|
|
5
5
|
|
|
6
|
-
from sanic import Sanic
|
|
7
|
-
|
|
8
6
|
from rasa.cli import SubParsersAction
|
|
9
7
|
from rasa.cli.arguments import shell as arguments
|
|
10
|
-
from rasa.cli.arguments.default_arguments import add_skip_validation_flag
|
|
11
8
|
from rasa.core import constants
|
|
9
|
+
from sanic import Sanic
|
|
10
|
+
|
|
12
11
|
from rasa.utils.cli import remove_argument_from_parser
|
|
13
12
|
|
|
14
13
|
|
|
@@ -34,8 +33,6 @@ def add_subparser(
|
|
|
34
33
|
inspect_parser.set_defaults(func=inspect)
|
|
35
34
|
|
|
36
35
|
arguments.set_shell_arguments(inspect_parser)
|
|
37
|
-
add_skip_validation_flag(inspect_parser)
|
|
38
|
-
|
|
39
36
|
# it'd be confusing to expose those arguments to the user,
|
|
40
37
|
# so we remove them
|
|
41
38
|
remove_argument_from_parser(inspect_parser, "--credentials")
|
rasa/cli/run.py
CHANGED
|
@@ -6,7 +6,6 @@ from typing import List, Text
|
|
|
6
6
|
from rasa.api import run as rasa_run
|
|
7
7
|
from rasa.cli import SubParsersAction
|
|
8
8
|
from rasa.cli.arguments import run as arguments
|
|
9
|
-
from rasa.cli.arguments.default_arguments import SkipYamlValidation
|
|
10
9
|
from rasa.cli.utils import get_validated_path
|
|
11
10
|
from rasa.exceptions import ModelNotFound
|
|
12
11
|
from rasa.shared.constants import (
|
|
@@ -16,7 +15,6 @@ from rasa.shared.constants import (
|
|
|
16
15
|
DEFAULT_MODELS_PATH,
|
|
17
16
|
DOCS_BASE_URL,
|
|
18
17
|
)
|
|
19
|
-
from rasa.shared.core.domain import Domain
|
|
20
18
|
from rasa.shared.utils.cli import print_error
|
|
21
19
|
|
|
22
20
|
logger = logging.getLogger(__name__)
|
|
@@ -89,11 +87,6 @@ def run(args: argparse.Namespace) -> None:
|
|
|
89
87
|
args.credentials, "credentials", DEFAULT_CREDENTIALS_PATH, True
|
|
90
88
|
)
|
|
91
89
|
|
|
92
|
-
if SkipYamlValidation.DOMAIN.value in args.skip_yaml_validation:
|
|
93
|
-
Domain.validate_yaml = False
|
|
94
|
-
else:
|
|
95
|
-
Domain.validate_yaml = True
|
|
96
|
-
|
|
97
90
|
if args.enable_api:
|
|
98
91
|
if not args.remote_storage:
|
|
99
92
|
args.model = _validate_model_path(args.model, "model", DEFAULT_MODELS_PATH)
|
rasa/cli/studio/studio.py
CHANGED
|
@@ -5,6 +5,7 @@ from urllib.parse import ParseResult, urlparse
|
|
|
5
5
|
import questionary
|
|
6
6
|
from rasa.cli import SubParsersAction
|
|
7
7
|
|
|
8
|
+
import rasa.shared.utils.cli
|
|
8
9
|
import rasa.cli.studio.download
|
|
9
10
|
import rasa.cli.studio.train
|
|
10
11
|
import rasa.cli.studio.upload
|
|
@@ -50,6 +51,15 @@ def _add_config_subparser(
|
|
|
50
51
|
|
|
51
52
|
studio_config_parser.set_defaults(func=create_and_store_studio_config)
|
|
52
53
|
|
|
54
|
+
studio_config_parser.add_argument(
|
|
55
|
+
"--disable-verify",
|
|
56
|
+
"-x",
|
|
57
|
+
action="store_true",
|
|
58
|
+
default=False,
|
|
59
|
+
help="Disable strict SSL verification for the "
|
|
60
|
+
"Rasa Studio authentication server.",
|
|
61
|
+
)
|
|
62
|
+
|
|
53
63
|
# add advanced configuration flag to trigger
|
|
54
64
|
# advanced configuration setup for authentication settings
|
|
55
65
|
studio_config_parser.add_argument(
|
|
@@ -219,7 +229,17 @@ def _configure_studio_config(args: argparse.Namespace) -> StudioConfig:
|
|
|
219
229
|
studio_config = _create_studio_config(
|
|
220
230
|
studio_url, keycloak_url, realm_name, client_id
|
|
221
231
|
)
|
|
222
|
-
|
|
232
|
+
|
|
233
|
+
if args.disable_verify:
|
|
234
|
+
rasa.shared.utils.cli.print_info(
|
|
235
|
+
"Disabling SSL verification for the Rasa Studio authentication server."
|
|
236
|
+
)
|
|
237
|
+
studio_auth = StudioAuth(studio_config, verify=False)
|
|
238
|
+
else:
|
|
239
|
+
rasa.shared.utils.cli.print_info(
|
|
240
|
+
"Enabling SSL verification for the Rasa Studio authentication server."
|
|
241
|
+
)
|
|
242
|
+
studio_auth = StudioAuth(studio_config, verify=True)
|
|
223
243
|
|
|
224
244
|
if _check_studio_auth(studio_auth):
|
|
225
245
|
return studio_config
|
rasa/cli/train.py
CHANGED
|
@@ -110,20 +110,16 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
|
|
|
110
110
|
for f in args.data
|
|
111
111
|
]
|
|
112
112
|
|
|
113
|
-
training_data_importer = TrainingDataImporter.load_from_config(
|
|
114
|
-
domain_path=domain, training_data_paths=args.data, config_path=config
|
|
115
|
-
)
|
|
116
|
-
|
|
117
113
|
if not args.skip_validation:
|
|
118
114
|
structlogger.info(
|
|
119
115
|
"cli.train.run_training",
|
|
120
116
|
event_info="Started validating domain and training data...",
|
|
121
117
|
)
|
|
122
|
-
|
|
118
|
+
importer = TrainingDataImporter.load_from_config(
|
|
119
|
+
domain_path=domain, training_data_paths=args.data, config_path=config
|
|
120
|
+
)
|
|
123
121
|
rasa.cli.utils.validate_files(
|
|
124
|
-
args.fail_on_validation_warnings,
|
|
125
|
-
args.validation_max_history,
|
|
126
|
-
training_data_importer,
|
|
122
|
+
args.fail_on_validation_warnings, args.validation_max_history, importer
|
|
127
123
|
)
|
|
128
124
|
|
|
129
125
|
training_result = train_all(
|
|
@@ -142,7 +138,6 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
|
|
|
142
138
|
model_to_finetune=_model_for_finetuning(args),
|
|
143
139
|
finetuning_epoch_fraction=args.epoch_fraction,
|
|
144
140
|
remote_storage=args.remote_storage,
|
|
145
|
-
file_importer=training_data_importer,
|
|
146
141
|
)
|
|
147
142
|
if training_result.code != 0 and can_exit:
|
|
148
143
|
sys.exit(training_result.code)
|
rasa/cli/utils.py
CHANGED
|
@@ -470,10 +470,10 @@ def get_e2e_results_file_name(
|
|
|
470
470
|
) -> str:
|
|
471
471
|
"""Returns the name of the e2e results file."""
|
|
472
472
|
if results_output_path.is_dir():
|
|
473
|
-
file_name = results_output_path
|
|
473
|
+
file_name = str(results_output_path) + f"/e2e_results_{result_type}.yml"
|
|
474
474
|
else:
|
|
475
475
|
parent = results_output_path.parent
|
|
476
476
|
stem = results_output_path.stem
|
|
477
|
-
file_name = parent
|
|
477
|
+
file_name = str(parent) + f"/{stem}_{result_type}.yml"
|
|
478
478
|
|
|
479
|
-
return
|
|
479
|
+
return file_name
|
rasa/core/agent.py
CHANGED
|
@@ -19,7 +19,6 @@ from rasa.core.exceptions import AgentNotReady
|
|
|
19
19
|
from rasa.core.http_interpreter import RasaNLUHttpInterpreter
|
|
20
20
|
from rasa.core.lock_store import InMemoryLockStore, LockStore
|
|
21
21
|
from rasa.core.nlg import NaturalLanguageGenerator, TemplatedNaturalLanguageGenerator
|
|
22
|
-
from rasa.core.persistor import StorageType
|
|
23
22
|
from rasa.core.policies.policy import PolicyPrediction
|
|
24
23
|
from rasa.core.processor import MessageProcessor
|
|
25
24
|
from rasa.core.tracker_store import (
|
|
@@ -29,6 +28,7 @@ from rasa.core.tracker_store import (
|
|
|
29
28
|
)
|
|
30
29
|
from rasa.core.utils import AvailableEndpoints
|
|
31
30
|
from rasa.exceptions import ModelNotFound
|
|
31
|
+
from rasa.nlu.persistor import StorageType
|
|
32
32
|
from rasa.nlu.utils import is_url
|
|
33
33
|
from rasa.shared.constants import DEFAULT_SENDER_ID
|
|
34
34
|
from rasa.shared.core.domain import Domain
|
|
@@ -544,7 +544,7 @@ class Agent:
|
|
|
544
544
|
|
|
545
545
|
def load_model_from_remote_storage(self, model_name: Text) -> None:
|
|
546
546
|
"""Loads an Agent from remote storage."""
|
|
547
|
-
from rasa.
|
|
547
|
+
from rasa.nlu.persistor import get_persistor
|
|
548
548
|
|
|
549
549
|
persistor = get_persistor(self.remote_storage)
|
|
550
550
|
|
rasa/core/brokers/kafka.py
CHANGED
|
@@ -2,8 +2,6 @@ import asyncio
|
|
|
2
2
|
import os
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
-
from functools import cached_property
|
|
6
|
-
|
|
7
5
|
import structlog
|
|
8
6
|
import threading
|
|
9
7
|
from asyncio import AbstractEventLoop
|
|
@@ -272,7 +270,7 @@ class KafkaEventBroker(EventBroker):
|
|
|
272
270
|
if self.producer:
|
|
273
271
|
self.producer.flush()
|
|
274
272
|
|
|
275
|
-
@
|
|
273
|
+
@rasa.shared.utils.common.lazy_property
|
|
276
274
|
def rasa_environment(self) -> Optional[Text]:
|
|
277
275
|
"""Get value of the `RASA_ENVIRONMENT` environment variable."""
|
|
278
276
|
return os.environ.get("RASA_ENVIRONMENT", "RASA_ENVIRONMENT_NOT_SET")
|
rasa/core/brokers/pika.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
|
-
from functools import cached_property
|
|
5
|
-
|
|
6
4
|
import structlog
|
|
7
5
|
import os
|
|
8
6
|
import ssl
|
|
@@ -335,7 +333,7 @@ class PikaEventBroker(EventBroker):
|
|
|
335
333
|
delivery_mode=aio_pika.DeliveryMode.PERSISTENT,
|
|
336
334
|
)
|
|
337
335
|
|
|
338
|
-
@
|
|
336
|
+
@rasa.shared.utils.common.lazy_property
|
|
339
337
|
def rasa_environment(self) -> Optional[Text]:
|
|
340
338
|
"""Get value of the `RASA_ENVIRONMENT` environment variable."""
|
|
341
339
|
return os.environ.get("RASA_ENVIRONMENT")
|
rasa/core/channels/socketio.py
CHANGED
|
@@ -37,11 +37,7 @@ class SocketBlueprint(Blueprint):
|
|
|
37
37
|
:param options: Options to be used while registering the
|
|
38
38
|
blueprint into the app.
|
|
39
39
|
"""
|
|
40
|
-
|
|
41
|
-
path = self.ctx.socketio_path
|
|
42
|
-
else:
|
|
43
|
-
path = options.get("url_prefix", "/socket.io")
|
|
44
|
-
self.ctx.sio.attach(app, path)
|
|
40
|
+
self.ctx.sio.attach(app, self.ctx.socketio_path)
|
|
45
41
|
super().register(app, options)
|
|
46
42
|
|
|
47
43
|
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import structlog
|
|
2
2
|
|
|
3
|
+
from rasa.utils.licensing import (
|
|
4
|
+
PRODUCT_AREA,
|
|
5
|
+
VOICE_SCOPE,
|
|
6
|
+
validate_license_from_env,
|
|
7
|
+
)
|
|
3
8
|
|
|
4
9
|
structlogger = structlog.get_logger()
|
|
5
10
|
|
|
6
11
|
|
|
7
12
|
def validate_voice_license_scope() -> None:
|
|
8
|
-
from rasa.utils.licensing import (
|
|
9
|
-
PRODUCT_AREA,
|
|
10
|
-
VOICE_SCOPE,
|
|
11
|
-
validate_license_from_env,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
13
|
"""Validate that the correct license scope is present."""
|
|
15
14
|
structlogger.info(
|
|
16
15
|
f"Validating current Rasa Pro license scope which must include "
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
from typing import Any, Dict, Optional, Text
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
import structlog
|
|
5
4
|
from jinja2 import Template
|
|
6
5
|
|
|
7
6
|
from rasa import telemetry
|
|
8
7
|
from rasa.core.nlg.response import TemplatedNaturalLanguageGenerator
|
|
9
8
|
from rasa.shared.constants import (
|
|
10
|
-
LLM_API_HEALTH_CHECK_ENV_VAR,
|
|
11
9
|
LLM_CONFIG_KEY,
|
|
12
10
|
MODEL_CONFIG_KEY,
|
|
13
11
|
MODEL_NAME_CONFIG_KEY,
|
|
@@ -25,7 +23,6 @@ from rasa.shared.utils.llm import (
|
|
|
25
23
|
USER,
|
|
26
24
|
combine_custom_and_default_config,
|
|
27
25
|
get_prompt_template,
|
|
28
|
-
llm_api_health_check,
|
|
29
26
|
llm_factory,
|
|
30
27
|
try_instantiate_llm_client,
|
|
31
28
|
)
|
|
@@ -100,18 +97,12 @@ class ContextualResponseRephraser(TemplatedNaturalLanguageGenerator):
|
|
|
100
97
|
self.trace_prompt_tokens = self.nlg_endpoint.kwargs.get(
|
|
101
98
|
"trace_prompt_tokens", False
|
|
102
99
|
)
|
|
103
|
-
|
|
100
|
+
try_instantiate_llm_client(
|
|
104
101
|
self.nlg_endpoint.kwargs.get(LLM_CONFIG_KEY),
|
|
105
102
|
DEFAULT_LLM_CONFIG,
|
|
106
103
|
"contextual_response_rephraser.init",
|
|
107
|
-
ContextualResponseRephraser
|
|
104
|
+
"ContextualResponseRephraser",
|
|
108
105
|
)
|
|
109
|
-
if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
|
|
110
|
-
llm_api_health_check(
|
|
111
|
-
llm_client,
|
|
112
|
-
"contextual_response_rephraser.init",
|
|
113
|
-
ContextualResponseRephraser.__name__,
|
|
114
|
-
)
|
|
115
106
|
|
|
116
107
|
def _last_message_if_human(self, tracker: DialogueStateTracker) -> Optional[str]:
|
|
117
108
|
"""Returns the latest message from the tracker.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import importlib.resources
|
|
2
2
|
import json
|
|
3
|
-
import os
|
|
4
3
|
import re
|
|
5
4
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text
|
|
6
5
|
|
|
@@ -48,7 +47,6 @@ from rasa.graph_components.providers.forms_provider import Forms
|
|
|
48
47
|
from rasa.graph_components.providers.responses_provider import Responses
|
|
49
48
|
from rasa.shared.constants import (
|
|
50
49
|
EMBEDDINGS_CONFIG_KEY,
|
|
51
|
-
LLM_API_HEALTH_CHECK_ENV_VAR,
|
|
52
50
|
LLM_CONFIG_KEY,
|
|
53
51
|
MODEL_CONFIG_KEY,
|
|
54
52
|
MODEL_NAME_CONFIG_KEY,
|
|
@@ -74,7 +72,6 @@ from rasa.shared.utils.llm import (
|
|
|
74
72
|
DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
|
|
75
73
|
embedder_factory,
|
|
76
74
|
get_prompt_template,
|
|
77
|
-
llm_api_health_check,
|
|
78
75
|
llm_factory,
|
|
79
76
|
sanitize_message_for_prompt,
|
|
80
77
|
tracker_as_readable_transcript,
|
|
@@ -295,18 +292,12 @@ class EnterpriseSearchPolicy(Policy):
|
|
|
295
292
|
)
|
|
296
293
|
|
|
297
294
|
# validate llm configuration
|
|
298
|
-
|
|
295
|
+
try_instantiate_llm_client(
|
|
299
296
|
self.config.get(LLM_CONFIG_KEY),
|
|
300
297
|
DEFAULT_LLM_CONFIG,
|
|
301
298
|
"enterprise_search_policy.train",
|
|
302
|
-
EnterpriseSearchPolicy
|
|
299
|
+
"EnterpriseSearchPolicy",
|
|
303
300
|
)
|
|
304
|
-
if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
|
|
305
|
-
llm_api_health_check(
|
|
306
|
-
llm_client,
|
|
307
|
-
"enterprise_search_policy.train",
|
|
308
|
-
EnterpriseSearchPolicy.__name__,
|
|
309
|
-
)
|
|
310
301
|
|
|
311
302
|
if store_type == DEFAULT_VECTOR_STORE_TYPE:
|
|
312
303
|
logger.info("enterprise_search_policy.train.faiss")
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import importlib.resources
|
|
2
2
|
import math
|
|
3
|
-
import os
|
|
4
3
|
from dataclasses import dataclass, field
|
|
5
4
|
from typing import Any, Dict, List, Optional, Set, TYPE_CHECKING, Text, Tuple
|
|
6
5
|
|
|
@@ -32,7 +31,6 @@ from rasa.graph_components.providers.responses_provider import Responses
|
|
|
32
31
|
from rasa.shared.constants import (
|
|
33
32
|
REQUIRED_SLOTS_KEY,
|
|
34
33
|
EMBEDDINGS_CONFIG_KEY,
|
|
35
|
-
LLM_API_HEALTH_CHECK_ENV_VAR,
|
|
36
34
|
LLM_CONFIG_KEY,
|
|
37
35
|
MODEL_CONFIG_KEY,
|
|
38
36
|
MODEL_NAME_CONFIG_KEY,
|
|
@@ -69,7 +67,6 @@ from rasa.shared.utils.llm import (
|
|
|
69
67
|
combine_custom_and_default_config,
|
|
70
68
|
embedder_factory,
|
|
71
69
|
get_prompt_template,
|
|
72
|
-
llm_api_health_check,
|
|
73
70
|
llm_factory,
|
|
74
71
|
sanitize_message_for_prompt,
|
|
75
72
|
tracker_as_readable_transcript,
|
|
@@ -490,16 +487,12 @@ class IntentlessPolicy(Policy):
|
|
|
490
487
|
A policy must return its resource locator so that potential children nodes
|
|
491
488
|
can load the policy from the resource.
|
|
492
489
|
"""
|
|
493
|
-
|
|
490
|
+
try_instantiate_llm_client(
|
|
494
491
|
self.config.get(LLM_CONFIG_KEY),
|
|
495
492
|
DEFAULT_LLM_CONFIG,
|
|
496
493
|
"intentless_policy.train",
|
|
497
|
-
IntentlessPolicy
|
|
494
|
+
"IntentlessPolicy",
|
|
498
495
|
)
|
|
499
|
-
if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
|
|
500
|
-
llm_api_health_check(
|
|
501
|
-
llm_client, "intentless_policy.train", IntentlessPolicy.__name__
|
|
502
|
-
)
|
|
503
496
|
|
|
504
497
|
responses = filter_responses(responses, forms, flows or FlowsList([]))
|
|
505
498
|
telemetry.track_intentless_policy_train()
|
rasa/core/processor.py
CHANGED
|
@@ -101,6 +101,9 @@ logger = logging.getLogger(__name__)
|
|
|
101
101
|
structlogger = structlog.get_logger()
|
|
102
102
|
|
|
103
103
|
MAX_NUMBER_OF_PREDICTIONS = int(os.environ.get("MAX_NUMBER_OF_PREDICTIONS", "10"))
|
|
104
|
+
MAX_NUMBER_OF_PREDICTIONS_CALM = int(
|
|
105
|
+
os.environ.get("MAX_NUMBER_OF_PREDICTIONS_CALM", "1000")
|
|
106
|
+
)
|
|
104
107
|
|
|
105
108
|
|
|
106
109
|
class MessageProcessor:
|
|
@@ -114,6 +117,7 @@ class MessageProcessor:
|
|
|
114
117
|
generator: NaturalLanguageGenerator,
|
|
115
118
|
action_endpoint: Optional[EndpointConfig] = None,
|
|
116
119
|
max_number_of_predictions: int = MAX_NUMBER_OF_PREDICTIONS,
|
|
120
|
+
max_number_of_predictions_calm: int = MAX_NUMBER_OF_PREDICTIONS_CALM,
|
|
117
121
|
on_circuit_break: Optional[LambdaType] = None,
|
|
118
122
|
http_interpreter: Optional[RasaNLUHttpInterpreter] = None,
|
|
119
123
|
endpoints: Optional["AvailableEndpoints"] = None,
|
|
@@ -122,7 +126,6 @@ class MessageProcessor:
|
|
|
122
126
|
self.nlg = generator
|
|
123
127
|
self.tracker_store = tracker_store
|
|
124
128
|
self.lock_store = lock_store
|
|
125
|
-
self.max_number_of_predictions = max_number_of_predictions
|
|
126
129
|
self.on_circuit_break = on_circuit_break
|
|
127
130
|
self.action_endpoint = action_endpoint
|
|
128
131
|
self.model_filename, self.model_metadata, self.graph_runner = self._load_model(
|
|
@@ -130,6 +133,10 @@ class MessageProcessor:
|
|
|
130
133
|
)
|
|
131
134
|
self.endpoints = endpoints
|
|
132
135
|
|
|
136
|
+
self.max_number_of_predictions = max_number_of_predictions
|
|
137
|
+
self.max_number_of_predictions_calm = max_number_of_predictions_calm
|
|
138
|
+
self.is_calm_assistant = self._is_calm_assistant()
|
|
139
|
+
|
|
133
140
|
if self.model_metadata.assistant_id is None:
|
|
134
141
|
rasa.shared.utils.io.raise_warning(
|
|
135
142
|
f"The model metadata does not contain a value for the "
|
|
@@ -972,11 +979,15 @@ class MessageProcessor:
|
|
|
972
979
|
) -> int:
|
|
973
980
|
"""Select the action limit based on the tracker state.
|
|
974
981
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
982
|
+
This function determines the maximum number of predictions that should be
|
|
983
|
+
made during a dialogue conversation. Typically, the number of predictions
|
|
984
|
+
is limited to the number of actions executed so far in the conversation.
|
|
985
|
+
However, in certain states (e.g., when the user is correcting the
|
|
986
|
+
conversation flow), more predictions may be allowed as the system traverses
|
|
987
|
+
through a long dialogue flow.
|
|
988
|
+
|
|
989
|
+
Additionally, if the `ROUTE_TO_CALM_SLOT` is present in the tracker slots,
|
|
990
|
+
the action limit is adjusted to a separate limit for CALM-based flows.
|
|
980
991
|
|
|
981
992
|
Args:
|
|
982
993
|
tracker: instance of DialogueStateTracker.
|
|
@@ -984,6 +995,18 @@ class MessageProcessor:
|
|
|
984
995
|
Returns:
|
|
985
996
|
The maximum number of predictions to make.
|
|
986
997
|
"""
|
|
998
|
+
# Check if it is a CALM assistant and if so, that the `ROUTE_TO_CALM_SLOT`
|
|
999
|
+
# is either not present or set to `True`.
|
|
1000
|
+
# If it does, use the specific prediction limit for CALM assistants.
|
|
1001
|
+
# Otherwise, use the default prediction limit.
|
|
1002
|
+
if self.is_calm_assistant and (
|
|
1003
|
+
not tracker.has_coexistence_routing_slot
|
|
1004
|
+
or tracker.get_slot(ROUTE_TO_CALM_SLOT)
|
|
1005
|
+
):
|
|
1006
|
+
max_number_of_predictions = self.max_number_of_predictions_calm
|
|
1007
|
+
else:
|
|
1008
|
+
max_number_of_predictions = self.max_number_of_predictions
|
|
1009
|
+
|
|
987
1010
|
reversed_events = list(tracker.events)[::-1]
|
|
988
1011
|
is_conversation_in_flow_correction = False
|
|
989
1012
|
for e in reversed_events:
|
|
@@ -998,8 +1021,10 @@ class MessageProcessor:
|
|
|
998
1021
|
# allow for more predictions to be made as we might be traversing through
|
|
999
1022
|
# a long flow. We multiply the number of predictions by 10 to allow for
|
|
1000
1023
|
# more predictions to be made - the factor is a best guess.
|
|
1001
|
-
return
|
|
1002
|
-
|
|
1024
|
+
return max_number_of_predictions * 5
|
|
1025
|
+
|
|
1026
|
+
# Return the default
|
|
1027
|
+
return max_number_of_predictions
|
|
1003
1028
|
|
|
1004
1029
|
def is_action_limit_reached(
|
|
1005
1030
|
self, tracker: DialogueStateTracker, should_predict_another_action: bool
|
|
@@ -1387,3 +1412,27 @@ class MessageProcessor:
|
|
|
1387
1412
|
]
|
|
1388
1413
|
|
|
1389
1414
|
return len(filtered_commands) > 0
|
|
1415
|
+
|
|
1416
|
+
def _is_calm_assistant(self) -> bool:
|
|
1417
|
+
"""Inspects the nodes of the graph schema to determine whether
|
|
1418
|
+
any node is associated with the `FlowPolicy`, which is indicative of a
|
|
1419
|
+
CALM assistant setup.
|
|
1420
|
+
|
|
1421
|
+
Returns:
|
|
1422
|
+
bool: True if any node in the graph schema uses `FlowPolicy`.
|
|
1423
|
+
"""
|
|
1424
|
+
# Get the graph schema's nodes from the graph runner.
|
|
1425
|
+
nodes: dict[str, Any] = self.graph_runner._graph_schema.nodes # type: ignore[attr-defined]
|
|
1426
|
+
|
|
1427
|
+
flow_policy_class_path = "rasa.core.policies.flow_policy.FlowPolicy"
|
|
1428
|
+
# Iterate over the nodes and check if any node uses `FlowPolicy`.
|
|
1429
|
+
for node_name, schema_node in nodes.items():
|
|
1430
|
+
if (
|
|
1431
|
+
schema_node.uses is not None
|
|
1432
|
+
and f"{schema_node.uses.__module__}.{schema_node.uses.__name__}"
|
|
1433
|
+
== flow_policy_class_path
|
|
1434
|
+
):
|
|
1435
|
+
return True
|
|
1436
|
+
|
|
1437
|
+
# Return False if no node is found using `FlowPolicy`.
|
|
1438
|
+
return False
|