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
@@ -0,0 +1,245 @@
1
+ import re
2
+ import sys
3
+ from functools import lru_cache
4
+ from typing import Any, Callable, Dict, List, Optional, Type, Union
5
+
6
+ import structlog
7
+
8
+ from rasa.dialogue_understanding.commands import (
9
+ CancelFlowCommand,
10
+ ChitChatAnswerCommand,
11
+ ClarifyCommand,
12
+ Command,
13
+ HumanHandoffCommand,
14
+ KnowledgeAnswerCommand,
15
+ RepeatBotMessagesCommand,
16
+ SetSlotCommand,
17
+ SkipQuestionCommand,
18
+ StartFlowCommand,
19
+ )
20
+ from rasa.dialogue_understanding.commands.prompt_command import PromptCommand
21
+ from rasa.dialogue_understanding.commands.utils import start_flow_by_name
22
+ from rasa.shared.core.flows import FlowsList
23
+
24
+ structlogger = structlog.get_logger()
25
+
26
+
27
+ DEFAULT_COMMANDS = [
28
+ SetSlotCommand,
29
+ StartFlowCommand,
30
+ CancelFlowCommand,
31
+ ChitChatAnswerCommand,
32
+ SkipQuestionCommand,
33
+ KnowledgeAnswerCommand,
34
+ HumanHandoffCommand,
35
+ ClarifyCommand,
36
+ RepeatBotMessagesCommand,
37
+ ]
38
+
39
+
40
+ @lru_cache(maxsize=128)
41
+ def _get_compiled_pattern(pattern_str: str) -> re.Pattern:
42
+ return re.compile(pattern_str)
43
+
44
+
45
+ def _create_default_commands(
46
+ default_commands_to_remove: Union[List[Type[PromptCommand]], List[str]],
47
+ ) -> List[Type[PromptCommand]]:
48
+ """Return an updated list of default commands after removing the provided commands.
49
+
50
+ Args:
51
+ default_commands_to_remove: A list of commands to remove from the default
52
+ commands.
53
+
54
+ Returns:
55
+ A copy of the default commands with the provided commands removed.
56
+ """
57
+ commands_after_removal = []
58
+ for command in DEFAULT_COMMANDS:
59
+ if (
60
+ command not in default_commands_to_remove
61
+ and command.__name__ not in default_commands_to_remove
62
+ ):
63
+ commands_after_removal.append(command)
64
+
65
+ return commands_after_removal
66
+
67
+
68
+ def _get_additional_parsing_logic(
69
+ command_clz: Type[PromptCommand],
70
+ ) -> Optional[Callable[[PromptCommand, FlowsList], Optional[PromptCommand]]]:
71
+ """Get additional parsing logic for a command."""
72
+ command_to_parsing_fn_mapper: Dict[
73
+ Type[PromptCommand], Callable[..., Optional[PromptCommand]]
74
+ ] = {
75
+ ClarifyCommand: _parse_clarify_command,
76
+ SetSlotCommand: _parse_set_slot_command,
77
+ StartFlowCommand: _parse_start_flow_command,
78
+ }
79
+ return command_to_parsing_fn_mapper.get(command_clz)
80
+
81
+
82
+ def validate_custom_commands(command_classes: List[Type[PromptCommand]]) -> None:
83
+ clz_not_inheriting_from_command_clz = [
84
+ command_clz
85
+ for command_clz in command_classes
86
+ if not issubclass(command_clz, Command)
87
+ ]
88
+
89
+ if clz_not_inheriting_from_command_clz:
90
+ structlogger.error(
91
+ "command_parser.validate_custom_commands.invalid_command",
92
+ invalid_commands=clz_not_inheriting_from_command_clz,
93
+ event_info=(
94
+ "The additional command classes must be a subclass of the 'Command' "
95
+ "class. Please refer to the class in "
96
+ "`rasa.dialogue_understanding.commands.command.Command`"
97
+ ),
98
+ )
99
+ sys.exit(1)
100
+
101
+ clz_not_adhering_to_prompt_command_protocol = [
102
+ command_clz
103
+ for command_clz in command_classes
104
+ if not isinstance(command_clz, PromptCommand)
105
+ ]
106
+
107
+ if clz_not_adhering_to_prompt_command_protocol:
108
+ structlogger.error(
109
+ "command_parser.validate_custom_commands.invalid_command",
110
+ invalid_commands=clz_not_adhering_to_prompt_command_protocol,
111
+ event_info=(
112
+ "The additional command classes must adhere to the 'PromptCommand' "
113
+ "protocol. Please refer to the protocol in "
114
+ "`rasa.dialogue_understanding.commands.prompt_command.PromptCommand`"
115
+ ),
116
+ )
117
+ sys.exit(1)
118
+
119
+
120
+ def parse_commands(
121
+ actions: Optional[str],
122
+ flows: FlowsList,
123
+ is_handle_flows_prompt: bool = False,
124
+ additional_commands: Optional[List[Type[PromptCommand]]] = None,
125
+ default_commands_to_remove: Optional[
126
+ Union[List[Type[PromptCommand]], List[str]]
127
+ ] = None,
128
+ **kwargs: Any,
129
+ ) -> List[Command]:
130
+ """Parse a list of action commands."""
131
+ if not actions:
132
+ return []
133
+
134
+ commands: List[Command] = []
135
+ validate_custom_commands(additional_commands or [])
136
+
137
+ default_commands = DEFAULT_COMMANDS
138
+ if default_commands_to_remove:
139
+ default_commands = _create_default_commands(default_commands_to_remove)
140
+
141
+ for action in actions.strip().splitlines():
142
+ if is_handle_flows_prompt:
143
+ # Needed for multistep command generator.
144
+ if (
145
+ len(commands) >= 2
146
+ or len(commands) == 1
147
+ and isinstance(commands[0], ClarifyCommand)
148
+ ):
149
+ break
150
+ commands.extend(
151
+ _parse_standard_commands(default_commands, action.strip(), flows, **kwargs)
152
+ )
153
+ if additional_commands:
154
+ commands.extend(
155
+ _parse_custom_commands(
156
+ additional_commands, action.strip(), flows, **kwargs
157
+ )
158
+ )
159
+ return commands
160
+
161
+
162
+ def _parse_standard_commands(
163
+ standard_commands: List[Type[PromptCommand]],
164
+ action: str,
165
+ flows: FlowsList,
166
+ **kwargs: Any,
167
+ ) -> List[Command]:
168
+ """Parse predefined standard commands."""
169
+ commands: List[Command] = []
170
+ for command_clz in standard_commands:
171
+ pattern = _get_compiled_pattern(command_clz.regex_pattern())
172
+ if match := pattern.search(action):
173
+ parsed_command = command_clz.from_dsl(match, **kwargs)
174
+ if _additional_parsing_fn := _get_additional_parsing_logic(command_clz):
175
+ parsed_command = _additional_parsing_fn(parsed_command, flows, **kwargs)
176
+ if parsed_command:
177
+ commands.append(parsed_command)
178
+ return commands
179
+
180
+
181
+ def _parse_custom_commands(
182
+ custom_commands: List[Type[PromptCommand]],
183
+ action: str,
184
+ flows: FlowsList,
185
+ **kwargs: Any,
186
+ ) -> List[Command]:
187
+ """Parse custom commands."""
188
+ commands: List[Command] = []
189
+ for command_clz in custom_commands:
190
+ pattern = _get_compiled_pattern(command_clz.regex_pattern())
191
+ if match := pattern.search(action):
192
+ if parsed_command := command_clz.from_dsl(match, flows=flows, **kwargs):
193
+ commands.append(parsed_command)
194
+ return commands
195
+
196
+
197
+ def _parse_set_slot_command(
198
+ parsed_command: Optional[SetSlotCommand], flows: FlowsList, **kwargs: Any
199
+ ) -> Optional[PromptCommand]:
200
+ """Additional parsing logic for the SetSlotCommand."""
201
+ if not parsed_command:
202
+ return None
203
+ # error case where the llm tries to start a flow using a slot set
204
+ if parsed_command.name == "flow_name":
205
+ return start_flow_by_name(parsed_command.value, flows)
206
+ return parsed_command
207
+
208
+
209
+ def _parse_clarify_command(
210
+ parsed_command: Optional[ClarifyCommand], flows: FlowsList, **kwargs: Any
211
+ ) -> Optional[PromptCommand]:
212
+ """Additional parsing logic for the ClarifyCommand."""
213
+ if not parsed_command:
214
+ return None
215
+
216
+ # if no options are available
217
+ if not parsed_command.options:
218
+ # Return the command if options are optional; else, return an empty list
219
+ return (
220
+ ClarifyCommand([])
221
+ if kwargs.get("clarify_options_optional", False)
222
+ else None
223
+ )
224
+ valid_options = [
225
+ flow for flow in parsed_command.options if flow in flows.user_flow_ids
226
+ ]
227
+ unique_valid_options = list(set(valid_options))
228
+
229
+ # if there is only one valid option, start the flow
230
+ if len(unique_valid_options) == 1:
231
+ return start_flow_by_name(valid_options[0], flows)
232
+
233
+ # if there are multiple valid options, return a clarify command
234
+ if len(valid_options) > 1:
235
+ return ClarifyCommand(valid_options)
236
+ return None
237
+
238
+
239
+ def _parse_start_flow_command(
240
+ parsed_command: Optional[StartFlowCommand], flows: FlowsList, **kwargs: Any
241
+ ) -> Optional[PromptCommand]:
242
+ """Additional parsing logic for the StartFlowCommand."""
243
+ if not parsed_command:
244
+ return None
245
+ return start_flow_by_name(parsed_command.flow, flows)
@@ -1,7 +1,9 @@
1
1
  from rasa.shared.constants import (
2
- PROVIDER_CONFIG_KEY,
3
- OPENAI_PROVIDER,
2
+ MAX_TOKENS_CONFIG_KEY,
4
3
  MODEL_CONFIG_KEY,
4
+ OPENAI_PROVIDER,
5
+ PROVIDER_CONFIG_KEY,
6
+ TEMPERATURE_CONFIG_KEY,
5
7
  TIMEOUT_CONFIG_KEY,
6
8
  )
7
9
  from rasa.shared.utils.llm import (
@@ -12,8 +14,8 @@ from rasa.shared.utils.llm import (
12
14
  DEFAULT_LLM_CONFIG = {
13
15
  PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
14
16
  MODEL_CONFIG_KEY: DEFAULT_OPENAI_CHAT_MODEL_NAME_ADVANCED,
15
- "temperature": 0.0,
16
- "max_tokens": DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
17
+ TEMPERATURE_CONFIG_KEY: 0.0,
18
+ MAX_TOKENS_CONFIG_KEY: DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
17
19
  TIMEOUT_CONFIG_KEY: 7,
18
20
  }
19
21
 
@@ -25,3 +27,9 @@ FLOW_RETRIEVAL_ACTIVE_KEY = "active"
25
27
  FLOW_RETRIEVAL_EMBEDDINGS_CONFIG_KEY = "embeddings"
26
28
 
27
29
  FLOW_RETRIEVAL_FLOW_THRESHOLD = 20
30
+
31
+ COMMAND_PROMPT_FILE_NAME = "command_prompt.jinja2"
32
+ LLM_BASED_COMMAND_GENERATOR_CONFIG_FILE = "config.json"
33
+
34
+ MODEL_NAME_GPT_4O_2024_11_20 = "gpt-4o-2024-11-20"
35
+ MODEL_NAME_CLAUDE_3_5_SONNET_20240620 = "claude-3-5-sonnet-20240620"
@@ -18,7 +18,7 @@ flows within a conversational context.
18
18
  """
19
19
 
20
20
  import importlib
21
- from typing import Dict, Text, Any, List, Optional
21
+ from typing import Any, Dict, List, Optional, Text
22
22
 
23
23
  import structlog
24
24
  from jinja2 import Template
@@ -27,19 +27,19 @@ from langchain.schema.embeddings import Embeddings
27
27
  from langchain_community.vectorstores.faiss import FAISS
28
28
  from langchain_community.vectorstores.utils import DistanceStrategy
29
29
 
30
+ import rasa.shared.utils.io
30
31
  from rasa.engine.storage.resource import Resource
31
32
  from rasa.engine.storage.storage import ModelStorage
32
- import rasa.shared.utils.io
33
33
  from rasa.shared.constants import (
34
34
  EMBEDDINGS_CONFIG_KEY,
35
- PROVIDER_CONFIG_KEY,
36
35
  OPENAI_PROVIDER,
36
+ PROVIDER_CONFIG_KEY,
37
37
  )
38
38
  from rasa.shared.core.domain import Domain
39
39
  from rasa.shared.core.flows import FlowsList
40
40
  from rasa.shared.core.trackers import DialogueStateTracker
41
41
  from rasa.shared.exceptions import ProviderClientAPIException
42
- from rasa.shared.nlu.constants import TEXT, FLOWS_FROM_SEMANTIC_SEARCH
42
+ from rasa.shared.nlu.constants import FLOWS_FROM_SEMANTIC_SEARCH, TEXT
43
43
  from rasa.shared.nlu.training_data.message import Message
44
44
  from rasa.shared.providers.embedding._langchain_embedding_client_adapter import (
45
45
  _LangchainEmbeddingClientAdapter,
@@ -48,13 +48,13 @@ from rasa.shared.utils.health_check.embeddings_health_check_mixin import (
48
48
  EmbeddingsHealthCheckMixin,
49
49
  )
50
50
  from rasa.shared.utils.llm import (
51
- tracker_as_readable_transcript,
52
- embedder_factory,
53
51
  DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
54
52
  USER,
55
- get_prompt_template,
56
53
  allowed_values_for_slot,
54
+ embedder_factory,
55
+ get_prompt_template,
57
56
  resolve_model_client_config,
57
+ tracker_as_readable_transcript,
58
58
  )
59
59
 
60
60
  DEFAULT_FLOW_DOCUMENT_TEMPLATE = importlib.resources.read_text(
@@ -1,37 +1,43 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from functools import lru_cache
3
- from typing import Dict, Any, List, Optional, Tuple, Union, Text
3
+ from typing import Any, Dict, List, Optional, Set, Text, Tuple, Union
4
4
 
5
5
  import structlog
6
6
  from jinja2 import Template
7
7
 
8
+ import rasa.dialogue_understanding.generator.utils
8
9
  import rasa.shared.utils.io
9
10
  from rasa.dialogue_understanding.commands import (
10
11
  Command,
12
+ SetSlotCommand,
11
13
  StartFlowCommand,
12
14
  )
15
+ from rasa.dialogue_understanding.constants import KEY_MINIMIZE_NUM_CALLS
13
16
  from rasa.dialogue_understanding.generator import CommandGenerator
14
17
  from rasa.dialogue_understanding.generator.constants import (
15
18
  DEFAULT_LLM_CONFIG,
16
- LLM_CONFIG_KEY,
17
- FLOW_RETRIEVAL_KEY,
18
19
  FLOW_RETRIEVAL_ACTIVE_KEY,
19
20
  FLOW_RETRIEVAL_FLOW_THRESHOLD,
21
+ FLOW_RETRIEVAL_KEY,
22
+ LLM_CONFIG_KEY,
20
23
  )
21
24
  from rasa.dialogue_understanding.generator.flow_retrieval import FlowRetrieval
22
- from rasa.engine.graph import GraphComponent, ExecutionContext
25
+ from rasa.dialogue_understanding.stack.utils import top_flow_frame
26
+ from rasa.engine.graph import ExecutionContext, GraphComponent
23
27
  from rasa.engine.recipes.default_recipe import DefaultV1Recipe
24
28
  from rasa.engine.storage.resource import Resource
25
29
  from rasa.engine.storage.storage import ModelStorage
30
+ from rasa.shared.core.constants import SetSlotExtractor
26
31
  from rasa.shared.core.domain import Domain
27
- from rasa.shared.core.flows import FlowStep, Flow, FlowsList
32
+ from rasa.shared.core.flows import Flow, FlowsList, FlowStep
28
33
  from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
34
+ from rasa.shared.core.slot_mappings import SlotFillingManager
29
35
  from rasa.shared.core.trackers import DialogueStateTracker
30
- from rasa.shared.exceptions import FileIOException
31
- from rasa.shared.exceptions import ProviderClientAPIException
36
+ from rasa.shared.exceptions import FileIOException, ProviderClientAPIException
32
37
  from rasa.shared.nlu.constants import FLOWS_IN_PROMPT
33
38
  from rasa.shared.nlu.training_data.message import Message
34
39
  from rasa.shared.nlu.training_data.training_data import TrainingData
40
+ from rasa.shared.providers.llm.llm_response import LLMResponse, measure_llm_latency
35
41
  from rasa.shared.utils.health_check.llm_health_check_mixin import LLMHealthCheckMixin
36
42
  from rasa.shared.utils.llm import (
37
43
  allowed_values_for_slot,
@@ -169,7 +175,7 @@ class LLMBasedCommandGenerator(
169
175
  """
170
176
  self.perform_llm_health_check(
171
177
  self.config.get(LLM_CONFIG_KEY),
172
- DEFAULT_LLM_CONFIG,
178
+ self.get_default_llm_config(),
173
179
  "llm_based_command_generator.train",
174
180
  LLMBasedCommandGenerator.__name__,
175
181
  )
@@ -304,22 +310,33 @@ class LLMBasedCommandGenerator(
304
310
  )
305
311
  return filtered_flows
306
312
 
307
- async def invoke_llm(self, prompt: Text) -> Optional[Text]:
313
+ @measure_llm_latency
314
+ async def invoke_llm(
315
+ self, prompt: Union[List[dict], List[str], str]
316
+ ) -> Optional[LLMResponse]:
308
317
  """Use LLM to generate a response.
309
318
 
310
319
  Args:
311
- prompt: The prompt to send to the LLM.
320
+ prompt: The prompt can be,
321
+ - a list of preformatted messages. Each message should be a dictionary
322
+ with the following keys:
323
+ - content: The message content.
324
+ - role: The role of the message (e.g. user or system).
325
+ - a list of messages. Each message is a string and will be formatted
326
+ as a user message.
327
+ - a single message as a string which will be formatted as user message.
312
328
 
313
329
  Returns:
314
- The generated text.
330
+ An LLMResponse object.
315
331
 
316
332
  Raises:
317
- ProviderClientAPIException if an error during API call.
333
+ ProviderClientAPIException: If an error occurs during the LLM API call.
318
334
  """
319
- llm = llm_factory(self.config.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG)
335
+ llm = llm_factory(
336
+ self.config.get(LLM_CONFIG_KEY), self.get_default_llm_config()
337
+ )
320
338
  try:
321
- llm_response = await llm.acompletion(prompt)
322
- return llm_response.choices[0]
339
+ return await llm.acompletion(prompt)
323
340
  except Exception as e:
324
341
  # unfortunately, langchain does not wrap LLM exceptions which means
325
342
  # we have to catch all exceptions here
@@ -328,50 +345,6 @@ class LLMBasedCommandGenerator(
328
345
  message="LLM call exception", original_exception=e
329
346
  )
330
347
 
331
- @staticmethod
332
- def start_flow_by_name(flow_name: str, flows: FlowsList) -> List[Command]:
333
- """Start a flow by name.
334
-
335
- If the flow does not exist, no command is returned.
336
- """
337
- if flow_name in flows.user_flow_ids:
338
- return [StartFlowCommand(flow=flow_name)]
339
- else:
340
- structlogger.debug(
341
- "llm_command_generator.flow.start_invalid_flow_id", flow=flow_name
342
- )
343
- return []
344
-
345
- @staticmethod
346
- def is_none_value(value: str) -> bool:
347
- """Check if the value is a none value."""
348
- return value in {
349
- "[missing information]",
350
- "[missing]",
351
- "None",
352
- "undefined",
353
- "null",
354
- }
355
-
356
- @staticmethod
357
- def clean_extracted_value(value: str) -> str:
358
- """Clean up the extracted value from the llm."""
359
- # replace any combination of single quotes, double quotes, and spaces
360
- # from the beginning and end of the string
361
- return value.strip("'\" ")
362
-
363
- @classmethod
364
- def get_nullable_slot_value(cls, slot_value: str) -> Union[str, None]:
365
- """Get the slot value or None if the value is a none value.
366
-
367
- Args:
368
- slot_value: the value to coerce
369
-
370
- Returns:
371
- The slot value or None if the value is a none value.
372
- """
373
- return slot_value if not cls.is_none_value(slot_value) else None
374
-
375
348
  def prepare_flows_for_template(
376
349
  self, flows: FlowsList, tracker: DialogueStateTracker
377
350
  ) -> List[Dict[str, Any]]:
@@ -498,3 +471,158 @@ class LLMBasedCommandGenerator(
498
471
  if isinstance(current_step, CollectInformationFlowStep)
499
472
  else (None, None)
500
473
  )
474
+
475
+ @staticmethod
476
+ def _prior_commands_contain_start_flow(prior_commands: List[Command]) -> bool:
477
+ return any(isinstance(command, StartFlowCommand) for command in prior_commands)
478
+
479
+ @staticmethod
480
+ def _prior_commands_contain_set_slot_for_active_collect_step(
481
+ prior_commands: List[Command],
482
+ flows: FlowsList,
483
+ tracker: DialogueStateTracker,
484
+ ) -> bool:
485
+ latest_user_frame = top_flow_frame(tracker.stack, ignore_call_frames=False)
486
+
487
+ if latest_user_frame is None:
488
+ return False
489
+
490
+ active_flow = latest_user_frame.flow(flows)
491
+ active_step = active_flow.step_by_id(latest_user_frame.step_id)
492
+
493
+ if not isinstance(active_step, CollectInformationFlowStep):
494
+ return False
495
+
496
+ return any(
497
+ command.name == active_step.collect
498
+ for command in prior_commands
499
+ if isinstance(command, SetSlotCommand)
500
+ )
501
+
502
+ def _should_skip_llm_call(
503
+ self,
504
+ prior_commands: List[Command],
505
+ flows: FlowsList,
506
+ tracker: DialogueStateTracker,
507
+ ) -> bool:
508
+ """Skip invoking the LLM.
509
+
510
+ This returns True if the bot builder sets the property
511
+ KEY_MINIMIZE_NUM_CALLS to True and the prior commands
512
+ either contain a StartFlowCommand or a SetSlot command
513
+ for the current collect step.
514
+ """
515
+ return self.config.get(KEY_MINIMIZE_NUM_CALLS, False) and (
516
+ self._prior_commands_contain_start_flow(prior_commands)
517
+ or self._prior_commands_contain_set_slot_for_active_collect_step(
518
+ prior_commands, flows, tracker
519
+ )
520
+ )
521
+
522
+ @staticmethod
523
+ def _check_commands_against_slot_mappings(
524
+ commands: List[Command],
525
+ tracker: DialogueStateTracker,
526
+ domain: Optional[Domain] = None,
527
+ ) -> List[Command]:
528
+ """Check if the LLM-issued slot commands are fillable.
529
+
530
+ The LLM-issued slot commands are fillable if the slot
531
+ mappings are satisfied (in particular the mapping conditions).
532
+ """
533
+ if not domain:
534
+ return commands
535
+
536
+ llm_fillable_slots = [
537
+ tracker.slots.get(command.name)
538
+ for command in commands
539
+ if isinstance(command, SetSlotCommand)
540
+ and command.extractor == SetSlotExtractor.LLM.value
541
+ and tracker.slots.get(command.name) is not None
542
+ ]
543
+
544
+ if not llm_fillable_slots:
545
+ return commands
546
+
547
+ slot_filling_manager = SlotFillingManager(domain, tracker)
548
+ slots_to_be_removed = []
549
+
550
+ structlogger.debug(
551
+ "command_processor.check_commands_against_slot_mappings.active_flow",
552
+ active_flow=tracker.active_flow,
553
+ )
554
+
555
+ for slot in llm_fillable_slots:
556
+ should_fill_slot = False
557
+ for mapping in slot.mappings: # type: ignore[union-attr]
558
+ should_fill_slot = slot_filling_manager.should_fill_slot(
559
+ slot.name, # type: ignore[union-attr]
560
+ mapping,
561
+ )
562
+
563
+ if should_fill_slot:
564
+ break
565
+
566
+ if not should_fill_slot:
567
+ structlogger.debug(
568
+ "command_processor.check_commands_against_slot_mappings.slot_not_fillable",
569
+ slot_name=slot.name, # type: ignore[union-attr]
570
+ )
571
+ slots_to_be_removed.append(slot.name) # type: ignore[union-attr]
572
+
573
+ if not slots_to_be_removed:
574
+ return commands
575
+
576
+ filtered_commands = [
577
+ command
578
+ for command in commands
579
+ if not (
580
+ isinstance(command, SetSlotCommand)
581
+ and command.name in slots_to_be_removed
582
+ )
583
+ ]
584
+
585
+ return filtered_commands
586
+
587
+ def _check_start_flow_command_overlap(
588
+ self,
589
+ prior_commands: List[Command],
590
+ commands: List[Command],
591
+ prior_start_flow_names: Set[str],
592
+ current_start_flow_names: Set[str],
593
+ ) -> List[Command]:
594
+ """Prioritize the prior commands over the LLM-issued commands."""
595
+ different_flow_names = current_start_flow_names.difference(
596
+ prior_start_flow_names
597
+ )
598
+
599
+ if not different_flow_names:
600
+ return prior_commands + commands
601
+
602
+ # discard the flow names that are different to prior start flow commands
603
+ filtered_commands = [
604
+ command
605
+ for command in commands
606
+ if not isinstance(command, StartFlowCommand)
607
+ or command.flow not in different_flow_names
608
+ ]
609
+ return prior_commands + filtered_commands
610
+
611
+ def _filter_slot_commands(
612
+ self,
613
+ prior_commands: List[Command],
614
+ commands: List[Command],
615
+ overlapping_slot_names: Set[str],
616
+ ) -> Tuple[List[Command], List[Command]]:
617
+ """Prioritize prior commands over LLM ones in the case of same slot."""
618
+ filtered_commands = (
619
+ rasa.dialogue_understanding.generator.utils.filter_slot_commands(
620
+ commands, overlapping_slot_names
621
+ )
622
+ )
623
+ return prior_commands, filtered_commands
624
+
625
+ @staticmethod
626
+ def get_default_llm_config() -> Dict[str, Any]:
627
+ """Get the default LLM config for the command generator."""
628
+ return DEFAULT_LLM_CONFIG
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, Optional, Text
1
+ from typing import Any, Dict, List, Optional, Text, Union
2
2
 
3
3
  import structlog
4
4
  from deprecated import deprecated # type: ignore[import]
@@ -10,6 +10,7 @@ from rasa.engine.recipes.default_recipe import DefaultV1Recipe
10
10
  from rasa.engine.storage.resource import Resource
11
11
  from rasa.engine.storage.storage import ModelStorage
12
12
  from rasa.shared.exceptions import ProviderClientAPIException
13
+ from rasa.shared.providers.llm.llm_response import LLMResponse
13
14
  from rasa.shared.utils.io import raise_deprecation_warning
14
15
 
15
16
  structlogger = structlog.get_logger()
@@ -24,7 +25,7 @@ structlogger = structlog.get_logger()
24
25
  @deprecated(
25
26
  reason=(
26
27
  "The LLMCommandGenerator is deprecated and will be removed in Rasa 4.0.0. "
27
- "Please use use SingleStepLLMCommandGenerator instead."
28
+ "Please use SingleStepLLMCommandGenerator instead."
28
29
  )
29
30
  )
30
31
  class LLMCommandGenerator(SingleStepLLMCommandGenerator):
@@ -53,7 +54,9 @@ class LLMCommandGenerator(SingleStepLLMCommandGenerator):
53
54
  **kwargs,
54
55
  )
55
56
 
56
- async def invoke_llm(self, prompt: Text) -> Optional[Text]:
57
+ async def invoke_llm(
58
+ self, prompt: Union[List[dict], List[str], str]
59
+ ) -> Optional[LLMResponse]:
57
60
  try:
58
61
  return await super().invoke_llm(prompt)
59
62
  except ProviderClientAPIException: