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
@@ -28,6 +28,14 @@ class NLUTrigger:
28
28
  """
29
29
  return self.intent == intent and confidence >= self.confidence_threshold
30
30
 
31
+ def __eq__(self, other: object) -> bool:
32
+ if isinstance(other, NLUTrigger):
33
+ return (
34
+ self.intent == other.intent
35
+ and self.confidence_threshold == other.confidence_threshold
36
+ )
37
+ return False
38
+
31
39
 
32
40
  @dataclass
33
41
  class NLUTriggers:
@@ -115,3 +123,8 @@ class NLUTriggers:
115
123
  trigger_condition.is_triggered(intent, confidence)
116
124
  for trigger_condition in self.trigger_conditions
117
125
  )
126
+
127
+ def __eq__(self, other: object) -> bool:
128
+ if isinstance(other, NLUTriggers):
129
+ return self.trigger_conditions == other.trigger_conditions
130
+ return False
@@ -31,15 +31,13 @@ class ActionFlowStep(FlowStep):
31
31
  **base.__dict__,
32
32
  )
33
33
 
34
- def as_json(self) -> Dict[Text, Any]:
34
+ def as_json(self) -> Dict[Text, Any]: # type: ignore[override]
35
35
  """Serialize the ActionFlowStep
36
36
 
37
37
  Returns:
38
38
  The ActionFlowStep object as serialized data.
39
39
  """
40
- data = super().as_json()
41
- data["action"] = self.action
42
- return data
40
+ return super().as_json(step_properties={"action": self.action})
43
41
 
44
42
  @property
45
43
  def default_id_postfix(self) -> str:
@@ -55,3 +53,8 @@ class ActionFlowStep(FlowStep):
55
53
  def custom_action(self) -> Optional[str]:
56
54
  """Return all the custom actions used in this step."""
57
55
  return self.action if not self.action.startswith(UTTER_PREFIX) else None
56
+
57
+ def __eq__(self, other: object) -> bool:
58
+ if isinstance(other, type(self)):
59
+ return self.action == other.action and super().__eq__(other)
60
+ return False
@@ -34,15 +34,13 @@ class CallFlowStep(FlowStep):
34
34
  **base.__dict__,
35
35
  )
36
36
 
37
- def as_json(self) -> Dict[Text, Any]:
37
+ def as_json(self) -> Dict[Text, Any]: # type: ignore[override]
38
38
  """Returns the flow step as a dictionary.
39
39
 
40
40
  Returns:
41
41
  The flow step as a dictionary.
42
42
  """
43
- dump = super().as_json()
44
- dump["call"] = self.call
45
- return dump
43
+ return super().as_json(step_properties={"call": self.call})
46
44
 
47
45
  def steps_in_tree(
48
46
  self, should_resolve_calls: bool = True
@@ -62,3 +60,12 @@ class CallFlowStep(FlowStep):
62
60
  def default_id_postfix(self) -> str:
63
61
  """Returns the default id postfix of the flow step."""
64
62
  return f"call_{self.call}"
63
+
64
+ def __eq__(self, other: object) -> bool:
65
+ if isinstance(other, type(self)):
66
+ return (
67
+ self.call == other.call
68
+ and self.called_flow_reference == other.called_flow_reference
69
+ and super().__eq__(other)
70
+ )
71
+ return False
@@ -1,11 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import Any, Dict, List, Set, Text
4
+ from typing import Any, Dict, List, Optional, Set, Text, Union
5
+
6
+ import structlog
5
7
 
6
8
  from rasa.shared.constants import ACTION_ASK_PREFIX, UTTER_ASK_PREFIX
7
9
  from rasa.shared.core.flows.flow_step import FlowStep
8
10
  from rasa.shared.core.slots import SlotRejection
11
+ from rasa.shared.exceptions import RasaException
12
+
13
+ DEFAULT_ASK_BEFORE_FILLING = False
14
+ DEFAULT_RESET_AFTER_FLOW_ENDS = True
15
+ DEFAULT_FORCE_SLOT_FILLING = False
16
+
17
+ logger = structlog.get_logger(__name__)
18
+
19
+ SilenceTimeoutInstructionType = Union[int, float, Dict[str, Any]]
9
20
 
10
21
 
11
22
  @dataclass
@@ -20,12 +31,14 @@ class CollectInformationFlowStep(FlowStep):
20
31
  """The action that the assistant uses to ask for the slot."""
21
32
  rejections: List[SlotRejection]
22
33
  """how the slot value is validated using predicate evaluation."""
23
- ask_before_filling: bool = False
34
+ ask_before_filling: bool = DEFAULT_ASK_BEFORE_FILLING
24
35
  """Whether to always ask the question even if the slot is already filled."""
25
- reset_after_flow_ends: bool = True
36
+ reset_after_flow_ends: bool = DEFAULT_RESET_AFTER_FLOW_ENDS
26
37
  """Whether to reset the slot value at the end of the flow."""
27
38
  force_slot_filling: bool = False
28
39
  """Whether to keep only the SetSlot command for the collected slot."""
40
+ silence_timeout: Optional[float] = None
41
+ """The silence timeout for the collect information step."""
29
42
 
30
43
  @classmethod
31
44
  def from_json(
@@ -40,10 +53,15 @@ class CollectInformationFlowStep(FlowStep):
40
53
  Returns:
41
54
  A CollectInformationFlowStep object
42
55
  """
56
+
57
+ silence_timeout = cls._deserialise_silence_timeout(
58
+ data.get("silence_timeout", None)
59
+ )
60
+
43
61
  base = super().from_json(flow_id, data)
44
62
  return CollectInformationFlowStep(
45
63
  collect=data["collect"],
46
- utter=data.get("utter", f"{UTTER_ASK_PREFIX}{data['collect']}"),
64
+ utter=data.get("utter", cls._default_utter(data["collect"])),
47
65
  # as of now it is not possible to define a different name for the
48
66
  # action, always use the default name 'action_ask_<slot_name>'
49
67
  collect_action=f"{ACTION_ASK_PREFIX}{data['collect']}",
@@ -54,10 +72,40 @@ class CollectInformationFlowStep(FlowStep):
54
72
  for rejection in data.get("rejections", [])
55
73
  ],
56
74
  force_slot_filling=data.get("force_slot_filling", False),
75
+ silence_timeout=silence_timeout,
57
76
  **base.__dict__,
58
77
  )
59
78
 
60
- def as_json(self) -> Dict[str, Any]:
79
+ @staticmethod
80
+ def _deserialise_silence_timeout(
81
+ silence_timeout_json: Optional[SilenceTimeoutInstructionType],
82
+ ) -> Optional[float]:
83
+ """Deserialize silence timeout from JSON."""
84
+ if not silence_timeout_json:
85
+ return None
86
+
87
+ if not isinstance(silence_timeout_json, (int, float)):
88
+ raise RasaException(
89
+ f"Invalid silence timeout value: {silence_timeout_json}. "
90
+ "If defined at collect step, silence timeout must be a number."
91
+ )
92
+
93
+ silence_timeout = silence_timeout_json
94
+
95
+ if silence_timeout and silence_timeout < 0:
96
+ raise RasaException(
97
+ f"Invalid silence timeout value: {silence_timeout}. "
98
+ "Silence timeout must be a non-negative number."
99
+ )
100
+ return silence_timeout
101
+
102
+ @staticmethod
103
+ def _default_utter(collect: str) -> str:
104
+ return f"{UTTER_ASK_PREFIX}{collect}"
105
+
106
+ def as_json(
107
+ self, step_properties: Optional[Dict[Text, Any]] = None
108
+ ) -> Dict[str, Any]:
61
109
  """Serialize the CollectInformationFlowStep object.
62
110
 
63
111
  Returns:
@@ -70,8 +118,10 @@ class CollectInformationFlowStep(FlowStep):
70
118
  data["reset_after_flow_ends"] = self.reset_after_flow_ends
71
119
  data["rejections"] = [rejection.as_dict() for rejection in self.rejections]
72
120
  data["force_slot_filling"] = self.force_slot_filling
121
+ if self.silence_timeout:
122
+ data["silence_timeout"] = self.silence_timeout
73
123
 
74
- return data
124
+ return super().as_json(step_properties=data)
75
125
 
76
126
  @property
77
127
  def default_id_postfix(self) -> str:
@@ -82,3 +132,18 @@ class CollectInformationFlowStep(FlowStep):
82
132
  def utterances(self) -> Set[str]:
83
133
  """Return all the utterances used in this step."""
84
134
  return {self.utter} | {r.utter for r in self.rejections}
135
+
136
+ def __eq__(self, other: object) -> bool:
137
+ if isinstance(other, type(self)):
138
+ return (
139
+ self.collect == other.collect
140
+ and self.utter == other.utter
141
+ and self.collect_action == other.collect_action
142
+ and self.rejections == other.rejections
143
+ and self.ask_before_filling == other.ask_before_filling
144
+ and self.reset_after_flow_ends == other.reset_after_flow_ends
145
+ and self.force_slot_filling == other.force_slot_filling
146
+ and self.silence_timeout == other.silence_timeout
147
+ and super().__eq__(other)
148
+ )
149
+ return False
@@ -28,7 +28,7 @@ class InternalFlowStep(FlowStep):
28
28
  "or de-serialized."
29
29
  )
30
30
 
31
- def as_json(self) -> Dict[Text, Any]:
31
+ def as_json(self) -> Dict[Text, Any]: # type: ignore[override]
32
32
  """Serialize the InternalFlowStep object
