rasa-pro 3.13.8__py3-none-any.whl → 3.14.0a1__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/__init__.py +0 -0
- rasa/builder/auth.py +176 -0
- rasa/builder/config.py +91 -0
- rasa/builder/copilot/__init__.py +0 -0
- rasa/builder/copilot/constants.py +28 -0
- rasa/builder/copilot/copilot.py +376 -0
- rasa/builder/copilot/copilot_response_handler.py +522 -0
- rasa/builder/copilot/copilot_templated_message_provider.py +58 -0
- rasa/builder/copilot/exceptions.py +32 -0
- rasa/builder/copilot/models.py +464 -0
- rasa/builder/copilot/prompts/__init__.py +0 -0
- rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +771 -0
- rasa/builder/copilot/signing.py +305 -0
- rasa/builder/copilot/telemetry.py +200 -0
- rasa/builder/copilot/templated_messages/__init__.py +0 -0
- rasa/builder/copilot/templated_messages/copilot_internal_messages_templates.yml +16 -0
- rasa/builder/copilot/templated_messages/copilot_templated_responses.yml +38 -0
- rasa/builder/document_retrieval/__init__.py +0 -0
- rasa/builder/document_retrieval/constants.py +15 -0
- rasa/builder/document_retrieval/inkeep-rag-response-schema.json +64 -0
- rasa/builder/document_retrieval/inkeep_document_retrieval.py +238 -0
- rasa/builder/document_retrieval/models.py +62 -0
- rasa/builder/download.py +147 -0
- rasa/builder/exceptions.py +91 -0
- rasa/builder/guardrails/__init__.py +1 -0
- rasa/builder/guardrails/constants.py +9 -0
- rasa/builder/guardrails/exceptions.py +4 -0
- rasa/builder/guardrails/lakera.py +206 -0
- rasa/builder/guardrails/models.py +231 -0
- rasa/builder/guardrails/store.py +238 -0
- rasa/builder/guardrails/utils.py +328 -0
- rasa/builder/job_manager.py +87 -0
- rasa/builder/jobs.py +276 -0
- rasa/builder/llm_service.py +246 -0
- rasa/builder/logging_utils.py +265 -0
- rasa/builder/main.py +199 -0
- rasa/builder/models.py +216 -0
- rasa/builder/project_generator.py +462 -0
- rasa/builder/project_info.py +72 -0
- rasa/builder/scrape_rasa_docs.py +97 -0
- rasa/builder/service.py +1335 -0
- rasa/builder/shared/tracker_context.py +212 -0
- rasa/builder/skill_to_bot_prompt.jinja2 +164 -0
- rasa/builder/training_service.py +183 -0
- rasa/builder/validation_service.py +97 -0
- rasa/cli/project_templates/basic/actions/__init__ +0 -0
- rasa/cli/project_templates/basic/actions/action_human_handoff.py +40 -0
- rasa/cli/project_templates/basic/config.yml +30 -0
- rasa/cli/project_templates/basic/credentials.yml +33 -0
- rasa/cli/project_templates/basic/data/data.md +9 -0
- rasa/cli/project_templates/basic/data/general/feedback.yml +21 -0
- rasa/cli/project_templates/basic/data/general/goodbye.yml +6 -0
- rasa/cli/project_templates/basic/data/general/hello.yml +6 -0
- rasa/cli/project_templates/basic/data/general/help.yml +6 -0
- rasa/cli/project_templates/basic/data/general/human_handoff.yml +16 -0
- rasa/cli/project_templates/basic/data/general/show_faqs.yml +6 -0
- rasa/cli/project_templates/basic/data/system/patterns/pattern_cannot_handle.yml +7 -0
- rasa/cli/project_templates/basic/data/system/patterns/pattern_completed.yml +7 -0
- rasa/cli/project_templates/basic/data/system/patterns/pattern_correction.yml +7 -0
- rasa/cli/project_templates/basic/data/system/patterns/pattern_search.yml +8 -0
- rasa/cli/project_templates/basic/data/system/patterns/pattern_session_start.yml +8 -0
- rasa/cli/project_templates/basic/docs/docs.md +5 -0
- rasa/cli/project_templates/basic/docs/template.txt +28 -0
- rasa/cli/project_templates/basic/domain/domain.md +9 -0
- rasa/cli/project_templates/basic/domain/general/feedback.yml +25 -0
- rasa/cli/project_templates/basic/domain/general/goodbye.yml +9 -0
- rasa/cli/project_templates/basic/domain/general/hello.yml +7 -0
- rasa/cli/project_templates/basic/domain/general/help.yml +21 -0
- rasa/cli/project_templates/basic/domain/general/human_handoff.yml +32 -0
- rasa/cli/project_templates/basic/domain/general/show_faqs.yml +14 -0
- rasa/cli/project_templates/basic/domain/system/patterns/pattern_cannot_handle.yml +5 -0
- rasa/cli/project_templates/basic/domain/system/patterns/pattern_session_start.yml +19 -0
- rasa/cli/project_templates/basic/endpoints.yml +77 -0
- rasa/cli/project_templates/basic/prompts/rephraser_demo_personality_prompt.jinja2 +38 -0
- rasa/cli/project_templates/default/config.yml +5 -1
- rasa/cli/project_templates/default/endpoints.yml +15 -0
- rasa/cli/project_templates/finance/actions/__init__.py +46 -0
- rasa/cli/project_templates/finance/actions/accounts/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +47 -0
- rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +40 -0
- rasa/cli/project_templates/finance/actions/action_session_start.py +74 -0
- rasa/cli/project_templates/finance/actions/cards/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +48 -0
- rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +36 -0
- rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +54 -0
- rasa/cli/project_templates/finance/actions/database.py +277 -0
- rasa/cli/project_templates/finance/actions/transfers/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +52 -0
- rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +51 -0
- rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +40 -0
- rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +40 -0
- rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +46 -0
- rasa/cli/project_templates/finance/actions/transfers/action_process_immediate_payment.py +18 -0
- rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +49 -0
- rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +19 -0
- rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +36 -0
- rasa/cli/project_templates/finance/config.yml +23 -0
- rasa/cli/project_templates/finance/credentials.yml +32 -0
- rasa/cli/project_templates/finance/csvs/accounts.csv +8 -0
- rasa/cli/project_templates/finance/csvs/advisors.csv +7 -0
- rasa/cli/project_templates/finance/csvs/appointments.csv +211 -0
- rasa/cli/project_templates/finance/csvs/branches.csv +10 -0
- rasa/cli/project_templates/finance/csvs/cards.csv +11 -0
- rasa/cli/project_templates/finance/csvs/payees.csv +11 -0
- rasa/cli/project_templates/finance/csvs/transactions.csv +71 -0
- rasa/cli/project_templates/finance/csvs/users.csv +4 -0
- rasa/cli/project_templates/finance/data/accounts/check_balance.yml +10 -0
- rasa/cli/project_templates/finance/data/cards/block_card.yml +66 -0
- rasa/cli/project_templates/finance/data/cards/select_card.yml +12 -0
- rasa/cli/project_templates/finance/data/general/bot_identity.yml +6 -0
- rasa/cli/project_templates/finance/data/general/feedback.yml +20 -0
- rasa/cli/project_templates/finance/data/general/goodbye.yml +6 -0
- rasa/cli/project_templates/finance/data/general/hello.yml +7 -0
- rasa/cli/project_templates/finance/data/general/help.yml +9 -0
- rasa/cli/project_templates/finance/data/general/human_handoff.yml +16 -0
- rasa/cli/project_templates/finance/data/general/welcome.yml +9 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +5 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_completed.yml +7 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_correction.yml +7 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_search.yml +8 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +8 -0
- rasa/cli/project_templates/finance/data/system/source/accounts.json +51 -0
- rasa/cli/project_templates/finance/data/system/source/advisors.json +44 -0
- rasa/cli/project_templates/finance/data/system/source/appointments.json +1474 -0
- rasa/cli/project_templates/finance/data/system/source/branches.json +47 -0
- rasa/cli/project_templates/finance/data/system/source/cards.json +72 -0
- rasa/cli/project_templates/finance/data/system/source/payees.json +74 -0
- rasa/cli/project_templates/finance/data/system/source/transactions.json +492 -0
- rasa/cli/project_templates/finance/data/system/source/users.json +29 -0
- rasa/cli/project_templates/finance/data/transfers/add_payee.yml +29 -0
- rasa/cli/project_templates/finance/data/transfers/list_payees.yml +5 -0
- rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +21 -0
- rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +67 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +7 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +8 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +48 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +47 -0
- rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +11 -0
- rasa/cli/project_templates/finance/domain/cards/block_card.yml +101 -0
- rasa/cli/project_templates/finance/domain/cards/select_card.yml +12 -0
- rasa/cli/project_templates/finance/domain/general/assistant_details.yml +12 -0
- rasa/cli/project_templates/finance/domain/general/bot_identity.yml +5 -0
- rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -0
- rasa/cli/project_templates/finance/domain/general/defaults.yml +24 -0
- rasa/cli/project_templates/finance/domain/general/feedback.yml +28 -0
- rasa/cli/project_templates/finance/domain/general/goodbye.yml +7 -0
- rasa/cli/project_templates/finance/domain/general/help.yml +5 -0
- rasa/cli/project_templates/finance/domain/general/human_handoff.yml +30 -0
- rasa/cli/project_templates/finance/domain/general/utils.yml +13 -0
- rasa/cli/project_templates/finance/domain/general/welcome.yml +8 -0
- rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +47 -0
- rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +4 -0
- rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +16 -0
- rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +79 -0
- rasa/cli/project_templates/finance/endpoints.yml +76 -0
- rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +19 -0
- rasa/cli/project_templates/telco/actions/__init__.py +0 -0
- rasa/cli/project_templates/telco/actions/billing/__init__.py +0 -0
- rasa/cli/project_templates/telco/actions/billing/actions_billing.py +204 -0
- rasa/cli/project_templates/telco/actions/general/__init__.py +0 -0
- rasa/cli/project_templates/telco/actions/general/action_human_handoff.py +49 -0
- rasa/cli/project_templates/telco/actions/network/__init__.py +0 -0
- rasa/cli/project_templates/telco/actions/network/actions_get_data_from_db.py +48 -0
- rasa/cli/project_templates/telco/actions/network/actions_run_diagnostics.py +28 -0
- rasa/cli/project_templates/telco/actions/network/actions_session_start.py +18 -0
- rasa/cli/project_templates/telco/config.yml +29 -0
- rasa/cli/project_templates/telco/credentials.yml +33 -0
- rasa/cli/project_templates/telco/csvs/billing.csv +19 -0
- rasa/cli/project_templates/telco/csvs/customers.csv +5 -0
- rasa/cli/project_templates/telco/data/billing/flow_understand_bill.yml +45 -0
- rasa/cli/project_templates/telco/data/general/bot_challenge.yml +6 -0
- rasa/cli/project_templates/telco/data/general/feedback.yml +20 -0
- rasa/cli/project_templates/telco/data/general/goodbye.yml +6 -0
- rasa/cli/project_templates/telco/data/general/hello.yml +6 -0
- rasa/cli/project_templates/telco/data/general/human_handoff.yml +16 -0
- rasa/cli/project_templates/telco/data/general/patterns.yml +30 -0
- rasa/cli/project_templates/telco/data/network/flow_reboot_router.yml +8 -0
- rasa/cli/project_templates/telco/data/network/flow_reset_router.yml +7 -0
- rasa/cli/project_templates/telco/data/network/flow_solve_internet_issue.yml +73 -0
- rasa/cli/project_templates/telco/docs/docs.md +5 -0
- rasa/cli/project_templates/telco/docs/network/reset_vs_rboot_router.txt +1 -0
- rasa/cli/project_templates/telco/docs/network/restart_router.txt +6 -0
- rasa/cli/project_templates/telco/docs/network/run_speed_test.txt +6 -0
- rasa/cli/project_templates/telco/domain/billing/domain_undertand_bill.yml +102 -0
- rasa/cli/project_templates/telco/domain/general/bot_challenge.yml +4 -0
- rasa/cli/project_templates/telco/domain/general/feedback.yml +25 -0
- rasa/cli/project_templates/telco/domain/general/goodbye.yml +7 -0
- rasa/cli/project_templates/telco/domain/general/hello.yml +5 -0
- rasa/cli/project_templates/telco/domain/general/human_handoff.yml +29 -0
- rasa/cli/project_templates/telco/domain/general/patterns.yml +33 -0
- rasa/cli/project_templates/telco/domain/network/domain_reboot_router.yml +21 -0
- rasa/cli/project_templates/telco/domain/network/domain_reset_router.yml +12 -0
- rasa/cli/project_templates/telco/domain/network/domain_run_speed_test.yml +25 -0
- rasa/cli/project_templates/telco/domain/network/domain_solve_internet_issue.yml +75 -0
- rasa/cli/project_templates/telco/domain/shared.yml +129 -0
- rasa/cli/project_templates/telco/endpoints.yml +77 -0
- rasa/cli/project_templates/telco/prompts/rephraser_demo_personality_prompt.jinja2 +40 -0
- rasa/cli/project_templates/tutorial/config.yml +2 -1
- rasa/cli/scaffold.py +46 -2
- rasa/cli/train.py +2 -2
- rasa/core/actions/action.py +27 -38
- rasa/core/actions/action_run_slot_rejections.py +1 -1
- rasa/core/channels/channel.py +4 -3
- rasa/core/channels/constants.py +3 -0
- rasa/core/channels/development_inspector.py +48 -15
- rasa/core/channels/inspector/dist/assets/{arc-0b11fe30.js → arc-18042c22.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-9eef30a7.js → blockDiagram-38ab4fdb-fdd6bcfa.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-03e94f28.js → c4Diagram-3d4e48cf-f5ae6786.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-b9b536fc.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-95c09eba.js → classDiagram-70f12bd4-81efba3e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-38e8446c.js → classDiagram-v2-f2320105-3b6b6a92.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-78d2ddcf.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-57dc3038.js → createText-2e5e7dd3-31422447.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-4bac0545.js → edges-e0da2a9e-518a90db.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-81795c90.js → erDiagram-9861fffd-a6d3c25a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-89489ae6.js → flowDb-956e92f1-e048c2be.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-cd152627.js → flowDiagram-66a62f08-c7474c91.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-8b09c060.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-3da369bc.js → flowchart-elk-definition-4a651766-cb4d8723.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-85ec16f8.js → ganttDiagram-c361ad54-346636a2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-495bc140.js → gitGraphDiagram-72cf32ee-7c508874.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-1ec4d266.js → graph-14702d8a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-0a0e97c9.js → index-3862675e-f18b534b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-c804b295.js → index-4d4bdf3a.js} +254 -254
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-4d54bcde.js → infoDiagram-f8f76790-64154b83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-dc097114.js → journeyDiagram-49397b02-833a5f95.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-1a08981e.js → layout-5a3b2123.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-95f7f1d3.js → line-2272a8c7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-97e69543.js → linear-35bcf273.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-8c71ff03.js → mindmap-definition-fc14e90a-92dcb0e9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-f14c71c7.js → pieDiagram-8a3498a8-94dbc900.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-f1d3c9ff.js → quadrantDiagram-120e2f19-8b7a9c33.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-bfa2412f.js → requirementDiagram-deff3bca-6f7eab81.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-53f2c97b.js → sankeyDiagram-04a897e0-f43e581d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-319d7c0e.js → sequenceDiagram-704730f1-0bcbefc3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-76a09418.js → stateDiagram-587899a1-b8a74083.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-a67f15d4.js → stateDiagram-v2-d93cdb3a-2070218f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-0654e7c3.js → styles-6aaf32cf-f1d54e34.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1394bb9d.js → styles-9a916d00-980de489.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-e4c5bdae.js → styles-c10674c1-3c03abde.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-50957104.js → svgDrawCommon-08f97a94-46ba068f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-b0885a6a.js → timeline-definition-85554ec2-901f5e3d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-79e6541a.js → xychartDiagram-e933f94c-acbc628a.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/App.tsx +60 -15
- rasa/core/channels/inspector/src/components/Chat.tsx +3 -2
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +1 -1
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +12 -3
- rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +268 -0
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +6 -2
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +8 -3
- rasa/core/channels/inspector/src/types.ts +8 -0
- rasa/core/channels/socketio.py +212 -51
- rasa/core/channels/studio_chat.py +161 -50
- rasa/core/channels/voice_ready/twilio_voice.py +1 -1
- rasa/core/channels/voice_stream/audiocodes.py +9 -6
- rasa/core/channels/voice_stream/browser_audio.py +39 -4
- rasa/core/channels/voice_stream/call_state.py +13 -2
- rasa/core/channels/voice_stream/genesys.py +16 -13
- rasa/core/channels/voice_stream/jambonz.py +13 -11
- rasa/core/channels/voice_stream/twilio_media_streams.py +14 -13
- rasa/core/channels/voice_stream/util.py +11 -1
- rasa/core/channels/voice_stream/voice_channel.py +106 -32
- rasa/core/nlg/contextual_response_rephraser.py +11 -7
- rasa/core/nlg/generator.py +21 -5
- rasa/core/nlg/response.py +43 -6
- rasa/core/nlg/translate.py +8 -0
- rasa/core/policies/enterprise_search_policy.py +4 -7
- rasa/core/policies/flows/flow_executor.py +8 -1
- rasa/core/run.py +13 -3
- rasa/dialogue_understanding/generator/flow_retrieval.py +10 -9
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +1 -1
- rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
- rasa/e2e_test/e2e_test_schema.yml +3 -3
- rasa/model_manager/model_api.py +4 -5
- rasa/model_manager/runner_service.py +1 -1
- rasa/model_manager/socket_bridge.py +27 -15
- rasa/model_manager/trainer_service.py +12 -9
- rasa/model_manager/utils.py +1 -29
- rasa/shared/core/domain.py +62 -15
- rasa/shared/core/flows/flow_step.py +7 -1
- rasa/shared/core/flows/steps/call.py +8 -1
- rasa/shared/core/flows/yaml_flows_io.py +16 -8
- rasa/shared/core/slots.py +4 -0
- rasa/shared/importers/importer.py +6 -0
- rasa/shared/importers/utils.py +77 -1
- rasa/shared/utils/common.py +2 -1
- rasa/studio/upload.py +12 -46
- rasa/telemetry.py +97 -23
- rasa/utils/io.py +27 -9
- rasa/utils/json_utils.py +6 -1
- rasa/utils/licensing.py +21 -10
- rasa/utils/log_utils.py +5 -1
- rasa/utils/openapi.py +144 -0
- rasa/utils/plotting.py +1 -1
- rasa/validator.py +7 -3
- rasa/version.py +1 -1
- {rasa_pro-3.13.8.dist-info → rasa_pro-3.14.0a1.dist-info}/METADATA +22 -23
- {rasa_pro-3.13.8.dist-info → rasa_pro-3.14.0a1.dist-info}/RECORD +380 -104
- rasa/core/channels/inspector/dist/assets/channel-51d02e9e.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-cc738fa6.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-0c716443.js +0 -1
- {rasa_pro-3.13.8.dist-info → rasa_pro-3.14.0a1.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.8.dist-info → rasa_pro-3.14.0a1.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.8.dist-info → rasa_pro-3.14.0a1.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import audioop
|
|
2
4
|
import json
|
|
3
5
|
import uuid
|
|
@@ -20,6 +22,7 @@ from rasa.core.channels.voice_ready.utils import (
|
|
|
20
22
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
21
23
|
from rasa.core.channels.voice_stream.call_state import call_state
|
|
22
24
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
25
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
23
26
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
24
27
|
ContinueConversationAction,
|
|
25
28
|
EndConversationAction,
|
|
@@ -35,7 +38,7 @@ JAMBONZ_STREAMS_WEBSOCKET_PATH = "webhooks/jambonz_stream/websocket"
|
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
def map_call_params(data: Dict[Text, str]) -> CallParameters:
|
|
38
|
-
"""Map the
|
|
41
|
+
"""Map the Jambonz stream parameters to the CallParameters dataclass."""
|
|
39
42
|
call_sid = data.get("callSid", "None")
|
|
40
43
|
from_number = data.get("from", "Unknown")
|
|
41
44
|
to_number = data.get("to")
|
|
@@ -94,7 +97,7 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
94
97
|
@classmethod
|
|
95
98
|
def from_credentials(
|
|
96
99
|
cls, credentials: Optional[Dict[Text, Any]]
|
|
97
|
-
) ->
|
|
100
|
+
) -> JambonzStreamInputChannel:
|
|
98
101
|
"""Create a channel from credentials dictionary.
|
|
99
102
|
|
|
100
103
|
Args:
|
|
@@ -109,19 +112,18 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
109
112
|
JambonzStreamInputChannel instance
|
|
110
113
|
"""
|
|
111
114
|
# Get common credentials from parent
|
|
112
|
-
|
|
115
|
+
cls.validate_credentials(credentials)
|
|
116
|
+
new_creds = repack_voice_credentials(credentials)
|
|
117
|
+
return cls(**new_creds)
|
|
113
118
|
|
|
119
|
+
@classmethod
|
|
120
|
+
def validate_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> None:
|
|
121
|
+
cls.validate_basic_credentials(credentials)
|
|
114
122
|
# Check optional basic auth credentials
|
|
115
123
|
username = credentials.get("username") # type: ignore[union-attr]
|
|
116
124
|
password = credentials.get("password") # type: ignore[union-attr]
|
|
117
125
|
validate_username_password_credentials(username, password, "Jambonz Stream")
|
|
118
126
|
|
|
119
|
-
# Update channel with auth credentials
|
|
120
|
-
channel.username = username # type: ignore[attr-defined]
|
|
121
|
-
channel.password = password # type: ignore[attr-defined]
|
|
122
|
-
|
|
123
|
-
return channel # type: ignore[return-value]
|
|
124
|
-
|
|
125
127
|
def _websocket_stream_url(self) -> str:
|
|
126
128
|
"""Returns the websocket stream URL."""
|
|
127
129
|
# depending on the config value, the url might contain http as a
|
|
@@ -158,14 +160,14 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
158
160
|
if data["type"] == "mark":
|
|
159
161
|
if data["data"]["name"] == call_state.latest_bot_audio_id:
|
|
160
162
|
# Just finished streaming last audio bytes
|
|
161
|
-
call_state.is_bot_speaking = False
|
|
163
|
+
call_state.is_bot_speaking = False
|
|
162
164
|
if call_state.should_hangup:
|
|
163
165
|
logger.debug(
|
|
164
166
|
"jambonz.hangup", marker=call_state.latest_bot_audio_id
|
|
165
167
|
)
|
|
166
168
|
return EndConversationAction()
|
|
167
169
|
else:
|
|
168
|
-
call_state.is_bot_speaking = True
|
|
170
|
+
call_state.is_bot_speaking = True
|
|
169
171
|
elif data["event"] == "dtmf":
|
|
170
172
|
# TODO: handle DTMF input
|
|
171
173
|
logger.debug("jambonz.dtmf.received", dtmf=data["dtmf"])
|
|
@@ -26,6 +26,7 @@ from rasa.core.channels.voice_ready.utils import (
|
|
|
26
26
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
27
27
|
from rasa.core.channels.voice_stream.call_state import call_state
|
|
28
28
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
29
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
29
30
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
30
31
|
ContinueConversationAction,
|
|
31
32
|
EndConversationAction,
|
|
@@ -120,20 +121,20 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
|
|
|
120
121
|
cls,
|
|
121
122
|
credentials: Optional[Dict[str, Any]],
|
|
122
123
|
) -> VoiceInputChannel:
|
|
123
|
-
credentials
|
|
124
|
+
cls.validate_credentials(credentials)
|
|
125
|
+
new_creds = repack_voice_credentials(credentials)
|
|
126
|
+
return cls(**new_creds)
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
@classmethod
|
|
129
|
+
def validate_credentials(
|
|
130
|
+
cls,
|
|
131
|
+
credentials: Optional[Dict[str, Any]],
|
|
132
|
+
) -> None:
|
|
133
|
+
cls.validate_basic_credentials(credentials)
|
|
134
|
+
username = credentials.get("username") if credentials else None
|
|
135
|
+
password = credentials.get("password") if credentials else None
|
|
127
136
|
validate_username_password_credentials(username, password, "TwilioMediaStreams")
|
|
128
137
|
|
|
129
|
-
return cls(
|
|
130
|
-
credentials["server_url"],
|
|
131
|
-
credentials["asr"],
|
|
132
|
-
credentials["tts"],
|
|
133
|
-
username=username,
|
|
134
|
-
password=password,
|
|
135
|
-
)
|
|
136
|
-
|
|
137
138
|
@classmethod
|
|
138
139
|
def name(cls) -> str:
|
|
139
140
|
return "twilio_media_streams"
|
|
@@ -175,14 +176,14 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
|
|
|
175
176
|
elif data["event"] == "mark":
|
|
176
177
|
if data["mark"]["name"] == call_state.latest_bot_audio_id:
|
|
177
178
|
# Just finished streaming last audio bytes
|
|
178
|
-
call_state.is_bot_speaking = False
|
|
179
|
+
call_state.is_bot_speaking = False
|
|
179
180
|
if call_state.should_hangup:
|
|
180
181
|
logger.debug(
|
|
181
182
|
"twilio_streams.hangup", marker=call_state.latest_bot_audio_id
|
|
182
183
|
)
|
|
183
184
|
return EndConversationAction()
|
|
184
185
|
else:
|
|
185
|
-
call_state.is_bot_speaking = True
|
|
186
|
+
call_state.is_bot_speaking = True
|
|
186
187
|
return ContinueConversationAction()
|
|
187
188
|
|
|
188
189
|
def create_output_channel(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import audioop
|
|
2
2
|
import wave
|
|
3
3
|
from dataclasses import asdict, dataclass
|
|
4
|
-
from typing import Optional, Type, TypeVar
|
|
4
|
+
from typing import Dict, Optional, Type, TypeVar
|
|
5
5
|
|
|
6
6
|
import structlog
|
|
7
7
|
|
|
@@ -55,3 +55,13 @@ class MergeableConfig:
|
|
|
55
55
|
@classmethod
|
|
56
56
|
def from_dict(cls: Type[T], data: dict[str, Optional[str]]) -> T:
|
|
57
57
|
return cls(**data)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def repack_voice_credentials(
|
|
61
|
+
credentials: Dict[str, str],
|
|
62
|
+
) -> Dict[str, str]:
|
|
63
|
+
"""Repack voice credentials to ensure they are in the correct format."""
|
|
64
|
+
new_creds = {**credentials}
|
|
65
|
+
new_creds["asr_config"] = new_creds.pop("asr", None)
|
|
66
|
+
new_creds["tts_config"] = new_creds.pop("tts", None)
|
|
67
|
+
return new_creds
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import copy
|
|
5
|
+
import time
|
|
3
6
|
from dataclasses import asdict, dataclass
|
|
4
7
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, List, Optional, Tuple
|
|
5
8
|
|
|
@@ -8,6 +11,11 @@ from sanic import Websocket # type: ignore
|
|
|
8
11
|
from sanic.exceptions import ServerError, WebsocketClosed
|
|
9
12
|
|
|
10
13
|
from rasa.core.channels import InputChannel, OutputChannel, UserMessage
|
|
14
|
+
from rasa.core.channels.constants import (
|
|
15
|
+
USER_CONVERSATION_SESSION_END,
|
|
16
|
+
USER_CONVERSATION_SESSION_START,
|
|
17
|
+
USER_CONVERSATION_SILENCE_TIMEOUT,
|
|
18
|
+
)
|
|
11
19
|
from rasa.core.channels.voice_ready.utils import (
|
|
12
20
|
CallParameters,
|
|
13
21
|
validate_voice_license_scope,
|
|
@@ -45,9 +53,6 @@ from rasa.utils.io import remove_emojis
|
|
|
45
53
|
logger = structlog.get_logger(__name__)
|
|
46
54
|
|
|
47
55
|
# define constants for the voice channel
|
|
48
|
-
USER_CONVERSATION_SESSION_END = "/session_end"
|
|
49
|
-
USER_CONVERSATION_SESSION_START = "/session_start"
|
|
50
|
-
USER_CONVERSATION_SILENCE_TIMEOUT = "/silence_timeout"
|
|
51
56
|
|
|
52
57
|
|
|
53
58
|
@dataclass
|
|
@@ -189,7 +194,7 @@ class VoiceOutputChannel(OutputChannel):
|
|
|
189
194
|
def update_silence_timeout(self) -> None:
|
|
190
195
|
"""Updates the silence timeout for the session."""
|
|
191
196
|
if self.tracker_state:
|
|
192
|
-
call_state.silence_timeout = self.tracker_state["slots"][
|
|
197
|
+
call_state.silence_timeout = self.tracker_state["slots"][
|
|
193
198
|
SILENCE_TIMEOUT_SLOT
|
|
194
199
|
]
|
|
195
200
|
logger.debug(
|
|
@@ -207,22 +212,63 @@ class VoiceOutputChannel(OutputChannel):
|
|
|
207
212
|
"""Uses the concise button output format for voice channels."""
|
|
208
213
|
await self.send_text_with_buttons_concise(recipient_id, text, buttons, **kwargs)
|
|
209
214
|
|
|
215
|
+
def _track_rasa_processing_latency(self) -> None:
|
|
216
|
+
"""Track and log Rasa processing completion latency."""
|
|
217
|
+
if call_state.rasa_processing_start_time:
|
|
218
|
+
call_state.rasa_processing_latency_ms = (
|
|
219
|
+
time.time() - call_state.rasa_processing_start_time
|
|
220
|
+
) * 1000
|
|
221
|
+
logger.debug(
|
|
222
|
+
"voice_channel.rasa_processing_latency",
|
|
223
|
+
latency_ms=call_state.rasa_processing_latency_ms,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
def _track_tts_first_byte_latency(self) -> None:
|
|
227
|
+
"""Track and log TTS first byte latency."""
|
|
228
|
+
if call_state.tts_start_time:
|
|
229
|
+
call_state.tts_first_byte_latency_ms = (
|
|
230
|
+
time.time() - call_state.tts_start_time
|
|
231
|
+
) * 1000
|
|
232
|
+
logger.debug(
|
|
233
|
+
"voice_channel.tts_first_byte_latency",
|
|
234
|
+
latency_ms=call_state.tts_first_byte_latency_ms,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
def _track_tts_complete_latency(self) -> None:
|
|
238
|
+
"""Track and log TTS completion latency."""
|
|
239
|
+
if call_state.tts_start_time:
|
|
240
|
+
call_state.tts_complete_latency_ms = (
|
|
241
|
+
time.time() - call_state.tts_start_time
|
|
242
|
+
) * 1000
|
|
243
|
+
logger.debug(
|
|
244
|
+
"voice_channel.tts_complete_latency",
|
|
245
|
+
latency_ms=call_state.tts_complete_latency_ms,
|
|
246
|
+
)
|
|
247
|
+
|
|
210
248
|
async def send_text_message(
|
|
211
249
|
self, recipient_id: str, text: str, **kwargs: Any
|
|
212
250
|
) -> None:
|
|
213
251
|
text = remove_emojis(text)
|
|
214
252
|
self.update_silence_timeout()
|
|
253
|
+
|
|
254
|
+
# Track Rasa processing completion
|
|
255
|
+
self._track_rasa_processing_latency()
|
|
256
|
+
|
|
257
|
+
# Track TTS start time
|
|
258
|
+
call_state.tts_start_time = time.time()
|
|
259
|
+
|
|
215
260
|
cached_audio_bytes = self.tts_cache.get(text)
|
|
216
261
|
collected_audio_bytes = RasaAudioBytes(b"")
|
|
217
262
|
seconds_marker = -1
|
|
218
263
|
last_sent_offset = 0
|
|
264
|
+
first_audio_sent = False
|
|
219
265
|
logger.debug("voice_channel.sending_audio", text=text)
|
|
220
266
|
|
|
221
267
|
# Send start marker before first chunk
|
|
222
268
|
try:
|
|
223
269
|
await self.send_start_marker(recipient_id)
|
|
224
270
|
except (WebsocketClosed, ServerError):
|
|
225
|
-
call_state.connection_failed = True
|
|
271
|
+
call_state.connection_failed = True
|
|
226
272
|
|
|
227
273
|
if cached_audio_bytes:
|
|
228
274
|
audio_stream = self.chunk_audio(cached_audio_bytes)
|
|
@@ -244,6 +290,11 @@ class VoiceOutputChannel(OutputChannel):
|
|
|
244
290
|
|
|
245
291
|
if should_send:
|
|
246
292
|
try:
|
|
293
|
+
# Track TTS first byte time
|
|
294
|
+
if not first_audio_sent:
|
|
295
|
+
self._track_tts_first_byte_latency()
|
|
296
|
+
first_audio_sent = True
|
|
297
|
+
|
|
247
298
|
# Send only the new bytes since last send
|
|
248
299
|
new_bytes = RasaAudioBytes(collected_audio_bytes[last_sent_offset:])
|
|
249
300
|
await self.send_audio_bytes(recipient_id, new_bytes)
|
|
@@ -256,24 +307,31 @@ class VoiceOutputChannel(OutputChannel):
|
|
|
256
307
|
|
|
257
308
|
except (WebsocketClosed, ServerError):
|
|
258
309
|
# ignore sending error, and keep collecting and caching audio bytes
|
|
259
|
-
call_state.connection_failed = True
|
|
310
|
+
call_state.connection_failed = True
|
|
260
311
|
|
|
261
312
|
# Send any remaining audio not yet sent
|
|
262
313
|
remaining_bytes = len(collected_audio_bytes) - last_sent_offset
|
|
263
314
|
if remaining_bytes > 0:
|
|
264
315
|
try:
|
|
316
|
+
# Track TTS first byte time if not already tracked
|
|
317
|
+
if not first_audio_sent:
|
|
318
|
+
self._track_tts_first_byte_latency()
|
|
319
|
+
|
|
265
320
|
new_bytes = RasaAudioBytes(collected_audio_bytes[last_sent_offset:])
|
|
266
321
|
await self.send_audio_bytes(recipient_id, new_bytes)
|
|
267
322
|
except (WebsocketClosed, ServerError):
|
|
268
323
|
# ignore sending error
|
|
269
|
-
call_state.connection_failed = True
|
|
324
|
+
call_state.connection_failed = True
|
|
325
|
+
|
|
326
|
+
# Track TTS completion time
|
|
327
|
+
self._track_tts_complete_latency()
|
|
270
328
|
|
|
271
329
|
try:
|
|
272
330
|
await self.send_end_marker(recipient_id)
|
|
273
331
|
except (WebsocketClosed, ServerError):
|
|
274
332
|
# ignore sending error
|
|
275
333
|
pass
|
|
276
|
-
call_state.latest_bot_audio_id = self.latest_message_id
|
|
334
|
+
call_state.latest_bot_audio_id = self.latest_message_id
|
|
277
335
|
|
|
278
336
|
if not cached_audio_bytes:
|
|
279
337
|
self.tts_cache.put(text, collected_audio_bytes)
|
|
@@ -298,7 +356,7 @@ class VoiceOutputChannel(OutputChannel):
|
|
|
298
356
|
return
|
|
299
357
|
|
|
300
358
|
async def hangup(self, recipient_id: str, **kwargs: Any) -> None:
|
|
301
|
-
call_state.should_hangup = True
|
|
359
|
+
call_state.should_hangup = True
|
|
302
360
|
|
|
303
361
|
|
|
304
362
|
class VoiceInputChannel(InputChannel):
|
|
@@ -345,32 +403,32 @@ class VoiceInputChannel(InputChannel):
|
|
|
345
403
|
if call_state.silence_timeout_watcher:
|
|
346
404
|
logger.debug("voice_channel.cancelling_current_timeout_watcher_task")
|
|
347
405
|
call_state.silence_timeout_watcher.cancel()
|
|
348
|
-
call_state.silence_timeout_watcher = None
|
|
406
|
+
call_state.silence_timeout_watcher = None
|
|
349
407
|
|
|
350
408
|
@classmethod
|
|
351
|
-
def
|
|
352
|
-
|
|
353
|
-
credentials: Optional[Dict[str, Any]],
|
|
354
|
-
) -> InputChannel:
|
|
409
|
+
def validate_basic_credentials(cls, credentials: Optional[Dict[str, Any]]) -> None:
|
|
410
|
+
"""Validate the basic credentials for the voice channel."""
|
|
355
411
|
if not credentials:
|
|
356
412
|
cls.raise_missing_credentials_exception()
|
|
357
|
-
|
|
358
|
-
if not credentials.get("server_url"):
|
|
359
|
-
raise InvalidConfigException("No server_url provided in credentials.")
|
|
360
|
-
if not credentials.get("asr"):
|
|
413
|
+
if not isinstance(credentials, dict):
|
|
361
414
|
raise InvalidConfigException(
|
|
362
|
-
"
|
|
415
|
+
"Credentials must be a dictionary for voice channel."
|
|
363
416
|
)
|
|
364
|
-
|
|
417
|
+
|
|
418
|
+
required_keys = {"server_url", "asr", "tts"}
|
|
419
|
+
credentials_keys = set(credentials.keys())
|
|
420
|
+
if not required_keys.issubset(credentials_keys):
|
|
421
|
+
missing_fields = required_keys - credentials_keys
|
|
365
422
|
raise InvalidConfigException(
|
|
366
|
-
"
|
|
423
|
+
f"Missing required fields in credentials: {', '.join(missing_fields)} "
|
|
424
|
+
f"for channel {cls.name()}"
|
|
367
425
|
)
|
|
368
426
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
427
|
+
@classmethod
|
|
428
|
+
def from_credentials(
|
|
429
|
+
cls, credentials: Optional[Dict[str, Any]]
|
|
430
|
+
) -> VoiceInputChannel:
|
|
431
|
+
raise NotImplementedError
|
|
374
432
|
|
|
375
433
|
def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
|
|
376
434
|
raise NotImplementedError
|
|
@@ -439,10 +497,8 @@ class VoiceInputChannel(InputChannel):
|
|
|
439
497
|
if was_bot_speaking_before and not is_bot_speaking_after:
|
|
440
498
|
logger.debug("voice_channel.bot_stopped_speaking")
|
|
441
499
|
self._cancel_silence_timeout_watcher()
|
|
442
|
-
call_state.silence_timeout_watcher = (
|
|
443
|
-
|
|
444
|
-
self.monitor_silence_timeout(asr_event_queue)
|
|
445
|
-
)
|
|
500
|
+
call_state.silence_timeout_watcher = asyncio.create_task(
|
|
501
|
+
self.monitor_silence_timeout(asr_event_queue)
|
|
446
502
|
)
|
|
447
503
|
if isinstance(channel_action, NewAudioAction):
|
|
448
504
|
await asr_engine.send_audio_chunks(channel_action.audio_bytes)
|
|
@@ -498,6 +554,16 @@ class VoiceInputChannel(InputChannel):
|
|
|
498
554
|
"""Create a matching voice output channel for this voice input channel."""
|
|
499
555
|
raise NotImplementedError
|
|
500
556
|
|
|
557
|
+
def _track_asr_latency(self) -> None:
|
|
558
|
+
"""Track and log ASR processing latency."""
|
|
559
|
+
if call_state.user_speech_start_time:
|
|
560
|
+
call_state.asr_latency_ms = (
|
|
561
|
+
time.time() - call_state.user_speech_start_time
|
|
562
|
+
) * 1000
|
|
563
|
+
logger.debug(
|
|
564
|
+
"voice_channel.asr_latency", latency_ms=call_state.asr_latency_ms
|
|
565
|
+
)
|
|
566
|
+
|
|
501
567
|
async def handle_asr_event(
|
|
502
568
|
self,
|
|
503
569
|
e: ASREvent,
|
|
@@ -511,7 +577,12 @@ class VoiceInputChannel(InputChannel):
|
|
|
511
577
|
logger.debug(
|
|
512
578
|
"VoiceInputChannel.handle_asr_event.new_transcript", transcript=e.text
|
|
513
579
|
)
|
|
514
|
-
call_state.is_user_speaking = False
|
|
580
|
+
call_state.is_user_speaking = False
|
|
581
|
+
|
|
582
|
+
# Track ASR and Rasa latencies
|
|
583
|
+
self._track_asr_latency()
|
|
584
|
+
call_state.rasa_processing_start_time = time.time()
|
|
585
|
+
|
|
515
586
|
output_channel = self.create_output_channel(voice_websocket, tts_engine)
|
|
516
587
|
message = UserMessage(
|
|
517
588
|
text=e.text,
|
|
@@ -522,8 +593,11 @@ class VoiceInputChannel(InputChannel):
|
|
|
522
593
|
)
|
|
523
594
|
await on_new_message(message)
|
|
524
595
|
elif isinstance(e, UserIsSpeaking):
|
|
596
|
+
# Track when user starts speaking for ASR latency calculation
|
|
597
|
+
if not call_state.is_user_speaking:
|
|
598
|
+
call_state.user_speech_start_time = time.time()
|
|
525
599
|
self._cancel_silence_timeout_watcher()
|
|
526
|
-
call_state.is_user_speaking = True
|
|
600
|
+
call_state.is_user_speaking = True
|
|
527
601
|
elif isinstance(e, UserSilence):
|
|
528
602
|
output_channel = self.create_output_channel(voice_websocket, tts_engine)
|
|
529
603
|
message = UserMessage(
|
|
@@ -225,8 +225,10 @@ class ContextualResponseRephraser(
|
|
|
225
225
|
|
|
226
226
|
@measure_llm_latency
|
|
227
227
|
async def _generate_llm_response(self, prompt: str) -> Optional[LLMResponse]:
|
|
228
|
-
"""Use LLM to generate a response
|
|
229
|
-
|
|
228
|
+
"""Use LLM to generate a response.
|
|
229
|
+
|
|
230
|
+
Returns an LLMResponse object containing both the generated text
|
|
231
|
+
(choices) and metadata.
|
|
230
232
|
|
|
231
233
|
Args:
|
|
232
234
|
prompt: The prompt to send to the LLM.
|
|
@@ -315,14 +317,18 @@ class ContextualResponseRephraser(
|
|
|
315
317
|
return response
|
|
316
318
|
|
|
317
319
|
prompt_template_text = self._template_for_response_rephrasing(response)
|
|
320
|
+
|
|
321
|
+
# Last user message (=current input) should always be in prompt if available
|
|
318
322
|
last_message_by_user = getattr(tracker.latest_message, "text", "")
|
|
319
323
|
current_input = (
|
|
320
324
|
f"{USER}: {last_message_by_user}" if last_message_by_user else ""
|
|
321
325
|
)
|
|
322
326
|
|
|
327
|
+
# Only summarise conversation history if flagged
|
|
323
328
|
if self.summarize_history:
|
|
324
329
|
history = await self._create_history(tracker)
|
|
325
330
|
else:
|
|
331
|
+
# Count multiple utterances by bot/user as single turn
|
|
326
332
|
turns_wrapper = (
|
|
327
333
|
_count_multiple_utterances_as_single_turn
|
|
328
334
|
if self.count_multiple_utterances_as_single_turn
|
|
@@ -365,6 +371,7 @@ class ContextualResponseRephraser(
|
|
|
365
371
|
)
|
|
366
372
|
|
|
367
373
|
if not (llm_response and llm_response.choices and llm_response.choices[0]):
|
|
374
|
+
# If the LLM fails to generate a response, return the original response.
|
|
368
375
|
return response
|
|
369
376
|
|
|
370
377
|
updated_text = llm_response.choices[0]
|
|
@@ -412,12 +419,9 @@ class ContextualResponseRephraser(
|
|
|
412
419
|
Returns:
|
|
413
420
|
The generated response.
|
|
414
421
|
"""
|
|
415
|
-
|
|
416
|
-
stack_context = tracker.stack.current_context()
|
|
417
|
-
templated_response = self.generate_from_slots(
|
|
422
|
+
templated_response = await super().generate(
|
|
418
423
|
utter_action=utter_action,
|
|
419
|
-
|
|
420
|
-
stack_context=stack_context,
|
|
424
|
+
tracker=tracker,
|
|
421
425
|
output_channel=output_channel,
|
|
422
426
|
**kwargs,
|
|
423
427
|
)
|
rasa/core/nlg/generator.py
CHANGED
|
@@ -6,6 +6,8 @@ from pypred import Predicate
|
|
|
6
6
|
|
|
7
7
|
import rasa.shared.utils.common
|
|
8
8
|
import rasa.shared.utils.io
|
|
9
|
+
from rasa.core.nlg.translate import has_translation
|
|
10
|
+
from rasa.engine.language import Language
|
|
9
11
|
from rasa.shared.constants import CHANNEL, RESPONSE_CONDITION
|
|
10
12
|
from rasa.shared.core.domain import Domain
|
|
11
13
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
@@ -131,11 +133,23 @@ class ResponseVariationFilter:
|
|
|
131
133
|
|
|
132
134
|
return True
|
|
133
135
|
|
|
136
|
+
def _filter_by_language(
|
|
137
|
+
self, responses: List[Dict[Text, Any]], language: Optional[Language] = None
|
|
138
|
+
) -> List[Dict[Text, Any]]:
|
|
139
|
+
if not language:
|
|
140
|
+
return responses
|
|
141
|
+
|
|
142
|
+
if filtered := [r for r in responses if has_translation(r, language)]:
|
|
143
|
+
return filtered
|
|
144
|
+
# if no translation is found, return the original response variations
|
|
145
|
+
return responses
|
|
146
|
+
|
|
134
147
|
def responses_for_utter_action(
|
|
135
148
|
self,
|
|
136
149
|
utter_action: Text,
|
|
137
150
|
output_channel: Text,
|
|
138
151
|
filled_slots: Dict[Text, Any],
|
|
152
|
+
language: Optional[Language] = None,
|
|
139
153
|
) -> List[Dict[Text, Any]]:
|
|
140
154
|
"""Returns array of responses that fit the channel, action and condition."""
|
|
141
155
|
# filter responses without a condition
|
|
@@ -176,16 +190,16 @@ class ResponseVariationFilter:
|
|
|
176
190
|
)
|
|
177
191
|
|
|
178
192
|
if conditional_channel:
|
|
179
|
-
return conditional_channel
|
|
193
|
+
return self._filter_by_language(conditional_channel, language)
|
|
180
194
|
|
|
181
195
|
if default_channel:
|
|
182
|
-
return default_channel
|
|
196
|
+
return self._filter_by_language(default_channel, language)
|
|
183
197
|
|
|
184
198
|
if conditional_no_channel:
|
|
185
|
-
return conditional_no_channel
|
|
199
|
+
return self._filter_by_language(conditional_no_channel, language)
|
|
186
200
|
|
|
187
201
|
if default_no_channel:
|
|
188
|
-
return default_no_channel
|
|
202
|
+
return self._filter_by_language(default_no_channel, language)
|
|
189
203
|
|
|
190
204
|
# if there is no response variation selected,
|
|
191
205
|
# return the internal error response to prevent
|
|
@@ -198,7 +212,9 @@ class ResponseVariationFilter:
|
|
|
198
212
|
f"a default variation and that all the conditions are valid. "
|
|
199
213
|
f"Returning the internal error response.",
|
|
200
214
|
)
|
|
201
|
-
return self.
|
|
215
|
+
return self._filter_by_language(
|
|
216
|
+
self.responses.get("utter_internal_error_rasa", []), language
|
|
217
|
+
)
|
|
202
218
|
|
|
203
219
|
def get_response_variation_id(
|
|
204
220
|
self,
|
rasa/core/nlg/response.py
CHANGED
|
@@ -5,8 +5,11 @@ from typing import Any, Dict, List, Optional, Text
|
|
|
5
5
|
from rasa.core.constants import DEFAULT_TEMPLATE_ENGINE, TEMPLATE_ENGINE_CONFIG_KEY
|
|
6
6
|
from rasa.core.nlg import interpolator
|
|
7
7
|
from rasa.core.nlg.generator import NaturalLanguageGenerator, ResponseVariationFilter
|
|
8
|
-
from rasa.
|
|
8
|
+
from rasa.core.nlg.translate import get_translated_buttons, get_translated_text
|
|
9
|
+
from rasa.engine.language import Language
|
|
10
|
+
from rasa.shared.constants import BUTTONS, RESPONSE_CONDITION, TEXT
|
|
9
11
|
from rasa.shared.core.domain import RESPONSE_KEYS_TO_INTERPOLATE
|
|
12
|
+
from rasa.shared.core.flows.constants import KEY_TRANSLATION
|
|
10
13
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
11
14
|
from rasa.shared.nlu.constants import METADATA
|
|
12
15
|
|
|
@@ -30,7 +33,11 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
30
33
|
|
|
31
34
|
# noinspection PyUnusedLocal
|
|
32
35
|
def _random_response_for(
|
|
33
|
-
self,
|
|
36
|
+
self,
|
|
37
|
+
utter_action: Text,
|
|
38
|
+
output_channel: Text,
|
|
39
|
+
filled_slots: Dict[Text, Any],
|
|
40
|
+
language: Optional[Language] = None,
|
|
34
41
|
) -> Optional[Dict[Text, Any]]:
|
|
35
42
|
"""Select random response for the utter action from available ones.
|
|
36
43
|
|
|
@@ -42,7 +49,7 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
42
49
|
if utter_action in self.responses:
|
|
43
50
|
response_filter = ResponseVariationFilter(self.responses)
|
|
44
51
|
suitable_responses = response_filter.responses_for_utter_action(
|
|
45
|
-
utter_action, output_channel, filled_slots
|
|
52
|
+
utter_action, output_channel, filled_slots, language
|
|
46
53
|
)
|
|
47
54
|
|
|
48
55
|
if suitable_responses:
|
|
@@ -75,9 +82,36 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
75
82
|
"""Generate a response for the requested utter action."""
|
|
76
83
|
filled_slots = tracker.current_slot_values()
|
|
77
84
|
stack_context = tracker.stack.current_context()
|
|
78
|
-
|
|
79
|
-
utter_action,
|
|
85
|
+
response = self.generate_from_slots(
|
|
86
|
+
utter_action,
|
|
87
|
+
filled_slots,
|
|
88
|
+
stack_context,
|
|
89
|
+
output_channel,
|
|
90
|
+
tracker.current_language,
|
|
91
|
+
**kwargs,
|
|
80
92
|
)
|
|
93
|
+
if response is not None:
|
|
94
|
+
return self.translate_response(response, tracker.current_language)
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
def translate_response(
|
|
98
|
+
self, response: Dict[Text, Any], language: Optional[Language] = None
|
|
99
|
+
) -> Dict[Text, Any]:
|
|
100
|
+
message_copy = copy.deepcopy(response)
|
|
101
|
+
|
|
102
|
+
text = get_translated_text(
|
|
103
|
+
text=message_copy.pop(TEXT, None),
|
|
104
|
+
translation=message_copy.pop(KEY_TRANSLATION, {}),
|
|
105
|
+
language=language,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
buttons = get_translated_buttons(
|
|
109
|
+
buttons=message_copy.pop(BUTTONS, None), language=language
|
|
110
|
+
)
|
|
111
|
+
message_copy[TEXT] = text
|
|
112
|
+
if buttons:
|
|
113
|
+
message_copy[BUTTONS] = buttons
|
|
114
|
+
return message_copy
|
|
81
115
|
|
|
82
116
|
def generate_from_slots(
|
|
83
117
|
self,
|
|
@@ -85,12 +119,15 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
85
119
|
filled_slots: Dict[Text, Any],
|
|
86
120
|
stack_context: Dict[Text, Any],
|
|
87
121
|
output_channel: Text,
|
|
122
|
+
language: Optional[Language] = None,
|
|
88
123
|
**kwargs: Any,
|
|
89
124
|
) -> Optional[Dict[Text, Any]]:
|
|
90
125
|
"""Generate a response for the requested utter action."""
|
|
91
126
|
# Fetching a random response for the passed utter action
|
|
92
127
|
r = copy.deepcopy(
|
|
93
|
-
self._random_response_for(
|
|
128
|
+
self._random_response_for(
|
|
129
|
+
utter_action, output_channel, filled_slots, language
|
|
130
|
+
)
|
|
94
131
|
)
|
|
95
132
|
# Filling the slots in the response with placeholders and returning the response
|
|
96
133
|
if r is not None:
|
rasa/core/nlg/translate.py
CHANGED
|
@@ -23,6 +23,14 @@ def get_translated_text(
|
|
|
23
23
|
return translation.get(language_code, text)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def has_translation(
|
|
27
|
+
message: Dict[Text, Any], language: Optional[Language] = None
|
|
28
|
+
) -> bool:
|
|
29
|
+
"""Check if the message has a translation for the given language."""
|
|
30
|
+
language_code = language.code if language else None
|
|
31
|
+
return language_code in message.get(KEY_TRANSLATION, {})
|
|
32
|
+
|
|
33
|
+
|
|
26
34
|
def get_translated_buttons(
|
|
27
35
|
buttons: Optional[List[Dict[Text, Any]]], language: Optional[Language] = None
|
|
28
36
|
) -> Optional[List[Dict[Text, Any]]]:
|