rasa-pro 3.11.5__py3-none-any.whl → 3.12.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 (559) hide show
  1. README.md +10 -13
  2. rasa/__main__.py +7 -7
  3. rasa/anonymization/anonymisation_rule_yaml_reader.py +1 -1
  4. rasa/anonymization/anonymization_pipeline.py +3 -3
  5. rasa/anonymization/anonymization_rule_executor.py +17 -11
  6. rasa/anonymization/anonymization_rule_orchestrator.py +2 -3
  7. rasa/cli/arguments/data.py +2 -2
  8. rasa/cli/arguments/default_arguments.py +1 -1
  9. rasa/cli/arguments/evaluate.py +2 -1
  10. rasa/cli/arguments/interactive.py +1 -1
  11. rasa/cli/arguments/run.py +1 -1
  12. rasa/cli/arguments/test.py +7 -5
  13. rasa/cli/arguments/train.py +3 -3
  14. rasa/cli/arguments/visualize.py +2 -2
  15. rasa/cli/arguments/x.py +1 -0
  16. rasa/cli/data.py +20 -3
  17. rasa/cli/dialogue_understanding_test.py +386 -0
  18. rasa/cli/evaluate.py +1 -1
  19. rasa/cli/export.py +6 -6
  20. rasa/cli/inspect.py +20 -1
  21. rasa/cli/interactive.py +4 -5
  22. rasa/cli/llm_fine_tuning.py +51 -16
  23. rasa/cli/markers.py +1 -2
  24. rasa/cli/project_templates/calm/actions/add_contact.py +1 -1
  25. rasa/cli/project_templates/calm/config.yml +2 -2
  26. rasa/cli/project_templates/calm/domain/list_contacts.yml +1 -2
  27. rasa/cli/project_templates/calm/domain/remove_contact.yml +1 -2
  28. rasa/cli/project_templates/calm/domain/shared.yml +1 -4
  29. rasa/cli/project_templates/calm/endpoints.yml +2 -2
  30. rasa/cli/project_templates/tutorial/actions/actions.py +3 -2
  31. rasa/cli/shell.py +5 -6
  32. rasa/cli/studio/download.py +1 -2
  33. rasa/cli/studio/studio.py +2 -3
  34. rasa/cli/studio/train.py +0 -1
  35. rasa/cli/telemetry.py +2 -2
  36. rasa/cli/test.py +11 -11
  37. rasa/cli/train.py +3 -0
  38. rasa/cli/utils.py +25 -5
  39. rasa/constants.py +0 -1
  40. rasa/core/__init__.py +0 -1
  41. rasa/core/actions/action.py +135 -208
  42. rasa/core/actions/action_handle_digressions.py +164 -0
  43. rasa/core/actions/action_hangup.py +1 -1
  44. rasa/core/actions/action_repeat_bot_messages.py +2 -2
  45. rasa/core/actions/action_run_slot_rejections.py +18 -6
  46. rasa/core/actions/action_trigger_chitchat.py +1 -1
  47. rasa/core/actions/action_trigger_flow.py +5 -5
  48. rasa/core/actions/action_trigger_search.py +1 -1
  49. rasa/core/actions/custom_action_executor.py +1 -1
  50. rasa/core/actions/direct_custom_actions_executor.py +1 -0
  51. rasa/core/actions/forms.py +22 -15
  52. rasa/core/actions/http_custom_action_executor.py +8 -1
  53. rasa/core/actions/loops.py +3 -3
  54. rasa/core/actions/two_stage_fallback.py +13 -13
  55. rasa/core/auth_retry_tracker_store.py +1 -2
  56. rasa/core/brokers/broker.py +2 -1
  57. rasa/core/brokers/file.py +1 -1
  58. rasa/core/brokers/kafka.py +8 -8
  59. rasa/core/brokers/pika.py +8 -9
  60. rasa/core/brokers/sql.py +4 -3
  61. rasa/core/channels/__init__.py +7 -0
  62. rasa/core/channels/botframework.py +2 -2
  63. rasa/core/channels/callback.py +4 -4
  64. rasa/core/channels/channel.py +11 -11
  65. rasa/core/channels/console.py +0 -1
  66. rasa/core/channels/development_inspector.py +80 -24
  67. rasa/core/channels/facebook.py +5 -5
  68. rasa/core/channels/hangouts.py +7 -8
  69. rasa/core/channels/inspector/dist/assets/{arc-f0f8bd46.js → arc-9f1365dc.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7162c77d.js → blockDiagram-38ab4fdb-e0f81b12.js} +1 -1
  71. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-b1d0d098.js → c4Diagram-3d4e48cf-9deaee1c.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/channel-44956714.js +1 -0
  73. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-807a1b27.js → classDiagram-70f12bd4-20450a96.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-5238dcdb.js → classDiagram-v2-f2320105-749d2abf.js} +1 -1
  75. rasa/core/channels/inspector/dist/assets/clone-a9475142.js +1 -0
  76. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-75dfaa67.js → createText-2e5e7dd3-bef0b38c.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-df20501d.js → edges-e0da2a9e-943801a7.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-13cf4797.js → erDiagram-9861fffd-d523a948.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-a4991264.js → flowDb-956e92f1-54e4cf19.js} +1 -1
  80. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-ccecf773.js → flowDiagram-66a62f08-48bfbbe8.js} +1 -1
  81. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-43fa749a.js +1 -0
  82. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-b5801783.js → flowchart-elk-definition-4a651766-17c30827.js} +1 -1
  83. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-161e079a.js → ganttDiagram-c361ad54-43086f2d.js} +1 -1
  84. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-f38e86a4.js → gitGraphDiagram-72cf32ee-5c8b693e.js} +1 -1
  85. rasa/core/channels/inspector/dist/assets/{graph-be6ef5d8.js → graph-41a90d26.js} +1 -1
  86. rasa/core/channels/inspector/dist/assets/{index-3862675e-d9ce8994.js → index-3862675e-b43eeae9.js} +1 -1
  87. rasa/core/channels/inspector/dist/assets/{index-7794b245.js → index-e8affe45.js} +155 -155
  88. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-5000a3dc.js → infoDiagram-f8f76790-0b20676b.js} +1 -1
  89. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-8ef0a17a.js → journeyDiagram-49397b02-39bce7b5.js} +1 -1
  90. rasa/core/channels/inspector/dist/assets/{layout-d649bc98.js → layout-dc8eeea4.js} +1 -1
  91. rasa/core/channels/inspector/dist/assets/{line-95add810.js → line-c4d2e756.js} +1 -1
  92. rasa/core/channels/inspector/dist/assets/{linear-f6025094.js → linear-86f6f2d9.js} +1 -1
  93. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-2e8531c4.js → mindmap-definition-fc14e90a-4216f771.js} +1 -1
  94. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-918adfdb.js → pieDiagram-8a3498a8-1a0cfa96.js} +1 -1
  95. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-cbd01797.js → quadrantDiagram-120e2f19-f91e67cf.js} +1 -1
  96. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6a8b877b.js → requirementDiagram-deff3bca-d4046bed.js} +1 -1
  97. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-c377c3fe.js → sankeyDiagram-04a897e0-2cf6d1d7.js} +1 -1
  98. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-ab9e9b7f.js → sequenceDiagram-704730f1-751ac4f5.js} +1 -1
  99. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-5e6ae67d.js → stateDiagram-587899a1-f734f4d4.js} +1 -1
  100. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-40643476.js → stateDiagram-v2-d93cdb3a-91c65710.js} +1 -1
  101. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-afb8d108.js → styles-6aaf32cf-e0cff7be.js} +1 -1
  102. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-7edc9423.js → styles-9a916d00-c8029e5d.js} +1 -1
  103. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-c1d8f7e9.js → styles-c10674c1-114f312a.js} +1 -1
  104. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f494b2ef.js → svgDrawCommon-08f97a94-b7b9dc00.js} +1 -1
  105. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-11c7cdd0.js → timeline-definition-85554ec2-9536d189.js} +1 -1
  106. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-3f191ec1.js → xychartDiagram-e933f94c-bf3b0f36.js} +1 -1
  107. rasa/core/channels/inspector/dist/index.html +1 -1
  108. rasa/core/channels/inspector/package.json +1 -0
  109. rasa/core/channels/inspector/src/App.tsx +15 -2
  110. rasa/core/channels/inspector/src/components/RasaLogo.tsx +31 -0
  111. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +68 -0
  112. rasa/core/channels/inspector/src/components/Welcome.tsx +19 -13
  113. rasa/core/channels/inspector/yarn.lock +5 -0
  114. rasa/core/channels/mattermost.py +4 -4
  115. rasa/core/channels/rasa_chat.py +4 -4
  116. rasa/core/channels/rest.py +11 -12
  117. rasa/core/channels/rocketchat.py +4 -3
  118. rasa/core/channels/slack.py +6 -5
  119. rasa/core/channels/socketio.py +8 -28
  120. rasa/core/channels/studio_chat.py +212 -0
  121. rasa/core/channels/telegram.py +105 -55
  122. rasa/core/channels/twilio.py +3 -3
  123. rasa/core/channels/vier_cvg.py +2 -2
  124. rasa/core/channels/voice_ready/audiocodes.py +9 -9
  125. rasa/core/channels/voice_ready/jambonz.py +5 -5
  126. rasa/core/channels/voice_ready/jambonz_protocol.py +3 -4
  127. rasa/core/channels/voice_ready/twilio_voice.py +9 -8
  128. rasa/core/channels/voice_ready/utils.py +2 -2
  129. rasa/core/channels/voice_stream/asr/asr_engine.py +12 -6
  130. rasa/core/channels/voice_stream/asr/asr_event.py +5 -0
  131. rasa/core/channels/voice_stream/asr/azure.py +16 -3
  132. rasa/core/channels/voice_stream/asr/deepgram.py +76 -19
  133. rasa/core/channels/voice_stream/audiocodes.py +292 -0
  134. rasa/core/channels/voice_stream/browser_audio.py +14 -7
  135. rasa/core/channels/voice_stream/call_state.py +6 -2
  136. rasa/core/channels/voice_stream/genesys.py +320 -0
  137. rasa/core/channels/voice_stream/tts/azure.py +13 -5
  138. rasa/core/channels/voice_stream/tts/cartesia.py +34 -14
  139. rasa/core/channels/voice_stream/tts/tts_cache.py +3 -2
  140. rasa/core/channels/voice_stream/tts/tts_engine.py +1 -1
  141. rasa/core/channels/voice_stream/twilio_media_streams.py +12 -8
  142. rasa/core/channels/voice_stream/util.py +1 -1
  143. rasa/core/channels/voice_stream/voice_channel.py +100 -56
  144. rasa/core/channels/webexteams.py +3 -4
  145. rasa/core/constants.py +2 -0
  146. rasa/core/evaluation/marker.py +7 -6
  147. rasa/core/evaluation/marker_base.py +15 -16
  148. rasa/core/evaluation/marker_stats.py +3 -4
  149. rasa/core/evaluation/marker_tracker_loader.py +5 -4
  150. rasa/core/exporter.py +4 -4
  151. rasa/core/featurizers/precomputation.py +8 -8
  152. rasa/core/featurizers/single_state_featurizer.py +7 -7
  153. rasa/core/featurizers/tracker_featurizers.py +13 -13
  154. rasa/core/http_interpreter.py +3 -4
  155. rasa/core/information_retrieval/__init__.py +1 -1
  156. rasa/core/information_retrieval/faiss.py +4 -4
  157. rasa/core/information_retrieval/information_retrieval.py +2 -2
  158. rasa/core/information_retrieval/milvus.py +3 -3
  159. rasa/core/information_retrieval/qdrant.py +3 -3
  160. rasa/core/jobs.py +1 -0
  161. rasa/core/lock.py +2 -3
  162. rasa/core/lock_store.py +3 -3
  163. rasa/core/migrate.py +12 -9
  164. rasa/core/nlg/__init__.py +1 -1
  165. rasa/core/nlg/callback.py +2 -3
  166. rasa/core/nlg/contextual_response_rephraser.py +82 -14
  167. rasa/core/nlg/generator.py +85 -17
  168. rasa/core/nlg/interpolator.py +4 -3
  169. rasa/core/nlg/response.py +9 -7
  170. rasa/core/nlg/summarize.py +1 -0
  171. rasa/core/nlg/translate.py +55 -0
  172. rasa/core/persistor.py +3 -3
  173. rasa/core/policies/ensemble.py +10 -9
  174. rasa/core/policies/enterprise_search_policy.py +87 -21
  175. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +1 -1
  176. rasa/core/policies/flow_policy.py +13 -14
  177. rasa/core/policies/flows/flow_executor.py +85 -55
  178. rasa/core/policies/intentless_policy.py +6 -7
  179. rasa/core/policies/memoization.py +22 -20
  180. rasa/core/policies/policy.py +24 -22
  181. rasa/core/policies/rule_policy.py +37 -36
  182. rasa/core/policies/ted_policy.py +87 -85
  183. rasa/core/policies/unexpected_intent_policy.py +77 -75
  184. rasa/core/processor.py +167 -74
  185. rasa/core/run.py +5 -4
  186. rasa/core/secrets_manager/endpoints.py +2 -3
  187. rasa/core/secrets_manager/factory.py +2 -3
  188. rasa/core/secrets_manager/secret_manager.py +2 -3
  189. rasa/core/secrets_manager/vault.py +2 -2
  190. rasa/core/test.py +30 -30
  191. rasa/core/tracker_store.py +138 -49
  192. rasa/core/train.py +1 -1
  193. rasa/core/training/__init__.py +2 -2
  194. rasa/core/training/converters/responses_prefix_converter.py +1 -2
  195. rasa/core/training/interactive.py +13 -13
  196. rasa/core/training/story_conflict.py +4 -5
  197. rasa/core/training/training.py +3 -5
  198. rasa/core/utils.py +5 -5
  199. rasa/core/visualize.py +1 -1
  200. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -2
  201. rasa/dialogue_understanding/coexistence/llm_based_router.py +5 -5
  202. rasa/dialogue_understanding/commands/__init__.py +22 -22
  203. rasa/dialogue_understanding/commands/can_not_handle_command.py +38 -1
  204. rasa/dialogue_understanding/commands/cancel_flow_command.py +96 -9
  205. rasa/dialogue_understanding/commands/change_flow_command.py +36 -2
  206. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +36 -4
  207. rasa/dialogue_understanding/commands/clarify_command.py +46 -4
  208. rasa/dialogue_understanding/commands/command.py +3 -2
  209. rasa/dialogue_understanding/commands/command_syntax_manager.py +55 -0
  210. rasa/dialogue_understanding/commands/correct_slots_command.py +14 -5
  211. rasa/dialogue_understanding/commands/error_command.py +1 -1
  212. rasa/dialogue_understanding/commands/free_form_answer_command.py +2 -1
  213. rasa/dialogue_understanding/commands/handle_code_change_command.py +2 -2
  214. rasa/dialogue_understanding/commands/handle_digressions_command.py +144 -0
  215. rasa/dialogue_understanding/commands/human_handoff_command.py +34 -4
  216. rasa/dialogue_understanding/commands/knowledge_answer_command.py +36 -4
  217. rasa/dialogue_understanding/commands/noop_command.py +2 -1
  218. rasa/dialogue_understanding/commands/prompt_command.py +94 -0
  219. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +34 -4
  220. rasa/dialogue_understanding/commands/restart_command.py +2 -5
  221. rasa/dialogue_understanding/commands/session_end_command.py +3 -5
  222. rasa/dialogue_understanding/commands/session_start_command.py +3 -5
  223. rasa/dialogue_understanding/commands/set_slot_command.py +55 -16
  224. rasa/dialogue_understanding/commands/skip_question_command.py +34 -4
  225. rasa/dialogue_understanding/commands/start_flow_command.py +78 -2
  226. rasa/dialogue_understanding/commands/user_silence_command.py +3 -5
  227. rasa/dialogue_understanding/commands/utils.py +126 -43
  228. rasa/dialogue_understanding/constants.py +2 -0
  229. rasa/dialogue_understanding/generator/__init__.py +2 -0
  230. rasa/dialogue_understanding/generator/command_generator.py +120 -79
  231. rasa/dialogue_understanding/generator/command_parser.py +245 -0
  232. rasa/dialogue_understanding/generator/constants.py +12 -4
  233. rasa/dialogue_understanding/generator/flow_retrieval.py +7 -7
  234. rasa/dialogue_understanding/generator/llm_based_command_generator.py +187 -59
  235. rasa/dialogue_understanding/generator/llm_command_generator.py +6 -3
  236. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +106 -110
  237. rasa/dialogue_understanding/generator/nlu_command_adapter.py +53 -11
  238. rasa/dialogue_understanding/generator/prompt_templates/__init__.py +0 -0
  239. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +58 -0
  240. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +57 -0
  241. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +574 -0
  242. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +41 -386
  243. rasa/dialogue_understanding/generator/utils.py +76 -0
  244. rasa/dialogue_understanding/patterns/cancel.py +2 -1
  245. rasa/dialogue_understanding/patterns/cannot_handle.py +1 -0
  246. rasa/dialogue_understanding/patterns/chitchat.py +1 -1
  247. rasa/dialogue_understanding/patterns/clarify.py +2 -1
  248. rasa/dialogue_understanding/patterns/code_change.py +2 -0
  249. rasa/dialogue_understanding/patterns/collect_information.py +7 -4
  250. rasa/dialogue_understanding/patterns/completed.py +1 -1
  251. rasa/dialogue_understanding/patterns/continue_interrupted.py +1 -1
  252. rasa/dialogue_understanding/patterns/correction.py +17 -3
  253. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +78 -2
  254. rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
  255. rasa/dialogue_understanding/patterns/human_handoff.py +1 -1
  256. rasa/dialogue_understanding/patterns/internal_error.py +1 -0
  257. rasa/dialogue_understanding/patterns/search.py +1 -1
  258. rasa/dialogue_understanding/patterns/session_start.py +1 -1
  259. rasa/dialogue_understanding/patterns/skip_question.py +1 -0
  260. rasa/dialogue_understanding/patterns/user_silence.py +1 -1
  261. rasa/dialogue_understanding/patterns/validate_slot.py +65 -0
  262. rasa/dialogue_understanding/processor/command_processor.py +193 -43
  263. rasa/dialogue_understanding/processor/command_processor_component.py +1 -1
  264. rasa/dialogue_understanding/stack/dialogue_stack.py +4 -3
  265. rasa/dialogue_understanding/stack/frames/__init__.py +2 -2
  266. rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +4 -1
  267. rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +2 -3
  268. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +5 -2
  269. rasa/dialogue_understanding/stack/frames/search_frame.py +4 -1
  270. rasa/dialogue_understanding/stack/utils.py +56 -10
  271. rasa/dialogue_understanding/utils.py +164 -0
  272. rasa/dialogue_understanding_test/README.md +429 -0
  273. rasa/dialogue_understanding_test/__init__.py +0 -0
  274. rasa/dialogue_understanding_test/command_comparison.py +60 -0
  275. rasa/dialogue_understanding_test/command_metric_calculation.py +122 -0
  276. rasa/dialogue_understanding_test/constants.py +22 -0
  277. rasa/dialogue_understanding_test/du_test_case.py +448 -0
  278. rasa/dialogue_understanding_test/du_test_result.py +390 -0
  279. rasa/dialogue_understanding_test/du_test_runner.py +322 -0
  280. rasa/dialogue_understanding_test/du_test_schema.yml +161 -0
  281. rasa/dialogue_understanding_test/io.py +443 -0
  282. rasa/dialogue_understanding_test/test_case_simulation/__init__.py +0 -0
  283. rasa/dialogue_understanding_test/test_case_simulation/exception.py +28 -0
  284. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +336 -0
  285. rasa/dialogue_understanding_test/utils.py +70 -0
  286. rasa/dialogue_understanding_test/validation.py +77 -0
  287. rasa/e2e_test/aggregate_test_stats_calculator.py +1 -1
  288. rasa/e2e_test/assertions.py +202 -175
  289. rasa/e2e_test/assertions_schema.yml +6 -0
  290. rasa/e2e_test/constants.py +16 -1
  291. rasa/e2e_test/e2e_config.py +102 -41
  292. rasa/e2e_test/e2e_config_schema.yml +28 -10
  293. rasa/e2e_test/e2e_test_case.py +5 -5
  294. rasa/e2e_test/e2e_test_converter.py +2 -3
  295. rasa/e2e_test/e2e_test_coverage_report.py +6 -6
  296. rasa/e2e_test/e2e_test_result.py +1 -1
  297. rasa/e2e_test/e2e_test_runner.py +143 -38
  298. rasa/e2e_test/llm_judge_prompts/answer_relevance_prompt_template.jinja2 +93 -0
  299. rasa/e2e_test/llm_judge_prompts/groundedness_prompt_template.jinja2 +169 -0
  300. rasa/e2e_test/stub_custom_action.py +1 -1
  301. rasa/e2e_test/utils/generative_assertions.py +243 -0
  302. rasa/e2e_test/utils/io.py +123 -93
  303. rasa/e2e_test/utils/validation.py +101 -3
  304. rasa/engine/caching.py +5 -7
  305. rasa/engine/constants.py +1 -1
  306. rasa/engine/graph.py +3 -2
  307. rasa/engine/language.py +182 -0
  308. rasa/engine/recipes/config_files/default_config.yml +4 -0
  309. rasa/engine/recipes/default_components.py +13 -15
  310. rasa/engine/recipes/default_recipe.py +65 -49
  311. rasa/engine/recipes/graph_recipe.py +10 -7
  312. rasa/engine/recipes/recipe.py +2 -2
  313. rasa/engine/runner/dask.py +2 -2
  314. rasa/engine/runner/interface.py +1 -0
  315. rasa/engine/storage/local_model_storage.py +6 -4
  316. rasa/engine/storage/resource.py +2 -1
  317. rasa/engine/storage/storage.py +8 -3
  318. rasa/engine/training/components.py +2 -1
  319. rasa/engine/training/fingerprinting.py +4 -2
  320. rasa/engine/training/graph_trainer.py +4 -4
  321. rasa/engine/training/hooks.py +2 -2
  322. rasa/engine/validation.py +36 -33
  323. rasa/exceptions.py +3 -2
  324. rasa/graph_components/converters/nlu_message_converter.py +3 -3
  325. rasa/graph_components/providers/domain_for_core_training_provider.py +3 -3
  326. rasa/graph_components/providers/domain_provider.py +3 -2
  327. rasa/graph_components/providers/flows_provider.py +2 -3
  328. rasa/graph_components/providers/forms_provider.py +4 -4
  329. rasa/graph_components/providers/nlu_training_data_provider.py +5 -3
  330. rasa/graph_components/providers/responses_provider.py +4 -4
  331. rasa/graph_components/providers/rule_only_provider.py +3 -2
  332. rasa/graph_components/providers/story_graph_provider.py +8 -8
  333. rasa/graph_components/providers/training_tracker_provider.py +3 -2
  334. rasa/graph_components/validators/default_recipe_validator.py +16 -16
  335. rasa/graph_components/validators/finetuning_validator.py +10 -8
  336. rasa/hooks.py +19 -14
  337. rasa/jupyter.py +2 -2
  338. rasa/llm_fine_tuning/annotation_module.py +4 -4
  339. rasa/llm_fine_tuning/conversations.py +5 -33
  340. rasa/llm_fine_tuning/llm_data_preparation_module.py +6 -4
  341. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -4
  342. rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +18 -13
  343. rasa/llm_fine_tuning/paraphrasing_module.py +6 -2
  344. rasa/llm_fine_tuning/storage.py +3 -3
  345. rasa/llm_fine_tuning/train_test_split_module.py +27 -27
  346. rasa/llm_fine_tuning/utils.py +7 -0
  347. rasa/markers/marker.py +2 -3
  348. rasa/markers/marker_base.py +1 -2
  349. rasa/markers/upload.py +2 -2
  350. rasa/markers/validate.py +2 -3
  351. rasa/model.py +3 -5
  352. rasa/model_manager/config.py +1 -1
  353. rasa/model_manager/model_api.py +5 -4
  354. rasa/model_manager/runner_service.py +13 -10
  355. rasa/model_manager/socket_bridge.py +15 -9
  356. rasa/model_manager/studio_jwt_auth.py +1 -0
  357. rasa/model_manager/trainer_service.py +9 -7
  358. rasa/model_manager/utils.py +1 -1
  359. rasa/model_manager/warm_rasa_process.py +14 -9
  360. rasa/model_service.py +5 -6
  361. rasa/model_testing.py +13 -15
  362. rasa/model_training.py +29 -29
  363. rasa/nlu/classifiers/diet_classifier.py +72 -73
  364. rasa/nlu/classifiers/fallback_classifier.py +9 -8
  365. rasa/nlu/classifiers/keyword_intent_classifier.py +7 -6
  366. rasa/nlu/classifiers/logistic_regression_classifier.py +3 -3
  367. rasa/nlu/classifiers/mitie_intent_classifier.py +5 -4
  368. rasa/nlu/classifiers/regex_message_handler.py +3 -2
  369. rasa/nlu/classifiers/sklearn_intent_classifier.py +2 -2
  370. rasa/nlu/convert.py +2 -2
  371. rasa/nlu/emulators/dialogflow.py +3 -3
  372. rasa/nlu/emulators/luis.py +5 -5
  373. rasa/nlu/emulators/no_emulator.py +1 -0
  374. rasa/nlu/emulators/wit.py +4 -4
  375. rasa/nlu/extractors/crf_entity_extractor.py +11 -11
  376. rasa/nlu/extractors/duckling_entity_extractor.py +7 -6
  377. rasa/nlu/extractors/entity_synonyms.py +10 -9
  378. rasa/nlu/extractors/extractor.py +16 -16
  379. rasa/nlu/extractors/mitie_entity_extractor.py +10 -9
  380. rasa/nlu/extractors/regex_entity_extractor.py +11 -10
  381. rasa/nlu/extractors/spacy_entity_extractor.py +2 -2
  382. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +15 -14
  383. rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +2 -1
  384. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +10 -9
  385. rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +9 -7
  386. rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +13 -12
  387. rasa/nlu/featurizers/featurizer.py +5 -4
  388. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +6 -6
  389. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -4
  390. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +4 -4
  391. rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +2 -0
  392. rasa/nlu/model.py +0 -1
  393. rasa/nlu/selectors/response_selector.py +67 -68
  394. rasa/nlu/test.py +38 -38
  395. rasa/nlu/tokenizers/jieba_tokenizer.py +1 -2
  396. rasa/nlu/tokenizers/mitie_tokenizer.py +2 -2
  397. rasa/nlu/tokenizers/spacy_tokenizer.py +3 -3
  398. rasa/nlu/tokenizers/tokenizer.py +6 -7
  399. rasa/nlu/tokenizers/whitespace_tokenizer.py +1 -1
  400. rasa/nlu/utils/bilou_utils.py +7 -7
  401. rasa/nlu/utils/hugging_face/registry.py +22 -22
  402. rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +2 -1
  403. rasa/nlu/utils/mitie_utils.py +2 -1
  404. rasa/nlu/utils/pattern_utils.py +1 -1
  405. rasa/nlu/utils/spacy_utils.py +3 -3
  406. rasa/plugin.py +12 -1
  407. rasa/server.py +3 -2
  408. rasa/shared/constants.py +45 -18
  409. rasa/shared/core/command_payload_reader.py +15 -7
  410. rasa/shared/core/constants.py +34 -4
  411. rasa/shared/core/conversation.py +1 -2
  412. rasa/shared/core/domain.py +19 -20
  413. rasa/shared/core/events.py +60 -39
  414. rasa/shared/core/flows/__init__.py +0 -1
  415. rasa/shared/core/flows/constants.py +11 -0
  416. rasa/shared/core/flows/flow.py +107 -26
  417. rasa/shared/core/flows/flow_step.py +4 -3
  418. rasa/shared/core/flows/flow_step_links.py +1 -2
  419. rasa/shared/core/flows/flow_step_sequence.py +1 -1
  420. rasa/shared/core/flows/flows_list.py +3 -3
  421. rasa/shared/core/flows/flows_yaml_schema.json +69 -3
  422. rasa/shared/core/flows/nlu_trigger.py +1 -1
  423. rasa/shared/core/flows/steps/__init__.py +2 -2
  424. rasa/shared/core/flows/steps/action.py +1 -1
  425. rasa/shared/core/flows/steps/call.py +1 -1
  426. rasa/shared/core/flows/steps/collect.py +22 -40
  427. rasa/shared/core/flows/steps/internal.py +1 -1
  428. rasa/shared/core/flows/steps/link.py +1 -1
  429. rasa/shared/core/flows/steps/no_operation.py +2 -2
  430. rasa/shared/core/flows/steps/set_slots.py +1 -1
  431. rasa/shared/core/flows/utils.py +44 -4
  432. rasa/shared/core/flows/validation.py +4 -6
  433. rasa/shared/core/generator.py +20 -21
  434. rasa/shared/core/slot_mappings.py +360 -121
  435. rasa/shared/core/slots.py +163 -6
  436. rasa/shared/core/trackers.py +108 -33
  437. rasa/shared/core/training_data/loading.py +1 -1
  438. rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
  439. rasa/shared/core/training_data/story_reader/story_step_builder.py +4 -4
  440. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +29 -31
  441. rasa/shared/core/training_data/story_writer/yaml_story_writer.py +22 -24
  442. rasa/shared/core/training_data/structures.py +11 -12
  443. rasa/shared/core/training_data/visualization.py +10 -10
  444. rasa/shared/data.py +6 -6
  445. rasa/shared/engine/caching.py +0 -1
  446. rasa/shared/exceptions.py +2 -2
  447. rasa/shared/importers/importer.py +58 -2
  448. rasa/shared/importers/rasa.py +5 -6
  449. rasa/shared/importers/utils.py +1 -1
  450. rasa/shared/nlu/constants.py +9 -0
  451. rasa/shared/nlu/training_data/entities_parser.py +6 -6
  452. rasa/shared/nlu/training_data/features.py +3 -3
  453. rasa/shared/nlu/training_data/formats/__init__.py +1 -1
  454. rasa/shared/nlu/training_data/formats/dialogflow.py +4 -5
  455. rasa/shared/nlu/training_data/formats/luis.py +7 -8
  456. rasa/shared/nlu/training_data/formats/rasa.py +4 -5
  457. rasa/shared/nlu/training_data/formats/rasa_yaml.py +17 -16
  458. rasa/shared/nlu/training_data/formats/readerwriter.py +8 -11
  459. rasa/shared/nlu/training_data/formats/wit.py +3 -4
  460. rasa/shared/nlu/training_data/loading.py +4 -4
  461. rasa/shared/nlu/training_data/lookup_tables_parser.py +1 -1
  462. rasa/shared/nlu/training_data/message.py +13 -14
  463. rasa/shared/nlu/training_data/schemas/data_schema.py +1 -1
  464. rasa/shared/nlu/training_data/schemas/responses.yml +19 -11
  465. rasa/shared/nlu/training_data/synonyms_parser.py +3 -3
  466. rasa/shared/nlu/training_data/training_data.py +12 -13
  467. rasa/shared/nlu/training_data/util.py +11 -10
  468. rasa/shared/providers/_configs/azure_entra_id_config.py +541 -0
  469. rasa/shared/providers/_configs/azure_openai_client_config.py +150 -15
  470. rasa/shared/providers/_configs/client_config.py +3 -1
  471. rasa/shared/providers/_configs/default_litellm_client_config.py +9 -7
  472. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +13 -11
  473. rasa/shared/providers/_configs/litellm_router_client_config.py +12 -10
  474. rasa/shared/providers/_configs/model_group_config.py +8 -5
  475. rasa/shared/providers/_configs/oauth_config.py +33 -0
  476. rasa/shared/providers/_configs/openai_client_config.py +14 -12
  477. rasa/shared/providers/_configs/rasa_llm_client_config.py +5 -3
  478. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +12 -11
  479. rasa/shared/providers/_configs/utils.py +1 -0
  480. rasa/shared/providers/_ssl_verification_utils.py +5 -6
  481. rasa/shared/providers/_utils.py +5 -5
  482. rasa/shared/providers/constants.py +6 -0
  483. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -1
  484. rasa/shared/providers/embedding/azure_openai_embedding_client.py +32 -7
  485. rasa/shared/providers/embedding/embedding_client.py +1 -1
  486. rasa/shared/providers/embedding/litellm_router_embedding_client.py +5 -2
  487. rasa/shared/providers/llm/_base_litellm_client.py +43 -18
  488. rasa/shared/providers/llm/azure_openai_llm_client.py +90 -34
  489. rasa/shared/providers/llm/default_litellm_llm_client.py +4 -2
  490. rasa/shared/providers/llm/litellm_router_llm_client.py +32 -9
  491. rasa/shared/providers/llm/llm_client.py +24 -8
  492. rasa/shared/providers/llm/llm_response.py +61 -2
  493. rasa/shared/providers/llm/openai_llm_client.py +11 -5
  494. rasa/shared/providers/llm/rasa_llm_client.py +17 -14
  495. rasa/shared/providers/llm/self_hosted_llm_client.py +35 -15
  496. rasa/shared/providers/mappings.py +18 -19
  497. rasa/shared/providers/router/_base_litellm_router_client.py +48 -15
  498. rasa/shared/providers/router/router_client.py +3 -1
  499. rasa/shared/utils/cli.py +1 -1
  500. rasa/shared/utils/common.py +15 -1
  501. rasa/shared/utils/constants.py +3 -0
  502. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +1 -1
  503. rasa/shared/utils/health_check/health_check.py +3 -3
  504. rasa/shared/utils/health_check/llm_health_check_mixin.py +1 -1
  505. rasa/shared/utils/io.py +1 -1
  506. rasa/shared/utils/llm.py +100 -18
  507. rasa/shared/utils/pykwalify_extensions.py +25 -1
  508. rasa/shared/utils/schemas/domain.yml +26 -1
  509. rasa/shared/utils/schemas/events.py +1 -1
  510. rasa/shared/utils/yaml.py +24 -20
  511. rasa/studio/auth.py +3 -3
  512. rasa/studio/config.py +1 -2
  513. rasa/studio/data_handler.py +3 -3
  514. rasa/studio/download.py +1 -1
  515. rasa/studio/results_logger.py +3 -3
  516. rasa/studio/upload.py +21 -5
  517. rasa/telemetry.py +127 -48
  518. rasa/tracing/config.py +5 -3
  519. rasa/tracing/constants.py +12 -0
  520. rasa/tracing/instrumentation/attribute_extractors.py +92 -14
  521. rasa/tracing/instrumentation/instrumentation.py +61 -5
  522. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +1 -1
  523. rasa/tracing/instrumentation/metrics.py +52 -11
  524. rasa/tracing/metric_instrument_provider.py +54 -14
  525. rasa/utils/common.py +12 -24
  526. rasa/utils/endpoints.py +1 -1
  527. rasa/utils/io.py +7 -7
  528. rasa/utils/licensing.py +3 -4
  529. rasa/utils/log_utils.py +7 -6
  530. rasa/utils/ml_utils.py +1 -0
  531. rasa/utils/plotting.py +3 -3
  532. rasa/utils/sanic_error_handler.py +1 -1
  533. rasa/utils/tensorflow/callback.py +2 -2
  534. rasa/utils/tensorflow/crf.py +2 -2
  535. rasa/utils/tensorflow/data_generator.py +5 -5
  536. rasa/utils/tensorflow/environment.py +3 -3
  537. rasa/utils/tensorflow/feature_array.py +2 -3
  538. rasa/utils/tensorflow/layers.py +18 -12
  539. rasa/utils/tensorflow/layers_utils.py +2 -1
  540. rasa/utils/tensorflow/metrics.py +2 -2
  541. rasa/utils/tensorflow/model_data.py +7 -7
  542. rasa/utils/tensorflow/model_data_utils.py +10 -9
  543. rasa/utils/tensorflow/models.py +31 -32
  544. rasa/utils/tensorflow/rasa_layers.py +20 -19
  545. rasa/utils/tensorflow/types.py +2 -1
  546. rasa/utils/train_utils.py +23 -21
  547. rasa/utils/url_tools.py +1 -1
  548. rasa/validator.py +594 -115
  549. rasa/version.py +1 -1
  550. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/METADATA +23 -26
  551. rasa_pro-3.12.0.dist-info/RECORD +829 -0
  552. rasa/core/channels/inspector/dist/assets/channel-e265ea59.js +0 -1
  553. rasa/core/channels/inspector/dist/assets/clone-21f8a43d.js +0 -1
  554. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-5c8ce12d.js +0 -1
  555. rasa_pro-3.11.5.dist-info/RECORD +0 -785
  556. /rasa/dialogue_understanding/generator/{single_step → prompt_templates}/command_prompt_template.jinja2 +0 -0
  557. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/NOTICE +0 -0
  558. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/WHEEL +0 -0
  559. {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/entry_points.txt +0 -0
@@ -1,63 +1,64 @@
1
1
  import importlib.resources
2
- import re
3
- from typing import Dict, Any, List, Optional, Tuple, Union, Text
2
+ from typing import Any, Dict, List, Optional, Text, Tuple, Union
4
3
 
5
4
  import structlog
5
+ from deprecated import deprecated # type: ignore[import]
6
6
  from jinja2 import Template
7
7
 
8
8
  import rasa.shared.utils.io
9
9
  from rasa.dialogue_understanding.commands import (
10
+ CannotHandleCommand,
11
+ ChangeFlowCommand,
10
12
  Command,
11
13
  ErrorCommand,
12
14
  SetSlotCommand,
13
- CancelFlowCommand,
14
15
  StartFlowCommand,
15
- HumanHandoffCommand,
16
- ChitChatAnswerCommand,
17
- SkipQuestionCommand,
18
- KnowledgeAnswerCommand,
19
- ClarifyCommand,
20
- CannotHandleCommand,
21
16
  )
22
- from rasa.dialogue_understanding.commands.change_flow_command import ChangeFlowCommand
17
+ from rasa.dialogue_understanding.commands.can_not_handle_command import (
18
+ DATA_KEY_CANNOT_HANDLE_REASON,
19
+ )
20
+ from rasa.dialogue_understanding.generator.command_parser import (
21
+ parse_commands as parse_commands_using_command_parsers,
22
+ )
23
23
  from rasa.dialogue_understanding.generator.constants import (
24
+ DEFAULT_LLM_CONFIG,
25
+ FLOW_RETRIEVAL_KEY,
24
26
  LLM_CONFIG_KEY,
25
27
  USER_INPUT_CONFIG_KEY,
26
- FLOW_RETRIEVAL_KEY,
27
- DEFAULT_LLM_CONFIG,
28
28
  )
29
29
  from rasa.dialogue_understanding.generator.flow_retrieval import FlowRetrieval
30
30
  from rasa.dialogue_understanding.generator.llm_based_command_generator import (
31
31
  LLMBasedCommandGenerator,
32
32
  )
33
33
  from rasa.dialogue_understanding.stack.frames import UserFlowStackFrame
34
- from rasa.dialogue_understanding.stack.utils import (
35
- top_flow_frame,
36
- top_user_flow_frame,
37
- user_flows_on_the_stack,
34
+ from rasa.dialogue_understanding.stack.utils import top_flow_frame, top_user_flow_frame
35
+ from rasa.dialogue_understanding.utils import (
36
+ add_commands_to_message_parse_data,
37
+ add_prompt_to_message_parse_data,
38
38
  )
39
39
  from rasa.engine.graph import ExecutionContext
40
40
  from rasa.engine.recipes.default_recipe import DefaultV1Recipe
41
41
  from rasa.engine.storage.resource import Resource
42
42
  from rasa.engine.storage.storage import ModelStorage
43
43
  from rasa.shared.constants import (
44
- RASA_PATTERN_CANNOT_HANDLE_NOT_SUPPORTED,
45
44
  EMBEDDINGS_CONFIG_KEY,
45
+ RASA_PATTERN_CANNOT_HANDLE_NOT_SUPPORTED,
46
+ ROUTE_TO_CALM_SLOT,
46
47
  )
47
- from rasa.shared.constants import ROUTE_TO_CALM_SLOT
48
- from rasa.shared.core.flows import FlowStep, Flow, FlowsList
48
+ from rasa.shared.core.flows import Flow, FlowsList, FlowStep
49
49
  from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
50
50
  from rasa.shared.core.trackers import DialogueStateTracker
51
51
  from rasa.shared.exceptions import ProviderClientAPIException
52
52
  from rasa.shared.nlu.constants import TEXT
53
53
  from rasa.shared.nlu.training_data.message import Message
54
- from rasa.shared.utils.io import deep_container_fingerprint
54
+ from rasa.shared.providers.llm.llm_response import LLMResponse
55
+ from rasa.shared.utils.io import deep_container_fingerprint, raise_deprecation_warning
55
56
  from rasa.shared.utils.llm import (
56
- get_prompt_template,
57
- tracker_as_readable_transcript,
58
- sanitize_message_for_prompt,
59
57
  allowed_values_for_slot,
58
+ get_prompt_template,
60
59
  resolve_model_client_config,
60
+ sanitize_message_for_prompt,
61
+ tracker_as_readable_transcript,
61
62
  )
62
63
 
63
64
  # multistep template keys
@@ -100,6 +101,12 @@ structlogger = structlog.get_logger()
100
101
  ],
101
102
  is_trainable=True,
102
103
  )
