rasa-pro 3.13.1a19__py3-none-any.whl → 3.13.1a20__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 (275) hide show
  1. rasa/__main__.py +8 -0
  2. rasa/builder/auth.py +71 -0
  3. rasa/builder/config.py +16 -0
  4. rasa/builder/copilot/constants.py +15 -0
  5. rasa/builder/copilot/copilot.py +342 -0
  6. rasa/builder/copilot/copilot_response_handler.py +471 -0
  7. rasa/builder/copilot/exceptions.py +20 -0
  8. rasa/builder/copilot/models.py +344 -0
  9. rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +495 -0
  10. rasa/builder/copilot/telemetry.py +195 -0
  11. rasa/builder/document_retrieval/__init__.py +0 -0
  12. rasa/builder/document_retrieval/constants.py +16 -0
  13. rasa/builder/{inkeep_document_retrieval.py → document_retrieval/inkeep_document_retrieval.py} +24 -30
  14. rasa/builder/document_retrieval/models.py +62 -0
  15. rasa/builder/download.py +140 -0
  16. rasa/builder/guardrails/__init__.py +1 -0
  17. rasa/builder/guardrails/constants.py +4 -0
  18. rasa/builder/guardrails/exceptions.py +4 -0
  19. rasa/builder/guardrails/lakera.py +188 -0
  20. rasa/builder/guardrails/models.py +199 -0
  21. rasa/builder/guardrails/utils.py +305 -0
  22. rasa/builder/job_manager.py +87 -0
  23. rasa/builder/jobs.py +232 -0
  24. rasa/builder/llm_service.py +59 -7
  25. rasa/builder/logging_utils.py +162 -4
  26. rasa/builder/main.py +29 -16
  27. rasa/builder/models.py +90 -233
  28. rasa/builder/project_generator.py +91 -7
  29. rasa/builder/scrape_rasa_docs.py +1 -1
  30. rasa/builder/service.py +632 -440
  31. rasa/builder/shared/tracker_context.py +212 -0
  32. rasa/builder/validation_service.py +4 -4
  33. rasa/cli/data.py +8 -3
  34. rasa/cli/project_templates/basic/actions/action_api.py +15 -0
  35. rasa/cli/project_templates/basic/actions/action_human_handoff.py +44 -0
  36. rasa/cli/project_templates/basic/config.yml +23 -0
  37. rasa/cli/project_templates/{plain → basic}/credentials.yml +8 -7
  38. rasa/cli/project_templates/basic/data/general/feedback.yml +20 -0
  39. rasa/cli/project_templates/basic/data/general/goodbye.yml +6 -0
  40. rasa/cli/project_templates/basic/data/general/hello.yml +7 -0
  41. rasa/cli/project_templates/basic/data/general/help.yml +6 -0
  42. rasa/cli/project_templates/basic/data/general/human_handoff.yml +16 -0
  43. rasa/cli/project_templates/basic/data/general/welcome.yml +9 -0
  44. rasa/cli/project_templates/{finance/data/patterns → basic/data/system}/pattern_completed.yml +2 -1
  45. rasa/cli/project_templates/basic/data/system/pattern_correction.yml +7 -0
  46. rasa/cli/project_templates/basic/data/system/pattern_search.yml +8 -0
  47. rasa/cli/project_templates/basic/data/system/pattern_session_start.yml +8 -0
  48. rasa/cli/project_templates/basic/docs/rasa_assistant_qa.txt +65 -0
  49. rasa/cli/project_templates/basic/docs/template.txt +7 -0
  50. rasa/cli/project_templates/basic/domain/general/assistant_details.yml +12 -0
  51. rasa/cli/project_templates/basic/domain/general/bot_identity.yml +5 -0
  52. rasa/cli/project_templates/basic/domain/general/cannot_handle.yml +5 -0
  53. rasa/cli/project_templates/basic/domain/general/feedback.yml +28 -0
  54. rasa/cli/project_templates/basic/domain/general/goodbye.yml +7 -0
  55. rasa/cli/project_templates/basic/domain/general/help.yml +5 -0
  56. rasa/cli/project_templates/basic/domain/general/human_handoff_domain.yml +35 -0
  57. rasa/cli/project_templates/{finance/domain/default_actions.yml → basic/domain/general/utils.yml} +0 -3
  58. rasa/cli/project_templates/basic/domain/general/welcome.yml +7 -0
  59. rasa/cli/project_templates/{plain → basic}/endpoints.yml +42 -27
  60. rasa/cli/project_templates/basic/prompts/rephraser_demo_personality_prompt.jinja2 +19 -0
  61. rasa/cli/project_templates/defaults.py +25 -3
  62. rasa/cli/project_templates/finance/actions/__init__.py +46 -0
  63. rasa/cli/project_templates/finance/actions/accounts/__init__.py +0 -0
  64. rasa/cli/project_templates/finance/actions/{action_ask_account.py → accounts/action_ask_account.py} +6 -9
  65. rasa/cli/project_templates/finance/actions/{action_check_balance.py → accounts/action_check_balance.py} +4 -4
  66. rasa/cli/project_templates/finance/actions/action_session_start.py +11 -6
  67. rasa/cli/project_templates/finance/actions/cards/__init__.py +0 -0
  68. rasa/cli/project_templates/finance/actions/{action_ask_card.py → cards/action_ask_card.py} +4 -3
  69. rasa/cli/project_templates/finance/actions/{action_check_card_existence.py → cards/action_check_card_existence.py} +4 -3
  70. rasa/cli/project_templates/finance/actions/{action_update_card_status.py → cards/action_update_card_status.py} +18 -9
  71. rasa/cli/project_templates/finance/actions/database.py +1 -0
  72. rasa/cli/project_templates/finance/actions/transfers/__init__.py +0 -0
  73. rasa/cli/project_templates/finance/actions/{action_add_payee.py → transfers/action_add_payee.py} +8 -3
  74. rasa/cli/project_templates/finance/actions/{action_ask_account_from.py → transfers/action_ask_account_from.py} +5 -4
  75. rasa/cli/project_templates/finance/actions/{action_check_payee_existence.py → transfers/action_check_payee_existence.py} +3 -3
  76. rasa/cli/project_templates/finance/actions/{action_check_sufficient_funds.py → transfers/action_check_sufficient_funds.py} +3 -4
  77. rasa/cli/project_templates/finance/actions/{action_list_payees.py → transfers/action_list_payees.py} +4 -3
  78. rasa/cli/project_templates/finance/actions/{action_remove_payee.py → transfers/action_remove_payee.py} +4 -4
  79. rasa/cli/project_templates/finance/config.yml +8 -19
  80. rasa/cli/project_templates/finance/credentials.yml +6 -7
  81. rasa/cli/project_templates/finance/csvs/cards.csv +10 -10
  82. rasa/cli/project_templates/finance/csvs/payees.csv +10 -9
  83. rasa/cli/project_templates/finance/data/{flows → accounts}/check_balance.yml +2 -1
  84. rasa/cli/project_templates/finance/data/general/bot_identity.yml +6 -0
  85. rasa/cli/project_templates/finance/data/general/feedback.yml +20 -0
  86. rasa/cli/project_templates/finance/data/general/goodbye.yml +6 -0
  87. rasa/cli/project_templates/finance/data/general/hello.yml +7 -0
  88. rasa/cli/project_templates/finance/data/{flows/welcome.yml → general/help.yml} +2 -7
  89. rasa/cli/project_templates/finance/data/general/human_handoff.yml +16 -0
  90. rasa/cli/project_templates/finance/data/general/welcome.yml +9 -0
  91. rasa/cli/project_templates/finance/data/{patterns → system/patterns}/pattern_chitchat.yml +0 -2
  92. rasa/cli/project_templates/finance/data/system/patterns/pattern_completed.yml +7 -0
  93. rasa/cli/project_templates/finance/data/system/patterns/pattern_correction.yml +7 -0
  94. rasa/cli/project_templates/finance/data/system/patterns/pattern_search.yml +8 -0
  95. rasa/cli/project_templates/finance/data/{patterns → system/patterns}/pattern_session_start.yml +0 -1
  96. rasa/cli/project_templates/finance/domain/{check_balance.yml → accounts/check_balance.yml} +2 -0
  97. rasa/cli/project_templates/finance/domain/general/assistant_details.yml +12 -0
  98. rasa/cli/project_templates/finance/domain/general/bot_identity.yml +5 -0
  99. rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -0
  100. rasa/cli/project_templates/finance/domain/general/defaults.yml +24 -0
  101. rasa/cli/project_templates/finance/domain/general/feedback.yml +28 -0
  102. rasa/cli/project_templates/finance/domain/general/goodbye.yml +7 -0
  103. rasa/cli/project_templates/finance/domain/general/help.yml +5 -0
  104. rasa/cli/project_templates/finance/domain/general/human_handoff.yml +30 -0
  105. rasa/cli/project_templates/finance/domain/general/utils.yml +13 -0
  106. rasa/cli/project_templates/finance/domain/general/welcome.yml +8 -0
  107. rasa/cli/project_templates/finance/endpoints.yml +1 -0
  108. rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +3 -3
  109. rasa/cli/project_templates/telco/actions/actions_billing.py +24 -17
  110. rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py +6 -1
  111. rasa/cli/project_templates/telco/actions/actions_run_diagnostics.py +6 -1
  112. rasa/cli/project_templates/telco/actions/actions_session_start.py +6 -1
  113. rasa/cli/project_templates/tutorial/config.yml +2 -1
  114. rasa/cli/scaffold.py +27 -2
  115. rasa/cli/train.py +8 -0
  116. rasa/cli/utils.py +31 -15
  117. rasa/core/actions/action.py +28 -41
  118. rasa/core/actions/action_run_slot_rejections.py +1 -1
  119. rasa/core/channels/development_inspector.py +47 -14
  120. rasa/core/channels/inspector/dist/assets/{arc-371401b1.js → arc-1ddec37b.js} +1 -1
  121. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-3f126156.js → blockDiagram-38ab4fdb-18af387c.js} +1 -1
  122. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-12f22eb7.js → c4Diagram-3d4e48cf-250127a3.js} +1 -1
  123. rasa/core/channels/inspector/dist/assets/channel-59f6d54b.js +1 -0
  124. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-03b1d386.js → classDiagram-70f12bd4-c3388b34.js} +1 -1
  125. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-84f69d63.js → classDiagram-v2-f2320105-9c893a82.js} +1 -1
  126. rasa/core/channels/inspector/dist/assets/clone-26177ddb.js +1 -0
  127. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-ca47fd38.js → createText-2e5e7dd3-c111213b.js} +1 -1
  128. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-f837ca8a.js → edges-e0da2a9e-812a729d.js} +1 -1
  129. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-8717ac54.js → erDiagram-9861fffd-fd5051bc.js} +1 -1
  130. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-94f38b83.js → flowDb-956e92f1-3287ac02.js} +1 -1
  131. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-b616f9fb.js → flowDiagram-66a62f08-692fb0b2.js} +1 -1
  132. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-29c03f5a.js +1 -0
  133. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-f5d24bb8.js → flowchart-elk-definition-4a651766-008376f1.js} +1 -1
  134. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-b43ba8d9.js → ganttDiagram-c361ad54-df330a69.js} +1 -1
  135. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-c3aafaa5.js → gitGraphDiagram-72cf32ee-e03676fb.js} +1 -1
  136. rasa/core/channels/inspector/dist/assets/{graph-0d0a2c10.js → graph-46fad2ba.js} +1 -1
  137. rasa/core/channels/inspector/dist/assets/{index-3862675e-58ea0305.js → index-3862675e-a484ac55.js} +1 -1
  138. rasa/core/channels/inspector/dist/assets/{index-cce6f8a1.js → index-a003633f.js} +179 -179
  139. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b8f60461.js → infoDiagram-f8f76790-3f9e6ec2.js} +1 -1
  140. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-95be5545.js → journeyDiagram-49397b02-79f72383.js} +1 -1
  141. rasa/core/channels/inspector/dist/assets/{layout-da885b9b.js → layout-aad098e5.js} +1 -1
  142. rasa/core/channels/inspector/dist/assets/{line-f1c817d3.js → line-219ab7ae.js} +1 -1
  143. rasa/core/channels/inspector/dist/assets/{linear-d42801e6.js → linear-2cddbe62.js} +1 -1
  144. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-a38923a6.js → mindmap-definition-fc14e90a-1d41ed99.js} +1 -1
  145. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-ca6e71e9.js → pieDiagram-8a3498a8-cc496ee8.js} +1 -1
  146. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-b290dae9.js → quadrantDiagram-120e2f19-84d32884.js} +1 -1
  147. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-03f02ceb.js → requirementDiagram-deff3bca-c0deb984.js} +1 -1
  148. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-c49eee40.js → sankeyDiagram-04a897e0-b9d7fd62.js} +1 -1
  149. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-b2cd6a3d.js → sequenceDiagram-704730f1-7d517565.js} +1 -1
  150. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-e53a2028.js → stateDiagram-587899a1-98ef9b27.js} +1 -1
  151. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-e1982a03.js → stateDiagram-v2-d93cdb3a-cee70748.js} +1 -1
  152. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-d0226ca5.js → styles-6aaf32cf-3f9d1c96.js} +1 -1
  153. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-0e21dc00.js → styles-9a916d00-67471923.js} +1 -1
  154. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-9588494e.js → styles-c10674c1-bd093fb7.js} +1 -1
  155. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-be478d4f.js → svgDrawCommon-08f97a94-675794e8.js} +1 -1
  156. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-74631749.js → timeline-definition-85554ec2-0ac67617.js} +1 -1
  157. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-a043552f.js → xychartDiagram-e933f94c-c018dc37.js} +1 -1
  158. rasa/core/channels/inspector/dist/index.html +2 -2
  159. rasa/core/channels/inspector/index.html +1 -1
  160. rasa/core/channels/inspector/package.json +4 -3
  161. rasa/core/channels/inspector/src/App.tsx +53 -7
  162. rasa/core/channels/inspector/src/components/Chat.tsx +3 -2
  163. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +1 -1
  164. rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +268 -0
  165. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +6 -2
  166. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +8 -3
  167. rasa/core/channels/inspector/src/types.ts +8 -0
  168. rasa/core/channels/inspector/yarn.lock +12 -12
  169. rasa/core/channels/studio_chat.py +119 -34
  170. rasa/core/channels/voice_ready/twilio_voice.py +1 -1
  171. rasa/core/channels/voice_stream/asr/asr_engine.py +5 -1
  172. rasa/core/channels/voice_stream/asr/deepgram.py +5 -0
  173. rasa/core/channels/voice_stream/audiocodes.py +16 -8
  174. rasa/core/channels/voice_stream/browser_audio.py +39 -4
  175. rasa/core/channels/voice_stream/call_state.py +13 -2
  176. rasa/core/channels/voice_stream/genesys.py +16 -13
  177. rasa/core/channels/voice_stream/jambonz.py +14 -12
  178. rasa/core/channels/voice_stream/twilio_media_streams.py +14 -13
  179. rasa/core/channels/voice_stream/util.py +11 -1
  180. rasa/core/channels/voice_stream/voice_channel.py +108 -29
  181. rasa/core/nlg/callback.py +1 -1
  182. rasa/core/nlg/contextual_response_rephraser.py +19 -9
  183. rasa/core/nlg/generator.py +21 -5
  184. rasa/core/nlg/response.py +43 -6
  185. rasa/core/nlg/translate.py +8 -0
  186. rasa/core/policies/enterprise_search_policy.py +16 -21
  187. rasa/dialogue_understanding/commands/correct_slots_command.py +38 -10
  188. rasa/dialogue_understanding/generator/command_generator.py +5 -5
  189. rasa/dialogue_understanding/generator/command_parser.py +9 -13
  190. rasa/dialogue_understanding/processor/command_processor.py +149 -55
  191. rasa/dialogue_understanding/stack/utils.py +13 -3
  192. rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
  193. rasa/dialogue_understanding_test/validation.py +9 -10
  194. rasa/e2e_test/e2e_config.py +18 -11
  195. rasa/e2e_test/e2e_test_schema.yml +3 -3
  196. rasa/e2e_test/utils/validation.py +17 -19
  197. rasa/engine/validation.py +86 -91
  198. rasa/exceptions.py +26 -1
  199. rasa/model_manager/model_api.py +2 -2
  200. rasa/model_manager/socket_bridge.py +8 -2
  201. rasa/shared/providers/_configs/default_litellm_client_config.py +3 -7
  202. rasa/shared/utils/cli.py +2 -0
  203. rasa/shared/utils/common.py +2 -1
  204. rasa/shared/utils/health_check/health_check.py +10 -14
  205. rasa/studio/upload.py +6 -2
  206. rasa/studio/utils.py +33 -22
  207. rasa/telemetry.py +95 -22
  208. rasa/utils/licensing.py +21 -10
  209. rasa/utils/log_utils.py +1 -1
  210. rasa/utils/tensorflow/transformer.py +3 -3
  211. rasa/validator.py +7 -5
  212. rasa/version.py +1 -1
  213. {rasa_pro-3.13.1a19.dist-info → rasa_pro-3.13.1a20.dist-info}/METADATA +7 -7
  214. {rasa_pro-3.13.1a19.dist-info → rasa_pro-3.13.1a20.dist-info}/RECORD +242 -205
  215. rasa/builder/constants.py +0 -4
  216. rasa/builder/copilot-llm-structured-output-response-schema.json +0 -69
  217. rasa/builder/copilot.py +0 -233
  218. rasa/builder/copilot_system_prompt.jinja2 +0 -245
  219. rasa/builder/create_openai_vector_store.py +0 -228
  220. rasa/builder/llm_context.py +0 -81
  221. rasa/cli/project_templates/finance/data/nlu.yml +0 -29
  222. rasa/cli/project_templates/finance/data/patterns/pattern_search.yml +0 -5
  223. rasa/cli/project_templates/finance/domain/default_flows.yml +0 -33
  224. rasa/cli/project_templates/finance/prompts/command-generator.jinja2 +0 -57
  225. rasa/cli/project_templates/finance/tests/conversation_repair/cancellations.yml +0 -12
  226. rasa/cli/project_templates/finance/tests/conversation_repair/cannot_handle.yml +0 -7
  227. rasa/cli/project_templates/finance/tests/conversation_repair/chitchat.yml +0 -7
  228. rasa/cli/project_templates/finance/tests/conversation_repair/clarification.yml +0 -9
  229. rasa/cli/project_templates/finance/tests/conversation_repair/completion.yml +0 -18
  230. rasa/cli/project_templates/finance/tests/conversation_repair/corrections.yml +0 -17
  231. rasa/cli/project_templates/finance/tests/conversation_repair/digressions.yml +0 -32
  232. rasa/cli/project_templates/finance/tests/conversation_repair/human_handoff.yml +0 -21
  233. rasa/cli/project_templates/finance/tests/conversation_repair/skipping_collect_steps.yml +0 -16
  234. rasa/cli/project_templates/finance/tests/demo_scripts/main.yml +0 -16
  235. rasa/cli/project_templates/finance/tests/happy_paths/balance_verification.yml +0 -15
  236. rasa/cli/project_templates/finance/tests/happy_paths/banking_questions.yml +0 -12
  237. rasa/cli/project_templates/finance/tests/happy_paths/card_blocking.yml +0 -52
  238. rasa/cli/project_templates/finance/tests/happy_paths/money_transfer.yml +0 -136
  239. rasa/cli/project_templates/finance/tests/happy_paths/payee_management.yml +0 -27
  240. rasa/cli/project_templates/finance/tests/happy_paths/user_greeted.yml +0 -5
  241. rasa/cli/project_templates/plain/config.yml +0 -17
  242. rasa/cli/project_templates/plain/data/patterns/pattern_session_start.yml +0 -7
  243. rasa/cli/project_templates/plain/domain.yml +0 -5
  244. rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +0 -1
  245. rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +0 -1
  246. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +0 -1
  247. rasa/shared/importers/static.py +0 -63
  248. /rasa/{cli/project_templates/plain/actions → builder/copilot}/__init__.py +0 -0
  249. /rasa/builder/{inkeep-rag-response-schema.json → document_retrieval/inkeep-rag-response-schema.json} +0 -0
  250. /rasa/cli/project_templates/finance/actions/{action_process_immediate_payment.py → transfers/action_process_immediate_payment.py} +0 -0
  251. /rasa/cli/project_templates/finance/actions/{action_schedule_payment.py → transfers/action_schedule_payment.py} +0 -0
  252. /rasa/cli/project_templates/finance/actions/{action_validate_payment_date.py → transfers/action_validate_payment_date.py} +0 -0
  253. /rasa/cli/project_templates/finance/data/{flows → cards}/block_card.yml +0 -0
  254. /rasa/cli/project_templates/finance/data/{flows → cards}/select_card.yml +0 -0
  255. /rasa/cli/project_templates/finance/data/{source → system/source}/accounts.json +0 -0
  256. /rasa/cli/project_templates/finance/data/{source → system/source}/advisors.json +0 -0
  257. /rasa/cli/project_templates/finance/data/{source → system/source}/appointments.json +0 -0
  258. /rasa/cli/project_templates/finance/data/{source → system/source}/branches.json +0 -0
  259. /rasa/cli/project_templates/finance/data/{source → system/source}/cards.json +0 -0
  260. /rasa/cli/project_templates/finance/data/{source → system/source}/payees.json +0 -0
  261. /rasa/cli/project_templates/finance/data/{source → system/source}/transactions.json +0 -0
  262. /rasa/cli/project_templates/finance/data/{source → system/source}/users.json +0 -0
  263. /rasa/cli/project_templates/finance/data/{flows → transfers}/add_payee.yml +0 -0
  264. /rasa/cli/project_templates/finance/data/{flows → transfers}/list_payees.yml +0 -0
  265. /rasa/cli/project_templates/finance/data/{flows → transfers}/remove_payee.yml +0 -0
  266. /rasa/cli/project_templates/finance/data/{flows → transfers}/transfer_money.yml +0 -0
  267. /rasa/cli/project_templates/finance/domain/{block_card.yml → cards/block_card.yml} +0 -0
  268. /rasa/cli/project_templates/finance/domain/{select_card.yml → cards/select_card.yml} +0 -0
  269. /rasa/cli/project_templates/finance/domain/{add_payee.yml → transfers/add_payee.yml} +0 -0
  270. /rasa/cli/project_templates/finance/domain/{list_payees.yml → transfers/list_payees.yml} +0 -0
  271. /rasa/cli/project_templates/finance/domain/{remove_payee.yml → transfers/remove_payee.yml} +0 -0
  272. /rasa/cli/project_templates/finance/domain/{transfer_money.yml → transfers/transfer_money.yml} +0 -0
  273. {rasa_pro-3.13.1a19.dist-info → rasa_pro-3.13.1a20.dist-info}/NOTICE +0 -0
  274. {rasa_pro-3.13.1a19.dist-info → rasa_pro-3.13.1a20.dist-info}/WHEEL +0 -0
  275. {rasa_pro-3.13.1a19.dist-info → rasa_pro-3.13.1a20.dist-info}/entry_points.txt +0 -0
