rasa-pro 3.14.0.dev7__py3-none-any.whl → 3.14.0.dev9__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 (471) hide show
  1. rasa/agents/agent_manager.py +1 -1
  2. rasa/agents/constants.py +2 -2
  3. rasa/agents/protocol/a2a/a2a_agent.py +385 -227
  4. rasa/agents/protocol/mcp/mcp_base_agent.py +30 -13
  5. rasa/agents/protocol/mcp/mcp_open_agent.py +31 -8
  6. rasa/agents/protocol/mcp/mcp_task_agent.py +32 -9
  7. rasa/agents/schemas/agent_output.py +1 -1
  8. rasa/agents/utils.py +90 -1
  9. rasa/builder/README.md +120 -0
  10. rasa/builder/__init__.py +0 -0
  11. rasa/builder/auth.py +176 -0
  12. rasa/builder/config.py +92 -0
  13. rasa/builder/copilot/__init__.py +0 -0
  14. rasa/builder/copilot/constants.py +31 -0
  15. rasa/builder/copilot/copilot.py +450 -0
  16. rasa/builder/copilot/copilot_response_handler.py +522 -0
  17. rasa/builder/copilot/copilot_templated_message_provider.py +58 -0
  18. rasa/builder/copilot/exceptions.py +32 -0
  19. rasa/builder/copilot/models.py +500 -0
  20. rasa/builder/copilot/prompts/__init__.py +0 -0
  21. rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +766 -0
  22. rasa/builder/copilot/prompts/latest_user_message_context_prompt.jinja2 +61 -0
  23. rasa/builder/copilot/signing.py +305 -0
  24. rasa/builder/copilot/telemetry.py +210 -0
  25. rasa/builder/copilot/templated_messages/__init__.py +0 -0
  26. rasa/builder/copilot/templated_messages/copilot_internal_messages_templates.yml +16 -0
  27. rasa/builder/copilot/templated_messages/copilot_templated_responses.yml +38 -0
  28. rasa/builder/document_retrieval/__init__.py +0 -0
  29. rasa/builder/document_retrieval/constants.py +15 -0
  30. rasa/builder/document_retrieval/inkeep-rag-response-schema.json +64 -0
  31. rasa/builder/document_retrieval/inkeep_document_retrieval.py +238 -0
  32. rasa/builder/document_retrieval/models.py +62 -0
  33. rasa/builder/download.py +140 -0
  34. rasa/builder/exceptions.py +91 -0
  35. rasa/builder/guardrails/__init__.py +1 -0
  36. rasa/builder/guardrails/constants.py +9 -0
  37. rasa/builder/guardrails/exceptions.py +4 -0
  38. rasa/builder/guardrails/lakera.py +206 -0
  39. rasa/builder/guardrails/models.py +231 -0
  40. rasa/builder/guardrails/store.py +238 -0
  41. rasa/builder/guardrails/utils.py +328 -0
  42. rasa/builder/job_manager.py +87 -0
  43. rasa/builder/jobs.py +282 -0
  44. rasa/builder/llm_service.py +246 -0
  45. rasa/builder/logging_utils.py +265 -0
  46. rasa/builder/main.py +243 -0
  47. rasa/builder/models.py +216 -0
  48. rasa/builder/project_generator.py +458 -0
  49. rasa/builder/project_info.py +72 -0
  50. rasa/builder/scrape_rasa_docs.py +97 -0
  51. rasa/builder/service.py +1345 -0
  52. rasa/builder/shared/tracker_context.py +212 -0
  53. rasa/builder/skill_to_bot_prompt.jinja2 +164 -0
  54. rasa/builder/template_cache.py +244 -0
  55. rasa/builder/training_service.py +194 -0
  56. rasa/builder/validation_service.py +97 -0
  57. rasa/cli/project_templates/basic/README.md +23 -0
  58. rasa/cli/project_templates/basic/actions/__init__ +0 -0
  59. rasa/cli/project_templates/basic/actions/action_human_handoff.py +40 -0
  60. rasa/cli/project_templates/basic/actions/actions.md +10 -0
  61. rasa/cli/project_templates/basic/config.yml +29 -0
  62. rasa/cli/project_templates/basic/credentials.yml +33 -0
  63. rasa/cli/project_templates/basic/data/data.md +9 -0
  64. rasa/cli/project_templates/basic/data/general/feedback.yml +21 -0
  65. rasa/cli/project_templates/basic/data/general/goodbye.yml +6 -0
  66. rasa/cli/project_templates/basic/data/general/hello.yml +6 -0
  67. rasa/cli/project_templates/basic/data/general/help.yml +6 -0
  68. rasa/cli/project_templates/basic/data/general/human_handoff.yml +16 -0
  69. rasa/cli/project_templates/basic/data/general/show_faqs.yml +6 -0
  70. rasa/cli/project_templates/basic/data/system/patterns/pattern_cannot_handle.yml +7 -0
  71. rasa/cli/project_templates/basic/data/system/patterns/pattern_completed.yml +7 -0
  72. rasa/cli/project_templates/basic/data/system/patterns/pattern_correction.yml +7 -0
  73. rasa/cli/project_templates/basic/data/system/patterns/pattern_search.yml +8 -0
  74. rasa/cli/project_templates/basic/data/system/patterns/pattern_session_start.yml +8 -0
  75. rasa/cli/project_templates/basic/docs/docs.md +5 -0
  76. rasa/cli/project_templates/basic/docs/template.txt +28 -0
  77. rasa/cli/project_templates/basic/domain/domain.md +8 -0
  78. rasa/cli/project_templates/basic/domain/general/feedback.yml +25 -0
  79. rasa/cli/project_templates/basic/domain/general/goodbye.yml +9 -0
  80. rasa/cli/project_templates/basic/domain/general/hello.yml +7 -0
  81. rasa/cli/project_templates/basic/domain/general/help.yml +21 -0
  82. rasa/cli/project_templates/basic/domain/general/human_handoff.yml +32 -0
  83. rasa/cli/project_templates/basic/domain/general/show_faqs.yml +14 -0
  84. rasa/cli/project_templates/basic/domain/system/patterns/pattern_cannot_handle.yml +5 -0
  85. rasa/cli/project_templates/basic/domain/system/patterns/pattern_session_start.yml +19 -0
  86. rasa/cli/project_templates/basic/endpoints.yml +67 -0
  87. rasa/cli/project_templates/basic/prompts/rephraser_demo_personality_prompt.jinja2 +38 -0
  88. rasa/cli/project_templates/default/config.yml +4 -0
  89. rasa/cli/project_templates/default/endpoints.yml +4 -0
  90. rasa/cli/project_templates/finance/README.md +25 -0
  91. rasa/cli/project_templates/finance/actions/__init__.py +46 -0
  92. rasa/cli/project_templates/finance/actions/accounts/__init__.py +0 -0
  93. rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +47 -0
  94. rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +40 -0
  95. rasa/cli/project_templates/finance/actions/action_session_start.py +74 -0
  96. rasa/cli/project_templates/finance/actions/actions.md +15 -0
  97. rasa/cli/project_templates/finance/actions/cards/__init__.py +0 -0
  98. rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +48 -0
  99. rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +36 -0
  100. rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +54 -0
  101. rasa/cli/project_templates/finance/actions/database.py +277 -0
  102. rasa/cli/project_templates/finance/actions/transfers/__init__.py +0 -0
  103. rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +52 -0
  104. rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +51 -0
  105. rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +40 -0
  106. rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +40 -0
  107. rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +46 -0
  108. rasa/cli/project_templates/finance/actions/transfers/action_process_immediate_payment.py +18 -0
  109. rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +49 -0
  110. rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +19 -0
  111. rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +36 -0
  112. rasa/cli/project_templates/finance/config.yml +23 -0
  113. rasa/cli/project_templates/finance/credentials.yml +32 -0
  114. rasa/cli/project_templates/finance/csvs/accounts.csv +8 -0
  115. rasa/cli/project_templates/finance/csvs/advisors.csv +7 -0
  116. rasa/cli/project_templates/finance/csvs/appointments.csv +211 -0
  117. rasa/cli/project_templates/finance/csvs/branches.csv +10 -0
  118. rasa/cli/project_templates/finance/csvs/cards.csv +11 -0
  119. rasa/cli/project_templates/finance/csvs/payees.csv +11 -0
  120. rasa/cli/project_templates/finance/csvs/transactions.csv +71 -0
  121. rasa/cli/project_templates/finance/csvs/users.csv +4 -0
  122. rasa/cli/project_templates/finance/data/accounts/check_balance.yml +10 -0
  123. rasa/cli/project_templates/finance/data/cards/block_card.yml +66 -0
  124. rasa/cli/project_templates/finance/data/cards/select_card.yml +12 -0
  125. rasa/cli/project_templates/finance/data/data.md +11 -0
  126. rasa/cli/project_templates/finance/data/general/bot_identity.yml +6 -0
  127. rasa/cli/project_templates/finance/data/general/feedback.yml +20 -0
  128. rasa/cli/project_templates/finance/data/general/goodbye.yml +6 -0
  129. rasa/cli/project_templates/finance/data/general/hello.yml +7 -0
  130. rasa/cli/project_templates/finance/data/general/help.yml +9 -0
  131. rasa/cli/project_templates/finance/data/general/human_handoff.yml +16 -0
  132. rasa/cli/project_templates/finance/data/general/welcome.yml +9 -0
  133. rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +5 -0
  134. rasa/cli/project_templates/finance/data/system/patterns/pattern_completed.yml +7 -0
  135. rasa/cli/project_templates/finance/data/system/patterns/pattern_correction.yml +7 -0
  136. rasa/cli/project_templates/finance/data/system/patterns/pattern_search.yml +8 -0
  137. rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +8 -0
  138. rasa/cli/project_templates/finance/data/system/source/accounts.json +51 -0
  139. rasa/cli/project_templates/finance/data/system/source/advisors.json +44 -0
  140. rasa/cli/project_templates/finance/data/system/source/appointments.json +1474 -0
  141. rasa/cli/project_templates/finance/data/system/source/branches.json +47 -0
  142. rasa/cli/project_templates/finance/data/system/source/cards.json +72 -0
  143. rasa/cli/project_templates/finance/data/system/source/payees.json +74 -0
  144. rasa/cli/project_templates/finance/data/system/source/transactions.json +492 -0
  145. rasa/cli/project_templates/finance/data/system/source/users.json +29 -0
  146. rasa/cli/project_templates/finance/data/transfers/add_payee.yml +29 -0
  147. rasa/cli/project_templates/finance/data/transfers/list_payees.yml +5 -0
  148. rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +21 -0
  149. rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +67 -0
  150. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +8 -0
  151. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +8 -0
  152. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +8 -0
  153. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +8 -0
  154. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +8 -0
  155. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +7 -0
  156. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +8 -0
  157. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +8 -0
  158. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +8 -0
  159. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +8 -0
  160. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +8 -0
  161. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +8 -0
  162. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +8 -0
  163. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +8 -0
  164. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +8 -0
  165. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +8 -0
  166. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +8 -0
  167. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +8 -0
  168. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +8 -0
  169. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +8 -0
  170. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +50 -0
  171. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +50 -0
  172. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +48 -0
  173. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +50 -0
  174. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +50 -0
  175. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +47 -0
  176. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +50 -0
  177. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +50 -0
  178. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +47 -0
  179. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +50 -0
  180. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +50 -0
  181. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +50 -0
  182. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +47 -0
  183. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +50 -0
  184. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +50 -0
  185. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +47 -0
  186. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +50 -0
  187. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +50 -0
  188. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +47 -0
  189. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +50 -0
  190. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +50 -0
  191. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +47 -0
  192. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +47 -0
  193. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +50 -0
  194. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +50 -0
  195. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +47 -0
  196. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +50 -0
  197. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +50 -0
  198. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +47 -0
  199. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +50 -0
  200. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +50 -0
  201. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +47 -0
  202. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +50 -0
  203. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +50 -0
  204. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +50 -0
  205. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +47 -0
  206. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +50 -0
  207. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +50 -0
  208. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +47 -0
  209. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +50 -0
  210. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +50 -0
  211. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +47 -0
  212. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +50 -0
  213. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +50 -0
  214. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +50 -0
  215. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +47 -0
  216. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +50 -0
  217. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +50 -0
  218. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +47 -0
  219. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +50 -0
  220. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +50 -0
  221. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +47 -0
  222. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +50 -0
  223. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +50 -0
  224. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +47 -0
  225. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +47 -0
  226. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +50 -0
  227. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +50 -0
  228. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +50 -0
  229. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +50 -0
  230. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +47 -0
  231. rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +11 -0
  232. rasa/cli/project_templates/finance/domain/cards/block_card.yml +101 -0
  233. rasa/cli/project_templates/finance/domain/cards/select_card.yml +12 -0
  234. rasa/cli/project_templates/finance/domain/domain.md +10 -0
  235. rasa/cli/project_templates/finance/domain/general/agent_details.yml +12 -0
  236. rasa/cli/project_templates/finance/domain/general/bot_identity.yml +5 -0
  237. rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -0
  238. rasa/cli/project_templates/finance/domain/general/defaults.yml +24 -0
  239. rasa/cli/project_templates/finance/domain/general/feedback.yml +28 -0
  240. rasa/cli/project_templates/finance/domain/general/goodbye.yml +7 -0
  241. rasa/cli/project_templates/finance/domain/general/help.yml +5 -0
  242. rasa/cli/project_templates/finance/domain/general/human_handoff.yml +30 -0
  243. rasa/cli/project_templates/finance/domain/general/utils.yml +13 -0
  244. rasa/cli/project_templates/finance/domain/general/welcome.yml +8 -0
  245. rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +47 -0
  246. rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +4 -0
  247. rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +16 -0
  248. rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +79 -0
  249. rasa/cli/project_templates/finance/endpoints.yml +66 -0
  250. rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +19 -0
  251. rasa/cli/project_templates/telco/README.md +25 -0
  252. rasa/cli/project_templates/telco/actions/__init__.py +0 -0
  253. rasa/cli/project_templates/telco/actions/actions.md +12 -0
  254. rasa/cli/project_templates/telco/actions/billing/__init__.py +0 -0
  255. rasa/cli/project_templates/telco/actions/billing/actions_billing.py +204 -0
  256. rasa/cli/project_templates/telco/actions/general/__init__.py +0 -0
  257. rasa/cli/project_templates/telco/actions/general/action_human_handoff.py +49 -0
  258. rasa/cli/project_templates/telco/actions/network/__init__.py +0 -0
  259. rasa/cli/project_templates/telco/actions/network/actions_get_data_from_db.py +48 -0
  260. rasa/cli/project_templates/telco/actions/network/actions_run_diagnostics.py +28 -0
  261. rasa/cli/project_templates/telco/actions/network/actions_session_start.py +18 -0
  262. rasa/cli/project_templates/telco/config.yml +29 -0
  263. rasa/cli/project_templates/telco/credentials.yml +33 -0
  264. rasa/cli/project_templates/telco/csvs/billing.csv +19 -0
  265. rasa/cli/project_templates/telco/csvs/customers.csv +5 -0
  266. rasa/cli/project_templates/telco/data/billing/flow_understand_bill.yml +45 -0
  267. rasa/cli/project_templates/telco/data/data.md +11 -0
  268. rasa/cli/project_templates/telco/data/general/bot_challenge.yml +6 -0
  269. rasa/cli/project_templates/telco/data/general/feedback.yml +20 -0
  270. rasa/cli/project_templates/telco/data/general/goodbye.yml +6 -0
  271. rasa/cli/project_templates/telco/data/general/hello.yml +6 -0
  272. rasa/cli/project_templates/telco/data/general/human_handoff.yml +16 -0
  273. rasa/cli/project_templates/telco/data/general/patterns.yml +30 -0
  274. rasa/cli/project_templates/telco/data/network/flow_reboot_router.yml +8 -0
  275. rasa/cli/project_templates/telco/data/network/flow_reset_router.yml +7 -0
  276. rasa/cli/project_templates/telco/data/network/flow_solve_internet_issue.yml +73 -0
  277. rasa/cli/project_templates/telco/docs/docs.md +5 -0
  278. rasa/cli/project_templates/telco/docs/network/reset_vs_rboot_router.txt +1 -0
  279. rasa/cli/project_templates/telco/docs/network/restart_router.txt +6 -0
  280. rasa/cli/project_templates/telco/docs/network/run_speed_test.txt +6 -0
  281. rasa/cli/project_templates/telco/domain/billing/understand_bill.yml +102 -0
  282. rasa/cli/project_templates/telco/domain/domain.md +14 -0
  283. rasa/cli/project_templates/telco/domain/general/bot_challenge.yml +4 -0
  284. rasa/cli/project_templates/telco/domain/general/feedback.yml +25 -0
  285. rasa/cli/project_templates/telco/domain/general/goodbye.yml +7 -0
  286. rasa/cli/project_templates/telco/domain/general/hello.yml +5 -0
  287. rasa/cli/project_templates/telco/domain/general/human_handoff.yml +26 -0
  288. rasa/cli/project_templates/telco/domain/general/patterns.yml +33 -0
  289. rasa/cli/project_templates/telco/domain/network/reboot_router.yml +21 -0
  290. rasa/cli/project_templates/telco/domain/network/reset_router.yml +12 -0
  291. rasa/cli/project_templates/telco/domain/network/run_speed_test.yml +25 -0
  292. rasa/cli/project_templates/telco/domain/network/solve_internet_issue.yml +75 -0
  293. rasa/cli/project_templates/telco/domain/shared.yml +129 -0
  294. rasa/cli/project_templates/telco/endpoints.yml +67 -0
  295. rasa/cli/project_templates/telco/prompts/rephraser_demo_personality_prompt.jinja2 +40 -0
  296. rasa/cli/project_templates/telco/tests/e2e_test_cases/billing/understand_bill.yml +67 -0
  297. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
  298. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/feedback.yml +46 -0
  299. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/goodbye.yml +9 -0
  300. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/hello.yml +8 -0
  301. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/human_handoff.yml +35 -0
  302. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/patterns.yml +23 -0
  303. rasa/cli/project_templates/telco/tests/e2e_test_cases/network/solve_internet_issue.yml +57 -0
  304. rasa/cli/project_templates/tutorial/config.yml +2 -1
  305. rasa/cli/scaffold.py +46 -2
  306. rasa/core/actions/action.py +0 -1
  307. rasa/core/available_agents.py +2 -0
  308. rasa/core/available_endpoints.py +17 -2
  309. rasa/core/channels/channel.py +4 -3
  310. rasa/core/channels/constants.py +3 -0
  311. rasa/core/channels/development_inspector.py +2 -22
  312. rasa/core/channels/inspector/README.md +26 -14
  313. rasa/core/channels/inspector/dist/assets/{arc-cce7e0a8.js → arc-edef10dd.js} +1 -1
  314. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-e2a49be7.js → blockDiagram-38ab4fdb-49f6762b.js} +1 -1
  315. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-3def7895.js → c4Diagram-3d4e48cf-313c08e6.js} +1 -1
  316. rasa/core/channels/inspector/dist/assets/channel-63aa27d1.js +1 -0
  317. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-e66fe4df.js → classDiagram-70f12bd4-35e41ce9.js} +1 -1
  318. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-eb874aaa.js → classDiagram-v2-f2320105-f346068d.js} +1 -1
  319. rasa/core/channels/inspector/dist/assets/clone-5566bae8.js +1 -0
  320. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-cf934643.js → createText-2e5e7dd3-7a44bce8.js} +1 -1
  321. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-8fdf9155.js → edges-e0da2a9e-d7cf78c7.js} +1 -1
  322. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-6106fb96.js → erDiagram-9861fffd-9813e81c.js} +1 -1
  323. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-4c2bb040.js → flowDb-956e92f1-d8ba0870.js} +1 -1
  324. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-f0ff96af.js → flowDiagram-66a62f08-51f0db4d.js} +1 -1
  325. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-32936074.js +1 -0
  326. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a21707ec.js → flowchart-elk-definition-4a651766-ff9ea384.js} +1 -1
  327. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-c165acb1.js → ganttDiagram-c361ad54-a8e13b6b.js} +1 -1
  328. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-b0564cf1.js → gitGraphDiagram-72cf32ee-3b171c6d.js} +1 -1
  329. rasa/core/channels/inspector/dist/assets/{graph-e557e67a.js → graph-790ef78b.js} +1 -1
  330. rasa/core/channels/inspector/dist/assets/{index-3862675e-1ce60e9e.js → index-3862675e-ecdce073.js} +1 -1
  331. rasa/core/channels/inspector/dist/assets/index-d705da80.js +1352 -0
  332. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-893569e2.js → infoDiagram-f8f76790-f5a422fe.js} +1 -1
  333. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-c29c864f.js → journeyDiagram-49397b02-3185b7ac.js} +1 -1
  334. rasa/core/channels/inspector/dist/assets/{layout-649a5eae.js → layout-837fd3aa.js} +1 -1
  335. rasa/core/channels/inspector/dist/assets/{line-0e5685ed.js → line-7e05afcb.js} +1 -1
  336. rasa/core/channels/inspector/dist/assets/{linear-eaa320bd.js → linear-162eb295.js} +1 -1
  337. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-f35df9e6.js → mindmap-definition-fc14e90a-f4978aee.js} +1 -1
  338. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-78339e96.js → pieDiagram-8a3498a8-b25d0a52.js} +1 -1
  339. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-9b5f2f14.js → quadrantDiagram-120e2f19-63db1afa.js} +1 -1
  340. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-d05ddb3a.js → requirementDiagram-deff3bca-1b486cc9.js} +1 -1
  341. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-d9be5dfd.js → sankeyDiagram-04a897e0-7e795291.js} +1 -1
  342. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-0f1c4348.js → sequenceDiagram-704730f1-b8aba159.js} +1 -1
  343. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-9ddf63b3.js → stateDiagram-587899a1-41529fd5.js} +1 -1
  344. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-bc2b81ed.js → stateDiagram-v2-d93cdb3a-b241043c.js} +1 -1
  345. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-0a287936.js → styles-6aaf32cf-b5b53234.js} +1 -1
  346. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-e3941990.js → styles-9a916d00-13d138e5.js} +1 -1
  347. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-ce4eca24.js → styles-c10674c1-94cbde3f.js} +1 -1
  348. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-d822b1a8.js → svgDrawCommon-08f97a94-453ae764.js} +1 -1
  349. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-e144c7a7.js → timeline-definition-85554ec2-8dcb88a4.js} +1 -1
  350. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-ab7f4e14.js → xychartDiagram-e933f94c-376af5f0.js} +1 -1
  351. rasa/core/channels/inspector/dist/index.html +2 -2
  352. rasa/core/channels/inspector/index.html +1 -1
  353. rasa/core/channels/inspector/src/App.tsx +16 -42
  354. rasa/core/channels/inspector/src/components/Chat.tsx +2 -3
  355. rasa/core/channels/inspector/src/components/DialogueHistoryStack.tsx +1 -0
  356. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +20 -3
  357. rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +63 -35
  358. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +14 -0
  359. rasa/core/channels/inspector/src/types.ts +32 -7
  360. rasa/core/channels/socketio.py +212 -51
  361. rasa/core/channels/studio_chat.py +59 -57
  362. rasa/core/channels/voice_stream/asr/asr_event.py +1 -1
  363. rasa/core/channels/voice_stream/asr/azure.py +6 -3
  364. rasa/core/channels/voice_stream/asr/deepgram.py +1 -1
  365. rasa/core/channels/voice_stream/audiocodes.py +3 -0
  366. rasa/core/channels/voice_stream/browser_audio.py +53 -3
  367. rasa/core/channels/voice_stream/genesys.py +2 -1
  368. rasa/core/channels/voice_stream/jambonz.py +9 -1
  369. rasa/core/channels/voice_stream/twilio_media_streams.py +16 -0
  370. rasa/core/channels/voice_stream/voice_channel.py +66 -3
  371. rasa/core/constants.py +6 -0
  372. rasa/core/iam_credentials_providers/__init__.py +0 -0
  373. rasa/core/iam_credentials_providers/aws_iam_credentials_providers.py +66 -0
  374. rasa/core/iam_credentials_providers/credentials_provider_protocol.py +89 -0
  375. rasa/core/policies/enterprise_search_policy.py +4 -7
  376. rasa/core/policies/flows/flow_executor.py +14 -5
  377. rasa/core/policies/ted_policy.py +7 -5
  378. rasa/core/processor.py +32 -0
  379. rasa/core/redis_connection_factory.py +411 -0
  380. rasa/core/run.py +13 -3
  381. rasa/core/tracker_stores/redis_tracker_store.py +32 -14
  382. rasa/core/tracker_stores/sql_tracker_store.py +57 -1
  383. rasa/dialogue_understanding/generator/flow_retrieval.py +10 -9
  384. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +10 -5
  385. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +10 -5
  386. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +20 -12
  387. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +19 -12
  388. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +6 -35
  389. rasa/dialogue_understanding/patterns/cancel.py +27 -6
  390. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +1 -1
  391. rasa/dialogue_understanding/processor/command_processor.py +35 -0
  392. rasa/engine/graph.py +5 -1
  393. rasa/engine/recipes/default_components.py +78 -10
  394. rasa/engine/recipes/default_recipe.py +41 -1
  395. rasa/engine/storage/local_model_storage.py +83 -3
  396. rasa/graph_components/validators/default_recipe_validator.py +153 -135
  397. rasa/model_manager/model_api.py +4 -5
  398. rasa/model_manager/runner_service.py +1 -1
  399. rasa/model_manager/socket_bridge.py +20 -15
  400. rasa/model_manager/trainer_service.py +12 -9
  401. rasa/model_manager/utils.py +1 -29
  402. rasa/model_manager/warm_rasa_process.py +1 -1
  403. rasa/model_training.py +14 -0
  404. rasa/nlu/classifiers/diet_classifier.py +22 -6
  405. rasa/nlu/classifiers/logistic_regression_classifier.py +18 -0
  406. rasa/nlu/extractors/extractor.py +1 -2
  407. rasa/shared/agents/auth/__init__.py +0 -0
  408. rasa/shared/agents/auth/agent_auth_factory.py +74 -0
  409. rasa/shared/agents/auth/agent_auth_manager.py +86 -0
  410. rasa/shared/agents/auth/auth_strategy/__init__.py +19 -0
  411. rasa/shared/agents/auth/auth_strategy/agent_auth_strategy.py +52 -0
  412. rasa/shared/agents/auth/auth_strategy/api_key_auth_strategy.py +42 -0
  413. rasa/shared/agents/auth/auth_strategy/bearer_token_auth_strategy.py +28 -0
  414. rasa/shared/agents/auth/auth_strategy/oauth2_auth_strategy.py +159 -0
  415. rasa/shared/agents/auth/constants.py +11 -0
  416. rasa/shared/agents/auth/types.py +11 -0
  417. rasa/shared/core/constants.py +1 -0
  418. rasa/shared/core/domain.py +58 -11
  419. rasa/shared/core/events.py +2 -0
  420. rasa/shared/core/flows/constants.py +5 -0
  421. rasa/shared/core/flows/flow_step.py +7 -1
  422. rasa/shared/core/flows/flows_list.py +6 -0
  423. rasa/shared/core/flows/steps/call.py +15 -12
  424. rasa/shared/core/flows/validation.py +238 -44
  425. rasa/shared/core/flows/yaml_flows_io.py +15 -6
  426. rasa/shared/core/slots.py +4 -0
  427. rasa/shared/exceptions.py +12 -0
  428. rasa/shared/importers/importer.py +6 -0
  429. rasa/shared/importers/utils.py +77 -1
  430. rasa/shared/nlu/training_data/schemas/responses.yml +3 -0
  431. rasa/shared/providers/_utils.py +60 -44
  432. rasa/shared/providers/embedding/default_litellm_embedding_client.py +2 -0
  433. rasa/shared/providers/llm/_base_litellm_client.py +2 -2
  434. rasa/shared/providers/llm/default_litellm_llm_client.py +2 -0
  435. rasa/shared/providers/llm/llm_response.py +4 -4
  436. rasa/shared/utils/common.py +24 -0
  437. rasa/shared/utils/llm.py +2 -1
  438. rasa/shared/utils/mcp/server_connection.py +84 -23
  439. rasa/shared/utils/mcp/utils.py +20 -0
  440. rasa/studio/upload.py +16 -47
  441. rasa/telemetry.py +97 -23
  442. rasa/tracing/config.py +38 -12
  443. rasa/tracing/instrumentation/attribute_extractors.py +5 -1
  444. rasa/tracing/instrumentation/instrumentation.py +85 -8
  445. rasa/utils/common.py +1 -1
  446. rasa/utils/io.py +27 -9
  447. rasa/utils/json_utils.py +6 -1
  448. rasa/utils/log_utils.py +5 -1
  449. rasa/utils/openapi.py +144 -0
  450. rasa/utils/tensorflow/__init__.py +29 -0
  451. rasa/utils/tensorflow/callback.py +1 -1
  452. rasa/utils/tensorflow/crf.py +1 -1
  453. rasa/utils/tensorflow/data_generator.py +21 -8
  454. rasa/utils/tensorflow/layers.py +11 -4
  455. rasa/utils/tensorflow/metrics.py +7 -3
  456. rasa/utils/tensorflow/models.py +41 -6
  457. rasa/utils/tensorflow/rasa_layers.py +6 -4
  458. rasa/utils/tensorflow/transformer.py +2 -3
  459. rasa/utils/train_utils.py +68 -38
  460. rasa/validator.py +18 -16
  461. rasa/version.py +1 -1
  462. rasa_pro-3.14.0.dev9.dist-info/METADATA +199 -0
  463. {rasa_pro-3.14.0.dev7.dist-info → rasa_pro-3.14.0.dev9.dist-info}/RECORD +466 -156
  464. rasa/core/channels/inspector/dist/assets/channel-858c2c20.js +0 -1
  465. rasa/core/channels/inspector/dist/assets/clone-4b80996c.js +0 -1
  466. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-16f09b7a.js +0 -1
  467. rasa/core/channels/inspector/dist/assets/index-996fe816.js +0 -1353
  468. rasa_pro-3.14.0.dev7.dist-info/METADATA +0 -190
  469. {rasa_pro-3.14.0.dev7.dist-info → rasa_pro-3.14.0.dev9.dist-info}/NOTICE +0 -0
  470. {rasa_pro-3.14.0.dev7.dist-info → rasa_pro-3.14.0.dev9.dist-info}/WHEEL +0 -0
  471. {rasa_pro-3.14.0.dev7.dist-info → rasa_pro-3.14.0.dev9.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,458 @@
1
+ """Service for generating Rasa projects from prompts."""
2
+
3
+ import json
4
+ import os
5
+ import shutil
6
+ from pathlib import Path
7
+ from textwrap import dedent
8
+ from typing import Any, Dict, Generator, List, Optional
9
+
10
+ import structlog
11
+
12
+ from rasa.builder import config
13
+ from rasa.builder.exceptions import ProjectGenerationError, ValidationError
14
+ from rasa.builder.llm_service import get_skill_generation_messages, llm_service
15
+ from rasa.builder.logging_utils import capture_exception_with_context
16
+ from rasa.builder.models import BotFiles
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
19
+ from rasa.builder.training_service import TrainingInput
20
+ from rasa.builder.validation_service import validate_project
21
+ from rasa.cli.scaffold import ProjectTemplateName, create_initial_project
22
+ from rasa.shared.constants import DEFAULT_MODELS_PATH
23
+ from rasa.shared.core.flows import yaml_flows_io
24
+ from rasa.shared.importers.importer import TrainingDataImporter
25
+ from rasa.shared.utils.yaml import dump_obj_as_yaml_to_string
26
+ from rasa.utils.io import InvalidPathException, subpath
27
+
28
+ structlogger = structlog.get_logger()
29
+
30
+
31
+ class ProjectGenerator:
32
+ """Service for generating Rasa projects from skill descriptions."""
33
+
34
+ def __init__(self, project_folder: str) -> None:
35
+ """Initialize the project generator with a folder for file persistence.
36
+
37
+ Args:
38
+ project_folder: Path to the folder where project files will be stored
39
+ """
40
+ self.project_folder = Path(project_folder)
41
+ self.project_folder.mkdir(parents=True, exist_ok=True)
42
+
43
+ @property
44
+ def project_info(self) -> ProjectInfo:
45
+ """Get the project info."""
46
+ return load_project_info(self.project_folder)
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
+
59
+ async def init_from_template(self, template: ProjectTemplateName) -> None:
60
+ """Create the initial project files."""
61
+ self.cleanup()
62
+ create_initial_project(self.project_folder.as_posix(), template)
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
+ copy_cache_for_template_if_available(template, self.project_folder)
66
+ # needs to happen after caching, as we download/copy .rasa and that would
67
+ # overwrite the project info file in .rasa
68
+ ensure_first_used(self.project_folder)
69
+
70
+ async def generate_project_with_retries(
71
+ self,
72
+ skill_description: str,
73
+ template: ProjectTemplateName,
74
+ max_retries: Optional[int] = None,
75
+ ) -> Dict[str, Optional[str]]:
76
+ """Generate a Rasa project with retry logic for validation failures.
77
+
78
+ Args:
79
+ skill_description: Natural language description of the skill
80
+ rasa_config: Rasa configuration dictionary
81
+ template: Project template to use for the initial project
82
+ max_retries: Maximum number of retry attempts
83
+
84
+ Returns:
85
+ Dictionary of generated file contents (filename -> content)
86
+
87
+ Raises:
88
+ ProjectGenerationError: If generation fails after all retries
89
+ """
90
+ if max_retries is None:
91
+ max_retries = config.MAX_RETRIES
92
+
93
+ # if ever we do not use the template, we need to ensure first_used is set
94
+ # separately!
95
+ await self.init_from_template(template)
96
+
97
+ project_data = self._get_bot_data_for_llm()
98
+
99
+ initial_messages = get_skill_generation_messages(
100
+ skill_description, project_data
101
+ )
102
+
103
+ async def _generate_with_retry(
104
+ messages: List[Dict[str, Any]], attempts_left: int
105
+ ) -> Dict[str, Optional[str]]:
106
+ try:
107
+ # Generate project data using LLM
108
+ project_data = await llm_service.generate_rasa_project(messages)
109
+
110
+ # Update stored bot data
111
+ self._update_bot_files_from_llm_response(project_data)
112
+
113
+ bot_files = self.get_bot_files()
114
+ structlogger.info(
115
+ "project_generator.generated_project",
116
+ attempts_left=attempts_left,
117
+ files=list(bot_files.keys()),
118
+ )
119
+
120
+ # Validate the generated project
121
+ await self._validate_generated_project()
122
+
123
+ structlogger.info(
124
+ "project_generator.validation_success", attempts_left=attempts_left
125
+ )
126
+
127
+ return bot_files
128
+
129
+ except ValidationError as e:
130
+ structlogger.error(
131
+ "project_generator.validation_error",
132
+ error=str(e),
133
+ attempts_left=attempts_left,
134
+ )
135
+
136
+ if attempts_left <= 0:
137
+ raise ProjectGenerationError(
138
+ f"Failed to generate valid Rasa project: {e}", max_retries
139
+ )
140
+
141
+ # Create error feedback for next attempt
142
+ error_feedback_messages = messages + [
143
+ {
144
+ "role": "assistant",
145
+ "content": json.dumps(project_data),
146
+ },
147
+ {
148
+ "role": "user",
149
+ "content": dedent(f"""
150
+ Previous attempt failed validation with error: {e}
151
+
152
+ Please fix the issues and generate a valid Rasa project.
153
+ Pay special attention to:
154
+ - Proper YAML syntax
155
+ - Required fields in domain and flows
156
+ - Consistent naming between flows and domain
157
+ - Valid slot types and mappings
158
+ """).strip(),
159
+ },
160
+ ]
161
+
162
+ return await _generate_with_retry(
163
+ error_feedback_messages, attempts_left - 1
164
+ )
165
+
166
+ except Exception as e:
167
+ structlogger.error(
168
+ "project_generator.generation_error",
169
+ error=str(e),
170
+ attempts_left=attempts_left,
171
+ )
172
+
173
+ if attempts_left <= 0:
174
+ raise ProjectGenerationError(
175
+ f"Failed to generate Rasa project: {e}", max_retries
176
+ )
177
+
178
+ # For non-validation errors, retry with original messages
179
+ return await _generate_with_retry(initial_messages, attempts_left - 1)
180
+
181
+ return await _generate_with_retry(initial_messages, max_retries)
182
+
183
+ async def _validate_generated_project(self) -> None:
184
+ """Validate the generated project using the validation service."""
185
+ importer = self._create_importer()
186
+ validation_error = await validate_project(importer)
187
+
188
+ if validation_error:
189
+ raise ValidationError(validation_error)
190
+
191
+ def _get_endpoints_file(self) -> Path:
192
+ """Get the endpoints file."""
193
+ return self.project_folder / "endpoints.yml"
194
+
195
+ def get_training_input(self) -> TrainingInput:
196
+ """Get the training input."""
197
+ return TrainingInput(
198
+ importer=self._create_importer(),
199
+ endpoints_file=self._get_endpoints_file(),
200
+ )
201
+
202
+ def _create_importer(self) -> TrainingDataImporter:
203
+ """Create a training data importer from the current bot files."""
204
+ try:
205
+ if (self.project_folder / "domain.yml").exists():
206
+ domain_path = self.project_folder / "domain.yml"
207
+ else:
208
+ domain_path = self.project_folder / "domain"
209
+
210
+ return TrainingDataImporter.load_from_config(
211
+ config_path=str(self.project_folder / "config.yml"),
212
+ domain_path=str(domain_path),
213
+ training_data_paths=[str(self.project_folder / "data")],
214
+ args={},
215
+ )
216
+
217
+ except Exception as e:
218
+ raise ValidationError(f"Failed to create importer: {e}")
219
+
220
+ def get_bot_files(
221
+ self,
222
+ allowed_file_extensions: Optional[List[str]] = None,
223
+ exclude_docs_directory: bool = False,
224
+ ) -> BotFiles:
225
+ """Get the current bot files by reading from disk.
226
+
227
+ Args:
228
+ allowed_file_extensions: Optional list of file extensions to include.
229
+ If None, fetch all files. If provided, only fetch files with matching
230
+ extensions. Use `""` empty string to allow files with no extensions.
231
+ exclude_docs_directory: Optional boolean indicating whether to exclude.
232
+
233
+ Returns:
234
+ Dictionary of file contents with relative paths as keys
235
+ """
236
+ bot_files: BotFiles = {}
237
+
238
+ for file in self.bot_file_paths():
239
+ relative_path = file.relative_to(self.project_folder)
240
+
241
+ # Exclude the docs directory if specified
242
+ if exclude_docs_directory and relative_path.parts[0] == "docs":
243
+ continue
244
+
245
+ # Exclude the files by file extensions if specified
246
+ if allowed_file_extensions is not None:
247
+ allowed_file_extensions = [
248
+ ext.lower() for ext in allowed_file_extensions
249
+ ]
250
+ if file.suffix.lstrip(".").lower() not in allowed_file_extensions:
251
+ continue
252
+ # Read file content and store with relative path as key
253
+ try:
254
+ bot_files[relative_path.as_posix()] = file.read_text(encoding="utf-8")
255
+ except Exception as e:
256
+ structlogger.debug(
257
+ "project_generator.get_bot_files.error",
258
+ error=str(e),
259
+ file_path=file.as_posix(),
260
+ )
261
+ bot_files[relative_path.as_posix()] = None
262
+ return bot_files
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
+
296
+ def _get_bot_data_for_llm(self) -> Dict[str, Any]:
297
+ """Get the current bot data for the LLM."""
298
+ file_importer = self._create_importer()
299
+
300
+ # only include data created by the user (or the builder llm)
301
+ # avoid including to many defaults that are not customized
302
+ domain = file_importer.get_user_domain()
303
+ flows = file_importer.get_user_flows()
304
+
305
+ return {
306
+ "domain": domain.as_dict(should_clean_json=True),
307
+ "flows": yaml_flows_io.get_flows_as_json(flows, should_clean_json=True),
308
+ }
309
+
310
+ def _path_for_flow(self, flow_id: str) -> str:
311
+ """Get the path for a flow."""
312
+ if flow_id.startswith("pattern_"):
313
+ return f"data/patterns/{flow_id}.yml"
314
+ else:
315
+ return f"data/flows/{flow_id}.yml"
316
+
317
+ def _update_bot_files_from_llm_response(self, project_data: Dict[str, Any]) -> None:
318
+ """Update the bot files with generated data by writing to disk."""
319
+ files = {"domain.yml": dump_obj_as_yaml_to_string(project_data["domain"])}
320
+ # split up flows into one file per flow in the /flows folder
321
+ for flow_id, flow_data in project_data["flows"].get("flows", {}).items():
322
+ flow_file_path = self._path_for_flow(flow_id)
323
+ single_flow_file_data = {"flows": {flow_id: flow_data}}
324
+ files[flow_file_path] = dump_obj_as_yaml_to_string(single_flow_file_data)
325
+
326
+ # removes any other flows that the LLM didn't generate
327
+ self._cleanup_flows()
328
+ self.update_bot_files(files)
329
+
330
+ def _cleanup_flows(self) -> None:
331
+ """Cleanup the flows folder."""
332
+ flows_folder = self.project_folder / "data" / "flows"
333
+ if flows_folder.exists():
334
+ shutil.rmtree(flows_folder)
335
+ flows_folder.mkdir(parents=True, exist_ok=True)
336
+
337
+ def update_bot_files(self, files: Dict[str, Optional[str]]) -> None:
338
+ """Update bot files with new content by writing to disk."""
339
+ for filename, content in files.items():
340
+ file_path = Path(subpath(str(self.project_folder), filename))
341
+ # Disallow updates inside .rasa project metadata directory
342
+ if any(
343
+ part.startswith(".")
344
+ for part in file_path.relative_to(self.project_folder).parts
345
+ ):
346
+ # silently ignore hidden paths
347
+ continue
348
+ file_path.parent.mkdir(parents=True, exist_ok=True)
349
+ file_path.write_text(content, encoding="utf-8")
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
+
440
+ def cleanup(self) -> None:
441
+ """Cleanup the project folder."""
442
+ # remove all the files and folders in the project folder resulting
443
+ # in an empty folder
444
+ for filename in os.listdir(self.project_folder):
445
+ file_path = os.path.join(self.project_folder, filename)
446
+ try:
447
+ if filename == "lost+found":
448
+ continue
449
+ if os.path.isfile(file_path) or os.path.islink(file_path):
450
+ os.unlink(file_path)
451
+ elif os.path.isdir(file_path):
452
+ shutil.rmtree(file_path)
453
+ except Exception as e:
454
+ structlogger.error(
455
+ "project_generator.cleanup_error",
456
+ error=str(e),
457
+ file_path=file_path,
458
+ )
@@ -0,0 +1,72 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from dataclasses import asdict, dataclass
5
+ from datetime import datetime, timezone
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ from rasa.constants import RASA_DIR_NAME
10
+
11
+
12
+ @dataclass
13
+ class ProjectInfo:
14
+ """Metadata persisted for the builder about the current project.
15
+
16
+ - first_used_utc_iso: RFC3339/ISO8601 string of when the project was first used.
17
+ """
18
+
19
+ first_used_utc_iso: Optional[str] = None
20
+
21
+ @classmethod
22
+ def from_json(cls, data: str) -> "ProjectInfo":
23
+ payload = json.loads(data) if data else {}
24
+ return cls(**payload)
25
+
26
+ def to_json(self) -> str:
27
+ return json.dumps(asdict(self))
28
+
29
+ def first_used_dt(self) -> Optional[datetime]:
30
+ if not self.first_used_utc_iso:
31
+ return None
32
+ value = self.first_used_utc_iso.strip()
33
+ if value.endswith("Z"):
34
+ value = value[:-1] + "+00:00"
35
+ try:
36
+ dt = datetime.fromisoformat(value)
37
+ except Exception:
38
+ return None
39
+ if dt.tzinfo is None:
40
+ dt = dt.replace(tzinfo=timezone.utc)
41
+ return dt.astimezone(timezone.utc)
42
+
43
+
44
+ def _project_info_path(project_folder: Path) -> Path:
45
+ return project_folder / RASA_DIR_NAME / "project_info.json"
46
+
47
+
48
+ def load_project_info(project_folder: Path) -> ProjectInfo:
49
+ path = _project_info_path(project_folder)
50
+ try:
51
+ if path.exists():
52
+ return ProjectInfo.from_json(path.read_text(encoding="utf-8"))
53
+ except Exception:
54
+ pass
55
+ return ProjectInfo()
56
+
57
+
58
+ def save_project_info(project_folder: Path, info: ProjectInfo) -> None:
59
+ path = _project_info_path(project_folder)
60
+ path.parent.mkdir(parents=True, exist_ok=True)
61
+ path.write_text(info.to_json(), encoding="utf-8")
62
+
63
+
64
+ def ensure_first_used(project_folder: Path) -> datetime:
65
+ info = load_project_info(project_folder)
66
+ if existing := info.first_used_dt():
67
+ return existing
68
+
69
+ now = datetime.now(timezone.utc)
70
+ info.first_used_utc_iso = now.isoformat()
71
+ save_project_info(project_folder, info)
72
+ return now
@@ -0,0 +1,97 @@
1
+ import json
2
+ import os
3
+ from pathlib import Path
4
+ from urllib.parse import urljoin, urlparse
5
+
6
+ import requests
7
+ from bs4 import BeautifulSoup
8
+
9
+ BASE_URL = "https://rasa.com"
10
+ DOCS_ROOT = "https://rasa.com/docs"
11
+ OUTPUT_DIR = "rasa_docs_md"
12
+ MAX_PAGES = 100 # Optional limit for safety
13
+
14
+ visited = set()
15
+ to_visit = [DOCS_ROOT]
16
+
17
+ os.makedirs(OUTPUT_DIR, exist_ok=True)
18
+
19
+
20
+ def is_valid_doc_url(url: str) -> bool:
21
+ return url.startswith(DOCS_ROOT) and not any(
22
+ [url.endswith(".pdf"), "#" in url, "mailto:" in url]
23
+ )
24
+
25
+
26
+ def slugify_url(url: str) -> str:
27
+ path = urlparse(url).path.strip("/").replace("/", "_")
28
+ return path if path else "index"
29
+
30
+
31
+ def clean_text(html: str) -> str:
32
+ soup = BeautifulSoup(html, "html.parser")
33
+
34
+ # Remove navs, footers, and code tabs (customize if needed)
35
+ for tag in soup(["nav", "footer", "script", "style", "form", "button"]):
36
+ tag.decompose()
37
+
38
+ main = soup.find("main") or soup.body
39
+ if not main:
40
+ return ""
41
+
42
+ # Replace <code> with backticks
43
+ for code in main.find_all("code"):
44
+ code.string = f"`{code.get_text(strip=True)}`"
45
+
46
+ text = main.get_text(separator="\n", strip=True)
47
+ return text
48
+
49
+
50
+ def save_as_markdown(text: str, url: str) -> str:
51
+ slug = slugify_url(url)
52
+ file_name = f"{slug}.md"
53
+ md_path = Path(OUTPUT_DIR) / file_name
54
+ with open(md_path, "w", encoding="utf-8") as f:
55
+ f.write(text)
56
+
57
+ print(f"✅ Saved: {md_path}")
58
+ return file_name
59
+
60
+
61
+ pages_scraped = 0
62
+ markdown_to_url = {}
63
+
64
+ while to_visit and pages_scraped < MAX_PAGES:
65
+ url = to_visit.pop(0)
66
+ if url in visited:
67
+ continue
68
+
69
+ try:
70
+ print(f"Scraping: {url}")
71
+ response = requests.get(url)
72
+ response.raise_for_status()
73
+
74
+ html = response.text
75
+ text = clean_text(html)
76
+ if len(text) < 200: # skip very short pages
77
+ print("⏭️ Skipped (too short)")
78
+ continue
79
+
80
+ file_name = save_as_markdown(text, url)
81
+ markdown_to_url[file_name] = url
82
+ pages_scraped += 1
83
+
84
+ soup = BeautifulSoup(html, "html.parser")
85
+ for link_tag in soup.find_all("a", href=True):
86
+ link = urljoin(url, link_tag["href"])
87
+ if is_valid_doc_url(link) and link not in visited:
88
+ to_visit.append(link)
89
+
90
+ visited.add(url)
91
+
92
+ except Exception as e:
93
+ print(f"⚠️ Failed to scrape {url}: {e}")
94
+
95
+
96
+ with open("markdown_to_url.json", "w") as f:
97
+ json.dump(markdown_to_url, f, indent=2)