104
+ @deprecated(
105
+ reason=(
106
+ "The MultiStepLLMCommandGenerator is deprecated and will be removed in "
107
+ "Rasa `4.0.0`."
108
+ )
109
+ )
103
110
  class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
104
111
  """An multi step command generator using LLM."""
105
112
 
@@ -111,6 +118,14 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
111
118
  prompt_templates: Optional[Dict[Text, Optional[Text]]] = None,
112
119
  **kwargs: Any,
113
120
  ) -> None:
121
+ raise_deprecation_warning(
122
+ message=(
123
+ "Support for `MultiStepLLMCommandGenerator` will be removed in Rasa "
124
+ "`4.0.0`. Please modify your assistant's configuration to use other "
125
+ "LLM command generators like the `SingleStepLLMCommandGenerator`."
126
+ )
127
+ )
128
+
114
129
  super().__init__(
115
130
  config, model_storage, resource, prompt_templates=prompt_templates, **kwargs
116
131
  )
@@ -120,7 +135,6 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
120
135
  FILL_SLOTS_KEY: None,
121
136
  }
122
137
  self._init_prompt_templates(prompt_templates)
123
-
124
138
  self.trace_prompt_tokens = self.config.get("trace_prompt_tokens", False)
125
139
 
126
140
  ### Implementations of LLMBasedCommandGenerator parent
