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,574 @@
1
+ import copy
2
+ from typing import Any, Dict, List, Optional, Text
3
+
4
+ import structlog
5
+
6
+ import rasa.shared.utils.io
7
+ from rasa.dialogue_understanding.commands import (
8
+ CannotHandleCommand,
9
+ Command,
10
+ ErrorCommand,
11
+ SetSlotCommand,
12
+ )
13
+ from rasa.dialogue_understanding.commands.command_syntax_manager import (
14
+ CommandSyntaxManager,
15
+ CommandSyntaxVersion,
16
+ )
17
+ from rasa.dialogue_understanding.generator import LLMBasedCommandGenerator
18
+ from rasa.dialogue_understanding.generator.command_parser import (
19
+ parse_commands as parse_commands_using_command_parsers,
20
+ )
21
+ from rasa.dialogue_understanding.generator.constants import (
22
+ COMMAND_PROMPT_FILE_NAME,
23
+ DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
24
+ FLOW_RETRIEVAL_KEY,
25
+ LLM_BASED_COMMAND_GENERATOR_CONFIG_FILE,
26
+ LLM_CONFIG_KEY,
27
+ MODEL_CONFIG_KEY,
28
+ MODEL_NAME_CLAUDE_3_5_SONNET_20240620,
29
+ MODEL_NAME_GPT_4O_2024_11_20,
30
+ OPENAI_PROVIDER,
31
+ PROVIDER_CONFIG_KEY,
32
+ TIMEOUT_CONFIG_KEY,
33
+ USER_INPUT_CONFIG_KEY,
34
+ )
35
+ from rasa.dialogue_understanding.generator.flow_retrieval import FlowRetrieval
36
+ from rasa.dialogue_understanding.stack.utils import top_flow_frame
37
+ from rasa.dialogue_understanding.utils import (
38
+ add_commands_to_message_parse_data,
39
+ add_prompt_to_message_parse_data,
40
+ )
41
+ from rasa.engine.graph import ExecutionContext
42
+ from rasa.engine.recipes.default_recipe import DefaultV1Recipe
43
+ from rasa.engine.storage.resource import Resource
44
+ from rasa.engine.storage.storage import ModelStorage
45
+ from rasa.shared.constants import (
46
+ ANTHROPIC_PROVIDER,
47
+ AWS_BEDROCK_PROVIDER,
48
+ AZURE_OPENAI_PROVIDER,
49
+ EMBEDDINGS_CONFIG_KEY,
50
+ MAX_TOKENS_CONFIG_KEY,
51
+ PROMPT_TEMPLATE_CONFIG_KEY,
52
+ ROUTE_TO_CALM_SLOT,
53
+ TEMPERATURE_CONFIG_KEY,
54
+ )
55
+ from rasa.shared.core.flows import FlowsList
56
+ from rasa.shared.core.trackers import DialogueStateTracker
57
+ from rasa.shared.exceptions import ProviderClientAPIException
58
+ from rasa.shared.nlu.constants import LLM_COMMANDS, LLM_PROMPT, TEXT
59
+ from rasa.shared.nlu.training_data.message import Message
60
+ from rasa.shared.providers.llm.llm_response import LLMResponse
61
+ from rasa.shared.utils.io import deep_container_fingerprint
62
+ from rasa.shared.utils.llm import (
63
+ allowed_values_for_slot,
64
+ get_default_prompt_template_based_on_model,
65
+ get_prompt_template,
66
+ resolve_model_client_config,
67
+ sanitize_message_for_prompt,
68
+ tracker_as_readable_transcript,
69
+ )
70
+ from rasa.utils.beta import BetaNotEnabledException, ensure_beta_feature_is_enabled
71
+ from rasa.utils.log_utils import log_llm
72
+
73
+ structlogger = structlog.get_logger()
74
+
75
+
76
+ DEFAULT_LLM_CONFIG = {
77
+ PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
78
+ MODEL_CONFIG_KEY: MODEL_NAME_GPT_4O_2024_11_20,
79
+ TEMPERATURE_CONFIG_KEY: 0.0,
80
+ MAX_TOKENS_CONFIG_KEY: DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
81
+ TIMEOUT_CONFIG_KEY: 7,
82
+ }
83
+
84
+ MODEL_PROMPT_MAPPER = {
85
+ f"{OPENAI_PROVIDER}/{MODEL_NAME_GPT_4O_2024_11_20}": (
86
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
87
+ ),
88
+ f"{AZURE_OPENAI_PROVIDER}/{MODEL_NAME_GPT_4O_2024_11_20}": (
89
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
90
+ ),
91
+ f"{AWS_BEDROCK_PROVIDER}/anthropic.{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}-v1:0": (
92
+ "command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2"
93
+ ),
94
+ f"{ANTHROPIC_PROVIDER}/{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}": (
95
+ "command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2"
96
+ ),
97
+ }
98
+
99
+ # When model is not configured, then we use the default prompt template
100
+ DEFAULT_COMMAND_PROMPT_TEMPLATE_FILE_NAME = (
101
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
102
+ )
103
+ # When the configured model is not found in the model prompt mapper, then we use the
104
+ # fallback prompt template
105
+ FALLBACK_COMMAND_PROMPT_TEMPLATE_FILE_NAME = (
106
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
107
+ )
108
+
109
+
110
+ class CommandParserValidatorSingleton:
111
+ """Singleton class to validate the command parser.
112
+
113
+ This class is used to validate the command parser. It keeps track of the number of
114
+ consecutive turns where no commands are parsed by the command parser. If the
115
+ number of consecutive turns exceeds a certain threshold, a warning is logged.
116
+ The prompt can use a DSL syntax that can be incompatible with the command syntax
117
+ used by the command parser. This class helps to detect such incompatibilities.
118
+ """
119
+
120
+ MAX_CONSECUTIVE_TURNS_NO_COMMAND_PREDICTED = 5
121
+ _NO_COMMAND_PREDICTED_TURN_COUNTER = 0
122
+ _command_parser_validated = False
123
+
124
+ @classmethod
125
+ def get_no_command_predicted_turn_counter(cls) -> int:
126
+ return cls._NO_COMMAND_PREDICTED_TURN_COUNTER
127
+
128
+ @classmethod
129
+ def should_validate_command_parser(cls) -> bool:
130
+ return not cls._command_parser_validated
131
+
132
+ @classmethod
133
+ def reset_command_parser_validation(cls) -> None:
134
+ cls._NO_COMMAND_PREDICTED_TURN_COUNTER = 0
135
+ cls._command_parser_validated = False
136
+
137
+ @classmethod
138
+ def validate_if_commands_are_parsed_from_llm_response(
139
+ cls, commands: List[Command], llm_response: str
140
+ ) -> None:
141
+ if llm_response and not commands:
142
+ cls._NO_COMMAND_PREDICTED_TURN_COUNTER += 1
143
+ else:
144
+ # Reset the counter if commands are generated, and mark
145
+ # the command parser as validated.
146
+ cls._NO_COMMAND_PREDICTED_TURN_COUNTER = 0
147
+ cls._command_parser_validated = True
148
+ return
149
+
150
+ if (
151
+ cls._NO_COMMAND_PREDICTED_TURN_COUNTER
152
+ >= cls.MAX_CONSECUTIVE_TURNS_NO_COMMAND_PREDICTED
153
+ ):
154
+ structlogger.warning(
155
+ "llm_command_generator.predict_commands.command_parser_not_working",
156
+ event_info=(
157
+ f"No commands were generated by the command parser for the last "
158
+ f"{cls._NO_COMMAND_PREDICTED_TURN_COUNTER} times. Check if you "
159
+ "are running incompatible prompt and LLM command generator."
160
+ ),
161
+ )
162
+
163
+
164
+ @DefaultV1Recipe.register(
165
+ [
166
+ DefaultV1Recipe.ComponentType.COMMAND_GENERATOR,
167
+ ],
168
+ is_trainable=True,
169
+ )
170
+ class CompactLLMCommandGenerator(LLMBasedCommandGenerator):
171
+ """A single step LLM-based command generator."""
172
+
173
+ def __init__(
174
+ self,
175
+ config: Dict[str, Any],
176
+ model_storage: ModelStorage,
177
+ resource: Resource,
178
+ prompt_template: Optional[Text] = None,
179
+ **kwargs: Any,
180
+ ) -> None:
181
+ super().__init__(
182
+ config,
183
+ model_storage,
184
+ resource,
185
+ prompt_template=prompt_template,
186
+ **kwargs,
187
+ )
188
+
189
+ # Get the prompt template from the config or the default prompt template.
190
+ self.prompt_template = self.resolve_component_prompt_template(
191
+ self.config, prompt_template
192
+ )
193
+
194
+ # Set the command syntax version to v2
195
+ CommandSyntaxManager.set_syntax_version(
196
+ self.get_component_command_syntax_version()
197
+ )
198
+
199
+ self.trace_prompt_tokens = self.config.get("trace_prompt_tokens", False)
200
+ self.repeat_command_enabled = self.is_repeat_command_enabled()
201
+
202
+ ### Implementations of LLMBasedCommandGenerator parent
203
+ @staticmethod
204
+ def get_default_config() -> Dict[str, Any]:
205
+ """The component's default config (see parent class for full docstring)."""
206
+ return {
207
+ PROMPT_TEMPLATE_CONFIG_KEY: None,
208
+ USER_INPUT_CONFIG_KEY: None,
209
+ LLM_CONFIG_KEY: None,
210
+ FLOW_RETRIEVAL_KEY: FlowRetrieval.get_default_config(),
211
+ }
212
+
213
+ def persist(self) -> None:
214
+ """Persist this component to disk for future loading."""
215
+ self._persist_prompt_template()
216
+ self._persist_config()
217
+ if self.flow_retrieval is not None:
218
+ self.flow_retrieval.persist()
219
+
220
+ def _persist_prompt_template(self) -> None:
221
+ """Persist prompt template for future loading."""
222
+ with self._model_storage.write_to(self._resource) as path:
223
+ rasa.shared.utils.io.write_text_file(
224
+ self.prompt_template, path / COMMAND_PROMPT_FILE_NAME
225
+ )
226
+
227
+ def _persist_config(self) -> None:
228
+ """Persist config as a source of truth for resolved clients."""
229
+ with self._model_storage.write_to(self._resource) as path:
230
+ rasa.shared.utils.io.dump_obj_as_json_to_file(
231
+ path / LLM_BASED_COMMAND_GENERATOR_CONFIG_FILE, self.config
232
+ )
233
+
234
+ @classmethod
235
+ def load(
236
+ cls: Any,
237
+ config: Dict[str, Any],
238
+ model_storage: ModelStorage,
239
+ resource: Resource,
240
+ execution_context: ExecutionContext,
241
+ **kwargs: Any,
242
+ ) -> "CompactLLMCommandGenerator":
243
+ """Loads trained component (see parent class for full docstring)."""
244
+ # Perform health check of the LLM API endpoint
245
+ llm_config = resolve_model_client_config(config.get(LLM_CONFIG_KEY, {}))
246
+ cls.perform_llm_health_check(
247
+ llm_config,
248
+ cls.get_default_llm_config(),
249
+ "compact_llm_command_generator.load",
250
+ cls.__name__,
251
+ )
252
+
253
+ # load prompt template from the model storage.
254
+ prompt_template = cls.load_prompt_template_from_model_storage(
255
+ model_storage, resource, COMMAND_PROMPT_FILE_NAME
256
+ )
257
+
258
+ # init base command generator
259
+ command_generator = cls(config, model_storage, resource, prompt_template)
260
+ # load flow retrieval if enabled
261
+ if command_generator.enabled_flow_retrieval:
262
+ command_generator.flow_retrieval = cls.load_flow_retrival(
263
+ command_generator.config, model_storage, resource
264
+ )
265
+
266
+ return command_generator
267
+
268
+ async def predict_commands(
269
+ self,
270
+ message: Message,
271
+ flows: FlowsList,
272
+ tracker: Optional[DialogueStateTracker] = None,
273
+ **kwargs: Any,
274
+ ) -> List[Command]:
275
+ """Predict commands using the LLM.
276
+
277
+ Args:
278
+ message: The message from the user.
279
+ flows: The flows available to the user.
280
+ tracker: The tracker containing the current state of the conversation.
281
+ **kwargs: Keyword arguments for forward compatibility.
282
+
283
+ Returns:
284
+ The commands generated by the llm.
285
+ """
286
+ prior_commands = self._get_prior_commands(message)
287
+
288
+ if tracker is None or flows.is_empty():
289
+ # cannot do anything if there are no flows or no tracker
290
+ return prior_commands
291
+
292
+ if self._should_skip_llm_call(prior_commands, flows, tracker):
293
+ return prior_commands
294
+
295
+ try:
296
+ commands = await self._predict_commands(message, flows, tracker)
297
+ except ProviderClientAPIException:
298
+ # if command predictions resulted in API exception
299
+ # "predict" the ErrorCommand
300
+ commands = [ErrorCommand()]
301
+ structlogger.warning(
302
+ "llm_command_generator.predict_commands.api_exception",
303
+ event_info=(
304
+ "ProviderClientAPIException occurred while predicting commands."
305
+ ),
306
+ commands=commands,
307
+ )
308
+
309
+ if not commands and not prior_commands:
310
+ # no commands are parsed or there's an invalid command
311
+ structlogger.warning(
312
+ "llm_command_generator.predict_commands",
313
+ message="No commands were predicted as the LLM response could "
314
+ "not be parsed or the LLM responded with an invalid command. "
315
+ "Returning a CannotHandleCommand instead.",
316
+ )
317
+ commands = [CannotHandleCommand()]
318
+
319
+ if tracker.has_coexistence_routing_slot:
320
+ # if coexistence feature is used, set the routing slot
321
+ commands += [SetSlotCommand(ROUTE_TO_CALM_SLOT, True)]
322
+
323
+ log_llm(
324
+ logger=structlogger,
325
+ log_module=self.__class__.__name__,
326
+ log_event="llm_command_generator.predict_commands.finished",
327
+ commands=commands,
328
+ )
329
+
330
+ domain = kwargs.get("domain")
331
+ commands = self._check_commands_against_slot_mappings(commands, tracker, domain)
332
+
333
+ return self._check_commands_overlap(prior_commands, commands)
334
+
335
+ async def _predict_commands(
336
+ self,
337
+ message: Message,
338
+ flows: FlowsList,
339
+ tracker: Optional[DialogueStateTracker] = None,
340
+ ) -> List[Command]:
341
+ """Predict commands using the LLM.
342
+
343
+ Args:
344
+ message: The message from the user.
345
+ flows: The flows available to the user.
346
+ tracker: The tracker containing the current state of the conversation.
347
+
348
+ Returns:
349
+ The commands generated by the llm.
350
+
351
+ Raises:
352
+ ProviderClientAPIException: If API calls raised an error.
353
+ """
354
+ # retrieve flows
355
+ filtered_flows = await self.filter_flows(message, flows, tracker)
356
+
357
+ flow_prompt = self.render_template(message, tracker, filtered_flows, flows)
358
+ log_llm(
359
+ logger=structlogger,
360
+ log_module=self.__class__.__name__,
361
+ log_event="llm_command_generator.predict_commands.prompt_rendered",
362
+ prompt=flow_prompt,
363
+ )
364
+
365
+ response = await self.invoke_llm(flow_prompt)
366
+ llm_response = LLMResponse.ensure_llm_response(response)
367
+ # The check for 'None' maintains compatibility with older versions
368
+ # of LLMCommandGenerator. In previous implementations, 'invoke_llm'
369
+ # might return 'None' to indicate a failure to generate actions.
370
+ if llm_response is None or not llm_response.choices:
371
+ structlogger.warning(
372
+ "llm_command_generator.predict_commands.no_actions_generated",
373
+ event_info=(
374
+ "No actions were generated by the LLM. Returning an ErrorCommand."
375
+ ),
376
+ )
377
+ return [ErrorCommand()]
378
+
379
+ action_list = llm_response.choices[0]
380
+
381
+ log_llm(
382
+ logger=structlogger,
383
+ log_module=self.__class__.__name__,
384
+ log_event="llm_command_generator.predict_commands.actions_generated",
385
+ action_list=action_list,
386
+ )
387
+
388
+ commands = self.parse_commands(action_list, tracker, flows)
389
+
390
+ if CommandParserValidatorSingleton.should_validate_command_parser():
391
+ CommandParserValidatorSingleton.validate_if_commands_are_parsed_from_llm_response(
392
+ commands, action_list
393
+ )
394
+
395
+ self._update_message_parse_data_for_fine_tuning(message, commands, flow_prompt)
396
+ add_commands_to_message_parse_data(message, self.__class__.__name__, commands)
397
+ add_prompt_to_message_parse_data(
398
+ message=message,
399
+ component_name=self.__class__.__name__,
400
+ prompt_name="command_generator_prompt",
401
+ user_prompt=flow_prompt,
402
+ llm_response=llm_response,
403
+ )
404
+
405
+ return commands
406
+
407
+ @staticmethod
408
+ def _update_message_parse_data_for_fine_tuning(
409
+ message: Message, commands: List[Command], prompt: str
410
+ ) -> None:
411
+ from rasa.llm_fine_tuning.annotation_module import preparing_fine_tuning_data
412
+
413
+ if preparing_fine_tuning_data:
414
+ # Add commands and prompt to the message object in order to create
415
+ # prompt -> commands pairs for fine-tuning
416
+ message.set(
417
+ LLM_COMMANDS,
418
+ [command.as_dict() for command in commands],
419
+ add_to_output=True,
420
+ )
421
+ message.set(LLM_PROMPT, prompt, add_to_output=True)
422
+
423
+ @classmethod
424
+ def parse_commands(
425
+ cls, actions: Optional[str], tracker: DialogueStateTracker, flows: FlowsList
426
+ ) -> List[Command]:
427
+ """Parse the actions returned by the llm into intent and entities.
428
+
429
+ Args:
430
+ actions: The actions returned by the llm.
431
+ tracker: The tracker containing the current state of the conversation.
432
+ flows: the list of flows
433
+
434
+ Returns:
435
+ The parsed commands.
436
+ """
437
+ commands = parse_commands_using_command_parsers(actions, flows)
438
+ if not commands:
439
+ structlogger.warning(
440
+ f"{cls.__name__}.parse_commands",
441
+ message="No commands were parsed from the LLM actions.",
442
+ actions=actions,
443
+ )
444
+
445
+ return commands
446
+
447
+ ### Helper methods
448
+ def render_template(
449
+ self,
450
+ message: Message,
451
+ tracker: DialogueStateTracker,
452
+ startable_flows: FlowsList,
453
+ all_flows: FlowsList,
454
+ ) -> str:
455
+ """Render the jinja template to create the prompt for the LLM.
456
+
457
+ Args:
458
+ message: The current message from the user.
459
+ tracker: The tracker containing the current state of the conversation.
460
+ startable_flows: The flows startable at this point in time by the user.
461
+ all_flows: all flows present in the assistant
462
+
463
+ Returns:
464
+ The rendered prompt template.
465
+ """
466
+ # need to make this distinction here because current step of the
467
+ # top_calling_frame would be the call step, but we need the collect step from
468
+ # the called frame. If no call is active calling and called frame are the same.
469
+ top_calling_frame = top_flow_frame(tracker.stack)
470
+ top_called_frame = top_flow_frame(tracker.stack, ignore_call_frames=False)
471
+
472
+ top_flow = top_calling_frame.flow(all_flows) if top_calling_frame else None
473
+ current_step = top_called_frame.step(all_flows) if top_called_frame else None
474
+
475
+ flow_slots = self.prepare_current_flow_slots_for_template(
476
+ top_flow, current_step, tracker
477
+ )
478
+ current_slot, current_slot_description = self.prepare_current_slot_for_template(
479
+ current_step
480
+ )
481
+ current_slot_type = None
482
+ current_slot_allowed_values = None
483
+ if current_slot:
484
+ current_slot_type = (
485
+ slot.type_name
486
+ if (slot := tracker.slots.get(current_slot)) is not None
487
+ else None
488
+ )
489
+ current_slot_allowed_values = allowed_values_for_slot(
490
+ tracker.slots.get(current_slot)
491
+ )
492
+ current_conversation = tracker_as_readable_transcript(tracker)
493
+ latest_user_message = sanitize_message_for_prompt(message.get(TEXT))
494
+ current_conversation += f"\nUSER: {latest_user_message}"
495
+
496
+ inputs = {
497
+ "available_flows": self.prepare_flows_for_template(
498
+ startable_flows, tracker
499
+ ),
500
+ "current_conversation": current_conversation,
501
+ "flow_slots": flow_slots,
502
+ "current_flow": top_flow.id if top_flow is not None else None,
503
+ "current_slot": current_slot,
504
+ "current_slot_description": current_slot_description,
505
+ "current_slot_type": current_slot_type,
506
+ "current_slot_allowed_values": current_slot_allowed_values,
507
+ "user_message": latest_user_message,
508
+ "is_repeat_command_enabled": self.repeat_command_enabled,
509
+ }
510
+
511
+ return self.compile_template(self.prompt_template).render(**inputs)
512
+
513
+ def is_repeat_command_enabled(self) -> bool:
514
+ """Check for feature flag"""
515
+ RASA_PRO_BETA_REPEAT_COMMAND_ENV_VAR_NAME = "RASA_PRO_BETA_REPEAT_COMMAND"
516
+ try:
517
+ ensure_beta_feature_is_enabled(
518
+ "Repeat Command",
519
+ env_flag=RASA_PRO_BETA_REPEAT_COMMAND_ENV_VAR_NAME,
520
+ )
521
+ except BetaNotEnabledException:
522
+ return False
523
+
524
+ return True
525
+
526
+ @classmethod
527
+ def fingerprint_addon(cls: Any, config: Dict[str, Any]) -> Optional[str]:
528
+ """Add a fingerprint for the graph."""
529
+ # Get the default prompt template based on the model name
530
+ llm_config = resolve_model_client_config(
531
+ config.get(LLM_CONFIG_KEY), CompactLLMCommandGenerator.__name__
532
+ )
533
+ embedding_config = resolve_model_client_config(
534
+ config.get(FLOW_RETRIEVAL_KEY, {}).get(EMBEDDINGS_CONFIG_KEY),
535
+ FlowRetrieval.__name__,
536
+ )
537
+
538
+ # Create a copy of the config to avoid modifying the original config
539
+ # and update the llm config with the resolved llm config.
540
+ _config_copy = copy.deepcopy(config)
541
+ _config_copy[LLM_CONFIG_KEY] = llm_config
542
+ prompt_template = cls.resolve_component_prompt_template(_config_copy)
543
+
544
+ return deep_container_fingerprint(
545
+ [prompt_template, llm_config, embedding_config]
546
+ )
547
+
548
+ @staticmethod
549
+ def get_default_llm_config() -> Dict[str, Any]:
550
+ """Get the default LLM config for the command generator."""
551
+ return DEFAULT_LLM_CONFIG
552
+
553
+ @staticmethod
554
+ def get_component_command_syntax_version() -> CommandSyntaxVersion:
555
+ return CommandSyntaxVersion.v2
556
+
557
+ @staticmethod
558
+ def resolve_component_prompt_template(
559
+ config: Dict[str, Any], prompt_template: Optional[str] = None
560
+ ) -> Optional[str]:
561
+ """Get the prompt template from the config or the default prompt template."""
562
+ # Get the default prompt template based on the model name.
563
+ default_command_prompt_template = get_default_prompt_template_based_on_model(
564
+ config.get(LLM_CONFIG_KEY, {}) or {},
565
+ MODEL_PROMPT_MAPPER,
566
+ DEFAULT_COMMAND_PROMPT_TEMPLATE_FILE_NAME,
567
+ FALLBACK_COMMAND_PROMPT_TEMPLATE_FILE_NAME,
568
+ )
569
+
570
+ # Return the prompt template either from the config or the default prompt.
571
+ return prompt_template or get_prompt_template(
572
+ config.get(PROMPT_TEMPLATE_CONFIG_KEY),
573
+ default_command_prompt_template,
574
+ )