33
33
 
34
34
  Returns:
@@ -43,3 +43,8 @@ class InternalFlowStep(FlowStep):
43
43
  def default_id_postfix(self) -> str:
44
44
  """Returns the default id postfix of the flow step."""
45
45
  raise ValueError("Internal flow steps do not need a default id")
46
+
47
+ def __eq__(self, other: object) -> bool:
48
+ if isinstance(other, type(self)):
49
+ return super().__eq__(other)
50
+ return False
@@ -42,17 +42,20 @@ class LinkFlowStep(FlowStep):
42
42
  **base.__dict__,
43
43
  )
44
44
 
45
- def as_json(self) -> Dict[Text, Any]:
45
+ def as_json(self) -> Dict[Text, Any]: # type: ignore[override]
46
46
  """Serialize the LinkFlowStep object
47
47
 
48
48
  Returns:
49
49
  the LinkFlowStep object as serialized data.
50
50
  """
51
- data = super().as_json()
52
- data["link"] = self.link
53
- return data
51
+ return super().as_json(step_properties={"link": self.link})
54
52
 
55
53
  @property
56
54
  def default_id_postfix(self) -> str:
57
55
  """Returns the default id postfix of the flow step."""
58
56
  return f"link_{self.link}"
57
+
58
+ def __eq__(self, other: object) -> bool:
59
+ if isinstance(other, type(self)):
60
+ return self.link == other.link and super().__eq__(other)
61
+ return False
@@ -34,17 +34,20 @@ class NoOperationFlowStep(FlowStep):
34
34
  **base.__dict__,
35
35
  )
36
36
 
37
- def as_json(self) -> Dict[Text, Any]:
37
+ def as_json(self) -> Dict[Text, Any]: # type: ignore[override]
38
38
  """Serialize the NoOperationFlowStep object
39
39
 
40
40
  Returns:
41
41
  the NoOperationFlowStep object as serialized data.
42
42
  """
43
- data = super().as_json()
44
- data["noop"] = self.noop
45
- return data
43
+ return super().as_json(step_properties={"noop": self.noop})
46
44
 
47
45
  @property
48
46
  def default_id_postfix(self) -> str:
49
47
  """Returns the default id postfix of the flow step."""
50
48
  return "noop"
49
+
50
+ def __eq__(self, other: object) -> bool:
51
+ if isinstance(other, type(self)):
52
+ return self.noop == other.noop and super().__eq__(other)
53
+ return False
@@ -35,17 +35,21 @@ class SetSlotsFlowStep(FlowStep):
35
35
  **base.__dict__,
36
36
  )
37
37
 
38
- def as_json(self) -> Dict[Text, Any]:
38
+ def as_json(self) -> Dict[Text, Any]: # type: ignore[override]
39
39
  """Serialize the SetSlotsFlowStep object
40
40
 
41
41
  Returns:
42
42
  the SetSlotsFlowStep object as serialized data
43
43
  """
44
- data = super().as_json()
45
- data["set_slots"] = [{slot["key"]: slot["value"]} for slot in self.slots]
46
- return data
44
+ set_slots = [{slot["key"]: slot["value"]} for slot in self.slots]
45
+ return super().as_json(step_properties={"set_slots": set_slots})
47
46
 
48
47
  @property
49
48
  def default_id_postfix(self) -> str:
50
49
  """Returns the default id postfix of the flow step."""
51
50
  return "set_slots"
51
+
52
+ def __eq__(self, other: object) -> bool:
53
+ if isinstance(other, type(self)):
54
+ return self.slots == other.slots and super().__eq__(other)
55
+ return False
@@ -8,6 +8,7 @@ from typing import List, Optional, Set, Text
8
8
 
9
9
  from rasa.shared.constants import (
10
10
  RASA_DEFAULT_FLOW_PATTERN_PREFIX,
11
+ RASA_PATTERN_CHITCHAT,
11
12
  RASA_PATTERN_HUMAN_HANDOFF,
12
13
  RASA_PATTERN_INTERNAL_ERROR,
13
14
  )
@@ -186,8 +187,10 @@ class ReferenceToPatternException(RasaException):
186
187
  return message + "Patterns can not be used as a target for a call step."
187
188
  else:
188
189
  return message + (
189
- "All patterns, except for 'pattern_human_handoff', can "
190
- "not be used as a target for a link step."
190
+ "Patterns cannot be used as a target in link steps, except for "
191
+ "'pattern_human_handoff', which may be linked from both user-defined "
192
+ "flows and other patterns. 'pattern_chitchat' may only be linked "
193
+ "from other patterns."
191
194
  )
192
195
 
193
196
 
@@ -578,11 +581,18 @@ def validate_linked_flows_exists(flows: "FlowsList") -> None:
578
581
  continue
579
582
 
580
583
  # It might be that the flows do not contain the default rasa patterns, but
581
- # only the user flows. Manually check for `pattern_human_handoff` as this
582
- # pattern can be linked to and it is part of the default patterns of rasa.
584
+ # only the user flows. Manually check for `pattern_human_handoff` and
585
+ # 'pattern_chitchat' as these patterns can be linked to and are part of the
586
+ # default patterns of rasa.
583
587
  if (
584
588
  flows.flow_by_id(step.link) is None
589
+ # Allow linking to human-handoff from both patterns
590
+ # and user-defined flows
585
591
  and step.link != RASA_PATTERN_HUMAN_HANDOFF
592
+ # Allow linking to 'pattern_chitchat' only from other patterns
593
+ and not (
594
+ flow.is_rasa_default_flow and step.link == RASA_PATTERN_CHITCHAT
595
+ )
586
596
  ):
587
597
  raise UnresolvedFlowException(step.link, flow.id, step.id)
588
598
 
@@ -597,7 +607,13 @@ def validate_patterns_are_not_called_or_linked(flows: "FlowsList") -> None:
597
607
  if (
598
608
  isinstance(step, LinkFlowStep)
599
609
  and step.link.startswith(RASA_DEFAULT_FLOW_PATTERN_PREFIX)
610
+ # Allow linking to human-handoff from both patterns
611
+ # and user-defined flows
600
612
  and step.link != RASA_PATTERN_HUMAN_HANDOFF
613
+ # Allow linking to 'pattern_chitchat' only from other patterns
614
+ and not (
615
+ flow.is_rasa_default_flow and step.link == RASA_PATTERN_CHITCHAT
616
+ )
601
617
  ):