@@ -144,7 +158,6 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
144
158
  **kwargs: Any,
145
159
  ) -> "MultiStepLLMCommandGenerator":
146
160
  """Loads trained component (see parent class for full docstring)."""
147
-
148
161
  # Perform health check of the LLM client config
149
162
  llm_config = resolve_model_client_config(config.get(LLM_CONFIG_KEY, {}))
150
163
  cls.perform_llm_health_check(
@@ -191,21 +204,29 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
191
204
  Returns:
192
205
  The commands generated by the llm.
193
206
  """
207
+ prior_commands = self._get_prior_commands(message)
208
+
194
209
  if tracker is None or flows.is_empty():
195
210
  # cannot do anything if there are no flows or no tracker
196
- return []
211
+ return prior_commands
212
+
213
+ if self._should_skip_llm_call(prior_commands, flows, tracker):
214
+ return prior_commands
197
215
 
198
216
  try:
199
217
  commands = await self._predict_commands_with_multi_step(
200
218
  message, flows, tracker
201
219
  )
202
220
  commands = self._clean_up_commands(commands)
221
+ add_commands_to_message_parse_data(
222
+ message, MultiStepLLMCommandGenerator.__name__, commands
223
+ )
203
224
  except ProviderClientAPIException:
204
225
  # if any step resulted in API exception, the command prediction cannot
205
226
  # be completed, "predict" the ErrorCommand
206
227
  commands = [ErrorCommand()]
207
228
 
208
- if not commands:
229
+ if not commands and not prior_commands:
209
230
  # if for any reason the final list of commands is empty,
210
231
  # "predict" CannotHandle
211
232
  commands = [CannotHandleCommand()]
@@ -219,7 +240,10 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
219
240
  commands=commands,
220
241
  )
221
242
 
222
- return commands
243
+ domain = kwargs.get("domain")
244
+ commands = self._check_commands_against_slot_mappings(commands, tracker, domain)
245
+
246
+ return self._check_commands_overlap(prior_commands, commands)
223
247
 
224
248
  @classmethod
225
249
  def parse_commands(
@@ -240,86 +264,15 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
240
264
  Returns:
241
265
  The parsed commands.
242
266
  """
243
- if not actions:
244
- return []
245
-
246
- commands: List[Command] = []
247
-
248
- slot_set_re = re.compile(
249
- r"""SetSlot\(['"]?([a-zA-Z_][a-zA-Z0-9_-]*)['"]?, ?['"]?(.*)['"]?\)"""
267
+ commands = parse_commands_using_command_parsers(
268
+ actions,
269
+ flows,
270
+ is_handle_flows_prompt=is_handle_flows_prompt,
271
+ additional_commands=[CannotHandleCommand, ChangeFlowCommand],
272
+ data={
273
+ DATA_KEY_CANNOT_HANDLE_REASON: RASA_PATTERN_CANNOT_HANDLE_NOT_SUPPORTED
274
+ },
250
275
  )
251
- start_flow_re = re.compile(r"StartFlow\(['\"]?([a-zA-Z0-9_-]+)['\"]?\)")
252
- change_flow_re = re.compile(r"ChangeFlow\(\)")
253
- cancel_flow_re = re.compile(r"CancelFlow\(\)")
254
- chitchat_re = re.compile(r"ChitChat\(\)")
255
- skip_question_re = re.compile(r"SkipQuestion\(\)")
256
- knowledge_re = re.compile(r"SearchAndReply\(\)")
257
- humand_handoff_re = re.compile(r"HumanHandoff\(\)")
258
- clarify_re = re.compile(r"Clarify\(([\"\'a-zA-Z0-9_, ]+)\)")
259
- cannot_handle_re = re.compile(r"CannotHandle\(\)")
260
-
261
- for action in actions.strip().splitlines():
262
- if is_handle_flows_prompt:
263
- if (
264
- len(commands) >= 2
265
- or len(commands) == 1
266
- and isinstance(commands[0], ClarifyCommand)
267
- ):
268
- break
269
-
270
- if cannot_handle_re.search(action):
271
- commands.append(
272
- CannotHandleCommand(RASA_PATTERN_CANNOT_HANDLE_NOT_SUPPORTED)
273
- )
274
- if match := slot_set_re.search(action):
275
- slot_name = cls.clean_extracted_value(match.group(1).strip())
276
- slot_value = cls.clean_extracted_value(match.group(2))
277
- # error case where the llm tries to start a flow using a slot set
278
- if slot_name == "flow_name":
279
- commands.extend(cls.start_flow_by_name(slot_value, flows))
280
- else:
281
- typed_slot_value = cls.get_nullable_slot_value(slot_value)
282
- commands.append(
283
- SetSlotCommand(name=slot_name, value=typed_slot_value)
284
- )
285
- elif match := start_flow_re.search(action):
286
- flow_name = match.group(1).strip()
287
- commands.extend(cls.start_flow_by_name(flow_name, flows))
288
- elif cancel_flow_re.search(action):
289
- commands.append(CancelFlowCommand())
290
- elif chitchat_re.search(action):
291
- commands.append(ChitChatAnswerCommand())
292
- elif skip_question_re.search(action):
293
- commands.append(SkipQuestionCommand())
294
- elif knowledge_re.search(action):
295
- commands.append(KnowledgeAnswerCommand())
296
- elif humand_handoff_re.search(action):
297
- commands.append(HumanHandoffCommand())
298
- elif match := clarify_re.search(action):
299
- options = sorted([opt.strip() for opt in match.group(1).split(",")])
300
- # Remove surrounding quotes if present
301
- cleaned_options = []
302
- for flow in options:
303
- if (flow.startswith('"') and flow.endswith('"')) or (
304
- flow.startswith("'") and flow.endswith("'")
305
- ):
306
- cleaned_options.append(flow[1:-1])
307
- else:
308
- cleaned_options.append(flow)
309
- # check if flow is valid
310
- valid_options = [
311
- flow
312
- for flow in cleaned_options
313
- if flow in flows.user_flow_ids
314
- and flow not in user_flows_on_the_stack(tracker.stack)
315
- ]
316
- if len(valid_options) == 1:
317
- commands.extend(cls.start_flow_by_name(valid_options[0], flows))
318
- elif 1 < len(valid_options) <= 5:
319
- commands.append(ClarifyCommand(valid_options))
320
- elif change_flow_re.search(action):
321
- commands.append(ChangeFlowCommand())
322
-
323
276
  if not commands:
324
277
  structlogger.debug(
325
278
  "multi_step_llm_command_generator.parse_commands",
@@ -533,7 +486,12 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
533
486
  prompt=prompt,
534
487
  )
535
488
 
536
- actions = await self.invoke_llm(prompt)
489
+ response = await self.invoke_llm(prompt)
490
+ llm_response = LLMResponse.ensure_llm_response(response)
491
+ actions = None
492
+ if llm_response and llm_response.choices:
493
+ actions = llm_response.choices[0]
494
+
537
495
  structlogger.debug(
538
496
  "multi_step_llm_command_generator"
539
497
  ".predict_commands_for_active_flow"
@@ -542,6 +500,16 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
542
500
  )
543
501
 
544
502
  commands = self.parse_commands(actions, tracker, available_flows)
503
+
504
+ if commands:
505
+ add_prompt_to_message_parse_data(
506
+ message=message,
507
+ component_name=MultiStepLLMCommandGenerator.__name__,
508
+ prompt_name="fill_slots_for_active_flow_prompt",
509
+ user_prompt=prompt,
510
+ llm_response=llm_response,
511
+ )
512
+
545
513
  return commands
546
514
 
547
515
  async def _predict_commands_for_handling_flows(
@@ -573,7 +541,12 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
573
541
  prompt=prompt,
574
542
  )
575
543
 
576
- actions = await self.invoke_llm(prompt)
544
+ response = await self.invoke_llm(prompt)
545
+ llm_response = LLMResponse.ensure_llm_response(response)
546
+ actions = None
547
+ if llm_response and llm_response.choices:
548
+ actions = llm_response.choices[0]
549
+
577
550
  structlogger.debug(
578
551
  "multi_step_llm_command_generator"
579
552
  ".predict_commands_for_handling_flows"
@@ -585,6 +558,15 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
585
558
  # filter out flows that are already started and active
586
559
  commands = self._filter_redundant_start_flow_commands(tracker, commands)
587
560
 
561
+ if commands:
562
+ add_prompt_to_message_parse_data(
563
+ message=message,
564
+ component_name=MultiStepLLMCommandGenerator.__name__,
565
+ prompt_name="handle_flows_prompt",
566
+ user_prompt=prompt,
567
+ llm_response=llm_response,
568
+ )
569
+
588
570
  return commands
589
571
 
590
572
  @staticmethod
@@ -649,7 +631,12 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
649
631
  prompt=prompt,
650
632
  )
651
633
 
652
- actions = await self.invoke_llm(prompt)
634
+ response = await self.invoke_llm(prompt)
635
+ llm_response = LLMResponse.ensure_llm_response(response)
636
+ actions = None
637
+ if llm_response and llm_response.choices:
638
+ actions = llm_response.choices[0]
639
+
653
640
  structlogger.debug(
654
641
  "multi_step_llm_command_generator"
655
642
  ".predict_commands_for_newly_started_flow"
@@ -674,6 +661,15 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
674
661
  commands=commands,
675
662
  )
676
663
 
664
+ if commands:
665
+ add_prompt_to_message_parse_data(
666
+ message=message,
667
+ component_name=MultiStepLLMCommandGenerator.__name__,
668
+ prompt_name="fill_slots_for_new_flow_prompt",
669
+ user_prompt=prompt,
670
+ llm_response=llm_response,
671
+ )
672
+
677
673
  return commands
678
674
 
679
675
  def _prepare_inputs(
@@ -1,18 +1,20 @@
1
- from typing import Dict, Text, Any, Optional, List
1
+ from typing import Any, Dict, List, Optional, Set, Text, Tuple
2
2
 
3
3
  import structlog
4
4
 
5
+ import rasa.dialogue_understanding.generator.utils
5
6
  from rasa.dialogue_understanding.commands import (
6
7
  Command,
7
- StartFlowCommand,
8
8
  SetSlotCommand,
9
+ StartFlowCommand,
9
10
  )
10
11
  from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
11
- from rasa.dialogue_understanding.commands.utils import (
12
+ from rasa.dialogue_understanding.generator import CommandGenerator
13
+ from rasa.dialogue_understanding.generator.utils import (
12
14
  triggerable_pattern_to_command_class,
13
15
  )
14
- from rasa.dialogue_understanding.generator import CommandGenerator
15
- from rasa.engine.graph import GraphComponent, ExecutionContext
16
+ from rasa.dialogue_understanding.utils import add_commands_to_message_parse_data
17
+ from rasa.engine.graph import ExecutionContext, GraphComponent
16
18
  from rasa.engine.recipes.default_recipe import DefaultV1Recipe
17
19
  from rasa.engine.storage.resource import Resource
18
20
  from rasa.engine.storage.storage import ModelStorage
@@ -20,10 +22,7 @@ from rasa.shared.constants import ROUTE_TO_CALM_SLOT
20
22
  from rasa.shared.core.domain import Domain
21
23
  from rasa.shared.core.flows.flows_list import FlowsList
22
24
  from rasa.shared.core.flows.steps import CollectInformationFlowStep
23
- from rasa.shared.core.slot_mappings import (
24
- SlotFillingManager,
25
- extract_slot_value,
26
- )
25
+ from rasa.shared.core.slot_mappings import SlotFillingManager, extract_slot_value
27
26
  from rasa.shared.core.trackers import DialogueStateTracker
28
27
  from rasa.shared.nlu.constants import ENTITIES, INTENT
29
28
  from rasa.shared.nlu.training_data.message import Message
@@ -100,9 +99,11 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
100
99
  Returns:
101
100
  The commands triggered by NLU.
102
101
  """
102
+ prior_commands = self._get_prior_commands(message)
103
+
103
104
  if tracker is None or flows.is_empty():
104
105
  # cannot do anything if there are no flows or no tracker
105
- return []
106
+ return prior_commands
106
107
 
107
108
  domain = kwargs.get("domain", None)
108
109
  commands = self.convert_nlu_to_commands(message, tracker, flows, domain)
@@ -148,7 +149,7 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
148
149
  commands=commands,
149
150
  )
150
151
 
151
- return commands
152
+ return self._check_commands_overlap(prior_commands, commands)
152
153
 
153
154
  @staticmethod
154
155
  def convert_nlu_to_commands(
@@ -205,8 +206,49 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
205
206
  commands=commands,
206
207
  )
207
208
 
209
+ add_commands_to_message_parse_data(
210
+ message, NLUCommandAdapter.__name__, commands
211
+ )
208
212
  return commands
209
213
 
214
+ def _check_start_flow_command_overlap(
215
+ self,
216
+ prior_commands: List[Command],
217
+ commands: List[Command],
218
+ prior_start_flow_names: Set[str],
219
+ current_start_flow_names: Set[str],
220
+ ) -> List[Command]:
221
+ """Prioritize the current NLU commands over the prior commands."""
222
+ different_flow_names = prior_start_flow_names.difference(
223
+ current_start_flow_names
224
+ )
225
+
226
+ if not different_flow_names:
227
+ return prior_commands + commands
228
+
229
+ filtered_commands = [
230
+ command
231
+ for command in prior_commands
232
+ if not isinstance(command, StartFlowCommand)
233
+ or command.flow not in different_flow_names
234
+ ]
235
+
236
+ return filtered_commands + commands
237
+
238
+ def _filter_slot_commands(
239
+ self,
240
+ prior_commands: List[Command],
241
+ commands: List[Command],
242
+ overlapping_slot_names: Set[str],
243
+ ) -> Tuple[List[Command], List[Command]]:
244
+ """Prioritize NLU commands over prior_commands in the case of same slot."""
245
+ filtered_prior_commands = (
246
+ rasa.dialogue_understanding.generator.utils.filter_slot_commands(
247
+ prior_commands, overlapping_slot_names
248
+ )
249
+ )
250
+ return filtered_prior_commands, commands
251
+
210
252
 
211
253
  def _issue_set_slot_commands(
212
254
  message: Message,
@@ -0,0 +1,58 @@
1
+ ## Task Description
2
+ Your task is to analyze the current conversation context and generate a list of actions to start new business processes that we call flows, to extract slots, or respond to small talk and knowledge requests.
3
+
4
+ --
5
+
6
+ ## Available Actions:
7
+ * `start flow flow_name`: Starting a flow. For example, `start flow transfer_money` or `start flow list_contacts`.
8
+ * `set slot slot_name slot_value`: Slot setting. For example, `set slot transfer_money_recipient Freddy`. Can be used to correct and change previously set values.
9
+ * `cancel flow`: Cancelling the current flow.
10
+ * `disambiguate flows flow_name1 flow_name2 ... flow_name_n`: Disambiguate which flow should be started when user input is ambiguous by listing the potential flows as options. For example, `disambiguate flows list_contacts add_contact remove_contact ...` if the user just wrote "contacts".
11
+ * `provide info`: Responding to the user's questions by supplying relevant information, such as answering FAQs or explaining services.
12
+ * `offtopic reply`: Responding to casual or social user messages that are unrelated to any flows, engaging in friendly conversation and addressing off-topic remarks.
13
+ * `hand over`: Handing over to a human, in case the user seems frustrated or explicitly asks to speak to one.
14
+
15
+ --
16
+
17
+ ## General Tips
18
+ * Do not fill slots with abstract values or placeholders.
19
+ * For categorical slots try to match the user message with allowed slot values. Use "other" if you cannot match it.
20
+ * Set the boolean slots based on the user response. Map positive responses to `True`, and negative to `False`.
21
+ * Always refer to the slot description to determine what information should be extracted and how it should be formatted.
22
+ * For text slots, extract values exactly as provided by the user unless the slot description specifies otherwise. Preserve formatting and avoid rewording, truncation, or making assumptions.
23
+ * Only use information provided by the user.
24
+ * Use clarification in ambiguous cases.
25
+ * Multiple flows can be started. If a user wants to digress into a second flow, you do not need to cancel the current flow.
26
+ * Do not cancel the flow unless the user explicitly requests it.
27
+ * Strictly adhere to the provided action format.
28
+ * Focus on the last message and take it one step at a time.
29
+ * Use the previous conversation steps only to aid understanding.
30
+
31
+ --
32
+
33
+ ## Available Flows and Slots
34
+ Use the following structured data:
35
+ ```json
36
+ {"flows":[{% for flow in available_flows %}{"name":"{{ flow.name }}","description":"{{ flow.description }}"{% if flow.slots %},"slots":[{% for slot in flow.slots %}{"name":"{{ slot.name }}"{% if slot.description %},"description":"{{ slot.description }}"{% endif %}{% if slot.allowed_values %},"allowed_values":{{ slot.allowed_values }}{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]}
37
+ ```
38
+
39
+ --
40
+
41
+ ## Current State
42
+ {% if current_flow != None %}Use the following structured data:
43
+ ```json
44
+ {"active_flow":"{{ current_flow }}","current_step":{"requested_slot":"{{ current_slot }}","requested_slot_description":"{{ current_slot_description }}"},"slots":[{% for slot in flow_slots %}{"name":"{{ slot.name }}","value":"{{ slot.value }}","type":"{{ slot.type }}"{% if slot.description %},"description":"{{ slot.description }}"{% endif %}{% if slot.allowed_values %},"allowed_values":"{{ slot.allowed_values }}"{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]}
45
+ ```{% else %}
46
+ You are currently not inside any flow.{% endif %}
47
+
48
+ ---
49
+
50
+ ## Conversation History
51
+ {{ current_conversation }}
52
+
53
+ ---
54
+
55
+ ## Task
56
+ Create an action list with one action per line in response to the user's last message: """{{ user_message }}""".
57
+
58
+ Your action list:
@@ -0,0 +1,57 @@
1
+ ## Task Description
2
+ Your task is to analyze the current conversation context and generate a list of actions to start new business processes that we call flows, to extract slots, or respond to small talk and knowledge requests.
3
+
4
+ ---
5
+
6
+ ## Available Flows and Slots
7
+ Use the following structured data:
8
+ ```json
9
+ {"flows":[{% for flow in available_flows %}{"name":"{{ flow.name }}","description":"{{ flow.description }}"{% if flow.slots %},"slots":[{% for slot in flow.slots %}{"name":"{{ slot.name }}"{% if slot.description %},"description":"{{ slot.description }}"{% endif %}{% if slot.allowed_values %},"allowed_values":{{ slot.allowed_values }}{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]}
10
+ ```
11
+
12
+ ---
13
+
14
+ ## Available Actions:
15
+ * `start flow flow_name`: Starting a flow. For example, `start flow transfer_money` or `start flow list_contacts`.
16
+ * `set slot slot_name slot_value`: Slot setting. For example, `set slot transfer_money_recipient Freddy`. Can be used to correct and change previously set values.
17
+ * `cancel flow`: Cancelling the current flow.
18
+ * `disambiguate flows flow_name1 flow_name2 ... flow_name_n`: Disambiguate which flow should be started when user input is ambiguous by listing the potential flows as options. For example, `disambiguate flows list_contacts add_contact remove_contact ...` if the user just wrote "contacts".
19
+ * `provide info`: Responding to the user's questions by supplying relevant information, such as answering FAQs or explaining services.
20
+ * `offtopic reply`: Responding to casual or social user messages that are unrelated to any flows, engaging in friendly conversation and addressing off-topic remarks.
21
+ * `hand over`: Handing over to a human, in case the user seems frustrated or explicitly asks to speak to one.
22
+
23
+ ---
24
+
25
+ ## General Tips
26
+ * Do not fill slots with abstract values or placeholders.
27
+ * For categorical slots try to match the user message with allowed slot values. Use "other" if you cannot match it.
28
+ * Set the boolean slots based on the user response. Map positive responses to `True`, and negative to `False`.
29
+ * Extract text slot values exactly as provided by the user. Avoid assumptions, format changes, or partial extractions.
30
+ * Only use information provided by the user.
31
+ * Use clarification in ambiguous cases.
32
+ * Multiple flows can be started. If a user wants to digress into a second flow, you do not need to cancel the current flow.
33
+ * Do not cancel the flow unless the user explicitly requests it.
34
+ * Strictly adhere to the provided action format.
35
+ * Focus on the last message and take it one step at a time.
36
+ * Use the previous conversation steps only to aid understanding.
37
+
38
+ ---
39
+
40
+ ## Current State
41
+ {% if current_flow != None %}Use the following structured data:
42
+ ```json
43
+ {"active_flow":"{{ current_flow }}","current_step":{"requested_slot":"{{ current_slot }}","requested_slot_description":"{{ current_slot_description }}"},"slots":[{% for slot in flow_slots %}{"name":"{{ slot.name }}","value":"{{ slot.value }}","type":"{{ slot.type }}"{% if slot.description %},"description":"{{ slot.description }}"{% endif %}{% if slot.allowed_values %},"allowed_values":"{{ slot.allowed_values }}"{% endif %}}{% if not loop.last %},{% endif %}{% endfor %}]}
44
+ ```{% else %}
45
+ You are currently not inside any flow.{% endif %}
46
+
47
+ ---
48
+
49
+ ## Conversation History
50
+ {{ current_conversation }}
51
+
52
+ ---
53
+
54
+ ## Task
55
+ Create an action list with one action per line in response to the user's last message: """{{ user_message }}""".
56
+
57
+ Your action list: