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,7 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import audioop
|
|
3
5
|
import base64
|
|
4
6
|
import json
|
|
7
|
+
import time
|
|
5
8
|
import uuid
|
|
6
9
|
from functools import partial
|
|
7
10
|
from typing import (
|
|
@@ -14,6 +17,7 @@ from typing import (
|
|
|
14
17
|
Optional,
|
|
15
18
|
Text,
|
|
16
19
|
Tuple,
|
|
20
|
+
Union,
|
|
17
21
|
)
|
|
18
22
|
|
|
19
23
|
import structlog
|
|
@@ -32,6 +36,7 @@ from rasa.core.channels.voice_stream.voice_channel import (
|
|
|
32
36
|
VoiceInputChannel,
|
|
33
37
|
VoiceOutputChannel,
|
|
34
38
|
)
|
|
39
|
+
from rasa.core.exceptions import AgentNotReady
|
|
35
40
|
from rasa.hooks import hookimpl
|
|
36
41
|
from rasa.plugin import plugin_manager
|
|
37
42
|
from rasa.shared.core.constants import ACTION_LISTEN_NAME
|
|
@@ -42,14 +47,15 @@ if TYPE_CHECKING:
|
|
|
42
47
|
from sanic import Sanic, Websocket # type: ignore[attr-defined]
|
|
43
48
|
from socketio import AsyncServer
|
|
44
49
|
|
|
45
|
-
from rasa.core.channels.channel import InputChannel, UserMessage
|
|
46
50
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
47
51
|
|
|
48
52
|
|
|
49
53
|
structlogger = structlog.get_logger()
|
|
50
54
|
|
|
51
55
|
|
|
52
|
-
def tracker_as_dump(
|
|
56
|
+
def tracker_as_dump(
|
|
57
|
+
tracker: "DialogueStateTracker", latency: Optional[float] = None
|
|
58
|
+
) -> Dict[str, Any]:
|
|
53
59
|
"""Create a dump of the tracker state."""
|
|
54
60
|
from rasa.shared.core.trackers import get_trackers_for_conversation_sessions
|
|
55
61
|
|
|
@@ -60,8 +66,14 @@ def tracker_as_dump(tracker: "DialogueStateTracker") -> str:
|
|
|
60
66
|
else:
|
|
61
67
|
last_tracker = multiple_tracker_sessions[-1]
|
|
62
68
|
|
|
69
|
+
# TODO: this is a bug: the bridge converts this back to json, but it
|
|
70
|
+
# should be json in the first place
|
|
63
71
|
state = last_tracker.current_state(EventVerbosity.AFTER_RESTART)
|
|
64
|
-
|
|
72
|
+
|
|
73
|
+
if latency is not None:
|
|
74
|
+
state["latency"] = {"rasa_processing_latency_ms": latency}
|
|
75
|
+
|
|
76
|
+
return state
|
|
65
77
|
|
|
66
78
|
|
|
67
79
|
def does_need_action_prediction(tracker: "DialogueStateTracker") -> bool:
|
|
@@ -143,6 +155,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
143
155
|
jwt_key: Optional[Text] = None,
|
|
144
156
|
jwt_method: Optional[Text] = "HS256",
|
|
145
157
|
metadata_key: Optional[Text] = "metadata",
|
|
158
|
+
enable_silence_timeout: bool = False,
|
|
146
159
|
) -> None:
|
|
147
160
|
"""Creates a `StudioChatInput` object."""
|
|
148
161
|
from rasa.core.agent import Agent
|
|
@@ -160,6 +173,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
160
173
|
jwt_key=jwt_key,
|
|
161
174
|
jwt_method=jwt_method,
|
|
162
175
|
metadata_key=metadata_key,
|
|
176
|
+
enable_silence_timeout=enable_silence_timeout,
|
|
163
177
|
)
|
|
164
178
|
|
|
165
179
|
# Initialize the Voice Input Channel
|
|
@@ -175,11 +189,14 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
175
189
|
# `background_tasks` holds the asyncio tasks for voice streaming
|
|
176
190
|
self.active_connections: Dict[str, SocketIOVoiceWebsocketAdapter] = {}
|
|
177
191
|
self.background_tasks: Dict[str, asyncio.Task] = {}
|
|
192
|
+
self._turn_start_times: Dict[Text, float] = {}
|
|
178
193
|
|
|
179
194
|
self._register_tracker_update_hook()
|
|
180
195
|
|
|
181
196
|
@classmethod
|
|
182
|
-
def from_credentials(
|
|
197
|
+
def from_credentials(
|
|
198
|
+
cls, credentials: Optional[Dict[Text, Any]]
|
|
199
|
+
) -> "StudioChatInput":
|
|
183
200
|
"""Creates a StudioChatInput channel from credentials."""
|
|
184
201
|
credentials = credentials or {}
|
|
185
202
|
|
|
@@ -197,35 +214,73 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
197
214
|
jwt_key=credentials.get("jwt_key"),
|
|
198
215
|
jwt_method=credentials.get("jwt_method", "HS256"),
|
|
199
216
|
metadata_key=credentials.get("metadata_key", "metadata"),
|
|
217
|
+
enable_silence_timeout=credentials.get("enable_silence_timeout", False),
|
|
200
218
|
)
|
|
201
219
|
|
|
220
|
+
async def emit(self, event: str, data: Union[Dict, str], room: str) -> None:
|
|
221
|
+
"""Emits an event to the websocket."""
|
|
222
|
+
if not self.sio_server:
|
|
223
|
+
structlogger.error("studio_chat.emit.sio_not_initialized")
|
|
224
|
+
return
|
|
225
|
+
await self.sio_server.emit(event, data, room=room)
|
|
226
|
+
|
|
202
227
|
def _register_tracker_update_hook(self) -> None:
|
|
203
228
|
plugin_manager().register(StudioTrackerUpdatePlugin(self))
|
|
204
229
|
|
|
205
|
-
async def on_tracker_updated(
|
|
230
|
+
async def on_tracker_updated(
|
|
231
|
+
self, tracker: "DialogueStateTracker", latency: Optional[float] = None
|
|
232
|
+
) -> None:
|
|
206
233
|
"""Triggers a tracker update notification after a change to the tracker."""
|
|
207
|
-
await self.publish_tracker_update(
|
|
234
|
+
await self.publish_tracker_update(
|
|
235
|
+
tracker.sender_id, tracker_as_dump(tracker, latency)
|
|
236
|
+
)
|
|
208
237
|
|
|
209
|
-
async def publish_tracker_update(self, sender_id: str, tracker_dump:
|
|
238
|
+
async def publish_tracker_update(self, sender_id: str, tracker_dump: str) -> None:
|
|
210
239
|
"""Publishes a tracker update notification to the websocket."""
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
240
|
+
await self.emit("tracker", tracker_dump, room=sender_id)
|
|
241
|
+
|
|
242
|
+
def _record_turn_start_time(self, sender_id: Text) -> None:
|
|
243
|
+
"""Records the start time of a new turn."""
|
|
244
|
+
self._turn_start_times[sender_id] = time.time()
|
|
245
|
+
|
|
246
|
+
def _get_latency(self, sender_id: Text) -> Optional[float]:
|
|
247
|
+
"""Returns the latency of the current turn in milliseconds."""
|
|
248
|
+
if sender_id not in self._turn_start_times:
|
|
249
|
+
return None
|
|
250
|
+
|
|
251
|
+
latency = (time.time() - self._turn_start_times[sender_id]) * 1000
|
|
252
|
+
# The turn is over, so we can remove the start time
|
|
253
|
+
del self._turn_start_times[sender_id]
|
|
254
|
+
return latency
|
|
215
255
|
|
|
216
256
|
async def on_message_proxy(
|
|
217
257
|
self,
|
|
218
|
-
on_new_message: Callable[[
|
|
219
|
-
message:
|
|
258
|
+
on_new_message: Callable[[UserMessage], Awaitable[Any]],
|
|
259
|
+
message: UserMessage,
|
|
220
260
|
) -> None:
|
|
221
261
|
"""Proxies the on_new_message call to the underlying channel.
|
|
222
262
|
|
|
223
263
|
Triggers a tracker update notification after processing the message.
|
|
224
264
|
"""
|
|
225
|
-
|
|
265
|
+
self._record_turn_start_time(message.sender_id)
|
|
266
|
+
try:
|
|
267
|
+
await on_new_message(message)
|
|
268
|
+
except Exception as e:
|
|
269
|
+
structlogger.exception(
|
|
270
|
+
"studio_chat.on_new_message.error",
|
|
271
|
+
error=str(e),
|
|
272
|
+
sender_id=message.sender_id,
|
|
273
|
+
)
|
|
226
274
|
|
|
227
|
-
if not self.agent:
|
|
275
|
+
if not self.agent or not self.agent.is_ready():
|
|
228
276
|
structlogger.error("studio_chat.on_message_proxy.agent_not_initialized")
|
|
277
|
+
await self.emit_error(
|
|
278
|
+
"The Rasa Pro model could not be loaded. "
|
|
279
|
+
"Please check the training and deployment logs "
|
|
280
|
+
"for more information.",
|
|
281
|
+
message.sender_id,
|
|
282
|
+
AgentNotReady("The Rasa Pro model could not be loaded."),
|
|
283
|
+
)
|
|
229
284
|
return
|
|
230
285
|
|
|
231
286
|
tracker = await self.agent.tracker_store.retrieve(message.sender_id)
|
|
@@ -233,7 +288,19 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
233
288
|
structlogger.error("studio_chat.on_message_proxy.tracker_not_found")
|
|
234
289
|
return
|
|
235
290
|
|
|
236
|
-
|
|
291
|
+
latency = self._get_latency(message.sender_id)
|
|
292
|
+
await self.on_tracker_updated(tracker, latency)
|
|
293
|
+
|
|
294
|
+
async def emit_error(self, message: str, room: str, e: Exception) -> None:
|
|
295
|
+
await self.emit(
|
|
296
|
+
"error",
|
|
297
|
+
{
|
|
298
|
+
"message": message,
|
|
299
|
+
"error": str(e),
|
|
300
|
+
"exception": str(type(e).__name__),
|
|
301
|
+
},
|
|
302
|
+
room=room,
|
|
303
|
+
)
|
|
237
304
|
|
|
238
305
|
async def handle_tracker_update(self, sid: str, data: Dict) -> None:
|
|
239
306
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
@@ -251,21 +318,41 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
251
318
|
structlogger.error("studio_chat.sio.domain_not_initialized")
|
|
252
319
|
return None
|
|
253
320
|
|
|
254
|
-
|
|
255
|
-
tracker = DialogueStateTracker.from_dict(
|
|
256
|
-
data["sender_id"], data["events"], domain.slots
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
# will override an existing tracker with the same id!
|
|
260
|
-
await self.agent.tracker_store.save(tracker)
|
|
321
|
+
tracker: Optional[DialogueStateTracker] = None
|
|
261
322
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
323
|
+
async with self.agent.lock_store.lock(data["sender_id"]):
|
|
324
|
+
try:
|
|
325
|
+
tracker = DialogueStateTracker.from_dict(
|
|
326
|
+
data["sender_id"], data["events"], domain.slots
|
|
327
|
+
)
|
|
265
328
|
|
|
266
|
-
|
|
329
|
+
# will override an existing tracker with the same id!
|
|
267
330
|
await self.agent.tracker_store.save(tracker)
|
|
268
331
|
|
|
332
|
+
processor = self.agent.processor
|
|
333
|
+
if processor and does_need_action_prediction(tracker):
|
|
334
|
+
output_channel = self.get_output_channel()
|
|
335
|
+
|
|
336
|
+
await processor._run_prediction_loop(output_channel, tracker)
|
|
337
|
+
await self.agent.tracker_store.save(tracker)
|
|
338
|
+
except Exception as e:
|
|
339
|
+
structlogger.error(
|
|
340
|
+
"studio_chat.sio.handle_tracker_update.error",
|
|
341
|
+
error=e,
|
|
342
|
+
sender_id=data["sender_id"],
|
|
343
|
+
)
|
|
344
|
+
await self.emit_error(
|
|
345
|
+
"An error occurred while updating the conversation.",
|
|
346
|
+
data["sender_id"],
|
|
347
|
+
e,
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
if not tracker:
|
|
351
|
+
# in case the tracker couldn't be updated, we retrieve the prior
|
|
352
|
+
# version and use that to populate the update
|
|
353
|
+
tracker = await self.agent.tracker_store.get_or_create_tracker(
|
|
354
|
+
data["sender_id"]
|
|
355
|
+
)
|
|
269
356
|
await self.on_tracker_updated(tracker)
|
|
270
357
|
|
|
271
358
|
def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
|
|
@@ -275,7 +362,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
275
362
|
async def collect_call_parameters(
|
|
276
363
|
self, channel_websocket: "Websocket"
|
|
277
364
|
) -> Optional[CallParameters]:
|
|
278
|
-
"""Voice method to collect call parameters"""
|
|
365
|
+
"""Voice method to collect call parameters."""
|
|
279
366
|
session_id = channel_websocket.session_id
|
|
280
367
|
return CallParameters(session_id, "local", "local", stream_id=session_id)
|
|
281
368
|
|
|
@@ -292,20 +379,20 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
292
379
|
elif "marker" in message:
|
|
293
380
|
if message["marker"] == call_state.latest_bot_audio_id:
|
|
294
381
|
# Just finished streaming last audio bytes
|
|
295
|
-
call_state.is_bot_speaking = False
|
|
382
|
+
call_state.is_bot_speaking = False
|
|
296
383
|
if call_state.should_hangup:
|
|
297
384
|
structlogger.debug(
|
|
298
385
|
"studio_chat.hangup", marker=call_state.latest_bot_audio_id
|
|
299
386
|
)
|
|
300
387
|
return EndConversationAction()
|
|
301
388
|
else:
|
|
302
|
-
call_state.is_bot_speaking = True
|
|
389
|
+
call_state.is_bot_speaking = True
|
|
303
390
|
return ContinueConversationAction()
|
|
304
391
|
|
|
305
|
-
def
|
|
392
|
+
def _create_output_channel(
|
|
306
393
|
self, voice_websocket: "Websocket", tts_engine: TTSEngine
|
|
307
394
|
) -> VoiceOutputChannel:
|
|
308
|
-
"""Create a voice output channel"""
|
|
395
|
+
"""Create a voice output channel."""
|
|
309
396
|
return StudioVoiceOutputChannel(
|
|
310
397
|
voice_websocket,
|
|
311
398
|
tts_engine,
|
|
@@ -332,7 +419,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
332
419
|
|
|
333
420
|
# Create a websocket adapter for this connection
|
|
334
421
|
ws_adapter = SocketIOVoiceWebsocketAdapter(
|
|
335
|
-
|
|
422
|
+
sio_server=self.sio_server,
|
|
336
423
|
session_id=session_id,
|
|
337
424
|
sid=sid,
|
|
338
425
|
bot_message_evt=self.bot_message_evt,
|
|
@@ -380,13 +467,12 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
380
467
|
task.cancel()
|
|
381
468
|
|
|
382
469
|
def blueprint(
|
|
383
|
-
self, on_new_message: Callable[[
|
|
470
|
+
self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
|
|
384
471
|
) -> SocketBlueprint:
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
)
|
|
472
|
+
proxied_on_message = partial(self.on_message_proxy, on_new_message)
|
|
473
|
+
socket_blueprint = super().blueprint(proxied_on_message)
|
|
388
474
|
|
|
389
|
-
if not self.
|
|
475
|
+
if not self.sio_server:
|
|
390
476
|
structlogger.error("studio_chat.blueprint.sio_not_initialized")
|
|
391
477
|
return socket_blueprint
|
|
392
478
|
|
|
@@ -396,12 +482,12 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
396
482
|
) -> None:
|
|
397
483
|
self.agent = app.ctx.agent
|
|
398
484
|
|
|
399
|
-
@self.
|
|
485
|
+
@self.sio_server.on("disconnect", namespace=self.namespace)
|
|
400
486
|
async def disconnect(sid: Text) -> None:
|
|
401
487
|
structlogger.debug("studio_chat.sio.disconnect", sid=sid)
|
|
402
488
|
self._cleanup_tasks_for_sid(sid)
|
|
403
489
|
|
|
404
|
-
@self.
|
|
490
|
+
@self.sio_server.on("session_request", namespace=self.namespace)
|
|
405
491
|
async def session_request(sid: Text, data: Optional[Dict]) -> None:
|
|
406
492
|
"""Overrides the base SocketIOInput session_request handler.
|
|
407
493
|
|
|
@@ -419,9 +505,9 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
419
505
|
|
|
420
506
|
# start a voice session if requested
|
|
421
507
|
if data and data.get("is_voice", False):
|
|
422
|
-
self._start_voice_session(data["session_id"], sid,
|
|
508
|
+
self._start_voice_session(data["session_id"], sid, proxied_on_message)
|
|
423
509
|
|
|
424
|
-
@self.
|
|
510
|
+
@self.sio_server.on(self.user_message_evt, namespace=self.namespace)
|
|
425
511
|
async def handle_message(sid: Text, data: Dict) -> None:
|
|
426
512
|
"""Overrides the base SocketIOInput handle_message handler."""
|
|
427
513
|
# Handle voice messages
|
|
@@ -432,10 +518,18 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
432
518
|
ws.put_message(data)
|
|
433
519
|
return
|
|
434
520
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
521
|
+
try:
|
|
522
|
+
# Handle text messages
|
|
523
|
+
await self.handle_user_message(sid, data, proxied_on_message)
|
|
524
|
+
except Exception as e:
|
|
525
|
+
structlogger.exception(
|
|
526
|
+
"studio_chat.sio.handle_message.error",
|
|
527
|
+
error=str(e),
|
|
528
|
+
sid=sid,
|
|
529
|
+
)
|
|
530
|
+
await self.emit("error", str(e), room=sid)
|
|
531
|
+
|
|
532
|
+
@self.sio_server.on("update_tracker", namespace=self.namespace)
|
|
439
533
|
async def on_update_tracker(sid: Text, data: Dict) -> None:
|
|
440
534
|
await self.handle_tracker_update(sid, data)
|
|
441
535
|
|
|
@@ -457,16 +551,33 @@ class StudioVoiceOutputChannel(VoiceOutputChannel):
|
|
|
457
551
|
|
|
458
552
|
def create_marker_message(self, recipient_id: str) -> Tuple[str, str]:
|
|
459
553
|
message_id = uuid.uuid4().hex
|
|
460
|
-
|
|
554
|
+
marker_data = {"marker": message_id}
|
|
555
|
+
|
|
556
|
+
# Include comprehensive latency information if available
|
|
557
|
+
latency_data = {
|
|
558
|
+
"asr_latency_ms": call_state.asr_latency_ms,
|
|
559
|
+
"rasa_processing_latency_ms": call_state.rasa_processing_latency_ms,
|
|
560
|
+
"tts_first_byte_latency_ms": call_state.tts_first_byte_latency_ms,
|
|
561
|
+
"tts_complete_latency_ms": call_state.tts_complete_latency_ms,
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
# Filter out None values from latency data
|
|
565
|
+
latency_data = {k: v for k, v in latency_data.items() if v is not None}
|
|
566
|
+
|
|
567
|
+
# Add latency data to marker if any metrics are available
|
|
568
|
+
if latency_data:
|
|
569
|
+
marker_data["latency"] = latency_data # type: ignore[assignment]
|
|
570
|
+
|
|
571
|
+
return json.dumps(marker_data), message_id
|
|
461
572
|
|
|
462
573
|
|
|
463
574
|
class SocketIOVoiceWebsocketAdapter:
|
|
464
575
|
"""Adapter to make Socket.IO work like a Sanic WebSocket for voice channels."""
|
|
465
576
|
|
|
466
577
|
def __init__(
|
|
467
|
-
self,
|
|
578
|
+
self, sio_server: "AsyncServer", session_id: str, sid: str, bot_message_evt: str
|
|
468
579
|
) -> None:
|
|
469
|
-
self.
|
|
580
|
+
self.sio_server = sio_server
|
|
470
581
|
self.bot_message_evt = bot_message_evt
|
|
471
582
|
self._closed = False
|
|
472
583
|
self._receive_queue: asyncio.Queue[Any] = asyncio.Queue()
|
|
@@ -485,7 +596,7 @@ class SocketIOVoiceWebsocketAdapter:
|
|
|
485
596
|
async def send(self, data: Any) -> None:
|
|
486
597
|
"""Send data to the client."""
|
|
487
598
|
if not self.closed:
|
|
488
|
-
await self.
|
|
599
|
+
await self.sio_server.emit(self.bot_message_evt, data, room=self.sid)
|
|
489
600
|
|
|
490
601
|
async def recv(self) -> Any:
|
|
491
602
|
"""Receive data from the client."""
|
|
@@ -30,7 +30,7 @@ TWILIO_VOICE_PATH = "webhooks/twilio_voice/webhook"
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def map_call_params(form: RequestParameters) -> CallParameters:
|
|
33
|
-
"""Map the
|
|
33
|
+
"""Map the Twilio Voice parameters to the CallParameters dataclass."""
|
|
34
34
|
return CallParameters(
|
|
35
35
|
call_id=form.get("CallSid"),
|
|
36
36
|
user_phone=form.get("Caller"),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import base64
|
|
3
5
|
import hmac
|
|
@@ -21,6 +23,7 @@ from rasa.core.channels.voice_stream.call_state import (
|
|
|
21
23
|
call_state,
|
|
22
24
|
)
|
|
23
25
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
26
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
24
27
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
25
28
|
ContinueConversationAction,
|
|
26
29
|
EndConversationAction,
|
|
@@ -85,7 +88,7 @@ class AudiocodesVoiceOutputChannel(VoiceOutputChannel):
|
|
|
85
88
|
# however, Audiocodes does not have an event to indicate that.
|
|
86
89
|
# This is an approximation, as the bot will be sent the audio chunks next
|
|
87
90
|
# which are played to the user immediately.
|
|
88
|
-
call_state.is_bot_speaking = True
|
|
91
|
+
call_state.is_bot_speaking = True
|
|
89
92
|
|
|
90
93
|
async def send_intermediate_marker(self, recipient_id: str) -> None:
|
|
91
94
|
"""Audiocodes doesn't need intermediate markers, so do nothing."""
|
|
@@ -127,10 +130,10 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
|
|
|
127
130
|
def from_credentials(
|
|
128
131
|
cls,
|
|
129
132
|
credentials: Optional[Dict[str, Any]],
|
|
130
|
-
) ->
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return
|
|
133
|
+
) -> AudiocodesVoiceInputChannel:
|
|
134
|
+
cls.validate_basic_credentials(credentials)
|
|
135
|
+
new_creds = repack_voice_credentials(credentials)
|
|
136
|
+
return cls(**new_creds)
|
|
134
137
|
|
|
135
138
|
def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
|
|
136
139
|
return RasaAudioBytes(base64.b64decode(input_bytes))
|
|
@@ -184,7 +187,7 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
|
|
|
184
187
|
pass
|
|
185
188
|
elif activity["name"] == "playFinished":
|
|
186
189
|
logger.debug("audiocodes_stream.playFinished", data=activity)
|
|
187
|
-
call_state.is_bot_speaking = False
|
|
190
|
+
call_state.is_bot_speaking = False
|
|
188
191
|
if call_state.should_hangup:
|
|
189
192
|
logger.info("audiocodes_stream.hangup")
|
|
190
193
|
self._send_hangup(ws, data)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import audioop
|
|
2
4
|
import base64
|
|
3
5
|
import json
|
|
4
6
|
import uuid
|
|
5
|
-
from typing import Any, Awaitable, Callable, Optional, Tuple
|
|
7
|
+
from typing import Any, Awaitable, Callable, Dict, Optional, Tuple
|
|
6
8
|
|
|
7
9
|
import structlog
|
|
8
10
|
from sanic import ( # type: ignore[attr-defined]
|
|
@@ -18,6 +20,7 @@ from rasa.core.channels.voice_ready.utils import CallParameters
|
|
|
18
20
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
19
21
|
from rasa.core.channels.voice_stream.call_state import call_state
|
|
20
22
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
23
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
21
24
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
22
25
|
ContinueConversationAction,
|
|
23
26
|
EndConversationAction,
|
|
@@ -45,10 +48,33 @@ class BrowserAudioOutputChannel(VoiceOutputChannel):
|
|
|
45
48
|
|
|
46
49
|
def create_marker_message(self, recipient_id: str) -> Tuple[str, str]:
|
|
47
50
|
message_id = uuid.uuid4().hex
|
|
48
|
-
|
|
51
|
+
marker_data = {"marker": message_id}
|
|
52
|
+
|
|
53
|
+
# Include comprehensive latency information if available
|
|
54
|
+
latency_data = {
|
|
55
|
+
"asr_latency_ms": call_state.asr_latency_ms,
|
|
56
|
+
"rasa_processing_latency_ms": call_state.rasa_processing_latency_ms,
|
|
57
|
+
"tts_first_byte_latency_ms": call_state.tts_first_byte_latency_ms,
|
|
58
|
+
"tts_complete_latency_ms": call_state.tts_complete_latency_ms,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Filter out None values from latency data
|
|
62
|
+
latency_data = {k: v for k, v in latency_data.items() if v is not None}
|
|
63
|
+
|
|
64
|
+
# Add latency data to marker if any metrics are available
|
|
65
|
+
if latency_data:
|
|
66
|
+
marker_data["latency"] = latency_data # type: ignore[assignment]
|
|
67
|
+
|
|
68
|
+
return json.dumps(marker_data), message_id
|
|
49
69
|
|
|
50
70
|
|
|
51
71
|
class BrowserAudioInputChannel(VoiceInputChannel):
|
|
72
|
+
def __init__(
|
|
73
|
+
self, server_url: str, asr_config: Dict[str, Any], tts_config: Dict[str, Any]
|
|
74
|
+
) -> None:
|
|
75
|
+
"""Initializes the browser audio input channel."""
|
|
76
|
+
super().__init__(server_url, asr_config, tts_config)
|
|
77
|
+
|
|
52
78
|
@classmethod
|
|
53
79
|
def name(cls) -> str:
|
|
54
80
|
return "browser_audio"
|
|
@@ -62,6 +88,15 @@ class BrowserAudioInputChannel(VoiceInputChannel):
|
|
|
62
88
|
call_id = f"inspect-{uuid.uuid4()}"
|
|
63
89
|
return CallParameters(call_id, "local", "local", stream_id=call_id)
|
|
64
90
|
|
|
91
|
+
@classmethod
|
|
92
|
+
def from_credentials(
|
|
93
|
+
cls,
|
|
94
|
+
credentials: Optional[Dict[str, Any]],
|
|
95
|
+
) -> BrowserAudioInputChannel:
|
|
96
|
+
cls.validate_basic_credentials(credentials)
|
|
97
|
+
new_creds = repack_voice_credentials(credentials)
|
|
98
|
+
return cls(**new_creds)
|
|
99
|
+
|
|
65
100
|
def map_input_message(
|
|
66
101
|
self,
|
|
67
102
|
message: Any,
|
|
@@ -75,14 +110,14 @@ class BrowserAudioInputChannel(VoiceInputChannel):
|
|
|
75
110
|
elif "marker" in data:
|
|
76
111
|
if data["marker"] == call_state.latest_bot_audio_id:
|
|
77
112
|
# Just finished streaming last audio bytes
|
|
78
|
-
call_state.is_bot_speaking = False
|
|
113
|
+
call_state.is_bot_speaking = False
|
|
79
114
|
if call_state.should_hangup:
|
|
80
115
|
logger.debug(
|
|
81
116
|
"browser_audio.hangup", marker=call_state.latest_bot_audio_id
|
|
82
117
|
)
|
|
83
118
|
return EndConversationAction()
|
|
84
119
|
else:
|
|
85
|
-
call_state.is_bot_speaking = True
|
|
120
|
+
call_state.is_bot_speaking = True
|
|
86
121
|
return ContinueConversationAction()
|
|
87
122
|
|
|
88
123
|
def create_output_channel(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from contextvars import ContextVar
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Any, Dict, Optional
|
|
4
|
+
from typing import Any, Dict, Optional, cast
|
|
5
5
|
|
|
6
6
|
from werkzeug.local import LocalProxy
|
|
7
7
|
|
|
@@ -19,9 +19,20 @@ class CallState:
|
|
|
19
19
|
should_hangup: bool = False
|
|
20
20
|
connection_failed: bool = False
|
|
21
21
|
|
|
22
|
+
# Latency tracking - start times only
|
|
23
|
+
user_speech_start_time: Optional[float] = None
|
|
24
|
+
rasa_processing_start_time: Optional[float] = None
|
|
25
|
+
tts_start_time: Optional[float] = None
|
|
26
|
+
|
|
27
|
+
# Calculated latencies (used by channels like browser_audio)
|
|
28
|
+
asr_latency_ms: Optional[float] = None
|
|
29
|
+
rasa_processing_latency_ms: Optional[float] = None
|
|
30
|
+
tts_first_byte_latency_ms: Optional[float] = None
|
|
31
|
+
tts_complete_latency_ms: Optional[float] = None
|
|
32
|
+
|
|
22
33
|
# Generic field for channel-specific state data
|
|
23
34
|
channel_data: Dict[str, Any] = field(default_factory=dict)
|
|
24
35
|
|
|
25
36
|
|
|
26
37
|
_call_state: ContextVar[CallState] = ContextVar("call_state")
|
|
27
|
-
call_state = LocalProxy(_call_state)
|
|
38
|
+
call_state: CallState = cast(CallState, LocalProxy(_call_state))
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import base64
|
|
3
5
|
import hashlib
|
|
@@ -21,6 +23,7 @@ from rasa.core.channels.voice_stream.call_state import (
|
|
|
21
23
|
call_state,
|
|
22
24
|
)
|
|
23
25
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
26
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
24
27
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
25
28
|
ContinueConversationAction,
|
|
26
29
|
EndConversationAction,
|
|
@@ -54,7 +57,7 @@ logger = structlog.get_logger(__name__)
|
|
|
54
57
|
|
|
55
58
|
|
|
56
59
|
def map_call_params(data: Dict[Text, Any]) -> CallParameters:
|
|
57
|
-
"""Map the
|
|
60
|
+
"""Map the Genesys parameters to the CallParameters dataclass."""
|
|
58
61
|
parameters = data["parameters"]
|
|
59
62
|
participant = parameters["participant"]
|
|
60
63
|
# sent as {"ani": "tel:+491604697810"}
|
|
@@ -107,7 +110,7 @@ class GenesysInputChannel(VoiceInputChannel):
|
|
|
107
110
|
def from_credentials(
|
|
108
111
|
cls,
|
|
109
112
|
credentials: Optional[Dict[str, Any]],
|
|
110
|
-
) ->
|
|
113
|
+
) -> GenesysInputChannel:
|
|
111
114
|
"""Create a channel from credentials dictionary.
|
|
112
115
|
|
|
113
116
|
Args:
|
|
@@ -121,21 +124,21 @@ class GenesysInputChannel(VoiceInputChannel):
|
|
|
121
124
|
Returns:
|
|
122
125
|
GenesysInputChannel instance
|
|
123
126
|
"""
|
|
124
|
-
|
|
127
|
+
cls.validate_credentials(credentials)
|
|
128
|
+
new_creds = repack_voice_credentials(credentials)
|
|
129
|
+
return cls(**new_creds)
|
|
125
130
|
|
|
126
|
-
|
|
131
|
+
@classmethod
|
|
132
|
+
def validate_credentials(cls, credentials: Optional[Dict[str, Any]]) -> None:
|
|
133
|
+
"""Validate the credentials for the Genesys voice channel."""
|
|
134
|
+
cls.validate_basic_credentials(credentials)
|
|
127
135
|
if not credentials.get("api_key"): # type: ignore[union-attr]
|
|
128
136
|
raise InvalidConfigException(
|
|
129
137
|
"No API key given for Genesys voice channel (api_key)."
|
|
130
138
|
)
|
|
131
139
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
channel.client_secret = credentials.get("client_secret") # type: ignore[union-attr,attr-defined]
|
|
135
|
-
|
|
136
|
-
return channel # type: ignore[return-value]
|
|
137
|
-
|
|
138
|
-
def _ensure_channel_data_initialized(self) -> None:
|
|
140
|
+
@staticmethod
|
|
141
|
+
def _ensure_channel_data_initialized() -> None:
|
|
139
142
|
"""Initialize Genesys-specific channel data if not already present.
|
|
140
143
|
|
|
141
144
|
Genesys requires the server and client each maintain a
|
|
@@ -216,10 +219,10 @@ class GenesysInputChannel(VoiceInputChannel):
|
|
|
216
219
|
self.handle_ping(ws, data)
|
|
217
220
|
elif msg_type == "playback_started":
|
|
218
221
|
logger.debug("genesys.handle_playback_started", message=data)
|
|
219
|
-
call_state.is_bot_speaking = True
|
|
222
|
+
call_state.is_bot_speaking = True
|
|
220
223
|
elif msg_type == "playback_completed":
|
|
221
224
|
logger.debug("genesys.handle_playback_completed", message=data)
|
|
222
|
-
call_state.is_bot_speaking = False
|
|
225
|
+
call_state.is_bot_speaking = False
|
|
223
226
|
if call_state.should_hangup:
|
|
224
227
|
logger.info("genesys.hangup")
|
|
225
228
|
self.disconnect(ws, data)
|