rasa-pro 3.14.0.dev20250922__py3-none-any.whl → 3.14.0rc1__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 (290) 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/tutorial/credentials.yml +10 -0
  52. rasa/cli/run.py +12 -10
  53. rasa/cli/scaffold.py +4 -4
  54. rasa/cli/shell.py +9 -5
  55. rasa/cli/studio/studio.py +1 -1
  56. rasa/cli/test.py +34 -14
  57. rasa/cli/train.py +41 -28
  58. rasa/cli/utils.py +1 -393
  59. rasa/cli/validation/__init__.py +0 -0
  60. rasa/cli/validation/bot_config.py +223 -0
  61. rasa/cli/validation/config_path_validation.py +257 -0
  62. rasa/cli/x.py +8 -4
  63. rasa/constants.py +7 -1
  64. rasa/core/actions/action.py +51 -10
  65. rasa/core/actions/grpc_custom_action_executor.py +1 -1
  66. rasa/core/agent.py +19 -2
  67. rasa/core/available_agents.py +229 -0
  68. rasa/core/channels/__init__.py +82 -35
  69. rasa/core/channels/development_inspector.py +3 -3
  70. rasa/core/channels/inspector/README.md +25 -13
  71. rasa/core/channels/inspector/dist/assets/{arc-35222594.js → arc-6177260a.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-a0efbfd3.js → blockDiagram-38ab4fdb-b054f038.js} +1 -1
  73. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-0584c0f2.js → c4Diagram-3d4e48cf-f25427d5.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/channel-bf9cbb34.js +1 -0
  75. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-39f40dbe.js → classDiagram-70f12bd4-c7a2af53.js} +1 -1
  76. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-1ad755f3.js → classDiagram-v2-f2320105-58db65c0.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/clone-8f9083bb.js +1 -0
  78. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-b0f4f0fe.js → createText-2e5e7dd3-088372e2.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-9039bff9.js → edges-e0da2a9e-58676240.js} +1 -1
  80. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-65c9b127.js → erDiagram-9861fffd-0c14d7c6.js} +1 -1
  81. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-4f08b38e.js → flowDb-956e92f1-ea63f85c.js} +1 -1
  82. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-e95c362a.js → flowDiagram-66a62f08-a2af48cd.js} +1 -1
  83. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-9ecd5b59.js +1 -0
  84. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-703c3015.js → flowchart-elk-definition-4a651766-6937abe7.js} +1 -1
  85. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-699328ea.js → ganttDiagram-c361ad54-7473f357.js} +1 -1
  86. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-04cf4b05.js → gitGraphDiagram-72cf32ee-d0c9405e.js} +1 -1
  87. rasa/core/channels/inspector/dist/assets/{graph-ee94449e.js → graph-0a6f8466.js} +1 -1
  88. rasa/core/channels/inspector/dist/assets/{index-3862675e-940162b4.js → index-3862675e-7610671a.js} +1 -1
  89. rasa/core/channels/inspector/dist/assets/index-74e01d94.js +1354 -0
  90. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-c79c2866.js → infoDiagram-f8f76790-be397dc7.js} +1 -1
  91. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-84489d30.js → journeyDiagram-49397b02-4cefbf62.js} +1 -1
  92. rasa/core/channels/inspector/dist/assets/{layout-a9aa9858.js → layout-e7fbc2bf.js} +1 -1
  93. rasa/core/channels/inspector/dist/assets/{line-eb73cf26.js → line-a8aa457c.js} +1 -1
  94. rasa/core/channels/inspector/dist/assets/{linear-b3399f9a.js → linear-3351e0d2.js} +1 -1
  95. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-b095bf1a.js → mindmap-definition-fc14e90a-b8cbf605.js} +1 -1
  96. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-07644b66.js → pieDiagram-8a3498a8-f327f774.js} +1 -1
  97. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-573a3f9c.js → quadrantDiagram-120e2f19-2854c591.js} +1 -1
  98. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-d457e1e1.js → requirementDiagram-deff3bca-964985d5.js} +1 -1
  99. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-9d26e1a2.js → sankeyDiagram-04a897e0-edeb4f33.js} +1 -1
  100. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3a9cde10.js → sequenceDiagram-704730f1-fcf70125.js} +1 -1
  101. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-4f3e8cec.js → stateDiagram-587899a1-0e770395.js} +1 -1
  102. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-e617e5bf.js → stateDiagram-v2-d93cdb3a-af8dcd22.js} +1 -1
  103. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-eab30d2f.js → styles-6aaf32cf-36a9e70d.js} +1 -1
  104. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-09994be2.js → styles-9a916d00-884a8b5b.js} +1 -1
  105. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-b7110364.js → styles-c10674c1-dc097813.js} +1 -1
  106. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-3ebc92ad.js → svgDrawCommon-08f97a94-5a2c7eed.js} +1 -1
  107. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-7d13d2f2.js → timeline-definition-85554ec2-e89c4f6e.js} +1 -1
  108. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-488385e1.js → xychartDiagram-e933f94c-afb6fe56.js} +1 -1
  109. rasa/core/channels/inspector/dist/index.html +1 -1
  110. rasa/core/channels/inspector/package.json +18 -18
  111. rasa/core/channels/inspector/src/App.tsx +29 -4
  112. rasa/core/channels/inspector/src/components/DialogueAgentStack.tsx +108 -0
  113. rasa/core/channels/inspector/src/components/{DialogueStack.tsx → DialogueHistoryStack.tsx} +4 -2
  114. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +7 -4
  115. rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -0
  116. rasa/core/channels/inspector/src/helpers/formatters.ts +24 -3
  117. rasa/core/channels/inspector/src/helpers/utils.test.ts +127 -0
  118. rasa/core/channels/inspector/src/helpers/utils.ts +66 -1
  119. rasa/core/channels/inspector/src/theme/base/styles.ts +19 -1
  120. rasa/core/channels/inspector/src/types.ts +21 -0
  121. rasa/core/channels/inspector/yarn.lock +336 -189
  122. rasa/core/channels/studio_chat.py +6 -6
  123. rasa/core/channels/telegram.py +4 -9
  124. rasa/core/channels/voice_stream/genesys.py +1 -1
  125. rasa/core/channels/voice_stream/tts/deepgram.py +140 -0
  126. rasa/core/channels/voice_stream/twilio_media_streams.py +5 -1
  127. rasa/core/channels/voice_stream/voice_channel.py +3 -0
  128. rasa/core/config/__init__.py +0 -0
  129. rasa/core/{available_endpoints.py → config/available_endpoints.py} +51 -16
  130. rasa/core/config/configuration.py +260 -0
  131. rasa/core/config/credentials.py +19 -0
  132. rasa/core/config/message_procesing_config.py +34 -0
  133. rasa/core/constants.py +4 -0
  134. rasa/core/policies/enterprise_search_policy.py +5 -3
  135. rasa/core/policies/flow_policy.py +4 -4
  136. rasa/core/policies/flows/agent_executor.py +632 -0
  137. rasa/core/policies/flows/flow_executor.py +136 -75
  138. rasa/core/policies/flows/mcp_tool_executor.py +298 -0
  139. rasa/core/policies/intentless_policy.py +1 -1
  140. rasa/core/policies/ted_policy.py +20 -12
  141. rasa/core/policies/unexpected_intent_policy.py +6 -0
  142. rasa/core/processor.py +68 -44
  143. rasa/core/run.py +37 -8
  144. rasa/core/test.py +4 -0
  145. rasa/core/tracker_stores/tracker_store.py +3 -7
  146. rasa/core/train.py +1 -1
  147. rasa/core/training/interactive.py +20 -18
  148. rasa/core/training/story_conflict.py +5 -5
  149. rasa/core/utils.py +22 -23
  150. rasa/dialogue_understanding/commands/__init__.py +8 -0
  151. rasa/dialogue_understanding/commands/cancel_flow_command.py +19 -5
  152. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +21 -2
  153. rasa/dialogue_understanding/commands/clarify_command.py +20 -2
  154. rasa/dialogue_understanding/commands/continue_agent_command.py +91 -0
  155. rasa/dialogue_understanding/commands/knowledge_answer_command.py +21 -2
  156. rasa/dialogue_understanding/commands/restart_agent_command.py +162 -0
  157. rasa/dialogue_understanding/commands/start_flow_command.py +68 -7
  158. rasa/dialogue_understanding/commands/utils.py +124 -2
  159. rasa/dialogue_understanding/generator/command_parser.py +4 -0
  160. rasa/dialogue_understanding/generator/llm_based_command_generator.py +50 -12
  161. rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
  162. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +1 -1
  163. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +66 -0
  164. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +66 -0
  165. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +89 -0
  166. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +88 -0
  167. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +42 -7
  168. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +40 -3
  169. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +20 -3
  170. rasa/dialogue_understanding/patterns/cancel.py +27 -6
  171. rasa/dialogue_understanding/patterns/clarify.py +3 -14
  172. rasa/dialogue_understanding/patterns/continue_interrupted.py +239 -6
  173. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +46 -8
  174. rasa/dialogue_understanding/processor/command_processor.py +136 -15
  175. rasa/dialogue_understanding/stack/dialogue_stack.py +98 -2
  176. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +57 -0
  177. rasa/dialogue_understanding/stack/utils.py +57 -3
  178. rasa/dialogue_understanding/utils.py +24 -4
  179. rasa/dialogue_understanding_test/du_test_runner.py +8 -3
  180. rasa/e2e_test/e2e_test_runner.py +13 -3
  181. rasa/engine/caching.py +2 -2
  182. rasa/engine/constants.py +1 -1
  183. rasa/engine/recipes/default_components.py +138 -49
  184. rasa/engine/recipes/default_recipe.py +108 -11
  185. rasa/engine/runner/dask.py +8 -5
  186. rasa/engine/validation.py +19 -6
  187. rasa/graph_components/validators/default_recipe_validator.py +86 -28
  188. rasa/hooks.py +5 -5
  189. rasa/llm_fine_tuning/utils.py +2 -2
  190. rasa/model_training.py +60 -47
  191. rasa/nlu/classifiers/diet_classifier.py +198 -98
  192. rasa/nlu/classifiers/logistic_regression_classifier.py +1 -4
  193. rasa/nlu/classifiers/mitie_intent_classifier.py +3 -0
  194. rasa/nlu/classifiers/sklearn_intent_classifier.py +1 -3
  195. rasa/nlu/extractors/crf_entity_extractor.py +9 -10
  196. rasa/nlu/extractors/mitie_entity_extractor.py +3 -0
  197. rasa/nlu/extractors/spacy_entity_extractor.py +3 -0
  198. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +4 -0
  199. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +5 -0
  200. rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +2 -0
  201. rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +3 -0
  202. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +4 -2
  203. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -0
  204. rasa/nlu/selectors/response_selector.py +10 -2
  205. rasa/nlu/tokenizers/jieba_tokenizer.py +3 -4
  206. rasa/nlu/tokenizers/mitie_tokenizer.py +3 -2
  207. rasa/nlu/tokenizers/spacy_tokenizer.py +3 -2
  208. rasa/nlu/utils/mitie_utils.py +3 -0
  209. rasa/nlu/utils/spacy_utils.py +3 -2
  210. rasa/plugin.py +8 -8
  211. rasa/privacy/privacy_manager.py +12 -3
  212. rasa/server.py +15 -3
  213. rasa/shared/agents/__init__.py +0 -0
  214. rasa/shared/agents/auth/__init__.py +0 -0
  215. rasa/shared/agents/auth/agent_auth_factory.py +105 -0
  216. rasa/shared/agents/auth/agent_auth_manager.py +92 -0
  217. rasa/shared/agents/auth/auth_strategy/__init__.py +19 -0
  218. rasa/shared/agents/auth/auth_strategy/agent_auth_strategy.py +52 -0
  219. rasa/shared/agents/auth/auth_strategy/api_key_auth_strategy.py +42 -0
  220. rasa/shared/agents/auth/auth_strategy/bearer_token_auth_strategy.py +28 -0
  221. rasa/shared/agents/auth/auth_strategy/oauth2_auth_strategy.py +167 -0
  222. rasa/shared/agents/auth/constants.py +12 -0
  223. rasa/shared/agents/auth/types.py +12 -0
  224. rasa/shared/agents/utils.py +35 -0
  225. rasa/shared/constants.py +8 -0
  226. rasa/shared/core/constants.py +16 -1
  227. rasa/shared/core/domain.py +0 -7
  228. rasa/shared/core/events.py +327 -0
  229. rasa/shared/core/flows/constants.py +5 -0
  230. rasa/shared/core/flows/flows_list.py +21 -5
  231. rasa/shared/core/flows/flows_yaml_schema.json +119 -184
  232. rasa/shared/core/flows/steps/call.py +49 -5
  233. rasa/shared/core/flows/steps/collect.py +98 -13
  234. rasa/shared/core/flows/validation.py +372 -8
  235. rasa/shared/core/flows/yaml_flows_io.py +3 -2
  236. rasa/shared/core/slots.py +2 -2
  237. rasa/shared/core/trackers.py +5 -2
  238. rasa/shared/exceptions.py +16 -0
  239. rasa/shared/importers/rasa.py +1 -1
  240. rasa/shared/importers/utils.py +9 -3
  241. rasa/shared/providers/llm/_base_litellm_client.py +41 -9
  242. rasa/shared/providers/llm/litellm_router_llm_client.py +8 -4
  243. rasa/shared/providers/llm/llm_client.py +7 -3
  244. rasa/shared/providers/llm/llm_response.py +66 -0
  245. rasa/shared/providers/llm/self_hosted_llm_client.py +8 -4
  246. rasa/shared/utils/common.py +24 -0
  247. rasa/shared/utils/health_check/health_check.py +7 -3
  248. rasa/shared/utils/llm.py +39 -16
  249. rasa/shared/utils/mcp/__init__.py +0 -0
  250. rasa/shared/utils/mcp/server_connection.py +247 -0
  251. rasa/shared/utils/mcp/utils.py +20 -0
  252. rasa/shared/utils/schemas/events.py +42 -0
  253. rasa/shared/utils/yaml.py +3 -1
  254. rasa/studio/pull/pull.py +3 -2
  255. rasa/studio/train.py +8 -7
  256. rasa/studio/upload.py +3 -6
  257. rasa/telemetry.py +69 -5
  258. rasa/tracing/config.py +45 -12
  259. rasa/tracing/constants.py +14 -0
  260. rasa/tracing/instrumentation/attribute_extractors.py +142 -9
  261. rasa/tracing/instrumentation/instrumentation.py +626 -21
  262. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +4 -4
  263. rasa/tracing/instrumentation/metrics.py +32 -0
  264. rasa/tracing/metric_instrument_provider.py +68 -0
  265. rasa/utils/common.py +92 -1
  266. rasa/utils/endpoints.py +11 -2
  267. rasa/utils/log_utils.py +96 -5
  268. rasa/utils/ml_utils.py +1 -1
  269. rasa/utils/tensorflow/__init__.py +7 -0
  270. rasa/utils/tensorflow/callback.py +136 -101
  271. rasa/utils/tensorflow/crf.py +1 -1
  272. rasa/utils/tensorflow/data_generator.py +21 -8
  273. rasa/utils/tensorflow/layers.py +21 -11
  274. rasa/utils/tensorflow/metrics.py +7 -3
  275. rasa/utils/tensorflow/models.py +56 -8
  276. rasa/utils/tensorflow/rasa_layers.py +8 -6
  277. rasa/utils/tensorflow/transformer.py +2 -3
  278. rasa/utils/train_utils.py +54 -24
  279. rasa/validator.py +5 -5
  280. rasa/version.py +1 -1
  281. {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/METADATA +46 -41
  282. {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/RECORD +285 -226
  283. rasa/builder/scrape_rasa_docs.py +0 -97
  284. rasa/core/channels/inspector/dist/assets/channel-8e08bed9.js +0 -1
  285. rasa/core/channels/inspector/dist/assets/clone-78c82dea.js +0 -1
  286. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b08f601.js +0 -1
  287. rasa/core/channels/inspector/dist/assets/index-c941dcb3.js +0 -1336
  288. {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/NOTICE +0 -0
  289. {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/WHEEL +0 -0
  290. {rasa_pro-3.14.0.dev20250922.dist-info → rasa_pro-3.14.0rc1.dist-info}/entry_points.txt +0 -0
rasa/cli/train.py CHANGED
@@ -7,10 +7,13 @@ from typing import Dict, List, Optional, Text, Union
7
7
  import structlog
8
8
 
9
9
  import rasa.cli.arguments.train as train_arguments
10
- import rasa.cli.utils
11
- import rasa.core.utils
12
- import rasa.utils.common
13
10
  from rasa.cli import SubParsersAction
11
+ from rasa.cli.validation.bot_config import validate_files
12
+ from rasa.cli.validation.config_path_validation import (
13
+ get_validated_config,
14
+ get_validated_path,
15
+ )
16
+ from rasa.core.config.configuration import Configuration
14
17
  from rasa.core.nlg.contextual_response_rephraser import ContextualResponseRephraser
15
18
  from rasa.core.nlg.generator import NaturalLanguageGenerator
16
19
  from rasa.core.train import do_compare_training
@@ -74,7 +77,9 @@ def add_subparser(
74
77
 
75
78
  def _check_nlg_endpoint_validity(endpoint: Union[Path, str]) -> None:
76
79
  try:
77
- endpoints = rasa.core.utils.read_endpoints_from_path(endpoint)
80
+ endpoints = Configuration.initialise_endpoints(
81
+ endpoints_path=endpoint
82
+ ).endpoints
78
83
  if endpoints.nlg is not None:
79
84
  validate_api_type_config_key_usage(
80
85
  endpoints.nlg.kwargs,
@@ -115,21 +120,17 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
115
120
  """
116
121
  from rasa.api import train as train_all
117
122
 
118
- domain = rasa.cli.utils.get_validated_path(
123
+ domain = get_validated_path(
119
124
  args.domain, "domain", DEFAULT_DOMAIN_PATHS, none_is_valid=True
120
125
  )
121
- config = rasa.cli.utils.get_validated_config(args.config, CONFIG_MANDATORY_KEYS)
126
+ config = get_validated_config(args.config, CONFIG_MANDATORY_KEYS)
122
127
 
123
128
  # Validates and loads endpoints with proper endpoint file location
124
- # This will initialise the endpoints singleton properly so that
125
- # it can be used safely throughout the codebase with
126
- # `AvailableEndpoints.get_instance()`
129
+ # TODO(Radovan): this should be probably be done in Configuration
127
130
  _check_nlg_endpoint_validity(args.endpoints)
128
131
 
129
132
  training_files = [
130
- rasa.cli.utils.get_validated_path(
131
- f, "data", DEFAULT_DATA_PATH, none_is_valid=True
132
- )
133
+ get_validated_path(f, "data", DEFAULT_DATA_PATH, none_is_valid=True)
133
134
  for f in args.data
134
135
  ]
135
136
 
@@ -143,15 +144,17 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
143
144
  event_info="Started validating domain and training data...",
144
145
  )
145
146
 
146
- rasa.cli.utils.validate_files(
147
+ validate_files(
147
148
  args.fail_on_validation_warnings,
148
149
  args.validation_max_history,
149
150
  training_data_importer,
151
+ sub_agents=args.sub_agents,
150
152
  )
151
153
 
152
154
  training_result = train_all(
153
155
  domain=domain,
154
156
  config=config,
157
+ endpoints=args.endpoints,
155
158
  training_files=training_files,
156
159
  output=args.out,
157
160
  dry_run=args.dry_run,
@@ -168,6 +171,7 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
168
171
  file_importer=training_data_importer,
169
172
  keep_local_model_copy=args.keep_local_model_copy,
170
173
  remote_root_only=args.remote_root_only,
174
+ sub_agents=args.sub_agents,
171
175
  )
172
176
  if training_result.code != 0 and can_exit:
173
177
  display_research_study_prompt()
@@ -177,13 +181,19 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
177
181
 
178
182
 
179
183
  def _model_for_finetuning(args: argparse.Namespace) -> Optional[Text]:
180
- if args.finetune == train_arguments.USE_LATEST_MODEL_FOR_FINE_TUNING:
181
- # We use this constant to signal that the user specified `--finetune` but
182
- # didn't provide a path to a model. In this case we try to load the latest
183
- # model from the output directory (that's usually models/).
184
- return args.out
185
- else:
186
- return args.finetune
184
+ if args.finetune is not None:
185
+ structlogger.error(
186
+ "cli.train.incremental_training_not_supported",
187
+ event_info=(
188
+ "Incremental training (--finetune) is "
189
+ "not supported in Rasa 3.14.0 onwards. "
190
+ "Please retrain your model from scratch "
191
+ "if you have updated your configuration. "
192
+ ),
193
+ )
194
+ display_research_study_prompt()
195
+ sys.exit(1)
196
+ return None
187
197
 
188
198
 
189
199
  def run_core_training(args: argparse.Namespace) -> Optional[Text]:
@@ -197,10 +207,10 @@ def run_core_training(args: argparse.Namespace) -> Optional[Text]:
197
207
  """
198
208
  from rasa.model_training import train_core
199
209
 
200
- args.domain = rasa.cli.utils.get_validated_path(
210
+ args.domain = get_validated_path(
201
211
  args.domain, "domain", DEFAULT_DOMAIN_PATHS, none_is_valid=True
202
212
  )
203
- story_file = rasa.cli.utils.get_validated_path(
213
+ story_file = get_validated_path(
204
214
  args.stories, "stories", DEFAULT_DATA_PATH, none_is_valid=True
205
215
  )
206
216
  additional_arguments = {
@@ -213,9 +223,11 @@ def run_core_training(args: argparse.Namespace) -> Optional[Text]:
213
223
  if isinstance(args.config, list):
214
224
  args.config = args.config[0]
215
225
 
216
- config = rasa.cli.utils.get_validated_config(
217
- args.config, CONFIG_MANDATORY_KEYS_CORE
218
- )
226
+ config = get_validated_config(args.config, CONFIG_MANDATORY_KEYS_CORE)
227
+
228
+ Configuration.initialise_message_processing(
229
+ message_processing_config_path=Path(config)
230
+ ).initialise_empty_endpoints()
219
231
 
220
232
  return asyncio.run(
221
233
  train_core(
@@ -231,6 +243,7 @@ def run_core_training(args: argparse.Namespace) -> Optional[Text]:
231
243
  )
232
244
  )
233
245
  else:
246
+ Configuration.initialise_empty()
234
247
  asyncio.run(do_compare_training(args, story_file, additional_arguments))
235
248
  return None
236
249
 
@@ -246,13 +259,13 @@ def run_nlu_training(args: argparse.Namespace) -> Optional[Text]:
246
259
  """
247
260
  from rasa.model_training import train_nlu
248
261
 
249
- config = rasa.cli.utils.get_validated_config(args.config, CONFIG_MANDATORY_KEYS_NLU)
250
- nlu_data = rasa.cli.utils.get_validated_path(
262
+ config = get_validated_config(args.config, CONFIG_MANDATORY_KEYS_NLU)
263
+ nlu_data = get_validated_path(
251
264
  args.nlu, "nlu", DEFAULT_DATA_PATH, none_is_valid=True
252
265
  )
253
266
 
254
267
  if args.domain:
255
- args.domain = rasa.cli.utils.get_validated_path(
268
+ args.domain = get_validated_path(
256
269
  args.domain, "domain", DEFAULT_DOMAIN_PATHS, none_is_valid=True
257
270
  )
258
271
 
rasa/cli/utils.py CHANGED
@@ -1,415 +1,23 @@
1
- import argparse
2
1
  import importlib
3
2
  import json
4
3
  import os
5
4
  import sys
6
- import time
7
5
  from pathlib import Path
8
6
  from types import FrameType
9
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text, Union, overload
7
+ from typing import TYPE_CHECKING, Any, Dict, List, Text
10
8
 
11
- import randomname
12
9
  import structlog
13
10
 
14
- import rasa.shared.utils.cli
15
11
  import rasa.shared.utils.io
16
- from rasa import telemetry
17
- from rasa.exceptions import ModelNotFound, ValidationError
18
- from rasa.shared.constants import (
19
- ASSISTANT_ID_DEFAULT_VALUE,
20
- ASSISTANT_ID_KEY,
21
- DEFAULT_CONFIG_PATH,
22
- )
23
- from rasa.shared.importers.importer import TrainingDataImporter
24
- from rasa.shared.utils.common import display_research_study_prompt
25
- from rasa.shared.utils.yaml import read_config_file
26
- from rasa.utils.io import write_yaml
27
12
 
28
13
  if TYPE_CHECKING:
29
14
  from questionary import Question
30
- from typing_extensions import Literal
31
-
32
- from rasa.validator import Validator
33
15
 
34
16
  structlogger = structlog.get_logger()
35
17
 
36
18
  FREE_TEXT_INPUT_PROMPT = "Type out your own message..."
37
19
 
38
20
 
39
- @overload
40
- def get_validated_path(
41
- current: Optional[Union[Path, Text]],
42
- parameter: Text,
43
- default: Optional[Union[Path, Text, List[Text]]] = ...,
44
- none_is_valid: "Literal[False]" = ...,
45
- ) -> Union[Path, Text]: ...
46
-
47
-
48
- @overload
49
- def get_validated_path(
50
- current: Optional[Union[Path, Text]],
51
- parameter: Text,
52
- default: Optional[Union[Path, Text, List[Text]]] = ...,
53
- none_is_valid: "Literal[True]" = ...,
54
- ) -> Optional[Union[Path, Text]]: ...
55
-
56
-
57
- def get_validated_path(
58
- current: Optional[Union[Path, Text]],
59
- parameter: Text,
60
- default: Optional[Union[Path, Text, List[Text]]] = None,
61
- none_is_valid: bool = False,
62
- ) -> Optional[Union[Path, Text]]:
63
- """Checks whether a file path or its default value is valid and returns it.
64
-
65
- Args:
66
- current: The parsed value.
67
- parameter: The name of the parameter.
68
- default: one or multiple default values of the parameter.
69
- none_is_valid: `True` if `None` is valid value for the path,
70
- else `False``
71
-
72
- Returns:
73
- The current value if valid,
74
- otherwise one of the default values of the argument if valid,
75
- otherwise `None` if allowed,
76
- otherwise raises an error and exits.
77
- """
78
- if current and os.path.exists(current):
79
- return current
80
-
81
- if parameter == "model":
82
- raise ModelNotFound(
83
- f"The provided model path '{current}' could not be found. "
84
- "Provide an existing model path."
85
- )
86
-
87
- # try to find a valid option among the defaults
88
- if isinstance(default, str) or isinstance(default, Path):
89
- default_options = [str(default)]
90
- elif isinstance(default, list):
91
- default_options = default
92
- else:
93
- default_options = []
94
-
95
- valid_options = (option for option in default_options if os.path.exists(option))
96
- chosen_option = next(valid_options, None)
97
-
98
- # warn and log if user-chosen parameter wasn't found and thus overwritten
99
- if chosen_option:
100
- shared_info = f"Using default location '{chosen_option}' instead."
101
- if current is None:
102
- structlogger.debug(
103
- "cli.get_validated_path.parameter_not_set",
104
- parameter=parameter,
105
- event_info=(f"Parameter '{parameter}' was not set. {shared_info}"),
106
- )
107
- elif current not in default_options:
108
- structlogger.warn(
109
- "cli.get_validated_path.path_does_not_exists",
110
- path=current,
111
- event_info=(
112
- f"The path '{current}' does not seem to exist. {shared_info}"
113
- ),
114
- )
115
-
116
- if chosen_option is None and not none_is_valid:
117
- cancel_cause_not_found(current, parameter, default)
118
-
119
- return chosen_option
120
-
121
-
122
- def missing_config_keys(
123
- path: Union["Path", Text], mandatory_keys: List[Text]
124
- ) -> List[Text]:
125
- """Checks whether the config file at `path` contains the `mandatory_keys`.
126
-
127
- Args:
128
- path: The path to the config file.
129
- mandatory_keys: A list of mandatory config keys.
130
-
131
- Returns:
132
- The list of missing config keys.
133
- """
134
- if not os.path.exists(path):
135
- return mandatory_keys
136
-
137
- config_data = read_config_file(path)
138
-
139
- return [k for k in mandatory_keys if k not in config_data or config_data[k] is None]
140
-
141
-
142
- def validate_assistant_id_in_config(config_file: Union["Path", Text]) -> None:
143
- """Verifies that the assistant_id key exists and has a unique value in config.
144
-
145
- Issues a warning if the key does not exist or has the default value and replaces it
146
- with a pseudo-random string value.
147
- """
148
- config_data = read_config_file(config_file, reader_type=["safe", "rt"])
149
- assistant_id = config_data.get(ASSISTANT_ID_KEY)
150
-
151
- if assistant_id is None or assistant_id == ASSISTANT_ID_DEFAULT_VALUE:
152
- structlogger.warn(
153
- "cli.validate_assistant_id_in_config.missing_unique_assistant_id_key",
154
- config=config_file,
155
- missing_key=ASSISTANT_ID_KEY,
156
- event_info=(
157
- f"The config file '{config_file!s}' is "
158
- f"missing a unique value for the "
159
- f"'{ASSISTANT_ID_KEY}' mandatory key. "
160
- f"Proceeding with generating a random "
161
- f"value and overwriting the '{ASSISTANT_ID_KEY}'"
162
- f" in the config file."
163
- ),
164
- )
165
-
166
- # add random value for assistant id, overwrite config file
167
- time_format = "%Y%m%d-%H%M%S"
168
- config_data[ASSISTANT_ID_KEY] = (
169
- f"{time.strftime(time_format)}-{randomname.get_name()}"
170
- )
171
-
172
- write_yaml(data=config_data, target=config_file, should_preserve_key_order=True)
173
-
174
- return
175
-
176
-
177
- def validate_config_path(
178
- config: Optional[Union[Text, "Path"]],
179
- default_config: Text = DEFAULT_CONFIG_PATH,
180
- ) -> Text:
181
- """Verifies that the config path exists.
182
-
183
- Exit if the config file does not exist.
184
-
185
- Args:
186
- config: Path to the config file.
187
- default_config: default config to use if the file at `config` doesn't exist.
188
-
189
- Returns: The path to the config file.
190
- """
191
- config = rasa.cli.utils.get_validated_path(config, "config", default_config)
192
-
193
- if not config or not os.path.exists(config):
194
- display_research_study_prompt()
195
- raise ValidationError(
196
- code="cli.validate_config_path.does_not_exists",
197
- config=config,
198
- event_info=(
199
- f"The config file '{config}' does not exist. "
200
- f"Use '--config' to specify a valid config file."
201
- ),
202
- )
203
-
204
- return str(config)
205
-
206
-
207
- def validate_mandatory_config_keys(
208
- config: Union[Text, "Path"],
209
- mandatory_keys: List[Text],
210
- ) -> Text:
211
- """Get a config from a config file and check if it is valid.
212
-
213
- Exit if the config isn't valid.
214
-
215
- Args:
216
- config: Path to the config file.
217
- mandatory_keys: The keys that have to be specified in the config file.
218
-
219
- Returns: The path to the config file if the config is valid.
220
- """
221
- missing_keys = set(rasa.cli.utils.missing_config_keys(config, mandatory_keys))
222
- if missing_keys:
223
- display_research_study_prompt()
224
- raise ValidationError(
225
- code="cli.validate_mandatory_config_keys.missing_keys",
226
- config=config,
227
- missing_keys=missing_keys,
228
- event_info=(
229
- "The config file '{}' is missing mandatory parameters: "
230
- "'{}'. Add missing parameters to config file and try again.".format(
231
- config, "', '".join(missing_keys)
232
- )
233
- ),
234
- )
235
-
236
- return str(config)
237
-
238
-
239
- def get_validated_config(
240
- config: Optional[Union[Text, "Path"]],
241
- mandatory_keys: List[Text],
242
- default_config: Text = DEFAULT_CONFIG_PATH,
243
- ) -> Text:
244
- """Validates config and returns path to validated config file."""
245
- config = validate_config_path(config, default_config)
246
- validate_assistant_id_in_config(config)
247
-
248
- config = validate_mandatory_config_keys(config, mandatory_keys)
249
-
250
- return config
251
-
252
-
253
- def validate_files(
254
- fail_on_warnings: bool,
255
- max_history: Optional[int],
256
- importer: TrainingDataImporter,
257
- stories_only: bool = False,
258
- flows_only: bool = False,
259
- translations_only: bool = False,
260
- ) -> None:
261
- """Validates either the story structure or the entire project.
262
-
263
- Args:
264
- fail_on_warnings: `True` if the process should exit with a non-zero status
265
- max_history: The max history to use when validating the story structure.
266
- importer: The `TrainingDataImporter` to use to load the training data.
267
- stories_only: If `True`, only the story structure is validated.
268
- flows_only: If `True`, only the flows are validated.
269
- translations_only: If `True`, only the translations data is validated.
270
- """
271
- from rasa.validator import Validator
272
-
273
- validator = Validator.from_importer(importer)
274
-
275
- if stories_only:
276
- all_good = _validate_story_structure(validator, max_history, fail_on_warnings)
277
- elif flows_only:
278
- all_good = validator.verify_flows()
279
- elif translations_only:
280
- all_good = validator.verify_translations()
281
- else:
282
- if importer.get_domain().is_empty():
283
- structlogger.error(
284
- "cli.validate_files.empty_domain",
285
- event_info="Encountered empty domain during validation.",
286
- )
287
- display_research_study_prompt()
288
- raise ValidationError(
289
- code="cli.validate_files.empty_domain",
290
- event_info="Encountered empty domain during validation.",
291
- )
292
-
293
- valid_domain = _validate_domain(validator)
294
- valid_nlu = _validate_nlu(validator, fail_on_warnings)
295
- valid_stories = _validate_story_structure(
296
- validator, max_history, fail_on_warnings
297
- )
298
- valid_flows = validator.verify_flows()
299
- if validator.config:
300
- valid_translations = validator.verify_translations(summary_mode=True)
301
- else:
302
- valid_translations = True
303
- valid_CALM_slot_mappings = validator.validate_CALM_slot_mappings()
304
-
305
- all_good = (
306
- valid_domain
307
- and valid_nlu
308
- and valid_stories
309
- and valid_flows
310
- and valid_translations
311
- and valid_CALM_slot_mappings
312
- )
313
-
314
- if validator.config:
315
- validator.warn_if_config_mandatory_keys_are_not_set()
316
-
317
- telemetry.track_validate_files(all_good)
318
- if not all_good:
319
- structlogger.error(
320
- "cli.validate_files.project_validation_error",
321
- event_info="Project validation completed with errors.",
322
- )
323
- display_research_study_prompt()
324
- raise ValidationError(
325
- code="cli.validate_files.project_validation_error",
326
- event_info="Project validation completed with errors.",
327
- )
328
-
329
-
330
- def _validate_domain(validator: "Validator") -> bool:
331
- valid_domain_validity = validator.verify_domain_validity()
332
- valid_actions_in_stories_rules = validator.verify_actions_in_stories_rules()
333
- valid_forms_in_stories_rules = validator.verify_forms_in_stories_rules()
334
- valid_form_slots = validator.verify_form_slots()
335
- valid_slot_mappings = validator.verify_slot_mappings()
336
- valid_responses = validator.check_for_no_empty_parenthesis_in_responses()
337
- valid_buttons = validator.validate_button_payloads()
338
- valid_slot_validation = validator.verify_slot_validation()
339
- valid_conditional_responses = (
340
- validator.validate_conditional_response_variation_predicates()
341
- )
342
- return (
343
- valid_domain_validity
344
- and valid_actions_in_stories_rules
345
- and valid_forms_in_stories_rules
346
- and valid_form_slots
347
- and valid_slot_mappings
348
- and valid_responses
349
- and valid_buttons
350
- and valid_slot_validation
351
- and valid_conditional_responses
352
- )
353
-
354
-
355
- def _validate_nlu(validator: "Validator", fail_on_warnings: bool) -> bool:
356
- return validator.verify_nlu(not fail_on_warnings)
357
-
358
-
359
- def _validate_story_structure(
360
- validator: "Validator", max_history: Optional[int], fail_on_warnings: bool
361
- ) -> bool:
362
- # Check if a valid setting for `max_history` was given
363
- if isinstance(max_history, int) and max_history < 1:
364
- raise argparse.ArgumentTypeError(
365
- f"The value of `--max-history {max_history}` is not a positive integer."
366
- )
367
-
368
- return validator.verify_story_structure(
369
- not fail_on_warnings, max_history=max_history
370
- )
371
-
372
-
373
- def cancel_cause_not_found(
374
- current: Optional[Union["Path", Text]],
375
- parameter: Text,
376
- default: Optional[Union["Path", Text, List[Text]]],
377
- ) -> None:
378
- """Exits with an error because the given path was not valid.
379
-
380
- Args:
381
- current: The path given by the user.
382
- parameter: The name of the parameter.
383
- default: The default value of the parameter.
384
-
385
- """
386
- default_clause = ""
387
- if default and isinstance(default, str):
388
- default_clause = f"use the default location ('{default}') or"
389
- elif default and isinstance(default, list):
390
- default_clause = f"use one of the default locations ({', '.join(default)}) or"
391
-
392
- structlogger.error(
393
- "cli.path_does_not_exist",
394
- path=current,
395
- event_info=(
396
- f"The path '{current}' does not exist. "
397
- f"Please make sure to {default_clause} specify it "
398
- f"with '--{parameter}'."
399
- ),
400
- )
401
- display_research_study_prompt()
402
- raise ValidationError(
403
- code="cli.path_does_not_exist",
404
- path=current,
405
- event_info=(
406
- f"The path '{current}' does not exist. "
407
- f"Please make sure to {default_clause} specify it "
408
- f"with '--{parameter}'."
409
- ),
410
- )
411
-
412
-
413
21
  def parse_last_positional_argument_as_model_path() -> None:
414
22
  """Fixes the parsing of a potential positional model path argument."""
415
23
  if (
File without changes