rasa-pro 3.13.1a18__py3-none-any.whl → 3.13.3__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/project_templates/defaults.py +25 -3
- rasa/cli/scaffold.py +3 -22
- rasa/core/actions/action.py +2 -4
- rasa/core/channels/studio_chat.py +10 -34
- rasa/core/channels/voice_stream/asr/asr_engine.py +5 -1
- rasa/core/channels/voice_stream/asr/deepgram.py +5 -0
- rasa/core/channels/voice_stream/audiocodes.py +9 -4
- rasa/core/channels/voice_stream/jambonz.py +1 -1
- rasa/core/channels/voice_stream/voice_channel.py +7 -0
- rasa/core/nlg/callback.py +1 -1
- rasa/core/policies/enterprise_search_policy.py +9 -8
- rasa/core/policies/flows/flow_executor.py +1 -8
- rasa/dialogue_understanding/commands/correct_slots_command.py +0 -10
- rasa/dialogue_understanding/generator/command_generator.py +5 -5
- rasa/dialogue_understanding/generator/flow_retrieval.py +9 -10
- rasa/dialogue_understanding/processor/command_processor.py +6 -1
- rasa/model_manager/model_api.py +3 -2
- rasa/model_manager/runner_service.py +1 -1
- rasa/model_manager/trainer_service.py +9 -12
- rasa/model_manager/utils.py +29 -1
- rasa/shared/core/domain.py +15 -62
- rasa/shared/core/flows/flow_step.py +1 -7
- rasa/shared/core/flows/yaml_flows_io.py +8 -16
- rasa/shared/core/slots.py +0 -4
- rasa/shared/importers/importer.py +0 -6
- rasa/shared/importers/utils.py +1 -77
- rasa/studio/upload.py +45 -10
- rasa/telemetry.py +1 -2
- rasa/utils/io.py +9 -27
- rasa/utils/json_utils.py +1 -6
- rasa/utils/log_utils.py +1 -5
- rasa/utils/plotting.py +1 -1
- rasa/validator.py +3 -7
- rasa/version.py +1 -1
- {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.3.dist-info}/METADATA +8 -9
- {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.3.dist-info}/RECORD +39 -261
- rasa/builder/README.md +0 -120
- rasa/builder/__init__.py +0 -0
- rasa/builder/config.py +0 -79
- rasa/builder/create_openai_vector_store.py +0 -228
- rasa/builder/exceptions.py +0 -55
- rasa/builder/inkeep-rag-response-schema.json +0 -64
- rasa/builder/inkeep_document_retrieval.py +0 -212
- rasa/builder/llm-helper-schema.json +0 -69
- rasa/builder/llm_context.py +0 -81
- rasa/builder/llm_helper_prompt.jinja2 +0 -245
- rasa/builder/llm_service.py +0 -317
- rasa/builder/logging_utils.py +0 -51
- rasa/builder/main.py +0 -147
- rasa/builder/models.py +0 -225
- rasa/builder/project_generator.py +0 -282
- rasa/builder/scrape_rasa_docs.py +0 -97
- rasa/builder/service.py +0 -742
- rasa/builder/skill_to_bot_prompt.jinja2 +0 -164
- rasa/builder/training_service.py +0 -132
- rasa/builder/validation_service.py +0 -93
- rasa/cli/project_templates/finance/actions/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/action_add_payee.py +0 -47
- rasa/cli/project_templates/finance/actions/action_ask_account.py +0 -50
- rasa/cli/project_templates/finance/actions/action_ask_account_from.py +0 -50
- rasa/cli/project_templates/finance/actions/action_ask_card.py +0 -47
- rasa/cli/project_templates/finance/actions/action_check_balance.py +0 -40
- rasa/cli/project_templates/finance/actions/action_check_card_existence.py +0 -35
- rasa/cli/project_templates/finance/actions/action_check_payee_existence.py +0 -40
- rasa/cli/project_templates/finance/actions/action_check_sufficient_funds.py +0 -41
- rasa/cli/project_templates/finance/actions/action_list_payees.py +0 -45
- rasa/cli/project_templates/finance/actions/action_process_immediate_payment.py +0 -18
- rasa/cli/project_templates/finance/actions/action_remove_payee.py +0 -49
- rasa/cli/project_templates/finance/actions/action_schedule_payment.py +0 -19
- rasa/cli/project_templates/finance/actions/action_session_start.py +0 -69
- rasa/cli/project_templates/finance/actions/action_update_card_status.py +0 -45
- rasa/cli/project_templates/finance/actions/action_validate_payment_date.py +0 -36
- rasa/cli/project_templates/finance/actions/database.py +0 -276
- rasa/cli/project_templates/finance/config.yml +0 -32
- rasa/cli/project_templates/finance/credentials.yml +0 -33
- rasa/cli/project_templates/finance/csvs/accounts.csv +0 -8
- rasa/cli/project_templates/finance/csvs/advisors.csv +0 -7
- rasa/cli/project_templates/finance/csvs/appointments.csv +0 -211
- rasa/cli/project_templates/finance/csvs/branches.csv +0 -10
- rasa/cli/project_templates/finance/csvs/cards.csv +0 -11
- rasa/cli/project_templates/finance/csvs/payees.csv +0 -10
- rasa/cli/project_templates/finance/csvs/transactions.csv +0 -71
- rasa/cli/project_templates/finance/csvs/users.csv +0 -4
- rasa/cli/project_templates/finance/data/flows/add_payee.yml +0 -29
- rasa/cli/project_templates/finance/data/flows/block_card.yml +0 -66
- rasa/cli/project_templates/finance/data/flows/check_balance.yml +0 -9
- rasa/cli/project_templates/finance/data/flows/list_payees.yml +0 -5
- rasa/cli/project_templates/finance/data/flows/remove_payee.yml +0 -21
- rasa/cli/project_templates/finance/data/flows/select_card.yml +0 -12
- rasa/cli/project_templates/finance/data/flows/transfer_money.yml +0 -67
- rasa/cli/project_templates/finance/data/flows/welcome.yml +0 -14
- rasa/cli/project_templates/finance/data/nlu.yml +0 -29
- rasa/cli/project_templates/finance/data/patterns/pattern_chitchat.yml +0 -7
- rasa/cli/project_templates/finance/data/patterns/pattern_completed.yml +0 -6
- rasa/cli/project_templates/finance/data/patterns/pattern_search.yml +0 -5
- rasa/cli/project_templates/finance/data/patterns/pattern_session_start.yml +0 -9
- rasa/cli/project_templates/finance/data/source/accounts.json +0 -51
- rasa/cli/project_templates/finance/data/source/advisors.json +0 -44
- rasa/cli/project_templates/finance/data/source/appointments.json +0 -1474
- rasa/cli/project_templates/finance/data/source/branches.json +0 -47
- rasa/cli/project_templates/finance/data/source/cards.json +0 -72
- rasa/cli/project_templates/finance/data/source/payees.json +0 -74
- rasa/cli/project_templates/finance/data/source/transactions.json +0 -492
- rasa/cli/project_templates/finance/data/source/users.json +0 -29
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +0 -7
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +0 -8
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +0 -48
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +0 -47
- rasa/cli/project_templates/finance/domain/add_payee.yml +0 -47
- rasa/cli/project_templates/finance/domain/block_card.yml +0 -101
- rasa/cli/project_templates/finance/domain/check_balance.yml +0 -9
- rasa/cli/project_templates/finance/domain/default_actions.yml +0 -16
- rasa/cli/project_templates/finance/domain/default_flows.yml +0 -33
- rasa/cli/project_templates/finance/domain/list_payees.yml +0 -4
- rasa/cli/project_templates/finance/domain/remove_payee.yml +0 -16
- rasa/cli/project_templates/finance/domain/select_card.yml +0 -12
- rasa/cli/project_templates/finance/domain/transfer_money.yml +0 -79
- rasa/cli/project_templates/finance/endpoints.yml +0 -62
- rasa/cli/project_templates/finance/prompts/command-generator.jinja2 +0 -57
- rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +0 -19
- rasa/cli/project_templates/finance/tests/conversation_repair/cancellations.yml +0 -12
- rasa/cli/project_templates/finance/tests/conversation_repair/cannot_handle.yml +0 -7
- rasa/cli/project_templates/finance/tests/conversation_repair/chitchat.yml +0 -7
- rasa/cli/project_templates/finance/tests/conversation_repair/clarification.yml +0 -9
- rasa/cli/project_templates/finance/tests/conversation_repair/completion.yml +0 -18
- rasa/cli/project_templates/finance/tests/conversation_repair/corrections.yml +0 -17
- rasa/cli/project_templates/finance/tests/conversation_repair/digressions.yml +0 -32
- rasa/cli/project_templates/finance/tests/conversation_repair/human_handoff.yml +0 -21
- rasa/cli/project_templates/finance/tests/conversation_repair/skipping_collect_steps.yml +0 -16
- rasa/cli/project_templates/finance/tests/demo_scripts/main.yml +0 -16
- rasa/cli/project_templates/finance/tests/happy_paths/balance_verification.yml +0 -15
- rasa/cli/project_templates/finance/tests/happy_paths/banking_questions.yml +0 -12
- rasa/cli/project_templates/finance/tests/happy_paths/card_blocking.yml +0 -52
- rasa/cli/project_templates/finance/tests/happy_paths/money_transfer.yml +0 -136
- rasa/cli/project_templates/finance/tests/happy_paths/payee_management.yml +0 -27
- rasa/cli/project_templates/finance/tests/happy_paths/user_greeted.yml +0 -5
- rasa/cli/project_templates/plain/actions/__init__.py +0 -0
- rasa/cli/project_templates/plain/config.yml +0 -17
- rasa/cli/project_templates/plain/credentials.yml +0 -33
- rasa/cli/project_templates/plain/data/patterns/pattern_session_start.yml +0 -7
- rasa/cli/project_templates/plain/domain.yml +0 -5
- rasa/cli/project_templates/plain/endpoints.yml +0 -58
- rasa/cli/project_templates/telco/actions/__init__.py +0 -0
- rasa/cli/project_templates/telco/actions/actions_billing.py +0 -197
- rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py +0 -43
- rasa/cli/project_templates/telco/actions/actions_run_diagnostics.py +0 -23
- rasa/cli/project_templates/telco/actions/actions_session_start.py +0 -13
- rasa/cli/project_templates/telco/config.yml +0 -25
- rasa/cli/project_templates/telco/credentials.yml +0 -33
- rasa/cli/project_templates/telco/csvs/billing.csv +0 -10
- rasa/cli/project_templates/telco/csvs/customers.csv +0 -5
- rasa/cli/project_templates/telco/data/flows/flow_global.yml +0 -5
- rasa/cli/project_templates/telco/data/flows/flow_reboot_router.yml +0 -8
- rasa/cli/project_templates/telco/data/flows/flow_reset_router.yml +0 -7
- rasa/cli/project_templates/telco/data/flows/flow_solve_internet_issue.yml +0 -73
- rasa/cli/project_templates/telco/data/flows/flow_undertand_bill.yml +0 -45
- rasa/cli/project_templates/telco/data/patterns/pattern_completed.yml +0 -7
- rasa/cli/project_templates/telco/data/patterns/pattern_human_handoff.yml +0 -6
- rasa/cli/project_templates/telco/data/patterns/pattern_search.yml +0 -7
- rasa/cli/project_templates/telco/data/patterns/pattern_session_start.yml +0 -9
- rasa/cli/project_templates/telco/docs/reset_vs_rboot_router.txt +0 -1
- rasa/cli/project_templates/telco/docs/restart_router.txt +0 -6
- rasa/cli/project_templates/telco/docs/run_speed_test.txt +0 -6
- rasa/cli/project_templates/telco/domain/domain_global.yml +0 -29
- rasa/cli/project_templates/telco/domain/domain_patterns.yml +0 -17
- rasa/cli/project_templates/telco/domain/domain_reboot_router.yml +0 -20
- rasa/cli/project_templates/telco/domain/domain_reset_router.yml +0 -11
- rasa/cli/project_templates/telco/domain/domain_run_speed_test.yml +0 -24
- rasa/cli/project_templates/telco/domain/domain_solve_internet_issue.yml +0 -74
- rasa/cli/project_templates/telco/domain/domain_undertand_bill.yml +0 -102
- rasa/cli/project_templates/telco/endpoints.yml +0 -60
- rasa/cli/project_templates/telco/prompts/command-generator.jinja2 +0 -57
- rasa/cli/project_templates/telco/tests/e2e_results_failed.yml +0 -62
- rasa/cli/project_templates/telco/tests/e2e_results_passed.yml +0 -130
- rasa/cli/project_templates/telco/tests/e2e_test_cases/billing_test_cases.yml +0 -68
- rasa/cli/project_templates/telco/tests/e2e_test_cases/global_test_cases.yml +0 -13
- rasa/cli/project_templates/telco/tests/e2e_test_cases/internet_slow_test_case.yml +0 -47
- rasa/cli/project_templates/telco/tests/e2e_test_cases/out_of_scope_test_case.yml +0 -21
- rasa/cli/project_templates/telco/tests/e2e_test_cases/patterns_test_cases.yml +0 -15
- rasa/shared/importers/static.py +0 -63
- rasa/utils/openapi.py +0 -144
- {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.3.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.3.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.3.dist-info}/entry_points.txt +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
import tempfile
|
|
4
5
|
from typing import Any, Dict, List, Optional, Text
|
|
5
6
|
|
|
@@ -78,14 +79,35 @@ def _get_domain_from_importer(config: Dict[Text, Any]) -> Domain:
|
|
|
78
79
|
Returns:
|
|
79
80
|
A Domain object .
|
|
80
81
|
"""
|
|
81
|
-
with
|
|
82
|
-
|
|
82
|
+
# We create the file with delete=False so that it can be re-opened on
|
|
83
|
+
# Windows. If delete=True, the file is opened with the _O_TEMPORARY flag
|
|
84
|
+
# which blocks any second open() call.
|
|
85
|
+
tmp = tempfile.NamedTemporaryFile("w+", suffix=".yml", delete=False)
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
path = tmp.name
|
|
89
|
+
|
|
90
|
+
# write_yaml() re-opens the same path. On Windows an already-open
|
|
91
|
+
# handle keeps the file locked for further opens, so we close
|
|
92
|
+
# the first handle before we call write_yaml().
|
|
93
|
+
tmp.close()
|
|
94
|
+
write_yaml(config, path)
|
|
95
|
+
|
|
83
96
|
importer = TrainingDataImporter.load_from_config(
|
|
84
97
|
domain_path=FlowSyncImporter.default_pattern_path(),
|
|
85
|
-
config_path=
|
|
98
|
+
config_path=path,
|
|
86
99
|
)
|
|
87
100
|
return importer.get_domain()
|
|
88
101
|
|
|
102
|
+
finally:
|
|
103
|
+
# Because we passed delete=False above, Python will not clean the file
|
|
104
|
+
# To avoid leaving garbage in the temp directory after the tests run,
|
|
105
|
+
# we remove it explicitly.
|
|
106
|
+
try:
|
|
107
|
+
os.remove(path)
|
|
108
|
+
except FileNotFoundError:
|
|
109
|
+
pass
|
|
110
|
+
|
|
89
111
|
|
|
90
112
|
def get_pattern_defaults(config: Dict[Text, Any]) -> PatternDefaults:
|
|
91
113
|
"""Get the default flows, responses and slots for patterns.
|
rasa/cli/scaffold.py
CHANGED
|
@@ -24,21 +24,10 @@ class ProjectTemplateName(Enum):
|
|
|
24
24
|
|
|
25
25
|
DEFAULT = "default"
|
|
26
26
|
TUTORIAL = "tutorial"
|
|
27
|
-
PLAIN = "plain"
|
|
28
|
-
FINANCE = "finance"
|
|
29
|
-
TELCO = "telco"
|
|
30
27
|
|
|
31
28
|
def __str__(self) -> str:
|
|
32
29
|
return self.value
|
|
33
30
|
|
|
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
|
-
|
|
42
31
|
|
|
43
32
|
template_domain_path = defaultdict(lambda: DEFAULT_DOMAIN_PATH)
|
|
44
33
|
template_domain_path[ProjectTemplateName.DEFAULT] = "domain"
|
|
@@ -170,17 +159,9 @@ def create_initial_project(
|
|
|
170
159
|
path: Text, template: ProjectTemplateName = ProjectTemplateName.DEFAULT
|
|
171
160
|
) -> None:
|
|
172
161
|
"""Creates directory structure and templates for initial project."""
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
if hasattr(dir_util, "_path_created"):
|
|
180
|
-
dir_util._path_created.clear()
|
|
181
|
-
else:
|
|
182
|
-
dir_util.SkipRepeatAbsolutePaths.clear()
|
|
183
|
-
dir_util.copy_tree(scaffold_path(template), path)
|
|
162
|
+
from distutils.dir_util import copy_tree
|
|
163
|
+
|
|
164
|
+
copy_tree(scaffold_path(template), path)
|
|
184
165
|
|
|
185
166
|
|
|
186
167
|
def scaffold_path(template: ProjectTemplateName) -> Text:
|
rasa/core/actions/action.py
CHANGED
|
@@ -908,12 +908,10 @@ class RemoteAction(Action):
|
|
|
908
908
|
draft.setdefault("buttons", [])
|
|
909
909
|
draft["buttons"].extend(buttons)
|
|
910
910
|
|
|
911
|
+
# Avoid overwriting `draft` values with empty values
|
|
911
912
|
response = {k: v for k, v in response.items() if v}
|
|
912
|
-
|
|
913
913
|
response.update(draft)
|
|
914
|
-
bot_messages.append(
|
|
915
|
-
create_bot_utterance(response, tracker.current_language)
|
|
916
|
-
)
|
|
914
|
+
bot_messages.append(create_bot_utterance(response))
|
|
917
915
|
|
|
918
916
|
return bot_messages
|
|
919
917
|
|
|
@@ -42,14 +42,14 @@ if TYPE_CHECKING:
|
|
|
42
42
|
from sanic import Sanic, Websocket # type: ignore[attr-defined]
|
|
43
43
|
from socketio import AsyncServer
|
|
44
44
|
|
|
45
|
-
from rasa.core.channels.channel import UserMessage
|
|
45
|
+
from rasa.core.channels.channel import InputChannel, UserMessage
|
|
46
46
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
structlogger = structlog.get_logger()
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def tracker_as_dump(tracker: "DialogueStateTracker") ->
|
|
52
|
+
def tracker_as_dump(tracker: "DialogueStateTracker") -> str:
|
|
53
53
|
"""Create a dump of the tracker state."""
|
|
54
54
|
from rasa.shared.core.trackers import get_trackers_for_conversation_sessions
|
|
55
55
|
|
|
@@ -60,9 +60,8 @@ def tracker_as_dump(tracker: "DialogueStateTracker") -> Dict[str, Any]:
|
|
|
60
60
|
else:
|
|
61
61
|
last_tracker = multiple_tracker_sessions[-1]
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return last_tracker.current_state(EventVerbosity.AFTER_RESTART)
|
|
63
|
+
state = last_tracker.current_state(EventVerbosity.AFTER_RESTART)
|
|
64
|
+
return json.dumps(state)
|
|
66
65
|
|
|
67
66
|
|
|
68
67
|
def does_need_action_prediction(tracker: "DialogueStateTracker") -> bool:
|
|
@@ -149,7 +148,6 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
149
148
|
from rasa.core.agent import Agent
|
|
150
149
|
|
|
151
150
|
self.agent: Optional[Agent] = None
|
|
152
|
-
self.latest_tracker_session_id = None
|
|
153
151
|
|
|
154
152
|
# Initialize the SocketIO input channel
|
|
155
153
|
SocketIOInput.__init__(
|
|
@@ -181,9 +179,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
181
179
|
self._register_tracker_update_hook()
|
|
182
180
|
|
|
183
181
|
@classmethod
|
|
184
|
-
def from_credentials(
|
|
185
|
-
cls, credentials: Optional[Dict[Text, Any]]
|
|
186
|
-
) -> "StudioChatInput":
|
|
182
|
+
def from_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> "InputChannel":
|
|
187
183
|
"""Creates a StudioChatInput channel from credentials."""
|
|
188
184
|
credentials = credentials or {}
|
|
189
185
|
|
|
@@ -215,11 +211,6 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
215
211
|
if not self.sio:
|
|
216
212
|
structlogger.error("studio_chat.on_tracker_updated.sio_not_initialized")
|
|
217
213
|
return
|
|
218
|
-
|
|
219
|
-
# we need the latest session id to use it for the llm helper to get the
|
|
220
|
-
# most recent conversation the user had with the bot.
|
|
221
|
-
self.latest_tracker_session_id = sender_id
|
|
222
|
-
|
|
223
214
|
await self.sio.emit("tracker", tracker_dump, room=sender_id)
|
|
224
215
|
|
|
225
216
|
async def on_message_proxy(
|
|
@@ -231,14 +222,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
231
222
|
|
|
232
223
|
Triggers a tracker update notification after processing the message.
|
|
233
224
|
"""
|
|
234
|
-
|
|
235
|
-
await on_new_message(message)
|
|
236
|
-
except Exception as e:
|
|
237
|
-
structlogger.exception(
|
|
238
|
-
"studio_chat.on_new_message.error",
|
|
239
|
-
error=str(e),
|
|
240
|
-
sender_id=message.sender_id,
|
|
241
|
-
)
|
|
225
|
+
await on_new_message(message)
|
|
242
226
|
|
|
243
227
|
if not self.agent:
|
|
244
228
|
structlogger.error("studio_chat.on_message_proxy.agent_not_initialized")
|
|
@@ -291,7 +275,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
291
275
|
async def collect_call_parameters(
|
|
292
276
|
self, channel_websocket: "Websocket"
|
|
293
277
|
) -> Optional[CallParameters]:
|
|
294
|
-
"""Voice method to collect call parameters
|
|
278
|
+
"""Voice method to collect call parameters"""
|
|
295
279
|
session_id = channel_websocket.session_id
|
|
296
280
|
return CallParameters(session_id, "local", "local", stream_id=session_id)
|
|
297
281
|
|
|
@@ -321,7 +305,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
321
305
|
def create_output_channel(
|
|
322
306
|
self, voice_websocket: "Websocket", tts_engine: TTSEngine
|
|
323
307
|
) -> VoiceOutputChannel:
|
|
324
|
-
"""Create a voice output channel
|
|
308
|
+
"""Create a voice output channel"""
|
|
325
309
|
return StudioVoiceOutputChannel(
|
|
326
310
|
voice_websocket,
|
|
327
311
|
tts_engine,
|
|
@@ -448,16 +432,8 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
448
432
|
ws.put_message(data)
|
|
449
433
|
return
|
|
450
434
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
await self.handle_user_message(sid, data, on_new_message)
|
|
454
|
-
except Exception as e:
|
|
455
|
-
structlogger.exception(
|
|
456
|
-
"studio_chat.sio.handle_message.error",
|
|
457
|
-
error=str(e),
|
|
458
|
-
sid=sid,
|
|
459
|
-
)
|
|
460
|
-
await self.sio.emit("error", str(e), room=sid)
|
|
435
|
+
# Handle text messages
|
|
436
|
+
await self.handle_user_message(sid, data, on_new_message)
|
|
461
437
|
|
|
462
438
|
@self.sio.on("update_tracker", namespace=self.namespace)
|
|
463
439
|
async def on_update_tracker(sid: Text, data: Dict) -> None:
|
|
@@ -26,7 +26,7 @@ logger = structlog.get_logger(__name__)
|
|
|
26
26
|
|
|
27
27
|
@dataclass
|
|
28
28
|
class ASREngineConfig(MergeableConfig):
|
|
29
|
-
|
|
29
|
+
keep_alive_interval: int = 5 # seconds
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class ASREngine(Generic[T]):
|
|
@@ -93,3 +93,7 @@ class ASREngine(Generic[T]):
|
|
|
93
93
|
def get_default_config() -> T:
|
|
94
94
|
"""Get the default config for this component."""
|
|
95
95
|
raise NotImplementedError
|
|
96
|
+
|
|
97
|
+
async def send_keep_alive(self) -> None:
|
|
98
|
+
"""Send a keep-alive message to the ASR system if supported."""
|
|
99
|
+
pass
|
|
@@ -145,3 +145,8 @@ class DeepgramASR(ASREngine[DeepgramASRConfig]):
|
|
|
145
145
|
def concatenate_transcripts(t1: str, t2: str) -> str:
|
|
146
146
|
"""Concatenate two transcripts making sure there is a space between them."""
|
|
147
147
|
return (t1.strip() + " " + t2.strip()).strip()
|
|
148
|
+
|
|
149
|
+
async def send_keep_alive(self) -> None:
|
|
150
|
+
"""Send a keep-alive message to the Deepgram websocket connection."""
|
|
151
|
+
if self.asr_socket is not None:
|
|
152
|
+
await self.asr_socket.send(json.dumps({"type": "KeepAlive"}))
|
|
@@ -81,6 +81,12 @@ class AudiocodesVoiceOutputChannel(VoiceOutputChannel):
|
|
|
81
81
|
logger.debug("Sending start marker", stream_id=self._get_stream_id())
|
|
82
82
|
await self.voice_websocket.send(media_message)
|
|
83
83
|
|
|
84
|
+
# This should be set when the bot actually starts speaking
|
|
85
|
+
# however, Audiocodes does not have an event to indicate that.
|
|
86
|
+
# This is an approximation, as the bot will be sent the audio chunks next
|
|
87
|
+
# which are played to the user immediately.
|
|
88
|
+
call_state.is_bot_speaking = True # type: ignore[attr-defined]
|
|
89
|
+
|
|
84
90
|
async def send_intermediate_marker(self, recipient_id: str) -> None:
|
|
85
91
|
"""Audiocodes doesn't need intermediate markers, so do nothing."""
|
|
86
92
|
pass
|
|
@@ -170,21 +176,20 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
|
|
|
170
176
|
if data["type"] == "activities":
|
|
171
177
|
activities = data["activities"]
|
|
172
178
|
for activity in activities:
|
|
173
|
-
logger.debug("audiocodes_stream.activity", data=activity)
|
|
174
179
|
if activity["name"] == "start":
|
|
175
|
-
#
|
|
180
|
+
# handled in collect_call_parameters
|
|
176
181
|
pass
|
|
177
182
|
elif activity["name"] == "dtmf":
|
|
178
|
-
|
|
183
|
+
logger.info("audiocodes_stream.dtmf_ignored", data=activity)
|
|
179
184
|
pass
|
|
180
185
|
elif activity["name"] == "playFinished":
|
|
181
186
|
logger.debug("audiocodes_stream.playFinished", data=activity)
|
|
187
|
+
call_state.is_bot_speaking = False # type: ignore[attr-defined]
|
|
182
188
|
if call_state.should_hangup:
|
|
183
189
|
logger.info("audiocodes_stream.hangup")
|
|
184
190
|
self._send_hangup(ws, data)
|
|
185
191
|
# the conversation should continue until
|
|
186
192
|
# we receive a end message from audiocodes
|
|
187
|
-
pass
|
|
188
193
|
else:
|
|
189
194
|
logger.warning("audiocodes_stream.unknown_activity", data=activity)
|
|
190
195
|
elif data["type"] == "userStream.start":
|
|
@@ -31,7 +31,7 @@ from rasa.core.channels.voice_stream.voice_channel import (
|
|
|
31
31
|
|
|
32
32
|
logger = structlog.get_logger()
|
|
33
33
|
|
|
34
|
-
JAMBONZ_STREAMS_WEBSOCKET_PATH = "webhooks/
|
|
34
|
+
JAMBONZ_STREAMS_WEBSOCKET_PATH = "webhooks/jambonz_stream/websocket"
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def map_call_params(data: Dict[Text, str]) -> CallParameters:
|
|
@@ -468,10 +468,17 @@ class VoiceInputChannel(InputChannel):
|
|
|
468
468
|
call_parameters,
|
|
469
469
|
)
|
|
470
470
|
|
|
471
|
+
async def asr_keep_alive_task() -> None:
|
|
472
|
+
interval = getattr(asr_engine.config, "keep_alive_interval", 5)
|
|
473
|
+
while True:
|
|
474
|
+
await asyncio.sleep(interval)
|
|
475
|
+
await asr_engine.send_keep_alive()
|
|
476
|
+
|
|
471
477
|
tasks = [
|
|
472
478
|
asyncio.create_task(consume_audio_bytes()),
|
|
473
479
|
asyncio.create_task(receive_asr_events()),
|
|
474
480
|
asyncio.create_task(handle_asr_events()),
|
|
481
|
+
asyncio.create_task(asr_keep_alive_task()),
|
|
475
482
|
]
|
|
476
483
|
await asyncio.wait(
|
|
477
484
|
tasks,
|
rasa/core/nlg/callback.py
CHANGED
|
@@ -19,7 +19,7 @@ def nlg_response_format_spec() -> Dict[Text, Any]:
|
|
|
19
19
|
return {
|
|
20
20
|
"type": "object",
|
|
21
21
|
"properties": {
|
|
22
|
-
"text": {"type": "string"},
|
|
22
|
+
"text": {"type": ["string", "null"]},
|
|
23
23
|
"id": {"type": ["string", "null"]},
|
|
24
24
|
"buttons": {"type": ["array", "null"], "items": {"type": "object"}},
|
|
25
25
|
"elements": {"type": ["array", "null"], "items": {"type": "object"}},
|
|
@@ -679,7 +679,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
679
679
|
answer_relevant = not _ENTERPRISE_SEARCH_ANSWER_NOT_RELEVANT_PATTERN.search(
|
|
680
680
|
llm_answer
|
|
681
681
|
)
|
|
682
|
-
|
|
682
|
+
|
|
683
683
|
return _RelevancyCheckResponse(
|
|
684
684
|
answer=llm_answer if answer_relevant else None,
|
|
685
685
|
relevant=answer_relevant,
|
|
@@ -784,19 +784,17 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
784
784
|
if not os.path.exists(docs_folder) or not os.path.isdir(docs_folder):
|
|
785
785
|
error_message = (
|
|
786
786
|
f"Document source directory does not exist or is not a "
|
|
787
|
-
f"directory: '{
|
|
787
|
+
f"directory: '{docs_folder}'. "
|
|
788
788
|
"Please specify a valid path to the documents source directory in the "
|
|
789
789
|
"vector_store configuration."
|
|
790
790
|
)
|
|
791
791
|
structlogger.error(
|
|
792
792
|
"enterprise_search_policy.train.faiss.invalid_source_directory",
|
|
793
793
|
message=error_message,
|
|
794
|
-
docs_folder={os.path.abspath(docs_folder)},
|
|
795
|
-
configuration_value=docs_folder,
|
|
796
794
|
)
|
|
797
795
|
print_error_and_exit(error_message)
|
|
798
796
|
|
|
799
|
-
docs = glob.glob(os.path.join(docs_folder, "
|
|
797
|
+
docs = glob.glob(os.path.join(docs_folder, "*.txt"), recursive=True)
|
|
800
798
|
if not docs or len(docs) < 1:
|
|
801
799
|
error_message = (
|
|
802
800
|
f"Document source directory is empty: '{docs_folder}'. "
|
|
@@ -1135,7 +1133,8 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
1135
1133
|
embeddings_config: Dict[Text, Any],
|
|
1136
1134
|
log_source_method: str,
|
|
1137
1135
|
) -> None:
|
|
1138
|
-
"""
|
|
1136
|
+
"""
|
|
1137
|
+
Perform the health checks using resolved LLM and embeddings configurations.
|
|
1139
1138
|
Resolved means the configuration is either:
|
|
1140
1139
|
- A reference to a model group that has already been expanded into
|
|
1141
1140
|
its corresponding configuration using the information from
|
|
@@ -1164,7 +1163,8 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
1164
1163
|
|
|
1165
1164
|
@classmethod
|
|
1166
1165
|
def get_system_default_prompt_based_on_config(cls, config: Dict[str, Any]) -> str:
|
|
1167
|
-
"""
|
|
1166
|
+
"""
|
|
1167
|
+
Resolves the default prompt template for Enterprise Search Policy based on
|
|
1168
1168
|
the component's configuration.
|
|
1169
1169
|
|
|
1170
1170
|
- The old prompt is selected when both citation and relevancy check are either
|
|
@@ -1195,7 +1195,8 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
|
|
|
1195
1195
|
relevancy_check_enabled: bool,
|
|
1196
1196
|
citation_enabled: bool,
|
|
1197
1197
|
) -> str:
|
|
1198
|
-
"""
|
|
1198
|
+
"""
|
|
1199
|
+
Returns the appropriate default prompt template based on the feature flags.
|
|
1199
1200
|
|
|
1200
1201
|
The selection follows this priority:
|
|
1201
1202
|
1. If relevancy check is enabled, return the prompt that includes both relevancy
|
|
@@ -740,14 +740,7 @@ def _run_action_step(
|
|
|
740
740
|
# do not log about non-existing validation actions of collect steps
|
|
741
741
|
utter_action_name = render_template_variables("{{context.utter}}", context)
|
|
742
742
|
if utter_action_name not in available_actions:
|
|
743
|
-
structlogger.warning(
|
|
744
|
-
"flow.step.run.action.unknown",
|
|
745
|
-
action=action_name,
|
|
746
|
-
event_info=(
|
|
747
|
-
f"The action '{action_name}' is not defined in the domain but "
|
|
748
|
-
f"getting triggered by the flow '{step.flow_id}'."
|
|
749
|
-
),
|
|
750
|
-
)
|
|
743
|
+
structlogger.warning("flow.step.run.action.unknown", action=action_name)
|
|
751
744
|
return ContinueFlowWithNextStep(events=initial_events)
|
|
752
745
|
|
|
753
746
|
|
|
@@ -232,16 +232,6 @@ class CorrectSlotsCommand(Command):
|
|
|
232
232
|
proposed_slots, all_flows, tracker
|
|
233
233
|
)
|
|
234
234
|
|
|
235
|
-
if not earliest_collect and not is_reset_only:
|
|
236
|
-
# if we could not find any step in the flow, where the slots were
|
|
237
|
-
# previously set, and we also don't want to reset the slots, do
|
|
238
|
-
# not correct the slots.
|
|
239
|
-
structlogger.debug(
|
|
240
|
-
"correct_slots_command.skip_correction",
|
|
241
|
-
is_reset_only=is_reset_only,
|
|
242
|
-
)
|
|
243
|
-
return None
|
|
244
|
-
|
|
245
235
|
return CorrectionPatternFlowStackFrame(
|
|
246
236
|
is_reset_only=is_reset_only,
|
|
247
237
|
corrected_slots=proposed_slots,
|
|
@@ -114,7 +114,7 @@ class CommandGenerator:
|
|
|
114
114
|
# slot asked by the active collect step.
|
|
115
115
|
# Or return a CannotHandleCommand if no matching command is found.
|
|
116
116
|
commands = self._filter_commands_during_force_slot_filling(
|
|
117
|
-
commands,
|
|
117
|
+
commands, flows, tracker
|
|
118
118
|
)
|
|
119
119
|
|
|
120
120
|
commands_dicts = [command.as_dict() for command in commands]
|
|
@@ -385,14 +385,14 @@ class CommandGenerator:
|
|
|
385
385
|
@staticmethod
|
|
386
386
|
def _filter_commands_during_force_slot_filling(
|
|
387
387
|
commands: List[Command],
|
|
388
|
-
|
|
388
|
+
flows: FlowsList,
|
|
389
389
|
tracker: Optional[DialogueStateTracker] = None,
|
|
390
390
|
) -> List[Command]:
|
|
391
391
|
"""Filter commands during a collect step that has set `force_slot_filling`.
|
|
392
392
|
|
|
393
393
|
Args:
|
|
394
394
|
commands: The commands to filter.
|
|
395
|
-
|
|
395
|
+
flows: All flows.
|
|
396
396
|
tracker: The tracker.
|
|
397
397
|
|
|
398
398
|
Returns:
|
|
@@ -409,7 +409,7 @@ class CommandGenerator:
|
|
|
409
409
|
)
|
|
410
410
|
return commands
|
|
411
411
|
|
|
412
|
-
updated_flows = find_updated_flows(tracker,
|
|
412
|
+
updated_flows = find_updated_flows(tracker, flows)
|
|
413
413
|
if updated_flows:
|
|
414
414
|
structlogger.debug(
|
|
415
415
|
"command_generator.filter_commands_during_force_slot_filling.running_flows_were_updated",
|
|
@@ -418,7 +418,7 @@ class CommandGenerator:
|
|
|
418
418
|
return [HandleCodeChangeCommand()]
|
|
419
419
|
|
|
420
420
|
stack = tracker.stack
|
|
421
|
-
step = get_current_collect_step(stack,
|
|
421
|
+
step = get_current_collect_step(stack, flows)
|
|
422
422
|
|
|
423
423
|
if step is None or not step.force_slot_filling:
|
|
424
424
|
return commands
|
|
@@ -219,6 +219,11 @@ class FlowRetrieval(EmbeddingsHealthCheckMixin):
|
|
|
219
219
|
if self.vector_store is not None:
|
|
220
220
|
with self._model_storage.write_to(self._resource) as model_path:
|
|
221
221
|
self.vector_store.save_local(model_path)
|
|
222
|
+
else:
|
|
223
|
+
structlogger.warning(
|
|
224
|
+
"flow_retrieval.persist_vector_store.not_initialized",
|
|
225
|
+
event_info="Vector store is None, not persisted.",
|
|
226
|
+
)
|
|
222
227
|
|
|
223
228
|
def _persist_config(self) -> None:
|
|
224
229
|
with self._model_storage.write_to(self._resource) as path:
|
|
@@ -244,16 +249,6 @@ class FlowRetrieval(EmbeddingsHealthCheckMixin):
|
|
|
244
249
|
)
|
|
245
250
|
|
|
246
251
|
flows_to_embedd = flows.exclude_link_only_flows()
|
|
247
|
-
|
|
248
|
-
if not flows_to_embedd:
|
|
249
|
-
structlogger.debug(
|
|
250
|
-
"flow_retrieval.populate_vector_store.no_flows_to_embed",
|
|
251
|
-
event_info=(
|
|
252
|
-
"No flows to embed in the vector store, skipping population."
|
|
253
|
-
),
|
|
254
|
-
)
|
|
255
|
-
return
|
|
256
|
-
|
|
257
252
|
embeddings = self._create_embedder(self.config)
|
|
258
253
|
documents = self._generate_flow_documents(flows_to_embedd, domain)
|
|
259
254
|
try:
|
|
@@ -425,6 +420,10 @@ class FlowRetrieval(EmbeddingsHealthCheckMixin):
|
|
|
425
420
|
The top k documents with similarity scores.
|
|
426
421
|
"""
|
|
427
422
|
if self.vector_store is None:
|
|
423
|
+
structlogger.error(
|
|
424
|
+
"flow_retrieval.query_vector_store.vector_store_not_configured",
|
|
425
|
+
event_info="Vector store is not configured",
|
|
426
|
+
)
|
|
428
427
|
return []
|
|
429
428
|
try:
|
|
430
429
|
documents_with_scores = (
|
|
@@ -398,7 +398,12 @@ def clean_up_commands(
|
|
|
398
398
|
"""
|
|
399
399
|
domain = domain if domain else Domain.empty()
|
|
400
400
|
|
|
401
|
-
slots_so_far,
|
|
401
|
+
slots_so_far, _ = filled_slots_for_active_flow(tracker, all_flows)
|
|
402
|
+
|
|
403
|
+
# update the slots so far with the slots that were set in the tracker
|
|
404
|
+
slots_so_far.update(
|
|
405
|
+
{event.key for event in tracker.events if isinstance(event, SlotSet)}
|
|
406
|
+
)
|
|
402
407
|
|
|
403
408
|
clean_commands: List[Command] = []
|
|
404
409
|
|
rasa/model_manager/model_api.py
CHANGED
|
@@ -39,9 +39,11 @@ from rasa.model_manager.trainer_service import (
|
|
|
39
39
|
update_training_status,
|
|
40
40
|
)
|
|
41
41
|
from rasa.model_manager.utils import (
|
|
42
|
+
InvalidPathException,
|
|
42
43
|
get_logs_content,
|
|
43
44
|
logs_base_path,
|
|
44
45
|
models_base_path,
|
|
46
|
+
subpath,
|
|
45
47
|
)
|
|
46
48
|
from rasa.model_manager.warm_rasa_process import (
|
|
47
49
|
initialize_warm_rasa_process,
|
|
@@ -51,7 +53,6 @@ from rasa.server import ErrorResponse
|
|
|
51
53
|
from rasa.shared.exceptions import InvalidConfigException
|
|
52
54
|
from rasa.shared.utils.yaml import dump_obj_as_yaml_to_string
|
|
53
55
|
from rasa.studio.upload import build_calm_import_parts
|
|
54
|
-
from rasa.utils.io import InvalidPathException, subpath
|
|
55
56
|
|
|
56
57
|
dotenv.load_dotenv()
|
|
57
58
|
|
|
@@ -104,7 +105,7 @@ async def update_status_of_all_bots() -> None:
|
|
|
104
105
|
await update_bot_status(bot)
|
|
105
106
|
|
|
106
107
|
|
|
107
|
-
def base_server_url(request:
|
|
108
|
+
def base_server_url(request: Request) -> str:
|
|
108
109
|
"""Return the base URL of the server."""
|
|
109
110
|
if SERVER_BASE_URL:
|
|
110
111
|
return SERVER_BASE_URL.rstrip("/")
|
|
@@ -15,11 +15,11 @@ from rasa.model_manager import config
|
|
|
15
15
|
from rasa.model_manager.utils import (
|
|
16
16
|
logs_path,
|
|
17
17
|
models_base_path,
|
|
18
|
+
subpath,
|
|
18
19
|
write_encoded_data_to_file,
|
|
19
20
|
)
|
|
20
21
|
from rasa.model_manager.warm_rasa_process import start_rasa_process
|
|
21
22
|
from rasa.studio.prompts import handle_prompts
|
|
22
|
-
from rasa.utils.io import subpath
|
|
23
23
|
|
|
24
24
|
structlogger = structlog.get_logger()
|
|
25
25
|
|
|
@@ -14,6 +14,7 @@ from rasa.model_manager.utils import (
|
|
|
14
14
|
ensure_base_directory_exists,
|
|
15
15
|
logs_path,
|
|
16
16
|
models_base_path,
|
|
17
|
+
subpath,
|
|
17
18
|
write_encoded_data_to_file,
|
|
18
19
|
)
|
|
19
20
|
from rasa.model_manager.warm_rasa_process import (
|
|
@@ -21,7 +22,6 @@ from rasa.model_manager.warm_rasa_process import (
|
|
|
21
22
|
)
|
|
22
23
|
from rasa.model_training import generate_random_model_name
|
|
23
24
|
from rasa.studio.prompts import handle_prompts
|
|
24
|
-
from rasa.utils.io import subpath
|
|
25
25
|
|
|
26
26
|
structlogger = structlog.get_logger()
|
|
27
27
|
|
|
@@ -53,15 +53,6 @@ class TrainingSession(BaseModel):
|
|
|
53
53
|
"""Check if the training is running."""
|
|
54
54
|
return self.status == TrainingSessionStatus.RUNNING
|
|
55
55
|
|
|
56
|
-
def has_just_finished(self) -> bool:
|
|
57
|
-
if not self.is_status_indicating_alive():
|
|
58
|
-
# skip if the training is not running
|
|
59
|
-
return False
|
|
60
|
-
if self.process.poll() is None:
|
|
61
|
-
# process is still running
|
|
62
|
-
return False
|
|
63
|
-
return True
|
|
64
|
-
|
|
65
56
|
def model_path(self) -> str:
|
|
66
57
|
"""Return the path to the model."""
|
|
67
58
|
return subpath(models_base_path(), f"{self.model_name}.tar.gz")
|
|
@@ -98,8 +89,14 @@ def terminate_training(training: TrainingSession) -> None:
|
|
|
98
89
|
|
|
99
90
|
|
|
100
91
|
def update_training_status(training: TrainingSession) -> None:
|
|
101
|
-
if training.
|
|
102
|
-
|
|
92
|
+
if not training.is_status_indicating_alive():
|
|
93
|
+
# skip if the training is not running
|
|
94
|
+
return
|
|
95
|
+
if training.process.poll() is None:
|
|
96
|
+
# process is still running
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
complete_training(training)
|
|
103
100
|
|
|
104
101
|
|
|
105
102
|
def complete_training(training: TrainingSession) -> None:
|
rasa/model_manager/utils.py
CHANGED
|
@@ -5,11 +5,15 @@ from typing import Optional
|
|
|
5
5
|
import structlog
|
|
6
6
|
|
|
7
7
|
from rasa.model_manager import config
|
|
8
|
-
from rasa.
|
|
8
|
+
from rasa.shared.exceptions import RasaException
|
|
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
|
+
|
|
13
17
|
def write_encoded_data_to_file(encoded_data: bytes, file: str) -> None:
|
|
14
18
|
"""Write base64 encoded data to a file."""
|
|
15
19
|
# create the directory if it does not exist of the parent directory
|
|
@@ -49,6 +53,30 @@ def logs_path(action_id: str) -> str:
|
|
|
49
53
|
return subpath(logs_base_path(), f"{action_id}.txt")
|
|
50
54
|
|
|
51
55
|
|
|
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
|
+
|
|
52
80
|
def get_logs_content(action_id: str) -> Optional[str]:
|
|
53
81
|
"""Return the content of the log file for a given action id."""
|
|
54
82
|
try:
|