rasa-pro 3.13.6__py3-none-any.whl → 3.14.0.dev1__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 (178) hide show
  1. rasa/agents/__init__.py +0 -0
  2. rasa/agents/agent_factory.py +122 -0
  3. rasa/agents/agent_manager.py +162 -0
  4. rasa/agents/constants.py +31 -0
  5. rasa/agents/core/__init__.py +0 -0
  6. rasa/agents/core/agent_protocol.py +108 -0
  7. rasa/agents/core/types.py +70 -0
  8. rasa/agents/exceptions.py +8 -0
  9. rasa/agents/protocol/__init__.py +5 -0
  10. rasa/agents/protocol/a2a/__init__.py +0 -0
  11. rasa/agents/protocol/a2a/a2a_agent.py +51 -0
  12. rasa/agents/protocol/mcp/__init__.py +0 -0
  13. rasa/agents/protocol/mcp/mcp_base_agent.py +697 -0
  14. rasa/agents/protocol/mcp/mcp_open_agent.py +275 -0
  15. rasa/agents/protocol/mcp/mcp_task_agent.py +447 -0
  16. rasa/agents/schemas/__init__.py +6 -0
  17. rasa/agents/schemas/agent_input.py +24 -0
  18. rasa/agents/schemas/agent_output.py +26 -0
  19. rasa/agents/schemas/agent_tool_result.py +51 -0
  20. rasa/agents/schemas/agent_tool_schema.py +112 -0
  21. rasa/agents/templates/__init__.py +0 -0
  22. rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +15 -0
  23. rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +13 -0
  24. rasa/agents/utils.py +72 -0
  25. rasa/api.py +5 -0
  26. rasa/cli/arguments/default_arguments.py +12 -0
  27. rasa/cli/arguments/run.py +2 -0
  28. rasa/cli/dialogue_understanding_test.py +4 -0
  29. rasa/cli/e2e_test.py +4 -0
  30. rasa/cli/inspect.py +3 -0
  31. rasa/cli/llm_fine_tuning.py +5 -0
  32. rasa/cli/run.py +4 -0
  33. rasa/cli/shell.py +3 -0
  34. rasa/cli/train.py +2 -2
  35. rasa/constants.py +6 -0
  36. rasa/core/actions/action.py +69 -39
  37. rasa/core/actions/action_run_slot_rejections.py +1 -1
  38. rasa/core/agent.py +16 -0
  39. rasa/core/available_agents.py +196 -0
  40. rasa/core/available_endpoints.py +30 -0
  41. rasa/core/channels/development_inspector.py +47 -14
  42. rasa/core/channels/inspector/dist/assets/{arc-0b11fe30.js → arc-2e78c586.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-9eef30a7.js → blockDiagram-38ab4fdb-806b712e.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-03e94f28.js → c4Diagram-3d4e48cf-0745efa9.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/channel-c436ca7c.js +1 -0
  46. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-95c09eba.js → classDiagram-70f12bd4-7bd1082b.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-38e8446c.js → classDiagram-v2-f2320105-d937ba49.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/clone-50dd656b.js +1 -0
  49. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-57dc3038.js → createText-2e5e7dd3-a2a564ca.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-4bac0545.js → edges-e0da2a9e-b5256940.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-81795c90.js → erDiagram-9861fffd-e6883ad2.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-89489ae6.js → flowDb-956e92f1-e576fc02.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-cd152627.js → flowDiagram-66a62f08-2e298d01.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b2aeaf8.js +1 -0
  55. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-3da369bc.js → flowchart-elk-definition-4a651766-dd7b150a.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-85ec16f8.js → ganttDiagram-c361ad54-5b79575c.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-495bc140.js → gitGraphDiagram-72cf32ee-3016f40a.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{graph-1ec4d266.js → graph-3e19170f.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/index-1bd9135e.js +1353 -0
  60. rasa/core/channels/inspector/dist/assets/{index-3862675e-0a0e97c9.js → index-3862675e-eb9c86de.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-4d54bcde.js → infoDiagram-f8f76790-b4280e4d.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-dc097114.js → journeyDiagram-49397b02-556091f8.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{layout-1a08981e.js → layout-08436411.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{line-95f7f1d3.js → line-683c4f3b.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{linear-97e69543.js → linear-cee6d791.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-8c71ff03.js → mindmap-definition-fc14e90a-a0bf0b1a.js} +1 -1
  67. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-f14c71c7.js → pieDiagram-8a3498a8-3730d5c4.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-f1d3c9ff.js → quadrantDiagram-120e2f19-12a20fed.js} +1 -1
  69. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-bfa2412f.js → requirementDiagram-deff3bca-b9732102.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-53f2c97b.js → sankeyDiagram-04a897e0-a2e72776.js} +1 -1
  71. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-319d7c0e.js → sequenceDiagram-704730f1-8b7a76bb.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-76a09418.js → stateDiagram-587899a1-e65853ac.js} +1 -1
  73. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-a67f15d4.js → stateDiagram-v2-d93cdb3a-6f58a44b.js} +1 -1
  74. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-0654e7c3.js → styles-6aaf32cf-df25b934.js} +1 -1
  75. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1394bb9d.js → styles-9a916d00-88357141.js} +1 -1
  76. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-e4c5bdae.js → styles-c10674c1-d600174d.js} +1 -1
  77. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-50957104.js → svgDrawCommon-08f97a94-4adc3e0b.js} +1 -1
  78. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-b0885a6a.js → timeline-definition-85554ec2-42816fa1.js} +1 -1
  79. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-79e6541a.js → xychartDiagram-e933f94c-621eb66a.js} +1 -1
  80. rasa/core/channels/inspector/dist/index.html +2 -2
  81. rasa/core/channels/inspector/index.html +1 -1
  82. rasa/core/channels/inspector/src/App.tsx +53 -7
  83. rasa/core/channels/inspector/src/components/Chat.tsx +3 -2
  84. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +1 -1
  85. rasa/core/channels/inspector/src/components/DialogueStack.tsx +7 -5
  86. rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +268 -0
  87. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +6 -2
  88. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +8 -3
  89. rasa/core/channels/inspector/src/helpers/formatters.ts +24 -3
  90. rasa/core/channels/inspector/src/theme/base/styles.ts +19 -1
  91. rasa/core/channels/inspector/src/types.ts +12 -0
  92. rasa/core/channels/studio_chat.py +125 -34
  93. rasa/core/channels/voice_ready/twilio_voice.py +1 -1
  94. rasa/core/channels/voice_stream/audiocodes.py +9 -6
  95. rasa/core/channels/voice_stream/browser_audio.py +39 -4
  96. rasa/core/channels/voice_stream/call_state.py +13 -2
  97. rasa/core/channels/voice_stream/genesys.py +16 -13
  98. rasa/core/channels/voice_stream/jambonz.py +13 -11
  99. rasa/core/channels/voice_stream/twilio_media_streams.py +14 -13
  100. rasa/core/channels/voice_stream/util.py +11 -1
  101. rasa/core/channels/voice_stream/voice_channel.py +101 -29
  102. rasa/core/constants.py +4 -0
  103. rasa/core/nlg/contextual_response_rephraser.py +11 -7
  104. rasa/core/nlg/generator.py +21 -5
  105. rasa/core/nlg/response.py +43 -6
  106. rasa/core/nlg/translate.py +8 -0
  107. rasa/core/policies/enterprise_search_policy.py +4 -2
  108. rasa/core/policies/flow_policy.py +2 -2
  109. rasa/core/policies/flows/flow_executor.py +374 -35
  110. rasa/core/policies/flows/mcp_tool_executor.py +240 -0
  111. rasa/core/processor.py +6 -1
  112. rasa/core/run.py +8 -1
  113. rasa/core/utils.py +21 -1
  114. rasa/dialogue_understanding/commands/__init__.py +8 -0
  115. rasa/dialogue_understanding/commands/cancel_flow_command.py +97 -4
  116. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +11 -0
  117. rasa/dialogue_understanding/commands/continue_agent_command.py +91 -0
  118. rasa/dialogue_understanding/commands/knowledge_answer_command.py +11 -0
  119. rasa/dialogue_understanding/commands/restart_agent_command.py +146 -0
  120. rasa/dialogue_understanding/commands/start_flow_command.py +129 -8
  121. rasa/dialogue_understanding/commands/utils.py +6 -2
  122. rasa/dialogue_understanding/generator/command_parser.py +4 -0
  123. rasa/dialogue_understanding/generator/llm_based_command_generator.py +50 -12
  124. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +61 -0
  125. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +61 -0
  126. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +81 -0
  127. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +81 -0
  128. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +7 -6
  129. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +7 -6
  130. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +41 -2
  131. rasa/dialogue_understanding/patterns/continue_interrupted.py +163 -1
  132. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +51 -7
  133. rasa/dialogue_understanding/processor/command_processor.py +27 -11
  134. rasa/dialogue_understanding/stack/dialogue_stack.py +123 -2
  135. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +57 -0
  136. rasa/dialogue_understanding/stack/utils.py +3 -2
  137. rasa/dialogue_understanding_test/du_test_runner.py +7 -2
  138. rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
  139. rasa/e2e_test/e2e_test_runner.py +5 -0
  140. rasa/e2e_test/e2e_test_schema.yml +3 -3
  141. rasa/model_manager/model_api.py +1 -1
  142. rasa/model_manager/socket_bridge.py +8 -2
  143. rasa/server.py +10 -0
  144. rasa/shared/agents/__init__.py +0 -0
  145. rasa/shared/agents/utils.py +35 -0
  146. rasa/shared/constants.py +5 -0
  147. rasa/shared/core/constants.py +12 -1
  148. rasa/shared/core/domain.py +5 -5
  149. rasa/shared/core/events.py +319 -0
  150. rasa/shared/core/flows/flows_list.py +2 -2
  151. rasa/shared/core/flows/flows_yaml_schema.json +101 -186
  152. rasa/shared/core/flows/steps/call.py +51 -5
  153. rasa/shared/core/flows/validation.py +45 -7
  154. rasa/shared/core/flows/yaml_flows_io.py +3 -3
  155. rasa/shared/providers/llm/_base_litellm_client.py +39 -7
  156. rasa/shared/providers/llm/litellm_router_llm_client.py +8 -4
  157. rasa/shared/providers/llm/llm_client.py +7 -3
  158. rasa/shared/providers/llm/llm_response.py +49 -0
  159. rasa/shared/providers/llm/self_hosted_llm_client.py +8 -4
  160. rasa/shared/utils/common.py +2 -1
  161. rasa/shared/utils/llm.py +28 -5
  162. rasa/shared/utils/mcp/__init__.py +0 -0
  163. rasa/shared/utils/mcp/server_connection.py +157 -0
  164. rasa/shared/utils/schemas/events.py +42 -0
  165. rasa/tracing/instrumentation/instrumentation.py +4 -2
  166. rasa/utils/common.py +53 -0
  167. rasa/utils/licensing.py +21 -10
  168. rasa/utils/plotting.py +1 -1
  169. rasa/version.py +1 -1
  170. {rasa_pro-3.13.6.dist-info → rasa_pro-3.14.0.dev1.dist-info}/METADATA +16 -15
  171. {rasa_pro-3.13.6.dist-info → rasa_pro-3.14.0.dev1.dist-info}/RECORD +174 -137
  172. rasa/core/channels/inspector/dist/assets/channel-51d02e9e.js +0 -1
  173. rasa/core/channels/inspector/dist/assets/clone-cc738fa6.js +0 -1
  174. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-0c716443.js +0 -1
  175. rasa/core/channels/inspector/dist/assets/index-c804b295.js +0 -1335
  176. {rasa_pro-3.13.6.dist-info → rasa_pro-3.14.0.dev1.dist-info}/NOTICE +0 -0
  177. {rasa_pro-3.13.6.dist-info → rasa_pro-3.14.0.dev1.dist-info}/WHEEL +0 -0
  178. {rasa_pro-3.13.6.dist-info → rasa_pro-3.14.0.dev1.dist-info}/entry_points.txt +0 -0
@@ -1,20 +1,12 @@
1
1
  {
2
2
  "type": "object",
3
- "required": [
4
- "flows"
5
- ],
3
+ "required": ["flows"],
6
4
  "properties": {
7
- "version": {
8
- "type": "string"
9
- },
5
+ "version": {"type": "string"},
10
6
  "flows": {
11
7
  "type": "object",
12
8
  "schema_name": "dictionary of flows",
13
- "patternProperties": {
14
- "^[A-Za-z_][A-Za-z0-9_]*$": {
15
- "$ref": "#/$defs/flow"
16
- }
17
- }
9
+ "patternProperties": {"^[A-Za-z_][A-Za-z0-9_]*$": {"$ref": "#/$defs/flow"}}
18
10
  }
19
11
  },
20
12
  "$defs": {
@@ -28,34 +20,22 @@
28
20
  {
29
21
  "schema_name": "intent trigger",
30
22
  "type": "object",
31
- "required": [
32
- "intent"
33
- ],
23
+ "required": ["intent"],
34
24
  "additionalProperties": false,
35
25
  "properties": {
36
26
  "intent": {
37
27
  "type": "object",
38
28
  "properties": {
39
- "confidence_threshold": {
40
- "type": "number"
41
- },
42
- "name": {
43
- "type": "string"
44
- }
29
+ "confidence_threshold": {"type": "number"},
30
+ "name": {"type": "string"}
45
31
  },
46
- "required": [
47
- "name"
48
- ]
32
+ "required": ["name"]
49
33
  }
50
34
  }
51
35
  },
52
36
  {
53
37
  "schema_name": "simple intent trigger",
54
- "properties": {
55
- "intent": {
56
- "type": "string"
57
- }
58
- }
38
+ "properties": {"intent": {"type": "string"}}
59
39
  }
60
40
  ]
61
41
  }
@@ -66,9 +46,7 @@
66
46
  "items": {
67
47
  "type": "object",
68
48
  "properties": {
69
- "id": {
70
- "type": "string"
71
- },
49
+ "id": {"type": "string"},
72
50
  "next": {
73
51
  "anyOf": [
74
52
  {
@@ -79,16 +57,11 @@
79
57
  "oneOf": [
80
58
  {
81
59
  "schema_name": "if-then block",
82
- "required": [
83
- "if",
84
- "then"
85
- ]
60
+ "required": ["if", "then"]
86
61
  },
87
62
  {
88
63
  "schema_name": "else block",
89
- "required": [
90
- "else"
91
- ]
64
+ "required": ["else"]
92
65
  }
93
66
  ],
94
67
  "properties": {
@@ -104,12 +77,7 @@
104
77
  }
105
78
  ]
106
79
  },
107
- "if": {
108
- "type": [
109
- "boolean",
110
- "string"
111
- ]
112
- },
80
+ "if": {"type": ["boolean", "string"]},
113
81
  "then": {
114
82
  "oneOf": [
115
83
  {
@@ -125,66 +93,25 @@
125
93
  }
126
94
  }
127
95
  },
128
- {
129
- "type": "string",
130
- "schema_name": "step id"
131
- }
96
+ {"type": "string", "schema_name": "step id"}
132
97
  ]
133
98
  },
134
- "action": {
135
- "type": "string"
136
- },
137
- "collect": {
138
- "type": "string"
139
- },
140
- "link": {
141
- "type": "string"
142
- },
143
- "call": {
144
- "type": "string"
145
- },
99
+ "action": {"type": "string"},
100
+ "collect": {"type": "string"},
101
+ "link": {"type": "string"},
102
+ "call": {"type": "string"},
146
103
  "set_slots": {
147
104
  "$ref": "#/$defs/set_slots",
148
105
  "schema_name": "slot set"
149
106
  }
150
107
  },
151
108
  "oneOf": [
152
- {
153
- "required": [
154
- "action"
155
- ],
156
- "schema_name": "action step"
157
- },
158
- {
159
- "required": [
160
- "collect"
161
- ],
162
- "schema_name": "collect step"
163
- },
164
- {
165
- "required": [
166
- "link"
167
- ],
168
- "schema_name": "link step"
169
- },
170
- {
171
- "required": [
172
- "call"
173
- ],
174
- "schema_name": "call step"
175
- },
176
- {
177
- "required": [
178
- "set_slots"
179
- ],
180
- "schema_name": "slot set step"
181
- },
182
- {
183
- "required": [
184
- "noop"
185
- ],
186
- "schema_name": ""
187
- }
109
+ {"required": ["action"], "schema_name": "action step"},
110
+ {"required": ["collect"], "schema_name": "collect step"},
111
+ {"required": ["link"], "schema_name": "link step"},
112
+ {"required": ["call"], "schema_name": "call step"},
113
+ {"required": ["set_slots"], "schema_name": "slot set step"},
114
+ {"required": ["noop"], "schema_name": ""}
188
115
  ],
189
116
  "dependentSchemas": {
190
117
  "action": {
@@ -196,10 +123,23 @@
196
123
  "metadata": {}
197
124
  }
198
125
  },
