rasa-pro 3.14.0.dev20250901__py3-none-any.whl → 3.14.0.dev20250922__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/config.py +1 -0
- 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/jobs.py +33 -21
- rasa/builder/main.py +38 -62
- rasa/builder/models.py +7 -7
- rasa/builder/project_generator.py +143 -147
- rasa/builder/service.py +42 -27
- rasa/builder/template_cache.py +69 -0
- rasa/builder/training_service.py +74 -4
- 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/core/actions/action_run_slot_rejections.py +1 -1
- rasa/core/actions/direct_custom_actions_executor.py +9 -2
- rasa/core/brokers/broker.py +1 -1
- rasa/core/brokers/kafka.py +52 -8
- rasa/core/channels/development_inspector.py +1 -21
- rasa/core/channels/hangouts.py +2 -2
- rasa/core/channels/inspector/dist/assets/{arc-18042c22.js → arc-35222594.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-fdd6bcfa.js → blockDiagram-38ab4fdb-a0efbfd3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-f5ae6786.js → c4Diagram-3d4e48cf-0584c0f2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-8e08bed9.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-81efba3e.js → classDiagram-70f12bd4-39f40dbe.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-3b6b6a92.js → classDiagram-v2-f2320105-1ad755f3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-78c82dea.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-31422447.js → createText-2e5e7dd3-b0f4f0fe.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-518a90db.js → edges-e0da2a9e-9039bff9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-a6d3c25a.js → erDiagram-9861fffd-65c9b127.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e048c2be.js → flowDb-956e92f1-4f08b38e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c7474c91.js → flowDiagram-66a62f08-e95c362a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b08f601.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb4d8723.js → flowchart-elk-definition-4a651766-703c3015.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-346636a2.js → ganttDiagram-c361ad54-699328ea.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-7c508874.js → gitGraphDiagram-72cf32ee-04cf4b05.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-14702d8a.js → graph-ee94449e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-f18b534b.js → index-3862675e-940162b4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-4d4bdf3a.js → index-c941dcb3.js} +132 -131
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-64154b83.js → infoDiagram-f8f76790-c79c2866.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-833a5f95.js → journeyDiagram-49397b02-84489d30.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-5a3b2123.js → layout-a9aa9858.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-2272a8c7.js → line-eb73cf26.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-35bcf273.js → linear-b3399f9a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-92dcb0e9.js → mindmap-definition-fc14e90a-b095bf1a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-94dbc900.js → pieDiagram-8a3498a8-07644b66.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-8b7a9c33.js → quadrantDiagram-120e2f19-573a3f9c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6f7eab81.js → requirementDiagram-deff3bca-d457e1e1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-f43e581d.js → sankeyDiagram-04a897e0-9d26e1a2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-0bcbefc3.js → sequenceDiagram-704730f1-3a9cde10.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-b8a74083.js → stateDiagram-587899a1-4f3e8cec.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-2070218f.js → stateDiagram-v2-d93cdb3a-e617e5bf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-f1d54e34.js → styles-6aaf32cf-eab30d2f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-980de489.js → styles-9a916d00-09994be2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-3c03abde.js → styles-c10674c1-b7110364.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-46ba068f.js → svgDrawCommon-08f97a94-3ebc92ad.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-901f5e3d.js → timeline-definition-85554ec2-7d13d2f2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-acbc628a.js → xychartDiagram-e933f94c-488385e1.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/App.tsx +5 -31
- rasa/core/channels/inspector/src/components/Chat.tsx +2 -3
- 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 +14 -0
- rasa/core/channels/inspector/src/types.ts +32 -7
- rasa/core/channels/studio_chat.py +23 -41
- 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 +2 -1
- rasa/core/channels/voice_stream/jambonz.py +9 -1
- rasa/core/channels/voice_stream/twilio_media_streams.py +16 -0
- rasa/core/channels/voice_stream/voice_channel.py +61 -0
- rasa/core/concurrent_lock_store.py +66 -16
- rasa/core/constants.py +7 -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/flows/flow_executor.py +1 -1
- rasa/core/processor.py +32 -0
- rasa/core/redis_connection_factory.py +469 -0
- rasa/core/tracker_stores/redis_tracker_store.py +32 -14
- rasa/core/tracker_stores/sql_tracker_store.py +57 -1
- rasa/engine/graph.py +5 -1
- rasa/engine/loader.py +12 -0
- rasa/engine/storage/local_model_storage.py +41 -4
- rasa/model_manager/socket_bridge.py +1 -2
- rasa/model_manager/warm_rasa_process.py +13 -3
- rasa/shared/core/constants.py +1 -0
- rasa/shared/core/events.py +2 -0
- rasa/shared/core/flows/flow.py +1 -1
- rasa/shared/nlu/training_data/schemas/responses.yml +3 -0
- rasa/utils/pypred.py +38 -0
- rasa/validator.py +12 -8
- rasa/version.py +1 -1
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/METADATA +19 -16
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/RECORD +231 -266
- 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/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.0.dev20250922.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/entry_points.txt +0 -0
rasa/core/lock_store.py
CHANGED
|
@@ -4,7 +4,7 @@ import asyncio
|
|
|
4
4
|
import json
|
|
5
5
|
import os
|
|
6
6
|
from contextlib import asynccontextmanager
|
|
7
|
-
from typing import Any, AsyncGenerator, Dict, Literal, Optional, Text, Union
|
|
7
|
+
from typing import Any, AsyncGenerator, Dict, List, Literal, Optional, Text, Union
|
|
8
8
|
|
|
9
9
|
import structlog
|
|
10
10
|
from pydantic import (
|
|
@@ -12,12 +12,18 @@ from pydantic import (
|
|
|
12
12
|
BaseModel,
|
|
13
13
|
Field,
|
|
14
14
|
NonNegativeInt,
|
|
15
|
+
ValidationError,
|
|
15
16
|
model_validator,
|
|
16
17
|
)
|
|
17
18
|
|
|
18
19
|
import rasa.shared.utils.common
|
|
19
|
-
from rasa.core.constants import DEFAULT_LOCK_LIFETIME
|
|
20
|
+
from rasa.core.constants import DEFAULT_LOCK_LIFETIME, IAM_CLOUD_PROVIDER_ENV_VAR_NAME
|
|
20
21
|
from rasa.core.lock import TicketLock
|
|
22
|
+
from rasa.core.redis_connection_factory import (
|
|
23
|
+
DeploymentMode,
|
|
24
|
+
RedisConfig,
|
|
25
|
+
RedisConnectionFactory,
|
|
26
|
+
)
|
|
21
27
|
from rasa.shared.exceptions import ConnectionException, RasaException
|
|
22
28
|
from rasa.shared.utils.io import raise_deprecation_warning
|
|
23
29
|
from rasa.utils.endpoints import EndpointConfig
|
|
@@ -221,7 +227,7 @@ class LockStore:
|
|
|
221
227
|
|
|
222
228
|
|
|
223
229
|
class RedisLockStoreConfig(BaseModel):
|
|
224
|
-
host: Union[AnyUrl, Literal["localhost"]] = Field(
|
|
230
|
+
host: Union[AnyUrl, Literal["localhost"], str] = Field(
|
|
225
231
|
default="localhost", description="The host of the redis server."
|
|
226
232
|
)
|
|
227
233
|
port: NonNegativeInt = Field(
|
|
@@ -269,6 +275,18 @@ class RedisLockStoreConfig(BaseModel):
|
|
|
269
275
|
"will be raised in case Redis doesn't respond "
|
|
270
276
|
"within `socket_timeout` seconds.",
|
|
271
277
|
)
|
|
278
|
+
deployment_mode: DeploymentMode = Field(
|
|
279
|
+
default=DeploymentMode.STANDARD,
|
|
280
|
+
description="Redis deployment mode: 'standard', 'cluster', or 'sentinel'",
|
|
281
|
+
)
|
|
282
|
+
endpoints: Optional[List[str]] = Field(
|
|
283
|
+
default=None,
|
|
284
|
+
description="List of endpoints for cluster/sentinel mode in 'host:port' format",
|
|
285
|
+
)
|
|
286
|
+
sentinel_service: Optional[str] = Field(
|
|
287
|
+
default=None,
|
|
288
|
+
description="Sentinel service name",
|
|
289
|
+
)
|
|
272
290
|
|
|
273
291
|
@model_validator(mode="before")
|
|
274
292
|
@classmethod
|
|
@@ -290,7 +308,9 @@ class RedisLockStoreConfig(BaseModel):
|
|
|
290
308
|
|
|
291
309
|
@model_validator(mode="after")
|
|
292
310
|
def verify_username_password(self) -> RedisLockStoreConfig:
|
|
293
|
-
if
|
|
311
|
+
if os.getenv(IAM_CLOUD_PROVIDER_ENV_VAR_NAME) is None and (
|
|
312
|
+
bool(self.username) ^ bool(self.password)
|
|
313
|
+
):
|
|
294
314
|
raise ValueError(
|
|
295
315
|
f"Expected username and password. "
|
|
296
316
|
f"Found: username: {'<has value>' if self.username else '<N/A>'}, "
|
|
@@ -298,9 +318,6 @@ class RedisLockStoreConfig(BaseModel):
|
|
|
298
318
|
)
|
|
299
319
|
return self
|
|
300
320
|
|
|
301
|
-
def to_strict_redis(self) -> Dict[str, Any]:
|
|
302
|
-
return self.model_dump(by_alias=True, exclude={"key_prefix"})
|
|
303
|
-
|
|
304
321
|
|
|
305
322
|
class RedisLockStore(LockStore):
|
|
306
323
|
"""Redis store for ticket locks."""
|
|
@@ -314,10 +331,26 @@ class RedisLockStore(LockStore):
|
|
|
314
331
|
Args:
|
|
315
332
|
config: Redis lock store configuration.
|
|
316
333
|
"""
|
|
317
|
-
import redis
|
|
318
|
-
|
|
319
334
|
self.config = config
|
|
320
|
-
|
|
335
|
+
try:
|
|
336
|
+
redis_config = RedisConfig(
|
|
337
|
+
host=str(self.config.host),
|
|
338
|
+
port=self.config.port,
|
|
339
|
+
db=self.config.db,
|
|
340
|
+
username=self.config.username,
|
|
341
|
+
password=self.config.password,
|
|
342
|
+
use_ssl=self.config.use_ssl,
|
|
343
|
+
ssl_keyfile=self.config.ssl_keyfile,
|
|
344
|
+
ssl_certfile=self.config.ssl_certfile,
|
|
345
|
+
ssl_ca_certs=self.config.ssl_ca_certs,
|
|
346
|
+
deployment_mode=self.config.deployment_mode.value,
|
|
347
|
+
endpoints=self.config.endpoints,
|
|
348
|
+
sentinel_service=self.config.sentinel_service,
|
|
349
|
+
socket_timeout=self.config.socket_timeout,
|
|
350
|
+
)
|
|
351
|
+
self.red = RedisConnectionFactory.create_connection(redis_config)
|
|
352
|
+
except ValidationError as e:
|
|
353
|
+
raise RasaException(f"Invalid Redis configuration: {e}")
|
|
321
354
|
|
|
322
355
|
self.key_prefix = DEFAULT_REDIS_LOCK_STORE_KEY_PREFIX
|
|
323
356
|
if self.config.key_prefix:
|
|
@@ -349,6 +382,9 @@ class RedisLockStore(LockStore):
|
|
|
349
382
|
"""Retrieves lock (see parent docstring for more information)."""
|
|
350
383
|
serialised_lock = self.red.get(self.key_prefix + conversation_id)
|
|
351
384
|
if serialised_lock:
|
|
385
|
+
# Handle bytes to string conversion for JSON parsing
|
|
386
|
+
if isinstance(serialised_lock, bytes):
|
|
387
|
+
serialised_lock = serialised_lock.decode("utf-8")
|
|
352
388
|
return TicketLock.from_dict(json.loads(serialised_lock))
|
|
353
389
|
|
|
354
390
|
return None
|
rasa/core/nlg/generator.py
CHANGED
|
@@ -2,7 +2,6 @@ from typing import Any, Dict, List, Optional, Text, Union
|
|
|
2
2
|
|
|
3
3
|
import structlog
|
|
4
4
|
from jinja2 import Template
|
|
5
|
-
from pypred import Predicate
|
|
6
5
|
|
|
7
6
|
import rasa.shared.utils.common
|
|
8
7
|
import rasa.shared.utils.io
|
|
@@ -12,6 +11,7 @@ from rasa.shared.constants import CHANNEL, RESPONSE_CONDITION
|
|
|
12
11
|
from rasa.shared.core.domain import Domain
|
|
13
12
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
14
13
|
from rasa.utils.endpoints import EndpointConfig
|
|
14
|
+
from rasa.utils.pypred import Predicate
|
|
15
15
|
|
|
16
16
|
structlogger = structlog.get_logger()
|
|
17
17
|
|
|
@@ -4,7 +4,6 @@ from typing import Any, Dict, List, Optional, Text
|
|
|
4
4
|
|
|
5
5
|
import structlog
|
|
6
6
|
from jinja2 import Template
|
|
7
|
-
from pypred import Predicate
|
|
8
7
|
from structlog.contextvars import (
|
|
9
8
|
bound_contextvars,
|
|
10
9
|
)
|
|
@@ -92,6 +91,7 @@ from rasa.shared.core.slots import Slot, SlotRejection
|
|
|
92
91
|
from rasa.shared.core.trackers import (
|
|
93
92
|
DialogueStateTracker,
|
|
94
93
|
)
|
|
94
|
+
from rasa.utils.pypred import Predicate
|
|
95
95
|
|
|
96
96
|
structlogger = structlog.get_logger()
|
|
97
97
|
|
rasa/core/processor.py
CHANGED
|
@@ -72,6 +72,7 @@ from rasa.shared.core.constants import (
|
|
|
72
72
|
ACTION_CORRECT_FLOW_SLOT,
|
|
73
73
|
ACTION_EXTRACT_SLOTS,
|
|
74
74
|
ACTION_LISTEN_NAME,
|
|
75
|
+
ACTION_METADATA_EXECUTION_TIME,
|
|
75
76
|
ACTION_SESSION_START_NAME,
|
|
76
77
|
FOLLOWUP_ACTION,
|
|
77
78
|
SESSION_START_METADATA_SLOT,
|
|
@@ -207,6 +208,7 @@ class MessageProcessor:
|
|
|
207
208
|
) -> Optional[List[Dict[Text, Any]]]:
|
|
208
209
|
"""Handle a single message with this processor."""
|
|
209
210
|
# preprocess message if necessary
|
|
211
|
+
self.time_turn_start = time.time()
|
|
210
212
|
tracker = await self.log_message(message, should_save_tracker=False)
|
|
211
213
|
|
|
212
214
|
if self.model_metadata.training_type == TrainingType.NLU:
|
|
@@ -1154,6 +1156,7 @@ class MessageProcessor:
|
|
|
1154
1156
|
should_predict_another_action = True
|
|
1155
1157
|
|
|
1156
1158
|
tracker = await self.run_command_processor(tracker)
|
|
1159
|
+
self.time_command_processor = time.time()
|
|
1157
1160
|
|
|
1158
1161
|
# action loop. predicts actions until we hit action listen
|
|
1159
1162
|
while should_predict_another_action and self._should_handle_message(tracker):
|
|
@@ -1403,6 +1406,34 @@ class MessageProcessor:
|
|
|
1403
1406
|
plugin_manager().hook.after_action_executed(tracker=tracker)
|
|
1404
1407
|
return self.should_predict_another_action(action.name())
|
|
1405
1408
|
|
|
1409
|
+
def _add_metadata_if_action_listen(
|
|
1410
|
+
self, action: Action, prediction: PolicyPrediction
|
|
1411
|
+
) -> None:
|
|
1412
|
+
"""Adds execution times to the ActionExecuted event metadata."""
|
|
1413
|
+
if not hasattr(self, "time_turn_start"):
|
|
1414
|
+
return
|
|
1415
|
+
|
|
1416
|
+
if not hasattr(self, "time_command_processor"):
|
|
1417
|
+
return
|
|
1418
|
+
|
|
1419
|
+
if not action.name() == ACTION_LISTEN_NAME:
|
|
1420
|
+
return
|
|
1421
|
+
|
|
1422
|
+
if prediction.action_metadata is None:
|
|
1423
|
+
prediction.action_metadata = {}
|
|
1424
|
+
|
|
1425
|
+
# calculate execution times
|
|
1426
|
+
execution_time_prediction_loop = (
|
|
1427
|
+
time.time() - self.time_command_processor
|
|
1428
|
+
) * 1000
|
|
1429
|
+
execution_time_command_processor = (
|
|
1430
|
+
self.time_command_processor - self.time_turn_start
|
|
1431
|
+
) * 1000
|
|
1432
|
+
prediction.action_metadata[ACTION_METADATA_EXECUTION_TIME] = {
|
|
1433
|
+
"command_processor": execution_time_command_processor,
|
|
1434
|
+
"prediction_loop": execution_time_prediction_loop,
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1406
1437
|
def _log_action_and_events_on_tracker(
|
|
1407
1438
|
self,
|
|
1408
1439
|
tracker: DialogueStateTracker,
|
|
@@ -1448,6 +1479,7 @@ class MessageProcessor:
|
|
|
1448
1479
|
tracker.update_with_events(prediction.events)
|
|
1449
1480
|
|
|
1450
1481
|
# log the action and its produced events
|
|
1482
|
+
self._add_metadata_if_action_listen(action, prediction)
|
|
1451
1483
|
tracker.update(
|
|
1452
1484
|
action.event_for_successful_execution(
|
|
1453
1485
|
prediction, was_successful, error_message
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any, Dict, List, Optional, Text, Tuple, Union
|
|
4
|
+
|
|
5
|
+
import redis
|
|
6
|
+
import structlog
|
|
7
|
+
from pydantic import BaseModel, ConfigDict
|
|
8
|
+
|
|
9
|
+
from rasa.core.constants import AWS_ELASTICACHE_CLUSTER_NAME_ENV_VAR_NAME
|
|
10
|
+
from rasa.core.iam_credentials_providers.credentials_provider_protocol import (
|
|
11
|
+
IAMCredentialsProvider,
|
|
12
|
+
IAMCredentialsProviderInput,
|
|
13
|
+
SupportedServiceType,
|
|
14
|
+
create_iam_credentials_provider,
|
|
15
|
+
)
|
|
16
|
+
from rasa.shared.exceptions import ConnectionException, RasaException
|
|
17
|
+
|
|
18
|
+
structlogger = structlog.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
DEFAULT_SOCKET_TIMEOUT_IN_SECONDS = 10
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DeploymentMode(Enum):
|
|
24
|
+
"""Supported Redis deployment modes."""
|
|
25
|
+
|
|
26
|
+
STANDARD = "standard"
|
|
27
|
+
CLUSTER = "cluster"
|
|
28
|
+
SENTINEL = "sentinel"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class StandardRedisConfig(BaseModel):
|
|
32
|
+
"""Base configuration for Redis connections."""
|
|
33
|
+
|
|
34
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
35
|
+
|
|
36
|
+
host: Text = "localhost"
|
|
37
|
+
port: int = 6379
|
|
38
|
+
username: Optional[Text] = None
|
|
39
|
+
password: Optional[Text] = None
|
|
40
|
+
use_ssl: bool = False
|
|
41
|
+
ssl_keyfile: Optional[Text] = None
|
|
42
|
+
ssl_certfile: Optional[Text] = None
|
|
43
|
+
ssl_ca_certs: Optional[Text] = None
|
|
44
|
+
db: int = 0
|
|
45
|
+
socket_timeout: float = DEFAULT_SOCKET_TIMEOUT_IN_SECONDS
|
|
46
|
+
decode_responses: bool = False
|
|
47
|
+
iam_credentials_provider: Optional[IAMCredentialsProvider] = None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ClusterRedisConfig(StandardRedisConfig):
|
|
51
|
+
"""Configuration for Redis Cluster connections."""
|
|
52
|
+
|
|
53
|
+
endpoints: List[Tuple[Text, int]]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class SentinelRedisConfig(StandardRedisConfig):
|
|
57
|
+
"""Configuration for Redis Sentinel connections."""
|
|
58
|
+
|
|
59
|
+
endpoints: List[Tuple[Text, int]]
|
|
60
|
+
sentinel_service: Optional[Text] = "mymaster"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class RedisConfig(BaseModel):
|
|
64
|
+
"""Base configuration for Redis connections."""
|
|
65
|
+
|
|
66
|
+
host: Text = "localhost"
|
|
67
|
+
port: int = 6379
|
|
68
|
+
username: Optional[Text] = None
|
|
69
|
+
password: Optional[Text] = None
|
|
70
|
+
use_ssl: bool = False
|
|
71
|
+
ssl_keyfile: Optional[Text] = None
|
|
72
|
+
ssl_certfile: Optional[Text] = None
|
|
73
|
+
ssl_ca_certs: Optional[Text] = None
|
|
74
|
+
db: int = 0
|
|
75
|
+
socket_timeout: float = DEFAULT_SOCKET_TIMEOUT_IN_SECONDS
|
|
76
|
+
decode_responses: bool = False
|
|
77
|
+
deployment_mode: Text = DeploymentMode.STANDARD.value
|
|
78
|
+
endpoints: Optional[List[Text]] = None
|
|
79
|
+
sentinel_service: Optional[Text] = None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class RedisConnectionFactory:
|
|
83
|
+
"""Factory class for creating Redis connections with different modes."""
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def create_connection(
|
|
87
|
+
cls,
|
|
88
|
+
config: RedisConfig,
|
|
89
|
+
) -> Union[redis.Redis, redis.RedisCluster]:
|
|
90
|
+
"""Create a Redis connection based on the configuration.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
config: Redis configuration object containing all connection parameters.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
A Redis connection - either a standard Redis connection, a RedisCluster
|
|
97
|
+
connection, or a Redis master connection managed by Sentinel.
|
|
98
|
+
|
|
99
|
+
Raises:
|
|
100
|
+
RasaException: If configuration is invalid.
|
|
101
|
+
"""
|
|
102
|
+
if config.endpoints is None:
|
|
103
|
+
config.endpoints = []
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
deployment_mode_enum = DeploymentMode(config.deployment_mode)
|
|
107
|
+
except ValueError:
|
|
108
|
+
valid_modes = [mode.value for mode in DeploymentMode]
|
|
109
|
+
raise RasaException(
|
|
110
|
+
f"Invalid deployment_mode '{config.deployment_mode}'. "
|
|
111
|
+
f"Must be one of: {', '.join(valid_modes)}"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
parsed_endpoints = cls._parse_and_validate_endpoints(
|
|
115
|
+
deployment_mode_enum, config.endpoints, config.host, config.port
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
iam_credentials_provider = create_iam_credentials_provider(
|
|
119
|
+
IAMCredentialsProviderInput(
|
|
120
|
+
service_name=SupportedServiceType.LOCK_STORE,
|
|
121
|
+
username=config.username,
|
|
122
|
+
cluster_name=os.getenv(AWS_ELASTICACHE_CLUSTER_NAME_ENV_VAR_NAME),
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
if deployment_mode_enum == DeploymentMode.CLUSTER:
|
|
127
|
+
cls._log_cluster_db_warning(deployment_mode_enum, config.db)
|
|
128
|
+
cluster_config = ClusterRedisConfig(
|
|
129
|
+
username=config.username,
|
|
130
|
+
password=config.password,
|
|
131
|
+
use_ssl=config.use_ssl,
|
|
132
|
+
ssl_certfile=config.ssl_certfile,
|
|
133
|
+
ssl_keyfile=config.ssl_keyfile,
|
|
134
|
+
ssl_ca_certs=config.ssl_ca_certs,
|
|
135
|
+
db=config.db,
|
|
136
|
+
socket_timeout=config.socket_timeout,
|
|
137
|
+
decode_responses=config.decode_responses,
|
|
138
|
+
endpoints=parsed_endpoints,
|
|
139
|
+
iam_credentials_provider=iam_credentials_provider,
|
|
140
|
+
)
|
|
141
|
+
return cls._create_cluster_connection(cluster_config)
|
|
142
|
+
elif deployment_mode_enum == DeploymentMode.SENTINEL:
|
|
143
|
+
sentinel_kwargs = {
|
|
144
|
+
"username": config.username,
|
|
145
|
+
"password": config.password,
|
|
146
|
+
"use_ssl": config.use_ssl,
|
|
147
|
+
"ssl_certfile": config.ssl_certfile,
|
|
148
|
+
"ssl_keyfile": config.ssl_keyfile,
|
|
149
|
+
"ssl_ca_certs": config.ssl_ca_certs,
|
|
150
|
+
"db": config.db,
|
|
151
|
+
"socket_timeout": config.socket_timeout,
|
|
152
|
+
"decode_responses": config.decode_responses,
|
|
153
|
+
"endpoints": parsed_endpoints,
|
|
154
|
+
"iam_credentials_provider": iam_credentials_provider,
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if config.sentinel_service is not None:
|
|
158
|
+
sentinel_kwargs["sentinel_service"] = config.sentinel_service
|
|
159
|
+
|
|
160
|
+
sentinel_config = SentinelRedisConfig(**sentinel_kwargs)
|
|
161
|
+
return cls._create_sentinel_connection(sentinel_config)
|
|
162
|
+
else:
|
|
163
|
+
standard_config = StandardRedisConfig(
|
|
164
|
+
host=config.host,
|
|
165
|
+
port=config.port,
|
|
166
|
+
username=config.username,
|
|
167
|
+
password=config.password,
|
|
168
|
+
use_ssl=config.use_ssl,
|
|
169
|
+
ssl_certfile=config.ssl_certfile,
|
|
170
|
+
ssl_keyfile=config.ssl_keyfile,
|
|
171
|
+
ssl_ca_certs=config.ssl_ca_certs,
|
|
172
|
+
db=config.db,
|
|
173
|
+
socket_timeout=config.socket_timeout,
|
|
174
|
+
decode_responses=config.decode_responses,
|
|
175
|
+
iam_credentials_provider=iam_credentials_provider,
|
|
176
|
+
)
|
|
177
|
+
return cls._create_standard_connection(standard_config)
|
|
178
|
+
|
|
179
|
+
@classmethod
|
|
180
|
+
def _parse_and_validate_endpoints(
|
|
181
|
+
cls,
|
|
182
|
+
deployment_mode: DeploymentMode,
|
|
183
|
+
endpoints: List[str],
|
|
184
|
+
host: Text,
|
|
185
|
+
port: int,
|
|
186
|
+
) -> List[Union[Dict[str, Any], Tuple[str, int]]]:
|
|
187
|
+
"""Parse and validate endpoints based on deployment mode."""
|
|
188
|
+
if deployment_mode == DeploymentMode.STANDARD:
|
|
189
|
+
if endpoints:
|
|
190
|
+
structlogger.warning(
|
|
191
|
+
"redis_connection_factory.standard_endpoints_ignored",
|
|
192
|
+
event_info="Parameter `endpoints` ignored in standard mode. "
|
|
193
|
+
"Only 'host' and 'port' are used for standard Redis connections.",
|
|
194
|
+
)
|
|
195
|
+
return []
|
|
196
|
+
|
|
197
|
+
if not endpoints:
|
|
198
|
+
endpoints = cls._get_default_endpoints(deployment_mode, host, port)
|
|
199
|
+
|
|
200
|
+
# Parse endpoints into appropriate format
|
|
201
|
+
parsed_endpoints = cls._parse_all_endpoints(endpoints, deployment_mode)
|
|
202
|
+
|
|
203
|
+
if not parsed_endpoints:
|
|
204
|
+
raise RasaException(
|
|
205
|
+
f"No valid '{deployment_mode.value}' endpoints provided"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return parsed_endpoints
|
|
209
|
+
|
|
210
|
+
@classmethod
|
|
211
|
+
def _get_default_endpoints(
|
|
212
|
+
cls,
|
|
213
|
+
deployment_mode: DeploymentMode,
|
|
214
|
+
host: Text,
|
|
215
|
+
port: int,
|
|
216
|
+
) -> List[str]:
|
|
217
|
+
"""Get default endpoints when none provided."""
|
|
218
|
+
if deployment_mode == DeploymentMode.CLUSTER:
|
|
219
|
+
structlogger.warning(
|
|
220
|
+
"redis_connection_factory.cluster_endpoints_not_provided",
|
|
221
|
+
event_info="No endpoints provided for cluster mode. "
|
|
222
|
+
"Using default 'host:port' configuration.",
|
|
223
|
+
)
|
|
224
|
+
return [f"{host}:{port}"]
|
|
225
|
+
elif deployment_mode == DeploymentMode.SENTINEL:
|
|
226
|
+
raise RasaException("Sentinel mode requires endpoints configuration")
|
|
227
|
+
|
|
228
|
+
return []
|
|
229
|
+
|
|
230
|
+
@classmethod
|
|
231
|
+
def _parse_single_endpoint(
|
|
232
|
+
cls, endpoint: str, deployment_mode: DeploymentMode
|
|
233
|
+
) -> Optional[Union[Dict[str, Any], Tuple[str, int]]]:
|
|
234
|
+
"""Parse a single endpoint string into the appropriate format."""
|
|
235
|
+
if not isinstance(endpoint, str):
|
|
236
|
+
structlogger.warning(
|
|
237
|
+
f"redis_connection_factory.invalid_{deployment_mode.value}_endpoint_type",
|
|
238
|
+
event_info=f"Invalid endpoint type for endpoint '{endpoint}'. "
|
|
239
|
+
"Expected string in 'host:port' format.",
|
|
240
|
+
)
|
|
241
|
+
return None
|
|
242
|
+
|
|
243
|
+
if ":" not in endpoint:
|
|
244
|
+
structlogger.warning(
|
|
245
|
+
f"redis_connection_factory.invalid_{deployment_mode.value}_endpoint_format",
|
|
246
|
+
event_info=f"Invalid format for endpoint '{endpoint}'. "
|
|
247
|
+
"Expected 'host:port'.",
|
|
248
|
+
)
|
|
249
|
+
return None
|
|
250
|
+
|
|
251
|
+
host, port_str = endpoint.rsplit(":", 1)
|
|
252
|
+
try:
|
|
253
|
+
port = int(port_str)
|
|
254
|
+
except ValueError:
|
|
255
|
+
structlogger.warning(
|
|
256
|
+
f"redis_connection_factory.invalid_{deployment_mode.value}_endpoint",
|
|
257
|
+
event_info=f"Invalid port in endpoint '{endpoint}'. "
|
|
258
|
+
"Expected format 'host:port'.",
|
|
259
|
+
)
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
return (host, port)
|
|
263
|
+
|
|
264
|
+
@classmethod
|
|
265
|
+
def _parse_all_endpoints(
|
|
266
|
+
cls,
|
|
267
|
+
endpoints: List[str],
|
|
268
|
+
deployment_mode: DeploymentMode,
|
|
269
|
+
) -> List[Union[Dict[str, Any], Tuple[str, int]]]:
|
|
270
|
+
"""Parse a list of endpoint strings into appropriate format."""
|
|
271
|
+
parsed_endpoints = []
|
|
272
|
+
for endpoint in endpoints:
|
|
273
|
+
parsed = cls._parse_single_endpoint(endpoint, deployment_mode)
|
|
274
|
+
if parsed:
|
|
275
|
+
parsed_endpoints.append(parsed)
|
|
276
|
+
return parsed_endpoints
|
|
277
|
+
|
|
278
|
+
@classmethod
|
|
279
|
+
def _create_cluster_connection(
|
|
280
|
+
cls,
|
|
281
|
+
config: ClusterRedisConfig,
|
|
282
|
+
) -> redis.RedisCluster:
|
|
283
|
+
"""Create a Redis Cluster connection.
|
|
284
|
+
|
|
285
|
+
Note: Database parameter is ignored in cluster mode (always uses db=0).
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
config: Cluster configuration containing all connection parameters.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
redis.RedisCluster: Configured cluster connection.
|
|
292
|
+
|
|
293
|
+
Raises:
|
|
294
|
+
ConnectionException: If cluster initialization fails.
|
|
295
|
+
"""
|
|
296
|
+
from redis.cluster import ClusterNode
|
|
297
|
+
|
|
298
|
+
structlogger.info(
|
|
299
|
+
"redis_connection_factory.cluster_mode",
|
|
300
|
+
event_info=f"Initializing Redis Cluster with {len(config.endpoints)} nodes",
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
cluster_nodes = [ClusterNode(host, port) for host, port in config.endpoints]
|
|
304
|
+
|
|
305
|
+
common_config_kwargs = {
|
|
306
|
+
"startup_nodes": cluster_nodes,
|
|
307
|
+
"ssl": config.use_ssl,
|
|
308
|
+
"ssl_certfile": config.ssl_certfile,
|
|
309
|
+
"ssl_keyfile": config.ssl_keyfile,
|
|
310
|
+
"ssl_ca_certs": config.ssl_ca_certs,
|
|
311
|
+
"socket_timeout": config.socket_timeout,
|
|
312
|
+
"decode_responses": config.decode_responses,
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
try:
|
|
316
|
+
if config.iam_credentials_provider is not None:
|
|
317
|
+
structlogger.debug("redis_connection_factory.cluster_iam_auth_enabled")
|
|
318
|
+
|
|
319
|
+
redis_cluster: redis.RedisCluster = redis.RedisCluster(
|
|
320
|
+
credential_provider=config.iam_credentials_provider,
|
|
321
|
+
**common_config_kwargs,
|
|
322
|
+
)
|
|
323
|
+
else:
|
|
324
|
+
redis_cluster = redis.RedisCluster(
|
|
325
|
+
username=config.username,
|
|
326
|
+
password=config.password,
|
|
327
|
+
**common_config_kwargs,
|
|
328
|
+
)
|
|
329
|
+
except Exception as e:
|
|
330
|
+
raise ConnectionException(f"Error initializing Redis Cluster: {e}")
|
|
331
|
+
|
|
332
|
+
return redis_cluster
|
|
333
|
+
|
|
334
|
+
@classmethod
|
|
335
|
+
def _create_sentinel_connection(
|
|
336
|
+
cls,
|
|
337
|
+
config: SentinelRedisConfig,
|
|
338
|
+
) -> redis.Redis:
|
|
339
|
+
"""Create a Sentinel-managed Redis connection.
|
|
340
|
+
|
|
341
|
+
Connects to Redis master through Sentinel service discovery.
|
|
342
|
+
Tests connection with ping() before returning.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
config: Sentinel configuration containing all connection parameters.
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
redis.Redis: Connection to the Redis master via sentinel.
|
|
349
|
+
|
|
350
|
+
Raises:
|
|
351
|
+
ConnectionException: If sentinel initialization or connection test fails.
|
|
352
|
+
"""
|
|
353
|
+
from redis.sentinel import Sentinel
|
|
354
|
+
|
|
355
|
+
structlogger.info(
|
|
356
|
+
"redis_connection_factory.sentinel_mode",
|
|
357
|
+
event_info=f"Initializing Redis Sentinel with {len(config.endpoints)} "
|
|
358
|
+
f"sentinel endpoints and service: {config.sentinel_service}",
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
# Configuration for Sentinel connection
|
|
362
|
+
connection_kwargs: Dict[str, Any] = {
|
|
363
|
+
"socket_timeout": config.socket_timeout,
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
sentinel_kwargs: Optional[Dict] = None
|
|
367
|
+
if config.iam_credentials_provider is not None:
|
|
368
|
+
structlogger.debug("redis_connection_factory.sentinel_iam_auth_enabled")
|
|
369
|
+
sentinel_kwargs = {"credential_provider": config.iam_credentials_provider}
|
|
370
|
+
else:
|
|
371
|
+
connection_kwargs.update(
|
|
372
|
+
{
|
|
373
|
+
"username": config.username,
|
|
374
|
+
"password": config.password,
|
|
375
|
+
}
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
# SSL configuration
|
|
379
|
+
if config.use_ssl:
|
|
380
|
+
connection_kwargs.update(
|
|
381
|
+
{
|
|
382
|
+
"ssl": config.use_ssl,
|
|
383
|
+
"ssl_certfile": config.ssl_certfile,
|
|
384
|
+
"ssl_keyfile": config.ssl_keyfile,
|
|
385
|
+
"ssl_ca_certs": config.ssl_ca_certs,
|
|
386
|
+
}
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
# Configuration for Redis client (master/replica)
|
|
390
|
+
client_kwargs = {
|
|
391
|
+
"db": config.db,
|
|
392
|
+
"decode_responses": config.decode_responses,
|
|
393
|
+
"socket_timeout": config.socket_timeout,
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
# Create Sentinel instance
|
|
397
|
+
try:
|
|
398
|
+
sentinel = Sentinel(
|
|
399
|
+
config.endpoints, sentinel_kwargs=sentinel_kwargs, **connection_kwargs
|
|
400
|
+
)
|
|
401
|
+
master = sentinel.master_for(config.sentinel_service, **client_kwargs)
|
|
402
|
+
|
|
403
|
+
# Test the connection
|
|
404
|
+
master.ping()
|
|
405
|
+
|
|
406
|
+
except Exception as e:
|
|
407
|
+
raise ConnectionException(f"Error initializing Redis Sentinel: {e}")
|
|
408
|
+
|
|
409
|
+
return master
|
|
410
|
+
|
|
411
|
+
@classmethod
|
|
412
|
+
def _create_standard_connection(
|
|
413
|
+
cls,
|
|
414
|
+
config: StandardRedisConfig,
|
|
415
|
+
) -> redis.Redis:
|
|
416
|
+
"""Create a standard Redis connection.
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
config: Standard configuration containing all connection parameters.
|
|
420
|
+
|
|
421
|
+
Returns:
|
|
422
|
+
redis.Redis: Configured Redis connection.
|
|
423
|
+
"""
|
|
424
|
+
structlogger.info(
|
|
425
|
+
"redis_connection_factory.standard_mode",
|
|
426
|
+
event_info="Initializing Redis connection",
|
|
427
|
+
)
|
|
428
|
+
# Build connection arguments
|
|
429
|
+
connection_args: Dict[str, Any] = {
|
|
430
|
+
"host": config.host,
|
|
431
|
+
"port": int(config.port),
|
|
432
|
+
"db": config.db,
|
|
433
|
+
"socket_timeout": float(config.socket_timeout),
|
|
434
|
+
"ssl": config.use_ssl,
|
|
435
|
+
"ssl_certfile": config.ssl_certfile,
|
|
436
|
+
"ssl_keyfile": config.ssl_keyfile,
|
|
437
|
+
"ssl_ca_certs": config.ssl_ca_certs,
|
|
438
|
+
"decode_responses": config.decode_responses,
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if config.iam_credentials_provider is not None:
|
|
442
|
+
structlogger.debug("redis_connection_factory.standard_iam_auth_enabled")
|
|
443
|
+
connection_args.update(
|
|
444
|
+
{"credential_provider": config.iam_credentials_provider}
|
|
445
|
+
)
|
|
446
|
+
else:
|
|
447
|
+
connection_args.update(
|
|
448
|
+
{
|
|
449
|
+
"password": config.password,
|
|
450
|
+
"username": config.username,
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
try:
|
|
455
|
+
standard_redis = redis.StrictRedis(**connection_args)
|
|
456
|
+
except Exception as e:
|
|
457
|
+
raise ConnectionException(f"Error initializing Redis connection: {e}")
|
|
458
|
+
|
|
459
|
+
return standard_redis
|
|
460
|
+
|
|
461
|
+
@classmethod
|
|
462
|
+
def _log_cluster_db_warning(cls, deployment_mode: DeploymentMode, db: int) -> None:
|
|
463
|
+
"""Log warning if db parameter is set in cluster mode."""
|
|
464
|
+
if deployment_mode == DeploymentMode.CLUSTER and db != 0:
|
|
465
|
+
structlogger.warning(
|
|
466
|
+
"redis_connection_factory.cluster_db_ignored",
|
|
467
|
+
event_info=f"Database parameter 'db={db}' ignored in cluster mode. "
|
|
468
|
+
"Redis Cluster only supports database 0.",
|
|
469
|
+
)
|