rasa-pro 3.13.1a18__py3-none-any.whl → 3.13.1.dev1__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 (266) hide show
  1. rasa/__init__.py +6 -0
  2. rasa/cli/scaffold.py +3 -22
  3. rasa/core/actions/action.py +3 -5
  4. rasa/core/channels/studio_chat.py +10 -34
  5. rasa/core/policies/enterprise_search_policy.py +8 -7
  6. rasa/core/policies/flows/flow_executor.py +1 -8
  7. rasa/dialogue_understanding/generator/flow_retrieval.py +9 -10
  8. rasa/dialogue_understanding/generator/llm_based_command_generator.py +15 -4
  9. rasa/dialogue_understanding/generator/llm_command_generator.py +3 -1
  10. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +48 -3
  11. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +15 -1
  12. rasa/hooks.py +55 -0
  13. rasa/llm_fine_tuning/utils.py +4 -2
  14. rasa/model_manager/model_api.py +3 -2
  15. rasa/model_manager/runner_service.py +1 -1
  16. rasa/model_manager/trainer_service.py +9 -12
  17. rasa/model_manager/utils.py +29 -1
  18. rasa/monkey_patches.py +91 -0
  19. rasa/shared/constants.py +6 -0
  20. rasa/shared/core/domain.py +15 -62
  21. rasa/shared/core/flows/flow_step.py +1 -7
  22. rasa/shared/core/flows/yaml_flows_io.py +8 -16
  23. rasa/shared/core/slots.py +0 -4
  24. rasa/shared/importers/importer.py +0 -6
  25. rasa/shared/importers/utils.py +1 -77
  26. rasa/shared/providers/constants.py +10 -0
  27. rasa/shared/providers/llm/_base_litellm_client.py +14 -4
  28. rasa/shared/providers/llm/litellm_router_llm_client.py +23 -12
  29. rasa/shared/providers/llm/llm_client.py +19 -15
  30. rasa/shared/providers/llm/self_hosted_llm_client.py +23 -18
  31. rasa/studio/upload.py +45 -10
  32. rasa/telemetry.py +1 -2
  33. rasa/tracing/instrumentation/attribute_extractors.py +1 -0
  34. rasa/utils/io.py +9 -27
  35. rasa/utils/json_utils.py +1 -6
  36. rasa/utils/log_utils.py +1 -5
  37. rasa/utils/plotting.py +1 -1
  38. rasa/validator.py +3 -7
  39. rasa/version.py +1 -1
  40. {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.1.dev1.dist-info}/METADATA +9 -9
  41. {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.1.dev1.dist-info}/RECORD +44 -265
  42. rasa/builder/README.md +0 -120
  43. rasa/builder/__init__.py +0 -0
  44. rasa/builder/config.py +0 -79
  45. rasa/builder/create_openai_vector_store.py +0 -228
  46. rasa/builder/exceptions.py +0 -55
  47. rasa/builder/inkeep-rag-response-schema.json +0 -64
  48. rasa/builder/inkeep_document_retrieval.py +0 -212
  49. rasa/builder/llm-helper-schema.json +0 -69
  50. rasa/builder/llm_context.py +0 -81
  51. rasa/builder/llm_helper_prompt.jinja2 +0 -245
  52. rasa/builder/llm_service.py +0 -317
  53. rasa/builder/logging_utils.py +0 -51
  54. rasa/builder/main.py +0 -147
  55. rasa/builder/models.py +0 -225
  56. rasa/builder/project_generator.py +0 -282
  57. rasa/builder/scrape_rasa_docs.py +0 -97
  58. rasa/builder/service.py +0 -742
  59. rasa/builder/skill_to_bot_prompt.jinja2 +0 -164
  60. rasa/builder/training_service.py +0 -132
  61. rasa/builder/validation_service.py +0 -93
  62. rasa/cli/project_templates/finance/actions/__init__.py +0 -0
  63. rasa/cli/project_templates/finance/actions/action_add_payee.py +0 -47
  64. rasa/cli/project_templates/finance/actions/action_ask_account.py +0 -50
  65. rasa/cli/project_templates/finance/actions/action_ask_account_from.py +0 -50
  66. rasa/cli/project_templates/finance/actions/action_ask_card.py +0 -47
  67. rasa/cli/project_templates/finance/actions/action_check_balance.py +0 -40
  68. rasa/cli/project_templates/finance/actions/action_check_card_existence.py +0 -35
  69. rasa/cli/project_templates/finance/actions/action_check_payee_existence.py +0 -40
  70. rasa/cli/project_templates/finance/actions/action_check_sufficient_funds.py +0 -41
  71. rasa/cli/project_templates/finance/actions/action_list_payees.py +0 -45
  72. rasa/cli/project_templates/finance/actions/action_process_immediate_payment.py +0 -18
  73. rasa/cli/project_templates/finance/actions/action_remove_payee.py +0 -49
  74. rasa/cli/project_templates/finance/actions/action_schedule_payment.py +0 -19
  75. rasa/cli/project_templates/finance/actions/action_session_start.py +0 -69
  76. rasa/cli/project_templates/finance/actions/action_update_card_status.py +0 -45
  77. rasa/cli/project_templates/finance/actions/action_validate_payment_date.py +0 -36
  78. rasa/cli/project_templates/finance/actions/database.py +0 -276
  79. rasa/cli/project_templates/finance/config.yml +0 -32
  80. rasa/cli/project_templates/finance/credentials.yml +0 -33
  81. rasa/cli/project_templates/finance/csvs/accounts.csv +0 -8
  82. rasa/cli/project_templates/finance/csvs/advisors.csv +0 -7
  83. rasa/cli/project_templates/finance/csvs/appointments.csv +0 -211
  84. rasa/cli/project_templates/finance/csvs/branches.csv +0 -10
  85. rasa/cli/project_templates/finance/csvs/cards.csv +0 -11
  86. rasa/cli/project_templates/finance/csvs/payees.csv +0 -10
  87. rasa/cli/project_templates/finance/csvs/transactions.csv +0 -71
  88. rasa/cli/project_templates/finance/csvs/users.csv +0 -4
  89. rasa/cli/project_templates/finance/data/flows/add_payee.yml +0 -29
  90. rasa/cli/project_templates/finance/data/flows/block_card.yml +0 -66
  91. rasa/cli/project_templates/finance/data/flows/check_balance.yml +0 -9
  92. rasa/cli/project_templates/finance/data/flows/list_payees.yml +0 -5
  93. rasa/cli/project_templates/finance/data/flows/remove_payee.yml +0 -21
  94. rasa/cli/project_templates/finance/data/flows/select_card.yml +0 -12
  95. rasa/cli/project_templates/finance/data/flows/transfer_money.yml +0 -67
  96. rasa/cli/project_templates/finance/data/flows/welcome.yml +0 -14
  97. rasa/cli/project_templates/finance/data/nlu.yml +0 -29
  98. rasa/cli/project_templates/finance/data/patterns/pattern_chitchat.yml +0 -7
  99. rasa/cli/project_templates/finance/data/patterns/pattern_completed.yml +0 -6
  100. rasa/cli/project_templates/finance/data/patterns/pattern_search.yml +0 -5
  101. rasa/cli/project_templates/finance/data/patterns/pattern_session_start.yml +0 -9
  102. rasa/cli/project_templates/finance/data/source/accounts.json +0 -51
  103. rasa/cli/project_templates/finance/data/source/advisors.json +0 -44
  104. rasa/cli/project_templates/finance/data/source/appointments.json +0 -1474
  105. rasa/cli/project_templates/finance/data/source/branches.json +0 -47
  106. rasa/cli/project_templates/finance/data/source/cards.json +0 -72
  107. rasa/cli/project_templates/finance/data/source/payees.json +0 -74
  108. rasa/cli/project_templates/finance/data/source/transactions.json +0 -492
  109. rasa/cli/project_templates/finance/data/source/users.json +0 -29
  110. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +0 -8
  111. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +0 -8
  112. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +0 -8
  113. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +0 -8
  114. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +0 -8
  115. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +0 -7
  116. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +0 -8
  117. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +0 -8
  118. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +0 -8
  119. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +0 -8
  120. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +0 -8
  121. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +0 -8
  122. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +0 -8
  123. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +0 -8
  124. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +0 -8
  125. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +0 -8
  126. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +0 -8
  127. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +0 -8
  128. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +0 -8
  129. rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +0 -8
  130. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +0 -50
  131. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +0 -50
  132. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +0 -48
  133. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +0 -50
  134. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +0 -50
  135. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +0 -47
  136. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +0 -50
  137. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +0 -50
  138. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +0 -47
  139. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +0 -50
  140. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +0 -50
  141. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +0 -50
  142. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +0 -47
  143. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +0 -50
  144. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +0 -50
  145. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +0 -47
  146. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +0 -50
  147. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +0 -50
  148. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +0 -47
  149. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +0 -50
  150. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +0 -50
  151. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +0 -47
  152. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +0 -47
  153. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +0 -50
  154. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +0 -50
  155. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +0 -47
  156. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +0 -50
  157. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +0 -50
  158. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +0 -47
  159. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +0 -50
  160. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +0 -50
  161. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +0 -47
  162. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +0 -50
  163. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +0 -50
  164. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +0 -50
  165. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +0 -47
  166. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +0 -50
  167. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +0 -50
  168. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +0 -47
  169. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +0 -50
  170. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +0 -50
  171. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +0 -47
  172. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +0 -50
  173. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +0 -50
  174. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +0 -50
  175. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +0 -47
  176. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +0 -50
  177. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +0 -50
  178. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +0 -47
  179. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +0 -50
  180. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +0 -50
  181. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +0 -47
  182. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +0 -50
  183. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +0 -50
  184. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +0 -47
  185. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +0 -47
  186. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +0 -50
  187. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +0 -50
  188. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +0 -50
  189. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +0 -50
  190. rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +0 -47
  191. rasa/cli/project_templates/finance/domain/add_payee.yml +0 -47
  192. rasa/cli/project_templates/finance/domain/block_card.yml +0 -101
  193. rasa/cli/project_templates/finance/domain/check_balance.yml +0 -9
  194. rasa/cli/project_templates/finance/domain/default_actions.yml +0 -16
  195. rasa/cli/project_templates/finance/domain/default_flows.yml +0 -33
  196. rasa/cli/project_templates/finance/domain/list_payees.yml +0 -4
  197. rasa/cli/project_templates/finance/domain/remove_payee.yml +0 -16
  198. rasa/cli/project_templates/finance/domain/select_card.yml +0 -12
  199. rasa/cli/project_templates/finance/domain/transfer_money.yml +0 -79
  200. rasa/cli/project_templates/finance/endpoints.yml +0 -62
  201. rasa/cli/project_templates/finance/prompts/command-generator.jinja2 +0 -57
  202. rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +0 -19
  203. rasa/cli/project_templates/finance/tests/conversation_repair/cancellations.yml +0 -12
  204. rasa/cli/project_templates/finance/tests/conversation_repair/cannot_handle.yml +0 -7
  205. rasa/cli/project_templates/finance/tests/conversation_repair/chitchat.yml +0 -7
  206. rasa/cli/project_templates/finance/tests/conversation_repair/clarification.yml +0 -9
  207. rasa/cli/project_templates/finance/tests/conversation_repair/completion.yml +0 -18
  208. rasa/cli/project_templates/finance/tests/conversation_repair/corrections.yml +0 -17
  209. rasa/cli/project_templates/finance/tests/conversation_repair/digressions.yml +0 -32
  210. rasa/cli/project_templates/finance/tests/conversation_repair/human_handoff.yml +0 -21
  211. rasa/cli/project_templates/finance/tests/conversation_repair/skipping_collect_steps.yml +0 -16
  212. rasa/cli/project_templates/finance/tests/demo_scripts/main.yml +0 -16
  213. rasa/cli/project_templates/finance/tests/happy_paths/balance_verification.yml +0 -15
  214. rasa/cli/project_templates/finance/tests/happy_paths/banking_questions.yml +0 -12
  215. rasa/cli/project_templates/finance/tests/happy_paths/card_blocking.yml +0 -52
  216. rasa/cli/project_templates/finance/tests/happy_paths/money_transfer.yml +0 -136
  217. rasa/cli/project_templates/finance/tests/happy_paths/payee_management.yml +0 -27
  218. rasa/cli/project_templates/finance/tests/happy_paths/user_greeted.yml +0 -5
  219. rasa/cli/project_templates/plain/actions/__init__.py +0 -0
  220. rasa/cli/project_templates/plain/config.yml +0 -17
  221. rasa/cli/project_templates/plain/credentials.yml +0 -33
  222. rasa/cli/project_templates/plain/data/patterns/pattern_session_start.yml +0 -7
  223. rasa/cli/project_templates/plain/domain.yml +0 -5
  224. rasa/cli/project_templates/plain/endpoints.yml +0 -58
  225. rasa/cli/project_templates/telco/actions/__init__.py +0 -0
  226. rasa/cli/project_templates/telco/actions/actions_billing.py +0 -197
  227. rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py +0 -43
  228. rasa/cli/project_templates/telco/actions/actions_run_diagnostics.py +0 -23
  229. rasa/cli/project_templates/telco/actions/actions_session_start.py +0 -13
  230. rasa/cli/project_templates/telco/config.yml +0 -25
  231. rasa/cli/project_templates/telco/credentials.yml +0 -33
  232. rasa/cli/project_templates/telco/csvs/billing.csv +0 -10
  233. rasa/cli/project_templates/telco/csvs/customers.csv +0 -5
  234. rasa/cli/project_templates/telco/data/flows/flow_global.yml +0 -5
  235. rasa/cli/project_templates/telco/data/flows/flow_reboot_router.yml +0 -8
  236. rasa/cli/project_templates/telco/data/flows/flow_reset_router.yml +0 -7
  237. rasa/cli/project_templates/telco/data/flows/flow_solve_internet_issue.yml +0 -73
  238. rasa/cli/project_templates/telco/data/flows/flow_undertand_bill.yml +0 -45
  239. rasa/cli/project_templates/telco/data/patterns/pattern_completed.yml +0 -7
  240. rasa/cli/project_templates/telco/data/patterns/pattern_human_handoff.yml +0 -6
  241. rasa/cli/project_templates/telco/data/patterns/pattern_search.yml +0 -7
  242. rasa/cli/project_templates/telco/data/patterns/pattern_session_start.yml +0 -9
  243. rasa/cli/project_templates/telco/docs/reset_vs_rboot_router.txt +0 -1
  244. rasa/cli/project_templates/telco/docs/restart_router.txt +0 -6
  245. rasa/cli/project_templates/telco/docs/run_speed_test.txt +0 -6
  246. rasa/cli/project_templates/telco/domain/domain_global.yml +0 -29
  247. rasa/cli/project_templates/telco/domain/domain_patterns.yml +0 -17
  248. rasa/cli/project_templates/telco/domain/domain_reboot_router.yml +0 -20
  249. rasa/cli/project_templates/telco/domain/domain_reset_router.yml +0 -11
  250. rasa/cli/project_templates/telco/domain/domain_run_speed_test.yml +0 -24
  251. rasa/cli/project_templates/telco/domain/domain_solve_internet_issue.yml +0 -74
  252. rasa/cli/project_templates/telco/domain/domain_undertand_bill.yml +0 -102
  253. rasa/cli/project_templates/telco/endpoints.yml +0 -60
  254. rasa/cli/project_templates/telco/prompts/command-generator.jinja2 +0 -57
  255. rasa/cli/project_templates/telco/tests/e2e_results_failed.yml +0 -62
  256. rasa/cli/project_templates/telco/tests/e2e_results_passed.yml +0 -130
  257. rasa/cli/project_templates/telco/tests/e2e_test_cases/billing_test_cases.yml +0 -68
  258. rasa/cli/project_templates/telco/tests/e2e_test_cases/global_test_cases.yml +0 -13
  259. rasa/cli/project_templates/telco/tests/e2e_test_cases/internet_slow_test_case.yml +0 -47
  260. rasa/cli/project_templates/telco/tests/e2e_test_cases/out_of_scope_test_case.yml +0 -21
  261. rasa/cli/project_templates/telco/tests/e2e_test_cases/patterns_test_cases.yml +0 -15
  262. rasa/shared/importers/static.py +0 -63
  263. rasa/utils/openapi.py +0 -144
  264. {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.1.dev1.dist-info}/NOTICE +0 -0
  265. {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.1.dev1.dist-info}/WHEEL +0 -0
  266. {rasa_pro-3.13.1a18.dist-info → rasa_pro-3.13.1.dev1.dist-info}/entry_points.txt +0 -0