199
- "noop": {
200
- "required": [
201
- "next"
202
- ]
126
+ "noop": {"required": ["next"]},
127
+ "call": {
128
+ "additionalProperties": false,
129
+ "properties": {
130
+ "call": {"type": "string"},
131
+ "id": {},
132
+ "next": {},
133
+ "metadata": {},
134
+ "description": {"type": "string"},
135
+ "mcp_server": {"type": "string"},
136
+ "mapping": {"$ref": "#/$defs/call_step/properties/mapping"},
137
+ "exit_if": {"$ref": "#/$defs/call_step/properties/exit_if"}
138
+ },
139
+ "dependentSchemas": {
140
+ "mcp_server": {"required": ["mapping"]},
141
+ "mapping": {"required": ["mcp_server"]}
142
+ }
203
143
  },
204
144
  "collect": {
205
145
  "additionalProperties": false,
@@ -208,130 +148,105 @@
208
148
  "id": {},
209
149
  "next": {},
210
150
  "metadata": {},
211
- "description": {
212
- "type": "string"
213
- },
214
- "ask_before_filling": {
215
- "type": "boolean"
216
- },
217
- "reset_after_flow_ends": {
218
- "type": "boolean"
219
- },
220
- "utter": {
221
- "type": "string"
222
- },
223
- "force_slot_filling": {
224
- "type": "boolean"
225
- },
151
+ "description": {"type": "string"},
152
+ "ask_before_filling": {"type": "boolean"},
153
+ "reset_after_flow_ends": {"type": "boolean"},
154
+ "utter": {"type": "string"},
155
+ "force_slot_filling": {"type": "boolean"},
226
156
  "rejections": {
227
157
  "type": "array",
228
158
  "schema_name": "list of rejections",
229
159
  "items": {
230
160
  "type": "object",
231
- "required": [
232
- "if",
233
- "utter"
234
- ],
161
+ "required": ["if", "utter"],
235
162
  "properties": {
236
- "if": {
237
- "type": [
238
- "boolean",
239
- "string"
240
- ]
241
- },
242
- "utter": {
243
- "type": "string"
244
- }
163
+ "if": {"type": ["boolean", "string"]},
164
+ "utter": {"type": "string"}
245
165
  }
246
166
  }
247
167
  },
248
- "silence_timeout": {
249
- "type": "number"
250
- }
168
+ "silence_timeout": {"type": "number"}
251
169
  }
252
170
  }
253
171
  }
254
172
  }
255
173
  },
256
174
  "flow": {
257
- "required": [
258
- "steps",
259
- "description"
260
- ],
175
+ "required": ["steps", "description"],
261
176
  "type": "object",
262
177
  "additionalProperties": false,
263
178
  "schema_name": "dictionary with flow properties",
264
179
  "properties": {
265
- "name": {
266
- "type": "string"
267
- },
268
- "description": {
269
- "type": "string"
270
- },
180
+ "name": {"type": "string"},
181
+ "description": {"type": "string"},
271
182
  "translation": {
272
183
  "type": "object",
184
+ "additionalProperties": false,
273
185
  "schema_name": "flow translation mapping",
274
- "properties": {
275
- "metadata": {
276
- "type": "object"
277
- }
278
- },
186
+ "properties": {"metadata": {"type": "object"}},
279
187
  "patternProperties": {
280
188
  "^(?!metadata$).+": {
281
189
  "type": "object",
282
190
  "additionalProperties": false,
283
- "required": [
284
- "name"
285
- ],
286
- "properties": {
287
- "name": {
288
- "type": "string"
289
- },
290
- "metadata": {}
291
- }
191
+ "required": ["name"],
192
+ "properties": {"name": {"type": "string"}, "metadata": {}}
292
193
  }
293
- },
294
- "additionalProperties": false
295
- },
296
- "if": {
297
- "type": [
298
- "string",
299
- "boolean"
300
- ]
301
- },
302
- "always_include_in_prompt": {
303
- "type": "boolean"
304
- },
305
- "nlu_trigger": {
306
- "$ref": "#/$defs/nlu_trigger"
307
- },
308
- "file_path": {
309
- "type": "string"
310
- },
311
- "steps": {
312
- "$ref": "#/$defs/steps"
313
- },
314
- "persisted_slots": {
315
- "$ref": "#/$defs/persisted_slots"
194
+ }
316
195
  },
317
- "run_pattern_completed": {
318
- "type": "boolean"
319
- }
196
+ "if": {"type": ["string", "boolean"]},
197
+ "always_include_in_prompt": {"type": "boolean"},
198
+ "nlu_trigger": {"$ref": "#/$defs/nlu_trigger"},
199
+ "file_path": {"type": "string"},
200
+ "steps": {"$ref": "#/$defs/steps"},
201
+ "persisted_slots": {"$ref": "#/$defs/persisted_slots"},
202
+ "run_pattern_completed": {"type": "boolean"}
320
203
  }
