rasa-pro 3.12.22__py3-none-any.whl → 3.13.0__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 (354) hide show
  1. rasa/__main__.py +3 -4
  2. rasa/api.py +1 -1
  3. rasa/cli/dialogue_understanding_test.py +1 -1
  4. rasa/cli/e2e_test.py +1 -8
  5. rasa/cli/evaluate.py +2 -2
  6. rasa/cli/export.py +5 -3
  7. rasa/cli/inspect.py +7 -0
  8. rasa/cli/llm_fine_tuning.py +1 -1
  9. rasa/cli/project_templates/default/config.yml +5 -32
  10. rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_cancels_during_a_correction.yml +1 -1
  11. rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_changes_mind_on_a_whim.yml +1 -1
  12. rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_handle.yml +1 -1
  13. rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_name.yml +1 -1
  14. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_adds_contact_to_their_list.yml +1 -1
  15. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_lists_contacts.yml +1 -1
  16. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact.yml +1 -1
  17. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact_from_list.yml +1 -1
  18. rasa/cli/project_templates/default/endpoints.yml +18 -2
  19. rasa/cli/project_templates/defaults.py +133 -0
  20. rasa/cli/project_templates/tutorial/config.yml +1 -1
  21. rasa/cli/project_templates/tutorial/endpoints.yml +1 -1
  22. rasa/cli/run.py +1 -1
  23. rasa/cli/scaffold.py +2 -3
  24. rasa/cli/shell.py +6 -1
  25. rasa/cli/studio/download.py +0 -22
  26. rasa/cli/studio/link.py +36 -0
  27. rasa/cli/studio/pull.py +79 -0
  28. rasa/cli/studio/push.py +78 -0
  29. rasa/cli/studio/studio.py +12 -0
  30. rasa/cli/studio/train.py +1 -5
  31. rasa/cli/studio/upload.py +6 -4
  32. rasa/cli/train.py +5 -1
  33. rasa/cli/utils.py +1 -1
  34. rasa/cli/x.py +1 -1
  35. rasa/constants.py +2 -0
  36. rasa/core/__init__.py +0 -16
  37. rasa/core/actions/action.py +43 -29
  38. rasa/core/actions/action_repeat_bot_messages.py +18 -22
  39. rasa/core/actions/action_run_slot_rejections.py +1 -2
  40. rasa/core/agent.py +24 -3
  41. rasa/core/available_endpoints.py +146 -0
  42. rasa/core/brokers/kafka.py +4 -0
  43. rasa/core/brokers/pika.py +5 -2
  44. rasa/core/brokers/sql.py +1 -1
  45. rasa/core/channels/__init__.py +3 -0
  46. rasa/core/channels/botframework.py +2 -2
  47. rasa/core/channels/channel.py +2 -2
  48. rasa/core/channels/development_inspector.py +1 -1
  49. rasa/core/channels/facebook.py +1 -4
  50. rasa/core/channels/hangouts.py +8 -5
  51. rasa/core/channels/inspector/.eslintrc.cjs +12 -6
  52. rasa/core/channels/inspector/.prettierrc +5 -0
  53. rasa/core/channels/inspector/README.md +11 -5
  54. rasa/core/channels/inspector/dist/assets/{arc-9f75cc3b.js → arc-371401b1.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7f34db23.js → blockDiagram-38ab4fdb-3f126156.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-948bab2c.js → c4Diagram-3d4e48cf-12f22eb7.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +1 -0
  58. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-53b0dd0e.js → classDiagram-70f12bd4-03b1d386.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-fdf789e7.js → classDiagram-v2-f2320105-84f69d63.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +1 -0
  61. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-87c4ece5.js → createText-2e5e7dd3-ca47fd38.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-5a8b0749.js → edges-e0da2a9e-f837ca8a.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-66da90e2.js → erDiagram-9861fffd-8717ac54.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-10044f05.js → flowDb-956e92f1-94f38b83.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-f338f66a.js → flowDiagram-66a62f08-b616f9fb.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +1 -0
  67. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-b13140aa.js → flowchart-elk-definition-4a651766-f5d24bb8.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-f2b4a55a.js → ganttDiagram-c361ad54-b43ba8d9.js} +1 -1
  69. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-dedc298d.js → gitGraphDiagram-72cf32ee-c3aafaa5.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/{graph-4ede11ff.js → graph-0d0a2c10.js} +1 -1
  71. rasa/core/channels/inspector/dist/assets/{index-3862675e-65549d37.js → index-3862675e-58ea0305.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/{index-3a23e736.js → index-cce6f8a1.js} +123 -123
  73. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-65439671.js → infoDiagram-f8f76790-b8f60461.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-56d03d98.js → journeyDiagram-49397b02-95be5545.js} +1 -1
  75. rasa/core/channels/inspector/dist/assets/{layout-dd48f7f4.js → layout-da885b9b.js} +1 -1
  76. rasa/core/channels/inspector/dist/assets/{line-1569ad2c.js → line-f1c817d3.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/{linear-48bf4935.js → linear-d42801e6.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-688504c1.js → mindmap-definition-fc14e90a-a38923a6.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-78b6d7e6.js → pieDiagram-8a3498a8-ca6e71e9.js} +1 -1
  80. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-048b84b3.js → quadrantDiagram-120e2f19-b290dae9.js} +1 -1
  81. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-dd67f107.js → requirementDiagram-deff3bca-03f02ceb.js} +1 -1
  82. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-8128436e.js → sankeyDiagram-04a897e0-c49eee40.js} +1 -1
  83. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-1a0d1461.js → sequenceDiagram-704730f1-b2cd6a3d.js} +1 -1
  84. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-46d388ed.js → stateDiagram-587899a1-e53a2028.js} +1 -1
  85. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-ea42951a.js → stateDiagram-v2-d93cdb3a-e1982a03.js} +1 -1
  86. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-7427ed0c.js → styles-6aaf32cf-d0226ca5.js} +1 -1
  87. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-ff5e5a16.js → styles-9a916d00-0e21dc00.js} +1 -1
  88. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-7b3680cf.js → styles-c10674c1-9588494e.js} +1 -1
  89. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f860f2ad.js → svgDrawCommon-08f97a94-be478d4f.js} +1 -1
  90. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-2eebf0c8.js → timeline-definition-85554ec2-74631749.js} +1 -1
  91. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-5d7f4e96.js → xychartDiagram-e933f94c-a043552f.js} +1 -1
  92. rasa/core/channels/inspector/dist/index.html +1 -1
  93. rasa/core/channels/inspector/package.json +3 -1
  94. rasa/core/channels/inspector/src/App.tsx +91 -90
  95. rasa/core/channels/inspector/src/components/Chat.tsx +45 -41
  96. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +40 -40
  97. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +57 -57
  98. rasa/core/channels/inspector/src/components/DialogueStack.tsx +36 -27
  99. rasa/core/channels/inspector/src/components/ExpandIcon.tsx +4 -4
  100. rasa/core/channels/inspector/src/components/FullscreenButton.tsx +7 -7
  101. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +28 -12
  102. rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +9 -9
  103. rasa/core/channels/inspector/src/components/RasaLogo.tsx +5 -5
  104. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +55 -60
  105. rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +5 -5
  106. rasa/core/channels/inspector/src/components/Slots.tsx +22 -22
  107. rasa/core/channels/inspector/src/components/Welcome.tsx +28 -31
  108. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +245 -0
  109. rasa/core/channels/inspector/src/helpers/audio/microphone-processor.js +12 -0
  110. rasa/core/channels/inspector/src/helpers/audio/playback-processor.js +36 -0
  111. rasa/core/channels/inspector/src/helpers/conversation.ts +7 -7
  112. rasa/core/channels/inspector/src/helpers/formatters.test.ts +181 -181
  113. rasa/core/channels/inspector/src/helpers/formatters.ts +111 -111
  114. rasa/core/channels/inspector/src/helpers/utils.ts +78 -61
  115. rasa/core/channels/inspector/src/main.tsx +8 -8
  116. rasa/core/channels/inspector/src/theme/Button/Button.ts +8 -8
  117. rasa/core/channels/inspector/src/theme/Heading/Heading.ts +7 -7
  118. rasa/core/channels/inspector/src/theme/Input/Input.ts +9 -9
  119. rasa/core/channels/inspector/src/theme/Link/Link.ts +6 -6
  120. rasa/core/channels/inspector/src/theme/Modal/Modal.ts +13 -13
  121. rasa/core/channels/inspector/src/theme/Table/Table.tsx +10 -10
  122. rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +5 -5
  123. rasa/core/channels/inspector/src/theme/base/breakpoints.ts +7 -7
  124. rasa/core/channels/inspector/src/theme/base/colors.ts +64 -64
  125. rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +21 -18
  126. rasa/core/channels/inspector/src/theme/base/radii.ts +8 -8
  127. rasa/core/channels/inspector/src/theme/base/shadows.ts +5 -5
  128. rasa/core/channels/inspector/src/theme/base/sizes.ts +5 -5
  129. rasa/core/channels/inspector/src/theme/base/space.ts +12 -12
  130. rasa/core/channels/inspector/src/theme/base/styles.ts +5 -5
  131. rasa/core/channels/inspector/src/theme/base/typography.ts +12 -12
  132. rasa/core/channels/inspector/src/theme/base/zIndices.ts +3 -3
  133. rasa/core/channels/inspector/src/theme/index.ts +38 -38
  134. rasa/core/channels/inspector/src/types.ts +56 -50
  135. rasa/core/channels/inspector/yarn.lock +5 -0
  136. rasa/core/channels/mattermost.py +1 -1
  137. rasa/core/channels/rasa_chat.py +2 -4
  138. rasa/core/channels/rest.py +5 -4
  139. rasa/core/channels/socketio.py +56 -41
  140. rasa/core/channels/studio_chat.py +329 -68
  141. rasa/core/channels/vier_cvg.py +1 -2
  142. rasa/core/channels/voice_ready/audiocodes.py +4 -11
  143. rasa/core/channels/voice_ready/jambonz.py +5 -6
  144. rasa/core/channels/voice_ready/twilio_voice.py +13 -12
  145. rasa/core/channels/voice_ready/utils.py +22 -0
  146. rasa/core/channels/voice_stream/audiocodes.py +13 -16
  147. rasa/core/channels/voice_stream/browser_audio.py +1 -1
  148. rasa/core/channels/voice_stream/genesys.py +37 -18
  149. rasa/core/channels/voice_stream/jambonz.py +232 -0
  150. rasa/core/channels/voice_stream/tts/__init__.py +8 -0
  151. rasa/core/channels/voice_stream/twilio_media_streams.py +15 -12
  152. rasa/core/channels/voice_stream/voice_channel.py +71 -27
  153. rasa/core/concurrent_lock_store.py +24 -10
  154. rasa/core/evaluation/marker_tracker_loader.py +1 -1
  155. rasa/core/exporter.py +37 -1
  156. rasa/core/http_interpreter.py +3 -7
  157. rasa/core/information_retrieval/faiss.py +18 -11
  158. rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
  159. rasa/core/jobs.py +2 -1
  160. rasa/core/lock_store.py +151 -60
  161. rasa/core/nlg/contextual_response_rephraser.py +17 -7
  162. rasa/core/nlg/generator.py +5 -22
  163. rasa/core/nlg/interpolator.py +2 -3
  164. rasa/core/nlg/response.py +6 -43
  165. rasa/core/nlg/summarize.py +1 -1
  166. rasa/core/nlg/translate.py +0 -8
  167. rasa/core/policies/enterprise_search_policy.py +305 -189
  168. rasa/core/policies/enterprise_search_policy_config.py +241 -0
  169. rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +67 -0
  170. rasa/core/policies/flow_policy.py +1 -1
  171. rasa/core/policies/flows/flow_executor.py +102 -17
  172. rasa/core/policies/intentless_policy.py +56 -17
  173. rasa/core/processor.py +70 -49
  174. rasa/core/run.py +33 -11
  175. rasa/core/tracker_stores/__init__.py +0 -0
  176. rasa/core/{auth_retry_tracker_store.py → tracker_stores/auth_retry_tracker_store.py} +66 -1
  177. rasa/core/tracker_stores/dynamo_tracker_store.py +256 -0
  178. rasa/core/tracker_stores/mongo_tracker_store.py +223 -0
  179. rasa/core/tracker_stores/redis_tracker_store.py +252 -0
  180. rasa/core/tracker_stores/sql_tracker_store.py +582 -0
  181. rasa/core/tracker_stores/tracker_store.py +839 -0
  182. rasa/core/training/interactive.py +1 -1
  183. rasa/core/utils.py +24 -95
  184. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -1
  185. rasa/dialogue_understanding/coexistence/llm_based_router.py +13 -11
  186. rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -0
  187. rasa/dialogue_understanding/commands/cancel_flow_command.py +3 -1
  188. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -0
  189. rasa/dialogue_understanding/commands/clarify_command.py +6 -2
  190. rasa/dialogue_understanding/commands/command_syntax_manager.py +1 -0
  191. rasa/dialogue_understanding/commands/correct_slots_command.py +5 -6
  192. rasa/dialogue_understanding/commands/error_command.py +1 -1
  193. rasa/dialogue_understanding/commands/human_handoff_command.py +3 -3
  194. rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -0
  195. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -0
  196. rasa/dialogue_understanding/commands/set_slot_command.py +8 -4
  197. rasa/dialogue_understanding/commands/skip_question_command.py +3 -3
  198. rasa/dialogue_understanding/commands/start_flow_command.py +7 -3
  199. rasa/dialogue_understanding/generator/__init__.py +7 -1
  200. rasa/dialogue_understanding/generator/command_generator.py +4 -2
  201. rasa/dialogue_understanding/generator/command_parser.py +2 -2
  202. rasa/dialogue_understanding/generator/command_parser_validator.py +63 -0
  203. rasa/dialogue_understanding/generator/llm_based_command_generator.py +1 -2
  204. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -2
  205. rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
  206. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +0 -2
  207. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -0
  208. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +1 -0
  209. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +79 -0
  210. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +79 -0
  211. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +26 -461
  212. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +147 -0
  213. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +461 -0
  214. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +20 -64
  215. rasa/dialogue_understanding/patterns/cancel.py +1 -2
  216. rasa/dialogue_understanding/patterns/clarify.py +1 -1
  217. rasa/dialogue_understanding/patterns/correction.py +2 -2
  218. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +42 -27
  219. rasa/dialogue_understanding/patterns/domain_for_patterns.py +190 -0
  220. rasa/dialogue_understanding/processor/command_processor.py +6 -7
  221. rasa/dialogue_understanding_test/command_metric_calculation.py +7 -40
  222. rasa/dialogue_understanding_test/command_metrics.py +38 -0
  223. rasa/dialogue_understanding_test/du_test_case.py +58 -25
  224. rasa/dialogue_understanding_test/du_test_result.py +228 -132
  225. rasa/dialogue_understanding_test/du_test_runner.py +11 -2
  226. rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
  227. rasa/dialogue_understanding_test/io.py +35 -8
  228. rasa/e2e_test/constants.py +1 -1
  229. rasa/e2e_test/e2e_test_runner.py +1 -1
  230. rasa/e2e_test/e2e_test_schema.yml +3 -3
  231. rasa/engine/constants.py +1 -1
  232. rasa/engine/graph.py +2 -2
  233. rasa/engine/recipes/default_recipe.py +1 -1
  234. rasa/engine/validation.py +3 -2
  235. rasa/hooks.py +2 -30
  236. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +2 -6
  237. rasa/model_manager/model_api.py +89 -1
  238. rasa/model_manager/runner_service.py +20 -4
  239. rasa/model_manager/socket_bridge.py +0 -7
  240. rasa/model_manager/trainer_service.py +10 -4
  241. rasa/plugin.py +2 -15
  242. rasa/privacy/__init__.py +0 -0
  243. rasa/privacy/constants.py +83 -0
  244. rasa/privacy/event_broker_utils.py +77 -0
  245. rasa/privacy/privacy_config.py +281 -0
  246. rasa/privacy/privacy_config_schema.json +86 -0
  247. rasa/privacy/privacy_filter.py +393 -0
  248. rasa/privacy/privacy_manager.py +594 -0
  249. rasa/server.py +23 -2
  250. rasa/shared/constants.py +17 -0
  251. rasa/shared/core/command_payload_reader.py +1 -5
  252. rasa/shared/core/constants.py +4 -3
  253. rasa/shared/core/domain.py +172 -11
  254. rasa/shared/core/events.py +100 -6
  255. rasa/shared/core/flows/flow.py +30 -5
  256. rasa/shared/core/flows/flow_step.py +19 -3
  257. rasa/shared/core/flows/flow_step_links.py +15 -0
  258. rasa/shared/core/flows/flow_step_sequence.py +6 -0
  259. rasa/shared/core/flows/flows_yaml_schema.json +3 -0
  260. rasa/shared/core/flows/nlu_trigger.py +13 -0
  261. rasa/shared/core/flows/steps/action.py +7 -4
  262. rasa/shared/core/flows/steps/call.py +11 -4
  263. rasa/shared/core/flows/steps/collect.py +71 -6
  264. rasa/shared/core/flows/steps/internal.py +6 -1
  265. rasa/shared/core/flows/steps/link.py +7 -4
  266. rasa/shared/core/flows/steps/no_operation.py +7 -4
  267. rasa/shared/core/flows/steps/set_slots.py +8 -4
  268. rasa/shared/core/flows/validation.py +25 -5
  269. rasa/shared/core/flows/yaml_flows_io.py +106 -5
  270. rasa/shared/core/slots.py +29 -1
  271. rasa/shared/core/trackers.py +21 -10
  272. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
  273. rasa/shared/importers/importer.py +8 -0
  274. rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
  275. rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
  276. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
  277. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  278. rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
  279. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
  280. rasa/shared/providers/_configs/utils.py +0 -99
  281. rasa/shared/providers/llm/default_litellm_llm_client.py +2 -2
  282. rasa/shared/utils/common.py +43 -1
  283. rasa/shared/utils/configs.py +110 -0
  284. rasa/shared/utils/constants.py +0 -3
  285. rasa/shared/utils/llm.py +245 -8
  286. rasa/shared/utils/pykwalify_extensions.py +0 -9
  287. rasa/shared/utils/yaml.py +32 -0
  288. rasa/studio/constants.py +1 -0
  289. rasa/studio/data_handler.py +33 -12
  290. rasa/studio/download.py +117 -435
  291. rasa/studio/link.py +211 -0
  292. rasa/studio/prompts.py +221 -0
  293. rasa/studio/pull/__init__.py +0 -0
  294. rasa/studio/pull/data.py +222 -0
  295. rasa/studio/pull/domains.py +60 -0
  296. rasa/studio/pull/pull.py +239 -0
  297. rasa/studio/push.py +138 -0
  298. rasa/studio/results_logger.py +6 -1
  299. rasa/studio/train.py +1 -1
  300. rasa/studio/upload.py +243 -72
  301. rasa/studio/utils.py +33 -0
  302. rasa/telemetry.py +83 -26
  303. rasa/tracing/config.py +4 -5
  304. rasa/tracing/constants.py +19 -1
  305. rasa/tracing/instrumentation/attribute_extractors.py +68 -16
  306. rasa/tracing/instrumentation/instrumentation.py +54 -3
  307. rasa/tracing/instrumentation/metrics.py +98 -15
  308. rasa/tracing/metric_instrument_provider.py +75 -3
  309. rasa/utils/common.py +43 -22
  310. rasa/utils/endpoints.py +22 -1
  311. rasa/utils/licensing.py +2 -3
  312. rasa/utils/log_utils.py +1 -45
  313. rasa/validator.py +2 -8
  314. rasa/version.py +1 -1
  315. {rasa_pro-3.12.22.dist-info → rasa_pro-3.13.0.dist-info}/METADATA +11 -12
  316. {rasa_pro-3.12.22.dist-info → rasa_pro-3.13.0.dist-info}/RECORD +333 -309
  317. rasa/anonymization/__init__.py +0 -2
  318. rasa/anonymization/anonymisation_rule_yaml_reader.py +0 -91
  319. rasa/anonymization/anonymization_pipeline.py +0 -286
  320. rasa/anonymization/anonymization_rule_executor.py +0 -266
  321. rasa/anonymization/anonymization_rule_orchestrator.py +0 -119
  322. rasa/anonymization/schemas/config.yml +0 -47
  323. rasa/anonymization/utils.py +0 -118
  324. rasa/cli/project_templates/calm/config.yml +0 -10
  325. rasa/cli/project_templates/calm/credentials.yml +0 -33
  326. rasa/cli/project_templates/calm/endpoints.yml +0 -58
  327. rasa/cli/project_templates/default/actions/actions.py +0 -27
  328. rasa/cli/project_templates/default/data/nlu.yml +0 -91
  329. rasa/cli/project_templates/default/data/rules.yml +0 -13
  330. rasa/cli/project_templates/default/data/stories.yml +0 -30
  331. rasa/cli/project_templates/default/domain.yml +0 -34
  332. rasa/cli/project_templates/default/tests/test_stories.yml +0 -91
  333. rasa/core/channels/inspector/dist/assets/channel-dfa68278.js +0 -1
  334. rasa/core/channels/inspector/dist/assets/clone-edb7f119.js +0 -1
  335. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-65e7c670.js +0 -1
  336. rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -191
  337. rasa/core/tracker_store.py +0 -1792
  338. /rasa/cli/project_templates/{calm → default}/actions/action_template.py +0 -0
  339. /rasa/cli/project_templates/{calm → default}/actions/add_contact.py +0 -0
  340. /rasa/cli/project_templates/{calm → default}/actions/db.py +0 -0
  341. /rasa/cli/project_templates/{calm → default}/actions/list_contacts.py +0 -0
  342. /rasa/cli/project_templates/{calm → default}/actions/remove_contact.py +0 -0
  343. /rasa/cli/project_templates/{calm → default}/data/flows/add_contact.yml +0 -0
  344. /rasa/cli/project_templates/{calm → default}/data/flows/list_contacts.yml +0 -0
  345. /rasa/cli/project_templates/{calm → default}/data/flows/remove_contact.yml +0 -0
  346. /rasa/cli/project_templates/{calm → default}/db/contacts.json +0 -0
  347. /rasa/cli/project_templates/{calm → default}/domain/add_contact.yml +0 -0
  348. /rasa/cli/project_templates/{calm → default}/domain/list_contacts.yml +0 -0
  349. /rasa/cli/project_templates/{calm → default}/domain/remove_contact.yml +0 -0
  350. /rasa/cli/project_templates/{calm → default}/domain/shared.yml +0 -0
  351. /rasa/{cli/project_templates/calm/actions → core/information_retrieval/ingestion}/__init__.py +0 -0
  352. {rasa_pro-3.12.22.dist-info → rasa_pro-3.13.0.dist-info}/NOTICE +0 -0
  353. {rasa_pro-3.12.22.dist-info → rasa_pro-3.13.0.dist-info}/WHEEL +0 -0
  354. {rasa_pro-3.12.22.dist-info → rasa_pro-3.13.0.dist-info}/entry_points.txt +0 -0
rasa/studio/upload.py CHANGED
@@ -2,11 +2,12 @@ import argparse
2
2
  import base64
3
3
  import re
4
4
  import sys
5
- from typing import Any, Dict, Iterable, List, Set, Text, Tuple, Union
5
+ from typing import Any, Dict, Iterable, List, Optional, Set, Text, Tuple, Union
6
6
 
7
7
  import questionary
8
8
  import requests
9
9
  import structlog
10
+ from pydantic import BaseModel, Field
10
11
 
11
12
  import rasa.cli.telemetry
12
13
  import rasa.cli.utils
@@ -30,14 +31,17 @@ from rasa.shared.nlu.training_data.formats.rasa_yaml import (
30
31
  RasaYAMLReader,
31
32
  RasaYAMLWriter,
32
33
  )
34
+ from rasa.shared.utils.llm import collect_custom_prompts
33
35
  from rasa.shared.utils.yaml import (
34
36
  dump_obj_as_yaml_to_string,
37
+ read_yaml,
35
38
  read_yaml_file,
36
39
  )
37
40
  from rasa.studio import results_logger
38
41
  from rasa.studio.auth import KeycloakTokenReader
39
42
  from rasa.studio.config import StudioConfig
40
43
  from rasa.studio.results_logger import StudioResult, with_studio_error_handler