rasa/builder/service.py DELETED
@@ -1,742 +0,0 @@
1
- """Main service for the prompt-to-bot functionality."""
2
-
3
- import os
4
- from typing import Any, Optional
5
-
6
- import structlog
7
- from sanic import Blueprint, HTTPResponse, response
8
- from sanic.request import Request
9
- from sanic_openapi import openapi
10
-
11
- from rasa.builder.exceptions import (
12
- LLMGenerationError,
13
- ProjectGenerationError,
14
- TrainingError,
15
- ValidationError,
16
- )
17
- from rasa.builder.llm_service import llm_service
18
- from rasa.builder.logging_utils import get_recent_logs
19
- from rasa.builder.models import (
20
- ApiErrorResponse,
21
- LLMBuilderContext,
22
- LLMBuilderRequest,
23
- LLMHelperResponse,
24
- PromptRequest,
25
- ServerSentEvent,
26
- TemplateRequest,
27
- )
28
- from rasa.builder.project_generator import ProjectGenerator
29
- from rasa.builder.training_service import train_and_load_agent
30
- from rasa.builder.validation_service import validate_project
31
- from rasa.cli.scaffold import ProjectTemplateName
32
- from rasa.core.channels.studio_chat import StudioChatInput
33
- from rasa.shared.core.trackers import DialogueStateTracker
34
- from rasa.studio.upload import CALMUserData, extract_calm_import_parts_from_importer
35
- from rasa.utils.openapi import model_to_schema
36
-
37
- structlogger = structlog.get_logger()
38
-
39
- # Create the blueprint
40
- bp = Blueprint("bot_builder", url_prefix="/api")
41
-
42
-
43
- def setup_project_generator(project_folder: Optional[str] = None) -> ProjectGenerator:
44
- """Initialize and return a ProjectGenerator instance."""
45
- if project_folder is None:
46
- import tempfile
47
-
48
- project_folder = tempfile.mkdtemp(prefix="rasa_builder_")
49
-
50
- # working directory needs to be the project folder, e.g.
51
- # for relative paths (./docs) in a projects config to work
52
- os.chdir(project_folder)
53
-
54
- structlogger.info(
55
- "bot_builder_service.service_initialized", project_folder=project_folder
56
- )
57
-
58
- return ProjectGenerator(project_folder)
59
-
60
-
61
- def get_project_generator(request: Request) -> ProjectGenerator:
62
- """Get the project generator from app context."""
63
- return request.app.ctx.project_generator
64
-
65
-
66
- def get_input_channel(request: Request) -> StudioChatInput:
67
- """Get the input channel from app context."""
68
- return request.app.ctx.input_channel
69
-
70
-
71
- def extract_calm_import_parts_from_project_generator(
72
- project_generator: ProjectGenerator,
73
- ) -> CALMUserData:
74
- """Extract CALMUserData from a ProjectGenerator.
75
-
76
- Args:
77
- project_generator: The project generator to extract data from
78
-
79
- Returns:
80
- CALMUserData containing flows, domain, config, endpoints, and nlu data
81
- """
82
- # Get the training data importer
83
- importer = project_generator._create_importer()
84
-
85
- # Extract endpoints (if exists)
86
- endpoints_path = project_generator.project_folder / "endpoints.yml"
87
- if endpoints_path.exists():
88
- from rasa.shared.utils.yaml import read_yaml_file
89
-
90
- endpoints = read_yaml_file(endpoints_path, expand_env_vars=False)
91
- else:
92
- endpoints = {}
93
-
94
- # Use the shared function with the importer and project data paths
95
- return extract_calm_import_parts_from_importer(
96
- importer=importer,
97
- config=None, # Let the shared function get config from importer
98
- endpoints=endpoints,
99
- )
100
-
101
-
102
- # Health check endpoint
103
- @bp.route("/", methods=["GET"])
104
- @openapi.summary("Health check endpoint")
105
- @openapi.description("Returns the health status of the Bot Builder service")
106
- @openapi.tag("health")
107
- @openapi.response(200, {"application/json": {"status": str, "service": str}})
108
- async def health(request: Request) -> HTTPResponse:
109
- """Health check endpoint."""
110
- return response.json({"status": "ok", "service": "bot-builder"})
111
-
112
-
113
- @bp.route("/prompt-to-bot", methods=["POST"])
114
- @openapi.summary("Generate bot from natural language prompt")
115
- @openapi.description(
116
- "Creates a complete conversational AI bot from a natural language prompt "
117
- "using LLM generation. Returns server-sent events (SSE) for real-time "
118
- "progress tracking through the entire bot creation process.\n\n"
119
- "**SSE Event Flow:**\n"
120
- "1. `received` - Request received by server\n"
121
- "2. `generating` - Generating bot project files\n"
122
- "3. `generation_success` - Bot generation completed successfully\n"
123
- "4. `training` - Training the bot model\n"
124
- "5. `train_success` - Model training completed\n"
125
- "6. `done` - Bot creation completed\n\n"
126
- "**Error Events (can occur at any time):**\n"
127
- "- `generation_error` - Failed to generate bot from prompt\n"
128
- "- `train_error` - Bot generated but training failed\n"
129
- "- `validation_error` - Generated bot configuration is invalid\n"
130
- "- `error` - Unexpected error occurred\n\n"
131
- "**Usage:** Send POST request with Content-Type: application/json and "
132
- "Accept: text/event-stream"
133
- )
134
- @openapi.tag("bot-generation")
135
- @openapi.body(
136
- {"application/json": model_to_schema(PromptRequest)},
137
- description="Prompt request with natural language description and client ID "
138
- "for tracking",
139
- required=True,
140
- )
141
- @openapi.response(
142
- 200,
143
- {"text/event-stream": str},
144
- description="Server-sent events stream with real-time progress updates",
145
- )
146
- @openapi.response(
147
- 400,
148
- {"application/json": model_to_schema(ApiErrorResponse)},
149
- description="Validation error in request payload",
150
- )
151
- @openapi.response(
152
- 500,
153
- {"application/json": model_to_schema(ApiErrorResponse)},
154
- description="Internal server error",
155
- )
156
- async def handle_prompt_to_bot(request: Request) -> None:
157
- """Handle prompt-to-bot generation requests."""
158
- sse_response = await request.respond(content_type="text/event-stream")
159
- project_generator = get_project_generator(request)
160
- input_channel = get_input_channel(request)
161
-
162
- try:
163
- # 1. Received
164
- await _send_sse_event(
165
- sse_response,
166
- ServerSentEvent(event="received", data={"status": "received"}),
167
- )
168
-
169
- # Validate request
170
- prompt_data = PromptRequest(**request.json)
171
-
172
- # 2. Generating
173
- await _send_sse_event(
174
- sse_response,
175
- ServerSentEvent(event="generating", data={"status": "generating"}),
176
- )
177
-
178
- try:
179
- # Generate project with retries
180
- bot_files = await project_generator.generate_project_with_retries(
181
- prompt_data.prompt,
182
- template=ProjectTemplateName.PLAIN,
183
- )
184
-
185
- await _send_sse_event(
186
- sse_response,
187
- ServerSentEvent(
188
- event="generation_success",
189
- data={"status": "generation_success"},
190
- ),
191
- )
192
-
193
- except (ProjectGenerationError, LLMGenerationError) as e:
194
- await _send_sse_event(
195
- sse_response,
196
- ServerSentEvent(
197
- event="generation_error",
198
- data={"status": "generation_error", "error": str(e)},
199
- ),
200
- )
201
- await sse_response.eof()
202
- return
203
-
204
- # 3. Training
205
- await _send_sse_event(
206
- sse_response,
207
- ServerSentEvent(event="training", data={"status": "training"}),
208
- )
209
-
210
- try:
211
- # Train and load agent
212
- importer = project_generator._create_importer()
213
- request.app.ctx.agent = await train_and_load_agent(importer)
214
-
215
- # Update input channel with new agent
216
- input_channel.agent = request.app.ctx.agent
217
-
218
- await _send_sse_event(
219
- sse_response,
220
- ServerSentEvent(
221
- event="train_success", data={"status": "train_success"}
222
- ),
223
- )
224
-
225
- except TrainingError as e:
226
- await _send_sse_event(
227
- sse_response,
228
- ServerSentEvent(
229
- event="train_error",
230
- data={"status": "train_error", "error": str(e)},
231
- ),
232
- )
233
- await sse_response.eof()
234
- return
235
-
236
- # 4. Done
237
- await _send_sse_event(
238
- sse_response,
239
- ServerSentEvent(
240
- event="done",
241
- data={
242
- "status": "done",
243
- },
244
- ),
245
- )
246
-
247
- structlogger.info(
248
- "bot_builder_service.prompt_to_bot.success",
249
- client_id=prompt_data.client_id,
250
- files_generated=list(bot_files.keys()),
251
- )
252
-
253
- except ValidationError as e:
254
- structlogger.error(
255
- "bot_builder_service.prompt_to_bot.validation_error", error=str(e)
256
- )
257
- await _send_sse_event(
258
- sse_response,
259
- ServerSentEvent(
260
- event="validation_error",
261
- data={"status": "validation_error", "error": str(e)},
262
- ),
263
- )
264
-
265
- except Exception as e:
266
- structlogger.error(
267
- "bot_builder_service.prompt_to_bot.unexpected_error", error=str(e)
268
- )
269
- await _send_sse_event(
270
- sse_response,
271
- ServerSentEvent(event="error", data={"status": "error", "error": str(e)}),
272
- )
273
- finally:
274
- await sse_response.eof()
275
-
276
-
277
- @bp.route("/template-to-bot", methods=["POST"])
278
- @openapi.summary("Generate bot from predefined template")
279
- @openapi.description(
280
- "Creates a complete conversational AI bot from a predefined template with "
281
- "immediate setup. Returns server-sent events (SSE) for real-time progress "
282
- "tracking through the entire bot creation process.\n\n"
283
- "**SSE Event Flow:**\n"
284
- "1. `received` - Request received by server\n"
285
- "2. `generating` - Initializing bot from template\n"
286
- "3. `generation_success` - Template initialization completed successfully\n"
287
- "4. `training` - Training the bot model\n"
288
- "5. `train_success` - Model training completed\n"
289
- "6. `done` - Bot creation completed\n\n"
290
- "**Error Events (can occur at any time):**\n"
291
- "- `generation_error` - Failed to initialize bot from template\n"
292
- "- `train_error` - Template loaded but training failed\n"
293
- "- `validation_error` - Template configuration is invalid\n"
294
- "- `error` - Unexpected error occurred\n\n"
295
- "**Usage:** Send POST request with Content-Type: application/json and "
296
- "Accept: text/event-stream\n"
297
- "**Templates Available:** Check available templates through the API or "
298
- "documentation"
299
- )
300
- @openapi.tag("bot-generation")
301
- @openapi.body(
302
- {"application/json": model_to_schema(TemplateRequest)},
303
- description="Template request with template name and client ID for " "tracking",
304
- required=True,
305
- )
306
- @openapi.response(
307
- 200,
308
- {"text/event-stream": model_to_schema(ServerSentEvent)},
309
- description="Server-sent events stream with real-time progress updates",
310
- example=ServerSentEvent(
311
- event="generation_success",
312
- data={"status": "generation_success"},
313
- ).model_dump(),
314
- )
315
- @openapi.response(
316
- 400,
317
- {"application/json": model_to_schema(ApiErrorResponse)},
318
- description="Validation error in request payload or invalid template name",
319
- )
320
- @openapi.response(
321
- 500,
322
- {"application/json": model_to_schema(ApiErrorResponse)},
323
- description="Internal server error",
324
- )
325
- async def handle_template_to_bot(request: Request) -> None:
326
- """Handle template-to-bot generation requests."""
327
- sse_response = await request.respond(content_type="text/event-stream")
328
- project_generator = get_project_generator(request)
329
- input_channel = get_input_channel(request)
330
-
331
- try:
332
- # 1. Received
333
- await _send_sse_event(
334
- sse_response,
335
- ServerSentEvent(event="received", data={"status": "received"}),
336
- )
337
-
338
- # Validate request
339
- template_data = TemplateRequest(**request.json)
340
-
341
- # 2. Generating
342
- await _send_sse_event(
343
- sse_response,
344
- ServerSentEvent(event="generating", data={"status": "generating"}),
345
- )
346
-
347
- try:
348
- # Generate project with retries
349
- project_generator.init_from_template(
350
- template_data.template_name,
351
- )
352
- bot_files = project_generator.get_bot_files()
353
-
354
- await _send_sse_event(
355
- sse_response,
356
- ServerSentEvent(
357
- event="generation_success",
358
- data={"status": "generation_success"},
359
- ),
360
- )
361
-
362
- except ProjectGenerationError as e:
363
- await _send_sse_event(
364
- sse_response,
365
- ServerSentEvent(
366
- event="generation_error",
367
- data={"status": "generation_error", "error": str(e)},
368
- ),
369
- )
370
- await sse_response.eof()
371
- return
372
-
373
- # 3. Training
374
- await _send_sse_event(
375
- sse_response,
376
- ServerSentEvent(event="training", data={"status": "training"}),
377
- )
378
-
379
- try:
380
- # Train and load agent
381
- importer = project_generator._create_importer()
382
- request.app.ctx.agent = await train_and_load_agent(importer)
383
-
384
- # Update input channel with new agent
385
- input_channel.agent = request.app.ctx.agent
386
-
387
- await _send_sse_event(
388
- sse_response,
389
- ServerSentEvent(
390
- event="train_success", data={"status": "train_success"}
391
- ),
392
- )
393
-
394
- except TrainingError as e:
395
- await _send_sse_event(
396
- sse_response,
397
- ServerSentEvent(
398
- event="train_error",
399
- data={"status": "train_error", "error": str(e)},
400
- ),
401
- )
402
- await sse_response.eof()
403
- return
404
-
405
- # 4. Done
406
- await _send_sse_event(
407
- sse_response,
408
- ServerSentEvent(
409
- event="done",
410
- data={
411
- "status": "done",
412
- },
413
- ),
414
- )
415
-
416
- structlogger.info(
417
- "bot_builder_service.template_to_bot.success",
418
- client_id=template_data.client_id,
419
- files_generated=list(bot_files.keys()),
420
- )
421
-
422
- except ValidationError as e:
423
- structlogger.error(
424
- "bot_builder_service.template_to_bot.validation_error", error=str(e)
425
- )
426
- await _send_sse_event(
427
- sse_response,
428
- ServerSentEvent(
429
- event="validation_error",
430
- data={"status": "validation_error", "error": str(e)},
431
- ),
432
- )
433
-
434
- except Exception as e:
435
- structlogger.error(
436
- "bot_builder_service.template_to_bot.unexpected_error", error=str(e)
437
- )
438
- await _send_sse_event(
439
- sse_response,
440
- ServerSentEvent(event="error", data={"status": "error", "error": str(e)}),
441
- )
442
- finally:
443
- await sse_response.eof()
444
-
445
-
446
- @bp.route("/files", methods=["GET"])
447
- @openapi.summary("Get bot files")
448
- @openapi.description("Retrieves the current bot configuration files and data")
449
- @openapi.tag("bot-files")
450
- @openapi.response(
451
- 200,
452
- {"application/json": {str: Optional[str]}},
453
- description="Bot files retrieved successfully",
454
- )
455
- @openapi.response(
456
- 500,
457
- {"application/json": model_to_schema(ApiErrorResponse)},
458
- description="Internal server error",
459
- )
460
- async def get_bot_files(request: Request) -> HTTPResponse:
461
- """Get current bot files."""
462
- project_generator = get_project_generator(request)
463
- bot_files = project_generator.get_bot_files()
464
- return response.json(bot_files)
465
-
466
-
467
- @bp.route("/files", methods=["PUT"])
468
- @openapi.summary("Update bot files")
469
- @openapi.description(
470
- "Updates the bot configuration files and retrains the model. "
471
- "Returns server-sent events (SSE) for real-time progress tracking "
472
- "through the entire update process.\n\n"
473
- "**SSE Event Flow:**\n"
474
- "1. `received` - Request received by server\n"
475
- "2. `validating` - Validating bot configuration files\n"
476
- "3. `validation_success` - File validation completed successfully\n"
477
- "4. `training` - Training the bot model with updated files\n"
478
- "5. `train_success` - Model training completed\n"
479
- "6. `done` - Bot files update completed\n\n"
480
- "**Error Events (can occur at any time):**\n"
481
- "- `validation_error` - Bot configuration files are invalid\n"
482
- "- `train_error` - Files updated but training failed\n"
483
- "- `error` - Unexpected error occurred\n\n"
484
- "**Usage:** Send PUT request with Content-Type: application/json and "
485
- "Accept: text/event-stream"
486
- )
487
- @openapi.tag("bot-files")
488
- @openapi.body(
489
- {"application/json": {"file_name": str}},
490
- description="A dictionary mapping file names to their updated content. "
491
- "The file name should be the name of the file in the project folder. "
492
- "Files that are not in the request will not be updated.",
493
- required=True,
494
- )
495
- @openapi.response(
496
- 200,
497
- {"text/event-stream": str},
498
- description="Server-sent events stream with update progress",
499
- )
500
- @openapi.response(
501
- 400,
502
- {"application/json": model_to_schema(ApiErrorResponse)},
503
- description="Validation error in bot files",
504
- )
505
- @openapi.response(
506
- 500,
507
- {"application/json": model_to_schema(ApiErrorResponse)},
508
- description="Internal server error",
509
- )
510
- async def update_bot_files(request: Request) -> None:
511
- """Update bot files with server-sent events for progress tracking."""
512
- sse_response = await request.respond(content_type="text/event-stream")
513
- project_generator = get_project_generator(request)
514
- input_channel = get_input_channel(request)
515
-
516
- try:
517
- # 1. Received
518
- await _send_sse_event(
519
- sse_response,
520
- ServerSentEvent(event="received", data={"status": "received"}),
521
- )
522
-
523
- # Update bot files
524
- bot_files = request.json
525
- project_generator.update_bot_files(bot_files)
526
-
527
- # 2. Validating
528
- await _send_sse_event(
529
- sse_response,
530
- ServerSentEvent(event="validating", data={"status": "validating"}),
531
- )
532
-
533
- try:
534
- importer = project_generator._create_importer()
535
- validation_error = await validate_project(importer)
536
-
537
- if validation_error:
538
- raise ValidationError(validation_error)
539
-
540
- await _send_sse_event(
541
- sse_response,
542
- ServerSentEvent(
543
- event="validation_success",
544
- data={"status": "validation_success"},
545
- ),
546
- )
547
-
548
- except ValidationError as e:
549
- await _send_sse_event(
550
- sse_response,
551
- ServerSentEvent(
552
- event="validation_error",
553
- data={"status": "validation_error", "error": str(e)},
554
- ),
555
- )
556
- await sse_response.eof()
557
- return
558
-
559
- # 3. Training
560
- await _send_sse_event(
561
- sse_response,
562
- ServerSentEvent(event="training", data={"status": "training"}),
563
- )
564
-
565
- try:
566
- request.app.ctx.agent = await train_and_load_agent(importer)
567
- input_channel.agent = request.app.ctx.agent
568
-
569
- await _send_sse_event(
570
- sse_response,
571
- ServerSentEvent(
572
- event="train_success", data={"status": "train_success"}
573
- ),
574
- )
575
-
576
- except TrainingError as e:
577
- await _send_sse_event(
578
- sse_response,
579
- ServerSentEvent(
580
- event="train_error",
581
- data={"status": "train_error", "error": str(e)},
582
- ),
583
- )
584
- await sse_response.eof()
585
- return
586
-
587
- # 4. Done
588
- await _send_sse_event(
589
- sse_response,
590
- ServerSentEvent(
591
- event="done",
592
- data={
593
- "status": "done",
594
- },
595
- ),
596
- )
597
-
598
- except Exception as e:
599
- await _send_sse_event(
600
- sse_response,
601
- ServerSentEvent(event="error", data={"status": "error", "error": str(e)}),
602
- )
603
- finally:
604
- await sse_response.eof()
605
-
606
-
607
- @bp.route("/data", methods=["GET"])
608
- @openapi.summary("Get bot data")
609
- @openapi.description(
610
- "Retrieves the current bot data in CALM import format with flows, domain, "
611
- "config, endpoints, and NLU data"
612
- )
613
- @openapi.tag("bot-data")
614
- @openapi.response(
615
- 200,
616
- {"application/json": model_to_schema(CALMUserData)},
617
- description="Bot data retrieved successfully",
618
- )
619
- @openapi.response(
620
- 500,
621
- {"application/json": model_to_schema(ApiErrorResponse)},
622
- description="Internal server error",
623
- )
624
- async def get_bot_data(request: Request) -> HTTPResponse:
625
- """Get current bot data in CALM import format."""
626
- try:
627
- project_generator = get_project_generator(request)
628
- calm_parts = extract_calm_import_parts_from_project_generator(project_generator)
629
-
630
- return response.json(calm_parts.model_dump())
631
- except Exception as e:
632
- structlogger.error("bot_builder_service.get_bot_data.error", error=str(e))
633
- return response.json(
634
- ApiErrorResponse(
635
- error="Failed to retrieve bot data",
636
- details={"error": str(e)},
637
- ).model_dump(),
638
- status=500,
639
- )
640
-
641
-
642
- @bp.route("/llm-builder", methods=["POST"])
643
- @openapi.summary("LLM assistant for bot building")
644
- @openapi.description(
645
- "Provides LLM-powered assistance for bot building tasks, including "
646
- "debugging, suggestions, and explanations"
647
- )
648
- @openapi.tag("llm-assistant")
649
- @openapi.body(
650
- {"application/json": model_to_schema(LLMBuilderRequest)},
651
- description="LLM builder request containing chat messages and context",
652
- required=True,
653
- )
654
- @openapi.response(
655
- 200,
656
- {"application/json": model_to_schema(LLMHelperResponse)},
657
- description="LLM response with assistance and suggestions",
658
- )
659
- @openapi.response(
660
- 400,
661
- {"application/json": model_to_schema(ApiErrorResponse)},
662
- description="Validation error in request",
663
- )
664
- @openapi.response(
665
- 502,
666
- {"application/json": model_to_schema(ApiErrorResponse)},
667
- description="LLM generation failed",
668
- )
669
- @openapi.response(
670
- 500,
671
- {"application/json": model_to_schema(ApiErrorResponse)},
672
- description="Internal server error",
673
- )
674
- async def llm_builder(request: Request) -> HTTPResponse:
675
- """Handle LLM builder requests."""
676
- project_generator = get_project_generator(request)
677
- input_channel = get_input_channel(request)
678
-
679
- try:
680
- # Validate request
681
- builder_request = LLMBuilderRequest(**request.json)
682
-
683
- # Get current conversation context
684
- current_tracker = await current_tracker_from_input_channel(
685
- request.app, input_channel
686
- )
687
- bot_logs = get_recent_logs()
688
- chat_bot_files = project_generator.get_bot_files()
689
-
690
- # create LLM builder context
691
- llm_builder_context = LLMBuilderContext(
692
- tracker=current_tracker,
693
- bot_logs=bot_logs,
694
- chat_bot_files=chat_bot_files,
695
- chat_history=builder_request.messages,
696
- )
697
-
698
- # Generate response
699
- messages = await llm_service.create_helper_messages(llm_builder_context)
700
- llm_response = await llm_service.generate_helper_response(messages)
701
-
702
- return response.json(llm_response)
703
-
704
- except LLMGenerationError as e:
705
- structlogger.error(
706
- "bot_builder_service.llm_builder.generation_error", error=str(e)
707
- )
708
- return response.json(
709
- ApiErrorResponse(
710
- error="LLM helper generation failed", details={"llm_error": str(e)}
711
- ).model_dump(),
712
- status=502,
713
- )
714
-
715
- except Exception as e:
716
- structlogger.error(
717
- "bot_builder_service.llm_builder.unexpected_error", error=str(e)
718
- )
719
- return response.json(
720
- ApiErrorResponse(
721
- error="Unexpected error in LLM builder",
722
- details=None,
723
- ).model_dump(),
724
- status=500,
725
- )
726
-
727
-
728
- async def current_tracker_from_input_channel(
729
- app: Any, input_channel: StudioChatInput
730
- ) -> Optional[DialogueStateTracker]:
731
- """Generate chat bot context from current conversation."""
732
- if app.ctx.agent and input_channel.latest_tracker_session_id:
733
- return await app.ctx.agent.tracker_store.retrieve(
734
- input_channel.latest_tracker_session_id
735
- )
736
- else:
737
- return None
738
-
739
-
740
- async def _send_sse_event(sse_response: HTTPResponse, event: ServerSentEvent) -> None:
741
- """Send a server-sent event."""
742
- await sse_response.send(event.format())