321
204
  },
322
205
  "set_slots": {
323
206
  "type": "array",
324
207
  "schema_name": "list of slot sets",
325
- "items": {
326
- "type": "object"
208
+ "items": {"type": "object"}
209
+ },
210
+ "call_step": {
211
+ "type": "object",
212
+ "additionalProperties": false,
213
+ "schema_name": "dictionary with call properties",
214
+ "required": ["call"],
215
+ "properties": {
216
+ "call": {"type": "string"},
217
+ "mcp_server": {"type": "string"},
218
+ "mapping": {
219
+ "type": "object",
220
+ "additionalProperties": false,
221
+ "schema_name": "input and output mapping for a MCP tool call",
222
+ "required": ["input", "output"],
223
+ "properties": {
224
+ "input": {
225
+ "type": "array",
226
+ "items": {
227
+ "type": "object",
228
+ "additionalProperties": false,
229
+ "required": ["slot", "param"],
230
+ "properties": {
231
+ "slot": {"type": "string"},
232
+ "param": {"type": "string"}
233
+ }
234
+ }
235
+ },
236
+ "output": {"type": "string"}
237
+ }
238
+ },
239
+ "exit_if": {
240
+ "type": "array",
241
+ "schema_name": "list of slot predicates to exit agent call",
242
+ "items": {"type": ["string"]}
243
+ }
327
244
  }
328
245
  },
329
246
  "persisted_slots": {
330
247
  "type": "array",
331
248
  "schema_name": "list of slots",
332
- "items": {
333
- "type": "string"
334
- }
249
+ "items": {"type": "string"}
335
250
  }
336
251
  }
337
252
  }
@@ -1,8 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Any, Dict, Generator, Optional, Text
4
+ from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Text
5
5
 
6
+ from rasa.core.available_agents import AvailableAgents
7
+ from rasa.core.available_endpoints import AvailableEndpoints
6
8
  from rasa.shared.core.flows.flow_step import FlowStep
7
9
 
8
10
  if TYPE_CHECKING:
@@ -11,11 +13,19 @@ if TYPE_CHECKING:
11
13
 
12
14
  @dataclass
13
15
  class CallFlowStep(FlowStep):
14
- """Represents the configuration of an call flow step."""
16
+ """Represents the configuration of a call flow/agent step."""
15
17
 
16
18
  call: Text
17
- """The flow to be called."""
19
+ """The flow to be called or the ID of the agent to be called."""
18
20
  called_flow_reference: Optional["Flow"] = None
21
+ # MCP Tool calling
22
+ """The MCP server that hosts the tool to be called."""
23
+ mcp_server: Optional[str] = None
24
+ """The input and output mapping for the MCP tool."""
25
+ mapping: Optional[Dict[str, Any]] = None
26
+ # Call agent exit condition
27
+ """A list of slot predicates that determine when to exit the agent loop."""
28
+ exit_if: Optional[List[str]] = None
19
29
 
20
30
  @classmethod
21
31
  def from_json(cls, flow_id: Text, data: Dict[Text, Any]) -> CallFlowStep:
@@ -31,6 +41,9 @@ class CallFlowStep(FlowStep):
31
41
  base = super().from_json(flow_id, data)
32
42
  return CallFlowStep(
33
43
  call=data.get("call", ""),
44
+ mcp_server=data.get("mcp_server", None),
45
+ mapping=data.get("mapping", None),
46
+ exit_if=data.get("exit_if", None),
34
47
  **base.__dict__,
35
48
  )
36
49
 
@@ -40,7 +53,16 @@ class CallFlowStep(FlowStep):
40
53
  Returns:
41
54
  The flow step as a dictionary.
42
55
  """
43
- return super().as_json(step_properties={"call": self.call})
56
+ step_properties: Dict[str, Any] = {
57
+ "call": self.call,
58
+ }
59
+ if self.is_calling_mcp_tool():
60
+ step_properties["mcp_server"] = self.mcp_server
61
+ step_properties["mapping"] = self.mapping
62
+ if self.exit_if:
63
+ step_properties["exit_if"] = self.exit_if
64
+
65
+ return super().as_json(step_properties=step_properties)
44
66
 
45
67
  def steps_in_tree(
46
68
  self, should_resolve_calls: bool = True
@@ -48,7 +70,7 @@ class CallFlowStep(FlowStep):
48
70
  """Returns the steps in the tree of the flow step."""
49
71
  yield self
50
72
 
51
- if should_resolve_calls:
73
+ if should_resolve_calls and self.is_calling_flow():
52
74
  if not self.called_flow_reference:
53
75
  raise ValueError("Call flow reference not set.")
54
76
 
@@ -56,6 +78,27 @@ class CallFlowStep(FlowStep):
56
78
 
57
79
  yield from self.next.steps_in_tree(should_resolve_calls)
58
80
 
81
+ def is_calling_flow(self) -> bool:
82
+ """Returns True if the call references a flow."""
83
+ return not self.is_calling_mcp_tool() and not self.is_calling_agent()
84
+
85
+ def is_calling_mcp_tool(self) -> bool:
86
+ """Returns True if the call references an MCP tool of an existing MCP server."""
87
+ mcp_server_list = AvailableEndpoints.get_instance().mcp_servers
88
+ if mcp_server_list is None:
89
+ return False
90
+
91
+ mcp_server_names = [server.name for server in mcp_server_list]
92
+ return (
93
+ self.mcp_server is not None
94
+ and self.mapping is not None
95
+ and self.mcp_server in mcp_server_names
96
+ )
97
+
98
+ def is_calling_agent(self) -> bool:
99
+ """Returns True if the call references an agent."""
100
+ return self.call in AvailableAgents.get_instance().agents
101
+
59
102
  @property
60
103
  def default_id_postfix(self) -> str:
61
104
  """Returns the default id postfix of the flow step."""
@@ -66,6 +109,9 @@ class CallFlowStep(FlowStep):
66
109
  return (
67
110
  self.call == other.call
68
111
  and self.called_flow_reference == other.called_flow_reference
112
+ and self.mcp_server == other.mcp_server
113
+ and self.mapping == other.mapping
114
+ and self.exit_if == other.exit_if
69
115
  and super().__eq__(other)
70
116
  )
71
117
  return False
@@ -261,7 +261,7 @@ class NoLinkAllowedInCalledFlowException(RasaException):
261
261
  )
262
262
 
263
263
 
264
- class UnresolvedFlowException(RasaException):
264
+ class UnresolvedLinkFlowException(RasaException):
265
265
  """Raised when a flow is called or linked from another flow but doesn't exist."""
266
266
 
267
267
  def __init__(self, flow_id: str, calling_flow_id: str, step_id: str) -> None:
@@ -273,13 +273,37 @@ class UnresolvedFlowException(RasaException):
273
273
  def __str__(self) -> str:
274
274
  """Return a string representation of the exception."""
275
275
  return (
276
- f"Flow '{self.flow_id}' is called or linked from flow "
276
+ f"Flow '{self.flow_id}' is linked from flow "
277
277
  f"'{self.calling_flow_id}' in step '{self.step_id}', "
278
278
  f"but it doesn't exist. "
279
279
  f"Please make sure that a flow with id '{self.flow_id}' exists."
280
280
  )
