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.

Files changed (361) hide show
  1. rasa/builder/config.py +1 -0
  2. rasa/builder/copilot/constants.py +3 -0
  3. rasa/builder/copilot/copilot.py +128 -54
  4. rasa/builder/copilot/models.py +39 -3
  5. rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +183 -188
  6. rasa/builder/copilot/prompts/latest_user_message_context_prompt.jinja2 +61 -0
  7. rasa/builder/copilot/telemetry.py +46 -20
  8. rasa/builder/document_retrieval/models.py +3 -3
  9. rasa/builder/download.py +1 -8
  10. rasa/builder/jobs.py +33 -21
  11. rasa/builder/main.py +38 -62
  12. rasa/builder/models.py +7 -7
  13. rasa/builder/project_generator.py +143 -147
  14. rasa/builder/service.py +42 -27
  15. rasa/builder/template_cache.py +69 -0
  16. rasa/builder/training_service.py +74 -4
  17. rasa/cli/project_templates/basic/README.md +23 -0
  18. rasa/cli/project_templates/basic/actions/actions.md +10 -0
  19. rasa/cli/project_templates/basic/config.yml +6 -4
  20. rasa/cli/project_templates/basic/data/data.md +5 -6
  21. rasa/cli/project_templates/basic/domain/domain.md +7 -5
  22. rasa/cli/project_templates/basic/domain/general/show_faqs.yml +1 -1
  23. rasa/cli/project_templates/basic/endpoints.yml +5 -1
  24. rasa/cli/project_templates/default/config.yml +4 -0
  25. rasa/cli/project_templates/default/endpoints.yml +4 -0
  26. rasa/cli/project_templates/finance/README.md +26 -0
  27. rasa/cli/project_templates/finance/actions/__init__.py +0 -46
  28. rasa/cli/project_templates/finance/actions/accounts/check_balance.py +18 -0
  29. rasa/cli/project_templates/finance/actions/actions.md +15 -0
  30. rasa/cli/project_templates/finance/actions/{transfers/action_process_immediate_payment.py → cards/check_that_card_exists.py} +6 -3
  31. rasa/cli/project_templates/finance/actions/cards/list_cards.py +22 -0
  32. rasa/cli/project_templates/finance/actions/contacts/__init__.py +0 -0
  33. rasa/cli/project_templates/finance/actions/contacts/add_contact.py +30 -0
  34. rasa/cli/project_templates/finance/actions/contacts/list_contacts.py +22 -0
  35. rasa/cli/project_templates/finance/actions/contacts/remove_contact.py +35 -0
  36. rasa/cli/project_templates/finance/actions/db.py +117 -0
  37. rasa/cli/project_templates/finance/actions/general/__init__.py +0 -0
  38. rasa/cli/project_templates/finance/actions/general/action_human_handoff.py +49 -0
  39. rasa/cli/project_templates/finance/actions/transfers/check_transfer_funds.py +27 -0
  40. rasa/cli/project_templates/finance/actions/transfers/check_transfer_limit.py +36 -0
  41. rasa/cli/project_templates/finance/actions/transfers/execute_recurrent_payment.py +20 -0
  42. rasa/cli/project_templates/finance/actions/transfers/execute_transfer.py +45 -0
  43. rasa/cli/project_templates/finance/actions/transfers/list_transactions.py +32 -0
  44. rasa/cli/project_templates/finance/config.yml +8 -0
  45. rasa/cli/project_templates/finance/credentials.yml +7 -6
  46. rasa/cli/project_templates/finance/data/accounts/check_balance.yml +3 -4
  47. rasa/cli/project_templates/finance/data/accounts/download_statements.yml +26 -0
  48. rasa/cli/project_templates/finance/data/bills/bill_pay_reminder.yml +25 -0
  49. rasa/cli/project_templates/finance/data/cards/activate_card.yml +35 -0
  50. rasa/cli/project_templates/finance/data/cards/block_card.yml +37 -58
  51. rasa/cli/project_templates/finance/data/cards/list_cards.yml +14 -0
  52. rasa/cli/project_templates/finance/data/cards/replace_card.yml +16 -0
  53. rasa/cli/project_templates/finance/data/cards/replace_eligible_card.yml +29 -0
  54. rasa/cli/project_templates/finance/data/contacts/add_contact.yml +33 -0
  55. rasa/cli/project_templates/finance/data/contacts/list_contacts.yml +14 -0
  56. rasa/cli/project_templates/finance/data/contacts/remove_contact.yml +31 -0
  57. rasa/cli/project_templates/finance/data/data.md +14 -0
  58. rasa/cli/project_templates/finance/data/general/bot_challenge.yml +6 -0
  59. rasa/cli/project_templates/finance/data/general/goodbye.yml +1 -1
  60. rasa/cli/project_templates/finance/data/general/hello.yml +1 -2
  61. rasa/cli/project_templates/finance/data/general/help.yml +2 -2
  62. rasa/cli/project_templates/finance/data/general/human_handoff.yml +2 -2
  63. rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +1 -1
  64. rasa/cli/project_templates/finance/data/transfers/check_transfer_limit.yml +18 -0
  65. rasa/cli/project_templates/finance/data/transfers/list_transactions.yml +46 -0
  66. rasa/cli/project_templates/finance/data/transfers/move_money_between_accounts.yml +51 -0
  67. rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +29 -62
  68. rasa/cli/project_templates/finance/data/transfers/transfer_money_to_a_third_party.yml +175 -0
  69. rasa/cli/project_templates/finance/db/cards.json +18 -0
  70. rasa/cli/project_templates/finance/db/contacts.json +10 -0
  71. rasa/cli/project_templates/finance/db/my_account.json +6 -0
  72. rasa/cli/project_templates/finance/db/transactions.json +22 -0
  73. rasa/cli/project_templates/finance/docs/docs.md +8 -0
  74. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/budgeting_analytics.txt +22 -0
  75. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/multi_currency_accounts.txt +19 -0
  76. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/premium_benefits.txt +19 -0
  77. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/contactless_limits.txt +16 -0
  78. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/freeze_unfreeze_card.txt +16 -0
  79. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/lost_stolen_card.txt +19 -0
  80. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/instant_payments.txt +19 -0
  81. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/international_transfers.txt +19 -0
  82. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/fraud_protection.txt +22 -0
  83. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/secure_payments.txt +22 -0
  84. rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +9 -5
  85. rasa/cli/project_templates/finance/domain/accounts/download_statements.yml +40 -0
  86. rasa/cli/project_templates/finance/domain/bills/bill_pay_reminder.yml +49 -0
  87. rasa/cli/project_templates/finance/domain/cards/activate_card.yml +24 -0
  88. rasa/cli/project_templates/finance/domain/cards/block_card.yml +33 -90
  89. rasa/cli/project_templates/finance/domain/cards/list_cards.yml +16 -0
  90. rasa/cli/project_templates/finance/domain/cards/replace_card.yml +43 -0
  91. rasa/cli/project_templates/finance/domain/cards/shared.yml +15 -0
  92. rasa/cli/project_templates/finance/domain/contacts/add_contact.yml +37 -0
  93. rasa/cli/project_templates/finance/domain/contacts/list_contacts.yml +16 -0
  94. rasa/cli/project_templates/finance/domain/contacts/remove_contact.yml +32 -0
  95. rasa/cli/project_templates/finance/domain/domain.md +18 -0
  96. rasa/cli/project_templates/finance/domain/general/_shared.yml +39 -0
  97. rasa/cli/project_templates/finance/domain/general/bot_challenge.yml +4 -0
  98. rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -2
  99. rasa/cli/project_templates/finance/domain/general/feedback.yml +0 -3
  100. rasa/cli/project_templates/finance/domain/general/goodbye.yml +6 -6
  101. rasa/cli/project_templates/finance/domain/general/human_handoff.yml +10 -9
  102. rasa/cli/project_templates/finance/domain/general/welcome.yml +33 -2
  103. rasa/cli/project_templates/finance/domain/transfers/check_transfer_limit.yml +32 -0
  104. rasa/cli/project_templates/finance/domain/transfers/list_transactions.yml +44 -0
  105. rasa/cli/project_templates/finance/domain/transfers/shared.yml +17 -0
  106. rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +203 -61
  107. rasa/cli/project_templates/finance/endpoints.yml +8 -4
  108. rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +31 -12
  109. rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/check_balance.yml +9 -0
  110. rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/download_statements.yml +43 -0
  111. rasa/cli/project_templates/finance/tests/e2e_test_cases/cards/block_card.yml +55 -0
  112. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
  113. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/feedback.yml +46 -0
  114. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/goodbye.yml +9 -0
  115. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/hello.yml +8 -0
  116. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/human_handoff.yml +35 -0
  117. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/patterns.yml +22 -0
  118. rasa/cli/project_templates/finance/tests/e2e_test_cases/transfers/transfer_money.yml +56 -0
  119. rasa/cli/project_templates/telco/README.md +25 -0
  120. rasa/cli/project_templates/telco/actions/actions.md +12 -0
  121. rasa/cli/project_templates/telco/config.yml +6 -4
  122. rasa/cli/project_templates/telco/data/data.md +11 -0
  123. rasa/cli/project_templates/telco/data/general/human_handoff.yml +1 -1
  124. rasa/cli/project_templates/telco/docs/docs.md +3 -0
  125. rasa/cli/project_templates/telco/domain/domain.md +13 -0
  126. rasa/cli/project_templates/telco/domain/general/human_handoff.yml +3 -6
  127. rasa/cli/project_templates/telco/endpoints.yml +5 -1
  128. rasa/cli/project_templates/telco/prompts/rephraser_demo_personality_prompt.jinja2 +1 -1
  129. rasa/cli/project_templates/telco/tests/e2e_test_cases/billing/understand_bill.yml +67 -0
  130. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
  131. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/feedback.yml +46 -0
  132. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/goodbye.yml +9 -0
  133. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/hello.yml +8 -0
  134. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/human_handoff.yml +35 -0
  135. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/patterns.yml +23 -0
  136. rasa/cli/project_templates/telco/tests/e2e_test_cases/network/solve_internet_issue.yml +57 -0
  137. rasa/core/actions/action_run_slot_rejections.py +1 -1
  138. rasa/core/actions/direct_custom_actions_executor.py +9 -2
  139. rasa/core/brokers/broker.py +1 -1
  140. rasa/core/brokers/kafka.py +52 -8
  141. rasa/core/channels/development_inspector.py +1 -21
  142. rasa/core/channels/hangouts.py +2 -2
  143. rasa/core/channels/inspector/dist/assets/{arc-18042c22.js → arc-35222594.js} +1 -1
  144. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-fdd6bcfa.js → blockDiagram-38ab4fdb-a0efbfd3.js} +1 -1
  145. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-f5ae6786.js → c4Diagram-3d4e48cf-0584c0f2.js} +1 -1
  146. rasa/core/channels/inspector/dist/assets/channel-8e08bed9.js +1 -0
  147. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-81efba3e.js → classDiagram-70f12bd4-39f40dbe.js} +1 -1
  148. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-3b6b6a92.js → classDiagram-v2-f2320105-1ad755f3.js} +1 -1
  149. rasa/core/channels/inspector/dist/assets/clone-78c82dea.js +1 -0
  150. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-31422447.js → createText-2e5e7dd3-b0f4f0fe.js} +1 -1
  151. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-518a90db.js → edges-e0da2a9e-9039bff9.js} +1 -1
  152. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-a6d3c25a.js → erDiagram-9861fffd-65c9b127.js} +1 -1
  153. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e048c2be.js → flowDb-956e92f1-4f08b38e.js} +1 -1
  154. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c7474c91.js → flowDiagram-66a62f08-e95c362a.js} +1 -1
  155. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b08f601.js +1 -0
  156. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb4d8723.js → flowchart-elk-definition-4a651766-703c3015.js} +1 -1
  157. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-346636a2.js → ganttDiagram-c361ad54-699328ea.js} +1 -1
  158. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-7c508874.js → gitGraphDiagram-72cf32ee-04cf4b05.js} +1 -1
  159. rasa/core/channels/inspector/dist/assets/{graph-14702d8a.js → graph-ee94449e.js} +1 -1
  160. rasa/core/channels/inspector/dist/assets/{index-3862675e-f18b534b.js → index-3862675e-940162b4.js} +1 -1
  161. rasa/core/channels/inspector/dist/assets/{index-4d4bdf3a.js → index-c941dcb3.js} +132 -131
  162. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-64154b83.js → infoDiagram-f8f76790-c79c2866.js} +1 -1
  163. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-833a5f95.js → journeyDiagram-49397b02-84489d30.js} +1 -1
  164. rasa/core/channels/inspector/dist/assets/{layout-5a3b2123.js → layout-a9aa9858.js} +1 -1
  165. rasa/core/channels/inspector/dist/assets/{line-2272a8c7.js → line-eb73cf26.js} +1 -1
  166. rasa/core/channels/inspector/dist/assets/{linear-35bcf273.js → linear-b3399f9a.js} +1 -1
  167. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-92dcb0e9.js → mindmap-definition-fc14e90a-b095bf1a.js} +1 -1
  168. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-94dbc900.js → pieDiagram-8a3498a8-07644b66.js} +1 -1
  169. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-8b7a9c33.js → quadrantDiagram-120e2f19-573a3f9c.js} +1 -1
  170. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6f7eab81.js → requirementDiagram-deff3bca-d457e1e1.js} +1 -1
  171. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-f43e581d.js → sankeyDiagram-04a897e0-9d26e1a2.js} +1 -1
  172. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-0bcbefc3.js → sequenceDiagram-704730f1-3a9cde10.js} +1 -1
  173. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-b8a74083.js → stateDiagram-587899a1-4f3e8cec.js} +1 -1
  174. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-2070218f.js → stateDiagram-v2-d93cdb3a-e617e5bf.js} +1 -1
  175. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-f1d54e34.js → styles-6aaf32cf-eab30d2f.js} +1 -1
  176. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-980de489.js → styles-9a916d00-09994be2.js} +1 -1
  177. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-3c03abde.js → styles-c10674c1-b7110364.js} +1 -1
  178. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-46ba068f.js → svgDrawCommon-08f97a94-3ebc92ad.js} +1 -1
  179. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-901f5e3d.js → timeline-definition-85554ec2-7d13d2f2.js} +1 -1
  180. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-acbc628a.js → xychartDiagram-e933f94c-488385e1.js} +1 -1
  181. rasa/core/channels/inspector/dist/index.html +1 -1
  182. rasa/core/channels/inspector/src/App.tsx +5 -31
  183. rasa/core/channels/inspector/src/components/Chat.tsx +2 -3
  184. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +9 -1
  185. rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +63 -35
  186. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +14 -0
  187. rasa/core/channels/inspector/src/types.ts +32 -7
  188. rasa/core/channels/studio_chat.py +23 -41
  189. rasa/core/channels/voice_stream/asr/asr_event.py +1 -1
  190. rasa/core/channels/voice_stream/asr/azure.py +6 -3
  191. rasa/core/channels/voice_stream/asr/deepgram.py +1 -1
  192. rasa/core/channels/voice_stream/audiocodes.py +3 -0
  193. rasa/core/channels/voice_stream/browser_audio.py +55 -3
  194. rasa/core/channels/voice_stream/genesys.py +2 -1
  195. rasa/core/channels/voice_stream/jambonz.py +9 -1
  196. rasa/core/channels/voice_stream/twilio_media_streams.py +16 -0
  197. rasa/core/channels/voice_stream/voice_channel.py +61 -0
  198. rasa/core/concurrent_lock_store.py +66 -16
  199. rasa/core/constants.py +7 -0
  200. rasa/core/iam_credentials_providers/__init__.py +0 -0
  201. rasa/core/iam_credentials_providers/aws_iam_credentials_providers.py +226 -0
  202. rasa/core/iam_credentials_providers/credentials_provider_protocol.py +90 -0
  203. rasa/core/lock_store.py +46 -10
  204. rasa/core/nlg/generator.py +1 -1
  205. rasa/core/policies/flows/flow_executor.py +1 -1
  206. rasa/core/processor.py +32 -0
  207. rasa/core/redis_connection_factory.py +469 -0
  208. rasa/core/tracker_stores/redis_tracker_store.py +32 -14
  209. rasa/core/tracker_stores/sql_tracker_store.py +57 -1
  210. rasa/engine/graph.py +5 -1
  211. rasa/engine/loader.py +12 -0
  212. rasa/engine/storage/local_model_storage.py +41 -4
  213. rasa/model_manager/socket_bridge.py +1 -2
  214. rasa/model_manager/warm_rasa_process.py +13 -3
  215. rasa/shared/core/constants.py +1 -0
  216. rasa/shared/core/events.py +2 -0
  217. rasa/shared/core/flows/flow.py +1 -1
  218. rasa/shared/nlu/training_data/schemas/responses.yml +3 -0
  219. rasa/utils/pypred.py +38 -0
  220. rasa/validator.py +12 -8
  221. rasa/version.py +1 -1
  222. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/METADATA +19 -16
  223. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/RECORD +231 -266
  224. rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +0 -47
  225. rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +0 -40
  226. rasa/cli/project_templates/finance/actions/action_session_start.py +0 -74
  227. rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +0 -48
  228. rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +0 -36
  229. rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +0 -54
  230. rasa/cli/project_templates/finance/actions/database.py +0 -277
  231. rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +0 -52
  232. rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +0 -51
  233. rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +0 -40
  234. rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +0 -40
  235. rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +0 -46
  236. rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +0 -49
  237. rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +0 -19
  238. rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +0 -36
  239. rasa/cli/project_templates/finance/csvs/accounts.csv +0 -8
  240. rasa/cli/project_templates/finance/csvs/advisors.csv +0 -7
  241. rasa/cli/project_templates/finance/csvs/appointments.csv +0 -211
  242. rasa/cli/project_templates/finance/csvs/branches.csv +0 -10
  243. rasa/cli/project_templates/finance/csvs/cards.csv +0 -11
  244. rasa/cli/project_templates/finance/csvs/payees.csv +0 -11
  245. rasa/cli/project_templates/finance/csvs/transactions.csv +0 -71
  246. rasa/cli/project_templates/finance/csvs/users.csv +0 -4
  247. rasa/cli/project_templates/finance/data/cards/select_card.yml +0 -12
  248. rasa/cli/project_templates/finance/data/general/bot_identity.yml +0 -6
  249. rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +0 -5
  250. rasa/cli/project_templates/finance/data/system/source/accounts.json +0 -51
  251. rasa/cli/project_templates/finance/data/system/source/advisors.json +0 -44
  252. rasa/cli/project_templates/finance/data/system/source/appointments.json +0 -1474
  253. rasa/cli/project_templates/finance/data/system/source/branches.json +0 -47
  254. rasa/cli/project_templates/finance/data/system/source/cards.json +0 -72
  255. rasa/cli/project_templates/finance/data/system/source/payees.json +0 -74
  256. rasa/cli/project_templates/finance/data/system/source/transactions.json +0 -492
  257. rasa/cli/project_templates/finance/data/system/source/users.json +0 -29
  258. rasa/cli/project_templates/finance/data/transfers/add_payee.yml +0 -29
  259. rasa/cli/project_templates/finance/data/transfers/list_payees.yml +0 -5
  260. rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +0 -21
  261. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +0 -8
  262. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +0 -8
  263. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +0 -8
  264. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +0 -8
  265. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +0 -8
  266. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +0 -7
  267. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +0 -8
  268. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +0 -8
  269. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +0 -8
  270. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +0 -8
  271. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +0 -8
  272. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +0 -8
  273. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +0 -8
  274. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +0 -8
  275. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +0 -8
  276. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +0 -8
  277. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +0 -8
  278. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +0 -8
  279. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +0 -8
  280. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +0 -8
  281. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +0 -50
  282. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +0 -50
  283. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +0 -48
  284. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +0 -50
  285. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +0 -50
  286. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +0 -47
  287. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +0 -50
  288. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +0 -50
  289. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +0 -47
  290. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +0 -50
  291. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +0 -50
  292. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +0 -50
  293. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +0 -47
  294. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +0 -50
  295. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +0 -50
  296. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +0 -47
  297. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +0 -50
  298. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +0 -50
  299. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +0 -47
  300. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +0 -50
  301. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +0 -50
  302. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +0 -47
  303. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +0 -47
  304. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +0 -50
  305. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +0 -50
  306. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +0 -47
  307. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +0 -50
  308. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +0 -50
  309. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +0 -47
  310. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +0 -50
  311. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +0 -50
  312. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +0 -47
  313. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +0 -50
  314. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +0 -50
  315. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +0 -50
  316. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +0 -47
  317. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +0 -50
  318. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +0 -50
  319. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +0 -47
  320. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +0 -50
  321. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +0 -50
  322. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +0 -47
  323. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +0 -50
  324. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +0 -50
  325. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +0 -50
  326. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +0 -47
  327. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +0 -50
  328. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +0 -50
  329. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +0 -47
  330. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +0 -50
  331. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +0 -50
  332. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +0 -47
  333. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +0 -50
  334. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +0 -50
  335. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +0 -47
  336. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +0 -47
  337. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +0 -50
  338. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +0 -50
  339. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +0 -50
  340. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +0 -50
  341. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +0 -47
  342. rasa/cli/project_templates/finance/domain/cards/select_card.yml +0 -12
  343. rasa/cli/project_templates/finance/domain/general/assistant_details.yml +0 -12
  344. rasa/cli/project_templates/finance/domain/general/bot_identity.yml +0 -5
  345. rasa/cli/project_templates/finance/domain/general/defaults.yml +0 -24
  346. rasa/cli/project_templates/finance/domain/general/help.yml +0 -5
  347. rasa/cli/project_templates/finance/domain/general/utils.yml +0 -13
  348. rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +0 -47
  349. rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +0 -4
  350. rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +0 -16
  351. rasa/core/channels/inspector/dist/assets/channel-b9b536fc.js +0 -1
  352. rasa/core/channels/inspector/dist/assets/clone-78d2ddcf.js +0 -1
  353. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-8b09c060.js +0 -1
  354. /rasa/cli/project_templates/telco/domain/billing/{domain_undertand_bill.yml → understand_bill.yml} +0 -0
  355. /rasa/cli/project_templates/telco/domain/network/{domain_reboot_router.yml → reboot_router.yml} +0 -0
  356. /rasa/cli/project_templates/telco/domain/network/{domain_reset_router.yml → reset_router.yml} +0 -0
  357. /rasa/cli/project_templates/telco/domain/network/{domain_run_speed_test.yml → run_speed_test.yml} +0 -0
  358. /rasa/cli/project_templates/telco/domain/network/{domain_solve_internet_issue.yml → solve_internet_issue.yml} +0 -0
  359. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/NOTICE +0 -0
  360. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/WHEEL +0 -0
  361. {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 bool(self.username) ^ bool(self.password):
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
- self.red = redis.StrictRedis(**self.config.to_strict_redis())
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
@@ -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
+ )