rasa-pro 3.14.0.dev20250901__py3-none-any.whl → 3.14.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rasa-pro might be problematic. Click here for more details.

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