44
+ from rasa.studio.utils import validate_argument_paths
41
45
  from rasa.telemetry import track_upload_to_studio_failed
42
46
 
43
47
  structlogger = structlog.get_logger()
@@ -64,6 +68,16 @@ DOMAIN_KEYS = [
64
68
  ]
65
69
 
66
70
 
71
+ class CALMImportParts(BaseModel):
72
+ """All pieces that will be uploaded to Rasa Studio."""
73
+
74
+ flows: Dict[str, Any]
75
+ domain: Dict[str, Any]
76
+ config: Dict[str, Any]
77
+ endpoints: Dict[str, Any]
78
+ nlu: Dict[str, Any] = Field(default_factory=dict)
79
+
80
+
67
81
  def _get_selected_entities_and_intents(
68
82
  args: argparse.Namespace,
69
83
  intents_from_files: Set[Text],
@@ -103,7 +117,7 @@ def run_validation(args: argparse.Namespace) -> None:
103
117
 
104
118
  training_data_importer = TrainingDataImporter.load_from_dict(
105
119
  domain_path=args.domain,
106
- training_data_paths=args.data,
120
+ training_data_paths=[args.data],
107
121
  config_path=args.config,
108
122
  expand_env_vars=False,
109
123
  )
@@ -130,6 +144,7 @@ def run_validation(args: argparse.Namespace) -> None:
130
144
 
131
145
  def handle_upload(args: argparse.Namespace) -> None:
132
146
  """Uploads primitives to rasa studio."""
147
+ validate_argument_paths(args)
133
148
  studio_config = StudioConfig.read_config()
134
149
  endpoint = studio_config.studio_url
135
150
  verify = not studio_config.disable_verify
@@ -154,15 +169,19 @@ def handle_upload(args: argparse.Namespace) -> None:
154
169
  args.config, "config", DEFAULT_CONFIG_PATH
155
170
  )