rasa/builder/jobs.py ADDED
@@ -0,0 +1,232 @@
1
+ from typing import Any, Optional
2
+
3
+ import structlog
4
+ from sanic import Sanic
5
+
6
+ from rasa.builder.exceptions import (
7
+ LLMGenerationError,
8
+ ProjectGenerationError,
9
+ TrainingError,
10
+ ValidationError,
11
+ )
12
+ from rasa.builder.job_manager import JobInfo, job_manager
13
+ from rasa.builder.models import (
14
+ JobStatus,
15
+ JobStatusEvent,
16
+ )
17
+ from rasa.builder.training_service import train_and_load_agent
18
+ from rasa.builder.validation_service import validate_project
19
+ from rasa.cli.scaffold import ProjectTemplateName
20
+
21
+ structlogger = structlog.get_logger()
22
+
23
+
24
+ async def push_job_status_event(
25
+ job: JobInfo, status: JobStatus, message: Optional[str] = None
26
+ ) -> None:
27
+ event = JobStatusEvent.from_status(status=status.value, message=message)
28
+ job.status = status.value
29
+ await job.put(event)
30
+
31
+
32
+ async def run_prompt_to_bot_job(
33
+ app: Any,
34
+ job: JobInfo,
35
+ prompt: str,
36
+ ) -> None:
37
+ """Run the prompt-to-bot job in the background.
38
+
39
+ Args:
40
+ app: The Sanic application instance.
41
+ job: The job information instance.
42
+ prompt: The natural language prompt for bot generation.
43
+ """
44
+ project_generator = app.ctx.project_generator
45
+ input_channel = app.ctx.input_channel
46
+ await push_job_status_event(job, JobStatus.received)
47
+
48
+ try:
49
+ # 1. Generating
50
+ await push_job_status_event(job, JobStatus.generating)
51
+ bot_files = await project_generator.generate_project_with_retries(
52
+ prompt,
53
+ template=ProjectTemplateName.BASIC,
54
+ )
55
+ await push_job_status_event(job, JobStatus.generation_success)
56
+
57
+ # 2. Training
58
+ await push_job_status_event(job, JobStatus.training)
59
+ importer = project_generator._create_importer()
60
+ app.ctx.agent = await train_and_load_agent(importer)
61
+ input_channel.agent = app.ctx.agent
62
+ await push_job_status_event(job, JobStatus.train_success)
63
+
64
+ structlogger.info(
65
+ "bot_builder_service.prompt_to_bot.success",
66
+ files_generated=list(bot_files.keys()),
67
+ )
68
+ await push_job_status_event(job, JobStatus.done)
69
+ job_manager.mark_done(job)
70
+
71
+ except TrainingError as exc:
72
+ structlogger.debug(
73
+ "prompt_to_bot_job.training_error", job_id=job.id, error=str(exc)
74
+ )
75
+ await push_job_status_event(job, JobStatus.train_error, message=str(exc))
76
+ job_manager.mark_done(job, error=str(exc))
77
+
78
+ except ValidationError as exc:
79
+ structlogger.debug(
80
+ "prompt_to_bot_job.validation_error", job_id=job.id, error=str(exc)
81
+ )
82
+ await push_job_status_event(job, JobStatus.validation_error, message=str(exc))
83
+ job_manager.mark_done(job, error=str(exc))
84
+
85
+ except (ProjectGenerationError, LLMGenerationError) as exc:
86
+ structlogger.debug(
87
+ "prompt_to_bot_job.generation_error", job_id=job.id, error=str(exc)
88
+ )
89
+ await push_job_status_event(job, JobStatus.generation_error, message=str(exc))
90
+ job_manager.mark_done(job, error=str(exc))
91
+
92
+ except Exception as exc:
93
+ # Capture full traceback
94
+ structlogger.exception(
95
+ "prompt_to_bot_job.unexpected_error", job_id=job.id, error=str(exc)
96
+ )
97
+ await push_job_status_event(job, JobStatus.error, message=str(exc))
98
+ job_manager.mark_done(job, error=str(exc))
99
+
100
+
101
+ async def run_template_to_bot_job(
102
+ app: "Sanic",
103
+ job: JobInfo,
104
+ template_name: ProjectTemplateName,
105
+ ) -> None:
106
+ """Run the template-to-bot job in the background.
107
+
108
+ Args:
109
+ app: The Sanic application instance.
110
+ job: The job information instance.
111
+ template_name: The name of the template to use for bot generation.
112
+ """
113
+ project_generator = app.ctx.project_generator
114
+ input_channel = app.ctx.input_channel
115
+ await push_job_status_event(job, JobStatus.received)
116
+
117
+ try:
118
+ # 1) Generating
119
+ await push_job_status_event(job, JobStatus.generating)
120
+ await project_generator.init_from_template(template_name)
121
+ bot_files = project_generator.get_bot_files()
122
+ await push_job_status_event(job, JobStatus.generation_success)
123
+
124
+ # 2) Training
125
+ await push_job_status_event(job, JobStatus.training)
126
+ importer = project_generator._create_importer()
127
+ app.ctx.agent = await train_and_load_agent(importer)
128
+ input_channel.agent = app.ctx.agent
129
+ await push_job_status_event(job, JobStatus.train_success)
130
+
131
+ # 3) Done
132
+ structlogger.info(
133
+ "bot_builder_service.template_to_bot.success",
134
+ files_generated=list(bot_files.keys()),
135
+ )
136
+ await push_job_status_event(job, JobStatus.done)
137
+ job_manager.mark_done(job)
138
+
139
+ except TrainingError as exc:
140
+ structlogger.debug(
141
+ "template_to_bot_job.training_error",
142
+ job_id=job.id,
143
+ error=str(exc),
144
+ )
145
+ await push_job_status_event(job, JobStatus.train_error, message=str(exc))
146
+ job_manager.mark_done(job, error=str(exc))
147
+
148
+ except ValidationError as exc:
149
+ structlogger.debug(
150
+ "template_to_bot_job.validation_error",
151
+ job_id=job.id,
152
+ error=str(exc),
153
+ )
154
+ await push_job_status_event(job, JobStatus.validation_error, message=str(exc))
155
+ job_manager.mark_done(job, error=str(exc))
156
+
157
+ except ProjectGenerationError as exc:
158
+ structlogger.debug(
159
+ "template_to_bot_job.generation_error",
160
+ job_id=job.id,
161
+ error=str(exc),
162
+ )
163
+ await push_job_status_event(job, JobStatus.generation_error, message=str(exc))
164
+ job_manager.mark_done(job, error=str(exc))
165
+
166
+ except Exception as exc:
167
+ # Capture full traceback
168
+ structlogger.exception(
169
+ "template_to_bot_job.unexpected_error",
170
+ job_id=job.id,
171
+ error=str(exc),
172
+ )
173
+ await push_job_status_event(job, JobStatus.error, message=str(exc))
174
+ job_manager.mark_done(job, error=str(exc))
175
+
176
+
177
+ async def run_update_files_job(
178
+ app: "Sanic",
179
+ job: JobInfo,
180
+ bot_files: dict,
181
+ ) -> None:
182
+ project_generator = app.ctx.project_generator
183
+ input_channel = app.ctx.input_channel
184
+ await push_job_status_event(job, JobStatus.received)
185
+
186
+ try:
187
+ project_generator.update_bot_files(bot_files)
188
+
189
+ # 1. Validating
190
+ await push_job_status_event(job, JobStatus.validating)
191
+ importer = project_generator._create_importer()
192
+ validation_error = await validate_project(importer)
193
+ if validation_error:
194
+ raise ValidationError(validation_error)
195
+ await push_job_status_event(job, JobStatus.validation_success)
196
+
197
+ # 2. Training
198
+ await push_job_status_event(job, JobStatus.training)
199
+ app.ctx.agent = await train_and_load_agent(importer)
200
+ input_channel.agent = app.ctx.agent
201
+ await push_job_status_event(job, JobStatus.train_success)
202
+
203
+ await push_job_status_event(job, JobStatus.done)
204
+ job_manager.mark_done(job)
205
+
206
+ except ValidationError as exc:
207
+ structlogger.debug(
208
+ "update_files_job.validation_error",
209
+ job_id=job.id,
210
+ error=str(exc),
211
+ )
212
+ await push_job_status_event(job, JobStatus.validation_error, message=str(exc))
213
+ job_manager.mark_done(job, error=str(exc))
214
+
215
+ except TrainingError as exc:
216
+ structlogger.debug(
217
+ "update_files_job.train_error",
218
+ job_id=job.id,
219
+ error=str(exc),
220
+ )
221
+ await push_job_status_event(job, JobStatus.train_error, message=str(exc))
222
+ job_manager.mark_done(job, error=str(exc))
223
+
224
+ except Exception as exc:
225
+ # Capture full traceback for anything truly unexpected
226
+ structlogger.exception(
227
+ "update_files_job.unexpected_error",
228
+ job_id=job.id,
229
+ error=str(exc),
230
+ )
231
+ await push_job_status_event(job, JobStatus.error, message=str(exc))
232
+ job_manager.mark_done(job, error=str(exc))
@@ -13,8 +13,10 @@ import structlog
13
13
  from jinja2 import Template
