rasa-pro 3.14.0a20__py3-none-any.whl → 3.14.0a23__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 (331) hide show
  1. rasa/__main__.py +15 -3
  2. rasa/agents/__init__.py +0 -0
  3. rasa/agents/agent_factory.py +122 -0
  4. rasa/agents/agent_manager.py +211 -0
  5. rasa/agents/constants.py +43 -0
  6. rasa/agents/core/__init__.py +0 -0
  7. rasa/agents/core/agent_protocol.py +107 -0
  8. rasa/agents/core/types.py +81 -0
  9. rasa/agents/exceptions.py +38 -0
  10. rasa/agents/protocol/__init__.py +5 -0
  11. rasa/agents/protocol/a2a/__init__.py +0 -0
  12. rasa/agents/protocol/a2a/a2a_agent.py +879 -0
  13. rasa/agents/protocol/mcp/__init__.py +0 -0
  14. rasa/agents/protocol/mcp/mcp_base_agent.py +726 -0
  15. rasa/agents/protocol/mcp/mcp_open_agent.py +327 -0
  16. rasa/agents/protocol/mcp/mcp_task_agent.py +522 -0
  17. rasa/agents/schemas/__init__.py +13 -0
  18. rasa/agents/schemas/agent_input.py +38 -0
  19. rasa/agents/schemas/agent_output.py +26 -0
  20. rasa/agents/schemas/agent_tool_result.py +65 -0
  21. rasa/agents/schemas/agent_tool_schema.py +186 -0
  22. rasa/agents/templates/__init__.py +0 -0
  23. rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +20 -0
  24. rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +22 -0
  25. rasa/agents/utils.py +206 -0
  26. rasa/agents/validation.py +485 -0
  27. rasa/api.py +24 -9
  28. rasa/builder/config.py +6 -2
  29. rasa/builder/guardrails/{lakera.py → clients.py} +55 -5
  30. rasa/builder/guardrails/constants.py +3 -0
  31. rasa/builder/guardrails/models.py +45 -10
  32. rasa/builder/guardrails/policy_checker.py +324 -0
  33. rasa/builder/guardrails/utils.py +42 -276
  34. rasa/builder/llm_service.py +32 -5
  35. rasa/builder/models.py +1 -0
  36. rasa/builder/project_generator.py +6 -1
  37. rasa/builder/service.py +16 -13
  38. rasa/builder/training_service.py +18 -24
  39. rasa/builder/validation_service.py +1 -1
  40. rasa/cli/arguments/default_arguments.py +12 -0
  41. rasa/cli/arguments/run.py +2 -0
  42. rasa/cli/arguments/train.py +2 -0
  43. rasa/cli/data.py +10 -8
  44. rasa/cli/dialogue_understanding_test.py +10 -7
  45. rasa/cli/e2e_test.py +9 -6
  46. rasa/cli/evaluate.py +4 -2
  47. rasa/cli/export.py +5 -2
  48. rasa/cli/inspect.py +8 -4
  49. rasa/cli/interactive.py +5 -4
  50. rasa/cli/llm_fine_tuning.py +11 -6
  51. rasa/cli/project_templates/finance/actions/general/__init__.py +0 -0
  52. rasa/cli/project_templates/finance/actions/general/action_human_handoff.py +49 -0
  53. rasa/cli/project_templates/finance/data/general/bot_challenge.yml +6 -0
  54. rasa/cli/project_templates/finance/data/general/goodbye.yml +1 -1
  55. rasa/cli/project_templates/finance/data/general/human_handoff.yml +1 -1
  56. rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +1 -1
  57. rasa/cli/project_templates/finance/domain/general/_shared.yml +0 -14
  58. rasa/cli/project_templates/finance/domain/general/bot_challenge.yml +4 -0
  59. rasa/cli/project_templates/finance/domain/general/goodbye.yml +7 -0
  60. rasa/cli/project_templates/finance/domain/general/human_handoff.yml +3 -6
  61. rasa/cli/project_templates/finance/domain/general/welcome.yml +29 -1
  62. rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/check_balance.yml +9 -0
  63. rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/download_statements.yml +43 -0
  64. rasa/cli/project_templates/finance/tests/e2e_test_cases/cards/block_card.yml +55 -0
  65. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
  66. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/feedback.yml +46 -0
  67. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/goodbye.yml +9 -0
  68. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/hello.yml +8 -0
  69. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/human_handoff.yml +35 -0
  70. rasa/cli/project_templates/finance/tests/e2e_test_cases/general/patterns.yml +22 -0
  71. rasa/cli/project_templates/finance/tests/e2e_test_cases/transfers/transfer_money.yml +56 -0
  72. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/feedback.yml +1 -1
  73. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/hello.yml +1 -1
  74. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/human_handoff.yml +1 -1
  75. rasa/cli/project_templates/telco/tests/e2e_test_cases/general/patterns.yml +1 -1
  76. rasa/cli/project_templates/tutorial/credentials.yml +10 -0
  77. rasa/cli/run.py +12 -10
  78. rasa/cli/scaffold.py +4 -4
  79. rasa/cli/shell.py +9 -5
  80. rasa/cli/studio/studio.py +1 -1
  81. rasa/cli/test.py +34 -14
  82. rasa/cli/train.py +41 -28
  83. rasa/cli/utils.py +1 -393
  84. rasa/cli/validation/__init__.py +0 -0
  85. rasa/cli/validation/bot_config.py +223 -0
  86. rasa/cli/validation/config_path_validation.py +257 -0
  87. rasa/cli/x.py +8 -4
  88. rasa/constants.py +7 -1
  89. rasa/core/actions/action.py +51 -10
  90. rasa/core/actions/action_run_slot_rejections.py +1 -1
  91. rasa/core/actions/direct_custom_actions_executor.py +9 -2
  92. rasa/core/actions/grpc_custom_action_executor.py +1 -1
  93. rasa/core/agent.py +19 -2
  94. rasa/core/available_agents.py +229 -0
  95. rasa/core/brokers/kafka.py +1 -1
  96. rasa/core/channels/__init__.py +82 -35
  97. rasa/core/channels/development_inspector.py +3 -3
  98. rasa/core/channels/inspector/README.md +25 -13
  99. rasa/core/channels/inspector/dist/assets/{arc-35222594.js → arc-6177260a.js} +1 -1
  100. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-a0efbfd3.js → blockDiagram-38ab4fdb-b054f038.js} +1 -1
  101. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-0584c0f2.js → c4Diagram-3d4e48cf-f25427d5.js} +1 -1
  102. rasa/core/channels/inspector/dist/assets/channel-bf9cbb34.js +1 -0
  103. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-39f40dbe.js → classDiagram-70f12bd4-c7a2af53.js} +1 -1
  104. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-1ad755f3.js → classDiagram-v2-f2320105-58db65c0.js} +1 -1
  105. rasa/core/channels/inspector/dist/assets/clone-8f9083bb.js +1 -0
  106. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-b0f4f0fe.js → createText-2e5e7dd3-088372e2.js} +1 -1
  107. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-9039bff9.js → edges-e0da2a9e-58676240.js} +1 -1
  108. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-65c9b127.js → erDiagram-9861fffd-0c14d7c6.js} +1 -1
  109. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-4f08b38e.js → flowDb-956e92f1-ea63f85c.js} +1 -1
  110. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-e95c362a.js → flowDiagram-66a62f08-a2af48cd.js} +1 -1
  111. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-9ecd5b59.js +1 -0
  112. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-703c3015.js → flowchart-elk-definition-4a651766-6937abe7.js} +1 -1
  113. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-699328ea.js → ganttDiagram-c361ad54-7473f357.js} +1 -1
  114. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-04cf4b05.js → gitGraphDiagram-72cf32ee-d0c9405e.js} +1 -1
  115. rasa/core/channels/inspector/dist/assets/{graph-ee94449e.js → graph-0a6f8466.js} +1 -1
  116. rasa/core/channels/inspector/dist/assets/{index-3862675e-940162b4.js → index-3862675e-7610671a.js} +1 -1
  117. rasa/core/channels/inspector/dist/assets/index-74e01d94.js +1354 -0
  118. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-c79c2866.js → infoDiagram-f8f76790-be397dc7.js} +1 -1
  119. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-84489d30.js → journeyDiagram-49397b02-4cefbf62.js} +1 -1
  120. rasa/core/channels/inspector/dist/assets/{layout-a9aa9858.js → layout-e7fbc2bf.js} +1 -1
  121. rasa/core/channels/inspector/dist/assets/{line-eb73cf26.js → line-a8aa457c.js} +1 -1
  122. rasa/core/channels/inspector/dist/assets/{linear-b3399f9a.js → linear-3351e0d2.js} +1 -1
  123. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-b095bf1a.js → mindmap-definition-fc14e90a-b8cbf605.js} +1 -1
  124. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-07644b66.js → pieDiagram-8a3498a8-f327f774.js} +1 -1
  125. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-573a3f9c.js → quadrantDiagram-120e2f19-2854c591.js} +1 -1
  126. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-d457e1e1.js → requirementDiagram-deff3bca-964985d5.js} +1 -1
  127. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-9d26e1a2.js → sankeyDiagram-04a897e0-edeb4f33.js} +1 -1
  128. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3a9cde10.js → sequenceDiagram-704730f1-fcf70125.js} +1 -1
  129. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-4f3e8cec.js → stateDiagram-587899a1-0e770395.js} +1 -1
  130. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-e617e5bf.js → stateDiagram-v2-d93cdb3a-af8dcd22.js} +1 -1
  131. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-eab30d2f.js → styles-6aaf32cf-36a9e70d.js} +1 -1
  132. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-09994be2.js → styles-9a916d00-884a8b5b.js} +1 -1
  133. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-b7110364.js → styles-c10674c1-dc097813.js} +1 -1
  134. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-3ebc92ad.js → svgDrawCommon-08f97a94-5a2c7eed.js} +1 -1
  135. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-7d13d2f2.js → timeline-definition-85554ec2-e89c4f6e.js} +1 -1
  136. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-488385e1.js → xychartDiagram-e933f94c-afb6fe56.js} +1 -1
  137. rasa/core/channels/inspector/dist/index.html +1 -1
  138. rasa/core/channels/inspector/package.json +18 -18
  139. rasa/core/channels/inspector/src/App.tsx +29 -4
  140. rasa/core/channels/inspector/src/components/DialogueAgentStack.tsx +108 -0
  141. rasa/core/channels/inspector/src/components/{DialogueStack.tsx → DialogueHistoryStack.tsx} +4 -2
  142. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +7 -4
  143. rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -0
  144. rasa/core/channels/inspector/src/helpers/formatters.ts +24 -3
  145. rasa/core/channels/inspector/src/helpers/utils.test.ts +127 -0
  146. rasa/core/channels/inspector/src/helpers/utils.ts +66 -1
  147. rasa/core/channels/inspector/src/theme/base/styles.ts +19 -1
  148. rasa/core/channels/inspector/src/types.ts +21 -0
  149. rasa/core/channels/inspector/yarn.lock +336 -189
  150. rasa/core/channels/studio_chat.py +6 -6
  151. rasa/core/channels/telegram.py +4 -9
  152. rasa/core/channels/voice_stream/browser_audio.py +2 -0
  153. rasa/core/channels/voice_stream/genesys.py +1 -1
  154. rasa/core/channels/voice_stream/tts/deepgram.py +140 -0
  155. rasa/core/channels/voice_stream/twilio_media_streams.py +5 -1
  156. rasa/core/channels/voice_stream/voice_channel.py +3 -0
  157. rasa/core/config/__init__.py +0 -0
  158. rasa/core/{available_endpoints.py → config/available_endpoints.py} +51 -16
  159. rasa/core/config/configuration.py +260 -0
  160. rasa/core/config/credentials.py +19 -0
  161. rasa/core/config/message_procesing_config.py +34 -0
  162. rasa/core/constants.py +5 -0
  163. rasa/core/iam_credentials_providers/aws_iam_credentials_providers.py +88 -3
  164. rasa/core/iam_credentials_providers/credentials_provider_protocol.py +2 -1
  165. rasa/core/lock_store.py +6 -4
  166. rasa/core/nlg/generator.py +1 -1
  167. rasa/core/policies/enterprise_search_policy.py +5 -3
  168. rasa/core/policies/flow_policy.py +4 -4
  169. rasa/core/policies/flows/agent_executor.py +632 -0
  170. rasa/core/policies/flows/flow_executor.py +137 -76
  171. rasa/core/policies/flows/mcp_tool_executor.py +298 -0
  172. rasa/core/policies/intentless_policy.py +1 -1
  173. rasa/core/policies/ted_policy.py +20 -12
  174. rasa/core/policies/unexpected_intent_policy.py +6 -0
  175. rasa/core/processor.py +68 -44
  176. rasa/core/redis_connection_factory.py +78 -20
  177. rasa/core/run.py +37 -8
  178. rasa/core/test.py +4 -0
  179. rasa/core/tracker_stores/sql_tracker_store.py +1 -1
  180. rasa/core/tracker_stores/tracker_store.py +3 -7
  181. rasa/core/train.py +1 -1
  182. rasa/core/training/interactive.py +20 -18
  183. rasa/core/training/story_conflict.py +5 -5
  184. rasa/core/utils.py +22 -23
  185. rasa/dialogue_understanding/commands/__init__.py +8 -0
  186. rasa/dialogue_understanding/commands/cancel_flow_command.py +19 -5
  187. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +21 -2
  188. rasa/dialogue_understanding/commands/clarify_command.py +20 -2
  189. rasa/dialogue_understanding/commands/continue_agent_command.py +91 -0
  190. rasa/dialogue_understanding/commands/knowledge_answer_command.py +21 -2
  191. rasa/dialogue_understanding/commands/restart_agent_command.py +162 -0
  192. rasa/dialogue_understanding/commands/start_flow_command.py +68 -7
  193. rasa/dialogue_understanding/commands/utils.py +124 -2
  194. rasa/dialogue_understanding/generator/command_parser.py +4 -0
  195. rasa/dialogue_understanding/generator/llm_based_command_generator.py +50 -12
  196. rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
  197. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +1 -1
  198. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +66 -0
  199. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +66 -0
  200. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +89 -0
  201. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +88 -0
  202. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +42 -7
  203. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +40 -3
  204. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +20 -3
  205. rasa/dialogue_understanding/patterns/cancel.py +27 -6
  206. rasa/dialogue_understanding/patterns/clarify.py +3 -14
  207. rasa/dialogue_understanding/patterns/continue_interrupted.py +239 -6
  208. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +46 -8
  209. rasa/dialogue_understanding/processor/command_processor.py +136 -15
  210. rasa/dialogue_understanding/stack/dialogue_stack.py +98 -2
  211. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +57 -0
  212. rasa/dialogue_understanding/stack/utils.py +57 -3
  213. rasa/dialogue_understanding/utils.py +24 -4
  214. rasa/dialogue_understanding_test/du_test_runner.py +8 -3
  215. rasa/e2e_test/e2e_test_runner.py +13 -3
  216. rasa/engine/caching.py +2 -2
  217. rasa/engine/constants.py +1 -1
  218. rasa/engine/loader.py +12 -0
  219. rasa/engine/recipes/default_components.py +138 -49
  220. rasa/engine/recipes/default_recipe.py +108 -11
  221. rasa/engine/runner/dask.py +8 -5
  222. rasa/engine/validation.py +19 -6
  223. rasa/graph_components/validators/default_recipe_validator.py +86 -28
  224. rasa/hooks.py +5 -5
  225. rasa/llm_fine_tuning/utils.py +2 -2
  226. rasa/model_training.py +60 -47
  227. rasa/nlu/classifiers/diet_classifier.py +198 -98
  228. rasa/nlu/classifiers/logistic_regression_classifier.py +1 -4
  229. rasa/nlu/classifiers/mitie_intent_classifier.py +3 -0
  230. rasa/nlu/classifiers/sklearn_intent_classifier.py +1 -3
  231. rasa/nlu/extractors/crf_entity_extractor.py +9 -10
  232. rasa/nlu/extractors/mitie_entity_extractor.py +3 -0
  233. rasa/nlu/extractors/spacy_entity_extractor.py +3 -0
  234. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +4 -0
  235. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +5 -0
  236. rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +2 -0
  237. rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +3 -0
  238. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +4 -2
  239. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -0
  240. rasa/nlu/selectors/response_selector.py +10 -2
  241. rasa/nlu/tokenizers/jieba_tokenizer.py +3 -4
  242. rasa/nlu/tokenizers/mitie_tokenizer.py +3 -2
  243. rasa/nlu/tokenizers/spacy_tokenizer.py +3 -2
  244. rasa/nlu/utils/mitie_utils.py +3 -0
  245. rasa/nlu/utils/spacy_utils.py +3 -2
  246. rasa/plugin.py +8 -8
  247. rasa/privacy/privacy_manager.py +12 -3
  248. rasa/server.py +15 -3
  249. rasa/shared/agents/__init__.py +0 -0
  250. rasa/shared/agents/auth/__init__.py +0 -0
  251. rasa/shared/agents/auth/agent_auth_factory.py +105 -0
  252. rasa/shared/agents/auth/agent_auth_manager.py +92 -0
  253. rasa/shared/agents/auth/auth_strategy/__init__.py +19 -0
  254. rasa/shared/agents/auth/auth_strategy/agent_auth_strategy.py +52 -0
  255. rasa/shared/agents/auth/auth_strategy/api_key_auth_strategy.py +42 -0
  256. rasa/shared/agents/auth/auth_strategy/bearer_token_auth_strategy.py +28 -0
  257. rasa/shared/agents/auth/auth_strategy/oauth2_auth_strategy.py +167 -0
  258. rasa/shared/agents/auth/constants.py +12 -0
  259. rasa/shared/agents/auth/types.py +12 -0
  260. rasa/shared/agents/utils.py +35 -0
  261. rasa/shared/constants.py +8 -0
  262. rasa/shared/core/constants.py +16 -1
  263. rasa/shared/core/domain.py +0 -7
  264. rasa/shared/core/events.py +327 -0
  265. rasa/shared/core/flows/constants.py +5 -0
  266. rasa/shared/core/flows/flow.py +1 -1
  267. rasa/shared/core/flows/flows_list.py +21 -5
  268. rasa/shared/core/flows/flows_yaml_schema.json +119 -184
  269. rasa/shared/core/flows/steps/call.py +49 -5
  270. rasa/shared/core/flows/steps/collect.py +98 -13
  271. rasa/shared/core/flows/validation.py +372 -8
  272. rasa/shared/core/flows/yaml_flows_io.py +3 -2
  273. rasa/shared/core/slots.py +2 -2
  274. rasa/shared/core/trackers.py +5 -2
  275. rasa/shared/exceptions.py +16 -0
  276. rasa/shared/importers/rasa.py +1 -1
  277. rasa/shared/importers/utils.py +9 -3
  278. rasa/shared/providers/llm/_base_litellm_client.py +41 -9
  279. rasa/shared/providers/llm/litellm_router_llm_client.py +8 -4
  280. rasa/shared/providers/llm/llm_client.py +7 -3
  281. rasa/shared/providers/llm/llm_response.py +66 -0
  282. rasa/shared/providers/llm/self_hosted_llm_client.py +8 -4
  283. rasa/shared/utils/common.py +24 -0
  284. rasa/shared/utils/health_check/health_check.py +7 -3
  285. rasa/shared/utils/llm.py +39 -16
  286. rasa/shared/utils/mcp/__init__.py +0 -0
  287. rasa/shared/utils/mcp/server_connection.py +247 -0
  288. rasa/shared/utils/mcp/utils.py +20 -0
  289. rasa/shared/utils/schemas/events.py +42 -0
  290. rasa/shared/utils/yaml.py +3 -1
  291. rasa/studio/pull/pull.py +3 -2
  292. rasa/studio/train.py +8 -7
  293. rasa/studio/upload.py +3 -6
  294. rasa/telemetry.py +69 -5
  295. rasa/tracing/config.py +45 -12
  296. rasa/tracing/constants.py +14 -0
  297. rasa/tracing/instrumentation/attribute_extractors.py +142 -9
  298. rasa/tracing/instrumentation/instrumentation.py +626 -21
  299. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +4 -4
  300. rasa/tracing/instrumentation/metrics.py +32 -0
  301. rasa/tracing/metric_instrument_provider.py +68 -0
  302. rasa/utils/common.py +92 -1
  303. rasa/utils/endpoints.py +11 -2
  304. rasa/utils/log_utils.py +96 -5
  305. rasa/utils/ml_utils.py +1 -1
  306. rasa/utils/pypred.py +38 -0
  307. rasa/utils/tensorflow/__init__.py +7 -0
  308. rasa/utils/tensorflow/callback.py +136 -101
  309. rasa/utils/tensorflow/crf.py +1 -1
  310. rasa/utils/tensorflow/data_generator.py +21 -8
  311. rasa/utils/tensorflow/layers.py +21 -11
  312. rasa/utils/tensorflow/metrics.py +7 -3
  313. rasa/utils/tensorflow/models.py +56 -8
  314. rasa/utils/tensorflow/rasa_layers.py +8 -6
  315. rasa/utils/tensorflow/transformer.py +2 -3
  316. rasa/utils/train_utils.py +54 -24
  317. rasa/validator.py +17 -13
  318. rasa/version.py +1 -1
  319. {rasa_pro-3.14.0a20.dist-info → rasa_pro-3.14.0a23.dist-info}/METADATA +48 -42
  320. {rasa_pro-3.14.0a20.dist-info → rasa_pro-3.14.0a23.dist-info}/RECORD +323 -251
  321. rasa/builder/scrape_rasa_docs.py +0 -97
  322. rasa/cli/project_templates/finance/data/general/agent_details.yml +0 -6
  323. rasa/cli/project_templates/finance/domain/_system/patterns/pattern_session_start.yml +0 -11
  324. rasa/cli/project_templates/finance/domain/general/agent_details.yml +0 -31
  325. rasa/core/channels/inspector/dist/assets/channel-8e08bed9.js +0 -1
  326. rasa/core/channels/inspector/dist/assets/clone-78c82dea.js +0 -1
  327. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b08f601.js +0 -1
  328. rasa/core/channels/inspector/dist/assets/index-c941dcb3.js +0 -1336
  329. {rasa_pro-3.14.0a20.dist-info → rasa_pro-3.14.0a23.dist-info}/NOTICE +0 -0
  330. {rasa_pro-3.14.0a20.dist-info → rasa_pro-3.14.0a23.dist-info}/WHEEL +0 -0
  331. {rasa_pro-3.14.0a20.dist-info → rasa_pro-3.14.0a23.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,223 @@
1
+ import argparse
2
+ import os
3
+ from typing import TYPE_CHECKING, Optional
4
+
5
+ import structlog
6
+
7
+ from rasa import telemetry
8
+ from rasa.exceptions import ValidationError
9
+ from rasa.shared.importers.importer import TrainingDataImporter
10
+ from rasa.shared.utils.common import display_research_study_prompt
11
+
12
+ if TYPE_CHECKING:
13
+ from rasa.validator import Validator
14
+
15
+ structlogger = structlog.get_logger()
16
+
17
+ FREE_TEXT_INPUT_PROMPT = "Type out your own message..."
18
+
19
+
20
+ def _validate_domain(validator: "Validator") -> bool:
21
+ valid_domain_validity = validator.verify_domain_validity()
22
+ valid_actions_in_stories_rules = validator.verify_actions_in_stories_rules()
23
+ valid_forms_in_stories_rules = validator.verify_forms_in_stories_rules()
24
+ valid_form_slots = validator.verify_form_slots()
25
+ valid_slot_mappings = validator.verify_slot_mappings()
26
+ valid_responses = validator.check_for_no_empty_parenthesis_in_responses()
27
+ valid_buttons = validator.validate_button_payloads()
28
+ valid_slot_validation = validator.verify_slot_validation()
29
+ valid_conditional_responses = (
30
+ validator.validate_conditional_response_variation_predicates()
31
+ )
32
+ return (
33
+ valid_domain_validity
34
+ and valid_actions_in_stories_rules
35
+ and valid_forms_in_stories_rules
36
+ and valid_form_slots
37
+ and valid_slot_mappings
38
+ and valid_responses
39
+ and valid_buttons
40
+ and valid_slot_validation
41
+ and valid_conditional_responses
42
+ )
43
+
44
+
45
+ def _validate_nlu(validator: "Validator", fail_on_warnings: bool) -> bool:
46
+ return validator.verify_nlu(not fail_on_warnings)
47
+
48
+
49
+ def _validate_story_structure(
50
+ validator: "Validator", max_history: Optional[int], fail_on_warnings: bool
51
+ ) -> bool:
52
+ # Check if a valid setting for `max_history` was given
53
+ if isinstance(max_history, int) and max_history < 1:
54
+ raise argparse.ArgumentTypeError(
55
+ f"The value of `--max-history {max_history}` is not a positive integer."
56
+ )
57
+
58
+ return validator.verify_story_structure(
59
+ not fail_on_warnings, max_history=max_history
60
+ )
61
+
62
+
63
+ def _validate_sub_agents(sub_agents_path: str) -> bool:
64
+ """Validates sub-agents configuration.
65
+
66
+ Args:
67
+ sub_agents_path: Path to the sub-agents directory.
68
+
69
+ Returns:
70
+ True if validation passes, False otherwise.
71
+ """
72
+ from rasa.agents.validation import validate_agent_folder
73
+ from rasa.core.constants import DEFAULT_SUB_AGENTS
74
+
75
+ try:
76
+ # Check if the sub-agents directory exists
77
+ if not os.path.isdir(sub_agents_path):
78
+ # If the sub-agents-path points to the default folder and it doesn't exist,
79
+ # no agents are available.
80
+ # AvailableAgents will handle the non-existing folder gracefully.
81
+
82
+ if sub_agents_path == DEFAULT_SUB_AGENTS:
83
+ structlogger.info(
84
+ "cli.validate_files.sub_agents_validation",
85
+ sub_agents_path=sub_agents_path,
86
+ event_info="Default sub-agents directory does not exist, "
87
+ "no sub-agents will be available.",
88
+ )
89
+ return True
90
+ else:
91
+ # For user-specified paths, the directory must exist
92
+ structlogger.error(
93
+ "cli.validate_files.sub_agents_validation_error",
94
+ sub_agents_path=sub_agents_path,
95
+ event_info=f"Sub-agents directory '{sub_agents_path}' "
96
+ "does not exist.",
97
+ )
98
+ return False
99
+
100
+ # Validate the actual config content using AvailableAgents
101
+ # This will validate file existence, structure, mandatory keys, etc.
102
+ try:
103
+ validate_agent_folder(sub_agents_path)
104
+
105
+ except ValidationError as e:
106
+ # This is a validation error - log it and return False
107
+ structlogger.error(
108
+ "cli.validate_files.sub_agents_validation_error",
109
+ sub_agents_path=sub_agents_path,
110
+ validation_error=str(e),
111
+ event_info=f"Sub-agents configuration validation failed: {e}",
112
+ )
113
+ return False
114
+
115
+ except Exception as e:
116
+ # This is an unexpected error
117
+ structlogger.error(
118
+ "cli.validate_files.sub_agents_validation_error",
119
+ sub_agents_path=sub_agents_path,
120
+ error=str(e),
121
+ event_info=f"Unexpected error during sub-agents validation: {e}",
122
+ )
123
+ return False
124
+
125
+ structlogger.info(
126
+ "cli.validate_files.sub_agents_validation_success",
127
+ sub_agents_path=sub_agents_path,
128
+ event_info="Sub-agents validation passed successfully.",
129
+ )
130
+ return True
131
+
132
+ except Exception as e:
133
+ # This is an unexpected error
134
+ structlogger.error(
135
+ "cli.validate_files.sub_agents_validation_error",
136
+ sub_agents_path=sub_agents_path,
137
+ error=str(e),
138
+ event_info="Sub-agents validation failed.",
139
+ )
140
+ return False
141
+
142
+
143
+ def validate_files(
144
+ fail_on_warnings: bool,
145
+ max_history: Optional[int],
146
+ importer: TrainingDataImporter,
147
+ stories_only: bool = False,
148
+ flows_only: bool = False,
149
+ translations_only: bool = False,
150
+ sub_agents: Optional[str] = None,
151
+ ) -> None:
152
+ """Validates either the story structure or the entire project.
153
+
154
+ Args:
155
+ fail_on_warnings: `True` if the process should exit with a non-zero status
156
+ max_history: The max history to use when validating the story structure.
157
+ importer: The `TrainingDataImporter` to use to load the training data.
158
+ stories_only: If `True`, only the story structure is validated.
159
+ flows_only: If `True`, only the flows are validated.
160
+ translations_only: If `True`, only the translations data is validated.
161
+ sub_agents: Path to sub-agents directory for validation.
162
+ """
163
+ from rasa.validator import Validator
164
+
165
+ validator = Validator.from_importer(importer)
166
+
167
+ if stories_only:
168
+ all_good = _validate_story_structure(validator, max_history, fail_on_warnings)
169
+ elif flows_only:
170
+ all_good = validator.verify_flows()
171
+ elif translations_only:
172
+ all_good = validator.verify_translations()
173
+ else:
174
+ if importer.get_domain().is_empty():
175
+ structlogger.error(
176
+ "cli.validate_files.empty_domain",
177
+ event_info="Encountered empty domain during validation.",
178
+ )
179
+ display_research_study_prompt()
180
+ raise ValidationError(
181
+ code="cli.validate_files.empty_domain",
182
+ event_info="Encountered empty domain during validation.",
183
+ )
184
+
185
+ valid_domain = _validate_domain(validator)
186
+ valid_nlu = _validate_nlu(validator, fail_on_warnings)
187
+ valid_stories = _validate_story_structure(
188
+ validator, max_history, fail_on_warnings
189
+ )
190
+ valid_flows = validator.verify_flows()
191
+ if validator.config:
192
+ valid_translations = validator.verify_translations(summary_mode=True)
193
+ else:
194
+ valid_translations = True
195
+ valid_CALM_slot_mappings = validator.validate_CALM_slot_mappings()
196
+
197
+ # Validate sub-agents if specified
198
+ valid_sub_agents = _validate_sub_agents(sub_agents) if sub_agents else True
199
+
200
+ all_good = (
201
+ valid_domain
202
+ and valid_nlu
203
+ and valid_stories
204
+ and valid_flows
205
+ and valid_translations
206
+ and valid_CALM_slot_mappings
207
+ and valid_sub_agents
208
+ )
209
+
210
+ if validator.config:
211
+ validator.warn_if_config_mandatory_keys_are_not_set()
212
+
213
+ telemetry.track_validate_files(all_good)
214
+ if not all_good:
215
+ structlogger.error(
216
+ "cli.validate_files.project_validation_error",
217
+ event_info="Project validation completed with errors.",
218
+ )
219
+ display_research_study_prompt()
220
+ raise ValidationError(
221
+ code="cli.validate_files.project_validation_error",
222
+ event_info="Project validation completed with errors.",
223
+ )
@@ -0,0 +1,257 @@
1
+ import os
2
+ import time
3
+ from pathlib import Path
4
+ from typing import List, Optional, Text, Union
5
+
6
+ import randomname
7
+ import structlog
8
+
9
+ from rasa.exceptions import ModelNotFound, ValidationError
10
+ from rasa.shared.constants import (
11
+ ASSISTANT_ID_DEFAULT_VALUE,
12
+ ASSISTANT_ID_KEY,
13
+ DEFAULT_CONFIG_PATH,
14
+ )
15
+ from rasa.shared.utils.common import display_research_study_prompt
16
+ from rasa.shared.utils.yaml import read_config_file
17
+ from rasa.utils.io import write_yaml
18
+
19
+ structlogger = structlog.get_logger()
20
+
21
+
22
+ FREE_TEXT_INPUT_PROMPT = "Type out your own message..."
23
+
24
+
25
+ def get_validated_path(
26
+ current: Optional[Union[Path, Text]],
27
+ parameter: Text,
28
+ default: Optional[Union[Path, Text, List[Text], List[Path]]] = None,
29
+ none_is_valid: bool = False,
30
+ ) -> Optional[Union[Path, Text]]:
31
+ """Checks whether a file path or its default value is valid and returns it.
32
+
33
+ Args:
34
+ current: The parsed value.
35
+ parameter: The name of the parameter.
36
+ default: one or multiple default values of the parameter.
37
+ none_is_valid: `True` if `None` is valid value for the path,
38
+ else `False``
39
+
40
+ Returns:
41
+ The current value if valid,
42
+ otherwise one of the default values of the argument if valid,
43
+ otherwise `None` if allowed,
44
+ otherwise raises an error and exits.
45
+ """
46
+ if current and os.path.exists(current):
47
+ return current
48
+
49
+ if parameter == "model":
50
+ raise ModelNotFound(
51
+ f"The provided model path '{current}' could not be found. "
52
+ "Provide an existing model path."
53
+ )
54
+
55
+ default_options: Union[List[str], List[Path]] = []
56
+ # try to find a valid option among the defaults
57
+ if isinstance(default, str) or isinstance(default, Path):
58
+ default_options = [str(default)]
59
+ elif isinstance(default, list):
60
+ default_options = default
61
+
62
+ valid_options = (option for option in default_options if os.path.exists(option))
63
+ chosen_option = next(valid_options, None)
64
+
65
+ # warn and log if user-chosen parameter wasn't found and thus overwritten
66
+ if chosen_option:
67
+ shared_info = f"Using default location '{chosen_option}' instead."
68
+ if current is None:
69
+ structlogger.debug(
70
+ "cli.get_validated_path.parameter_not_set",
71
+ parameter=parameter,
72
+ event_info=(f"Parameter '{parameter}' was not set. {shared_info}"),
73
+ )
74
+ elif current not in default_options:
75
+ structlogger.warn(
76
+ "cli.get_validated_path.path_does_not_exists",
77
+ path=current,
78
+ event_info=(
79
+ f"The path '{current}' does not seem to exist. {shared_info}"
80
+ ),
81
+ )
82
+
83
+ if chosen_option is None and not none_is_valid:
84
+ _cancel_cause_not_found(current, parameter, default)
85
+
86
+ return chosen_option
87
+
88
+
89
+ def validate_assistant_id_in_config(config_file: Union["Path", Text]) -> None:
90
+ """Verifies that the assistant_id key exists and has a unique value in config.
91
+
92
+ Issues a warning if the key does not exist or has the default value and replaces it
93
+ with a pseudo-random string value.
94
+ """
95
+ config_data = read_config_file(config_file, reader_type=["safe", "rt"])
96
+ assistant_id = config_data.get(ASSISTANT_ID_KEY)
97
+
98
+ if assistant_id is None or assistant_id == ASSISTANT_ID_DEFAULT_VALUE:
99
+ structlogger.warn(
100
+ "cli.validate_assistant_id_in_config.missing_unique_assistant_id_key",
101
+ config=config_file,
102
+ missing_key=ASSISTANT_ID_KEY,
103
+ event_info=(
104
+ f"The config file '{config_file!s}' is "
105
+ f"missing a unique value for the "
106
+ f"'{ASSISTANT_ID_KEY}' mandatory key. "
107
+ f"Proceeding with generating a random "
108
+ f"value and overwriting the '{ASSISTANT_ID_KEY}'"
109
+ f" in the config file."
110
+ ),
111
+ )
112
+
113
+ # add random value for assistant id, overwrite config file
114
+ time_format = "%Y%m%d-%H%M%S"
115
+ config_data[ASSISTANT_ID_KEY] = (
116
+ f"{time.strftime(time_format)}-{randomname.get_name()}"
117
+ )
118
+
119
+ write_yaml(data=config_data, target=config_file, should_preserve_key_order=True)
120
+
121
+ return
122
+
123
+
124
+ def validate_config_path(
125
+ config: Optional[Union[Text, "Path"]],
126
+ default_config: Text = DEFAULT_CONFIG_PATH,
127
+ ) -> Text:
128
+ """Verifies that the config path exists.
129
+
130
+ Exit if the config file does not exist.
131
+
132
+ Args:
133
+ config: Path to the config file.
134
+ default_config: default config to use if the file at `config` doesn't exist.
135
+
136
+ Returns: The path to the config file.
137
+ """
138
+ config = get_validated_path(config, "config", default_config)
139
+
140
+ if not config or not os.path.exists(config):
141
+ display_research_study_prompt()
142
+ raise ValidationError(
143
+ code="cli.validate_config_path.does_not_exists",
144
+ config=config,
145
+ event_info=(
146
+ f"The config file '{config}' does not exist. "
147
+ f"Use '--config' to specify a valid config file."
148
+ ),
149
+ )
150
+
151
+ return str(config)
152
+
153
+
154
+ def validate_mandatory_config_keys(
155
+ config: Union[Text, "Path"],
156
+ mandatory_keys: List[Text],
157
+ ) -> Text:
158
+ """Get a config from a config file and check if it is valid.
159
+
160
+ Exit if the config isn't valid.
161
+
162
+ Args:
163
+ config: Path to the config file.
164
+ mandatory_keys: The keys that have to be specified in the config file.
165
+
166
+ Returns: The path to the config file if the config is valid.
167
+ """
168
+ missing_keys = set(_missing_config_keys(config, mandatory_keys))
169
+ if missing_keys:
170
+ display_research_study_prompt()
171
+ raise ValidationError(
172
+ code="cli.validate_mandatory_config_keys.missing_keys",
173
+ config=config,
174
+ missing_keys=missing_keys,
175
+ event_info=(
176
+ "The config file '{}' is missing mandatory parameters: "
177
+ "'{}'. Add missing parameters to config file and try again.".format(
178
+ config, "', '".join(missing_keys)
179
+ )
180
+ ),
181
+ )
182
+
183
+ return str(config)
184
+
185
+
186
+ def get_validated_config(
187
+ config: Optional[Union[Text, "Path"]],
188
+ mandatory_keys: List[Text],
189
+ default_config: Text = DEFAULT_CONFIG_PATH,
190
+ ) -> Text:
191
+ """Validates config and returns path to validated config file."""
192
+ config = validate_config_path(config, default_config)
193
+ validate_assistant_id_in_config(config)
194
+
195
+ config = validate_mandatory_config_keys(config, mandatory_keys)
196
+
197
+ return config
198
+
199
+
200
+ def _missing_config_keys(
201
+ path: Union["Path", Text], mandatory_keys: List[Text]
202
+ ) -> List[Text]:
203
+ """Checks whether the config file at `path` contains the `mandatory_keys`.
204
+
205
+ Args:
206
+ path: The path to the config file.
207
+ mandatory_keys: A list of mandatory config keys.
208
+
209
+ Returns:
210
+ The list of missing config keys.
211
+ """
212
+ if not os.path.exists(path):
213
+ return mandatory_keys
214
+
215
+ config_data = read_config_file(path)
216
+
217
+ return [k for k in mandatory_keys if k not in config_data or config_data[k] is None]
218
+
219
+
220
+ def _cancel_cause_not_found(
221
+ current: Optional[Union["Path", Text]],
222
+ parameter: Text,
223
+ default: Optional[Union["Path", Text, List[Text]]],
224
+ ) -> None:
225
+ """Exits with an error because the given path was not valid.
226
+
227
+ Args:
228
+ current: The path given by the user.
229
+ parameter: The name of the parameter.
230
+ default: The default value of the parameter.
231
+
232
+ """
233
+ default_clause = ""
234
+ if default and isinstance(default, str):
235
+ default_clause = f"use the default location ('{default}') or"
236
+ elif default and isinstance(default, list):
237
+ default_clause = f"use one of the default locations ({', '.join(default)}) or"
238
+
239
+ structlogger.error(
240
+ "cli.path_does_not_exist",
241
+ path=current,
242
+ event_info=(
243
+ f"The path '{current}' does not exist. "
244
+ f"Please make sure to {default_clause} specify it "
245
+ f"with '--{parameter}'."
246
+ ),
247
+ )
248
+ display_research_study_prompt()
249
+ raise ValidationError(
250
+ code="cli.path_does_not_exist",
251
+ path=current,
252
+ event_info=(
253
+ f"The path '{current}' does not exist. "
254
+ f"Please make sure to {default_clause} specify it "
255
+ f"with '--{parameter}'."
256
+ ),
257
+ )
rasa/cli/x.py CHANGED
@@ -15,7 +15,9 @@ import rasa.utils.common
15
15
  import rasa.utils.io
16
16
  from rasa.cli import SubParsersAction
17
17
  from rasa.cli.arguments import x as arguments
18
- from rasa.core.available_endpoints import AvailableEndpoints
18
+ from rasa.cli.validation.config_path_validation import get_validated_path
19
+ from rasa.core.config.available_endpoints import AvailableEndpoints
20
+ from rasa.core.config.configuration import Configuration
19
21
  from rasa.shared.constants import (
20
22
  DEFAULT_CREDENTIALS_PATH,
21
23
  DEFAULT_ENDPOINTS_PATH,
@@ -90,7 +92,7 @@ def _prepare_credentials_for_rasa_x(
90
92
  ) -> Text:
91
93
  if credentials_path:
92
94
  credentials_path = str(
93
- rasa.cli.utils.get_validated_path(
95
+ get_validated_path(
94
96
  credentials_path, "credentials", DEFAULT_CREDENTIALS_PATH, True
95
97
  )
96
98
  )
@@ -179,7 +181,9 @@ def run_in_enterprise_connection_mode(args: argparse.Namespace) -> None:
179
181
  print_success("Starting a Rasa server in Rasa Enterprise connection mode... 🚀")
180
182
 
181
183
  credentials_path, endpoints_path = _get_credentials_and_endpoints_paths(args)
182
- endpoints = AvailableEndpoints.get_instance(endpoints_path)
184
+ endpoints = Configuration.initialise_endpoints(
185
+ endpoints_path=Path(endpoints_path)
186
+ ).endpoints
183
187
 
184
188
  _rasa_service(args, endpoints, None, credentials_path)
185
189
 
@@ -195,7 +199,7 @@ def _get_credentials_and_endpoints_paths(
195
199
  _pull_runtime_config_from_server(config_endpoint)
196
200
  )
197
201
  else:
198
- endpoints_config_path = rasa.cli.utils.get_validated_path(
202
+ endpoints_config_path = get_validated_path(
199
203
  args.endpoints, "endpoints", DEFAULT_ENDPOINTS_PATH, True
200
204
  )
201
205
  credentials_path = None
rasa/constants.py CHANGED
@@ -18,12 +18,18 @@ CONFIG_TELEMETRY_ID = "rasa_user_id"
18
18
  CONFIG_TELEMETRY_ENABLED = "enabled"
19
19
  CONFIG_TELEMETRY_DATE = "date"
20
20
 
21
- MINIMUM_COMPATIBLE_VERSION = "3.11.0rc1"
21
+ MINIMUM_COMPATIBLE_VERSION = "3.14.0.dev10"
22
22
 
23
23
  GLOBAL_USER_CONFIG_PATH = os.path.expanduser("~/.config/rasa/global.yml")
24
24
 
25
+ # Logging level for external libraries (default: ERROR to reduce noise)
25
26
  DEFAULT_LOG_LEVEL_LIBRARIES = "ERROR"
26
27
  ENV_LOG_LEVEL_LIBRARIES = "LOG_LEVEL_LIBRARIES"
28
+
29
+ # MCP (Model Context Protocol) logging configuration
30
+ ENV_LOG_LEVEL_MCP = "LOG_LEVEL_MCP"
31
+ ENV_MCP_LOGGING_ENABLED = "MCP_LOGGING_ENABLED"
32
+
27
33
  ENV_LOG_LEVEL_MATPLOTLIB = "LOG_LEVEL_MATPLOTLIB"
28
34
  ENV_LOG_LEVEL_RABBITMQ = "LOG_LEVEL_RABBITMQ"
29
35
  ENV_LOG_LEVEL_KAFKA = "LOG_LEVEL_KAFKA"
@@ -47,6 +47,7 @@ from rasa.shared.constants import (
47
47
  UTTER_PREFIX,
48
48
  )
49
49
  from rasa.shared.core.constants import (
50
+ ACTION_AGENT_REQUEST_USER_INPUT_NAME,
50
51
  ACTION_BACK_NAME,
51
52
  ACTION_DEACTIVATE_LOOP_NAME,
52
53
  ACTION_DEFAULT_ASK_AFFIRMATION_NAME,
@@ -56,6 +57,8 @@ from rasa.shared.core.constants import (
56
57
  ACTION_LISTEN_NAME,
57
58
  ACTION_METADATA_EXECUTION_ERROR_MESSAGE,
58
59
  ACTION_METADATA_EXECUTION_SUCCESS,
60
+ ACTION_METADATA_MESSAGE_KEY,
61
+ ACTION_METADATA_TEXT_KEY,
59
62
  ACTION_RESET_ROUTING,
60
63
  ACTION_RESTART_NAME,
61
64
  ACTION_REVERT_FALLBACK_EVENTS_NAME,
@@ -88,7 +91,12 @@ from rasa.shared.core.slot_mappings import (
88
91
  )
89
92
  from rasa.shared.core.trackers import DialogueStateTracker
90
93
  from rasa.shared.exceptions import RasaException
91
- from rasa.shared.nlu.constants import INTENT_NAME_KEY, INTENT_RANKING_KEY
94
+ from rasa.shared.nlu.constants import (
95
+ INTENT,
96
+ INTENT_NAME_KEY,
97
+ INTENT_RANKING_KEY,
98
+ PREDICTED_CONFIDENCE_KEY,
99
+ )
92
100
  from rasa.shared.utils.io import raise_warning
93
101
  from rasa.shared.utils.schemas.events import EVENTS_SCHEMA
94
102
  from rasa.utils.endpoints import EndpointConfig
@@ -113,6 +121,10 @@ def default_actions(action_endpoint: Optional[EndpointConfig] = None) -> List["A
113
121
  from rasa.core.actions.two_stage_fallback import TwoStageFallbackAction
114
122
  from rasa.dialogue_understanding.patterns.cancel import ActionCancelFlow
115
123
  from rasa.dialogue_understanding.patterns.clarify import ActionClarifyFlows
124
+ from rasa.dialogue_understanding.patterns.continue_interrupted import (
125
+ ActionCancelInterruptedFlows,
126
+ ActionContinueInterruptedFlow,
127
+ )
116
128
  from rasa.dialogue_understanding.patterns.correction import ActionCorrectFlowSlot
117
129
 
118
130
  return [
@@ -127,6 +139,7 @@ def default_actions(action_endpoint: Optional[EndpointConfig] = None) -> List["A
127
139
  TwoStageFallbackAction(action_endpoint),
128
140
  ActionUnlikelyIntent(),
129
141
  ActionSendText(),
142
+ ActionAgentRequestUserInfo(),
130
143
  ActionBack(),
131
144
  ActionExtractSlots(action_endpoint),
132
145
  ActionCancelFlow(),
@@ -139,6 +152,8 @@ def default_actions(action_endpoint: Optional[EndpointConfig] = None) -> List["A
139
152
  ActionResetRouting(),
140
153
  ActionHangup(),
141
154
  ActionRepeatBotMessages(),
155
+ ActionContinueInterruptedFlow(),
156
+ ActionCancelInterruptedFlows(),
142
157
  ]
143
158
 
144
159
 
@@ -873,8 +888,8 @@ class RemoteAction(Action):
873
888
  ) -> List[BotUttered]:
874
889
  """Use the responses generated by the action endpoint and utter them."""
875
890
  bot_messages = []
876
- domain: Domain = kwargs.get("domain", None)
877
- action_name: str = kwargs.get("action_name", None)
891
+ domain: Optional[Domain] = kwargs.get("domain", None)
892
+ action_name: Optional[str] = kwargs.get("action_name", None)
878
893
  for response in responses:
879
894
  generated_response = response.pop("response", None)
880
895
  if generated_response is not None:
@@ -1014,13 +1029,13 @@ def _revert_affirmation_events(tracker: "DialogueStateTracker") -> List[Event]:
1014
1029
  revert_events += _revert_rephrasing_events()
1015
1030
 
1016
1031
  last_user_event = tracker.get_last_event_for(UserUttered)
1017
- if not last_user_event:
1018
- raise TypeError("Cannot find last event to revert to.")
1032
+ if not last_user_event or not isinstance(last_user_event, UserUttered):
1033
+ raise TypeError("Cannot find last user uttered event to revert to.")
1019
1034
 
1020
1035
  last_user_event = copy.deepcopy(last_user_event)
1021
1036
  # FIXME: better type annotation for `parse_data` would require
1022
1037
  # a larger refactoring (e.g. switch to dataclass)
1023
- last_user_event.parse_data["intent"]["confidence"] = 1.0 # type: ignore[typeddict-item]
1038
+ last_user_event.parse_data[INTENT][PREDICTED_CONFIDENCE_KEY] = 1.0 # type: ignore[literal-required]
1024
1039
 
1025
1040
  return revert_events + [last_user_event]
1026
1041
 
@@ -1037,8 +1052,8 @@ def _revert_single_affirmation_events() -> List[Event]:
1037
1052
 
1038
1053
  def _revert_successful_rephrasing(tracker: "DialogueStateTracker") -> List[Event]:
1039
1054
  last_user_event = tracker.get_last_event_for(UserUttered)
1040
- if not last_user_event:
1041
- raise TypeError("Cannot find last event to revert to.")
1055
+ if not last_user_event or not isinstance(last_user_event, UserUttered):
1056
+ raise TypeError("Cannot find last user uttered event to revert to.")
1042
1057
 
1043
1058
  last_user_event = copy.deepcopy(last_user_event)
1044
1059
  return _revert_rephrasing_events() + [last_user_event]
@@ -1138,9 +1153,9 @@ class ActionSendText(Action):
1138
1153
  metadata: Optional[Dict[Text, Any]] = None,
1139
1154
  ) -> List[Event]:
1140
1155
  """Runs action. Please see parent class for the full docstring."""
1141
- fallback = {"text": ""}
1156
+ fallback = {ACTION_METADATA_TEXT_KEY: ""}
1142
1157
  metadata_copy = copy.deepcopy(metadata) if metadata else {}
1143
- message = metadata_copy.get("message", fallback)
1158
+ message = metadata_copy.get(ACTION_METADATA_MESSAGE_KEY, fallback)
1144
1159
 
1145
1160
  should_send_text = metadata_copy.get("should_send_text", True)
1146
1161
  if should_send_text:
@@ -1148,6 +1163,32 @@ class ActionSendText(Action):
1148
1163
  return []
1149
1164
 
1150
1165
 
1166
+ class ActionAgentRequestUserInfo(Action):
1167
+ """Sends a text message to the output channel that requests some user information.
1168
+
1169
+ The difference to `ActionSendText` is that this action will pause the main advancing
1170
+ flow loop until the user responds to the request
1171
+ (`should_predict_another_action` will return False for this action).
1172
+ """
1173
+
1174
+ def name(self) -> Text:
1175
+ return ACTION_AGENT_REQUEST_USER_INPUT_NAME
1176
+
1177
+ async def run(
1178
+ self,
1179
+ output_channel: "OutputChannel",
1180
+ nlg: "NaturalLanguageGenerator",
1181
+ tracker: "DialogueStateTracker",
1182
+ domain: "Domain",
1183
+ metadata: Optional[Dict[Text, Any]] = None,
1184
+ ) -> List[Event]:
1185
+ """Runs action. Please see parent class for the full docstring."""
1186
+ fallback = {ACTION_METADATA_TEXT_KEY: ""}
1187
+ metadata_copy = copy.deepcopy(metadata) if metadata else {}
1188
+ message = metadata_copy.get(ACTION_METADATA_MESSAGE_KEY, fallback)
1189
+ return [create_bot_utterance(message)]
1190
+
1191
+
1151
1192
  class ActionExtractSlots(Action):
1152
1193
  """Default action that runs after each user turn.
1153
1194
 
@@ -2,7 +2,6 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text, Union
2
2
 
3
3
  import structlog
4
4
  from jinja2 import Template
5
- from pypred import Predicate
6
5
 
7
6
  from rasa.core.actions.action import Action, create_bot_utterance
8
7
  from rasa.core.utils import add_bot_utterance_metadata
@@ -21,6 +20,7 @@ from rasa.shared.core.slots import (
21
20
  Slot,
22
21
  SlotRejection,
23
22
  )
23
+ from rasa.utils.pypred import Predicate
24
24
 
25
25
  if TYPE_CHECKING:
26
26
  from rasa.core.channels.channel import OutputChannel