rasa-pro 3.14.0.dev20250901__py3-none-any.whl → 3.14.0rc1__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/__main__.py +15 -3
- rasa/agents/__init__.py +0 -0
- rasa/agents/agent_factory.py +122 -0
- rasa/agents/agent_manager.py +211 -0
- rasa/agents/constants.py +43 -0
- rasa/agents/core/__init__.py +0 -0
- rasa/agents/core/agent_protocol.py +107 -0
- rasa/agents/core/types.py +81 -0
- rasa/agents/exceptions.py +38 -0
- rasa/agents/protocol/__init__.py +5 -0
- rasa/agents/protocol/a2a/__init__.py +0 -0
- rasa/agents/protocol/a2a/a2a_agent.py +879 -0
- rasa/agents/protocol/mcp/__init__.py +0 -0
- rasa/agents/protocol/mcp/mcp_base_agent.py +726 -0
- rasa/agents/protocol/mcp/mcp_open_agent.py +327 -0
- rasa/agents/protocol/mcp/mcp_task_agent.py +522 -0
- rasa/agents/schemas/__init__.py +13 -0
- rasa/agents/schemas/agent_input.py +38 -0
- rasa/agents/schemas/agent_output.py +26 -0
- rasa/agents/schemas/agent_tool_result.py +65 -0
- rasa/agents/schemas/agent_tool_schema.py +186 -0
- rasa/agents/templates/__init__.py +0 -0
- rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +20 -0
- rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +22 -0
- rasa/agents/utils.py +206 -0
- rasa/agents/validation.py +485 -0
- rasa/api.py +24 -9
- rasa/builder/config.py +7 -2
- rasa/builder/copilot/constants.py +3 -0
- rasa/builder/copilot/copilot.py +128 -54
- rasa/builder/copilot/models.py +39 -3
- rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +183 -188
- rasa/builder/copilot/prompts/latest_user_message_context_prompt.jinja2 +61 -0
- rasa/builder/copilot/telemetry.py +46 -20
- rasa/builder/document_retrieval/models.py +3 -3
- rasa/builder/download.py +1 -8
- rasa/builder/guardrails/{lakera.py → clients.py} +55 -5
- rasa/builder/guardrails/constants.py +3 -0
- rasa/builder/guardrails/models.py +45 -10
- rasa/builder/guardrails/policy_checker.py +324 -0
- rasa/builder/guardrails/utils.py +42 -276
- rasa/builder/jobs.py +33 -21
- rasa/builder/llm_service.py +32 -5
- rasa/builder/main.py +38 -62
- rasa/builder/models.py +8 -7
- rasa/builder/project_generator.py +149 -148
- rasa/builder/service.py +58 -40
- rasa/builder/template_cache.py +69 -0
- rasa/builder/training_service.py +84 -20
- rasa/builder/validation_service.py +1 -1
- rasa/cli/arguments/default_arguments.py +12 -0
- rasa/cli/arguments/run.py +2 -0
- rasa/cli/arguments/train.py +2 -0
- rasa/cli/data.py +10 -8
- rasa/cli/dialogue_understanding_test.py +10 -7
- rasa/cli/e2e_test.py +9 -6
- rasa/cli/evaluate.py +4 -2
- rasa/cli/export.py +5 -2
- rasa/cli/inspect.py +8 -4
- rasa/cli/interactive.py +5 -4
- rasa/cli/llm_fine_tuning.py +11 -6
- rasa/cli/project_templates/basic/README.md +23 -0
- rasa/cli/project_templates/basic/actions/actions.md +10 -0
- rasa/cli/project_templates/basic/config.yml +6 -4
- rasa/cli/project_templates/basic/data/data.md +5 -6
- rasa/cli/project_templates/basic/domain/domain.md +7 -5
- rasa/cli/project_templates/basic/domain/general/show_faqs.yml +1 -1
- rasa/cli/project_templates/basic/endpoints.yml +5 -1
- rasa/cli/project_templates/default/config.yml +4 -0
- rasa/cli/project_templates/default/endpoints.yml +4 -0
- rasa/cli/project_templates/finance/README.md +26 -0
- rasa/cli/project_templates/finance/actions/__init__.py +0 -46
- rasa/cli/project_templates/finance/actions/accounts/check_balance.py +18 -0
- rasa/cli/project_templates/finance/actions/actions.md +15 -0
- rasa/cli/project_templates/finance/actions/{transfers/action_process_immediate_payment.py → cards/check_that_card_exists.py} +6 -3
- rasa/cli/project_templates/finance/actions/cards/list_cards.py +22 -0
- rasa/cli/project_templates/finance/actions/contacts/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/contacts/add_contact.py +30 -0
- rasa/cli/project_templates/finance/actions/contacts/list_contacts.py +22 -0
- rasa/cli/project_templates/finance/actions/contacts/remove_contact.py +35 -0
- rasa/cli/project_templates/finance/actions/db.py +117 -0
- rasa/cli/project_templates/finance/actions/general/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/general/action_human_handoff.py +49 -0
- rasa/cli/project_templates/finance/actions/transfers/check_transfer_funds.py +27 -0
- rasa/cli/project_templates/finance/actions/transfers/check_transfer_limit.py +36 -0
- rasa/cli/project_templates/finance/actions/transfers/execute_recurrent_payment.py +20 -0
- rasa/cli/project_templates/finance/actions/transfers/execute_transfer.py +45 -0
- rasa/cli/project_templates/finance/actions/transfers/list_transactions.py +32 -0
- rasa/cli/project_templates/finance/config.yml +8 -0
- rasa/cli/project_templates/finance/credentials.yml +7 -6
- rasa/cli/project_templates/finance/data/accounts/check_balance.yml +3 -4
- rasa/cli/project_templates/finance/data/accounts/download_statements.yml +26 -0
- rasa/cli/project_templates/finance/data/bills/bill_pay_reminder.yml +25 -0
- rasa/cli/project_templates/finance/data/cards/activate_card.yml +35 -0
- rasa/cli/project_templates/finance/data/cards/block_card.yml +37 -58
- rasa/cli/project_templates/finance/data/cards/list_cards.yml +14 -0
- rasa/cli/project_templates/finance/data/cards/replace_card.yml +16 -0
- rasa/cli/project_templates/finance/data/cards/replace_eligible_card.yml +29 -0
- rasa/cli/project_templates/finance/data/contacts/add_contact.yml +33 -0
- rasa/cli/project_templates/finance/data/contacts/list_contacts.yml +14 -0
- rasa/cli/project_templates/finance/data/contacts/remove_contact.yml +31 -0
- rasa/cli/project_templates/finance/data/data.md +14 -0
- rasa/cli/project_templates/finance/data/general/bot_challenge.yml +6 -0
- rasa/cli/project_templates/finance/data/general/goodbye.yml +1 -1
- rasa/cli/project_templates/finance/data/general/hello.yml +1 -2
- rasa/cli/project_templates/finance/data/general/help.yml +2 -2
- rasa/cli/project_templates/finance/data/general/human_handoff.yml +2 -2
- rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +1 -1
- rasa/cli/project_templates/finance/data/transfers/check_transfer_limit.yml +18 -0
- rasa/cli/project_templates/finance/data/transfers/list_transactions.yml +46 -0
- rasa/cli/project_templates/finance/data/transfers/move_money_between_accounts.yml +51 -0
- rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +29 -62
- rasa/cli/project_templates/finance/data/transfers/transfer_money_to_a_third_party.yml +175 -0
- rasa/cli/project_templates/finance/db/cards.json +18 -0
- rasa/cli/project_templates/finance/db/contacts.json +10 -0
- rasa/cli/project_templates/finance/db/my_account.json +6 -0
- rasa/cli/project_templates/finance/db/transactions.json +22 -0
- rasa/cli/project_templates/finance/docs/docs.md +8 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/budgeting_analytics.txt +22 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/multi_currency_accounts.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/premium_benefits.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/contactless_limits.txt +16 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/freeze_unfreeze_card.txt +16 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/lost_stolen_card.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/instant_payments.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/international_transfers.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/fraud_protection.txt +22 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/secure_payments.txt +22 -0
- rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +9 -5
- rasa/cli/project_templates/finance/domain/accounts/download_statements.yml +40 -0
- rasa/cli/project_templates/finance/domain/bills/bill_pay_reminder.yml +49 -0
- rasa/cli/project_templates/finance/domain/cards/activate_card.yml +24 -0
- rasa/cli/project_templates/finance/domain/cards/block_card.yml +33 -90
- rasa/cli/project_templates/finance/domain/cards/list_cards.yml +16 -0
- rasa/cli/project_templates/finance/domain/cards/replace_card.yml +43 -0
- rasa/cli/project_templates/finance/domain/cards/shared.yml +15 -0
- rasa/cli/project_templates/finance/domain/contacts/add_contact.yml +37 -0
- rasa/cli/project_templates/finance/domain/contacts/list_contacts.yml +16 -0
- rasa/cli/project_templates/finance/domain/contacts/remove_contact.yml +32 -0
- rasa/cli/project_templates/finance/domain/domain.md +18 -0
- rasa/cli/project_templates/finance/domain/general/_shared.yml +39 -0
- rasa/cli/project_templates/finance/domain/general/bot_challenge.yml +4 -0
- rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -2
- rasa/cli/project_templates/finance/domain/general/feedback.yml +0 -3
- rasa/cli/project_templates/finance/domain/general/goodbye.yml +6 -6
- rasa/cli/project_templates/finance/domain/general/human_handoff.yml +10 -9
- rasa/cli/project_templates/finance/domain/general/welcome.yml +33 -2
- rasa/cli/project_templates/finance/domain/transfers/check_transfer_limit.yml +32 -0
- rasa/cli/project_templates/finance/domain/transfers/list_transactions.yml +44 -0
- rasa/cli/project_templates/finance/domain/transfers/shared.yml +17 -0
- rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +203 -61
- rasa/cli/project_templates/finance/endpoints.yml +8 -4
- rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +31 -12
- rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/check_balance.yml +9 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/download_statements.yml +43 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/cards/block_card.yml +55 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/feedback.yml +46 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/goodbye.yml +9 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/hello.yml +8 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/human_handoff.yml +35 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/patterns.yml +22 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/transfers/transfer_money.yml +56 -0
- rasa/cli/project_templates/telco/README.md +25 -0
- rasa/cli/project_templates/telco/actions/actions.md +12 -0
- rasa/cli/project_templates/telco/config.yml +6 -4
- rasa/cli/project_templates/telco/data/data.md +11 -0
- rasa/cli/project_templates/telco/data/general/human_handoff.yml +1 -1
- rasa/cli/project_templates/telco/docs/docs.md +3 -0
- rasa/cli/project_templates/telco/domain/domain.md +13 -0
- rasa/cli/project_templates/telco/domain/general/human_handoff.yml +3 -6
- rasa/cli/project_templates/telco/endpoints.yml +5 -1
- rasa/cli/project_templates/telco/prompts/rephraser_demo_personality_prompt.jinja2 +1 -1
- rasa/cli/project_templates/telco/tests/e2e_test_cases/billing/understand_bill.yml +67 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/feedback.yml +46 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/goodbye.yml +9 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/hello.yml +8 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/human_handoff.yml +35 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/patterns.yml +23 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/network/solve_internet_issue.yml +57 -0
- rasa/cli/project_templates/tutorial/credentials.yml +10 -0
- rasa/cli/run.py +12 -10
- rasa/cli/scaffold.py +4 -4
- rasa/cli/shell.py +9 -5
- rasa/cli/studio/studio.py +1 -1
- rasa/cli/test.py +34 -14
- rasa/cli/train.py +41 -28
- rasa/cli/utils.py +1 -393
- rasa/cli/validation/__init__.py +0 -0
- rasa/cli/validation/bot_config.py +223 -0
- rasa/cli/validation/config_path_validation.py +257 -0
- rasa/cli/x.py +8 -4
- rasa/constants.py +7 -1
- rasa/core/actions/action.py +51 -10
- rasa/core/actions/action_run_slot_rejections.py +1 -1
- rasa/core/actions/direct_custom_actions_executor.py +9 -2
- rasa/core/actions/grpc_custom_action_executor.py +1 -1
- rasa/core/agent.py +19 -2
- rasa/core/available_agents.py +229 -0
- rasa/core/brokers/broker.py +1 -1
- rasa/core/brokers/kafka.py +52 -8
- rasa/core/channels/__init__.py +82 -35
- rasa/core/channels/development_inspector.py +4 -24
- rasa/core/channels/hangouts.py +2 -2
- rasa/core/channels/inspector/README.md +25 -13
- rasa/core/channels/inspector/dist/assets/{arc-18042c22.js → arc-6177260a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-fdd6bcfa.js → blockDiagram-38ab4fdb-b054f038.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-f5ae6786.js → c4Diagram-3d4e48cf-f25427d5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-bf9cbb34.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-81efba3e.js → classDiagram-70f12bd4-c7a2af53.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-3b6b6a92.js → classDiagram-v2-f2320105-58db65c0.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-8f9083bb.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-31422447.js → createText-2e5e7dd3-088372e2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-518a90db.js → edges-e0da2a9e-58676240.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-a6d3c25a.js → erDiagram-9861fffd-0c14d7c6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e048c2be.js → flowDb-956e92f1-ea63f85c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c7474c91.js → flowDiagram-66a62f08-a2af48cd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-9ecd5b59.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb4d8723.js → flowchart-elk-definition-4a651766-6937abe7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-346636a2.js → ganttDiagram-c361ad54-7473f357.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-7c508874.js → gitGraphDiagram-72cf32ee-d0c9405e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-14702d8a.js → graph-0a6f8466.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-f18b534b.js → index-3862675e-7610671a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-74e01d94.js +1354 -0
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-64154b83.js → infoDiagram-f8f76790-be397dc7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-833a5f95.js → journeyDiagram-49397b02-4cefbf62.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-5a3b2123.js → layout-e7fbc2bf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-2272a8c7.js → line-a8aa457c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-35bcf273.js → linear-3351e0d2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-92dcb0e9.js → mindmap-definition-fc14e90a-b8cbf605.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-94dbc900.js → pieDiagram-8a3498a8-f327f774.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-8b7a9c33.js → quadrantDiagram-120e2f19-2854c591.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6f7eab81.js → requirementDiagram-deff3bca-964985d5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-f43e581d.js → sankeyDiagram-04a897e0-edeb4f33.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-0bcbefc3.js → sequenceDiagram-704730f1-fcf70125.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-b8a74083.js → stateDiagram-587899a1-0e770395.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-2070218f.js → stateDiagram-v2-d93cdb3a-af8dcd22.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-f1d54e34.js → styles-6aaf32cf-36a9e70d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-980de489.js → styles-9a916d00-884a8b5b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-3c03abde.js → styles-c10674c1-dc097813.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-46ba068f.js → svgDrawCommon-08f97a94-5a2c7eed.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-901f5e3d.js → timeline-definition-85554ec2-e89c4f6e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-acbc628a.js → xychartDiagram-e933f94c-afb6fe56.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/package.json +18 -18
- rasa/core/channels/inspector/src/App.tsx +34 -35
- rasa/core/channels/inspector/src/components/Chat.tsx +2 -3
- rasa/core/channels/inspector/src/components/DialogueAgentStack.tsx +108 -0
- rasa/core/channels/inspector/src/components/{DialogueStack.tsx → DialogueHistoryStack.tsx} +4 -2
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +9 -1
- rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +63 -35
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +20 -3
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +24 -3
- rasa/core/channels/inspector/src/helpers/utils.test.ts +127 -0
- rasa/core/channels/inspector/src/helpers/utils.ts +66 -1
- rasa/core/channels/inspector/src/theme/base/styles.ts +19 -1
- rasa/core/channels/inspector/src/types.ts +53 -7
- rasa/core/channels/inspector/yarn.lock +336 -189
- rasa/core/channels/studio_chat.py +29 -47
- rasa/core/channels/telegram.py +4 -9
- rasa/core/channels/voice_stream/asr/asr_event.py +1 -1
- rasa/core/channels/voice_stream/asr/azure.py +6 -3
- rasa/core/channels/voice_stream/asr/deepgram.py +1 -1
- rasa/core/channels/voice_stream/audiocodes.py +3 -0
- rasa/core/channels/voice_stream/browser_audio.py +55 -3
- rasa/core/channels/voice_stream/genesys.py +3 -2
- rasa/core/channels/voice_stream/jambonz.py +9 -1
- rasa/core/channels/voice_stream/tts/deepgram.py +140 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +21 -1
- rasa/core/channels/voice_stream/voice_channel.py +64 -0
- rasa/core/concurrent_lock_store.py +66 -16
- rasa/core/config/__init__.py +0 -0
- rasa/core/{available_endpoints.py → config/available_endpoints.py} +51 -16
- rasa/core/config/configuration.py +260 -0
- rasa/core/config/credentials.py +19 -0
- rasa/core/config/message_procesing_config.py +34 -0
- rasa/core/constants.py +11 -0
- rasa/core/iam_credentials_providers/__init__.py +0 -0
- rasa/core/iam_credentials_providers/aws_iam_credentials_providers.py +226 -0
- rasa/core/iam_credentials_providers/credentials_provider_protocol.py +90 -0
- rasa/core/lock_store.py +46 -10
- rasa/core/nlg/generator.py +1 -1
- rasa/core/policies/enterprise_search_policy.py +5 -3
- rasa/core/policies/flow_policy.py +4 -4
- rasa/core/policies/flows/agent_executor.py +632 -0
- rasa/core/policies/flows/flow_executor.py +137 -76
- rasa/core/policies/flows/mcp_tool_executor.py +298 -0
- rasa/core/policies/intentless_policy.py +1 -1
- rasa/core/policies/ted_policy.py +20 -12
- rasa/core/policies/unexpected_intent_policy.py +6 -0
- rasa/core/processor.py +100 -44
- rasa/core/redis_connection_factory.py +469 -0
- rasa/core/run.py +37 -8
- rasa/core/test.py +4 -0
- rasa/core/tracker_stores/redis_tracker_store.py +32 -14
- rasa/core/tracker_stores/sql_tracker_store.py +57 -1
- rasa/core/tracker_stores/tracker_store.py +3 -7
- rasa/core/train.py +1 -1
- rasa/core/training/interactive.py +20 -18
- rasa/core/training/story_conflict.py +5 -5
- rasa/core/utils.py +22 -23
- rasa/dialogue_understanding/commands/__init__.py +8 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +19 -5
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +21 -2
- rasa/dialogue_understanding/commands/clarify_command.py +20 -2
- rasa/dialogue_understanding/commands/continue_agent_command.py +91 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +21 -2
- rasa/dialogue_understanding/commands/restart_agent_command.py +162 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +68 -7
- rasa/dialogue_understanding/commands/utils.py +124 -2
- rasa/dialogue_understanding/generator/command_parser.py +4 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +50 -12
- rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +1 -1
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +66 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +66 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +89 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +88 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +42 -7
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +40 -3
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +20 -3
- rasa/dialogue_understanding/patterns/cancel.py +27 -6
- rasa/dialogue_understanding/patterns/clarify.py +3 -14
- rasa/dialogue_understanding/patterns/continue_interrupted.py +239 -6
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +46 -8
- rasa/dialogue_understanding/processor/command_processor.py +136 -15
- rasa/dialogue_understanding/stack/dialogue_stack.py +98 -2
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +57 -0
- rasa/dialogue_understanding/stack/utils.py +57 -3
- rasa/dialogue_understanding/utils.py +24 -4
- rasa/dialogue_understanding_test/du_test_runner.py +8 -3
- rasa/e2e_test/e2e_test_runner.py +13 -3
- rasa/engine/caching.py +2 -2
- rasa/engine/constants.py +1 -1
- rasa/engine/graph.py +5 -1
- rasa/engine/loader.py +12 -0
- rasa/engine/recipes/default_components.py +138 -49
- rasa/engine/recipes/default_recipe.py +108 -11
- rasa/engine/runner/dask.py +8 -5
- rasa/engine/storage/local_model_storage.py +41 -4
- rasa/engine/validation.py +19 -6
- rasa/graph_components/validators/default_recipe_validator.py +86 -28
- rasa/hooks.py +5 -5
- rasa/llm_fine_tuning/utils.py +2 -2
- rasa/model_manager/socket_bridge.py +1 -2
- rasa/model_manager/warm_rasa_process.py +13 -3
- rasa/model_training.py +60 -47
- rasa/nlu/classifiers/diet_classifier.py +198 -98
- rasa/nlu/classifiers/logistic_regression_classifier.py +1 -4
- rasa/nlu/classifiers/mitie_intent_classifier.py +3 -0
- rasa/nlu/classifiers/sklearn_intent_classifier.py +1 -3
- rasa/nlu/extractors/crf_entity_extractor.py +9 -10
- rasa/nlu/extractors/mitie_entity_extractor.py +3 -0
- rasa/nlu/extractors/spacy_entity_extractor.py +3 -0
- rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +4 -0
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +5 -0
- rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +2 -0
- rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +3 -0
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +4 -2
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -0
- rasa/nlu/selectors/response_selector.py +10 -2
- rasa/nlu/tokenizers/jieba_tokenizer.py +3 -4
- rasa/nlu/tokenizers/mitie_tokenizer.py +3 -2
- rasa/nlu/tokenizers/spacy_tokenizer.py +3 -2
- rasa/nlu/utils/mitie_utils.py +3 -0
- rasa/nlu/utils/spacy_utils.py +3 -2
- rasa/plugin.py +8 -8
- rasa/privacy/privacy_manager.py +12 -3
- rasa/server.py +15 -3
- rasa/shared/agents/__init__.py +0 -0
- rasa/shared/agents/auth/__init__.py +0 -0
- rasa/shared/agents/auth/agent_auth_factory.py +105 -0
- rasa/shared/agents/auth/agent_auth_manager.py +92 -0
- rasa/shared/agents/auth/auth_strategy/__init__.py +19 -0
- rasa/shared/agents/auth/auth_strategy/agent_auth_strategy.py +52 -0
- rasa/shared/agents/auth/auth_strategy/api_key_auth_strategy.py +42 -0
- rasa/shared/agents/auth/auth_strategy/bearer_token_auth_strategy.py +28 -0
- rasa/shared/agents/auth/auth_strategy/oauth2_auth_strategy.py +167 -0
- rasa/shared/agents/auth/constants.py +12 -0
- rasa/shared/agents/auth/types.py +12 -0
- rasa/shared/agents/utils.py +35 -0
- rasa/shared/constants.py +8 -0
- rasa/shared/core/constants.py +17 -1
- rasa/shared/core/domain.py +0 -7
- rasa/shared/core/events.py +329 -0
- rasa/shared/core/flows/constants.py +5 -0
- rasa/shared/core/flows/flow.py +1 -1
- rasa/shared/core/flows/flows_list.py +21 -5
- rasa/shared/core/flows/flows_yaml_schema.json +119 -184
- rasa/shared/core/flows/steps/call.py +49 -5
- rasa/shared/core/flows/steps/collect.py +98 -13
- rasa/shared/core/flows/validation.py +372 -8
- rasa/shared/core/flows/yaml_flows_io.py +3 -2
- rasa/shared/core/slots.py +2 -2
- rasa/shared/core/trackers.py +5 -2
- rasa/shared/exceptions.py +16 -0
- rasa/shared/importers/rasa.py +1 -1
- rasa/shared/importers/utils.py +9 -3
- rasa/shared/nlu/training_data/schemas/responses.yml +3 -0
- rasa/shared/providers/llm/_base_litellm_client.py +41 -9
- rasa/shared/providers/llm/litellm_router_llm_client.py +8 -4
- rasa/shared/providers/llm/llm_client.py +7 -3
- rasa/shared/providers/llm/llm_response.py +66 -0
- rasa/shared/providers/llm/self_hosted_llm_client.py +8 -4
- rasa/shared/utils/common.py +24 -0
- rasa/shared/utils/health_check/health_check.py +7 -3
- rasa/shared/utils/llm.py +39 -16
- rasa/shared/utils/mcp/__init__.py +0 -0
- rasa/shared/utils/mcp/server_connection.py +247 -0
- rasa/shared/utils/mcp/utils.py +20 -0
- rasa/shared/utils/schemas/events.py +42 -0
- rasa/shared/utils/yaml.py +3 -1
- rasa/studio/pull/pull.py +3 -2
- rasa/studio/train.py +8 -7
- rasa/studio/upload.py +3 -6
- rasa/telemetry.py +69 -5
- rasa/tracing/config.py +45 -12
- rasa/tracing/constants.py +14 -0
- rasa/tracing/instrumentation/attribute_extractors.py +142 -9
- rasa/tracing/instrumentation/instrumentation.py +626 -21
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +4 -4
- rasa/tracing/instrumentation/metrics.py +32 -0
- rasa/tracing/metric_instrument_provider.py +68 -0
- rasa/utils/common.py +92 -1
- rasa/utils/endpoints.py +11 -2
- rasa/utils/log_utils.py +96 -5
- rasa/utils/ml_utils.py +1 -1
- rasa/utils/pypred.py +38 -0
- rasa/utils/tensorflow/__init__.py +7 -0
- rasa/utils/tensorflow/callback.py +136 -101
- rasa/utils/tensorflow/crf.py +1 -1
- rasa/utils/tensorflow/data_generator.py +21 -8
- rasa/utils/tensorflow/layers.py +21 -11
- rasa/utils/tensorflow/metrics.py +7 -3
- rasa/utils/tensorflow/models.py +56 -8
- rasa/utils/tensorflow/rasa_layers.py +8 -6
- rasa/utils/tensorflow/transformer.py +2 -3
- rasa/utils/train_utils.py +54 -24
- rasa/validator.py +17 -13
- rasa/version.py +1 -1
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0rc1.dist-info}/METADATA +59 -51
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0rc1.dist-info}/RECORD +452 -428
- rasa/builder/scrape_rasa_docs.py +0 -97
- rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +0 -47
- rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +0 -40
- rasa/cli/project_templates/finance/actions/action_session_start.py +0 -74
- rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +0 -48
- rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +0 -36
- rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +0 -54
- rasa/cli/project_templates/finance/actions/database.py +0 -277
- rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +0 -52
- rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +0 -51
- rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +0 -40
- rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +0 -40
- rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +0 -46
- rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +0 -49
- rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +0 -19
- rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +0 -36
- rasa/cli/project_templates/finance/csvs/accounts.csv +0 -8
- rasa/cli/project_templates/finance/csvs/advisors.csv +0 -7
- rasa/cli/project_templates/finance/csvs/appointments.csv +0 -211
- rasa/cli/project_templates/finance/csvs/branches.csv +0 -10
- rasa/cli/project_templates/finance/csvs/cards.csv +0 -11
- rasa/cli/project_templates/finance/csvs/payees.csv +0 -11
- rasa/cli/project_templates/finance/csvs/transactions.csv +0 -71
- rasa/cli/project_templates/finance/csvs/users.csv +0 -4
- rasa/cli/project_templates/finance/data/cards/select_card.yml +0 -12
- rasa/cli/project_templates/finance/data/general/bot_identity.yml +0 -6
- rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +0 -5
- rasa/cli/project_templates/finance/data/system/source/accounts.json +0 -51
- rasa/cli/project_templates/finance/data/system/source/advisors.json +0 -44
- rasa/cli/project_templates/finance/data/system/source/appointments.json +0 -1474
- rasa/cli/project_templates/finance/data/system/source/branches.json +0 -47
- rasa/cli/project_templates/finance/data/system/source/cards.json +0 -72
- rasa/cli/project_templates/finance/data/system/source/payees.json +0 -74
- rasa/cli/project_templates/finance/data/system/source/transactions.json +0 -492
- rasa/cli/project_templates/finance/data/system/source/users.json +0 -29
- rasa/cli/project_templates/finance/data/transfers/add_payee.yml +0 -29
- rasa/cli/project_templates/finance/data/transfers/list_payees.yml +0 -5
- rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +0 -21
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +0 -7
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +0 -8
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +0 -48
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +0 -47
- rasa/cli/project_templates/finance/domain/cards/select_card.yml +0 -12
- rasa/cli/project_templates/finance/domain/general/assistant_details.yml +0 -12
- rasa/cli/project_templates/finance/domain/general/bot_identity.yml +0 -5
- rasa/cli/project_templates/finance/domain/general/defaults.yml +0 -24
- rasa/cli/project_templates/finance/domain/general/help.yml +0 -5
- rasa/cli/project_templates/finance/domain/general/utils.yml +0 -13
- rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +0 -47
- rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +0 -4
- rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +0 -16
- rasa/core/channels/inspector/dist/assets/channel-b9b536fc.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-78d2ddcf.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-8b09c060.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-4d4bdf3a.js +0 -1335
- /rasa/cli/project_templates/telco/domain/billing/{domain_undertand_bill.yml → understand_bill.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_reboot_router.yml → reboot_router.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_reset_router.yml → reset_router.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_run_speed_test.yml → run_speed_test.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_solve_internet_issue.yml → solve_internet_issue.yml} +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0rc1.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0rc1.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0rc1.dist-info}/entry_points.txt +0 -0
|
@@ -4,7 +4,6 @@ import asyncio
|
|
|
4
4
|
import audioop
|
|
5
5
|
import base64
|
|
6
6
|
import json
|
|
7
|
-
import time
|
|
8
7
|
import uuid
|
|
9
8
|
from functools import partial
|
|
10
9
|
from typing import (
|
|
@@ -53,9 +52,7 @@ if TYPE_CHECKING:
|
|
|
53
52
|
structlogger = structlog.get_logger()
|
|
54
53
|
|
|
55
54
|
|
|
56
|
-
def tracker_as_dump(
|
|
57
|
-
tracker: "DialogueStateTracker", latency: Optional[float] = None
|
|
58
|
-
) -> Dict[str, Any]:
|
|
55
|
+
def tracker_as_dump(tracker: "DialogueStateTracker") -> Dict[str, Any]:
|
|
59
56
|
"""Create a dump of the tracker state."""
|
|
60
57
|
from rasa.shared.core.trackers import get_trackers_for_conversation_sessions
|
|
61
58
|
|
|
@@ -66,13 +63,7 @@ def tracker_as_dump(
|
|
|
66
63
|
else:
|
|
67
64
|
last_tracker = multiple_tracker_sessions[-1]
|
|
68
65
|
|
|
69
|
-
# TODO: this is a bug: the bridge converts this back to json, but it
|
|
70
|
-
# should be json in the first place
|
|
71
66
|
state = last_tracker.current_state(EventVerbosity.AFTER_RESTART)
|
|
72
|
-
|
|
73
|
-
if latency is not None:
|
|
74
|
-
state["latency"] = {"rasa_processing_latency_ms": latency}
|
|
75
|
-
|
|
76
67
|
return state
|
|
77
68
|
|
|
78
69
|
|
|
@@ -102,12 +93,12 @@ class StudioTrackerUpdatePlugin:
|
|
|
102
93
|
"""Remove tasks that have already completed."""
|
|
103
94
|
self.tasks = [task for task in self.tasks if not task.done()]
|
|
104
95
|
|
|
105
|
-
@hookimpl
|
|
96
|
+
@hookimpl
|
|
106
97
|
def after_new_user_message(self, tracker: "DialogueStateTracker") -> None:
|
|
107
98
|
"""Triggers a tracker update notification after a new user message."""
|
|
108
99
|
self.handle_tracker_update(tracker)
|
|
109
100
|
|
|
110
|
-
@hookimpl
|
|
101
|
+
@hookimpl
|
|
111
102
|
def after_action_executed(self, tracker: "DialogueStateTracker") -> None:
|
|
112
103
|
"""Triggers a tracker update notification after an action is executed."""
|
|
113
104
|
self.handle_tracker_update(tracker)
|
|
@@ -127,7 +118,7 @@ class StudioTrackerUpdatePlugin:
|
|
|
127
118
|
self.tasks.append(task)
|
|
128
119
|
self._cleanup_tasks()
|
|
129
120
|
|
|
130
|
-
@hookimpl
|
|
121
|
+
@hookimpl
|
|
131
122
|
def after_server_stop(self) -> None:
|
|
132
123
|
"""Cancels all remaining tasks when the server stops."""
|
|
133
124
|
self._cancel_tasks()
|
|
@@ -227,32 +218,16 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
227
218
|
def _register_tracker_update_hook(self) -> None:
|
|
228
219
|
plugin_manager().register(StudioTrackerUpdatePlugin(self))
|
|
229
220
|
|
|
230
|
-
async def on_tracker_updated(
|
|
231
|
-
self, tracker: "DialogueStateTracker", latency: Optional[float] = None
|
|
232
|
-
) -> None:
|
|
221
|
+
async def on_tracker_updated(self, tracker: "DialogueStateTracker") -> None:
|
|
233
222
|
"""Triggers a tracker update notification after a change to the tracker."""
|
|
234
|
-
await self.publish_tracker_update(
|
|
235
|
-
tracker.sender_id, tracker_as_dump(tracker, latency)
|
|
236
|
-
)
|
|
223
|
+
await self.publish_tracker_update(tracker.sender_id, tracker_as_dump(tracker))
|
|
237
224
|
|
|
238
|
-
async def publish_tracker_update(
|
|
225
|
+
async def publish_tracker_update(
|
|
226
|
+
self, sender_id: str, tracker_dump: Dict[str, Any]
|
|
227
|
+
) -> None:
|
|
239
228
|
"""Publishes a tracker update notification to the websocket."""
|
|
240
229
|
await self.emit("tracker", tracker_dump, room=sender_id)
|
|
241
230
|
|
|
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
|
|
255
|
-
|
|
256
231
|
async def on_message_proxy(
|
|
257
232
|
self,
|
|
258
233
|
on_new_message: Callable[[UserMessage], Awaitable[Any]],
|
|
@@ -262,7 +237,6 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
262
237
|
|
|
263
238
|
Triggers a tracker update notification after processing the message.
|
|
264
239
|
"""
|
|
265
|
-
self._record_turn_start_time(message.sender_id)
|
|
266
240
|
try:
|
|
267
241
|
await on_new_message(message)
|
|
268
242
|
except Exception as e:
|
|
@@ -288,8 +262,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
288
262
|
structlogger.error("studio_chat.on_message_proxy.tracker_not_found")
|
|
289
263
|
return
|
|
290
264
|
|
|
291
|
-
|
|
292
|
-
await self.on_tracker_updated(tracker, latency)
|
|
265
|
+
await self.on_tracker_updated(tracker)
|
|
293
266
|
|
|
294
267
|
async def emit_error(self, message: str, room: str, e: Exception) -> None:
|
|
295
268
|
await self.emit(
|
|
@@ -389,16 +362,23 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
389
362
|
call_state.is_bot_speaking = True
|
|
390
363
|
return ContinueConversationAction()
|
|
391
364
|
|
|
392
|
-
def
|
|
365
|
+
def create_output_channel(
|
|
393
366
|
self, voice_websocket: "Websocket", tts_engine: TTSEngine
|
|
394
367
|
) -> VoiceOutputChannel:
|
|
395
|
-
"""Create a voice output channel."""
|
|
368
|
+
"""Create a voice output channel. This is used by VoiceInputChannel."""
|
|
396
369
|
return StudioVoiceOutputChannel(
|
|
397
370
|
voice_websocket,
|
|
398
371
|
tts_engine,
|
|
399
372
|
self.tts_cache,
|
|
400
373
|
)
|
|
401
374
|
|
|
375
|
+
async def interrupt_playback(
|
|
376
|
+
self, ws: Websocket, call_parameters: CallParameters
|
|
377
|
+
) -> None:
|
|
378
|
+
"""Interrupt the current playback of audio."""
|
|
379
|
+
structlogger.debug("studio_chat.interrupt_playback")
|
|
380
|
+
await ws.send(json.dumps({"interruptPlayback": True}))
|
|
381
|
+
|
|
402
382
|
def _start_voice_session(
|
|
403
383
|
self,
|
|
404
384
|
session_id: str,
|
|
@@ -458,7 +438,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
458
438
|
if sid in self.active_connections:
|
|
459
439
|
del self.active_connections[sid]
|
|
460
440
|
|
|
461
|
-
@hookimpl
|
|
441
|
+
@hookimpl
|
|
462
442
|
def after_server_stop(self) -> None:
|
|
463
443
|
"""Cleanup background tasks and active connections when the server stops."""
|
|
464
444
|
structlogger.info("studio_chat.after_server_stop.cleanup")
|
|
@@ -469,8 +449,9 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
469
449
|
def blueprint(
|
|
470
450
|
self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
|
|
471
451
|
) -> SocketBlueprint:
|
|
472
|
-
|
|
473
|
-
|
|
452
|
+
socket_blueprint = super().blueprint(
|
|
453
|
+
partial(self.on_message_proxy, on_new_message)
|
|
454
|
+
)
|
|
474
455
|
|
|
475
456
|
if not self.sio_server:
|
|
476
457
|
structlogger.error("studio_chat.blueprint.sio_not_initialized")
|
|
@@ -480,7 +461,8 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
480
461
|
async def after_server_start(
|
|
481
462
|
app: "Sanic", _: asyncio.AbstractEventLoop
|
|
482
463
|
) -> None:
|
|
483
|
-
|
|
464
|
+
if hasattr(app.ctx, "agent"):
|
|
465
|
+
self.agent = app.ctx.agent
|
|
484
466
|
|
|
485
467
|
@self.sio_server.on("disconnect", namespace=self.namespace)
|
|
486
468
|
async def disconnect(sid: Text) -> None:
|
|
@@ -505,7 +487,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
505
487
|
|
|
506
488
|
# start a voice session if requested
|
|
507
489
|
if data and data.get("is_voice", False):
|
|
508
|
-
self._start_voice_session(data["session_id"], sid,
|
|
490
|
+
self._start_voice_session(data["session_id"], sid, on_new_message)
|
|
509
491
|
|
|
510
492
|
@self.sio_server.on(self.user_message_evt, namespace=self.namespace)
|
|
511
493
|
async def handle_message(sid: Text, data: Dict) -> None:
|
|
@@ -520,7 +502,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
520
502
|
|
|
521
503
|
try:
|
|
522
504
|
# Handle text messages
|
|
523
|
-
await self.handle_user_message(sid, data,
|
|
505
|
+
await self.handle_user_message(sid, data, on_new_message)
|
|
524
506
|
except Exception as e:
|
|
525
507
|
structlogger.exception(
|
|
526
508
|
"studio_chat.sio.handle_message.error",
|
|
@@ -551,7 +533,7 @@ class StudioVoiceOutputChannel(VoiceOutputChannel):
|
|
|
551
533
|
|
|
552
534
|
def create_marker_message(self, recipient_id: str) -> Tuple[str, str]:
|
|
553
535
|
message_id = uuid.uuid4().hex
|
|
554
|
-
marker_data = {"marker": message_id}
|
|
536
|
+
marker_data: Dict[str, Any] = {"marker": message_id}
|
|
555
537
|
|
|
556
538
|
# Include comprehensive latency information if available
|
|
557
539
|
latency_data = {
|
|
@@ -566,7 +548,7 @@ class StudioVoiceOutputChannel(VoiceOutputChannel):
|
|
|
566
548
|
|
|
567
549
|
# Add latency data to marker if any metrics are available
|
|
568
550
|
if latency_data:
|
|
569
|
-
marker_data["latency"] = latency_data
|
|
551
|
+
marker_data["latency"] = latency_data
|
|
570
552
|
|
|
571
553
|
return json.dumps(marker_data), message_id
|
|
572
554
|
|
rasa/core/channels/telegram.py
CHANGED
|
@@ -4,6 +4,9 @@ import typing
|
|
|
4
4
|
from copy import deepcopy
|
|
5
5
|
from typing import Any, Awaitable, Callable, Dict, List, Optional, Text
|
|
6
6
|
|
|
7
|
+
# Import aiogram at module level to raise error if not installed
|
|
8
|
+
from aiogram import Bot
|
|
9
|
+
from aiogram.types import Message, Update
|
|
7
10
|
from sanic import Blueprint, response
|
|
8
11
|
from sanic.request import Request
|
|
9
12
|
from sanic.response import HTTPResponse
|
|
@@ -28,15 +31,7 @@ class TelegramOutput(OutputChannel):
|
|
|
28
31
|
return "telegram"
|
|
29
32
|
|
|
30
33
|
def __init__(self, access_token: Optional[Text]) -> None:
|
|
31
|
-
|
|
32
|
-
from aiogram import Bot
|
|
33
|
-
|
|
34
|
-
self.bot = Bot(access_token)
|
|
35
|
-
except ImportError:
|
|
36
|
-
raise ImportError(
|
|
37
|
-
"To use the Telegram channel, please install the aiogram package "
|
|
38
|
-
"with 'pip install aiogram'"
|
|
39
|
-
)
|
|
34
|
+
self.bot = Bot(access_token)
|
|
40
35
|
|
|
41
36
|
async def send_text_message(
|
|
42
37
|
self, recipient_id: Text, text: Text, **kwargs: Any
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import os
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, AsyncIterator, Dict, Optional
|
|
4
|
+
from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, Optional
|
|
5
5
|
|
|
6
6
|
import structlog
|
|
7
7
|
|
|
@@ -15,6 +15,9 @@ from rasa.core.channels.voice_stream.audio_bytes import HERTZ, RasaAudioBytes
|
|
|
15
15
|
from rasa.shared.constants import AZURE_SPEECH_API_KEY_ENV_VAR
|
|
16
16
|
from rasa.shared.exceptions import ConnectionException
|
|
17
17
|
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from azure.cognitiveservices.speech import SpeechRecognitionEventArgs
|
|
20
|
+
|
|
18
21
|
logger = structlog.get_logger(__name__)
|
|
19
22
|
|
|
20
23
|
|
|
@@ -43,9 +46,9 @@ class AzureASR(ASREngine[AzureASRConfig]):
|
|
|
43
46
|
)
|
|
44
47
|
self.main_loop = asyncio.get_running_loop()
|
|
45
48
|
|
|
46
|
-
def signal_user_is_speaking(self, event:
|
|
49
|
+
def signal_user_is_speaking(self, event: "SpeechRecognitionEventArgs") -> None:
|
|
47
50
|
"""Replace the azure event with a generic is speaking event."""
|
|
48
|
-
self.fill_queue(UserIsSpeaking())
|
|
51
|
+
self.fill_queue(UserIsSpeaking(event.result.text))
|
|
49
52
|
|
|
50
53
|
def fill_queue(self, event: Any) -> None:
|
|
51
54
|
"""Either puts the event or a dedicated ASR Event into the queue."""
|
|
@@ -117,7 +117,7 @@ class DeepgramASR(ASREngine[DeepgramASRConfig]):
|
|
|
117
117
|
self.accumulated_transcript, transcript
|
|
118
118
|
)
|
|
119
119
|
elif transcript:
|
|
120
|
-
return UserIsSpeaking()
|
|
120
|
+
return UserIsSpeaking(transcript)
|
|
121
121
|
# event that comes after utterance_end_ms of no new transcript
|
|
122
122
|
elif data_type == "UtteranceEnd":
|
|
123
123
|
if self.accumulated_transcript:
|
|
@@ -89,6 +89,7 @@ class AudiocodesVoiceOutputChannel(VoiceOutputChannel):
|
|
|
89
89
|
# This is an approximation, as the bot will be sent the audio chunks next
|
|
90
90
|
# which are played to the user immediately.
|
|
91
91
|
call_state.is_bot_speaking = True
|
|
92
|
+
VoiceInputChannel._cancel_silence_timeout_watcher()
|
|
92
93
|
|
|
93
94
|
async def send_intermediate_marker(self, recipient_id: str) -> None:
|
|
94
95
|
"""Audiocodes doesn't need intermediate markers, so do nothing."""
|
|
@@ -116,6 +117,7 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
|
|
|
116
117
|
server_url: str,
|
|
117
118
|
asr_config: Dict,
|
|
118
119
|
tts_config: Dict,
|
|
120
|
+
interruptions: Optional[Dict[str, int]] = None,
|
|
119
121
|
token: Optional[Text] = None,
|
|
120
122
|
):
|
|
121
123
|
mark_as_beta_feature("Audiocodes (audiocodes_stream) Channel")
|
|
@@ -123,6 +125,7 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
|
|
|
123
125
|
server_url=server_url,
|
|
124
126
|
asr_config=asr_config,
|
|
125
127
|
tts_config=tts_config,
|
|
128
|
+
interruptions=interruptions,
|
|
126
129
|
)
|
|
127
130
|
self.token = token
|
|
128
131
|
|
|
@@ -3,7 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
import audioop
|
|
4
4
|
import base64
|
|
5
5
|
import json
|
|
6
|
+
import os
|
|
6
7
|
import uuid
|
|
8
|
+
import wave
|
|
7
9
|
from typing import Any, Awaitable, Callable, Dict, Optional, Tuple
|
|
8
10
|
|
|
9
11
|
import structlog
|
|
@@ -69,11 +71,48 @@ class BrowserAudioOutputChannel(VoiceOutputChannel):
|
|
|
69
71
|
|
|
70
72
|
|
|
71
73
|
class BrowserAudioInputChannel(VoiceInputChannel):
|
|
74
|
+
requires_voice_license = False
|
|
75
|
+
|
|
72
76
|
def __init__(
|
|
73
|
-
self,
|
|
77
|
+
self,
|
|
78
|
+
server_url: str,
|
|
79
|
+
asr_config: Dict[str, Any],
|
|
80
|
+
tts_config: Dict[str, Any],
|
|
81
|
+
recording: bool = False,
|
|
82
|
+
interruptions: Optional[Dict[str, int]] = None,
|
|
74
83
|
) -> None:
|
|
75
84
|
"""Initializes the browser audio input channel."""
|
|
76
|
-
super().__init__(server_url, asr_config, tts_config)
|
|
85
|
+
super().__init__(server_url, asr_config, tts_config, interruptions)
|
|
86
|
+
|
|
87
|
+
# For debugging, recording of user audio might be useful
|
|
88
|
+
# to identify audio quality issues or transcription errors
|
|
89
|
+
self._recording_enabled = recording
|
|
90
|
+
self._wav_file: Optional[wave.Wave_write] = None
|
|
91
|
+
|
|
92
|
+
def _start_recording(self, call_id: str, user_id: str) -> None:
|
|
93
|
+
os.makedirs("recordings", exist_ok=True)
|
|
94
|
+
filename = f"{user_id}_{call_id}.wav"
|
|
95
|
+
file_path = os.path.join("recordings", filename)
|
|
96
|
+
|
|
97
|
+
if not self._recording_enabled:
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
self._wav_file = wave.open(file_path, "wb")
|
|
101
|
+
self._wav_file.setnchannels(1) # Mono audio
|
|
102
|
+
self._wav_file.setsampwidth(4) # 32-bit audio (4 bytes)
|
|
103
|
+
self._wav_file.setframerate(8000) # 8kHz sample rate
|
|
104
|
+
logger.info("voice_channel.user_audio_recording.started", file_path=file_path)
|
|
105
|
+
|
|
106
|
+
def _append_audio_to_recording(self, audio_bytes: bytes) -> None:
|
|
107
|
+
if self._wav_file and self._recording_enabled:
|
|
108
|
+
self._wav_file.writeframes(audio_bytes)
|
|
109
|
+
|
|
110
|
+
def _stop_recording(self) -> None:
|
|
111
|
+
"""Close the recording file if it's open."""
|
|
112
|
+
if self._wav_file:
|
|
113
|
+
self._wav_file.close()
|
|
114
|
+
self._wav_file = None
|
|
115
|
+
logger.debug("voice_channel.user_audio_recording.stopped")
|
|
77
116
|
|
|
78
117
|
@classmethod
|
|
79
118
|
def name(cls) -> str:
|
|
@@ -94,7 +133,7 @@ class BrowserAudioInputChannel(VoiceInputChannel):
|
|
|
94
133
|
credentials: Optional[Dict[str, Any]],
|
|
95
134
|
) -> BrowserAudioInputChannel:
|
|
96
135
|
cls.validate_basic_credentials(credentials)
|
|
97
|
-
new_creds = repack_voice_credentials(credentials)
|
|
136
|
+
new_creds = repack_voice_credentials(credentials or {})
|
|
98
137
|
return cls(**new_creds)
|
|
99
138
|
|
|
100
139
|
def map_input_message(
|
|
@@ -105,6 +144,7 @@ class BrowserAudioInputChannel(VoiceInputChannel):
|
|
|
105
144
|
data = json.loads(message)
|
|
106
145
|
if "audio" in data:
|
|
107
146
|
channel_bytes = base64.b64decode(data["audio"])
|
|
147
|
+
self._append_audio_to_recording(channel_bytes)
|
|
108
148
|
audio_bytes = self.channel_bytes_to_rasa_audio_bytes(channel_bytes)
|
|
109
149
|
return NewAudioAction(audio_bytes)
|
|
110
150
|
elif "marker" in data:
|
|
@@ -120,6 +160,13 @@ class BrowserAudioInputChannel(VoiceInputChannel):
|
|
|
120
160
|
call_state.is_bot_speaking = True
|
|
121
161
|
return ContinueConversationAction()
|
|
122
162
|
|
|
163
|
+
async def interrupt_playback(
|
|
164
|
+
self, ws: Websocket, call_parameters: CallParameters
|
|
165
|
+
) -> None:
|
|
166
|
+
"""Interrupt the current playback of audio."""
|
|
167
|
+
logger.debug("browser_audio.interrupt_playback")
|
|
168
|
+
await ws.send(json.dumps({"interruptPlayback": True}))
|
|
169
|
+
|
|
123
170
|
def create_output_channel(
|
|
124
171
|
self, voice_websocket: Websocket, tts_engine: TTSEngine
|
|
125
172
|
) -> VoiceOutputChannel:
|
|
@@ -142,8 +189,13 @@ class BrowserAudioInputChannel(VoiceInputChannel):
|
|
|
142
189
|
@blueprint.websocket("/websocket") # type: ignore
|
|
143
190
|
async def handle_message(request: Request, ws: Websocket) -> None:
|
|
144
191
|
try:
|
|
192
|
+
call_parameters = await self.collect_call_parameters(ws)
|
|
193
|
+
if call_parameters and call_parameters.call_id:
|
|
194
|
+
self._start_recording(call_parameters.call_id, "local")
|
|
145
195
|
await self.run_audio_streaming(on_new_message, ws)
|
|
146
196
|
except Exception as e:
|
|
147
197
|
logger.error("browser_audio.handle_message.error", error=e)
|
|
198
|
+
finally:
|
|
199
|
+
self._stop_recording()
|
|
148
200
|
|
|
149
201
|
return blueprint
|
|
@@ -99,10 +99,11 @@ class GenesysInputChannel(VoiceInputChannel):
|
|
|
99
99
|
server_url: str,
|
|
100
100
|
asr_config: Dict,
|
|
101
101
|
tts_config: Dict,
|
|
102
|
+
interruptions: Optional[Dict[str, int]] = None,
|
|
102
103
|
api_key: Optional[Text] = None,
|
|
103
104
|
client_secret: Optional[Text] = None,
|
|
104
105
|
) -> None:
|
|
105
|
-
super().__init__(server_url, asr_config, tts_config)
|
|
106
|
+
super().__init__(server_url, asr_config, tts_config, interruptions)
|
|
106
107
|
self.api_key = api_key
|
|
107
108
|
self.client_secret = client_secret
|
|
108
109
|
|
|
@@ -274,7 +275,7 @@ class GenesysInputChannel(VoiceInputChannel):
|
|
|
274
275
|
|
|
275
276
|
def handle_ping(self, ws: Websocket, message: dict) -> None:
|
|
276
277
|
"""Handle ping message from Genesys."""
|
|
277
|
-
response = {
|
|
278
|
+
response: Dict[str, Any] = {
|
|
278
279
|
"version": "2",
|
|
279
280
|
"type": "pong",
|
|
280
281
|
"seq": self._get_next_sequence(),
|
|
@@ -81,6 +81,7 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
81
81
|
server_url: str,
|
|
82
82
|
asr_config: Dict,
|
|
83
83
|
tts_config: Dict,
|
|
84
|
+
interruptions: Optional[Dict[str, int]] = None,
|
|
84
85
|
username: Optional[Text] = None,
|
|
85
86
|
password: Optional[Text] = None,
|
|
86
87
|
) -> None:
|
|
@@ -90,7 +91,7 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
90
91
|
username: Optional username for basic auth
|
|
91
92
|
password: Optional password for basic auth
|
|
92
93
|
"""
|
|
93
|
-
super().__init__(server_url, asr_config, tts_config)
|
|
94
|
+
super().__init__(server_url, asr_config, tts_config, interruptions)
|
|
94
95
|
self.username = username
|
|
95
96
|
self.password = password
|
|
96
97
|
|
|
@@ -185,6 +186,13 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
185
186
|
self.tts_cache,
|
|
186
187
|
)
|
|
187
188
|
|
|
189
|
+
async def interrupt_playback(
|
|
190
|
+
self, ws: Websocket, call_parameters: CallParameters
|
|
191
|
+
) -> None:
|
|
192
|
+
"""Interrupt the current playback of audio."""
|
|
193
|
+
logger.debug("jambonz.interrupt_playback")
|
|
194
|
+
await ws.send(json.dumps({"type": "killAudio"}))
|
|
195
|
+
|
|
188
196
|
def blueprint(
|
|
189
197
|
self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
|
|
190
198
|
) -> Blueprint:
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import AsyncIterator, Dict, Optional
|
|
4
|
+
from urllib.parse import urlencode
|
|
5
|
+
|
|
6
|
+
import aiohttp
|
|
7
|
+
import orjson
|
|
8
|
+
import structlog
|
|
9
|
+
from aiohttp import ClientConnectorError, ClientTimeout, WSMsgType
|
|
10
|
+
|
|
11
|
+
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
12
|
+
from rasa.core.channels.voice_stream.tts.tts_engine import (
|
|
13
|
+
TTSEngine,
|
|
14
|
+
TTSEngineConfig,
|
|
15
|
+
TTSError,
|
|
16
|
+
)
|
|
17
|
+
from rasa.shared.constants import DEEPGRAM_API_KEY_ENV_VAR
|
|
18
|
+
from rasa.shared.exceptions import ConnectionException
|
|
19
|
+
|
|
20
|
+
structlogger = structlog.get_logger()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class DeepgramTTSConfig(TTSEngineConfig):
|
|
25
|
+
model_id: Optional[str] = None
|
|
26
|
+
endpoint: Optional[str] = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DeepgramTTS(TTSEngine[DeepgramTTSConfig]):
|
|
30
|
+
session: Optional[aiohttp.ClientSession] = None
|
|
31
|
+
required_env_vars = (DEEPGRAM_API_KEY_ENV_VAR,)
|
|
32
|
+
ws: Optional[aiohttp.ClientWebSocketResponse] = None
|
|
33
|
+
|
|
34
|
+
def __init__(self, config: Optional[DeepgramTTSConfig] = None):
|
|
35
|
+
super().__init__(config)
|
|
36
|
+
timeout = ClientTimeout(total=self.config.timeout)
|
|
37
|
+
# Have to create this class-shared session lazily at run time otherwise
|
|
38
|
+
# the async event loop doesn't work
|
|
39
|
+
if self.__class__.session is None or self.__class__.session.closed:
|
|
40
|
+
self.__class__.session = aiohttp.ClientSession(timeout=timeout)
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def get_request_headers(config: DeepgramTTSConfig) -> dict[str, str]:
|
|
44
|
+
deepgram_api_key = os.environ[DEEPGRAM_API_KEY_ENV_VAR]
|
|
45
|
+
return {
|
|
46
|
+
"Authorization": f"Token {deepgram_api_key!s}",
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async def close_connection(self) -> None:
|
|
50
|
+
"""Close WebSocket connection if it exists."""
|
|
51
|
+
if self.ws and not self.ws.closed:
|
|
52
|
+
await self.ws.close()
|
|
53
|
+
self.ws = None
|
|
54
|
+
|
|
55
|
+
def get_websocket_url(self, config: DeepgramTTSConfig) -> str:
|
|
56
|
+
"""Build WebSocket URL with query parameters."""
|
|
57
|
+
base_url = config.endpoint
|
|
58
|
+
query_params = {
|
|
59
|
+
"model": config.model_id,
|
|
60
|
+
"encoding": "mulaw",
|
|
61
|
+
"sample_rate": "8000",
|
|
62
|
+
}
|
|
63
|
+
return f"{base_url}?{urlencode(query_params)}"
|
|
64
|
+
|
|
65
|
+
async def synthesize(
|
|
66
|
+
self, text: str, config: Optional[DeepgramTTSConfig] = None
|
|
67
|
+
) -> AsyncIterator[RasaAudioBytes]:
|
|
68
|
+
"""Generate speech from text using Deepgram WebSocket TTS API."""
|
|
69
|
+
config = self.config.merge(config)
|
|
70
|
+
headers = self.get_request_headers(config)
|
|
71
|
+
ws_url = self.get_websocket_url(config)
|
|
72
|
+
|
|
73
|
+
if self.session is None:
|
|
74
|
+
raise ConnectionException("Client session is not initialized")
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
self.ws = await self.session.ws_connect(
|
|
78
|
+
ws_url,
|
|
79
|
+
headers=headers,
|
|
80
|
+
timeout=float(self.config.timeout),
|
|
81
|
+
)
|
|
82
|
+
await self.ws.send_json(
|
|
83
|
+
{
|
|
84
|
+
"type": "Speak",
|
|
85
|
+
"text": text,
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
await self.ws.send_json({"type": "Flush"})
|
|
89
|
+
async for msg in self.ws:
|
|
90
|
+
if msg.type == WSMsgType.BINARY:
|
|
91
|
+
# Binary data is the raw audio
|
|
92
|
+
yield self.engine_bytes_to_rasa_audio_bytes(msg.data)
|
|
93
|
+
elif msg.type == WSMsgType.TEXT:
|
|
94
|
+
# Handle control messages if needed
|
|
95
|
+
data = orjson.loads(msg.data)
|
|
96
|
+
if data.get("type") == "Close":
|
|
97
|
+
break
|
|
98
|
+
elif data.get("type") == "Flushed":
|
|
99
|
+
break # End of stream
|
|
100
|
+
elif msg.type == WSMsgType.CLOSED:
|
|
101
|
+
break
|
|
102
|
+
elif msg.type == WSMsgType.ERROR:
|
|
103
|
+
structlogger.error(
|
|
104
|
+
"deepgram.synthesize.ws.error", error=str(msg.data)
|
|
105
|
+
)
|
|
106
|
+
raise TTSError(f"WebSocket error: {msg.data}")
|
|
107
|
+
|
|
108
|
+
# Send a close message
|
|
109
|
+
if self.ws and not self.ws.closed:
|
|
110
|
+
await self.ws.send_json({"type": "Close"})
|
|
111
|
+
|
|
112
|
+
except ClientConnectorError as e:
|
|
113
|
+
structlogger.error("deepgram.synthesize.ws.connection_error", error=str(e))
|
|
114
|
+
raise TTSError(f"Failed to connect to Deepgram TTS service: {e}")
|
|
115
|
+
except TimeoutError as e:
|
|
116
|
+
structlogger.error("deepgram.synthesize.ws.timeout", error=str(e))
|
|
117
|
+
raise TTSError(f"Connection to Deepgram TTS service timed out: {e}")
|
|
118
|
+
except Exception as e:
|
|
119
|
+
structlogger.error("deepgram.synthesize.ws.error", error=str(e))
|
|
120
|
+
raise TTSError(f"Error during TTS synthesis: {e}")
|
|
121
|
+
finally:
|
|
122
|
+
# Ensure connection is closed
|
|
123
|
+
await self.close_connection()
|
|
124
|
+
|
|
125
|
+
def engine_bytes_to_rasa_audio_bytes(self, chunk: bytes) -> RasaAudioBytes:
|
|
126
|
+
"""Convert the generated tts audio bytes into rasa audio bytes."""
|
|
127
|
+
# WebSocket returns raw audio bytes directly
|
|
128
|
+
return RasaAudioBytes(chunk)
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
def get_default_config() -> DeepgramTTSConfig:
|
|
132
|
+
return DeepgramTTSConfig(
|
|
133
|
+
model_id="aura-2-andromeda-en",
|
|
134
|
+
endpoint="wss://api.deepgram.com/v1/speak",
|
|
135
|
+
timeout=30,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
@classmethod
|
|
139
|
+
def from_config_dict(cls, config: Dict) -> "DeepgramTTS":
|
|
140
|
+
return cls(DeepgramTTSConfig.from_dict(config))
|
|
@@ -14,6 +14,9 @@ from sanic import ( # type: ignore[attr-defined]
|
|
|
14
14
|
response,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
+
# Import twilio at module level to raise error if not installed
|
|
18
|
+
from twilio.twiml.voice_response import VoiceResponse
|
|
19
|
+
|
|
17
20
|
from rasa.core.channels import UserMessage
|
|
18
21
|
from rasa.core.channels.channel import (
|
|
19
22
|
create_auth_requested_response_provider,
|
|
@@ -105,6 +108,7 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
|
|
|
105
108
|
server_url: str,
|
|
106
109
|
asr_config: Dict,
|
|
107
110
|
tts_config: Dict,
|
|
111
|
+
interruptions: Optional[Dict[str, int]] = None,
|
|
108
112
|
username: Optional[Text] = None,
|
|
109
113
|
password: Optional[Text] = None,
|
|
110
114
|
):
|
|
@@ -112,6 +116,7 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
|
|
|
112
116
|
server_url=server_url,
|
|
113
117
|
asr_config=asr_config,
|
|
114
118
|
tts_config=tts_config,
|
|
119
|
+
interruptions=interruptions,
|
|
115
120
|
)
|
|
116
121
|
self.username = username
|
|
117
122
|
self.password = password
|
|
@@ -143,7 +148,8 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
|
|
|
143
148
|
"""Get the sender ID for the channel.
|
|
144
149
|
|
|
145
150
|
Twilio Media Streams uses the Stream ID as Sender ID because
|
|
146
|
-
it is required in OutputChannel.send_text_message to send messages.
|
|
151
|
+
it is required in OutputChannel.send_text_message to send messages.
|
|
152
|
+
"""
|
|
147
153
|
return call_parameters.stream_id # type: ignore[return-value]
|
|
148
154
|
|
|
149
155
|
def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
|
|
@@ -195,6 +201,20 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
|
|
|
195
201
|
self.tts_cache,
|
|
196
202
|
)
|
|
197
203
|
|
|
204
|
+
async def interrupt_playback(
|
|
205
|
+
self, ws: Websocket, call_parameters: CallParameters
|
|
206
|
+
) -> None:
|
|
207
|
+
"""Interrupt the current playback of audio."""
|
|
208
|
+
logger.debug("twilio_media_streams.interrupt_playback")
|
|
209
|
+
await ws.send(
|
|
210
|
+
json.dumps(
|
|
211
|
+
{
|
|
212
|
+
"event": "clear",
|
|
213
|
+
"streamSid": call_parameters.stream_id,
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
)
|
|
217
|
+
|
|
198
218
|
def blueprint(
|
|
199
219
|
self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
|
|
200
220
|
) -> Blueprint:
|