14
14
 
15
15
  from rasa.builder import config
16
- from rasa.builder.copilot import Copilot
16
+ from rasa.builder.copilot.copilot import Copilot
17
+ from rasa.builder.copilot.copilot_response_handler import CopilotResponseHandler
17
18
  from rasa.builder.exceptions import LLMGenerationError
19
+ from rasa.builder.guardrails.lakera import LakeraAIGuardrails
18
20
  from rasa.constants import PACKAGE_NAME
19
21
  from rasa.shared.constants import DOMAIN_SCHEMA_FILE, RESPONSES_SCHEMA_FILE
20
22
  from rasa.shared.core.flows.yaml_flows_io import FLOWS_SCHEMA_FILE
@@ -31,10 +33,12 @@ class LLMService:
31
33
  self._client: Optional[openai.AsyncOpenAI] = None
32
34
  self._domain_schema: Optional[Dict[str, Any]] = None
33
35
  self._flows_schema: Optional[Dict[str, Any]] = None
34
- self._copilot = None
36
+ self._copilot: Optional[Copilot] = None
37
+ self._guardrails: Optional[LakeraAIGuardrails] = None
38
+ self._copilot_response_handler: Optional[CopilotResponseHandler] = None
35
39
 
36
40
  @property
37
- def copilot(self):
41
+ def copilot(self) -> Copilot:
38
42
  """Get or lazy create copilot instance."""