156
171
 
172
+ config = read_yaml_file(args.config, expand_env_vars=False)
173
+ assistant_name = args.assistant_name or _get_assistant_name(config)
174
+ args.assistant_name = assistant_name
175
+ if not _handle_existing_assistant(
176
+ assistant_name, studio_config.studio_url, verify, args
177
+ ):
178
+ return
179
+
157
180
  Domain.expand_env_vars = False
158
181
  RasaYAMLReader.expand_env_vars = False
159
182
  YAMLFlowsReader.expand_env_vars = False
160
183
 
161
- # check safely if args.calm is set and not fail if not
162
- if hasattr(args, "calm") and args.calm:
163
- upload_calm_assistant(args, endpoint, verify=verify)
164
- else:
165
- upload_nlu_assistant(args, endpoint, verify=verify)
184
+ upload_calm_assistant(args, endpoint, verify=verify)
166
185
 
167
186
 
168
187
  config_keys = [
@@ -212,75 +231,95 @@ def _get_assistant_name(config: Dict[Text, Any]) -> str:
212
231
  return assistant_name
213
232
 
214
233
 
215
- @with_studio_error_handler
216
- def upload_calm_assistant(
217
- args: argparse.Namespace, endpoint: str, verify: bool = True
218
- ) -> StudioResult:
219
- """Validates and uploads the CALM assistant data to Rasa Studio.
234
+ def build_calm_import_parts(
235
+ data_path: Union[Text, List[Text]],
236
+ domain_path: Text,
237
+ config_path: Text,
238
+ endpoints_path: Optional[Text] = None,
239
+ assistant_name: Optional[Text] = None,
240
+ ) -> Tuple[str, CALMImportParts]:
241
+ """Builds the parts of the assistant to be uploaded to Studio.
220
242
 
221
243
  Args:
222
- args: The command line arguments
223
- - data: The path to the training data
224
- - domain: The path to the domain
225
- - flows: The path to the flows
226
- - endpoints: The path to the endpoints
227
- - config: The path to the config
228
- endpoint: The studio endpoint
244
+ data_path: The path to the training data
245
+ domain_path: The path to the domain
246
+ config_path: The path to the config
247
+ endpoints_path: The path to the endpoints
248
+ assistant_name: The name of the assistant
249
+
229
250
  Returns:
230
- None
251
+ The assistant name and the parts to be uploaded
231
252
  """
232
- run_validation(args)
233
-
234
- structlogger.info(
235
- "rasa.studio.upload.loading_data", event_info="Parsing CALM assistant data..."
236
- )
237
-
238
253
  importer = TrainingDataImporter.load_from_dict(
239
- domain_path=args.domain,
240
- config_path=args.config,
254
+ domain_path=domain_path,
255
+ config_path=config_path,
241
256
  expand_env_vars=False,
242
257
  )
243
258
 
244
- # Prepare config and domain
245
- config = importer.get_config()
246
- assistant_name = _get_assistant_name(config)
247
- config_from_files = read_yaml_file(args.config, expand_env_vars=False)
248
- domain_from_files = importer.get_user_domain().as_dict()
259
+ config = read_yaml_file(config_path, expand_env_vars=False)
260
+ endpoints = read_yaml_file(endpoints_path, expand_env_vars=False)
261
+ assistant_name = assistant_name or _get_assistant_name(config)
249
262
 
250
- # Extract domain and config values
263
+ domain_from_files = importer.get_user_domain().as_dict()
251
264
  domain = extract_values(domain_from_files, DOMAIN_KEYS)
252
265
 
253
- # Prepare flows
254
266
  flow_importer = FlowSyncImporter.load_from_dict(
255
- training_data_paths=args.data, expand_env_vars=False
267
+ training_data_paths=[str(data_path)], expand_env_vars=False
256
268
  )
269
+
257
270
  flows = list(flow_importer.get_user_flows())
271
+ flows_yaml = YamlFlowsWriter().dumps(flows)
272
+ flows = read_yaml(flows_yaml, expand_env_vars=False)
258
273
 
259
- # We instantiate the TrainingDataImporter again on purpose to avoid
260
- # adding patterns to domain's actions. More info https://t.ly/W8uuc
261
274
  nlu_importer = TrainingDataImporter.load_from_dict(
262
- training_data_paths=args.data, expand_env_vars=False
275
+ training_data_paths=[str(data_path)], expand_env_vars=False
263
276
  )
264
277
  nlu_data = nlu_importer.get_nlu_data()
265
278
  nlu_examples = nlu_data.filter_training_examples(
266
279
  lambda ex: ex.get("intent") in nlu_data.intents
267
280
  )
268
281
  nlu_examples_yaml = RasaYAMLWriter().dumps(nlu_examples)
282
+ nlu = read_yaml(nlu_examples_yaml, expand_env_vars=False)
283
+
284
+ parts = CALMImportParts(
285
+ flows=flows,
286
+ domain=domain,
287
+ config=config,
288
+ endpoints=endpoints,
289
+ nlu=nlu,
290
+ )
291
+
292
+ return assistant_name, parts
293
+
294
+
295
+ @with_studio_error_handler
296
+ def upload_calm_assistant(
297
+ args: argparse.Namespace, endpoint: str, verify: bool = True
298
+ ) -> StudioResult:
299
+ def yaml_or_empty(part: Dict[Text, Any]) -> Optional[str]:
300
+ return dump_obj_as_yaml_to_string(part) if part else None
269
301
 
270
- # Prepare endpoints
271
- endpoints_from_files = read_yaml_file(args.endpoints, expand_env_vars=False)
272
- endpoints_str = dump_obj_as_yaml_to_string(
273
- endpoints_from_files, transform=remove_quotes
302
+ run_validation(args)
303
+ structlogger.info(
304
+ "rasa.studio.upload.loading_data", event_info="Parsing CALM assistant data..."
305
+ )
306
+ assistant_name, parts = build_calm_import_parts(
307
+ data_path=args.data,
308
+ domain_path=args.domain,
309
+ config_path=args.config,
310
+ endpoints_path=args.endpoints,
311
+ assistant_name=args.assistant_name,
274
312
  )
275
313
 
276
- # Build GraphQL request
314
+ prompts_json = collect_custom_prompts(parts.config, parts.endpoints)
277
315
  graphql_req = build_import_request(
278
316
  assistant_name,
279
- flows_yaml=YamlFlowsWriter().dumps(flows),
280
- domain_yaml=dump_obj_as_yaml_to_string(domain),
281
- config_yaml=dump_obj_as_yaml_to_string(config_from_files),
282
- endpoints=endpoints_str,
283
- nlu_yaml=nlu_examples_yaml,
317
+ flows_yaml=yaml_or_empty(parts.flows),
318
+ domain_yaml=yaml_or_empty(parts.domain),
319
+ config_yaml=yaml_or_empty(parts.config),
320
+ endpoints=yaml_or_empty(parts.endpoints),
321
+ nlu_yaml=yaml_or_empty(parts.nlu),
322
+ prompts_json=prompts_json,
284
323
  )
285
324
 
286
325
  structlogger.info(
@@ -312,7 +351,7 @@ def upload_nlu_assistant(
312
351
  )
313
352
  importer = TrainingDataImporter.load_from_dict(
314
353
  domain_path=args.domain,
315
- training_data_paths=args.data,
354
+ training_data_paths=[args.data],
316
355
  config_path=args.config,
317
356
  expand_env_vars=False,
318
357
  )
@@ -395,7 +434,6 @@ def make_request(endpoint: str, graphql_req: Dict, verify: bool = True) -> Studi
395
434
  },
396
435
  verify=verify,
397
436
  )
398
-
399
437
  if results_logger.response_has_errors(res.json()):
400
438
  track_upload_to_studio_failed(res.json())
401
439
  return StudioResult.error(res.json())
@@ -423,39 +461,69 @@ def _add_missing_entities(
423
461
 
424
462
  def build_import_request(
425
463
  assistant_name: str,
426
- flows_yaml: str,
427
- domain_yaml: str,
428
- config_yaml: str,
429
- endpoints: str,
430
- nlu_yaml: str = "",
464
+ flows_yaml: Optional[str] = None,
465
+ domain_yaml: Optional[str] = None,
466
+ config_yaml: Optional[str] = None,
467
+ endpoints: Optional[str] = None,
468
+ nlu_yaml: Optional[str] = None,
469
+ prompts_json: Optional[Dict[str, str]] = None,
431
470
  ) -> Dict:
432
- # b64encode expects bytes and returns bytes so we need to decode to string
433
- base64_domain = base64.b64encode(domain_yaml.encode("utf-8")).decode("utf-8")
434
- base64_flows = base64.b64encode(flows_yaml.encode("utf-8")).decode("utf-8")
435
- base64_config = base64.b64encode(config_yaml.encode("utf-8")).decode("utf-8")
436
- base64_nlu = base64.b64encode(nlu_yaml.encode("utf-8")).decode("utf-8")
437
- base64_endpoints = base64.b64encode(endpoints.encode("utf-8")).decode("utf-8")
471
+ """Builds the GraphQL request for uploading a modern assistant.
472
+
473
+ Args:
474
+ assistant_name: The name of the assistant
475
+ flows_yaml: The YAML representation of the flows
476
+ domain_yaml: The YAML representation of the domain
477
+ config_yaml: The YAML representation of the config
478
+ endpoints: The YAML representation of the endpoints
479
+ nlu_yaml: The YAML representation of the NLU data
480
+ prompts_json: The JSON representation of the prompts
481
+
482
+ Returns:
483
+ A dictionary representing the GraphQL request for uploading the assistant.
484
+ """
485
+ inputs_map = {
486
+ "domain": domain_yaml,
487
+ "flows": flows_yaml,
488
+ "config": config_yaml,
489
+ "endpoints": endpoints,
490
+ "nlu": nlu_yaml,
491
+ }
492
+
493
+ payload: Dict[Text, Any] = {
494
+ field: convert_string_to_base64(value)
495
+ for field, value in inputs_map.items()
496
+ if value is not None
497
+ }
498
+
499
+ if prompts_json:
500
+ payload["prompts"] = prompts_json
501
+
502
+ variables_input = {"assistantName": assistant_name, **payload}
438
503
 
439
504
  graphql_req = {
440
505
  "query": (
441
506
  "mutation UploadModernAssistant($input: UploadModernAssistantInput!)"
442
507
  "{\n uploadModernAssistant(input: $input)\n}"
443
508
  ),
444
- "variables": {
445
- "input": {
446
- "assistantName": assistant_name,
447
- "domain": base64_domain,
448
- "flows": base64_flows,
449
- "nlu": base64_nlu,
450
- "config": base64_config,
451
- "endpoints": base64_endpoints,
452
- }
453
- },
509
+ "variables": {"input": variables_input},
454
510
  }
455
511
 
456
512
  return graphql_req
457
513
 
458
514
 
515
+ def convert_string_to_base64(string: str) -> str:
516
+ """Converts a string to base64.
517
+
518
+ Args:
519
+ string: The string to convert
520
+
521
+ Returns:
522
+ The base64 encoded string
523
+ """
524
+ return base64.b64encode(string.encode("utf-8")).decode("utf-8")
525
+
526
+
459
527
  def build_request(
460
528
  assistant_name: str, nlu_examples_yaml: str, domain_yaml: str
461
529
  ) -> Dict:
@@ -563,3 +631,106 @@ def remove_quotes(node: Any) -> Any:
563
631
  return {k: remove_quotes(v) for k, v in node.items()}
564
632
  else:
565
633
  return node
634
+
635
+
636
+ def check_if_assistant_already_exists(
637
+ assistant_name: str, endpoint: str, verify: bool = True
638
+ ) -> bool:
639
+ """Checks if the assistant already exists in Studio.
640
+
641
+ Args:
642
+ assistant_name: The name of the assistant
643
+ endpoint: The studio endpoint
644
+ verify: Whether to verify SSL
645
+
646
+ Returns:
647
+ bool: The upload confirmation
648
+ """
649
+ graphql_req = build_get_assistant_by_name_request(assistant_name)
650
+
651
+ structlogger.info(
652
+ "rasa.studio.upload.assistant_already_exists",
653
+ event_info="Checking if assistant already exists...",
654
+ assistant_name=assistant_name,
655
+ )
656
+
657
+ token = KeycloakTokenReader().get_token()
658
+ res = requests.post(
659
+ endpoint,
660
+ json=graphql_req,
661
+ headers={
662
+ "Authorization": f"{token.token_type} {token.access_token}",
663
+ "Content-Type": "application/json",
664
+ },
665
+ verify=verify,
666
+ )
667
+ response = res.json()["data"]["assistantByName"] or {}
668
+ if results_logger.response_has_id(response):
669
+ structlogger.info(
670
+ "rasa.studio.upload.assistant_already_exists",
671
+ event_info="Assistant already exists.",
672
+ )
673
+ return True
674
+
675
+ structlogger.info(
676
+ "rasa.studio.upload.assistant_already_exists", event_info="Assistant not found."
677
+ )
678
+ return False
679
+
680
+
681
+ def build_get_assistant_by_name_request(
682
+ assistant_name: str,
683
+ ) -> Dict:
684
+ graphql_req = {
685
+ "query": (
686
+ "query AssistantByName($input: AssistantByNameInput!) {"
687
+ " assistantByName(input: $input) {"
688
+ " ... on Assistant { id name mode }"
689
+ " ... on AssistantByName_AssistantNotFound { _ }"
690
+ " }"
691
+ "}"
692
+ ),
693
+ "variables": {
694
+ "input": {
695
+ "assistantName": assistant_name,
696
+ }
697
+ },
698
+ }
699
+ return graphql_req
700
+
701
+
702
+ def _handle_existing_assistant(
703
+ assistant_name: str,
704
+ endpoint: str,
705
+ verify: bool,
706
+ args: argparse.Namespace,
707
+ ) -> bool:
708
+ """Deal with the case that an assistant with the same name already exists.
709
+
710
+ Args:
711
+ assistant_name: The name of the assistant
712
+ endpoint: The studio endpoint
713
+ verify: Whether to verify SSL
714
+ args: The command line arguments
715
+
716
+ Returns:
717
+ bool: True if the assistant does not exist and can be created,
718
+ False if the assistant already exists and was linked.
719
+ """
720
+ from rasa.studio.link import handle_link
721
+
722
+ if not check_if_assistant_already_exists(assistant_name, endpoint, verify):
723
+ return True
724
+
725
+ should_link = questionary.confirm(
726
+ f"An assistant named {assistant_name} already exists in Studio. "
727
+ f"Would you like to link your local project to this existing assistant?"
728
+ ).ask()
729
+
730
+ if not should_link:
731
+ rasa.shared.utils.cli.print_error_and_exit("Upload cancelled.")
732
+ return False
733
+
734
+ args.assistant_name = assistant_name
735
+ handle_link(args)
736
+ return False
rasa/studio/utils.py ADDED
@@ -0,0 +1,33 @@
1
+ import argparse
2
+ from pathlib import Path
3
+
4
+ import rasa.shared.utils.cli
5
+ from rasa.shared.constants import (
6
+ DEFAULT_CONFIG_PATH,
7
+ DEFAULT_DATA_PATH,
8
+ DEFAULT_ENDPOINTS_PATH,
9
+ )
10
+ from rasa.studio.constants import DOMAIN_FILENAME
11
+
12
+
13
+ def validate_argument_paths(args: argparse.Namespace) -> None:
14
+ """Validates the paths provided in the command line arguments.
15
+
16
+ Args:
17
+ args: The command line arguments containing paths to validate.
18
+ """
19
+
20
+ def validate_path(arg_name: str, default: str) -> None:
21
+ path_value = getattr(args, arg_name, None)
22
+ if path_value and path_value != default:
23
+ resolved_path = Path(path_value).resolve()
24
+ if not resolved_path.exists():
25
+ rasa.shared.utils.cli.print_error_and_exit(
26
+ f"{arg_name.capitalize()} file or directory "
27
+ f"'{path_value}' does not exist."
28
+ )
29
+
30
+ validate_path("domain", DOMAIN_FILENAME)
31
+ validate_path("config", DEFAULT_CONFIG_PATH)
32
+ validate_path("endpoints", DEFAULT_ENDPOINTS_PATH)
33
+ validate_path("data", DEFAULT_DATA_PATH)
rasa/telemetry.py CHANGED
@@ -23,7 +23,6 @@ import structlog
23
23
  from terminaltables import SingleTable
24
24
 
25
25
  import rasa
26
- import rasa.anonymization.utils
27
26
  import rasa.shared.utils.io
28
27
  import rasa.utils.io
29
28
  from rasa import model
@@ -34,6 +33,7 @@ from rasa.constants import (
34
33
  CONFIG_TELEMETRY_ID,
35
34
  )
36
35
  from rasa.engine.storage.local_model_storage import LocalModelStorage
36
+ from rasa.privacy.privacy_config import AnonymizationType, PrivacyConfig
37
37
  from rasa.shared.constants import (
38
38
  ASSISTANT_ID_KEY,
39
39
  CONFIG_LANGUAGE_KEY,
@@ -62,10 +62,10 @@ from rasa.utils import common as rasa_utils
62
62
 
63
63
  if typing.TYPE_CHECKING:
64
64
  from rasa.core.agent import Agent
65
+ from rasa.core.available_endpoints import AvailableEndpoints
65
66
  from rasa.core.brokers.broker import EventBroker
66
67
  from rasa.core.channels.channel import InputChannel
67
- from rasa.core.tracker_store import TrackerStore
68
- from rasa.core.utils import AvailableEndpoints
68
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
69
69
  from rasa.e2e_test.e2e_test_case import Fixture, Metadata, TestCase
70
70
  from rasa.shared.importers.importer import TrainingDataImporter
71
71
  from rasa.shared.nlu.training_data.training_data import TrainingData
@@ -149,6 +149,7 @@ TELEMETRY_ENTERPRISE_SEARCH_POLICY_TRAINING_COMPLETED_EVENT = (
149
149
  TELEMETRY_ENTERPRISE_SEARCH_POLICY_PREDICT_EVENT = "Enterprise Search Policy Predicted"
150
150
  TELEMETRY_VALIDATION_ERROR_LOG_EVENT = "Validation Error Logged"
151
151
  TELEMETRY_UPLOAD_TO_STUDIO_FAILED_EVENT = "Upload to Studio Failed"
152
+ TELEMETRY_PRIVACY_ENABLED_EVENT = "PII Management in CALM Enabled"
152
153
 
153
154
  # licensing events
154
155
  TELEMETRY_CONVERSATION_COUNT = "Conversation Count"
@@ -1129,6 +1130,7 @@ def _get_llm_command_generator_config(config: Dict[str, Any]) -> Optional[Dict]:
1129
1130
  LLMBasedCommandGenerator,
1130
1131
  LLMCommandGenerator,
1131
1132
  MultiStepLLMCommandGenerator,
1133
+ SearchReadyLLMCommandGenerator,
1132
1134
  SingleStepLLMCommandGenerator,
1133
1135
  )
1134
1136
  from rasa.dialogue_understanding.generator.constants import (
@@ -1156,6 +1158,7 @@ def _get_llm_command_generator_config(config: Dict[str, Any]) -> Optional[Dict]:
1156
1158
  SingleStepLLMCommandGenerator.__name__,
1157
1159
  MultiStepLLMCommandGenerator.__name__,
1158
1160
  CompactLLMCommandGenerator.__name__,
1161
+ SearchReadyLLMCommandGenerator.__name__,
1159
1162
  ]:
1160
1163
  return component
1161
1164
  return None
@@ -1167,6 +1170,7 @@ def _get_llm_command_generator_config(config: Dict[str, Any]) -> Optional[Dict]:
1167
1170
  SingleStepLLMCommandGenerator.__name__: SingleStepLLMCommandGenerator,
1168
1171
  MultiStepLLMCommandGenerator.__name__: MultiStepLLMCommandGenerator,
1169
1172
  CompactLLMCommandGenerator.__name__: CompactLLMCommandGenerator,
1173
+ SearchReadyLLMCommandGenerator.__name__: SearchReadyLLMCommandGenerator,
1170
1174
  }
1171
1175
  llm_config = component.get(LLM_CONFIG_KEY, {})
1172
1176
  # Config at this stage is not yet resolved, so read from `model_group`
@@ -1353,7 +1357,7 @@ def track_server_start(
1353
1357
  number_of_workers: number of used Sanic workers
1354
1358
  is_api_enabled: whether the rasa API server is enabled
1355
1359
  """
1356
- from rasa.core.utils import AvailableEndpoints
1360
+ from rasa.core.available_endpoints import AvailableEndpoints
1357
1361
 
1358
1362
  def project_fingerprint_and_assistant_id_from_model(
1359
1363
  _model_directory: Optional[Text],
@@ -1745,7 +1749,6 @@ def identify_endpoint_config_traits(
1745
1749
 
1746
1750
  traits = append_tracing_trait(traits, endpoints_file)
1747
1751
  traits = append_metrics_trait(traits, endpoints_file)
1748
- traits = append_anonymization_trait(traits, endpoints_file)
1749
1752
 
1750
1753
  _identify(traits, context)
1751
1754
 
@@ -1784,27 +1787,6 @@ def append_metrics_trait(
1784
1787
  return traits
1785
1788
 
1786
1789
 
1787
- def append_anonymization_trait(
1788
- traits: Dict[str, Any], endpoints_file: Optional[str]
1789
- ) -> Dict[str, Any]:
1790
- """Append the anonymization trait to the traits dictionary."""
1791
- from rasa.anonymization.anonymisation_rule_yaml_reader import (
1792
- KEY_ANONYMIZATION_RULES,
1793
- )
1794
-
1795
- anonymization_config = rasa.anonymization.utils.read_endpoint_config(
1796
- endpoints_file, KEY_ANONYMIZATION_RULES
1797
- )
1798
-
1799
- traits[KEY_ANONYMIZATION_RULES] = (
1800
- rasa.anonymization.utils.extract_anonymization_traits(
1801
- anonymization_config, KEY_ANONYMIZATION_RULES
1802
- )
1803
- )
1804
-
1805
- return traits
1806
-
1807
-
1808
1790
  @ensure_telemetry_enabled
1809
1791
  def track_enterprise_search_policy_train_started() -> None:
1810
1792
  """Track when a user starts training Enterprise Search policy."""
@@ -1821,6 +1803,7 @@ def track_enterprise_search_policy_train_completed(
1821
1803
  llm_model: Optional[str],
1822
1804
  llm_model_group_id: Optional[str],
1823
1805
  citation_enabled: Optional[bool],
1806
+ relevancy_check_enabled: Optional[bool],
1824
1807
  ) -> None:
1825
1808
  """Track when a user completes training Enterprise Search policy."""
1826
1809
  _track(
@@ -1834,6 +1817,7 @@ def track_enterprise_search_policy_train_completed(
1834
1817
  "llm_model": llm_model,
1835
1818
  "llm_model_group_id": llm_model_group_id,
1836
1819
  "citation_enabled": citation_enabled,
1820
+ "relevancy_check_enabled": relevancy_check_enabled,
1837
1821
  },
1838
1822
  )
1839
1823
 
@@ -1848,6 +1832,7 @@ def track_enterprise_search_policy_predict(
1848
1832
  llm_model: Optional[str],
1849
1833
  llm_model_group_id: Optional[str],
1850
1834
  citation_enabled: Optional[bool],
1835
+ relevancy_check_enabled: Optional[bool],
1851
1836
  ) -> None:
1852
1837
  """Track when a user predicts the next action using Enterprise Search policy."""
1853
1838
  _track(
@@ -1861,6 +1846,7 @@ def track_enterprise_search_policy_predict(
1861
1846
  "llm_model": llm_model,
1862
1847
  "llm_model_group_id": llm_model_group_id,
1863
1848
  "citation_enabled": citation_enabled,
1849
+ "relevancy_check_enabled": relevancy_check_enabled,
1864
1850
  },
1865
1851
  )
1866
1852
 
@@ -1946,3 +1932,74 @@ def track_upload_to_studio_failed(response_json: Dict[str, Any]) -> None:
1946
1932
  TELEMETRY_UPLOAD_TO_STUDIO_FAILED_EVENT,
1947
1933
  {"studio_response_json": response_json},
1948
1934
  )
1935
+
1936
+
1937
+ def _extract_privacy_enabled_event_properties(
1938
+ privacy_config: "PrivacyConfig",
1939
+ stream_pii: bool,
1940
+ ) -> Dict[str, Any]:
1941
+ """Extract properties when PII management is enabled."""
1942
+ number_of_total_rules = len(privacy_config.anonymization_rules)
1943
+ count_of_redact = sum(
1944
+ 1
1945
+ for rule in privacy_config.anonymization_rules.values()
1946
+ if rule.method_type == AnonymizationType.REDACT
1947
+ )
1948
+ count_of_mask = sum(
1949
+ 1
1950
+ for rule in privacy_config.anonymization_rules.values()
1951
+ if rule.method_type == AnonymizationType.MASK
1952
+ )
1953
+
1954
+ tracker_store_anonymization_enabled = (
1955
+ privacy_config.tracker_store_settings is not None
1956
+ and privacy_config.tracker_store_settings.anonymization_policy is not None
1957
+ )
1958
+ anonymization_cron_trigger = (
1959
+ privacy_config.tracker_store_settings.anonymization_policy.cron # type: ignore[union-attr]
1960
+ if tracker_store_anonymization_enabled
1961
+ else None
1962
+ )
1963
+
1964
+ tracker_store_deletion_enabled = (
1965
+ privacy_config.tracker_store_settings is not None
1966
+ and privacy_config.tracker_store_settings.deletion_policy is not None
1967
+ )
1968
+
1969
+ deletion_cron_trigger = (
1970
+ privacy_config.tracker_store_settings.deletion_policy.cron # type: ignore[union-attr]
1971
+ if tracker_store_deletion_enabled
1972
+ else None
1973
+ )
1974
+
1975
+ return {
1976
+ "num_total_rules": number_of_total_rules,
1977
+ "redact_count": count_of_redact,
1978
+ "mask_count": count_of_mask,
1979
+ "stream_pii": stream_pii,
1980
+ "tracker_store_anonymization_enabled": tracker_store_anonymization_enabled,
1981
+ "tracker_store_deletion_enabled": tracker_store_deletion_enabled,
1982
+ "anonymization_cron_trigger": str(anonymization_cron_trigger),
1983
+ "deletion_cron_trigger": str(deletion_cron_trigger),
1984
+ }
1985
+
1986
+
1987
+ def _extract_stream_pii(event_broker: Optional["EventBroker"]) -> bool:
1988
+ """Extract whether un-anonymized PII streaming is enabled for the event broker."""
1989
+ return (
1990
+ event_broker.stream_pii
1991
+ if event_broker is not None and hasattr(event_broker, "stream_pii")
1992
+ else False
1993
+ )
1994
+
1995
+
1996
+ @ensure_telemetry_enabled
1997
+ def track_privacy_enabled(
1998
+ privacy_config: "PrivacyConfig", event_broker: Optional["EventBroker"]
1999
+ ) -> None:
2000
+ """Track when PII management capability is enabled"""
2001
+ stream_pii = _extract_stream_pii(event_broker)
2002
+ privacy_properties = _extract_privacy_enabled_event_properties(
2003
+ privacy_config, stream_pii
2004
+ )
2005
+ _track(TELEMETRY_PRIVACY_ENABLED_EVENT, privacy_properties)