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

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

Potentially problematic release.


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

Files changed (361) hide show
  1. rasa/builder/config.py +1 -0
  2. rasa/builder/copilot/constants.py +3 -0
  3. rasa/builder/copilot/copilot.py +128 -54
  4. rasa/builder/copilot/models.py +39 -3
  5. rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +183 -188
  6. rasa/builder/copilot/prompts/latest_user_message_context_prompt.jinja2 +61 -0
  7. rasa/builder/copilot/telemetry.py +46 -20
  8. rasa/builder/document_retrieval/models.py +3 -3
  9. rasa/builder/download.py +1 -8
  10. rasa/builder/jobs.py +33 -21
  11. rasa/builder/main.py +38 -62
  12. rasa/builder/models.py +7 -7
  13. rasa/builder/project_generator.py +143 -147
  14. rasa/builder/service.py +42 -27
  15. rasa/builder/template_cache.py +69 -0
  16. rasa/builder/training_service.py +74 -4
  17. rasa/cli/project_templates/basic/README.md +23 -0
  18. rasa/cli/project_templates/basic/actions/actions.md +10 -0
  19. rasa/cli/project_templates/basic/config.yml +6 -4
  20. rasa/cli/project_templates/basic/data/data.md +5 -6
  21. rasa/cli/project_templates/basic/domain/domain.md +7 -5
  22. rasa/cli/project_templates/basic/domain/general/show_faqs.yml +1 -1
  23. rasa/cli/project_templates/basic/endpoints.yml +5 -1
  24. rasa/cli/project_templates/default/config.yml +4 -0
  25. rasa/cli/project_templates/default/endpoints.yml +4 -0
  26. rasa/cli/project_templates/finance/README.md +26 -0
  27. rasa/cli/project_templates/finance/actions/__init__.py +0 -46
  28. rasa/cli/project_templates/finance/actions/accounts/check_balance.py +18 -0
  29. rasa/cli/project_templates/finance/actions/actions.md +15 -0
  30. rasa/cli/project_templates/finance/actions/{transfers/action_process_immediate_payment.py → cards/check_that_card_exists.py} +6 -3
  31. rasa/cli/project_templates/finance/actions/cards/list_cards.py +22 -0
  32. rasa/cli/project_templates/finance/actions/contacts/__init__.py +0 -0
  33. rasa/cli/project_templates/finance/actions/contacts/add_contact.py +30 -0
  34. rasa/cli/project_templates/finance/actions/contacts/list_contacts.py +22 -0
  35. rasa/cli/project_templates/finance/actions/contacts/remove_contact.py +35 -0
  36. rasa/cli/project_templates/finance/actions/db.py +117 -0
  37. rasa/cli/project_templates/finance/actions/general/__init__.py +0 -0
  38. rasa/cli/project_templates/finance/actions/general/action_human_handoff.py +49 -0
  39. rasa/cli/project_templates/finance/actions/transfers/check_transfer_funds.py +27 -0
  40. rasa/cli/project_templates/finance/actions/transfers/check_transfer_limit.py +36 -0
  41. rasa/cli/project_templates/finance/actions/transfers/execute_recurrent_payment.py +20 -0
  42. rasa/cli/project_templates/finance/actions/transfers/execute_transfer.py +45 -0
  43. rasa/cli/project_templates/finance/actions/transfers/list_transactions.py +32 -0
  44. rasa/cli/project_templates/finance/config.yml +8 -0
  45. rasa/cli/project_templates/finance/credentials.yml +7 -6
  46. rasa/cli/project_templates/finance/data/accounts/check_balance.yml +3 -4
  47. rasa/cli/project_templates/finance/data/accounts/download_statements.yml +26 -0
  48. rasa/cli/project_templates/finance/data/bills/bill_pay_reminder.yml +25 -0
  49. rasa/cli/project_templates/finance/data/cards/activate_card.yml +35 -0
  50. rasa/cli/project_templates/finance/data/cards/block_card.yml +37 -58
  51. rasa/cli/project_templates/finance/data/cards/list_cards.yml +14 -0
  52. rasa/cli/project_templates/finance/data/cards/replace_card.yml +16 -0
  53. rasa/cli/project_templates/finance/data/cards/replace_eligible_card.yml +29 -0
  54. rasa/cli/project_templates/finance/data/contacts/add_contact.yml +33 -0
  55. rasa/cli/project_templates/finance/data/contacts/list_contacts.yml +14 -0
  56. rasa/cli/project_templates/finance/data/contacts/remove_contact.yml +31 -0
  57. rasa/cli/project_templates/finance/data/data.md +14 -0
  58. rasa/cli/project_templates/finance/data/general/bot_challenge.yml +6 -0
  59. rasa/cli/project_templates/finance/data/general/goodbye.yml +1 -1
  60. rasa/cli/project_templates/finance/data/general/hello.yml +1 -2
  61. rasa/cli/project_templates/finance/data/general/help.yml +2 -2
  62. rasa/cli/project_templates/finance/data/general/human_handoff.yml +2 -2
  63. rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +1 -1
  64. rasa/cli/project_templates/finance/data/transfers/check_transfer_limit.yml +18 -0
  65. rasa/cli/project_templates/finance/data/transfers/list_transactions.yml +46 -0
  66. rasa/cli/project_templates/finance/data/transfers/move_money_between_accounts.yml +51 -0
  67. rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +29 -62
  68. rasa/cli/project_templates/finance/data/transfers/transfer_money_to_a_third_party.yml +175 -0
  69. rasa/cli/project_templates/finance/db/cards.json +18 -0
  70. rasa/cli/project_templates/finance/db/contacts.json +10 -0
  71. rasa/cli/project_templates/finance/db/my_account.json +6 -0
  72. rasa/cli/project_templates/finance/db/transactions.json +22 -0
  73. rasa/cli/project_templates/finance/docs/docs.md +8 -0
  74. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/budgeting_analytics.txt +22 -0
  75. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/multi_currency_accounts.txt +19 -0
  76. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/premium_benefits.txt +19 -0
  77. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/contactless_limits.txt +16 -0
  78. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/freeze_unfreeze_card.txt +16 -0
  79. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/lost_stolen_card.txt +19 -0
  80. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/instant_payments.txt +19 -0
  81. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/international_transfers.txt +19 -0
  82. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/fraud_protection.txt +22 -0
  83. rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/secure_payments.txt +22 -0
  84. rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +9 -5
  85. rasa/cli/project_templates/finance/domain/accounts/download_statements.yml +40 -0
  86. rasa/cli/project_templates/finance/domain/bills/bill_pay_reminder.yml +49 -0
  87. rasa/cli/project_templates/finance/domain/cards/activate_card.yml +24 -0
  88. rasa/cli/project_templates/finance/domain/cards/block_card.yml +33 -90
  89. rasa/cli/project_templates/finance/domain/cards/list_cards.yml +16 -0
  90. rasa/cli/project_templates/finance/domain/cards/replace_card.yml +43 -0
  91. rasa/cli/project_templates/finance/domain/cards/shared.yml +15 -0
  92. rasa/cli/project_templates/finance/domain/contacts/add_contact.yml +37 -0
  93. rasa/cli/project_templates/finance/domain/contacts/list_contacts.yml +16 -0
  94. rasa/cli/project_templates/finance/domain/contacts/remove_contact.yml +32 -0
  95. rasa/cli/project_templates/finance/domain/domain.md +18 -0
  96. rasa/cli/project_templates/finance/domain/general/_shared.yml +39 -0
  97. rasa/cli/project_templates/finance/domain/general/bot_challenge.yml +4 -0
  98. rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -2
  99. rasa/cli/project_templates/finance/domain/general/feedback.yml +0 -3
  100. rasa/cli/project_templates/finance/domain/general/goodbye.yml +6 -6
  101. rasa/cli/project_templates/finance/domain/general/human_handoff.yml +10 -9
  102. rasa/cli/project_templates/finance/domain/general/welcome.yml +33 -2
  103. rasa/cli/project_templates/finance/domain/transfers/check_transfer_limit.yml +32 -0
  104. rasa/cli/project_templates/finance/domain/transfers/list_transactions.yml +44 -0
  105. rasa/cli/project_templates/finance/domain/transfers/shared.yml +17 -0
  106. rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +203 -61
  107. rasa/cli/project_templates/finance/endpoints.yml +8 -4
  108. rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +31 -12
  109. rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/check_balance.yml +9 -0
  110. rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/download_statements.yml +43 -0
  111. rasa/cli/project_templates/finance/tests/e2e_test_cases/cards/block_card.yml +55 -0
  112. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
  113. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/feedback.yml +46 -0
  114. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/goodbye.yml +9 -0
  115. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/hello.yml +8 -0
  116. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/human_handoff.yml +35 -0
  117. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/patterns.yml +22 -0
  118. rasa/cli/project_templates/finance/tests/e2e_test_cases/transfers/transfer_money.yml +56 -0
  119. rasa/cli/project_templates/telco/README.md +25 -0
  120. rasa/cli/project_templates/telco/actions/actions.md +12 -0
  121. rasa/cli/project_templates/telco/config.yml +6 -4
  122. rasa/cli/project_templates/telco/data/data.md +11 -0
  123. rasa/cli/project_templates/telco/data/general/human_handoff.yml +1 -1
  124. rasa/cli/project_templates/telco/docs/docs.md +3 -0
  125. rasa/cli/project_templates/telco/domain/domain.md +13 -0
  126. rasa/cli/project_templates/telco/domain/general/human_handoff.yml +3 -6
  127. rasa/cli/project_templates/telco/endpoints.yml +5 -1
  128. rasa/cli/project_templates/telco/prompts/rephraser_demo_personality_prompt.jinja2 +1 -1
  129. rasa/cli/project_templates/telco/tests/e2e_test_cases/billing/understand_bill.yml +67 -0
  130. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
  131. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/feedback.yml +46 -0
  132. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/goodbye.yml +9 -0
  133. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/hello.yml +8 -0
  134. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/human_handoff.yml +35 -0
  135. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/patterns.yml +23 -0
  136. rasa/cli/project_templates/telco/tests/e2e_test_cases/network/solve_internet_issue.yml +57 -0
  137. rasa/core/actions/action_run_slot_rejections.py +1 -1
  138. rasa/core/actions/direct_custom_actions_executor.py +9 -2
  139. rasa/core/brokers/broker.py +1 -1
  140. rasa/core/brokers/kafka.py +52 -8
  141. rasa/core/channels/development_inspector.py +1 -21
  142. rasa/core/channels/hangouts.py +2 -2
  143. rasa/core/channels/inspector/dist/assets/{arc-18042c22.js → arc-35222594.js} +1 -1
  144. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-fdd6bcfa.js → blockDiagram-38ab4fdb-a0efbfd3.js} +1 -1
  145. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-f5ae6786.js → c4Diagram-3d4e48cf-0584c0f2.js} +1 -1
  146. rasa/core/channels/inspector/dist/assets/channel-8e08bed9.js +1 -0
  147. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-81efba3e.js → classDiagram-70f12bd4-39f40dbe.js} +1 -1
  148. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-3b6b6a92.js → classDiagram-v2-f2320105-1ad755f3.js} +1 -1
  149. rasa/core/channels/inspector/dist/assets/clone-78c82dea.js +1 -0
  150. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-31422447.js → createText-2e5e7dd3-b0f4f0fe.js} +1 -1
  151. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-518a90db.js → edges-e0da2a9e-9039bff9.js} +1 -1
  152. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-a6d3c25a.js → erDiagram-9861fffd-65c9b127.js} +1 -1
  153. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e048c2be.js → flowDb-956e92f1-4f08b38e.js} +1 -1
  154. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c7474c91.js → flowDiagram-66a62f08-e95c362a.js} +1 -1
  155. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b08f601.js +1 -0
  156. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb4d8723.js → flowchart-elk-definition-4a651766-703c3015.js} +1 -1
  157. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-346636a2.js → ganttDiagram-c361ad54-699328ea.js} +1 -1
  158. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-7c508874.js → gitGraphDiagram-72cf32ee-04cf4b05.js} +1 -1
  159. rasa/core/channels/inspector/dist/assets/{graph-14702d8a.js → graph-ee94449e.js} +1 -1
  160. rasa/core/channels/inspector/dist/assets/{index-3862675e-f18b534b.js → index-3862675e-940162b4.js} +1 -1
  161. rasa/core/channels/inspector/dist/assets/{index-4d4bdf3a.js → index-c941dcb3.js} +132 -131
  162. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-64154b83.js → infoDiagram-f8f76790-c79c2866.js} +1 -1
  163. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-833a5f95.js → journeyDiagram-49397b02-84489d30.js} +1 -1
  164. rasa/core/channels/inspector/dist/assets/{layout-5a3b2123.js → layout-a9aa9858.js} +1 -1
  165. rasa/core/channels/inspector/dist/assets/{line-2272a8c7.js → line-eb73cf26.js} +1 -1
  166. rasa/core/channels/inspector/dist/assets/{linear-35bcf273.js → linear-b3399f9a.js} +1 -1
  167. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-92dcb0e9.js → mindmap-definition-fc14e90a-b095bf1a.js} +1 -1
  168. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-94dbc900.js → pieDiagram-8a3498a8-07644b66.js} +1 -1
  169. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-8b7a9c33.js → quadrantDiagram-120e2f19-573a3f9c.js} +1 -1
  170. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6f7eab81.js → requirementDiagram-deff3bca-d457e1e1.js} +1 -1
  171. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-f43e581d.js → sankeyDiagram-04a897e0-9d26e1a2.js} +1 -1
  172. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-0bcbefc3.js → sequenceDiagram-704730f1-3a9cde10.js} +1 -1
  173. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-b8a74083.js → stateDiagram-587899a1-4f3e8cec.js} +1 -1
  174. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-2070218f.js → stateDiagram-v2-d93cdb3a-e617e5bf.js} +1 -1
  175. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-f1d54e34.js → styles-6aaf32cf-eab30d2f.js} +1 -1
  176. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-980de489.js → styles-9a916d00-09994be2.js} +1 -1
  177. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-3c03abde.js → styles-c10674c1-b7110364.js} +1 -1
  178. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-46ba068f.js → svgDrawCommon-08f97a94-3ebc92ad.js} +1 -1
  179. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-901f5e3d.js → timeline-definition-85554ec2-7d13d2f2.js} +1 -1
  180. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-acbc628a.js → xychartDiagram-e933f94c-488385e1.js} +1 -1
  181. rasa/core/channels/inspector/dist/index.html +1 -1
  182. rasa/core/channels/inspector/src/App.tsx +5 -31
  183. rasa/core/channels/inspector/src/components/Chat.tsx +2 -3
  184. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +9 -1
  185. rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +63 -35
  186. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +14 -0
  187. rasa/core/channels/inspector/src/types.ts +32 -7
  188. rasa/core/channels/studio_chat.py +23 -41
  189. rasa/core/channels/voice_stream/asr/asr_event.py +1 -1
  190. rasa/core/channels/voice_stream/asr/azure.py +6 -3
  191. rasa/core/channels/voice_stream/asr/deepgram.py +1 -1
  192. rasa/core/channels/voice_stream/audiocodes.py +3 -0
  193. rasa/core/channels/voice_stream/browser_audio.py +55 -3
  194. rasa/core/channels/voice_stream/genesys.py +2 -1
  195. rasa/core/channels/voice_stream/jambonz.py +9 -1
  196. rasa/core/channels/voice_stream/twilio_media_streams.py +16 -0
  197. rasa/core/channels/voice_stream/voice_channel.py +61 -0
  198. rasa/core/concurrent_lock_store.py +66 -16
  199. rasa/core/constants.py +7 -0
  200. rasa/core/iam_credentials_providers/__init__.py +0 -0
  201. rasa/core/iam_credentials_providers/aws_iam_credentials_providers.py +226 -0
  202. rasa/core/iam_credentials_providers/credentials_provider_protocol.py +90 -0
  203. rasa/core/lock_store.py +46 -10
  204. rasa/core/nlg/generator.py +1 -1
  205. rasa/core/policies/flows/flow_executor.py +1 -1
  206. rasa/core/processor.py +32 -0
  207. rasa/core/redis_connection_factory.py +469 -0
  208. rasa/core/tracker_stores/redis_tracker_store.py +32 -14
  209. rasa/core/tracker_stores/sql_tracker_store.py +57 -1
  210. rasa/engine/graph.py +5 -1
  211. rasa/engine/loader.py +12 -0
  212. rasa/engine/storage/local_model_storage.py +41 -4
  213. rasa/model_manager/socket_bridge.py +1 -2
  214. rasa/model_manager/warm_rasa_process.py +13 -3
  215. rasa/shared/core/constants.py +1 -0
  216. rasa/shared/core/events.py +2 -0
  217. rasa/shared/core/flows/flow.py +1 -1
  218. rasa/shared/nlu/training_data/schemas/responses.yml +3 -0
  219. rasa/utils/pypred.py +38 -0
  220. rasa/validator.py +12 -8
  221. rasa/version.py +1 -1
  222. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/METADATA +19 -16
  223. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/RECORD +231 -266
  224. rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +0 -47
  225. rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +0 -40
  226. rasa/cli/project_templates/finance/actions/action_session_start.py +0 -74
  227. rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +0 -48
  228. rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +0 -36
  229. rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +0 -54
  230. rasa/cli/project_templates/finance/actions/database.py +0 -277
  231. rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +0 -52
  232. rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +0 -51
  233. rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +0 -40
  234. rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +0 -40
  235. rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +0 -46
  236. rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +0 -49
  237. rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +0 -19
  238. rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +0 -36
  239. rasa/cli/project_templates/finance/csvs/accounts.csv +0 -8
  240. rasa/cli/project_templates/finance/csvs/advisors.csv +0 -7
  241. rasa/cli/project_templates/finance/csvs/appointments.csv +0 -211
  242. rasa/cli/project_templates/finance/csvs/branches.csv +0 -10
  243. rasa/cli/project_templates/finance/csvs/cards.csv +0 -11
  244. rasa/cli/project_templates/finance/csvs/payees.csv +0 -11
  245. rasa/cli/project_templates/finance/csvs/transactions.csv +0 -71
  246. rasa/cli/project_templates/finance/csvs/users.csv +0 -4
  247. rasa/cli/project_templates/finance/data/cards/select_card.yml +0 -12
  248. rasa/cli/project_templates/finance/data/general/bot_identity.yml +0 -6
  249. rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +0 -5
  250. rasa/cli/project_templates/finance/data/system/source/accounts.json +0 -51
  251. rasa/cli/project_templates/finance/data/system/source/advisors.json +0 -44
  252. rasa/cli/project_templates/finance/data/system/source/appointments.json +0 -1474
  253. rasa/cli/project_templates/finance/data/system/source/branches.json +0 -47
  254. rasa/cli/project_templates/finance/data/system/source/cards.json +0 -72
  255. rasa/cli/project_templates/finance/data/system/source/payees.json +0 -74
  256. rasa/cli/project_templates/finance/data/system/source/transactions.json +0 -492
  257. rasa/cli/project_templates/finance/data/system/source/users.json +0 -29
  258. rasa/cli/project_templates/finance/data/transfers/add_payee.yml +0 -29
  259. rasa/cli/project_templates/finance/data/transfers/list_payees.yml +0 -5
  260. rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +0 -21
  261. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +0 -8
  262. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +0 -8
  263. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +0 -8
  264. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +0 -8
  265. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +0 -8
  266. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +0 -7
  267. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +0 -8
  268. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +0 -8
  269. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +0 -8
  270. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +0 -8
  271. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +0 -8
  272. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +0 -8
  273. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +0 -8
  274. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +0 -8
  275. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +0 -8
  276. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +0 -8
  277. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +0 -8
  278. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +0 -8
  279. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +0 -8
  280. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +0 -8
  281. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +0 -50
  282. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +0 -50
  283. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +0 -48
  284. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +0 -50
  285. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +0 -50
  286. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +0 -47
  287. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +0 -50
  288. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +0 -50
  289. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +0 -47
  290. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +0 -50
  291. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +0 -50
  292. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +0 -50
  293. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +0 -47
  294. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +0 -50
  295. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +0 -50
  296. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +0 -47
  297. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +0 -50
  298. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +0 -50
  299. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +0 -47
  300. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +0 -50
  301. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +0 -50
  302. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +0 -47
  303. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +0 -47
  304. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +0 -50
  305. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +0 -50
  306. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +0 -47
  307. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +0 -50
  308. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +0 -50
  309. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +0 -47
  310. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +0 -50
  311. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +0 -50
  312. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +0 -47
  313. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +0 -50
  314. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +0 -50
  315. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +0 -50
  316. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +0 -47
  317. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +0 -50
  318. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +0 -50
  319. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +0 -47
  320. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +0 -50
  321. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +0 -50
  322. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +0 -47
  323. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +0 -50
  324. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +0 -50
  325. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +0 -50
  326. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +0 -47
  327. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +0 -50
  328. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +0 -50
  329. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +0 -47
  330. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +0 -50
  331. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +0 -50
  332. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +0 -47
  333. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +0 -50
  334. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +0 -50
  335. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +0 -47
  336. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +0 -47
  337. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +0 -50
  338. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +0 -50
  339. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +0 -50
  340. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +0 -50
  341. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +0 -47
  342. rasa/cli/project_templates/finance/domain/cards/select_card.yml +0 -12
  343. rasa/cli/project_templates/finance/domain/general/assistant_details.yml +0 -12
  344. rasa/cli/project_templates/finance/domain/general/bot_identity.yml +0 -5
  345. rasa/cli/project_templates/finance/domain/general/defaults.yml +0 -24
  346. rasa/cli/project_templates/finance/domain/general/help.yml +0 -5
  347. rasa/cli/project_templates/finance/domain/general/utils.yml +0 -13
  348. rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +0 -47
  349. rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +0 -4
  350. rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +0 -16
  351. rasa/core/channels/inspector/dist/assets/channel-b9b536fc.js +0 -1
  352. rasa/core/channels/inspector/dist/assets/clone-78d2ddcf.js +0 -1
  353. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-8b09c060.js +0 -1
  354. /rasa/cli/project_templates/telco/domain/billing/{domain_undertand_bill.yml → understand_bill.yml} +0 -0
  355. /rasa/cli/project_templates/telco/domain/network/{domain_reboot_router.yml → reboot_router.yml} +0 -0
  356. /rasa/cli/project_templates/telco/domain/network/{domain_reset_router.yml → reset_router.yml} +0 -0
  357. /rasa/cli/project_templates/telco/domain/network/{domain_run_speed_test.yml → run_speed_test.yml} +0 -0
  358. /rasa/cli/project_templates/telco/domain/network/{domain_solve_internet_issue.yml → solve_internet_issue.yml} +0 -0
  359. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/NOTICE +0 -0
  360. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/WHEEL +0 -0
  361. {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/entry_points.txt +0 -0
rasa/builder/jobs.py CHANGED
@@ -16,10 +16,13 @@ from rasa.builder.models import (
16
16
  JobStatusEvent,
17
17
  )
18
18
  from rasa.builder.project_generator import ProjectGenerator
19
- from rasa.builder.training_service import train_and_load_agent
19
+ from rasa.builder.training_service import (
20
+ train_and_load_agent,
21
+ try_load_existing_agent,
22
+ update_agent,
23
+ )
20
24
  from rasa.builder.validation_service import validate_project
21
25
  from rasa.cli.scaffold import ProjectTemplateName
22
- from rasa.core.channels.studio_chat import StudioChatInput
23
26
 
24
27
  structlogger = structlog.get_logger()
25
28
 
@@ -45,7 +48,6 @@ async def run_prompt_to_bot_job(
45
48
  prompt: The natural language prompt for bot generation.
46
49
  """
47
50
  project_generator: ProjectGenerator = app.ctx.project_generator
48
- input_channel: StudioChatInput = app.ctx.input_channel
49
51
 
50
52
  await push_job_status_event(job, JobStatus.received)
51
53
 
@@ -60,10 +62,8 @@ async def run_prompt_to_bot_job(
60
62
 
61
63
  # 2. Training
62
64
  await push_job_status_event(job, JobStatus.training)
63
- app.ctx.agent = await train_and_load_agent(
64
- project_generator.get_training_input()
65
- )
66
- input_channel.agent = app.ctx.agent
65
+ agent = await train_and_load_agent(project_generator.get_training_input())
66
+ update_agent(agent, app)
67
67
  await push_job_status_event(job, JobStatus.train_success)
68
68
 
69
69
  structlogger.info(
@@ -128,8 +128,7 @@ async def run_template_to_bot_job(
128
128
  job: The job information instance.
129
129
  template_name: The name of the template to use for bot generation.
130
130
  """
131
- project_generator = app.ctx.project_generator
132
- input_channel = app.ctx.input_channel
131
+ project_generator: ProjectGenerator = app.ctx.project_generator
133
132
 
134
133
  await push_job_status_event(job, JobStatus.received)
135
134
 
@@ -142,10 +141,14 @@ async def run_template_to_bot_job(
142
141
 
143
142
  # 2) Training
144
143
  await push_job_status_event(job, JobStatus.training)
145
- app.ctx.agent = await train_and_load_agent(
146
- project_generator.get_training_input()
147
- )
148
- input_channel.agent = app.ctx.agent
144
+ agent = await try_load_existing_agent(project_generator.project_folder)
145
+ if agent is None:
146
+ agent = await train_and_load_agent(project_generator.get_training_input())
147
+ else:
148
+ structlogger.info(
149
+ "bot_builder_service.template_to_bot.agent_loaded_from_cache",
150
+ )
151
+ update_agent(agent, app)
149
152
  await push_job_status_event(job, JobStatus.train_success)
150
153
 
151
154
  # 3) Done
@@ -204,17 +207,26 @@ async def run_template_to_bot_job(
204
207
  job_manager.mark_done(job, error=str(exc))
205
208
 
206
209
 
207
- async def run_update_files_job(
210
+ async def run_replace_all_files_job(
208
211
  app: "Sanic",
209
212
  job: JobInfo,
210
213
  bot_files: dict,
211
214
  ) -> None:
215
+ """Run the replace-all-files job in the background.
216
+
217
+ This replaces all bot files with the provided files and deletes any files
218
+ not included in the request (excluding .rasa/ and models/ directories).
219
+
220
+ Args:
221
+ app: The Sanic application instance.
222
+ job: The job information instance.
223
+ bot_files: Dictionary of file names to content for replacement.
224
+ """
212
225
  project_generator = app.ctx.project_generator
213
- input_channel = app.ctx.input_channel
214
226
  await push_job_status_event(job, JobStatus.received)
215
227
 
216
228
  try:
217
- project_generator.update_bot_files(bot_files)
229
+ project_generator.replace_all_bot_files(bot_files)
218
230
 
219
231
  # 1. Validating
220
232
  await push_job_status_event(job, JobStatus.validating)
@@ -226,8 +238,8 @@ async def run_update_files_job(
226
238
 
227
239
  # 2. Training
228
240
  await push_job_status_event(job, JobStatus.training)
229
- app.ctx.agent = await train_and_load_agent(training_input)
230
- input_channel.agent = app.ctx.agent
241
+ agent = await train_and_load_agent(training_input)
242
+ update_agent(agent, app)
231
243
  await push_job_status_event(job, JobStatus.train_success)
232
244
 
233
245
  await push_job_status_event(job, JobStatus.done)
@@ -238,7 +250,7 @@ async def run_update_files_job(
238
250
  if config.VALIDATION_FAIL_ON_WARNINGS:
239
251
  log_levels.append("warning")
240
252
  structlogger.debug(
241
- "update_files_job.validation_error",
253
+ "replace_all_files_job.validation_error",
242
254
  job_id=job.id,
243
255
  error=str(exc),
244
256
  validation_logs=exc.validation_logs,
@@ -252,7 +264,7 @@ async def run_update_files_job(
252
264
 
253
265
  except TrainingError as exc:
254
266
  structlogger.debug(
255
- "update_files_job.train_error",
267
+ "replace_all_files_job.train_error",
256
268
  job_id=job.id,
257
269
  error=str(exc),
258
270
  )
@@ -262,7 +274,7 @@ async def run_update_files_job(
262
274
  except Exception as exc:
263
275
  # Capture full traceback for anything truly unexpected
264
276
  structlogger.exception(
265
- "update_files_job.unexpected_error",
277
+ "replace_all_files_job.unexpected_error",
266
278
  job_id=job.id,
267
279
  error=str(exc),
268
280
  )
rasa/builder/main.py CHANGED
@@ -22,10 +22,9 @@ from rasa.builder.logging_utils import (
22
22
  log_request_start,
23
23
  )
24
24
  from rasa.builder.service import bp, setup_project_generator
25
- from rasa.core.agent import Agent, load_agent
26
- from rasa.core.available_endpoints import AvailableEndpoints
25
+ from rasa.builder.training_service import try_load_existing_agent, update_agent
27
26
  from rasa.core.channels.studio_chat import StudioChatInput
28
- from rasa.model import get_latest_model
27
+ from rasa.model_manager.warm_rasa_process import warmup
29
28
  from rasa.server import configure_cors
30
29
  from rasa.utils.common import configure_logging_and_warnings
31
30
  from rasa.utils.log_utils import configure_structlog
@@ -60,63 +59,6 @@ def setup_input_channel() -> StudioChatInput:
60
59
  return StudioChatInput.from_credentials(credentials=studio_chat_credentials)
61
60
 
62
61
 
63
- async def try_load_existing_agent(project_folder: str) -> Optional[Agent]:
64
- """Try to load an existing agent from the project's models directory.
65
-
66
- Args:
67
- project_folder: Path to the project folder
68
-
69
- Returns:
70
- Loaded Agent instance if successful, None otherwise
71
- """
72
- models_dir = os.path.join(project_folder, "models")
73
-
74
- if not os.path.exists(models_dir) or not os.path.isdir(models_dir):
75
- structlogger.debug("No models directory found", models_dir=models_dir)
76
- return None
77
-
78
- try:
79
- # Find the latest model in the models directory
80
- latest_model_path = get_latest_model(models_dir)
81
- if not latest_model_path:
82
- structlogger.debug(
83
- "No models found in models directory", models_dir=models_dir
84
- )
85
- return None
86
-
87
- structlogger.info(
88
- "Found existing model, attempting to load", model_path=latest_model_path
89
- )
90
-
91
- # Get available endpoints for agent loading
92
- available_endpoints = AvailableEndpoints.get_instance()
93
-
94
- # Load the agent
95
- agent = await load_agent(
96
- model_path=latest_model_path, endpoints=available_endpoints
97
- )
98
-
99
- if agent and agent.is_ready():
100
- structlogger.info(
101
- "Successfully loaded existing agent", model_path=latest_model_path
102
- )
103
- return agent
104
- else:
105
- structlogger.warning(
106
- "Agent loaded but not ready", model_path=latest_model_path
107
- )
108
- return None
109
-
110
- except Exception as e:
111
- structlogger.warning(
112
- "Failed to load existing agent",
113
- models_dir=models_dir,
114
- error=str(e),
115
- exc_info=True,
116
- )
117
- return None
118
-
119
-
120
62
  def setup_middleware(app: Sanic) -> None:
121
63
  """Setup middleware for request/response processing."""
122
64
 
@@ -157,7 +99,6 @@ def create_app(project_folder: str) -> Sanic:
157
99
  use_authentication=app.config.USE_AUTHENTICATION,
158
100
  rasa_version=rasa.__version__,
159
101
  )
160
- app.ctx.agent = None
161
102
 
162
103
  # Set up project generator and store in app context
163
104
  app.ctx.project_generator = setup_project_generator(project_folder)
@@ -165,6 +106,8 @@ def create_app(project_folder: str) -> Sanic:
165
106
  # Set up input channel and store in app context
166
107
  app.ctx.input_channel = setup_input_channel()
167
108
 
109
+ update_agent(None, app)
110
+
168
111
  # Register the blueprint
169
112
  app.blueprint(bp)
170
113
 
@@ -196,7 +139,7 @@ def create_app(project_folder: str) -> Sanic:
196
139
  try:
197
140
  existing_agent = await try_load_existing_agent(project_folder)
198
141
  if existing_agent:
199
- app.ctx.agent = existing_agent
142
+ update_agent(existing_agent, app)
200
143
  structlogger.info("Agent loaded on server startup")
201
144
  else:
202
145
  structlogger.info(
@@ -208,6 +151,33 @@ def create_app(project_folder: str) -> Sanic:
208
151
  return app
209
152
 
210
153
 
154
+ def _apply_llm_overrides_from_builder_env() -> None:
155
+ # Prefer a dedicated builder key, fall back to license if you proxy with it
156
+ if not config.HELLO_LLM_PROXY_BASE_URL:
157
+ return
158
+
159
+ structlogger.debug(
160
+ "builder.main.using_llm_proxy", base_url=config.HELLO_LLM_PROXY_BASE_URL
161
+ )
162
+
163
+ if not config.RASA_PRO_LICENSE:
164
+ structlogger.error(
165
+ "copilot.proxy_missing_license",
166
+ event_info=(
167
+ "HELLO_LLM_PROXY_BASE_URL is set but RASA_PRO_LICENSE is missing."
168
+ ),
169
+ )
170
+ return
171
+
172
+ if not os.getenv("OPENAI_API_BASE") and not os.getenv("OPENAI_API_KEY"):
173
+ base_url = config.HELLO_LLM_PROXY_BASE_URL.rstrip("/")
174
+ # needed for litellm client
175
+ os.environ["OPENAI_API_BASE"] = base_url
176
+ # needed for openai async client
177
+ os.environ["OPENAI_BASE_URL"] = base_url
178
+ os.environ["OPENAI_API_KEY"] = config.RASA_PRO_LICENSE
179
+
180
+
211
181
  def main(project_folder: Optional[str] = None) -> None:
212
182
  """Main entry point."""
213
183
  try:
@@ -218,6 +188,12 @@ def main(project_folder: Optional[str] = None) -> None:
218
188
  rasa.telemetry.initialize_telemetry()
219
189
  rasa.telemetry.initialize_error_reporting(private_mode=False)
220
190
 
191
+ _apply_llm_overrides_from_builder_env()
192
+
193
+ if config.HELLO_RASA_PROJECT_ID:
194
+ # ensures long import times for modules are ahead of time
195
+ warmup()
196
+
221
197
  # working directory needs to be the project folder, e.g.
222
198
  # for relative paths (./docs) in a projects config to work
223
199
  if not project_folder:
rasa/builder/models.py CHANGED
@@ -6,7 +6,7 @@ from pathlib import Path
6
6
  from typing import Any, Dict, List, Literal, Optional
7
7
 
8
8
  import structlog
9
- from pydantic import BaseModel, Field, validator
9
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
10
10
 
11
11
  from rasa.cli.scaffold import ProjectTemplateName
12
12
  from rasa.shared.importers.importer import TrainingDataImporter
@@ -21,7 +21,8 @@ class PromptRequest(BaseModel):
21
21
  ..., min_length=1, max_length=10000, description="The skill description prompt"
22
22
  )
23
23
 
24
- @validator("prompt")
24
+ @field_validator("prompt")
25
+ @classmethod
25
26
  def validate_prompt(cls, v: str) -> str:
26
27
  if not v.strip():
27
28
  raise ValueError("Prompt cannot be empty or whitespace only")
@@ -38,7 +39,8 @@ class TemplateRequest(BaseModel):
38
39
  ),
39
40
  )
40
41
 
41
- @validator("template_name")
42
+ @field_validator("template_name")
43
+ @classmethod
42
44
  def validate_template_name(cls, v: Any) -> Any:
43
45
  if v not in ProjectTemplateName:
44
46
  raise ValueError(
@@ -54,10 +56,8 @@ class BotDataUpdateRequest(BaseModel):
54
56
  flows_yml: Optional[str] = Field(None, alias="flows.yml")
55
57
  config_yml: Optional[str] = Field(None, alias="config.yml")
56
58
 
57
- class Config:
58
- """Config for BotDataUpdateRequest."""
59
-
60
- allow_population_by_field_name = True
59
+ # Allow using either field names or aliases when creating the model
60
+ model_config = ConfigDict(populate_by_name=True)
61
61
 
62
62
 
63
63
  class BotData(BaseModel):
@@ -3,30 +3,27 @@
3
3
  import json
4
4
  import os
5
5
  import shutil
6
- import tarfile
7
- import tempfile
8
6
  from pathlib import Path
9
7
  from textwrap import dedent
10
8
  from typing import Any, Dict, Generator, List, Optional
11
9
 
12
- import aiofiles
13
- import aiohttp
14
10
  import structlog
15
11
 
16
- import rasa.version
17
12
  from rasa.builder import config
18
13
  from rasa.builder.exceptions import ProjectGenerationError, ValidationError
19
14
  from rasa.builder.llm_service import get_skill_generation_messages, llm_service
20
15
  from rasa.builder.logging_utils import capture_exception_with_context
21
16
  from rasa.builder.models import BotFiles
22
17
  from rasa.builder.project_info import ProjectInfo, ensure_first_used, load_project_info
18
+ from rasa.builder.template_cache import copy_cache_for_template_if_available
23
19
  from rasa.builder.training_service import TrainingInput
24
20
  from rasa.builder.validation_service import validate_project
25
21
  from rasa.cli.scaffold import ProjectTemplateName, create_initial_project
22
+ from rasa.shared.constants import DEFAULT_MODELS_PATH
26
23
  from rasa.shared.core.flows import yaml_flows_io
27
24
  from rasa.shared.importers.importer import TrainingDataImporter
28
25
  from rasa.shared.utils.yaml import dump_obj_as_yaml_to_string
29
- from rasa.utils.io import subpath
26
+ from rasa.utils.io import InvalidPathException, subpath
30
27
 
31
28
  structlogger = structlog.get_logger()
32
29
 
@@ -48,12 +45,25 @@ class ProjectGenerator:
48
45
  """Get the project info."""
49
46
  return load_project_info(self.project_folder)
50
47
 
48
+ def is_empty(self) -> bool:
49
+ """Check if the project folder is empty.
50
+
51
+ Excluding hidden paths.
52
+ """
53
+ return not any(
54
+ file.is_file()
55
+ for file in self.project_folder.iterdir()
56
+ if not file.name.startswith(".")
57
+ )
58
+
51
59
  async def init_from_template(self, template: ProjectTemplateName) -> None:
52
60
  """Create the initial project files."""
53
61
  self.cleanup()
54
62
  create_initial_project(self.project_folder.as_posix(), template)
55
- await download_cache_for_template(template, self.project_folder.as_posix())
56
- # needs to happen after caching, as we download .rasa and that would
63
+ # If a local cache for this template exists, copy it into the project.
64
+ # We no longer download here to avoid blocking project creation.
65
+ await copy_cache_for_template_if_available(template, self.project_folder)
66
+ # needs to happen after caching, as we download/copy .rasa and that would
57
67
  # overwrite the project info file in .rasa
58
68
  ensure_first_used(self.project_folder)
59
69
 
@@ -225,25 +235,9 @@ class ProjectGenerator:
225
235
  """
226
236
  bot_files: BotFiles = {}
227
237
 
228
- for file in self.project_folder.glob("**/*"):
229
- # Skip directories
230
- if not file.is_file():
231
- continue
232
-
238
+ for file in self.bot_file_paths():
233
239
  relative_path = file.relative_to(self.project_folder)
234
240
 
235
- # Skip hidden files and directories (any path component starting with '.')
236
- # as well as `__pycache__` folders
237
- if any(part.startswith(".") for part in relative_path.parts):
238
- continue
239
-
240
- if "__pycache__" in relative_path.parts:
241
- continue
242
-
243
- # exclude the project_folder / models folder
244
- if relative_path.parts[0] == "models":
245
- continue
246
-
247
241
  # Exclude the docs directory if specified
248
242
  if exclude_docs_directory and relative_path.parts[0] == "docs":
249
243
  continue
@@ -255,7 +249,6 @@ class ProjectGenerator:
255
249
  ]
256
250
  if file.suffix.lstrip(".").lower() not in allowed_file_extensions:
257
251
  continue
258
-
259
252
  # Read file content and store with relative path as key
260
253
  try:
261
254
  bot_files[relative_path.as_posix()] = file.read_text(encoding="utf-8")
@@ -266,9 +259,40 @@ class ProjectGenerator:
266
259
  file_path=file.as_posix(),
267
260
  )
268
261
  bot_files[relative_path.as_posix()] = None
269
-
270
262
  return bot_files
271
263
 
264
+ def is_restricted_path(self, path: Path) -> bool:
265
+ """Check if the path is restricted.
266
+
267
+ These paths are excluded from deletion and editing by the user.
268
+ """
269
+ relative_path = path.relative_to(self.project_folder)
270
+
271
+ # Skip hidden files and directories (any path component starting with '.')
272
+ # as well as `__pycache__` folders
273
+ if any(part.startswith(".") for part in relative_path.parts):
274
+ return True
275
+
276
+ if "__pycache__" in relative_path.parts:
277
+ return True
278
+
279
+ # exclude the project_folder / models folder
280
+ if relative_path.parts[0] == DEFAULT_MODELS_PATH:
281
+ return True
282
+
283
+ return False
284
+
285
+ def bot_file_paths(
286
+ self,
287
+ ) -> Generator[Path, None, None]:
288
+ """Get the paths of all bot files."""
289
+ for file in self.project_folder.glob("**/*"):
290
+ # Skip directories
291
+ if not file.is_file() or self.is_restricted_path(file):
292
+ continue
293
+
294
+ yield file
295
+
272
296
  def _get_bot_data_for_llm(self) -> Dict[str, Any]:
273
297
  """Get the current bot data for the LLM."""
274
298
  file_importer = self._create_importer()
@@ -313,7 +337,7 @@ class ProjectGenerator:
313
337
  def update_bot_files(self, files: Dict[str, Optional[str]]) -> None:
314
338
  """Update bot files with new content by writing to disk."""
315
339
  for filename, content in files.items():
316
- file_path = Path(subpath(self.project_folder, filename))
340
+ file_path = Path(subpath(str(self.project_folder), filename))
317
341
  # Disallow updates inside .rasa project metadata directory
318
342
  if any(
319
343
  part.startswith(".")
@@ -324,6 +348,95 @@ class ProjectGenerator:
324
348
  file_path.parent.mkdir(parents=True, exist_ok=True)
325
349
  file_path.write_text(content, encoding="utf-8")
326
350
 
351
+ def ensure_all_files_are_writable(self, files: Dict[str, Optional[str]]) -> None:
352
+ """Ensure all files are writable."""
353
+ for filename, content in files.items():
354
+ file_path = Path(subpath(str(self.project_folder), filename))
355
+ if self.is_restricted_path(file_path):
356
+ raise InvalidPathException(
357
+ f"This file or folder is restricted from editing: {file_path}"
358
+ )
359
+
360
+ def replace_all_bot_files(self, files: Dict[str, Optional[str]]) -> None:
361
+ """Replace all bot files with new content, deleting files not in the request.
362
+
363
+ Files/folders starting with .rasa/ or models/ are excluded from deletion.
364
+
365
+ Args:
366
+ files: Dictionary mapping file names to their content
367
+ """
368
+ self.ensure_all_files_are_writable(files)
369
+ # Collect all existing files - any files not in the new `files` dict will be
370
+ # deleted from this set
371
+ existing_files = set(path.as_posix() for path in self.bot_file_paths())
372
+
373
+ # Write all new files
374
+ for filename, content in files.items():
375
+ if content is None:
376
+ continue
377
+
378
+ file_path = Path(subpath(str(self.project_folder), filename))
379
+ file_path.parent.mkdir(parents=True, exist_ok=True)
380
+
381
+ try:
382
+ file_path.write_text(content, encoding="utf-8")
383
+ except Exception as e:
384
+ # Log write failure and avoid deleting an existing file by mistake
385
+ capture_exception_with_context(
386
+ e,
387
+ "project_generator.replace_all_bot_files.write_error",
388
+ extra={"file_path": file_path},
389
+ )
390
+ if file_path.as_posix() in existing_files:
391
+ # Keep the original file if it already existed
392
+ existing_files.discard(file_path.as_posix())
393
+ continue
394
+
395
+ # Remove from deletion set since this file is in the new set of files
396
+ existing_files.discard(file_path.as_posix())
397
+
398
+ # Delete files that weren't in the request
399
+ for file_to_delete in existing_files:
400
+ file_path = Path(file_to_delete)
401
+ try:
402
+ file_path.unlink()
403
+ except Exception as e:
404
+ capture_exception_with_context(
405
+ e,
406
+ "project_generator.replace_all_bot_files.delete_error",
407
+ extra={"file_path": file_path},
408
+ )
409
+
410
+ # Clean up empty directories (except excluded ones)
411
+ self._cleanup_empty_directories()
412
+
413
+ def _cleanup_empty_directories(self) -> None:
414
+ """Remove empty directories from the project folder.
415
+
416
+ Excludes hidden files and directories, and models/ from cleanup.
417
+ """
418
+ # Walk directories in reverse order (deepest first)
419
+ for dirpath, dirnames, filenames in os.walk(self.project_folder, topdown=False):
420
+ # Skip if this is the project root
421
+ if dirpath == str(self.project_folder):
422
+ continue
423
+
424
+ if self.is_restricted_path(Path(dirpath)):
425
+ continue
426
+
427
+ relative_path = Path(dirpath).relative_to(self.project_folder)
428
+
429
+ try:
430
+ # Only remove if directory is empty
431
+ if not os.listdir(dirpath):
432
+ os.rmdir(dirpath)
433
+ except Exception as e:
434
+ capture_exception_with_context(
435
+ e,
436
+ "project_generator.cleanup_empty_directories.error",
437
+ extra={"directory": relative_path.as_posix()},
438
+ )
439
+
327
440
  def cleanup(self) -> None:
328
441
  """Cleanup the project folder."""
329
442
  # remove all the files and folders in the project folder resulting
@@ -331,6 +444,8 @@ class ProjectGenerator:
331
444
  for filename in os.listdir(self.project_folder):
332
445
  file_path = os.path.join(self.project_folder, filename)
333
446
  try:
447
+ if filename == "lost+found":
448
+ continue
334
449
  if os.path.isfile(file_path) or os.path.islink(file_path):
335
450
  os.unlink(file_path)
336
451
  elif os.path.isdir(file_path):
@@ -341,122 +456,3 @@ class ProjectGenerator:
341
456
  error=str(e),
342
457
  file_path=file_path,
343
458
  )
344
-
345
-
346
- CACHE_BUCKET_URL = "https://trained-templates.s3.us-east-1.amazonaws.com"
347
-
348
-
349
- def _safe_tar_members(
350
- tar: tarfile.TarFile, destination_directory: Path
351
- ) -> Generator[tarfile.TarInfo, None, None]:
352
- """Yield safe members for extraction to prevent path traversal and links.
353
-
354
- Args:
355
- tar: Open tar file handle
356
- destination_directory: Directory to which files will be extracted
357
-
358
- Yields:
359
- Members that are safe to extract within destination_directory
360
- """
361
- base_path = destination_directory.resolve()
362
-
363
- for member in tar.getmembers():
364
- name = member.name
365
- # Skip empty names and absolute paths
366
- if not name or name.startswith("/") or name.startswith("\\"):
367
- continue
368
-
369
- # Disallow symlinks and hardlinks
370
- if member.issym() or member.islnk():
371
- continue
372
-
373
- # Compute the final path and ensure it's within base_path
374
- target_path = (base_path / name).resolve()
375
- try:
376
- target_path.relative_to(base_path)
377
- except ValueError:
378
- # Member would escape the destination directory
379
- continue
380
-
381
- yield member
382
-
383
-
384
- async def download_cache_for_template(
385
- template: ProjectTemplateName, project_folder: str
386
- ) -> None:
387
- # get a temp path for the cache file download
388
- temporary_cache_file = tempfile.NamedTemporaryFile(suffix=".tar.gz", delete=False)
389
-
390
- try:
391
- url = f"{CACHE_BUCKET_URL}/{rasa.version.__version__}-{template.value}.tar.gz"
392
- async with aiohttp.ClientSession() as session:
393
- async with session.get(url) as response:
394
- response.raise_for_status()
395
- async with aiofiles.open(temporary_cache_file.name, "wb") as f:
396
- async for chunk in response.content.iter_chunked(1024 * 1024):
397
- await f.write(chunk)
398
-
399
- # extract the cache to the project folder using safe member filtering
400
- with tarfile.open(temporary_cache_file.name, "r:gz") as tar:
401
- destination = Path(project_folder)
402
- destination.mkdir(parents=True, exist_ok=True)
403
- tar.extractall(
404
- path=destination,
405
- members=_safe_tar_members(tar, destination),
406
- )
407
-
408
- structlogger.info(
409
- "project_generator.download_cache_for_template.success",
410
- template=template,
411
- event_info=(
412
- f"Downloaded cache for template, extracted to {project_folder}."
413
- ),
414
- )
415
- except aiohttp.ClientResponseError as e:
416
- if e.status == 403:
417
- structlogger.debug(
418
- "project_generator.download_cache_for_template.no_cache_found",
419
- template=template,
420
- event_info=("No cache found for template, continuing without it."),
421
- )
422
- else:
423
- structlogger.debug(
424
- "project_generator.download_cache_for_template.response_error",
425
- error=str(e),
426
- status=e.status,
427
- template=template,
428
- event_info=(
429
- "Failed to download cache for template, continuing without it."
430
- ),
431
- )
432
- capture_exception_with_context(
433
- e,
434
- "project_generator.download_cache_for_template.response_error",
435
- tags={"template": template.value, "status": str(e.status)},
436
- )
437
- except Exception as exc:
438
- structlogger.debug(
439
- "project_generator.download_cache_for_template.unexpected_error",
440
- error=str(exc),
441
- template=template,
442
- event_info=(
443
- "Unexpected error when downloading cache for template, "
444
- "continuing without it."
445
- ),
446
- )
447
- capture_exception_with_context(
448
- exc,
449
- "project_generator.download_cache_for_template.unexpected_error",
450
- tags={"template": template.value},
451
- )
452
- finally:
453
- # Clean up the temporary file
454
- try:
455
- Path(temporary_cache_file.name).unlink(missing_ok=True)
456
- except Exception as exc:
457
- structlogger.debug(
458
- "project_generator.download_cache_for_template.cleanup_error",
459
- error=str(exc),
460
- template=template,
461
- event_info=("Failed to cleanup cache for template, ignoring."),
462
- )