rasa-pro 3.13.0.dev20250613__py3-none-any.whl → 3.13.0rc2__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/cli/e2e_test.py +0 -7
- rasa/cli/export.py +2 -0
- rasa/cli/project_templates/tutorial/config.yml +1 -1
- rasa/cli/project_templates/tutorial/endpoints.yml +1 -1
- rasa/cli/studio/download.py +1 -23
- rasa/cli/studio/link.py +0 -17
- rasa/cli/studio/pull.py +3 -2
- rasa/cli/studio/push.py +1 -1
- rasa/cli/studio/train.py +1 -5
- rasa/cli/studio/upload.py +1 -1
- rasa/core/agent.py +6 -0
- rasa/core/channels/__init__.py +3 -0
- rasa/core/channels/development_inspector.py +1 -1
- rasa/core/channels/facebook.py +1 -4
- rasa/core/channels/inspector/README.md +3 -3
- rasa/core/channels/inspector/dist/assets/{arc-c4b064fc.js → arc-371401b1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-215b5026.js → blockDiagram-38ab4fdb-3f126156.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-2b54a0a3.js → c4Diagram-3d4e48cf-12f22eb7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-daacea5f.js → classDiagram-70f12bd4-03b1d386.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-930d4dc2.js → classDiagram-v2-f2320105-84f69d63.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-83c206ba.js → createText-2e5e7dd3-ca47fd38.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b0eb01d0.js → edges-e0da2a9e-f837ca8a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-17586500.js → erDiagram-9861fffd-8717ac54.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-be2a1776.js → flowDb-956e92f1-94f38b83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c2120ebd.js → flowDiagram-66a62f08-b616f9fb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a6ab5c48.js → flowchart-elk-definition-4a651766-f5d24bb8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-ef613457.js → ganttDiagram-c361ad54-b43ba8d9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-d59185b3.js → gitGraphDiagram-72cf32ee-c3aafaa5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-0f155405.js → graph-0d0a2c10.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-d5f1d1b7.js → index-3862675e-58ea0305.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-47737d3a.js → index-cce6f8a1.js} +3 -3
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b07d141f.js → infoDiagram-f8f76790-b8f60461.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-1936d429.js → journeyDiagram-49397b02-95be5545.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-dde8d0f3.js → layout-da885b9b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-0c2c7ee0.js → line-f1c817d3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-35dd89a4.js → linear-d42801e6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-56192851.js → mindmap-definition-fc14e90a-a38923a6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-fc21ed78.js → pieDiagram-8a3498a8-ca6e71e9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-25e98518.js → quadrantDiagram-120e2f19-b290dae9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-546ff1f5.js → requirementDiagram-deff3bca-03f02ceb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-02d8b82d.js → sankeyDiagram-04a897e0-c49eee40.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3ca5a92e.js → sequenceDiagram-704730f1-b2cd6a3d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-128ea07c.js → stateDiagram-587899a1-e53a2028.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-95f290af.js → stateDiagram-v2-d93cdb3a-e1982a03.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-4984898a.js → styles-6aaf32cf-d0226ca5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1bf266ba.js → styles-9a916d00-0e21dc00.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-60521c63.js → styles-c10674c1-9588494e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-a25b6e12.js → svgDrawCommon-08f97a94-be478d4f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-0fc086bf.js → timeline-definition-85554ec2-74631749.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-44ee592e.js → xychartDiagram-e933f94c-a043552f.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +1 -1
- rasa/core/channels/socketio.py +56 -41
- rasa/core/channels/studio_chat.py +311 -8
- rasa/core/channels/voice_ready/audiocodes.py +1 -1
- rasa/core/channels/voice_ready/jambonz.py +5 -6
- rasa/core/channels/voice_ready/twilio_voice.py +13 -12
- rasa/core/channels/voice_ready/utils.py +22 -0
- rasa/core/channels/voice_stream/asr/azure.py +9 -0
- rasa/core/channels/voice_stream/audiocodes.py +5 -11
- rasa/core/channels/voice_stream/browser_audio.py +1 -1
- rasa/core/channels/voice_stream/genesys.py +35 -16
- rasa/core/channels/voice_stream/jambonz.py +232 -0
- rasa/core/channels/voice_stream/tts/__init__.py +8 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +12 -7
- rasa/core/channels/voice_stream/voice_channel.py +53 -15
- rasa/core/exporter.py +36 -0
- rasa/core/information_retrieval/faiss.py +18 -11
- rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
- rasa/core/nlg/contextual_response_rephraser.py +10 -1
- rasa/core/policies/enterprise_search_policy.py +189 -263
- rasa/core/policies/enterprise_search_policy_config.py +241 -0
- rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +6 -5
- rasa/core/policies/intentless_policy.py +47 -10
- rasa/core/processor.py +6 -0
- rasa/core/utils.py +11 -2
- rasa/dialogue_understanding/coexistence/llm_based_router.py +13 -11
- rasa/dialogue_understanding/commands/__init__.py +4 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -2
- rasa/dialogue_understanding/commands/clarify_command.py +2 -2
- rasa/dialogue_understanding/commands/correct_slots_command.py +5 -6
- rasa/dialogue_understanding/commands/error_command.py +1 -1
- rasa/dialogue_understanding/commands/human_handoff_command.py +1 -3
- rasa/dialogue_understanding/commands/set_slot_command.py +4 -4
- rasa/dialogue_understanding/commands/skip_question_command.py +1 -3
- rasa/dialogue_understanding/commands/start_flow_command.py +3 -3
- rasa/dialogue_understanding/generator/command_generator.py +11 -1
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -2
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +0 -2
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +79 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +1 -0
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +2 -2
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -18
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +17 -11
- rasa/dialogue_understanding/patterns/cancel.py +1 -2
- rasa/dialogue_understanding/patterns/clarify.py +1 -1
- rasa/dialogue_understanding/patterns/correction.py +2 -2
- rasa/dialogue_understanding/processor/command_processor.py +11 -12
- rasa/dialogue_understanding/stack/utils.py +3 -1
- rasa/e2e_test/constants.py +1 -1
- rasa/e2e_test/e2e_test_coverage_report.py +1 -1
- rasa/engine/graph.py +2 -2
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +2 -6
- rasa/model_manager/runner_service.py +20 -4
- rasa/model_manager/trainer_service.py +6 -0
- rasa/privacy/privacy_manager.py +26 -11
- rasa/shared/constants.py +14 -0
- rasa/shared/core/command_payload_reader.py +1 -5
- rasa/shared/core/events.py +1 -3
- rasa/shared/core/flows/constants.py +2 -0
- rasa/shared/core/flows/flow.py +126 -12
- rasa/shared/core/flows/flows_list.py +18 -1
- rasa/shared/core/flows/steps/link.py +7 -2
- rasa/shared/core/flows/validation.py +25 -5
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
- rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
- rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
- rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
- rasa/shared/providers/_configs/openai_client_config.py +1 -1
- rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
- rasa/shared/providers/_configs/utils.py +0 -99
- rasa/shared/utils/common.py +1 -1
- rasa/shared/utils/configs.py +110 -0
- rasa/shared/utils/constants.py +0 -3
- rasa/shared/utils/llm.py +123 -8
- rasa/shared/utils/pykwalify_extensions.py +0 -9
- rasa/studio/constants.py +1 -0
- rasa/studio/data_handler.py +30 -9
- rasa/studio/download.py +171 -0
- rasa/studio/link.py +13 -2
- rasa/studio/prompts.py +221 -0
- rasa/studio/pull/__init__.py +0 -0
- rasa/studio/{download/flows.py → pull/data.py} +2 -131
- rasa/studio/{download → pull}/domains.py +1 -1
- rasa/studio/pull/pull.py +239 -0
- rasa/studio/push.py +7 -0
- rasa/studio/train.py +1 -1
- rasa/studio/upload.py +61 -5
- rasa/studio/utils.py +33 -0
- rasa/tracing/instrumentation/attribute_extractors.py +21 -7
- rasa/utils/common.py +11 -0
- rasa/version.py +1 -1
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/METADATA +4 -4
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/RECORD +155 -147
- rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-e847561e.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +0 -1
- rasa/studio/download/download.py +0 -416
- rasa/studio/pull.py +0 -94
- /rasa/{studio/download → core/information_retrieval/ingestion}/__init__.py +0 -0
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/entry_points.txt +0 -0
|
@@ -8,6 +8,7 @@ from rasa.dialogue_understanding.commands import (
|
|
|
8
8
|
Command,
|
|
9
9
|
CorrectSlotsCommand,
|
|
10
10
|
ErrorCommand,
|
|
11
|
+
HandleCodeChangeCommand,
|
|
11
12
|
SetSlotCommand,
|
|
12
13
|
StartFlowCommand,
|
|
13
14
|
)
|
|
@@ -398,15 +399,24 @@ class CommandGenerator:
|
|
|
398
399
|
The filtered commands.
|
|
399
400
|
"""
|
|
400
401
|
from rasa.dialogue_understanding.processor.command_processor import (
|
|
402
|
+
find_updated_flows,
|
|
401
403
|
get_current_collect_step,
|
|
402
404
|
)
|
|
403
405
|
|
|
404
406
|
if tracker is None:
|
|
405
|
-
structlogger.
|
|
407
|
+
structlogger.debug(
|
|
406
408
|
"command_generator.filter_commands_during_force_slot_filling.tracker_not_found",
|
|
407
409
|
)
|
|
408
410
|
return commands
|
|
409
411
|
|
|
412
|
+
updated_flows = find_updated_flows(tracker, available_flows)
|
|
413
|
+
if updated_flows:
|
|
414
|
+
structlogger.debug(
|
|
415
|
+
"command_generator.filter_commands_during_force_slot_filling.running_flows_were_updated",
|
|
416
|
+
updated_flow_ids=updated_flows,
|
|
417
|
+
)
|
|
418
|
+
return [HandleCodeChangeCommand()]
|
|
419
|
+
|
|
410
420
|
stack = tracker.stack
|
|
411
421
|
step = get_current_collect_step(stack, available_flows)
|
|
412
422
|
|
|
@@ -125,8 +125,9 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
|
|
|
125
125
|
raise_deprecation_warning(
|
|
126
126
|
message=(
|
|
127
127
|
"Support for `MultiStepLLMCommandGenerator` will be removed in Rasa "
|
|
128
|
-
"`4.0.0`. Please modify your assistant's configuration to use
|
|
129
|
-
"
|
|
128
|
+
"`4.0.0`. Please modify your assistant's configuration to use the "
|
|
129
|
+
"`CompactLLMCommandGenerator` or `SearchReadyLLMCommandGenerator` "
|
|
130
|
+
"instead."
|
|
130
131
|
)
|
|
131
132
|
)
|
|
132
133
|
|
|
@@ -190,9 +190,9 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
|
|
|
190
190
|
if len(commands) > 1:
|
|
191
191
|
structlogger.warning(
|
|
192
192
|
"nlu_command_adapter.predict_commands",
|
|
193
|
-
|
|
193
|
+
message=f"Too many flows found that are triggered by the "
|
|
194
194
|
f"intent '{message.get(INTENT)['name']}'. Take the first one.",
|
|
195
|
-
commands=commands,
|
|
195
|
+
commands=[command.__class__.__name__ for command in commands],
|
|
196
196
|
)
|
|
197
197
|
commands = [commands[0]]
|
|
198
198
|
|
|
@@ -41,9 +41,7 @@ Based on this information generate a list of actions you want to take. Your job
|
|
|
41
41
|
* Responding to knowledge-oriented user messages, described by "SearchAndReply()"
|
|
42
42
|
* Responding to a casual, non-task-oriented user message, described by "ChitChat()".
|
|
43
43
|
* Handing off to a human, in case the user seems frustrated or explicitly asks to speak to one, described by "HumanHandoff()".
|
|
44
|
-
{% if is_repeat_command_enabled %}
|
|
45
44
|
* Repeat the last bot messages, described by "RepeatLastBotMessages()". This is useful when the user asks to repeat the last bot messages.
|
|
46
|
-
{% endif %}
|
|
47
45
|
|
|
48
46
|
===
|
|
49
47
|
Write out the actions you want to take, one per line, in the order they should take place.
|
|
@@ -11,6 +11,7 @@ Your task is to analyze the current conversation context and generate a list of
|
|
|
11
11
|
* `provide info`: Responding to the user's questions by supplying relevant information, such as answering FAQs or explaining services.
|
|
12
12
|
* `offtopic reply`: Responding to casual or social user messages that are unrelated to any flows, engaging in friendly conversation and addressing off-topic remarks.
|
|
13
13
|
* `hand over`: Handing over to a human, in case the user seems frustrated or explicitly asks to speak to one.
|
|
14
|
+
* `repeat message`: Repeating the last bot message.
|
|
14
15
|
|
|
15
16
|
--
|
|
16
17
|
|
|
@@ -19,6 +19,7 @@ Use the following structured data:
|
|
|
19
19
|
* `provide info`: Responding to the user's questions by supplying relevant information, such as answering FAQs or explaining services.
|
|
20
20
|
* `offtopic reply`: Responding to casual or social user messages that are unrelated to any flows, engaging in friendly conversation and addressing off-topic remarks.
|
|
21
21
|
* `hand over`: Handing over to a human, in case the user seems frustrated or explicitly asks to speak to one.
|
|
22
|
+
* `repeat message`: Repeating the last bot message.
|
|
22
23
|
|
|
23
24
|
---
|
|
24
25
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
## Task Description
|
|
2
|
+
Your task is to analyze the current conversation context and generate a list of actions to start new business processes that we call flows, to extract slots, or respond to off-topic and knowledge requests.
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Available Actions:
|
|
7
|
+
* `start flow flow_name`: Start a flow. For example, `start flow transfer_money` or `start flow list_contacts`.
|
|
8
|
+
* `set slot slot_name slot_value`: Set a slot for the active flow. For example, `set slot transfer_money_recipient Freddy`. Can be used to correct and change previously set values.
|
|
9
|
+
* `disambiguate flows flow_name1 flow_name2 ... flow_name_n`: When a message could refer to multiple flows, list the possible flows as options to clarify. Example: `disambiguate flows list_contacts add_contact remove_contact`.
|
|
10
|
+
* `search and reply`: Provide a response from the knowledge base to address the user's inquiry when no flows fit, including domain knowledge, FAQs, and all off-topic or social messages.
|
|
11
|
+
* `cancel flow`: Cancel the current flow if the user requests it.
|
|
12
|
+
* `repeat message`: Repeat the last bot message.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## General Instructions
|
|
17
|
+
### Start Flow
|
|
18
|
+
* Only start a flow if the user's message is clear and fully addressed by that flow's description and purpose.
|
|
19
|
+
* Pay close attention to exact wording and scope in the flow description — do not assume or “stretch” the intended use of a flow.
|
|
20
|
+
### Set Slot
|
|
21
|
+
* Do not fill slots with abstract values or placeholders.
|
|
22
|
+
* For categorical slots, try to match the user message with allowed slot values. Use "other" if you cannot match it.
|
|
23
|
+
* Set the boolean slots based on the user's response. Map positive responses to `True`, and negative to `False`.
|
|
24
|
+
* Extract text slot values exactly as provided by the user. Avoid assumptions, format changes, or partial extractions.
|
|
25
|
+
### Disambiguate Flows
|
|
26
|
+
* Use `disambiguate flows` when the user's message matches multiple flows and you cannot decide which flow is most appropriate.
|
|
27
|
+
* If the user message is short and not precise enough to start a flow or `search and reply`, disambiguate.
|
|
28
|
+
* If a single flow is a strong/plausible fit, prefer starting that flow directly.
|
|
29
|
+
* If a user's message unambiguously and distinctly matches multiple flows, start all relevant flows at once (rather than disambiguating).
|
|
30
|
+
### Search and Reply
|
|
31
|
+
* Only start `search and reply` if the user intent is clear.
|
|
32
|
+
* Flow Priority: If you are unsure between starting a flow or `search and reply`, always prioritize starting a flow.
|
|
33
|
+
### Cancel Flow
|
|
34
|
+
* Do not cancel any flow unless the user explicitly requests it.
|
|
35
|
+
* Multiple flows can be started without cancelling the previous, if the user wants to pursue multiple processes.
|
|
36
|
+
### General Tips
|
|
37
|
+
* Only use information provided by the user.
|
|
38
|
+
* Strictly adhere to the provided action format.
|
|
39
|
+
* Focus on the last message and take it one step at a time.
|
|
40
|
+
* Use the previous conversation steps only to aid understanding.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Decision Rule Table
|
|
45
|
+
| Condition | Action |
|
|
46
|
+
|-------------------------------------------------------|--------------------|
|
|
47
|
+
| Flow perfectly matches user's message | start flow |
|
|
48
|
+
| Multiple flows are equally strong, relevant matches | disambiguate flows |
|
|
49
|
+
| User's message is unclear or imprecise | disambiguate flows |
|
|
50
|
+
| No flow fits at all, but knowledge base may help | search and reply |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Available Flows and Slots
|
|
55
|
+
Use the following structured data:
|
|
56
|
+
```json
|
|
57
|
+
{"flows":[{% for flow in available_flows %}{"name":"{{ flow.name }}","description":{{ flow.description | to_json_escaped_string }}{% if flow.slots %},"slots":[{% for slot in flow.slots %}{"name":"{{ slot.name }}"{% if slot.description %},"description":{{ slot.description | to_json_escaped_string }}{% endif %}{% if slot.allowed_values %},"allowed_values":{{ slot.allowed_values }}{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Current State
|
|
63
|
+
{% if current_flow != None %}Use the following structured data:
|
|
64
|
+
```json
|
|
65
|
+
{"active_flow":"{{ current_flow }}","current_step":{"requested_slot":"{{ current_slot }}","requested_slot_description":{{ current_slot_description | to_json_escaped_string }}},"slots":[{% for slot in flow_slots %}{"name":"{{ slot.name }}","value":"{{ slot.value }}","type":"{{ slot.type }}"{% if slot.description %},"description":{{ slot.description | to_json_escaped_string }}{% endif %}{% if slot.allowed_values %},"allowed_values":"{{ slot.allowed_values }}"{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]}
|
|
66
|
+
```{% else %}
|
|
67
|
+
You are currently not inside any flow.{% endif %}
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Conversation History
|
|
72
|
+
{{ current_conversation }}
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Task
|
|
77
|
+
Create an action list with one action per line in response to the user's last message: """{{ user_message }}""".
|
|
78
|
+
|
|
79
|
+
Your action list:
|
|
@@ -17,6 +17,7 @@ Use the following structured data:
|
|
|
17
17
|
* `disambiguate flows flow_name1 flow_name2 ... flow_name_n`: When a message could refer to multiple flows, list the possible flows as options to clarify. Example: `disambiguate flows list_contacts add_contact remove_contact`.
|
|
18
18
|
* `search and reply`: Provide a response from the knowledge base to address the user’s inquiry when no flows fit, including domain knowledge, FAQs, and all off-topic or social messages.
|
|
19
19
|
* `cancel flow`: Cancel the current flow if the user requests it.
|
|
20
|
+
* `repeat message`: Repeat the last bot message.
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
@@ -59,10 +59,10 @@ MODEL_PROMPT_MAPPER = {
|
|
|
59
59
|
),
|
|
60
60
|
f"{AWS_BEDROCK_PROVIDER}/anthropic."
|
|
61
61
|
f"{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}-v1:0": (
|
|
62
|
-
"
|
|
62
|
+
"command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2"
|
|
63
63
|
),
|
|
64
64
|
f"{ANTHROPIC_PROVIDER}/{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}": (
|
|
65
|
-
"
|
|
65
|
+
"command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2"
|
|
66
66
|
),
|
|
67
67
|
}
|
|
68
68
|
|
rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py
CHANGED
|
@@ -61,7 +61,6 @@ from rasa.shared.utils.llm import (
|
|
|
61
61
|
sanitize_message_for_prompt,
|
|
62
62
|
tracker_as_readable_transcript,
|
|
63
63
|
)
|
|
64
|
-
from rasa.utils.beta import BetaNotEnabledException, ensure_beta_feature_is_enabled
|
|
65
64
|
from rasa.utils.log_utils import log_llm
|
|
66
65
|
|
|
67
66
|
structlogger = structlog.get_logger()
|
|
@@ -106,14 +105,13 @@ class SingleStepBasedLLMCommandGenerator(LLMBasedCommandGenerator, ABC):
|
|
|
106
105
|
)
|
|
107
106
|
|
|
108
107
|
self.trace_prompt_tokens = self.config.get("trace_prompt_tokens", False)
|
|
109
|
-
self.repeat_command_enabled = self.is_repeat_command_enabled()
|
|
110
108
|
|
|
111
109
|
### Implementations of LLMBasedCommandGenerator parent
|
|
112
110
|
@staticmethod
|
|
113
111
|
def get_default_config() -> Dict[str, Any]:
|
|
114
112
|
"""The component's default config (see parent class for full docstring)."""
|
|
115
113
|
return {
|
|
116
|
-
PROMPT_TEMPLATE_CONFIG_KEY: None,
|
|
114
|
+
PROMPT_TEMPLATE_CONFIG_KEY: None, # TODO: remove in Rasa 4.0.0
|
|
117
115
|
USER_INPUT_CONFIG_KEY: None,
|
|
118
116
|
LLM_CONFIG_KEY: None,
|
|
119
117
|
FLOW_RETRIEVAL_KEY: FlowRetrieval.get_default_config(),
|
|
@@ -212,7 +210,7 @@ class SingleStepBasedLLMCommandGenerator(LLMBasedCommandGenerator, ABC):
|
|
|
212
210
|
event_info=(
|
|
213
211
|
"ProviderClientAPIException occurred while predicting commands."
|
|
214
212
|
),
|
|
215
|
-
commands=commands,
|
|
213
|
+
commands=commands, # no PII
|
|
216
214
|
)
|
|
217
215
|
|
|
218
216
|
if not commands and not prior_commands:
|
|
@@ -414,24 +412,10 @@ class SingleStepBasedLLMCommandGenerator(LLMBasedCommandGenerator, ABC):
|
|
|
414
412
|
"current_slot_type": current_slot_type,
|
|
415
413
|
"current_slot_allowed_values": current_slot_allowed_values,
|
|
416
414
|
"user_message": latest_user_message,
|
|
417
|
-
"is_repeat_command_enabled": self.repeat_command_enabled,
|
|
418
415
|
}
|
|
419
416
|
|
|
420
417
|
return self.compile_template(self.prompt_template).render(**inputs)
|
|
421
418
|
|
|
422
|
-
def is_repeat_command_enabled(self) -> bool:
|
|
423
|
-
"""Check for feature flag"""
|
|
424
|
-
RASA_PRO_BETA_REPEAT_COMMAND_ENV_VAR_NAME = "RASA_PRO_BETA_REPEAT_COMMAND"
|
|
425
|
-
try:
|
|
426
|
-
ensure_beta_feature_is_enabled(
|
|
427
|
-
"Repeat Command",
|
|
428
|
-
env_flag=RASA_PRO_BETA_REPEAT_COMMAND_ENV_VAR_NAME,
|
|
429
|
-
)
|
|
430
|
-
except BetaNotEnabledException:
|
|
431
|
-
return False
|
|
432
|
-
|
|
433
|
-
return True
|
|
434
|
-
|
|
435
419
|
@classmethod
|
|
436
420
|
def fingerprint_addon(cls: Any, config: Dict[str, Any]) -> Optional[str]:
|
|
437
421
|
"""Add a fingerprint for the graph."""
|
|
@@ -16,7 +16,11 @@ from rasa.shared.constants import (
|
|
|
16
16
|
PROMPT_CONFIG_KEY,
|
|
17
17
|
PROMPT_TEMPLATE_CONFIG_KEY,
|
|
18
18
|
)
|
|
19
|
-
from rasa.shared.utils.
|
|
19
|
+
from rasa.shared.utils.io import raise_deprecation_warning
|
|
20
|
+
from rasa.shared.utils.llm import (
|
|
21
|
+
check_prompt_config_keys_and_warn_if_deprecated,
|
|
22
|
+
get_prompt_template,
|
|
23
|
+
)
|
|
20
24
|
|
|
21
25
|
DEFAULT_COMMAND_PROMPT_TEMPLATE = importlib.resources.read_text(
|
|
22
26
|
"rasa.dialogue_understanding.generator.prompt_templates",
|
|
@@ -44,6 +48,14 @@ class SingleStepLLMCommandGenerator(SingleStepBasedLLMCommandGenerator):
|
|
|
44
48
|
prompt_template: Optional[Text] = None,
|
|
45
49
|
**kwargs: Any,
|
|
46
50
|
) -> None:
|
|
51
|
+
raise_deprecation_warning(
|
|
52
|
+
message=(
|
|
53
|
+
"Support for `SingleStepLLMCommandGenerator` will be removed in Rasa "
|
|
54
|
+
"`4.0.0`. Please modify your assistant's configuration to use the "
|
|
55
|
+
"`CompactLLMCommandGenerator` or `SearchReadyLLMCommandGenerator` "
|
|
56
|
+
"instead."
|
|
57
|
+
)
|
|
58
|
+
)
|
|
47
59
|
super().__init__(
|
|
48
60
|
config,
|
|
49
61
|
model_storage,
|
|
@@ -52,16 +64,10 @@ class SingleStepLLMCommandGenerator(SingleStepBasedLLMCommandGenerator):
|
|
|
52
64
|
**kwargs,
|
|
53
65
|
)
|
|
54
66
|
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
event_info=(
|
|
60
|
-
"The config parameter 'prompt' is deprecated "
|
|
61
|
-
"and will be removed in Rasa 4.0.0. "
|
|
62
|
-
"Please use the config parameter 'prompt_template' instead. "
|
|
63
|
-
),
|
|
64
|
-
)
|
|
67
|
+
# Warn if the prompt config key is used to set the prompt template
|
|
68
|
+
check_prompt_config_keys_and_warn_if_deprecated(
|
|
69
|
+
config, "single_step_llm_command_generator"
|
|
70
|
+
)
|
|
65
71
|
|
|
66
72
|
@staticmethod
|
|
67
73
|
def get_component_command_syntax_version() -> CommandSyntaxVersion:
|
|
@@ -90,7 +90,7 @@ class ActionCancelFlow(action.Action):
|
|
|
90
90
|
return []
|
|
91
91
|
|
|
92
92
|
if not isinstance(top, CancelPatternFlowStackFrame):
|
|
93
|
-
structlogger.warning("action.cancel_flow.no_cancel_frame"
|
|
93
|
+
structlogger.warning("action.cancel_flow.no_cancel_frame")
|
|
94
94
|
return []
|
|
95
95
|
|
|
96
96
|
for canceled_frame_id in top.canceled_frames:
|
|
@@ -105,7 +105,6 @@ class ActionCancelFlow(action.Action):
|
|
|
105
105
|
else:
|
|
106
106
|
structlogger.warning(
|
|
107
107
|
"action.cancel_flow.frame_not_found",
|
|
108
|
-
dialogue_stack=stack,
|
|
109
108
|
frame_id=canceled_frame_id,
|
|
110
109
|
)
|
|
111
110
|
|
|
@@ -89,7 +89,7 @@ class ActionClarifyFlows(action.Action):
|
|
|
89
89
|
return []
|
|
90
90
|
|
|
91
91
|
if not isinstance(top, ClarifyPatternFlowStackFrame):
|
|
92
|
-
structlogger.warning("action.clarify_flows.no_clarification_frame"
|
|
92
|
+
structlogger.warning("action.clarify_flows.no_clarification_frame")
|
|
93
93
|
return []
|
|
94
94
|
|
|
95
95
|
options_string = self.assemble_options_string(top.names)
|
|
@@ -114,7 +114,8 @@ class ActionCorrectFlowSlot(action.Action):
|
|
|
114
114
|
|
|
115
115
|
if not isinstance(top, CorrectionPatternFlowStackFrame):
|
|
116
116
|
structlogger.warning(
|
|
117
|
-
"action.correct_flow_slot.no_correction_frame",
|
|
117
|
+
"action.correct_flow_slot.no_correction_frame",
|
|
118
|
+
top=top, # no PII
|
|
118
119
|
)
|
|
119
120
|
return []
|
|
120
121
|
|
|
@@ -246,7 +247,6 @@ def reset_stack_on_tracker_to_prior_state(
|
|
|
246
247
|
"action.correct_flow_slot.no_target_frame_found",
|
|
247
248
|
reset_step_id=reset_step_id,
|
|
248
249
|
reset_flow_id=reset_flow_id,
|
|
249
|
-
stack_to_reset_to=stack_to_reset_to,
|
|
250
250
|
)
|
|
251
251
|
return tracker.stack
|
|
252
252
|
|
|
@@ -214,18 +214,18 @@ def execute_commands(
|
|
|
214
214
|
commands: List[Command] = get_commands_from_tracker(tracker)
|
|
215
215
|
original_tracker = tracker.copy()
|
|
216
216
|
|
|
217
|
-
commands = clean_up_commands(
|
|
218
|
-
commands, tracker, all_flows, execution_context, story_graph, domain
|
|
219
|
-
)
|
|
220
|
-
|
|
221
217
|
updated_flows = find_updated_flows(tracker, all_flows)
|
|
222
218
|
if updated_flows:
|
|
223
|
-
#
|
|
219
|
+
# if there are updated flows, we need to handle the code change
|
|
224
220
|
structlogger.debug(
|
|
225
221
|
"command_processor.execute_commands.running_flows_were_updated",
|
|
226
222
|
updated_flow_ids=updated_flows,
|
|
227
223
|
)
|
|
228
224
|
commands = [HandleCodeChangeCommand()]
|
|
225
|
+
else:
|
|
226
|
+
commands = clean_up_commands(
|
|
227
|
+
commands, tracker, all_flows, execution_context, story_graph, domain
|
|
228
|
+
)
|
|
229
229
|
|
|
230
230
|
# store current flow hashes if they changed
|
|
231
231
|
new_hashes = calculate_flow_fingerprints(all_flows)
|
|
@@ -348,7 +348,6 @@ def get_current_collect_step(
|
|
|
348
348
|
# but no flow that triggered it. this should never happen.
|
|
349
349
|
structlogger.warning(
|
|
350
350
|
"command_processor.get_current_collect_step.no_flow_on_stack",
|
|
351
|
-
stack=dialogue_stack,
|
|
352
351
|
)
|
|
353
352
|
return None
|
|
354
353
|
|
|
@@ -358,7 +357,7 @@ def get_current_collect_step(
|
|
|
358
357
|
# step from it
|
|
359
358
|
structlogger.warning(
|
|
360
359
|
"command_processor.get_current_collect_step.no_step_for_frame",
|
|
361
|
-
frame=frame_that_triggered_collect_infos,
|
|
360
|
+
frame=frame_that_triggered_collect_infos.frame_id,
|
|
362
361
|
)
|
|
363
362
|
return None
|
|
364
363
|
|
|
@@ -640,9 +639,9 @@ def clean_up_slot_command(
|
|
|
640
639
|
resulting_commands.append(command)
|
|
641
640
|
return resulting_commands
|
|
642
641
|
|
|
643
|
-
if (slot := tracker.slots.get(command.name)) is not None and
|
|
644
|
-
|
|
645
|
-
):
|
|
642
|
+
if (slot := tracker.slots.get(command.name)) is not None and str(
|
|
643
|
+
slot.value
|
|
644
|
+
) == str(command.value):
|
|
646
645
|
# the slot is already set, we don't need to set it again
|
|
647
646
|
structlogger.debug(
|
|
648
647
|
"command_processor.clean_up_slot_command.skip_command_slot_already_set",
|
|
@@ -724,7 +723,7 @@ def clean_up_chitchat_command(
|
|
|
724
723
|
)
|
|
725
724
|
structlogger.warn(
|
|
726
725
|
"command_processor.clean_up_chitchat_command.pattern_chitchat_not_found",
|
|
727
|
-
command=resulting_commands[0],
|
|
726
|
+
command=resulting_commands[0], # no PII
|
|
728
727
|
)
|
|
729
728
|
return resulting_commands
|
|
730
729
|
|
|
@@ -742,7 +741,7 @@ def clean_up_chitchat_command(
|
|
|
742
741
|
)
|
|
743
742
|
structlogger.warn(
|
|
744
743
|
"command_processor.clean_up_chitchat_command.replace_chitchat_answer_with_cannot_handle",
|
|
745
|
-
command=resulting_commands[0],
|
|
744
|
+
command=resulting_commands[0], # no PII
|
|
746
745
|
pattern_chitchat_uses_action_trigger_chitchat=has_action_trigger_chitchat,
|
|
747
746
|
defined_intentless_policy_in_config=defines_intentless_policy,
|
|
748
747
|
)
|
|
@@ -209,7 +209,9 @@ def get_collect_steps_excluding_ask_before_filling_for_active_flow(
|
|
|
209
209
|
All collect steps that are part of the current active flow,
|
|
210
210
|
excluding the collect steps that have to be asked before filling.
|
|
211
211
|
"""
|
|
212
|
-
active_frame = top_user_flow_frame(
|
|
212
|
+
active_frame = top_user_flow_frame(
|
|
213
|
+
dialogue_stack, ignore_call_and_link_frames=False
|
|
214
|
+
)
|
|
213
215
|
if active_frame is None:
|
|
214
216
|
return set()
|
|
215
217
|
active_flow = active_frame.flow(all_flows)
|
rasa/e2e_test/constants.py
CHANGED
|
@@ -40,7 +40,7 @@ DEFAULT_GROUNDEDNESS_PROMPT_TEMPLATE_FILE_NAME = "groundedness_prompt_template.j
|
|
|
40
40
|
DEFAULT_ANSWER_RELEVANCE_PROMPT_TEMPLATE_FILE_NAME = (
|
|
41
41
|
"answer_relevance_prompt_template.jinja2"
|
|
42
42
|
)
|
|
43
|
-
DEFAULT_E2E_TESTING_MODEL = "gpt-
|
|
43
|
+
DEFAULT_E2E_TESTING_MODEL = "gpt-4.1-mini-2025-04-14"
|
|
44
44
|
KEY_SCORE = "score"
|
|
45
45
|
KEY_JUSTIFICATION = "justification"
|
|
46
46
|
KEY_EXTRA_PARAMETERS = "extra_parameters"
|
|
@@ -21,7 +21,7 @@ from rasa.shared.core.flows.flow_path import FlowPath, FlowPathsList, PathNode
|
|
|
21
21
|
FLOW_NAME_COL_NAME = "Flow Name"
|
|
22
22
|
NUM_STEPS_COL_NAME = "Num Steps"
|
|
23
23
|
MISSING_STEPS_COL_NAME = "Missing Steps"
|
|
24
|
-
LINE_NUMBERS_COL_NAME = "Line Numbers"
|
|
24
|
+
LINE_NUMBERS_COL_NAME = "Line Numbers for Missing Steps"
|
|
25
25
|
COVERAGE_COL_NAME = "Coverage"
|
|
26
26
|
|
|
27
27
|
FLOWS_KEY = "flows"
|
rasa/engine/graph.py
CHANGED
|
@@ -500,9 +500,9 @@ class GraphNode:
|
|
|
500
500
|
structlogger.warning(
|
|
501
501
|
"graph.node.input_not_resolved",
|
|
502
502
|
node_name=self._node_name,
|
|
503
|
-
input_name=i,
|
|
503
|
+
input_name=i, # no PII
|
|
504
504
|
event_info=(
|
|
505
|
-
"Node input was not resolved, there is no
|
|
505
|
+
"Node input was not resolved, there is no output. "
|
|
506
506
|
"Another component should have provided this as an output."
|
|
507
507
|
),
|
|
508
508
|
)
|
|
@@ -22,11 +22,7 @@ from rasa.shared.constants import (
|
|
|
22
22
|
from rasa.shared.exceptions import ProviderClientAPIException
|
|
23
23
|
from rasa.shared.providers.mappings import OPENAI_PROVIDER
|
|
24
24
|
from rasa.shared.utils.constants import LOG_COMPONENT_SOURCE_METHOD_INIT
|
|
25
|
-
from rasa.shared.utils.llm import
|
|
26
|
-
USER,
|
|
27
|
-
get_prompt_template,
|
|
28
|
-
llm_factory,
|
|
29
|
-
)
|
|
25
|
+
from rasa.shared.utils.llm import USER, get_prompt_template, llm_factory
|
|
30
26
|
|
|
31
27
|
SEPARATOR = "\n\n"
|
|
32
28
|
BACKUP_SEPARATOR = "\nUSER:"
|
|
@@ -39,7 +35,7 @@ DEFAULT_REPHRASING_PROMPT_TEMPLATE = importlib.resources.read_text(
|
|
|
39
35
|
|
|
40
36
|
DEFAULT_LLM_CONFIG = {
|
|
41
37
|
PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
|
|
42
|
-
MODEL_CONFIG_KEY: "gpt-
|
|
38
|
+
MODEL_CONFIG_KEY: "gpt-4.1-mini-2025-04-14",
|
|
43
39
|
TIMEOUT_CONFIG_KEY: 7,
|
|
44
40
|
TEMPERATURE_CONFIG_KEY: 0.0,
|
|
45
41
|
MAX_COMPLETION_TOKENS_CONFIG_KEY: 4096,
|
|
@@ -2,7 +2,8 @@ import os
|
|
|
2
2
|
import shutil
|
|
3
3
|
import subprocess
|
|
4
4
|
from enum import Enum
|
|
5
|
-
from
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Dict, Optional, Union
|
|
6
7
|
|
|
7
8
|
import aiohttp
|
|
8
9
|
import structlog
|
|
@@ -18,6 +19,7 @@ from rasa.model_manager.utils import (
|
|
|
18
19
|
write_encoded_data_to_file,
|
|
19
20
|
)
|
|
20
21
|
from rasa.model_manager.warm_rasa_process import start_rasa_process
|
|
22
|
+
from rasa.studio.prompts import handle_prompts
|
|
21
23
|
|
|
22
24
|
structlogger = structlog.get_logger()
|
|
23
25
|
|
|
@@ -121,11 +123,25 @@ def get_open_port() -> int:
|
|
|
121
123
|
|
|
122
124
|
|
|
123
125
|
def write_encoded_config_data_to_files(
|
|
124
|
-
encoded_configs: Dict[str, bytes], base_path: str
|
|
126
|
+
encoded_configs: Dict[str, Union[bytes, Dict[str, str]]], base_path: str
|
|
125
127
|
) -> None:
|
|
126
128
|
"""Write the encoded config data to files."""
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
endpoints_encoded = encoded_configs.get("endpoints")
|
|
130
|
+
if endpoints_encoded:
|
|
131
|
+
write_encoded_data_to_file(
|
|
132
|
+
endpoints_encoded, subpath(base_path, "endpoints.yml")
|
|
133
|
+
)
|
|
134
|
+
config_encoded = encoded_configs.get("config")
|
|
135
|
+
if config_encoded:
|
|
136
|
+
write_encoded_data_to_file(config_encoded, subpath(base_path, "config.yml"))
|
|
137
|
+
credentials_encoded = encoded_configs.get("credentials")
|
|
138
|
+
if credentials_encoded:
|
|
139
|
+
write_encoded_data_to_file(
|
|
140
|
+
credentials_encoded, subpath(base_path, "credentials.yml")
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if prompts := encoded_configs.get("prompts"):
|
|
144
|
+
handle_prompts(prompts, Path(base_path))
|
|
129
145
|
|
|
130
146
|
|
|
131
147
|
def prepare_bot_directory(
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import shutil
|
|
3
3
|
import subprocess
|
|
4
4
|
from enum import Enum
|
|
5
|
+
from pathlib import Path
|
|
5
6
|
from typing import Any, Dict, Optional
|
|
6
7
|
|
|
7
8
|
import structlog
|
|
@@ -20,6 +21,7 @@ from rasa.model_manager.warm_rasa_process import (
|
|
|
20
21
|
start_rasa_process,
|
|
21
22
|
)
|
|
22
23
|
from rasa.model_training import generate_random_model_name
|
|
24
|
+
from rasa.studio.prompts import handle_prompts
|
|
23
25
|
|
|
24
26
|
structlogger = structlog.get_logger()
|
|
25
27
|
|
|
@@ -208,6 +210,7 @@ def write_training_data_to_files(
|
|
|
208
210
|
"stories": "base64 encoded stories.yml",
|
|
209
211
|
"rules": "base64 encoded rules.yml",
|
|
210
212
|
"nlu": "base64 encoded nlu.yml"
|
|
213
|
+
"prompts": "dictionary with the prompts",
|
|
211
214
|
}
|
|
212
215
|
```
|
|
213
216
|
"""
|
|
@@ -230,6 +233,9 @@ def write_training_data_to_files(
|
|
|
230
233
|
subpath(training_base_path + "/" + parent_path, file_name),
|
|
231
234
|
)
|
|
232
235
|
|
|
236
|
+
if prompts := encoded_training_data.get("prompts"):
|
|
237
|
+
handle_prompts(prompts, Path(training_base_path))
|
|
238
|
+
|
|
233
239
|
|
|
234
240
|
def prepare_training_directory(
|
|
235
241
|
training_base_path: str, assistant_id: str, encoded_training_data: Dict[str, Any]
|
rasa/privacy/privacy_manager.py
CHANGED
|
@@ -12,7 +12,7 @@ import structlog
|
|
|
12
12
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|
13
13
|
|
|
14
14
|
import rasa.shared.core.trackers
|
|
15
|
-
from rasa.core.tracker_stores.tracker_store import TrackerStore
|
|
15
|
+
from rasa.core.tracker_stores.tracker_store import FailSafeTrackerStore, TrackerStore
|
|
16
16
|
from rasa.privacy.constants import (
|
|
17
17
|
TEXT_KEY,
|
|
18
18
|
USER_CHAT_INACTIVITY_IN_MINUTES_ENV_VAR_NAME,
|
|
@@ -63,6 +63,7 @@ class BackgroundPrivacyManager:
|
|
|
63
63
|
self,
|
|
64
64
|
endpoints: Optional["AvailableEndpoints"],
|
|
65
65
|
event_loop: Optional["AbstractEventLoop"] = None,
|
|
66
|
+
in_memory_tracker_store: Optional[TrackerStore] = None,
|
|
66
67
|
):
|
|
67
68
|
self.config = (
|
|
68
69
|
PrivacyConfig.from_dict(endpoints.privacy)
|
|
@@ -76,15 +77,28 @@ class BackgroundPrivacyManager:
|
|
|
76
77
|
os.getenv(USER_CHAT_INACTIVITY_IN_MINUTES_ENV_VAR_NAME, 30)
|
|
77
78
|
)
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
if in_memory_tracker_store is not None:
|
|
81
|
+
# if an in-memory tracker store is provided,
|
|
82
|
+
# we need to keep the reference to it
|
|
83
|
+
# so that the background jobs can access it.
|
|
84
|
+
# We also set the event broker to None
|
|
85
|
+
# to prevent it from publishing events
|
|
86
|
+
# during the tracker store background jobs
|
|
87
|
+
in_memory_tracker_store.event_broker = None
|
|
88
|
+
tracker_store = in_memory_tracker_store
|
|
89
|
+
else:
|
|
90
|
+
# we recreate the tracker store here to ensure
|
|
91
|
+
# that this instance has no event brokers
|
|
92
|
+
# that could publish events during the tracker store
|
|
93
|
+
# background jobs
|
|
94
|
+
tracker_store = (
|
|
95
|
+
TrackerStore.create(endpoints.tracker_store)
|
|
96
|
+
if endpoints
|
|
97
|
+
else TrackerStore.create(None)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
self.tracker_store = FailSafeTrackerStore(tracker_store)
|
|
101
|
+
|
|
88
102
|
self.event_brokers: List["EventBroker"] = []
|
|
89
103
|
self.event_loop = event_loop
|
|
90
104
|
|
|
@@ -124,9 +138,10 @@ class BackgroundPrivacyManager:
|
|
|
124
138
|
cls,
|
|
125
139
|
endpoints: Optional["AvailableEndpoints"],
|
|
126
140
|
event_loop: Optional["AbstractEventLoop"] = None,
|
|
141
|
+
in_memory_tracker_store: Optional[TrackerStore] = None,
|
|
127
142
|
) -> BackgroundPrivacyManager:
|
|
128
143
|
"""Create an instance of BackgroundPrivacyManager."""
|
|
129
|
-
instance = cls(endpoints, event_loop)
|
|
144
|
+
instance = cls(endpoints, event_loop, in_memory_tracker_store)
|
|
130
145
|
return await instance.initialize(endpoints)
|
|
131
146
|
|
|
132
147
|
def stop(self) -> None:
|