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
@@ -0,0 +1,52 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, AsyncGenerator, Dict
3
+
4
+ import httpx
5
+
6
+ from rasa.shared.agents.auth.types import AgentAuthType
7
+ from rasa.shared.utils.io import resolve_environment_variables
8
+
9
+
10
+ class AgentAuthStrategy(ABC, httpx.Auth):
11
+ """Base class for authentication strategies."""
12
+
13
+ @classmethod
14
+ @abstractmethod
15
+ def from_config(cls, config: Dict[str, Any]) -> "AgentAuthStrategy":
16
+ """Create an authentication strategy instance from a config dictionary."""
17
+ ...
18
+
19
+ @property
20
+ @abstractmethod
21
+ def auth_type(self) -> AgentAuthType:
22
+ """Return the type of the authentication strategy."""
23
+ ...
24
+
25
+ @abstractmethod
26
+ async def get_headers(self) -> Dict[str, str]:
27
+ """Get authentication headers for requests.
28
+
29
+ Returns:
30
+ Dictionary containing authentication headers.
31
+ """
32
+ ...
33
+
34
+ async def async_auth_flow(
35
+ self, request: httpx.Request
36
+ ) -> AsyncGenerator[httpx.Request, httpx.Response]:
37
+ """Get authentication headers for requests.
38
+
39
+ Returns:
40
+ Async generator of requests with authentication headers.
41
+ """
42
+ # Get authentication headers.
43
+ auth_headers = await self.get_headers()
44
+
45
+ # Resolve environment variables in authentication headers.
46
+ resolved_auth_headers = resolve_environment_variables(auth_headers)
47
+
48
+ # Update request headers with resolved authentication headers.
49
+ request.headers.update(resolved_auth_headers)
50
+
51
+ # Yield request with resolved authentication headers.
52
+ yield request
@@ -0,0 +1,42 @@
1
+ """API Key authentication strategy implementation."""
2
+
3
+ from typing import Any, Dict
4
+
5
+ from rasa.shared.agents.auth.auth_strategy import AgentAuthStrategy
6
+ from rasa.shared.agents.auth.constants import (
7
+ CONFIG_API_KEY_KEY,
8
+ CONFIG_HEADER_FORMAT_KEY,
9
+ CONFIG_HEADER_NAME_KEY,
10
+ )
11
+ from rasa.shared.agents.auth.types import AgentAuthType
12
+
13
+
14
+ class APIKeyAuthStrategy(AgentAuthStrategy):
15
+ """API Key authentication strategy implementation."""
16
+
17
+ def __init__(
18
+ self,
19
+ api_key: str,
20
+ header_name: str = "Authorization",
21
+ header_format: str = "Bearer {key}",
22
+ ):
23
+ self.api_key = api_key
24
+ self.header_name = header_name
25
+ self.header_format = header_format
26
+
27
+ @classmethod
28
+ def from_config(cls, config: Dict[str, Any]) -> "APIKeyAuthStrategy":
29
+ api_key = config.get(CONFIG_API_KEY_KEY)
30
+ header_name = config.get(CONFIG_HEADER_NAME_KEY, "Authorization")
31
+ header_format = config.get(CONFIG_HEADER_FORMAT_KEY, "Bearer {key}")
32
+ if not api_key:
33
+ raise ValueError("API key is required for API KEY authentication")
34
+ return APIKeyAuthStrategy(api_key, header_name, header_format)
35
+
36
+ @property
37
+ def auth_type(self) -> AgentAuthType:
38
+ return AgentAuthType.API_KEY
39
+
40
+ async def get_headers(self) -> Dict[str, str]:
41
+ """Return API key authentication headers."""
42
+ return {self.header_name: self.header_format.format(key=self.api_key)}
@@ -0,0 +1,28 @@
1
+ """Bearer Token authentication strategy implementation."""
2
+
3
+ from typing import Any, Dict
4
+
5
+ from rasa.shared.agents.auth.auth_strategy import AgentAuthStrategy
6
+ from rasa.shared.agents.auth.constants import CONFIG_TOKEN_KEY
7
+ from rasa.shared.agents.auth.types import AgentAuthType
8
+
9
+
10
+ class BearerTokenAuthStrategy(AgentAuthStrategy):
11
+ """Bearer Token authentication strategy implementation."""
12
+
13
+ def __init__(self, token: str):
14
+ self._token = token
15
+
16
+ @classmethod
17
+ def from_config(cls, config: Dict[str, Any]) -> "BearerTokenAuthStrategy":
18
+ token = config.get(CONFIG_TOKEN_KEY)
19
+ if not token:
20
+ raise ValueError("Access token is required for Bearer Token authentication")
21
+ return BearerTokenAuthStrategy(token)
22
+
23
+ @property
24
+ def auth_type(self) -> AgentAuthType:
25
+ return AgentAuthType.BEARER_TOKEN
26
+
27
+ async def get_headers(self) -> Dict[str, str]:
28
+ return {"Authorization": f"Bearer {self._token}"}
@@ -0,0 +1,167 @@
1
+ """OAuth2 authentication strategy client credentials flow implementation."""
2
+
3
+ import asyncio
4
+ import time
5
+ from typing import Any, AsyncGenerator, Dict, Optional
6
+
7
+ import httpx
8
+
9
+ from rasa.shared.agents.auth.auth_strategy import AgentAuthStrategy
10
+ from rasa.shared.agents.auth.constants import (
11
+ CONFIG_CLIENT_ID_KEY,
12
+ CONFIG_CLIENT_SECRET_KEY,
13
+ CONFIG_OAUTH_KEY,
14
+ CONFIG_SCOPE_KEY,
15
+ CONFIG_TIMEOUT_KEY,
16
+ CONFIG_TOKEN_URL_KEY,
17
+ )
18
+ from rasa.shared.agents.auth.types import AgentAuthType
19
+ from rasa.shared.utils.io import resolve_environment_variables
20
+
21
+ KEY_ACCESS_TOKEN = "access_token"
22
+ KEY_CLIENT_CREDENTIALS = "client_credentials"
23
+ KEY_EXPIRES_IN = "expires_in"
24
+
25
+
26
+ class OAuth2AuthStrategy(AgentAuthStrategy):
27
+ """Client Credentials Flow authentication strategy."""
28
+
29
+ DEFAULT_ACCESS_TOKEN_TIMEOUT = 5
30
+ DEFAULT_ACCESS_TOKEN_EXPIRES_IN_SECONDS = 3600
31
+ DEFAULT_BUFFER_TIME_SECONDS = 10
32
+
33
+ def __init__(
34
+ self,
35
+ token_url: str,
36
+ client_id: str,
37
+ client_secret: str,
38
+ scope: str,
39
+ timeout: Optional[int] = None,
40
+ ):
41
+ self.token_url = token_url
42
+ self.client_id = client_id
43
+ self.client_secret = client_secret
44
+ self.scope = scope
45
+ self.timeout = timeout or self.DEFAULT_ACCESS_TOKEN_TIMEOUT
46
+
47
+ # Only client credentials flow is supported for server to server communication.
48
+ self._grant_type = KEY_CLIENT_CREDENTIALS
49
+
50
+ # Initialize defaults.
51
+ self._access_token: Optional[str] = None
52
+ self._expires_at: Optional[float] = None
53
+
54
+ # Initialize lock for concurrent access to the refresh the access token.
55
+ self._refresh_lock = asyncio.Lock()
56
+
57
+ @classmethod
58
+ def from_config(cls, config: Dict[str, Any]) -> "OAuth2AuthStrategy":
59
+ """Create OAuth2AuthStrategy from configuration dictionary."""
60
+ # Extract OAuth2 config from nested "oauth" key if present
61
+ oauth_config = config.get(CONFIG_OAUTH_KEY, config)
62
+ if not oauth_config:
63
+ raise ValueError("OAuth2 configuration is required")
64
+
65
+ token_url = oauth_config.get(CONFIG_TOKEN_URL_KEY)
66
+ client_id = oauth_config.get(CONFIG_CLIENT_ID_KEY)
67
+ client_secret = oauth_config.get(CONFIG_CLIENT_SECRET_KEY)
68
+ scope = oauth_config.get(CONFIG_SCOPE_KEY)
69
+ timeout = (
70
+ oauth_config.get(CONFIG_TIMEOUT_KEY) or cls.DEFAULT_ACCESS_TOKEN_TIMEOUT
71
+ )
72
+
73
+ if not token_url:
74
+ raise ValueError("Token URL is required for OAuth2 authentication")
75
+ if not client_id:
76
+ raise ValueError("Client ID is required for OAuth2 authentication")
77
+ if not client_secret:
78
+ raise ValueError("Client secret is required for OAuth2 authentication")
79
+ if not scope:
80
+ raise ValueError("Scope is required for OAuth2 authentication")
81
+
82
+ return cls(
83
+ token_url=token_url,
84
+ client_id=client_id,
85
+ client_secret=client_secret,
86
+ scope=scope,
87
+ timeout=timeout,
88
+ )
89
+
90
+ @property
91
+ def auth_type(self) -> AgentAuthType:
92
+ return AgentAuthType.OAUTH2
93
+
94
+ async def get_headers(self) -> Dict[str, str]:
95
+ """Return OAuth2 authentication headers."""
96
+ # Acquire lock to prevent concurrent access to the refresh the access token.
97
+ async with self._refresh_lock:
98
+ # Refresh if missing or expired
99
+ if not self._access_token or self._is_expired():
100
+ await self._refresh_access_token()
101
+ if not self._access_token:
102
+ raise ValueError("Failed to obtain access token")
103
+ return {"Authorization": f"Bearer {self._access_token}"}
104
+
105
+ def _is_expired(self) -> bool:
106
+ """Check if access token is expired."""
107
+ # Adding a buffer time to the expiration time to avoid race conditions.
108
+ return (
109
+ not self._expires_at
110
+ or self._expires_at <= time.time() + self.DEFAULT_BUFFER_TIME_SECONDS
111
+ )
112
+
113
+ async def _refresh_access_token(self) -> None:
114
+ """Fetch a new access token using client credentials flow."""
115
+ # Prepare data and headers
116
+ headers = {"Content-Type": "application/x-www-form-urlencoded"}
117
+ data = {
118
+ "grant_type": self._grant_type,
119
+ "client_id": self.client_id,
120
+ "client_secret": self.client_secret,
121
+ "scope": self.scope,
122
+ }
123
+
124
+ # Resolve environment variables in data.
125
+ resolved_data = resolve_environment_variables(data)
126
+
127
+ # Fetch access token
128
+ try:
129
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
130
+ resp = await client.post(
131
+ self.token_url, data=resolved_data, headers=headers
132
+ )
133
+ resp.raise_for_status()
134
+ token_data = resp.json()
135
+ except httpx.HTTPStatusError as e:
136
+ raise ValueError(
137
+ f"OAuth2 token request failed with status {e.response.status_code}: "
138
+ f"{e.response.text}"
139
+ ) from e
140
+ except httpx.RequestError as e:
141
+ raise ValueError(f"OAuth2 token request failed: {e}") from e
142
+ except Exception as e:
143
+ raise ValueError(
144
+ f"Unexpected error during OAuth2 token request: {e}"
145
+ ) from e
146
+
147
+ # Validate token data
148
+ if KEY_ACCESS_TOKEN not in token_data:
149
+ raise ValueError(f"No {KEY_ACCESS_TOKEN} in OAuth2 response")
150
+
151
+ # Set access token and expires at
152
+ self._access_token = token_data[KEY_ACCESS_TOKEN]
153
+ self._expires_at = time.time() + token_data.get(
154
+ KEY_EXPIRES_IN, self.DEFAULT_ACCESS_TOKEN_EXPIRES_IN_SECONDS
155
+ )
156
+
157
+ async def async_auth_flow(
158
+ self, request: httpx.Request
159
+ ) -> AsyncGenerator[httpx.Request, httpx.Response]:
160
+ """Inject Authorization header into outgoing requests.
161
+
162
+ Returns:
163
+ Async generator of requests with Authorization header.
164
+ """
165
+ auth_headers = await self.get_headers()
166
+ request.headers.update(auth_headers)
167
+ yield request
@@ -0,0 +1,12 @@
1
+ CONFIG_API_KEY_KEY = "api_key"
2
+ CONFIG_TOKEN_KEY = "token"
3
+ CONFIG_OAUTH_KEY = "oauth"
4
+ CONFIG_HEADER_NAME_KEY = "header_name"
5
+ CONFIG_HEADER_FORMAT_KEY = "header_format"
6
+ CONFIG_CLIENT_ID_KEY = "client_id"
7
+ CONFIG_CLIENT_SECRET_KEY = "client_secret"
8
+ CONFIG_TOKEN_URL_KEY = "token_url"
9
+ CONFIG_SCOPE_KEY = "scope"
10
+ CONFIG_GRANT_TYPE_KEY = "grant_type"
11
+ CONFIG_TIMEOUT_KEY = "timeout"
12
+ CONFIG_MODULE_KEY = "module"
@@ -0,0 +1,12 @@
1
+ """Fundamental types for authentication protocols."""
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class AgentAuthType(Enum):
7
+ """An Enum class that represents the supported authentication protocol types."""
8
+
9
+ API_KEY = "api_key"
10
+ OAUTH2 = "oauth2"
11
+ BEARER_TOKEN = "bearer_token"
12
+ CUSTOM = "custom"
@@ -0,0 +1,35 @@
1
+ from typing import Optional
2
+
3
+ from rasa.agents.core.types import AgentIdentifier, ProtocolType
4
+ from rasa.core.available_agents import AgentConfig, ProtocolConfig
5
+ from rasa.shared.core.flows.steps import CallFlowStep
6
+
7
+
8
+ def make_agent_identifier(
9
+ agent_name: str, protocol_type: ProtocolType
10
+ ) -> AgentIdentifier:
11
+ """Make an agent identifier."""
12
+ return AgentIdentifier(agent_name, protocol_type)
13
+
14
+
15
+ def get_protocol_type(
16
+ step: CallFlowStep, agent_config: Optional[AgentConfig]
17
+ ) -> ProtocolType:
18
+ """Get the protocol type for an agent.
19
+
20
+ Args:
21
+ step: The step that is calling the agent.
22
+ agent_config: The agent configuration.
23
+
24
+ Returns:
25
+ The protocol type for the agent.
26
+ """
27
+ if step.exit_if:
28
+ protocol_type = ProtocolType.MCP_TASK
29
+ else:
30
+ protocol_type = (
31
+ ProtocolType.A2A
32
+ if agent_config and agent_config.agent.protocol == ProtocolConfig.A2A
33
+ else ProtocolType.MCP_OPEN
34
+ )
35
+ return protocol_type
rasa/shared/constants.py CHANGED
@@ -249,6 +249,9 @@ _VALIDATE_ENVIRONMENT_MISSING_KEYS_KEY = "missing_keys"
249
249
  LLM_API_HEALTH_CHECK_ENV_VAR = "LLM_API_HEALTH_CHECK"
