rasa-pro 3.13.0a1.dev6__py3-none-any.whl → 3.13.0a1.dev7__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/builder/README.md +120 -0
- rasa/builder/config.py +69 -0
- rasa/builder/create_openai_vector_store.py +204 -45
- rasa/builder/exceptions.py +49 -0
- rasa/builder/llm_service.py +327 -0
- rasa/builder/logging_utils.py +51 -0
- rasa/builder/main.py +61 -0
- rasa/builder/models.py +174 -0
- rasa/builder/project_generator.py +264 -0
- rasa/builder/service.py +447 -0
- rasa/builder/skill_to_bot_prompt.jinja2 +6 -1
- rasa/builder/training_service.py +123 -0
- rasa/builder/validation_service.py +79 -0
- rasa/cli/project_templates/finance/config.yml +17 -0
- rasa/cli/project_templates/finance/credentials.yml +33 -0
- rasa/cli/project_templates/finance/data/flows/transfer_money.yml +5 -0
- rasa/cli/project_templates/finance/data/patterns/pattern_session_start.yml +7 -0
- rasa/cli/project_templates/finance/domain.yml +7 -0
- rasa/cli/project_templates/finance/endpoints.yml +58 -0
- rasa/cli/project_templates/plain/config.yml +17 -0
- rasa/cli/project_templates/plain/credentials.yml +33 -0
- rasa/cli/project_templates/plain/data/patterns/pattern_session_start.yml +7 -0
- rasa/cli/project_templates/plain/domain.yml +5 -0
- rasa/cli/project_templates/plain/endpoints.yml +58 -0
- rasa/cli/project_templates/telecom/config.yml +17 -0
- rasa/cli/project_templates/telecom/credentials.yml +33 -0
- rasa/cli/project_templates/telecom/data/flows/upgrade_contract.yml +5 -0
- rasa/cli/project_templates/telecom/data/patterns/pattern_session_start.yml +7 -0
- rasa/cli/project_templates/telecom/domain.yml +7 -0
- rasa/cli/project_templates/telecom/endpoints.yml +58 -0
- rasa/cli/scaffold.py +19 -3
- rasa/core/actions/action.py +5 -3
- rasa/model_manager/model_api.py +1 -1
- rasa/model_manager/runner_service.py +1 -1
- rasa/model_manager/trainer_service.py +1 -1
- rasa/model_manager/utils.py +1 -29
- rasa/shared/core/domain.py +62 -15
- rasa/shared/core/flows/yaml_flows_io.py +16 -8
- rasa/telemetry.py +2 -1
- rasa/utils/io.py +27 -9
- rasa/version.py +1 -1
- {rasa_pro-3.13.0a1.dev6.dist-info → rasa_pro-3.13.0a1.dev7.dist-info}/METADATA +1 -1
- {rasa_pro-3.13.0a1.dev6.dist-info → rasa_pro-3.13.0a1.dev7.dist-info}/RECORD +46 -19
- rasa/builder/prompt_to_bot.py +0 -650
- {rasa_pro-3.13.0a1.dev6.dist-info → rasa_pro-3.13.0a1.dev7.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.0a1.dev6.dist-info → rasa_pro-3.13.0a1.dev7.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.0a1.dev6.dist-info → rasa_pro-3.13.0a1.dev7.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This file contains the credentials for the voice & chat platforms
|
|
2
|
+
# which your bot is using.
|
|
3
|
+
# https://rasa.com/docs/rasa-pro/connectors/messaging-and-voice-channels/
|
|
4
|
+
|
|
5
|
+
rest:
|
|
6
|
+
# # you don't need to provide anything here - this channel doesn't
|
|
7
|
+
# # require any credentials
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#facebook:
|
|
11
|
+
# verify: "<verify>"
|
|
12
|
+
# secret: "<your secret>"
|
|
13
|
+
# page-access-token: "<your page access token>"
|
|
14
|
+
|
|
15
|
+
#slack:
|
|
16
|
+
# slack_token: "<your slack token>"
|
|
17
|
+
# slack_channel: "<the slack channel>"
|
|
18
|
+
# slack_signing_secret: "<your slack signing secret>"
|
|
19
|
+
|
|
20
|
+
#socketio:
|
|
21
|
+
# user_message_evt: <event name for user message>
|
|
22
|
+
# bot_message_evt: <event name for bot messages>
|
|
23
|
+
# session_persistence: <true/false>
|
|
24
|
+
|
|
25
|
+
#mattermost:
|
|
26
|
+
# url: "https://<mattermost instance>/api/v4"
|
|
27
|
+
# token: "<bot token>"
|
|
28
|
+
# webhook_url: "<callback URL>"
|
|
29
|
+
|
|
30
|
+
# This entry is needed if you are using Rasa Enterprise. The entry represents credentials
|
|
31
|
+
# for the Rasa Enterprise "channel", i.e. Talk to your bot and Share with guest testers.
|
|
32
|
+
rasa:
|
|
33
|
+
url: "http://localhost:5002/api"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# This file contains the different endpoints your bot can use.
|
|
2
|
+
|
|
3
|
+
# Server where the models are pulled from.
|
|
4
|
+
# https://rasa.com/docs/rasa-pro/production/model-storage#fetching-models-from-a-server
|
|
5
|
+
|
|
6
|
+
#models:
|
|
7
|
+
# url: http://my-server.com/models/default_core@latest
|
|
8
|
+
# wait_time_between_pulls: 10 # [optional](default: 100)
|
|
9
|
+
|
|
10
|
+
# Server which runs your custom actions.
|
|
11
|
+
# https://rasa.com/docs/rasa-pro/concepts/custom-actions
|
|
12
|
+
|
|
13
|
+
action_endpoint:
|
|
14
|
+
actions_module: "actions"
|
|
15
|
+
|
|
16
|
+
# Tracker store which is used to store the conversations.
|
|
17
|
+
# By default the conversations are stored in memory.
|
|
18
|
+
# https://rasa.com/docs/rasa-pro/production/tracker-stores
|
|
19
|
+
|
|
20
|
+
#tracker_store:
|
|
21
|
+
# type: redis
|
|
22
|
+
# url: <host of the redis instance, e.g. localhost>
|
|
23
|
+
# port: <port of your redis instance, usually 6379>
|
|
24
|
+
# db: <number of your database within redis, e.g. 0>
|
|
25
|
+
# password: <password used for authentication>
|
|
26
|
+
# use_ssl: <whether or not the communication is encrypted, default false>
|
|
27
|
+
|
|
28
|
+
#tracker_store:
|
|
29
|
+
# type: mongod
|
|
30
|
+
# url: <url to your mongo instance, e.g. mongodb://localhost:27017>
|
|
31
|
+
# db: <name of the db within your mongo instance, e.g. rasa>
|
|
32
|
+
# username: <username used for authentication>
|
|
33
|
+
# password: <password used for authentication>
|
|
34
|
+
|
|
35
|
+
# Event broker which all conversation events should be streamed to.
|
|
36
|
+
# https://rasa.com/docs/rasa-pro/production/event-brokers
|
|
37
|
+
|
|
38
|
+
#event_broker:
|
|
39
|
+
# url: localhost
|
|
40
|
+
# username: username
|
|
41
|
+
# password: password
|
|
42
|
+
# queue: queue
|
|
43
|
+
|
|
44
|
+
# The lines below activate contextual rephrasing, using the default OpenAI language model.
|
|
45
|
+
# Ensure the OPENAI_API_KEY is set to prevent any missing API key errors.
|
|
46
|
+
# For more details, refer to the documentation:
|
|
47
|
+
# https://rasa.com/docs/rasa-pro/concepts/contextual-response-rephraser
|
|
48
|
+
# To enable the rephraser, remove the comment symbols in the lines below.
|
|
49
|
+
#nlg:
|
|
50
|
+
# type: rephrase
|
|
51
|
+
|
|
52
|
+
model_groups:
|
|
53
|
+
- id: openai-gpt-4o
|
|
54
|
+
models:
|
|
55
|
+
- provider: openai
|
|
56
|
+
model: gpt-4o-2024-11-20
|
|
57
|
+
request_timeout: 7
|
|
58
|
+
max_tokens: 256
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# The config recipe.
|
|
2
|
+
recipe: default.v1
|
|
3
|
+
|
|
4
|
+
# The assistant project unique identifier
|
|
5
|
+
# This default value must be replaced with a unique assistant name within your deployment
|
|
6
|
+
assistant_id: placeholder_default
|
|
7
|
+
|
|
8
|
+
language: en
|
|
9
|
+
pipeline:
|
|
10
|
+
- name: CompactLLMCommandGenerator
|
|
11
|
+
llm:
|
|
12
|
+
model_group: openai-gpt-4o
|
|
13
|
+
|
|
14
|
+
# Configuration for Rasa Core.
|
|
15
|
+
policies:
|
|
16
|
+
- name: FlowPolicy
|
|
17
|
+
- name: IntentlessPolicy
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This file contains the credentials for the voice & chat platforms
|
|
2
|
+
# which your bot is using.
|
|
3
|
+
# https://rasa.com/docs/rasa-pro/connectors/messaging-and-voice-channels/
|
|
4
|
+
|
|
5
|
+
rest:
|
|
6
|
+
# # you don't need to provide anything here - this channel doesn't
|
|
7
|
+
# # require any credentials
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#facebook:
|
|
11
|
+
# verify: "<verify>"
|
|
12
|
+
# secret: "<your secret>"
|
|
13
|
+
# page-access-token: "<your page access token>"
|
|
14
|
+
|
|
15
|
+
#slack:
|
|
16
|
+
# slack_token: "<your slack token>"
|
|
17
|
+
# slack_channel: "<the slack channel>"
|
|
18
|
+
# slack_signing_secret: "<your slack signing secret>"
|
|
19
|
+
|
|
20
|
+
#socketio:
|
|
21
|
+
# user_message_evt: <event name for user message>
|
|
22
|
+
# bot_message_evt: <event name for bot messages>
|
|
23
|
+
# session_persistence: <true/false>
|
|
24
|
+
|
|
25
|
+
#mattermost:
|
|
26
|
+
# url: "https://<mattermost instance>/api/v4"
|
|
27
|
+
# token: "<bot token>"
|
|
28
|
+
# webhook_url: "<callback URL>"
|
|
29
|
+
|
|
30
|
+
# This entry is needed if you are using Rasa Enterprise. The entry represents credentials
|
|
31
|
+
# for the Rasa Enterprise "channel", i.e. Talk to your bot and Share with guest testers.
|
|
32
|
+
rasa:
|
|
33
|
+
url: "http://localhost:5002/api"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# This file contains the different endpoints your bot can use.
|
|
2
|
+
|
|
3
|
+
# Server where the models are pulled from.
|
|
4
|
+
# https://rasa.com/docs/rasa-pro/production/model-storage#fetching-models-from-a-server
|
|
5
|
+
|
|
6
|
+
#models:
|
|
7
|
+
# url: http://my-server.com/models/default_core@latest
|
|
8
|
+
# wait_time_between_pulls: 10 # [optional](default: 100)
|
|
9
|
+
|
|
10
|
+
# Server which runs your custom actions.
|
|
11
|
+
# https://rasa.com/docs/rasa-pro/concepts/custom-actions
|
|
12
|
+
|
|
13
|
+
action_endpoint:
|
|
14
|
+
actions_module: "actions"
|
|
15
|
+
|
|
16
|
+
# Tracker store which is used to store the conversations.
|
|
17
|
+
# By default the conversations are stored in memory.
|
|
18
|
+
# https://rasa.com/docs/rasa-pro/production/tracker-stores
|
|
19
|
+
|
|
20
|
+
#tracker_store:
|
|
21
|
+
# type: redis
|
|
22
|
+
# url: <host of the redis instance, e.g. localhost>
|
|
23
|
+
# port: <port of your redis instance, usually 6379>
|
|
24
|
+
# db: <number of your database within redis, e.g. 0>
|
|
25
|
+
# password: <password used for authentication>
|
|
26
|
+
# use_ssl: <whether or not the communication is encrypted, default false>
|
|
27
|
+
|
|
28
|
+
#tracker_store:
|
|
29
|
+
# type: mongod
|
|
30
|
+
# url: <url to your mongo instance, e.g. mongodb://localhost:27017>
|
|
31
|
+
# db: <name of the db within your mongo instance, e.g. rasa>
|
|
32
|
+
# username: <username used for authentication>
|
|
33
|
+
# password: <password used for authentication>
|
|
34
|
+
|
|
35
|
+
# Event broker which all conversation events should be streamed to.
|
|
36
|
+
# https://rasa.com/docs/rasa-pro/production/event-brokers
|
|
37
|
+
|
|
38
|
+
#event_broker:
|
|
39
|
+
# url: localhost
|
|
40
|
+
# username: username
|
|
41
|
+
# password: password
|
|
42
|
+
# queue: queue
|
|
43
|
+
|
|
44
|
+
# The lines below activate contextual rephrasing, using the default OpenAI language model.
|
|
45
|
+
# Ensure the OPENAI_API_KEY is set to prevent any missing API key errors.
|
|
46
|
+
# For more details, refer to the documentation:
|
|
47
|
+
# https://rasa.com/docs/rasa-pro/concepts/contextual-response-rephraser
|
|
48
|
+
# To enable the rephraser, remove the comment symbols in the lines below.
|
|
49
|
+
#nlg:
|
|
50
|
+
# type: rephrase
|
|
51
|
+
|
|
52
|
+
model_groups:
|
|
53
|
+
- id: openai-gpt-4o
|
|
54
|
+
models:
|
|
55
|
+
- provider: openai
|
|
56
|
+
model: gpt-4o-2024-11-20
|
|
57
|
+
request_timeout: 7
|
|
58
|
+
max_tokens: 256
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# The config recipe.
|
|
2
|
+
recipe: default.v1
|
|
3
|
+
|
|
4
|
+
# The assistant project unique identifier
|
|
5
|
+
# This default value must be replaced with a unique assistant name within your deployment
|
|
6
|
+
assistant_id: placeholder_default
|
|
7
|
+
|
|
8
|
+
language: en
|
|
9
|
+
pipeline:
|
|
10
|
+
- name: CompactLLMCommandGenerator
|
|
11
|
+
llm:
|
|
12
|
+
model_group: openai-gpt-4o
|
|
13
|
+
|
|
14
|
+
# Configuration for Rasa Core.
|
|
15
|
+
policies:
|
|
16
|
+
- name: FlowPolicy
|
|
17
|
+
- name: IntentlessPolicy
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This file contains the credentials for the voice & chat platforms
|
|
2
|
+
# which your bot is using.
|
|
3
|
+
# https://rasa.com/docs/rasa-pro/connectors/messaging-and-voice-channels/
|
|
4
|
+
|
|
5
|
+
rest:
|
|
6
|
+
# # you don't need to provide anything here - this channel doesn't
|
|
7
|
+
# # require any credentials
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#facebook:
|
|
11
|
+
# verify: "<verify>"
|
|
12
|
+
# secret: "<your secret>"
|
|
13
|
+
# page-access-token: "<your page access token>"
|
|
14
|
+
|
|
15
|
+
#slack:
|
|
16
|
+
# slack_token: "<your slack token>"
|
|
17
|
+
# slack_channel: "<the slack channel>"
|
|
18
|
+
# slack_signing_secret: "<your slack signing secret>"
|
|
19
|
+
|
|
20
|
+
#socketio:
|
|
21
|
+
# user_message_evt: <event name for user message>
|
|
22
|
+
# bot_message_evt: <event name for bot messages>
|
|
23
|
+
# session_persistence: <true/false>
|
|
24
|
+
|
|
25
|
+
#mattermost:
|
|
26
|
+
# url: "https://<mattermost instance>/api/v4"
|
|
27
|
+
# token: "<bot token>"
|
|
28
|
+
# webhook_url: "<callback URL>"
|
|
29
|
+
|
|
30
|
+
# This entry is needed if you are using Rasa Enterprise. The entry represents credentials
|
|
31
|
+
# for the Rasa Enterprise "channel", i.e. Talk to your bot and Share with guest testers.
|
|
32
|
+
rasa:
|
|
33
|
+
url: "http://localhost:5002/api"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# This file contains the different endpoints your bot can use.
|
|
2
|
+
|
|
3
|
+
# Server where the models are pulled from.
|
|
4
|
+
# https://rasa.com/docs/rasa-pro/production/model-storage#fetching-models-from-a-server
|
|
5
|
+
|
|
6
|
+
#models:
|
|
7
|
+
# url: http://my-server.com/models/default_core@latest
|
|
8
|
+
# wait_time_between_pulls: 10 # [optional](default: 100)
|
|
9
|
+
|
|
10
|
+
# Server which runs your custom actions.
|
|
11
|
+
# https://rasa.com/docs/rasa-pro/concepts/custom-actions
|
|
12
|
+
|
|
13
|
+
action_endpoint:
|
|
14
|
+
actions_module: "actions"
|
|
15
|
+
|
|
16
|
+
# Tracker store which is used to store the conversations.
|
|
17
|
+
# By default the conversations are stored in memory.
|
|
18
|
+
# https://rasa.com/docs/rasa-pro/production/tracker-stores
|
|
19
|
+
|
|
20
|
+
#tracker_store:
|
|
21
|
+
# type: redis
|
|
22
|
+
# url: <host of the redis instance, e.g. localhost>
|
|
23
|
+
# port: <port of your redis instance, usually 6379>
|
|
24
|
+
# db: <number of your database within redis, e.g. 0>
|
|
25
|
+
# password: <password used for authentication>
|
|
26
|
+
# use_ssl: <whether or not the communication is encrypted, default false>
|
|
27
|
+
|
|
28
|
+
#tracker_store:
|
|
29
|
+
# type: mongod
|
|
30
|
+
# url: <url to your mongo instance, e.g. mongodb://localhost:27017>
|
|
31
|
+
# db: <name of the db within your mongo instance, e.g. rasa>
|
|
32
|
+
# username: <username used for authentication>
|
|
33
|
+
# password: <password used for authentication>
|
|
34
|
+
|
|
35
|
+
# Event broker which all conversation events should be streamed to.
|
|
36
|
+
# https://rasa.com/docs/rasa-pro/production/event-brokers
|
|
37
|
+
|
|
38
|
+
#event_broker:
|
|
39
|
+
# url: localhost
|
|
40
|
+
# username: username
|
|
41
|
+
# password: password
|
|
42
|
+
# queue: queue
|
|
43
|
+
|
|
44
|
+
# The lines below activate contextual rephrasing, using the default OpenAI language model.
|
|
45
|
+
# Ensure the OPENAI_API_KEY is set to prevent any missing API key errors.
|
|
46
|
+
# For more details, refer to the documentation:
|
|
47
|
+
# https://rasa.com/docs/rasa-pro/concepts/contextual-response-rephraser
|
|
48
|
+
# To enable the rephraser, remove the comment symbols in the lines below.
|
|
49
|
+
#nlg:
|
|
50
|
+
# type: rephrase
|
|
51
|
+
|
|
52
|
+
model_groups:
|
|
53
|
+
- id: openai-gpt-4o
|
|
54
|
+
models:
|
|
55
|
+
- provider: openai
|
|
56
|
+
model: gpt-4o-2024-11-20
|
|
57
|
+
request_timeout: 7
|
|
58
|
+
max_tokens: 256
|
rasa/cli/scaffold.py
CHANGED
|
@@ -24,10 +24,21 @@ class ProjectTemplateName(Enum):
|
|
|
24
24
|
|
|
25
25
|
DEFAULT = "default"
|
|
26
26
|
TUTORIAL = "tutorial"
|
|
27
|
+
PLAIN = "plain"
|
|
28
|
+
FINANCE = "finance"
|
|
29
|
+
TELECOM = "telecom"
|
|
27
30
|
|
|
28
31
|
def __str__(self) -> str:
|
|
29
32
|
return self.value
|
|
30
33
|
|
|
34
|
+
@classmethod
|
|
35
|
+
def get_all_values(cls) -> List[str]:
|
|
36
|
+
return [name.value for name in cls]
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def supported_values(cls) -> str:
|
|
40
|
+
return ", ".join(cls.get_all_values())
|
|
41
|
+
|
|
31
42
|
|
|
32
43
|
template_domain_path = defaultdict(lambda: DEFAULT_DOMAIN_PATH)
|
|
33
44
|
template_domain_path[ProjectTemplateName.DEFAULT] = "domain"
|
|
@@ -159,9 +170,14 @@ def create_initial_project(
|
|
|
159
170
|
path: Text, template: ProjectTemplateName = ProjectTemplateName.DEFAULT
|
|
160
171
|
) -> None:
|
|
161
172
|
"""Creates directory structure and templates for initial project."""
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
copy_tree
|
|
173
|
+
import distutils.dir_util as dir_util
|
|
174
|
+
|
|
175
|
+
# clear the cache of the copy_tree function, this avoids issues if
|
|
176
|
+
# a project directory existed before and we removed folders in it
|
|
177
|
+
# with shutil.rmtree. see
|
|
178
|
+
# https://stackoverflow.com/questions/9160227/dir-util-copy-tree-fails-after-shutil-rmtree
|
|
179
|
+
dir_util._path_created.clear()
|
|
180
|
+
dir_util.copy_tree(scaffold_path(template), path)
|
|
165
181
|
|
|
166
182
|
|
|
167
183
|
def scaffold_path(template: ProjectTemplateName) -> Text:
|
rasa/core/actions/action.py
CHANGED
|
@@ -908,10 +908,12 @@ class RemoteAction(Action):
|
|
|
908
908
|
draft.setdefault("buttons", [])
|
|
909
909
|
draft["buttons"].extend(buttons)
|
|
910
910
|
|
|
911
|
-
# Avoid overwriting `draft` values with empty values
|
|
912
911
|
response = {k: v for k, v in response.items() if v}
|
|
913
|
-
|
|
914
|
-
|
|
912
|
+
|
|
913
|
+
response.update(draft)
|
|
914
|
+
bot_messages.append(
|
|
915
|
+
create_bot_utterance(response, tracker.current_language)
|
|
916
|
+
)
|
|
915
917
|
|
|
916
918
|
return bot_messages
|
|
917
919
|
|
rasa/model_manager/model_api.py
CHANGED
|
@@ -43,7 +43,6 @@ from rasa.model_manager.utils import (
|
|
|
43
43
|
get_logs_content,
|
|
44
44
|
logs_base_path,
|
|
45
45
|
models_base_path,
|
|
46
|
-
subpath,
|
|
47
46
|
)
|
|
48
47
|
from rasa.model_manager.warm_rasa_process import (
|
|
49
48
|
initialize_warm_rasa_process,
|
|
@@ -53,6 +52,7 @@ from rasa.server import ErrorResponse
|
|
|
53
52
|
from rasa.shared.exceptions import InvalidConfigException
|
|
54
53
|
from rasa.shared.utils.yaml import dump_obj_as_yaml_to_string
|
|
55
54
|
from rasa.studio.upload import build_calm_import_parts
|
|
55
|
+
from rasa.utils.io import subpath
|
|
56
56
|
|
|
57
57
|
dotenv.load_dotenv()
|
|
58
58
|
|
|
@@ -14,10 +14,10 @@ from rasa.model_manager import config
|
|
|
14
14
|
from rasa.model_manager.utils import (
|
|
15
15
|
logs_path,
|
|
16
16
|
models_base_path,
|
|
17
|
-
subpath,
|
|
18
17
|
write_encoded_data_to_file,
|
|
19
18
|
)
|
|
20
19
|
from rasa.model_manager.warm_rasa_process import start_rasa_process
|
|
20
|
+
from rasa.utils.io import subpath
|
|
21
21
|
|
|
22
22
|
structlogger = structlog.get_logger()
|
|
23
23
|
|
|
@@ -13,13 +13,13 @@ from rasa.model_manager.utils import (
|
|
|
13
13
|
ensure_base_directory_exists,
|
|
14
14
|
logs_path,
|
|
15
15
|
models_base_path,
|
|
16
|
-
subpath,
|
|
17
16
|
write_encoded_data_to_file,
|
|
18
17
|
)
|
|
19
18
|
from rasa.model_manager.warm_rasa_process import (
|
|
20
19
|
start_rasa_process,
|
|
21
20
|
)
|
|
22
21
|
from rasa.model_training import generate_random_model_name
|
|
22
|
+
from rasa.utils.io import subpath
|
|
23
23
|
|
|
24
24
|
structlogger = structlog.get_logger()
|
|
25
25
|
|
rasa/model_manager/utils.py
CHANGED
|
@@ -5,15 +5,11 @@ from typing import Optional
|
|
|
5
5
|
import structlog
|
|
6
6
|
|
|
7
7
|
from rasa.model_manager import config
|
|
8
|
-
from rasa.
|
|
8
|
+
from rasa.utils.io import subpath
|
|
9
9
|
|
|
10
10
|
structlogger = structlog.get_logger()
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class InvalidPathException(RasaException):
|
|
14
|
-
"""Raised if a path is invalid - e.g. path traversal is detected."""
|
|
15
|
-
|
|
16
|
-
|
|
17
13
|
def write_encoded_data_to_file(encoded_data: bytes, file: str) -> None:
|
|
18
14
|
"""Write base64 encoded data to a file."""
|
|
19
15
|
# create the directory if it does not exist of the parent directory
|
|
@@ -53,30 +49,6 @@ def logs_path(action_id: str) -> str:
|
|
|
53
49
|
return subpath(logs_base_path(), f"{action_id}.txt")
|
|
54
50
|
|
|
55
51
|
|
|
56
|
-
def subpath(parent: str, child: str) -> str:
|
|
57
|
-
"""Return the path to the child directory of the parent directory.
|
|
58
|
-
|
|
59
|
-
Ensures, that child doesn't navigate to parent directories. Prevents
|
|
60
|
-
path traversal. Raises an InvalidPathException if the path is invalid.
|
|
61
|
-
|
|
62
|
-
Based on Snyk's directory traversal mitigation:
|
|
63
|
-
https://learn.snyk.io/lesson/directory-traversal/
|
|
64
|
-
"""
|
|
65
|
-
safe_path = os.path.abspath(os.path.join(parent, child))
|
|
66
|
-
parent = os.path.abspath(parent)
|
|
67
|
-
|
|
68
|
-
common_base = os.path.commonpath([parent, safe_path])
|
|
69
|
-
if common_base != parent:
|
|
70
|
-
raise InvalidPathException(f"Invalid path: {safe_path}")
|
|
71
|
-
|
|
72
|
-
if os.path.basename(safe_path) != child:
|
|
73
|
-
raise InvalidPathException(
|
|
74
|
-
f"Invalid path - path traversal detected: {safe_path}"
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
return safe_path
|
|
78
|
-
|
|
79
|
-
|
|
80
52
|
def get_logs_content(action_id: str) -> Optional[str]:
|
|
81
53
|
"""Return the content of the log file for a given action id."""
|
|
82
54
|
try:
|
rasa/shared/core/domain.py
CHANGED
|
@@ -98,6 +98,8 @@ IS_RETRIEVAL_INTENT_KEY = "is_retrieval_intent"
|
|
|
98
98
|
ENTITY_ROLES_KEY = "roles"
|
|
99
99
|
ENTITY_GROUPS_KEY = "groups"
|
|
100
100
|
ENTITY_FEATURIZATION_KEY = "influence_conversation"
|
|
101
|
+
STORE_ENTITIES_AS_SLOTS_KEY = "store_entities_as_slots"
|
|
102
|
+
DOMAIN_CONFIG_KEY = "config"
|
|
101
103
|
|
|
102
104
|
KEY_SLOTS = "slots"
|
|
103
105
|
KEY_INTENTS = "intents"
|
|
@@ -146,6 +148,8 @@ MERGE_FUNC_MAPPING: Dict[Text, Callable[..., Any]] = {
|
|
|
146
148
|
KEY_FORMS: rasa.shared.utils.common.merge_dicts,
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
DEFAULT_STORE_ENTITIES_AS_SLOTS = True
|
|
152
|
+
|
|
149
153
|
DICT_DATA_KEYS = [
|
|
150
154
|
key
|
|
151
155
|
for key, value in MERGE_FUNC_MAPPING.items()
|
|
@@ -318,7 +322,7 @@ class Domain:
|
|
|
318
322
|
actions = cls._collect_action_names(domain_actions)
|
|
319
323
|
|
|
320
324
|
additional_arguments = {
|
|
321
|
-
**data.get(
|
|
325
|
+
**data.get(DOMAIN_CONFIG_KEY, {}),
|
|
322
326
|
"actions_which_explicitly_need_domain": (
|
|
323
327
|
cls._collect_actions_which_explicitly_need_domain(domain_actions)
|
|
324
328
|
),
|
|
@@ -468,9 +472,9 @@ class Domain:
|
|
|
468
472
|
return domain_dict
|
|
469
473
|
|
|
470
474
|
if override:
|
|
471
|
-
config = domain_dict.get(
|
|
475
|
+
config = domain_dict.get(DOMAIN_CONFIG_KEY, {})
|
|
472
476
|
for key, val in config.items():
|
|
473
|
-
combined[
|
|
477
|
+
combined[DOMAIN_CONFIG_KEY][key] = val
|
|
474
478
|
|
|
475
479
|
if (
|
|
476
480
|
override
|
|
@@ -508,10 +512,10 @@ class Domain:
|
|
|
508
512
|
return combined
|
|
509
513
|
|
|
510
514
|
def partial_merge(self, other: Domain) -> Domain:
|
|
511
|
-
"""
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
+
"""Returns a new Domain with intersection-based merging.
|
|
516
|
+
|
|
517
|
+
For each domain section only overwrite items that already exist in self.
|
|
518
|
+
Brand-new items in `other` are ignored.
|
|
515
519
|
|
|
516
520
|
Args:
|
|
517
521
|
other: The domain to merge with.
|
|
@@ -543,9 +547,9 @@ class Domain:
|
|
|
543
547
|
return Domain.from_dict(updated_self)
|
|
544
548
|
|
|
545
549
|
def difference(self, other: Domain) -> Domain:
|
|
546
|
-
"""
|
|
547
|
-
|
|
548
|
-
|
|
550
|
+
"""Returns a new Domain containing items in `self` that are NOT in `other`.
|
|
551
|
+
|
|
552
|
+
Uses simple equality checks for dict/list items.
|
|
549
553
|
|
|
550
554
|
Args:
|
|
551
555
|
other: The domain to compare with.
|
|
@@ -598,9 +602,16 @@ class Domain:
|
|
|
598
602
|
) -> Dict:
|
|
599
603
|
# add the config, session_config and training data version defaults
|
|
600
604
|
# if not included in the original domain dict
|
|
601
|
-
if
|
|
605
|
+
if (
|
|
606
|
+
DOMAIN_CONFIG_KEY not in data
|
|
607
|
+
and store_entities_as_slots != DEFAULT_STORE_ENTITIES_AS_SLOTS
|
|
608
|
+
):
|
|
602
609
|
data.update(
|
|
603
|
-
{
|
|
610
|
+
{
|
|
611
|
+
DOMAIN_CONFIG_KEY: {
|
|
612
|
+
STORE_ENTITIES_AS_SLOTS_KEY: store_entities_as_slots
|
|
613
|
+
}
|
|
614
|
+
}
|
|
604
615
|
)
|
|
605
616
|
|
|
606
617
|
if SESSION_CONFIG_KEY not in data:
|
|
@@ -937,7 +948,7 @@ class Domain:
|
|
|
937
948
|
forms: Union[Dict[Text, Any], List[Text]],
|
|
938
949
|
data: Dict,
|
|
939
950
|
action_texts: Optional[List[Text]] = None,
|
|
940
|
-
store_entities_as_slots: bool =
|
|
951
|
+
store_entities_as_slots: bool = DEFAULT_STORE_ENTITIES_AS_SLOTS,
|
|
941
952
|
session_config: SessionConfig = SessionConfig.default(),
|
|
942
953
|
**kwargs: Any,
|
|
943
954
|
) -> None:
|
|
@@ -1711,9 +1722,45 @@ class Domain:
|
|
|
1711
1722
|
else:
|
|
1712
1723
|
return True
|
|
1713
1724
|
|
|
1714
|
-
def
|
|
1725
|
+
def _uses_custom_session_config(self) -> bool:
|
|
1726
|
+
"""Check if the domain uses a custom session config."""
|
|
1727
|
+
return self._data.get(SESSION_CONFIG_KEY) != SessionConfig.default().as_dict()
|
|
1728
|
+
|
|
1729
|
+
def _uses_custom_domain_config(self) -> bool:
|
|
1730
|
+
"""Check if the domain uses a custom domain config."""
|
|
1731
|
+
return self._data.get(DOMAIN_CONFIG_KEY) != {
|
|
1732
|
+
STORE_ENTITIES_AS_SLOTS_KEY: DEFAULT_STORE_ENTITIES_AS_SLOTS
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
def _cleaned_json_data(self) -> Dict[Text, Any]:
|
|
1736
|
+
"""Remove default values from the domain data.
|
|
1737
|
+
|
|
1738
|
+
Only retains data that was customized by the user.
|
|
1739
|
+
|
|
1740
|
+
Returns:
|
|
1741
|
+
A cleaned dictionary version of the domain.
|
|
1742
|
+
"""
|
|
1743
|
+
cleaned_data = copy.deepcopy(self._data)
|
|
1744
|
+
|
|
1745
|
+
# Remove default config if it only contains store_entities_as_slots: False
|
|
1746
|
+
if DOMAIN_CONFIG_KEY in cleaned_data and not self._uses_custom_domain_config():
|
|
1747
|
+
del cleaned_data[DOMAIN_CONFIG_KEY]
|
|
1748
|
+
|
|
1749
|
+
# Remove default session config if it matches the default values
|
|
1750
|
+
if (
|
|
1751
|
+
SESSION_CONFIG_KEY in cleaned_data
|
|
1752
|
+
and not self._uses_custom_session_config()
|
|
1753
|
+
):
|
|
1754
|
+
del cleaned_data[SESSION_CONFIG_KEY]
|
|
1755
|
+
|
|
1756
|
+
return cleaned_data
|
|
1757
|
+
|
|
1758
|
+
def as_dict(self, should_clean_json: bool = False) -> Dict[Text, Any]:
|
|
1715
1759
|
"""Return serialized `Domain`."""
|
|
1716
|
-
|
|
1760
|
+
if should_clean_json:
|
|
1761
|
+
return self._cleaned_json_data()
|
|
1762
|
+
else:
|
|
1763
|
+
return self._data
|
|
1717
1764
|
|
|
1718
1765
|
@staticmethod
|
|
1719
1766
|
def get_responses_with_multilines(
|