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.

Files changed (76) hide show
  1. README.md +37 -1
  2. rasa/api.py +2 -8
  3. rasa/cli/arguments/default_arguments.py +2 -23
  4. rasa/cli/arguments/run.py +0 -2
  5. rasa/cli/e2e_test.py +8 -10
  6. rasa/cli/inspect.py +2 -5
  7. rasa/cli/run.py +0 -7
  8. rasa/cli/studio/studio.py +21 -1
  9. rasa/cli/train.py +4 -9
  10. rasa/cli/utils.py +3 -3
  11. rasa/core/agent.py +2 -2
  12. rasa/core/brokers/kafka.py +1 -3
  13. rasa/core/brokers/pika.py +1 -3
  14. rasa/core/channels/socketio.py +1 -5
  15. rasa/core/channels/voice_aware/utils.py +5 -6
  16. rasa/core/nlg/contextual_response_rephraser.py +2 -11
  17. rasa/core/policies/enterprise_search_policy.py +2 -11
  18. rasa/core/policies/intentless_policy.py +2 -9
  19. rasa/core/run.py +1 -2
  20. rasa/core/secrets_manager/constants.py +0 -4
  21. rasa/core/secrets_manager/factory.py +0 -8
  22. rasa/core/secrets_manager/vault.py +1 -11
  23. rasa/core/utils.py +19 -30
  24. rasa/dialogue_understanding/coexistence/llm_based_router.py +2 -9
  25. rasa/dialogue_understanding/commands/__init__.py +2 -0
  26. rasa/dialogue_understanding/commands/restart_command.py +58 -0
  27. rasa/dialogue_understanding/commands/set_slot_command.py +5 -1
  28. rasa/dialogue_understanding/commands/utils.py +3 -1
  29. rasa/dialogue_understanding/generator/llm_based_command_generator.py +2 -11
  30. rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
  31. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +15 -15
  32. rasa/dialogue_understanding/patterns/restart.py +37 -0
  33. rasa/e2e_test/e2e_test_runner.py +1 -1
  34. rasa/engine/graph.py +1 -0
  35. rasa/engine/recipes/config_files/default_config.yml +3 -0
  36. rasa/engine/recipes/default_recipe.py +1 -0
  37. rasa/engine/recipes/graph_recipe.py +1 -0
  38. rasa/engine/storage/local_model_storage.py +1 -0
  39. rasa/engine/storage/storage.py +5 -1
  40. rasa/model_training.py +6 -11
  41. rasa/{core → nlu}/persistor.py +1 -1
  42. rasa/server.py +1 -1
  43. rasa/shared/constants.py +3 -2
  44. rasa/shared/core/domain.py +47 -101
  45. rasa/shared/core/flows/flows_list.py +6 -19
  46. rasa/shared/core/flows/validation.py +0 -25
  47. rasa/shared/core/flows/yaml_flows_io.py +24 -3
  48. rasa/shared/importers/importer.py +32 -32
  49. rasa/shared/importers/multi_project.py +11 -23
  50. rasa/shared/importers/rasa.py +2 -7
  51. rasa/shared/importers/remote_importer.py +2 -2
  52. rasa/shared/importers/utils.py +1 -3
  53. rasa/shared/nlu/training_data/training_data.py +19 -18
  54. rasa/shared/providers/_configs/azure_openai_client_config.py +5 -3
  55. rasa/shared/providers/llm/_base_litellm_client.py +26 -10
  56. rasa/shared/providers/llm/self_hosted_llm_client.py +15 -3
  57. rasa/shared/utils/common.py +22 -3
  58. rasa/shared/utils/llm.py +5 -29
  59. rasa/shared/utils/schemas/model_config.yml +10 -0
  60. rasa/studio/auth.py +4 -0
  61. rasa/tracing/instrumentation/attribute_extractors.py +1 -1
  62. rasa/validator.py +5 -2
  63. rasa/version.py +1 -1
  64. {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/METADATA +43 -7
  65. {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/RECORD +68 -74
  66. rasa/model_manager/__init__.py +0 -0
  67. rasa/model_manager/config.py +0 -12
  68. rasa/model_manager/model_api.py +0 -464
  69. rasa/model_manager/runner_service.py +0 -185
  70. rasa/model_manager/socket_bridge.py +0 -44
  71. rasa/model_manager/trainer_service.py +0 -240
  72. rasa/model_manager/utils.py +0 -27
  73. rasa/model_service.py +0 -66
  74. {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/NOTICE +0 -0
  75. {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/WHEEL +0 -0
  76. {rasa_pro-3.10.7.dev4.dist-info → rasa_pro-3.10.8.dist-info}/entry_points.txt +0 -0
@@ -1,240 +0,0 @@
1
- import os
2
- from typing import Any, Dict, Optional
3
- import shutil
4
- import base64
5
- import structlog
6
- import subprocess
7
- from dataclasses import dataclass
8
-
9
- from rasa.model_manager.config import RASA_PYTHON_PATH, SERVER_BASE_WORKING_DIRECTORY
10
- from rasa.model_manager.utils import logs_path
11
-
12
- structlogger = structlog.get_logger()
13
-
14
-
15
- @dataclass
16
- class TrainingSession:
17
- """Store information about a training session."""
18
-
19
- training_id: str
20
- assistant_id: str
21
- client_id: Optional[str]
22
- progress: int
23
- status: str
24
- process: subprocess.Popen
25
-
26
-
27
- def train_path(training_id: str) -> str:
28
- """Return the path to the training directory for a given training id."""
29
- return os.path.abspath(f"{SERVER_BASE_WORKING_DIRECTORY}/trainings/{training_id}")
30
-
31
-
32
- def cache_for_assistant_path(assistant_id: str) -> str:
33
- """Return the path to the cache directory for a given assistant id."""
34
- return os.path.abspath(f"{SERVER_BASE_WORKING_DIRECTORY}/caches/{assistant_id}")
35
-
36
-
37
- def write_encoded_data_to_file(encoded_data: bytes, file: str) -> None:
38
- """Write base64 encoded data to a file."""
39
- # create the directory if it does not exist of the parent directory
40
- os.makedirs(os.path.dirname(file), exist_ok=True)
41
-
42
- with open(file, "w") as f:
43
- decoded = base64.b64decode(encoded_data)
44
- text = decoded.decode("utf-8")
45
- f.write(text)
46
-
47
-
48
- def terminate_training(training: TrainingSession) -> None:
49
- if training.status == "running":
50
- structlogger.info(
51
- "model_trainer.user_stopping_training", training_id=training.training_id
52
- )
53
- try:
54
- training.process.terminate()
55
- training.status = "stopped"
56
- except ProcessLookupError:
57
- structlogger.debug(
58
- "model_trainer.training_process_not_found",
59
- training_id=training.training_id,
60
- )
61
-
62
-
63
- def update_training_status(training: TrainingSession) -> None:
64
- if training.status != "running":
65
- # skip if the training is not running
66
- return
67
- if training.process.poll() is None:
68
- # process is still running
69
- return
70
-
71
- complete_training(training)
72
-
73
-
74
- def complete_training(training: TrainingSession) -> None:
75
- """Complete a training session.
76
-
77
- Transitions the status of a training process to "done" if the process has
78
- finished successfully, and to "error" if the process has finished with an
79
- error.
80
- """
81
- training.status = "done" if training.process.returncode == 0 else "error"
82
- training.progress = 100
83
-
84
- structlogger.info(
85
- "model_trainer.training_finished",
86
- training_id=training.training_id,
87
- status=training.status,
88
- )
89
-
90
- # persist the assistant cache to speed up future training runs for this
91
- # assistant
92
- persist_rasa_cache(training.assistant_id, train_path(training.training_id))
93
-
94
-
95
- def seed_training_directory_with_rasa_cache(
96
- training_base_path: str, assistant_id: str
97
- ) -> None:
98
- """Populate the training directory with the cache of a previous training."""
99
- # check if there is a cache for this assistant
100
- cache_path = cache_for_assistant_path(assistant_id)
101
-
102
- if os.path.exists(cache_path):
103
- structlogger.debug(
104
- "model_trainer.populating_training_dir_with_cache",
105
- assistant_id=assistant_id,
106
- training_base_path=training_base_path,
107
- )
108
- # copy the cache to the training directory
109
- shutil.copytree(cache_path, f"{training_base_path}/.rasa")
110
-
111
-
112
- def persist_rasa_cache(assistant_id: str, training_base_path: str) -> None:
113
- """Persist the cache of a training session to speed up future trainings."""
114
- # copy the cache from the training directory to the cache directory
115
- # cache files are stored inside of `/.rasa/` of the training folder
116
- structlogger.debug(
117
- "model_trainer.persisting_assistant_cache", assistant_id=assistant_id
118
- )
119
- cache_path = cache_for_assistant_path(assistant_id)
120
- # clean up the cache directory first
121
- shutil.rmtree(cache_path, ignore_errors=True)
122
- shutil.copytree(f"{training_base_path}/.rasa", cache_path)
123
-
124
-
125
- def write_training_data_to_files(
126
- encoded_training_data: Dict[str, Any], training_base_path: str
127
- ) -> None:
128
- """Write the training data to files in the training directory.
129
-
130
- Incoming data format, all keys being optional:
131
- ````
132
- {
133
- "domain": "base64 encoded domain.yml",
134
- "credentials": "base64 encoded credentials.yml",
135
- "endpoints": "base64 encoded endpoints.yml",
136
- "flows": "base64 encoded flows.yml",
137
- "config": "base64 encoded config.yml",
138
- "stories": "base64 encoded stories.yml",
139
- "rules": "base64 encoded rules.yml",
140
- "nlu": "base64 encoded nlu.yml"
141
- }
142
- ```
143
- """
144
- data_to_be_written_to_files = {
145
- "domain": "domain.yml",
146
- "credentials": "credentials.yml",
147
- "endpoints": "endpoints.yml",
148
- "flows": "data/flows.yml",
149
- "config": "config.yml",
150
- "stories": "data/stories.yml",
151
- "rules": "data/rules.yml",
152
- "nlu": "data/nlu.yml",
153
- }
154
-
155
- for key, file in data_to_be_written_to_files.items():
156
- write_encoded_data_to_file(
157
- encoded_training_data.get(key, ""),
158
- f"{training_base_path}/{file}",
159
- )
160
-
161
-
162
- def prepare_training_directory(
163
- training_base_path: str, assistant_id: str, data: Dict[str, Any]
164
- ) -> None:
165
- """Prepare the training directory for a new training session."""
166
- encoded_training_data = data.get("bot_config", {}).get("data", {})
167
-
168
- # create a new working directory and store the training data from the
169
- # request there. the training data in the request is base64 encoded
170
- os.makedirs(training_base_path, exist_ok=True)
171
-
172
- seed_training_directory_with_rasa_cache(training_base_path, assistant_id)
173
- write_training_data_to_files(encoded_training_data, training_base_path)
174
-
175
-
176
- def start_training_process(
177
- training_id: str, assistant_id: str, client_id: str, training_base_path: str
178
- ) -> TrainingSession:
179
- log_path = logs_path(training_id)
180
-
181
- # Start the training in a subprocess
182
- # set the working directory to the training directory
183
- # run the rasa train command as a subprocess, activating poetry before running
184
- # pipe the stdout and stderr to the same file
185
- process = subprocess.Popen(
186
- [
187
- RASA_PYTHON_PATH,
188
- "-m",
189
- "rasa.__main__",
190
- "train",
191
- "--debug",
192
- "--out",
193
- f"{training_base_path}/models",
194
- "--data",
195
- f"{training_base_path}/data",
196
- "--config",
197
- f"{training_base_path}/config.yml",
198
- "--domain",
199
- f"{training_base_path}/domain.yml",
200
- "--endpoints",
201
- f"{training_base_path}/endpoints.yml",
202
- ],
203
- cwd=training_base_path,
204
- stdout=open(log_path, "w"),
205
- stderr=subprocess.STDOUT,
206
- env=os.environ.copy(),
207
- )
208
-
209
- structlogger.info(
210
- "model_trainer.training_started",
211
- training_id=training_id,
212
- assistant_id=assistant_id,
213
- client_id=client_id,
214
- log=log_path,
215
- pid=process.pid,
216
- )
217
-
218
- return TrainingSession(
219
- training_id=training_id,
220
- assistant_id=assistant_id,
221
- client_id=client_id,
222
- progress=0,
223
- status="running",
224
- process=process, # Store the process handle
225
- )
226
-
227
-
228
- def run_training(
229
- training_id: str, assistant_id: str, client_id: str, data: Dict
230
- ) -> TrainingSession:
231
- """Run a training session."""
232
- training_base_path = train_path(training_id)
233
-
234
- prepare_training_directory(training_base_path, assistant_id, data)
235
- return start_training_process(
236
- training_id=training_id,
237
- assistant_id=assistant_id,
238
- client_id=client_id,
239
- training_base_path=training_base_path,
240
- )
@@ -1,27 +0,0 @@
1
- import os
2
-
3
- from rasa.model_manager.config import SERVER_BASE_WORKING_DIRECTORY
4
-
5
-
6
- def logs_base_path() -> str:
7
- """Return the path to the logs directory."""
8
- return os.path.abspath(f"{SERVER_BASE_WORKING_DIRECTORY}/logs")
9
-
10
-
11
- def models_base_path() -> str:
12
- """Return the path to the models directory."""
13
- return os.path.abspath(f"{SERVER_BASE_WORKING_DIRECTORY}/models")
14
-
15
-
16
- def logs_path(action_id: str) -> str:
17
- """Return the path to the log file for a given action id.
18
-
19
- Args:
20
- action_id: can either be a training_id or a deployment_id
21
- """
22
- return os.path.abspath(f"{logs_base_path()}/{action_id}.txt")
23
-
24
-
25
- def models_path(training_id: str) -> str:
26
- """Return the path to the models directory for a given training id."""
27
- return os.path.abspath(f"{models_base_path()}/{training_id}")
rasa/model_service.py DELETED
@@ -1,66 +0,0 @@
1
- import os
2
- import logging
3
-
4
- from sanic import Sanic
5
- import structlog
6
-
7
- from rasa.core.utils import list_routes
8
- from rasa.model_manager import model_api
9
- from rasa.model_manager.config import SERVER_BASE_URL
10
- from rasa.utils.common import configure_logging_and_warnings
11
- import rasa.utils.licensing
12
-
13
- structlogger = structlog.get_logger()
14
-
15
- MODEL_SERVICE_PORT = 8000
16
-
17
-
18
- def url_prefix_from_base_url() -> str:
19
- """Return the path prefix from the base URL."""
20
- if SERVER_BASE_URL:
21
- from urllib.parse import urlparse
22
-
23
- return urlparse(SERVER_BASE_URL).path
24
-
25
- return ""
26
-
27
-
28
- def main() -> None:
29
- """Start the Rasa Model Manager server.
30
-
31
- The API server can receive requests to train models, run bots, and manage
32
- the lifecycle of models and bots.
33
- """
34
- model_api.prepare_working_directories()
35
-
36
- configure_logging_and_warnings(
37
- log_level=logging.DEBUG,
38
- logging_config_file=None,
39
- warn_only_once=True,
40
- filter_repeated_logs=True,
41
- )
42
-
43
- rasa.utils.licensing.validate_license_from_env()
44
- # assert that an openai api key is set
45
- assert (
46
- "OPENAI_API_KEY" in os.environ
47
- ), "Please set the OPENAI_API_KEY environment variable"
48
-
49
- structlogger.debug("model_training.starting_server", port=MODEL_SERVICE_PORT)
50
- structlogger.debug("model_running.starting_server", port=MODEL_SERVICE_PORT)
51
-
52
- url_prefix = url_prefix_from_base_url()
53
- # configure the sanice application
54
- app = Sanic("RasaModelService")
55
- app.add_task(model_api.continuously_update_process_status)
56
- app.blueprint(model_api.external_blueprint(), url_prefix=url_prefix)
57
- app.blueprint(model_api.internal_blueprint())
58
-
59
- # list all routes
60
- list_routes(app)
61
-
62
- app.run(host="0.0.0.0", port=MODEL_SERVICE_PORT, legacy=True)
63
-
64
-
65
- if __name__ == "__main__":
66
- main()