250
250
  LLM_API_HEALTH_CHECK_DEFAULT_VALUE = "false"
251
251
 
252
+ MCP_API_HEALTH_CHECK_ENV_VAR = "MCP_API_HEALTH_CHECK"
253
+ MCP_API_HEALTH_CHECK_DEFAULT_VALUE = "false"
254
+
252
255
  AWS_REGION_NAME_CONFIG_KEY = "aws_region_name"
253
256
  AWS_ACCESS_KEY_ID_CONFIG_KEY = "aws_access_key_id"
254
257
  AWS_SECRET_ACCESS_KEY_CONFIG_KEY = "aws_secret_access_key"
@@ -345,6 +348,8 @@ PAYLOAD = "payload"
345
348
  # Used for LLM command generation
346
349
  ROLE_USER = "user"
347
350
  ROLE_SYSTEM = "system"
351
+ ROLE_ASSISTANT = "assistant"
352
+ ROLE_TOOL = "tool"
348
353
 
349
354
  # Used for key values in ValidateSlotPatternFlowStackFrame
350
355
  REFILL_UTTER = "refill_utter"
@@ -359,3 +364,6 @@ FAQ_INPUT_DATA_QUESTION_LINE_PREFIX = "Q:"
359
364
  FAQ_INPUT_DATA_ANSWER_LINE_PREFIX = "A:"