281
281
 
282
282
 
283
+ class UnresolvedCallStepException(RasaException):
284
+ """Valid call step should have a reference to an existing flow or agent.
285
+ Raised when it does not.
286
+ """
287
+
288
+ def __init__(
289
+ self, call_step_argument: str, calling_flow_id: str, step_id: str
290
+ ) -> None:
291
+ """Initializes the exception."""
292
+ self.call_step_argument = call_step_argument
293
+ self.calling_flow_id = calling_flow_id
294
+ self.step_id = step_id
295
+
296
+ def __str__(self) -> str:
297
+ """Return a string representation of the exception."""
298
+ return (
299
+ f"The call step '{self.step_id}' in flow '{self.calling_flow_id}' "
300
+ f"is invalid: there is no flow or agent with the "
301
+ f"id '{self.call_step_argument}'. "
302
+ f"Please make sure that the call step argument is a valid flow id "
303
+ f"or an agent id."
304
+ )
305
+
306
+
283
307
  class UnresolvedFlowStepIdException(RasaException):
284
308
  """Raised when a flow step is referenced, but its id can not be resolved."""
285
309
 
@@ -562,15 +586,29 @@ def validate_link_in_call_restriction(flows: "FlowsList") -> None:
562
586
  raise NoLinkAllowedInCalledFlowException(step.id, flow.id, step.call)
563
587
 
564
588
 
565
- def validate_called_flows_exists(flows: "FlowsList") -> None:
566
- """Validates that all called flows exist."""
589
+ def validate_call_steps(flows: "FlowsList") -> None:
590
+ """Validates that all called flows/agents exist and additional properties
591
+ are valid.
592
+ """
567
593
  for flow in flows.underlying_flows:
568
594
  for step in flow.steps:
569
595
  if not isinstance(step, CallFlowStep):
570
596
  continue
571
597
 
572
- if flows.flow_by_id(step.call) is None:
573
- raise UnresolvedFlowException(step.call, flow.id, step.id)
598
+ if (
599
+ not step.is_calling_agent()
600
+ and flows.flow_by_id(step.call) is None
601
+ and not step.is_calling_mcp_tool()
602
+ ):
603
+ raise UnresolvedCallStepException(step.call, flow.id, step.id)
604
+
605
+ if step.exit_if and not step.is_calling_agent():
606
+ # exit_if is only allowed for call steps that call an agent
607
+ raise RasaException(
608
+ f"Call step '{step.id}' in flow '{flow.id}' has an 'exit_if' "
609
+ f"condition, but it is not calling an agent. "
610
+ f"'exit_if' is only allowed for call steps that call an agent."
611
+ )
574
612
 
575
613
 
576
614
  def validate_linked_flows_exists(flows: "FlowsList") -> None:
@@ -594,7 +632,7 @@ def validate_linked_flows_exists(flows: "FlowsList") -> None:
594
632
  flow.is_rasa_default_flow and step.link == RASA_PATTERN_CHITCHAT
595
633
  )
596
634
  ):
597
- raise UnresolvedFlowException(step.link, flow.id, step.id)
635
+ raise UnresolvedLinkFlowException(step.link, flow.id, step.id)
598
636
 
599
637
 
600
638
  def validate_patterns_are_not_called_or_linked(flows: "FlowsList") -> None:
@@ -418,15 +418,15 @@ def process_yaml_content(yaml_content: Dict[str, Any]) -> Dict[str, Any]:
418
418
 
419
419
  # Under the "flows" key certain keys cannot have metadata
420
420
  _process_keys_recursively(
421
- yaml_content["flows"], ["nlu_trigger", "set_slots", "metadata"]
421
+ yaml_content["flows"],
422
+ ["nlu_trigger", "set_slots", "metadata", "mapping", "exit_if"],
422
423
  )
423
424
 
424
425
  return yaml_content
425
426
 
426
427
 
427
428
  def get_flow_as_json(flow: Flow, should_clean_json: bool = False) -> Dict[str, Any]:
428
- """
429
- Clean the Flow JSON by removing default values and empty fields.
429
+ """Clean the Flow JSON by removing default values and empty fields.
430
430
 
431
431
  Args:
432
432
  flow: The Flow object to clean.