39
43
  if self._copilot is None:
40
44
  self._copilot = Copilot()
@@ -49,6 +53,52 @@ class LLMService:
49
53
  )
50
54
  raise
51
55
 
56
+ @property
57
+ def copilot_response_handler(self) -> CopilotResponseHandler:
58
+ """Get or lazy create copilot response handler instance."""
59
+ if self._copilot_response_handler is None:
60
+ self._copilot_response_handler = CopilotResponseHandler(
61
+ rolling_buffer_size=config.COPILOT_HANDLER_ROLLING_BUFFER_SIZE,
62
+ )
63
+ try:
64
+ return self._copilot_response_handler
65
+ except Exception as e:
66
+ structlogger.error(
67
+ "llm_service.copilot_response_handler.error",
68
+ event_info=(
69
+ "LLM Service: Error getting copilot response handler instance."
70
+ ),
71
+ error=str(e),
72
+ )
73
+ raise
74
+
75
+ @property
76
+ def guardrails(self) -> LakeraAIGuardrails:
77
+ """Get or lazy create guardrails instance."""
78
+ if self._guardrails is None:
79
+ self._guardrails = LakeraAIGuardrails()
80
+ try:
81
+ return self._guardrails
82
+ except Exception as e:
83
+ structlogger.error(
84
+ "llm_service.guardrails.error",
85
+ event_info="LLM Service: Error getting guardrails instance.",
86
+ error=str(e),
87
+ )
88
+ raise
89
+
90
+ @staticmethod
91
+ def instantiate_copilot() -> Copilot:
92
+ """Instantiate a new Copilot instance."""
93
+ return Copilot()
94
+
95
+ @staticmethod
96
+ def instantiate_handler(rolling_buffer_size: int) -> CopilotResponseHandler:
97
+ """Instantiate a new CopilotResponseHandler instance."""
98
+ return CopilotResponseHandler(
99
+ rolling_buffer_size=rolling_buffer_size,
100
+ )
101
+
52
102
  @asynccontextmanager