360
365
  FAQ_DOCUMENT_ENTRY_SEPARATOR = "\n\n"
361
366
  FAQ_DOCUMENT_LINE_SEPARATOR = "\n"
367
+
368
+ # Constants for the MCP server
369
+ KEY_TOOL_CALLS = "tool_calls"
@@ -30,6 +30,7 @@ LOOP_NAME = "name"
30
30
  ACTION_LISTEN_NAME = "action_listen"
31
31
  ACTION_RESTART_NAME = "action_restart"
32
32
  ACTION_SEND_TEXT_NAME = "action_send_text"
33
+ ACTION_AGENT_REQUEST_USER_INPUT_NAME = "action_agent_request_user_input"
33
34
  ACTION_SESSION_START_NAME = "action_session_start"
34
35
  ACTION_DEFAULT_FALLBACK_NAME = "action_default_fallback"
35
36
  ACTION_DEACTIVATE_LOOP_NAME = "action_deactivate_loop"
@@ -53,10 +54,17 @@ ACTION_RESET_ROUTING = "action_reset_routing"
53
54
  ACTION_HANGUP = "action_hangup"
54
55
  ACTION_REPEAT_BOT_MESSAGES = "action_repeat_bot_messages"
55
56
 
57
+ # pattern continue interrupted flows
58
+ ACTION_CONTINUE_INTERRUPTED_FLOW = "action_continue_interrupted_flow"
59
+ ACTION_CANCEL_INTERRUPTED_FLOWS = "action_cancel_interrupted_flows"
60
+
61
+
56
62
  ACTION_METADATA_EXECUTION_SUCCESS = "execution_success"