602
618
  raise ReferenceToPatternException(
603
619
  step.link, flow.id, step.id, call_step=False
@@ -617,7 +633,8 @@ def validate_patterns_are_not_calling_or_linking_other_flows(
617
633
  """Validates that patterns do not contain call or link steps.
618
634
 
619
635
  Link steps to user flows are allowed for all patterns but 'pattern_internal_error'.
620
- Link steps to other patterns, except for 'pattern_human_handoff', are forbidden.
636
+ Link steps to other patterns, except for 'pattern_human_handoff' and
637
+ 'pattern_chitchat' are forbidden.
621
638
  """
622
639
  for flow in flows.underlying_flows:
623
640
  if not flow.is_rasa_default_flow:
@@ -627,6 +644,9 @@ def validate_patterns_are_not_calling_or_linking_other_flows(
627
644
  if step.link == RASA_PATTERN_HUMAN_HANDOFF:
628
645
  # links to 'pattern_human_handoff' are allowed
629
646
  continue
647
+ if step.link == RASA_PATTERN_CHITCHAT:
648
+ # links to 'pattern_chitchat' are allowed
649
+ continue
630
650
  if step.link.startswith(RASA_DEFAULT_FLOW_PATTERN_PREFIX):
631
651
  # all other patterns are allowed to link to user flows, but not
632
652
  # to other patterns
@@ -8,8 +8,15 @@ from ruamel import yaml as yaml
8
8
  import rasa.shared
9
9
  import rasa.shared.data
10
10
  import rasa.shared.utils.io
11
- from rasa.shared.core.flows.flow import Flow
11
+ from rasa.shared.core.flows.flow import DEFAULT_RUN_PATTERN_COMPLETED, Flow
12
+ from rasa.shared.core.flows.flow_step import FlowStep
12
13
  from rasa.shared.core.flows.flows_list import FlowsList
14
+ from rasa.shared.core.flows.steps import CollectInformationFlowStep
15
+ from rasa.shared.core.flows.steps.collect import (
16
+ DEFAULT_ASK_BEFORE_FILLING,
17
+ DEFAULT_FORCE_SLOT_FILLING,
18
+ DEFAULT_RESET_AFTER_FLOW_ENDS,
19
+ )
13
20
  from rasa.shared.exceptions import RasaException, YamlException
14
21
  from rasa.shared.utils.yaml import (
15
22
  dump_obj_as_yaml_to_string,
@@ -242,31 +249,43 @@ class YamlFlowsWriter:
242
249
  """Class that writes flows information in YAML format."""
243
250
 
244
251
  @staticmethod
245
- def dumps(flows: List[Flow]) -> Text:
252
+ def dumps(
253
+ flows: List[Flow],
254
+ should_clean_json: bool = False,
255
+ ) -> Text:
246
256
  """Dump `Flow`s to YAML.
247
257
 
248
258
  Args:
249
259
  flows: The `Flow`s to dump.
260
+ should_clean_json: Flag whether to clean the flow JSON.
250
261
 
251
262
  Returns:
252
263
  The dumped YAML.
253
264
  """
254
265
  dump = {}
255
266
  for flow in flows:
256
- dumped_flow = flow.as_json()
267
+ dumped_flow = get_flow_as_json(flow, should_clean_json)
257
268
  del dumped_flow["id"]
258
269
  dump[flow.id] = dumped_flow
259
270
  return dump_obj_as_yaml_to_string({KEY_FLOWS: dump})
260
271
 
261
272
  @staticmethod
262
- def dump(flows: List[Flow], filename: Union[Text, Path]) -> None:
273
+ def dump(
274
+ flows: List[Flow],
275
+ filename: Union[Text, Path],
276
+ should_clean_json: bool = False,
277
+ ) -> None:
263
278
  """Dump `Flow`s to YAML file.
264
279
 
265
280
  Args:
266
281
  flows: The `Flow`s to dump.
267
282
  filename: The path to the file to write to.
283
+ should_clean_json: Flag whether to clean the flow JSON.
268
284
  """
269
- rasa.shared.utils.io.write_text_file(YamlFlowsWriter.dumps(flows), filename)
285
+ rasa.shared.utils.io.write_text_file(
286
+ YamlFlowsWriter.dumps(flows, should_clean_json),
287
+ filename,
288
+ )
270
289
 
271
290
 
272
291
  def is_flows_file(file_path: Union[Text, Path]) -> bool:
@@ -403,3 +422,85 @@ def process_yaml_content(yaml_content: Dict[str, Any]) -> Dict[str, Any]:
403
422
  )
404
423
 
405
424
  return yaml_content
425
+
426
+
427
+ def get_flow_as_json(flow: Flow, should_clean_json: bool = False) -> Dict[str, Any]:
428
+ """
429
+ Clean the Flow JSON by removing default values and empty fields.
430
+
431
+ Args:
432
+ flow: The Flow object to clean.
433
+ should_clean_json: Flag indicating whether to clean the JSON.
434
+
435
+ Returns:
436
+ The cleaned Flow JSON as a dictionary.
437
+ """
438
+ step_id_to_default_id = {}
439
+ flow_data = flow.as_json()
440
+ if not should_clean_json:
441
+ return flow_data
442
+
443
+ def gather_step_ids(step: FlowStep) -> None:
444
+ """Create a map of step IDs to their default IDs."""
445
+ step_id_to_default_id[step.id] = step.default_id
446
+ for link in step.next.links:
447
+ for child in link.child_steps():
448
+ gather_step_ids(child)
449
+
450
+ def clean_flow_data(data: Dict[str, Any]) -> None:
451
+ """Remove or omit flow-level fields if they match defaults."""
452
+ for top_level_step in flow.step_sequence.steps:
453
+ gather_step_ids(top_level_step)
454
+
455
+ if data.get("run_pattern_completed") == DEFAULT_RUN_PATTERN_COMPLETED:
456
+ data.pop("run_pattern_completed", None)
457
+
458
+ if not data.get("persisted_slots"):
459
+ data.pop("persisted_slots", None)
460
+
461
+ _remove_keys_recursively(data, ["metadata"])
462
+
463
+ data.pop("file_path", None)
464
+
465
+ steps = data.get("steps", [])
466
+ for i, current_step in enumerate(steps):
467
+ # Look ahead to the next step if we should remove the 'next' field
468
+ next_step_data = steps[i + 1] if i + 1 < len(steps) else None
469
+ clean_step(current_step, next_step_data)
470
+
471
+ def clean_step(current_step: Dict[str, Any], next_step: Dict[str, Any]) -> None:
472
+ """Remove default fields from a step."""
473
+ # Remove 'next' if it exactly matches the next step's default ID
474
+ if next_step:
475
+ next_id = next_step.get("id")
476
+ default_id = step_id_to_default_id.get(next_id)
477
+ if next_id and current_step.get("next") == default_id:
478
+ current_step.pop("next", None)
479
+
480
+ # Remove 'id' if it equals its own default
481
+ step_id = current_step.get("id")
482
+ if step_id and step_id == step_id_to_default_id.get(step_id):
483
+ current_step.pop("id", None)
484
+
485
+ if "collect" in current_step:
486
+ clean_collect_step(current_step)
487
+
488
+ def clean_collect_step(step_data: Dict[str, Any]) -> None:
489
+ """Remove default fields from a collect step."""
490
+ slot_name = step_data["collect"]
491
+ default_utter = CollectInformationFlowStep._default_utter(slot_name)
492
+
493
+ if step_data.get("utter") == default_utter:
494
+ step_data.pop("utter", None)
495
+ if step_data.get("ask_before_filling") is DEFAULT_ASK_BEFORE_FILLING:
496
+ step_data.pop("ask_before_filling", None)
497
+ if step_data.get("reset_after_flow_ends") is DEFAULT_RESET_AFTER_FLOW_ENDS:
498
+ step_data.pop("reset_after_flow_ends", None)
499
+ if step_data.get("force_slot_filling") is DEFAULT_FORCE_SLOT_FILLING:
500
+ step_data.pop("force_slot_filling", None)
501
+ if not step_data.get("rejections"):
502
+ step_data.pop("rejections", None)
503
+
504
+ clean_flow_data(flow_data)
505
+
506
+ return flow_data
rasa/shared/core/slots.py CHANGED
@@ -311,6 +311,34 @@ class Slot(ABC):
311
311
  """Indicates if the slot requires validation."""
312
312
  return True if self.validation else False
313
313
 
314
+ def to_dict(
315
+ self,
316
+ *,
317
+ include_private: bool = False,
318
+ ) -> Dict[str, Any]:
319
+ """Return a dictionary with attributes of this slot instance.
320
+
321
+ Args:
322
+ include_private: If `True`, private attributes are included.
323
+
324
+ Returns:
325
+ A plain `dict` that can be JSON-serialised.
326
+ """
327
+ result: Dict[str, Any] = {}
328
+
329
+ for attr, value in vars(self).items():
330
+ if not include_private and attr.startswith("_"):
331
+ continue
332
+
333
+ if attr == "mappings":
334
+ result[attr] = [mapping.as_dict() for mapping in value]
335
+ continue
336
+
337
+ result[attr] = value
338
+
339
+ result.setdefault("type", self.type_name)
340
+ return result
341
+
314
342
 
315
343
  class FloatSlot(Slot):
316
344
  """A slot storing a float value."""
@@ -787,7 +815,7 @@ class StrictCategoricalSlot(CategoricalSlot):
787
815
  def coerce_value(self, value: Any) -> Any:
788
816
  """Coerce the value to one of the allowed ones or raise an error if invalid."""
789
817
  if value is None:
790
- return self.initial_value
818
+ return value
791
819
 
792
820
  for allowed_value in self.values:
793
821
  # Allowed values are always stored as strings, so we can use casefold().
@@ -1123,16 +1123,10 @@ class DialogueStateTracker:
1123
1123
  f"Please update the slot configuration accordingly."
1124
1124
  )
1125
1125
 
1126
- supported_languages = []
1127
- for language_code in language_slot.values:
1128
- is_default = language_code == language_slot.initial_value
1129
- language = Language.from_language_code(
1130
- language_code=language_code,
1131
- is_default=is_default,
1132
- )
1133
- supported_languages.append(language)
1134
-
1135
- return supported_languages
1126
+ return [
1127
+ Language.from_language_code(language_code)
1128
+ for language_code in language_slot.values
1129
+ ]
1136
1130
 
1137
1131
  @property
1138
1132
  def current_language(self) -> Optional[Language]:
@@ -1176,6 +1170,23 @@ class DialogueStateTracker:
1176
1170
  "Example: `language: en`."
1177
1171
  )
1178
1172
 
1173
+ def get_last_turn_events(self) -> List[Event]:
1174
+ """Get all events of the last conversation turn."""
1175
+ last_user_message = self.get_last_event_for(
1176
+ UserUttered, event_verbosity=EventVerbosity.ALL
1177
+ )
1178
+ if not last_user_message:
1179
+ return []
1180
+
1181
+ last_turn_events = []
1182
+ for event in reversed(self.events):
1183
+ if event.timestamp >= last_user_message.timestamp:
1184
+ last_turn_events.append(event)
1185
+ else:
1186
+ break
1187
+
1188
+ return list(reversed(last_turn_events))
1189
+
1179
1190
 
1180
1191
  class TrackerEventDiffEngine:
1181
1192
  """Computes event difference of two trackers."""
@@ -1,4 +1,3 @@
1
- import copy
2
1
  import functools
3
2
  import json
4
3
  import logging
@@ -648,9 +647,7 @@ class YAMLStoryReader(StoryReader):
648
647
  # message text did start with the special prefix -- however, a user might
649
648
  # just have decided to start their text this way.
650
649
  if not match:
651
- structlogger.warning(
652
- "message.parsing.failed", user_text=copy.deepcopy(user_text)
653
- )
650
+ structlogger.warning("message.parsing.failed")
654
651
  return message
655
652
 
656
653
  # Extract attributes from the match - and validate it via the domain.
@@ -18,6 +18,7 @@ import importlib_resources
18
18
 
19
19
  import rasa.shared.constants
20
20
  import rasa.shared.core.constants
21
+ import rasa.shared.data
21
22
  import rasa.shared.utils.common
22
23
  import rasa.shared.utils.io
23
24
  from rasa.shared.constants import CONFIG_ADDITIONAL_LANGUAGES_KEY, CONFIG_LANGUAGE_KEY
@@ -279,6 +280,13 @@ class TrainingDataImporter(ABC):
279
280
  """
280
281
  raise NotImplementedError
281
282
 
283
+ @staticmethod
284
+ def get_domain_files(
285
+ data_paths: Optional[Union[List[Text], Text]] = None,
286
+ ) -> List[Text]:
287
+ """Returns the domain file path (see parent class for full docstring)."""
288
+ return rasa.shared.data.get_data_files(data_paths, Domain.is_domain_file)
289
+
282
290
 
283
291
  class NluDataImporter(TrainingDataImporter):
284
292
  """Importer that skips any Core-related file reading."""