53
103
  async def _get_client(self) -> AsyncGenerator[openai.AsyncOpenAI, None]:
54
104
  """Get or create OpenAI client with proper resource management."""
@@ -91,7 +141,7 @@ class LLMService:
91
141
  },
92
142
  },
93
143
  }
94
- response = await client.chat.completions.create(
144
+ response = await client.chat.completions.create( # type: ignore
95
145
  model=config.OPENAI_MODEL,
96
146
  messages=messages,
97
147
  temperature=config.OPENAI_TEMPERATURE,
@@ -135,9 +185,11 @@ def _prepare_domain_schema() -> Dict[str, Any]:
135
185
  slot_mapping.pop("validation", None)
136
186
 
137
187
  # Add responses schema
138
- domain_schema["mapping"]["responses"] = read_schema_file(
139
- RESPONSES_SCHEMA_FILE, PACKAGE_NAME, False
140
- )["schema;responses"]
188
+ responses_schema = read_schema_file(RESPONSES_SCHEMA_FILE, PACKAGE_NAME, False)
189
+ if isinstance(responses_schema, dict):
190
+ domain_schema["mapping"]["responses"] = responses_schema["schema;responses"]
191
+ else:
192
+ raise ValueError("Expected responses schema to be a dictionary.")
141
193
 
142
194
  return domain_schema
143
195
 
@@ -1,11 +1,20 @@
1
- """Logging utilities for the prompt-to-bot service."""
1
+ """Logging and Sentry utilities for the builder service."""
2
2
 
3
3
  import collections
4
4
  import logging
5
5
  import threading
6
- from typing import Any, Deque, Dict
6
+ import time
7
+ import uuid
8
+ from typing import Any, Deque, Dict, Mapping, MutableMapping, Optional
9
+
10
+ import sentry_sdk
11
+ import structlog
12
+ from sanic import Request
7
13
 
8
14
  from rasa.builder import config
15
+ from rasa.builder.auth import HEADER_USER_ID
16
+
17
+ structlogger = structlog.get_logger()
9
18
 
10
19
  # Thread-safe deque for collecting recent logs
11
20
  _recent_logs: Deque[str] = collections.deque(maxlen=config.MAX_LOG_ENTRIES)
@@ -13,8 +22,8 @@ _logs_lock = threading.RLock()
13
22
 
14
23
 
15
24
  def collecting_logs_processor(
16
- logger: Any, log_level: str, event_dict: Dict[str, Any]
17
- ) -> Dict[str, Any]:
25
+ logger: Any, log_level: str, event_dict: MutableMapping[str, Any]
26
+ ) -> MutableMapping[str, Any]:
18
27
  """Structlog processor that collects recent log entries.
19
28
 
20
29
  This processor is thread-safe and maintains a rolling buffer of recent logs.
@@ -29,6 +38,22 @@ def collecting_logs_processor(
29
38
  return event_dict
30
39
 
31
40
 
41
+ def attach_request_id_processor(
42
+ logger: Any, log_level: str, event_dict: MutableMapping[str, Any]
43
+ ) -> MutableMapping[str, Any]:
44
+ """Structlog processor that attaches the request id to the event dict.
45
+
46
+ This processor is thread-safe and maintains a rolling buffer of recent logs.
47
+ """
48
+ try:
49
+ request = Request.get_current()
50
+ event_dict["correlation_id"] = request.ctx.correlation_id
51
+ return event_dict
52
+ except Exception:
53
+ # there is no request context, so we don't attach the request id
54
+ return event_dict
55
+
56
+
32
57
  def get_recent_logs() -> str:
33
58
  """Get recent log entries as a formatted string.
34
59
 
@@ -49,3 +74,136 @@ def get_log_count() -> int:
49
74
  """Get the current number of log entries."""
50
75
  with _logs_lock:
51
76
  return len(_recent_logs)
77
+
78
+
79
+ def _sanitize_headers(headers: Mapping[str, str]) -> Dict[str, Any]:
80
+ """Remove or redact sensitive headers for safe logging and Sentry context."""
81
+ lowered = {k.lower(): v for k, v in headers.items()}
82
+ result: Dict[str, Any] = {}
83
+ # Safe keepers
84
+ if "user-agent" in lowered:
85
+ result["user-agent"] = lowered["user-agent"]
86
+ if HEADER_USER_ID in lowered:
87
+ result[HEADER_USER_ID] = lowered[HEADER_USER_ID]
88
+ # Redact auth info
89
+ if "authorization" in lowered:
90
+ auth_val = lowered["authorization"]
91
+ # Keep only the scheme if present
92
+ scheme = auth_val.split(" ")[0] if auth_val else ""
93
+ result["authorization"] = f"{scheme} <redacted>" if scheme else "present"
94
+ return result
95
+
96
+
97
+ def ensure_correlation_id_on_request(request: Any) -> str:
98
+ """Ensure a correlation id exists on the request and return it."""
99
+ if not hasattr(request.ctx, "correlation_id") or not request.ctx.correlation_id:
100
+ request.ctx.correlation_id = uuid.uuid4().hex
101
+ return request.ctx.correlation_id
102
+
103
+
104
+ def extract_request_context() -> Dict[str, Any]:
105
+ """Extract safe request context for logging / Sentry."""
106
+ try:
107
+ request = Request.get_current()
108
+ headers = getattr(request, "headers", {}) or {}
109
+ args = getattr(request, "args", {}) or {}
110
+ json_body = getattr(request, "json", None)
111
+ content_length = getattr(request, "content_length", None)
112
+ ctx: Dict[str, Any] = {
113
+ "method": getattr(request, "method", None),
114
+ "path": getattr(request, "path", None),
115
+ "query_args": dict(args) if hasattr(args, "items") else args,
116
+ "remote_addr": getattr(request, "remote_addr", None),
117
+ "content_length": content_length,
118
+ "has_json": json_body is not None,
119
+ "headers": _sanitize_headers(dict(headers)),
120
+ }
121
+ if hasattr(request, "ctx"):
122
+ ctx["correlation_id"] = ensure_correlation_id_on_request(request)
123
+ # Common custom fields if present
124
+ ctx["user_id"] = request.headers.get(HEADER_USER_ID)
125
+ return ctx
126
+ except Exception:
127
+ return {}
128
+
129
+
130
+ def capture_exception_with_context(
131
+ exc: BaseException,
132
+ event_id: str,
133
+ extra: Optional[Dict[str, Any]] = None,
134
+ tags: Optional[Dict[str, str]] = None,
135
+ ) -> None:
136
+ """Capture exception in Sentry and log it with rich context.
137
+
138
+ Args:
139
+ request: Sanic request
140
+ exc: exception instance
141
+ event_id: structlog event id
142
+ extra: additional context to include
143
+ tags: sentry tags to attach
144
+ """
145
+ request_ctx = extract_request_context()
146
+ if extra is None:
147
+ extra = {}
148
+ # Sentry scope
149
+ try:
150
+ with sentry_sdk.configure_scope() as scope:
151
+ scope.set_tag("service", "bot-builder")
152
+ if tags:
153
+ for k, v in tags.items():
154
+ scope.set_tag(k, v)
155
+ # Flatten some useful fields as tags
156
+ if request_ctx.get("path"):
157
+ scope.set_tag("route", request_ctx["path"])
158
+ if request_ctx.get("method"):
159
+ scope.set_tag("method", request_ctx["method"])
160
+ if request_ctx.get("correlation_id"):
161
+ scope.set_tag("correlation_id", request_ctx["correlation_id"])
162
+ user_id = request_ctx.get("user_id")
163
+ if user_id and hasattr(scope, "set_user"):
164
+ scope.set_user({"id": str(user_id)})
165
+ # Context blocks
166
+ scope.set_context("request", request_ctx)
167
+ if extra:
168
+ scope.set_context("extra", extra)
169
+ sentry_sdk.capture_exception(exc)
170
+ except Exception:
171
+ # Never fail the app because Sentry failed
172
+ pass
173
+
174
+ # Structlog error with merged context (avoid dumping huge payloads)
175
+ structlogger.error(
176
+ event_id,
177
+ error=str(exc),
178
+ **{k: v for k, v in {**request_ctx, **extra}.items() if k not in {"headers"}},
179
+ )
180
+
181
+
182
+ def log_request_start(request: Any) -> float:
183
+ """Log request start and return start time."""
184
+ start = time.perf_counter()
185
+ cid = ensure_correlation_id_on_request(request)
186
+ ctx = extract_request_context()
187
+ structlogger.info(
188
+ "request.received",
189
+ method=ctx.get("method"),
190
+ path=ctx.get("path"),
191
+ remote_addr=ctx.get("remote_addr") or "unknown",
192
+ correlation_id=cid,
193
+ user_id=ctx.get("user_id"),
194
+ )
195
+ return start
196
+
197
+
198
+ def log_request_end(request: Any, response: Any, start: float) -> None:
199
+ """Log request completion with latency and correlation id."""
200
+ latency_ms = int((time.perf_counter() - start) * 1000)
201
+ cid = ensure_correlation_id_on_request(request)
202
+ structlogger.info(
203
+ "request.completed",
204
+ method=getattr(request, "method", None),
205
+ path=getattr(request, "path", None),
206
+ status=getattr(response, "status", None),
207
+ latency_ms=latency_ms,
208
+ correlation_id=cid,
209
+ )
rasa/builder/main.py CHANGED
@@ -11,8 +11,14 @@ from sanic.request import Request
11
11
  from sanic_openapi import openapi3_blueprint
12
12
 
13
13
  import rasa.core.utils
14
+ import rasa.telemetry
14
15
  from rasa.builder import config
15
- from rasa.builder.logging_utils import collecting_logs_processor
16
+ from rasa.builder.logging_utils import (
17
+ attach_request_id_processor,
18
+ collecting_logs_processor,
19
+ log_request_end,
20
+ log_request_start,
21
+ )
16
22
  from rasa.builder.service import bp, setup_project_generator
17
23
  from rasa.core.channels.studio_chat import StudioChatInput
18
24
  from rasa.server import configure_cors
@@ -37,7 +43,7 @@ def setup_logging() -> None:
37
43
  configure_structlog(
38
44
  log_level,
39
45
  include_time=True,
40
- additional_processors=[collecting_logs_processor],
46
+ additional_processors=[attach_request_id_processor, collecting_logs_processor],
41
47
  )
42
48
 
43
49
 
@@ -52,23 +58,26 @@ def setup_input_channel() -> StudioChatInput:
52
58
  def setup_middleware(app: Sanic) -> None:
53
59
  """Setup middleware for request/response processing."""
54
60
 
55
- @app.middleware("request")
61
+ @app.middleware("request") # type: ignore[misc,no-untyped-call]
56
62
  async def log_request(request: Request) -> None:
57
- structlogger.info(
58
- "request.received",
59
- method=request.method,
60
- path=request.path,
61
- remote_addr=request.remote_addr or "unknown",
62
- )
63
+ # store start time on request ctx for later latency calculation
64
+ request.ctx._start_time = log_request_start(request)
63
65
 
64
- @app.middleware("response")
66
+ @app.middleware("response") # type: ignore[misc,no-untyped-call]
65
67
  async def log_response(request: Request, response: HTTPResponse) -> None:
66
- structlogger.info(
67
- "request.completed",
68
- method=request.method,
69
- path=request.path,
70
- status=response.status,
71
- )
68
+ try:
69
+ start = getattr(request.ctx, "_start_time", None)
70
+ if start is None:
71
+ # If for some reason the request middleware didn't run
72
+ start = log_request_start(request)
73
+ # propagate correlation id for clients
74
+ correlation_id = getattr(request.ctx, "correlation_id", None)
75
+ if correlation_id:
76
+ response.headers["X-Correlation-Id"] = correlation_id
77
+ log_request_end(request, response, start)
78
+ except Exception:
79
+ # avoid breaking response path
80
+ pass
72
81
 
73
82
 
74
83
  def create_app(project_folder: Optional[str] = None) -> Sanic:
@@ -116,6 +125,10 @@ def main(project_folder: Optional[str] = None) -> None:
116
125
  # Setup logging
117
126
  setup_logging()
118
127
 
128
+ # Setup telemetry
129
+ rasa.telemetry.initialize_telemetry()
130
+ rasa.telemetry.initialize_error_reporting(private_mode=False)
131
+
119
132
  # Create and configure app
120
133
  app = create_app(project_folder)
121
134
  register_custom_sanic_error_handler(app)