57
63
  ACTION_METADATA_EXECUTION_ERROR_MESSAGE = "execution_error_message"
58
64
  ACTION_METADATA_EXECUTION_TIME = "execution_times"
59
65
 
66
+ ACTION_METADATA_MESSAGE_KEY = "message"
67
+ ACTION_METADATA_TEXT_KEY = "text"
60
68
 
61
69
  DEFAULT_ACTION_NAMES = [
62
70
  ACTION_LISTEN_NAME,
@@ -71,6 +79,7 @@ DEFAULT_ACTION_NAMES = [
71
79
  ACTION_UNLIKELY_INTENT_NAME,
72
80
  ACTION_BACK_NAME,
73
81
  ACTION_SEND_TEXT_NAME,
82
+ ACTION_AGENT_REQUEST_USER_INPUT_NAME,
74
83
  RULE_SNIPPET_ACTION_NAME,
75
84
  ACTION_EXTRACT_SLOTS,
76
85
  ACTION_CANCEL_FLOW,
@@ -83,6 +92,8 @@ DEFAULT_ACTION_NAMES = [
83
92
  ACTION_RESET_ROUTING,
84
93
  ACTION_HANGUP,
85
94
  ACTION_REPEAT_BOT_MESSAGES,
95
+ ACTION_CONTINUE_INTERRUPTED_FLOW,
96
+ ACTION_CANCEL_INTERRUPTED_FLOWS,
86
97
  ]
87
98
 
88
99
  ACTION_SHOULD_SEND_DOMAIN = "send_domain"
@@ -115,10 +126,11 @@ FLOW_SLOT_NAMES = [FLOW_HASHES_SLOT]
115
126
 
116
127
  # slots for audio timeout
117
128
  GLOBAL_SILENCE_TIMEOUT_KEY = "global_silence_timeout"
129
+ SILENCE_TIMEOUT_CHANNEL_KEY = "silence_timeout"
118
130
  SILENCE_TIMEOUT_SLOT = "silence_timeout"
119
131
  SLOT_CONSECUTIVE_SILENCE_TIMEOUTS = "consecutive_silence_timeouts"
120
132
  GLOBAL_SILENCE_TIMEOUT_DEFAULT_VALUE = 7.0
121
- SILENCE_SLOTS = [SILENCE_TIMEOUT_SLOT, SLOT_CONSECUTIVE_SILENCE_TIMEOUTS]
133
+ SILENCE_SLOTS = {SILENCE_TIMEOUT_SLOT, SLOT_CONSECUTIVE_SILENCE_TIMEOUTS}
122
134
  # slots for knowledge base
123
135
  SLOT_LISTED_ITEMS = "knowledge_base_listed_objects"
124
136
  SLOT_LAST_OBJECT = "knowledge_base_last_object"
@@ -137,6 +149,9 @@ DEFAULT_SLOT_NAMES = {
137
149
  FLOW_HASHES_SLOT,
138
150
  }
139
151
 
152
+ SLOTS_EXCLUDED_FOR_AGENT = (
153
+ SILENCE_SLOTS | DEFAULT_SLOT_NAMES | KNOWLEDGE_BASE_SLOT_NAMES
154
+ )
140
155
 
141
156
  SLOT_MAPPINGS = "mappings"
142
157
  MAPPING_CONDITIONS = "conditions"
@@ -32,7 +32,6 @@ from ruamel.yaml.scalarstring import DoubleQuotedScalarString
32
32
  import rasa.shared.core.slot_mappings
33
33
  import rasa.shared.utils.common
34
34
  import rasa.shared.utils.io
35
- from rasa.core.available_endpoints import AvailableEndpoints
36
35
  from rasa.shared.constants import (
37
36
  DEFAULT_CARRY_OVER_SLOTS_TO_NEW_SESSION,
38
37
  DEFAULT_SESSION_EXPIRATION_TIME_IN_MINUTES,
@@ -49,7 +48,6 @@ from rasa.shared.core.constants import (
49
48
  ACTION_SHOULD_SEND_DOMAIN,
50
49
  KEY_MAPPING_TYPE,
51
50
  KNOWLEDGE_BASE_SLOT_NAMES,
52
- SILENCE_TIMEOUT_SLOT,
53
51
  SLOT_MAPPINGS,
54
52
  SlotMappingType,
55
53
  )
@@ -312,11 +310,6 @@ class Domain:
312
310
  responses = data.get(KEY_RESPONSES, {})
313
311
 
314
312
  domain_slots = data.get(KEY_SLOTS, {})
315
- for slot_name, slot in domain_slots.items():
316
- if slot_name == SILENCE_TIMEOUT_SLOT:
317
- slot["initial_value"] = (
318
- AvailableEndpoints.get_instance().interaction_handling.global_silence_timeout
319
- )
320
313
  slots = cls.collect_slots(domain_slots)
321
314
  domain_actions = data.get(KEY_ACTIONS, [])
322
315
  actions = cls._collect_action_names(domain_actions)