rasa-pro 3.14.0.dev1__py3-none-any.whl → 3.14.0.dev20250818__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 (147) hide show
  1. rasa/api.py +0 -5
  2. rasa/cli/arguments/default_arguments.py +0 -12
  3. rasa/cli/arguments/run.py +0 -2
  4. rasa/cli/dialogue_understanding_test.py +0 -4
  5. rasa/cli/e2e_test.py +0 -4
  6. rasa/cli/inspect.py +0 -3
  7. rasa/cli/llm_fine_tuning.py +0 -5
  8. rasa/cli/run.py +0 -4
  9. rasa/cli/shell.py +0 -3
  10. rasa/constants.py +0 -6
  11. rasa/core/actions/action.py +2 -42
  12. rasa/core/agent.py +0 -16
  13. rasa/core/available_endpoints.py +0 -30
  14. rasa/core/channels/inspector/dist/assets/{arc-2e78c586.js → arc-1ddec37b.js} +1 -1
  15. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-806b712e.js → blockDiagram-38ab4fdb-18af387c.js} +1 -1
  16. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-0745efa9.js → c4Diagram-3d4e48cf-250127a3.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/channel-59f6d54b.js +1 -0
  18. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-7bd1082b.js → classDiagram-70f12bd4-c3388b34.js} +1 -1
  19. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-d937ba49.js → classDiagram-v2-f2320105-9c893a82.js} +1 -1
  20. rasa/core/channels/inspector/dist/assets/clone-26177ddb.js +1 -0
  21. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-a2a564ca.js → createText-2e5e7dd3-c111213b.js} +1 -1
  22. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b5256940.js → edges-e0da2a9e-812a729d.js} +1 -1
  23. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-e6883ad2.js → erDiagram-9861fffd-fd5051bc.js} +1 -1
  24. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e576fc02.js → flowDb-956e92f1-3287ac02.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-2e298d01.js → flowDiagram-66a62f08-692fb0b2.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-29c03f5a.js +1 -0
  27. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-dd7b150a.js → flowchart-elk-definition-4a651766-008376f1.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-5b79575c.js → ganttDiagram-c361ad54-df330a69.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-3016f40a.js → gitGraphDiagram-72cf32ee-e03676fb.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{graph-3e19170f.js → graph-46fad2ba.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{index-3862675e-eb9c86de.js → index-3862675e-a484ac55.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/index-a003633f.js +1335 -0
  33. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b4280e4d.js → infoDiagram-f8f76790-3f9e6ec2.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-556091f8.js → journeyDiagram-49397b02-79f72383.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{layout-08436411.js → layout-aad098e5.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{line-683c4f3b.js → line-219ab7ae.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{linear-cee6d791.js → linear-2cddbe62.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-a0bf0b1a.js → mindmap-definition-fc14e90a-1d41ed99.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-3730d5c4.js → pieDiagram-8a3498a8-cc496ee8.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-12a20fed.js → quadrantDiagram-120e2f19-84d32884.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-b9732102.js → requirementDiagram-deff3bca-c0deb984.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-a2e72776.js → sankeyDiagram-04a897e0-b9d7fd62.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-8b7a76bb.js → sequenceDiagram-704730f1-7d517565.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-e65853ac.js → stateDiagram-587899a1-98ef9b27.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-6f58a44b.js → stateDiagram-v2-d93cdb3a-cee70748.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-df25b934.js → styles-6aaf32cf-3f9d1c96.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-88357141.js → styles-9a916d00-67471923.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-d600174d.js → styles-c10674c1-bd093fb7.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-4adc3e0b.js → svgDrawCommon-08f97a94-675794e8.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-42816fa1.js → timeline-definition-85554ec2-0ac67617.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-621eb66a.js → xychartDiagram-e933f94c-c018dc37.js} +1 -1
  52. rasa/core/channels/inspector/dist/index.html +1 -1
  53. rasa/core/channels/inspector/src/components/DialogueStack.tsx +5 -7
  54. rasa/core/channels/inspector/src/helpers/formatters.ts +3 -24
  55. rasa/core/channels/inspector/src/theme/base/styles.ts +1 -19
  56. rasa/core/channels/inspector/src/types.ts +0 -4
  57. rasa/core/constants.py +0 -4
  58. rasa/core/policies/enterprise_search_policy.py +2 -4
  59. rasa/core/policies/flow_policy.py +2 -2
  60. rasa/core/policies/flows/flow_executor.py +35 -374
  61. rasa/core/processor.py +1 -6
  62. rasa/core/run.py +1 -8
  63. rasa/core/utils.py +1 -21
  64. rasa/dialogue_understanding/commands/__init__.py +0 -8
  65. rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -97
  66. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +0 -11
  67. rasa/dialogue_understanding/commands/knowledge_answer_command.py +0 -11
  68. rasa/dialogue_understanding/commands/start_flow_command.py +8 -129
  69. rasa/dialogue_understanding/commands/utils.py +2 -6
  70. rasa/dialogue_understanding/generator/command_parser.py +0 -4
  71. rasa/dialogue_understanding/generator/llm_based_command_generator.py +12 -50
  72. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +6 -7
  73. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +6 -7
  74. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -41
  75. rasa/dialogue_understanding/patterns/continue_interrupted.py +1 -163
  76. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +7 -51
  77. rasa/dialogue_understanding/stack/dialogue_stack.py +2 -123
  78. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +0 -57
  79. rasa/dialogue_understanding/stack/utils.py +2 -3
  80. rasa/dialogue_understanding_test/du_test_runner.py +2 -7
  81. rasa/e2e_test/e2e_test_runner.py +0 -5
  82. rasa/server.py +0 -10
  83. rasa/shared/constants.py +0 -5
  84. rasa/shared/core/constants.py +1 -12
  85. rasa/shared/core/domain.py +5 -5
  86. rasa/shared/core/events.py +0 -319
  87. rasa/shared/core/flows/flows_list.py +2 -2
  88. rasa/shared/core/flows/flows_yaml_schema.json +186 -101
  89. rasa/shared/core/flows/steps/call.py +5 -51
  90. rasa/shared/core/flows/validation.py +7 -45
  91. rasa/shared/core/flows/yaml_flows_io.py +3 -3
  92. rasa/shared/providers/llm/_base_litellm_client.py +7 -39
  93. rasa/shared/providers/llm/litellm_router_llm_client.py +4 -8
  94. rasa/shared/providers/llm/llm_client.py +3 -7
  95. rasa/shared/providers/llm/llm_response.py +0 -49
  96. rasa/shared/providers/llm/self_hosted_llm_client.py +4 -8
  97. rasa/shared/utils/llm.py +5 -28
  98. rasa/shared/utils/schemas/events.py +0 -42
  99. rasa/studio/upload.py +7 -4
  100. rasa/tracing/instrumentation/instrumentation.py +2 -4
  101. rasa/utils/common.py +0 -53
  102. rasa/version.py +1 -1
  103. {rasa_pro-3.14.0.dev1.dist-info → rasa_pro-3.14.0.dev20250818.dist-info}/METADATA +2 -3
  104. {rasa_pro-3.14.0.dev1.dist-info → rasa_pro-3.14.0.dev20250818.dist-info}/RECORD +107 -143
  105. rasa/agents/__init__.py +0 -0
  106. rasa/agents/agent_factory.py +0 -122
  107. rasa/agents/agent_manager.py +0 -162
  108. rasa/agents/constants.py +0 -31
  109. rasa/agents/core/__init__.py +0 -0
  110. rasa/agents/core/agent_protocol.py +0 -108
  111. rasa/agents/core/types.py +0 -70
  112. rasa/agents/exceptions.py +0 -8
  113. rasa/agents/protocol/__init__.py +0 -5
  114. rasa/agents/protocol/a2a/__init__.py +0 -0
  115. rasa/agents/protocol/a2a/a2a_agent.py +0 -51
  116. rasa/agents/protocol/mcp/__init__.py +0 -0
  117. rasa/agents/protocol/mcp/mcp_base_agent.py +0 -697
  118. rasa/agents/protocol/mcp/mcp_open_agent.py +0 -275
  119. rasa/agents/protocol/mcp/mcp_task_agent.py +0 -447
  120. rasa/agents/schemas/__init__.py +0 -6
  121. rasa/agents/schemas/agent_input.py +0 -24
  122. rasa/agents/schemas/agent_output.py +0 -26
  123. rasa/agents/schemas/agent_tool_result.py +0 -51
  124. rasa/agents/schemas/agent_tool_schema.py +0 -112
  125. rasa/agents/templates/__init__.py +0 -0
  126. rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +0 -15
  127. rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +0 -13
  128. rasa/agents/utils.py +0 -72
  129. rasa/core/available_agents.py +0 -196
  130. rasa/core/channels/inspector/dist/assets/channel-c436ca7c.js +0 -1
  131. rasa/core/channels/inspector/dist/assets/clone-50dd656b.js +0 -1
  132. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b2aeaf8.js +0 -1
  133. rasa/core/channels/inspector/dist/assets/index-1bd9135e.js +0 -1353
  134. rasa/core/policies/flows/mcp_tool_executor.py +0 -240
  135. rasa/dialogue_understanding/commands/continue_agent_command.py +0 -91
  136. rasa/dialogue_understanding/commands/restart_agent_command.py +0 -146
  137. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +0 -61
  138. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +0 -61
  139. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +0 -81
  140. rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +0 -81
  141. rasa/shared/agents/__init__.py +0 -0
  142. rasa/shared/agents/utils.py +0 -35
  143. rasa/shared/utils/mcp/__init__.py +0 -0
  144. rasa/shared/utils/mcp/server_connection.py +0 -157
  145. {rasa_pro-3.14.0.dev1.dist-info → rasa_pro-3.14.0.dev20250818.dist-info}/NOTICE +0 -0
  146. {rasa_pro-3.14.0.dev1.dist-info → rasa_pro-3.14.0.dev20250818.dist-info}/WHEEL +0 -0
  147. {rasa_pro-3.14.0.dev1.dist-info → rasa_pro-3.14.0.dev20250818.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,5 @@
1
- import {rasaColors} from '../theme/base/colors'
2
- import type {Event, Flow, Slot, Stack} from '../types'
1
+ import { rasaColors } from '../theme/base/colors'
2
+ import type { Event, Flow, Slot, Stack } from '../types'
3
3
 
4
4
  export function formatSlots(slots: { [key: string]: unknown }) {
5
5
  if (!slots) {
@@ -13,7 +13,7 @@ export function formatSlots(slots: { [key: string]: unknown }) {
13
13
  slotDuple[0] !== 'flow_hashes' &&
14
14
  slotDuple[1] != null,
15
15
  )
16
- .map((slotDuple) => ({name: slotDuple[0], value: slotDuple[1]}))
16
+ .map((slotDuple) => ({ name: slotDuple[0], value: slotDuple[1] }))
17
17
  }
18
18
 
19
19
  export const formatTestCases = (events: Event[], sessionId: string) => {
@@ -85,14 +85,11 @@ export const formatFlow = (
85
85
  `flowchart TD
86
86
  classDef collect stroke-width:1px
87
87
  classDef action fill:#FBFCFD,stroke:#A0B8CF
88
- classDef noop fill:#FBFCFD
89
- classDef callstep fill:#FBFCFD
90
88
  classDef link fill:#f43
91
89
  classDef slot fill:#e8f3db,stroke:#c5e1a5
92
90
  classDef endstep fill:#ccc,stroke:#444
93
91
  classDef previous stroke:${rasaColors.rasaOrange[400]},stroke-width:1px
94
92
  classDef active stroke:${rasaColors.rasaOrange[400]},stroke-width:3px,fill:${rasaColors.warning[50]}
95
- classDef pulse animation:pulse 2s infinite
96
93
  `,
97
94
  ]
98
95
  try {
@@ -213,24 +210,6 @@ function renderStepSequence(
213
210
  )}"]:::slot\n`
214
211
  }
215
212
 
216
- if (step.call) {
217
- const isAgentWaitingOnInput = !!currentStack?.agent_id && currentStack?.state === 'waiting_for_input'
218
- mermaidTextFragment += `${mermaidId}["${encodeDoubleQuotes(
219
- stepId,
220
- )} 🤖"]:::callstep\n`
221
-
222
- if (isAgentWaitingOnInput) {
223
- mermaidTextFragment += `class ${mermaidId} pulse\n`
224
- }
225
- }
226
-
227
- if (step.noop) {
228
- mermaidTextFragment += `${mermaidId}["${parseFieldUsingStack(
229
- stepId,
230
- currentStack
231
- )}"]:::noop\n`
232
- }
233
-
234
213
  if (activeStep && stepId === activeStep) {
235
214
  mermaidTextFragment += `class ${mermaidId} active\n`
236
215
  } else if (stepTrail?.includes(stepId)) {
@@ -1,19 +1,4 @@
1
- import {mode, StyleFunctionProps} from '@chakra-ui/theme-tools'
2
- import {keyframes} from "@chakra-ui/react";
3
-
4
-
5
- const pulse = keyframes`
6
- 0% {
7
- opacity: 1;
8
- }
9
- 50% {
10
- opacity: 0.5;
11
- }
12
- 100% {
13
- opacity: 1;
14
- }
15
- `;
16
-
1
+ import { mode, StyleFunctionProps } from '@chakra-ui/theme-tools'
17
2
 
18
3
  export const styles = {
19
4
  global: {
@@ -24,8 +9,5 @@ export const styles = {
24
9
  fontSize: theme.rasaFontSizes.md,
25
10
  letterSpacing: '0.025rem',
26
11
  }),
27
- '.pulse': {
28
- animation: `${pulse} 2s infinite`,
29
- },
30
12
  },
31
13
  }
@@ -40,8 +40,6 @@ export interface Stack {
40
40
  collect?: string
41
41
  utter?: string
42
42
  ended: boolean
43
- agent_id?: string
44
- state?: "waiting_for_input" | "interrupted"
45
43
  }
46
44
 
47
45
  export interface LatencyData {
@@ -97,6 +95,4 @@ interface Step {
97
95
  reset_after_flow_ends: boolean
98
96
  utter: string
99
97
  set_slots?: unknown
100
- call?: string
101
- noop?: boolean
102
98
  }
rasa/core/constants.py CHANGED
@@ -31,10 +31,6 @@ BEARER_TOKEN_PREFIX = "Bearer "
31
31
  # The lowest priority is intended to be used by machine learning policies.
32
32
  DEFAULT_POLICY_PRIORITY = 1
33
33
 
34
- DEFAULT_SUB_AGENTS = "sub_agents"
35
-
36
- MCP_SERVERS_KEY = "mcp_servers"
37
-
38
34
  # The priority of intent-prediction policies.
39
35
  # This should be below all rule based policies but higher than ML
40
36
  # based policies. This enables a loop inside ensemble where if none
@@ -63,8 +63,6 @@ from rasa.shared.constants import (
63
63
  )
64
64
  from rasa.shared.core.constants import (
65
65
  ACTION_CANCEL_FLOW,
66
- ACTION_METADATA_MESSAGE_KEY,
67
- ACTION_METADATA_TEXT_KEY,
68
66
  ACTION_SEND_TEXT_NAME,
69
67
  DEFAULT_SLOT_NAMES,
70
68
  )
@@ -587,8 +585,8 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
587
585
  return self._create_prediction_internal_error(domain, tracker)
588
586
 
589
587
  action_metadata = {
590
- ACTION_METADATA_MESSAGE_KEY: {
591
- ACTION_METADATA_TEXT_KEY: response,
588
+ "message": {
589
+ "text": response,
592
590
  SEARCH_RESULTS_METADATA_KEY: [
593
591
  result.text for result in documents.results
594
592
  ],
@@ -137,7 +137,7 @@ class FlowPolicy(Policy):
137
137
 
138
138
  # create executor and predict next action
139
139
  try:
140
- prediction = await flow_executor.advance_flows(
140
+ prediction = flow_executor.advance_flows(
141
141
  tracker, domain.action_names_or_texts, flows
142
142
  )
143
143
  return self._create_prediction_result(
@@ -164,7 +164,7 @@ class FlowPolicy(Policy):
164
164
  # we retry, with the internal error frame on the stack
165
165
  events = tracker.create_stack_updated_events(updated_stack)
166
166
  tracker.update_with_events(events)
167
- prediction = await flow_executor.advance_flows(
167
+ prediction = flow_executor.advance_flows(
168
168
  tracker, domain.action_names_or_texts, flows
169
169
  )
170
170
  collected_events = events + (prediction.events or [])
@@ -1,22 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- import asyncio
4
- from typing import Any, Dict, List, Optional, Text, cast
3
+ from typing import Any, Dict, List, Optional, Text
5
4
 
6
5
  import structlog
7
6
  from jinja2 import Template
8
7
  from pypred import Predicate
9
- from structlog.contextvars import bound_contextvars
10
-
11
- from rasa.agents.agent_manager import AgentManager
12
- from rasa.agents.constants import (
13
- AGENT_METADATA_AGENT_RESPONSE_KEY,
14
- AGENT_METADATA_EXIT_IF_KEY,
15
- AGENT_METADATA_TOOL_RESULTS_KEY,
8
+ from structlog.contextvars import (
9
+ bound_contextvars,
16
10
  )
17
- from rasa.agents.core.types import AgentStatus, ProtocolType
18
- from rasa.agents.schemas import AgentInput, AgentOutput
19
- from rasa.core.available_agents import AvailableAgents
11
+
20
12
  from rasa.core.available_endpoints import AvailableEndpoints
21
13
  from rasa.core.constants import ACTIVE_FLOW_METADATA_KEY, STEP_ID_METADATA_KEY
22
14
  from rasa.core.policies.flows.flow_exceptions import (
@@ -30,8 +22,7 @@ from rasa.core.policies.flows.flow_step_result import (
30
22
  FlowStepResult,
31
23
  PauseFlowReturnPrediction,
32
24
  )
33
- from rasa.core.policies.flows.mcp_tool_executor import call_mcp_tool
34
- from rasa.core.utils import get_slot_names_from_exit_conditions
25
+ from rasa.dialogue_understanding.commands import CancelFlowCommand
35
26
  from rasa.dialogue_understanding.patterns.cancel import CancelPatternFlowStackFrame
36
27
  from rasa.dialogue_understanding.patterns.collect_information import (
37
28
  FLOW_PATTERN_COLLECT_INFORMATION,
@@ -58,27 +49,17 @@ from rasa.dialogue_understanding.stack.frames import (
58
49
  UserFlowStackFrame,
59
50
  )
60
51
  from rasa.dialogue_understanding.stack.frames.flow_stack_frame import (
61
- AgentStackFrame,
62
- AgentState,
63
52
  FlowStackFrameType,
64
53
  )
65
- from rasa.dialogue_understanding.stack.utils import top_user_flow_frame
66
- from rasa.shared.agents.utils import get_protocol_type
54
+ from rasa.dialogue_understanding.stack.utils import (
55
+ top_user_flow_frame,
56
+ )
67
57
  from rasa.shared.constants import RASA_PATTERN_HUMAN_HANDOFF
68
58
  from rasa.shared.core.constants import (
69
- ACTION_AGENT_REQUEST_USER_INPUT_NAME,
70
59
  ACTION_LISTEN_NAME,
71
- ACTION_METADATA_MESSAGE_KEY,
72
- ACTION_METADATA_TEXT_KEY,
73
- ACTION_SEND_TEXT_NAME,
74
- FLOW_HASHES_SLOT,
75
60
  SILENCE_TIMEOUT_SLOT,
76
61
  )
77
62
  from rasa.shared.core.events import (
78
- AgentCancelled,
79
- AgentCompleted,
80
- AgentResumed,
81
- AgentStarted,
82
63
  Event,
83
64
  FlowCompleted,
84
65
  FlowResumed,
@@ -86,7 +67,11 @@ from rasa.shared.core.events import (
86
67
  SlotSet,
87
68
  )
88
69
  from rasa.shared.core.flows import FlowsList
89
- from rasa.shared.core.flows.flow import END_STEP, Flow, FlowStep
70
+ from rasa.shared.core.flows.flow import (
71
+ END_STEP,
72
+ Flow,
73
+ FlowStep,
74
+ )
90
75
  from rasa.shared.core.flows.flow_step_links import (
91
76
  ElseFlowStepLink,
92
77
  IfFlowStepLink,
@@ -104,19 +89,14 @@ from rasa.shared.core.flows.steps import (
104
89
  )
105
90
  from rasa.shared.core.flows.steps.constants import START_STEP
106
91
  from rasa.shared.core.slots import Slot, SlotRejection
107
- from rasa.shared.core.trackers import DialogueStateTracker
108
- from rasa.shared.utils.llm import tracker_as_readable_transcript
92
+ from rasa.shared.core.trackers import (
93
+ DialogueStateTracker,
94
+ )
109
95
 
110
96
  structlogger = structlog.get_logger()
111
97
 
112
98
  MAX_NUMBER_OF_STEPS = 250
113
99
 
114
- MAX_AGENT_RETRY_DELAY_SECONDS = 5
115
- MAX_AGENT_RETRIES = 3
116
-
117
- # Slots that should not be forwarded to sub-agents via AgentInput
118
- SLOTS_EXCLUDED_FOR_AGENT = [FLOW_HASHES_SLOT]
119
-
120
100
 
121
101
  def render_template_variables(text: str, context: Dict[Text, Any]) -> str:
122
102
  """Replace context variables in a text."""
@@ -168,13 +148,6 @@ def select_next_step_id(
168
148
  tracker: DialogueStateTracker,
169
149
  ) -> Optional[Text]:
170
150
  """Selects the next step id based on the current step."""
171
- # if the current step is a call step to an agent, and we already have an
172
- # AgentStackFrame on top of the stack, we need to return the current
173
- # step id again in order to loop back to the agent.
174
- agent_stack_frame = tracker.stack.top()
175
- if agent_stack_frame and isinstance(agent_stack_frame, AgentStackFrame):
176
- return current.id
177
-
178
151
  next_step = current.next
179
152
  if len(next_step.links) == 1 and isinstance(next_step.links[0], StaticFlowStepLink):
180
153
  return next_step.links[0].target
@@ -386,7 +359,7 @@ def reset_scoped_slots(
386
359
  return events
387
360
 
388
361
 
389
- async def advance_flows(
362
+ def advance_flows(
390
363
  tracker: DialogueStateTracker, available_actions: List[str], flows: FlowsList
391
364
  ) -> FlowActionPrediction:
392
365
  """Advance the current flows until the next action.
@@ -404,10 +377,10 @@ async def advance_flows(
404
377
  # if there are no flows, there is nothing to do
405
378
  return FlowActionPrediction(None, 0.0)
406
379
 
407
- return await advance_flows_until_next_action(tracker, available_actions, flows)
380
+ return advance_flows_until_next_action(tracker, available_actions, flows)
408
381
 
409
382
 
410
- async def advance_flows_until_next_action(
383
+ def advance_flows_until_next_action(
411
384
  tracker: DialogueStateTracker,
412
385
  available_actions: List[str],
413
386
  flows: FlowsList,
@@ -468,7 +441,7 @@ async def advance_flows_until_next_action(
468
441
 
469
442
  with bound_contextvars(step_id=next_step.id):
470
443
  step_stack = tracker.stack
471
- step_result = await run_step(
444
+ step_result = run_step(
472
445
  next_step,
473
446
  current_flow,
474
447
  step_stack,
@@ -504,9 +477,10 @@ async def advance_flows_until_next_action(
504
477
  # make sure we really return all events that got created during the
505
478
  # step execution of all steps (not only the last one)
506
479
  prediction.events = gathered_events
507
- prediction.metadata = prediction.metadata or {}
508
- prediction.metadata[ACTIVE_FLOW_METADATA_KEY] = tracker.active_flow
509
- prediction.metadata[STEP_ID_METADATA_KEY] = tracker.current_step_id
480
+ prediction.metadata = {
481
+ ACTIVE_FLOW_METADATA_KEY: tracker.active_flow,
482
+ STEP_ID_METADATA_KEY: tracker.current_step_id,
483
+ }
510
484
  return prediction
511
485
  else:
512
486
  structlogger.warning("flow.step.execution.no_action")
@@ -548,8 +522,6 @@ def validate_collect_step(
548
522
 
549
523
  def cancel_flow_and_push_internal_error(stack: DialogueStack, flow_name: str) -> None:
550
524
  """Cancel the top user flow and push the internal error pattern."""
551
- from rasa.dialogue_understanding.commands import CancelFlowCommand
552
-
553
525
  top_frame = stack.top()
554
526
 
555
527
  if isinstance(top_frame, BaseFlowStackFrame):
@@ -578,7 +550,7 @@ def attach_stack_metadata_to_events(
578
550
  event.metadata[ACTIVE_FLOW_METADATA_KEY] = flow_id
579
551
 
580
552
 
581
- async def run_step(
553
+ def run_step(
582
554
  step: FlowStep,
583
555
  flow: Flow,
584
556
  stack: DialogueStack,
@@ -643,7 +615,7 @@ async def run_step(
643
615
  return _run_link_step(initial_events, stack, step)
644
616
 
645
617
  elif isinstance(step, CallFlowStep):
646
- return await _run_call_step(initial_events, stack, step, tracker)
618
+ return _run_call_step(initial_events, stack, step)
647
619
 
648
620
  elif isinstance(step, SetSlotsFlowStep):
649
621
  return _run_set_slot_step(initial_events, step)
@@ -712,25 +684,17 @@ def _run_set_slot_step(
712
684
  return ContinueFlowWithNextStep(events=initial_events + slot_events)
713
685
 
714
686
 
715
- async def _run_call_step(
716
- initial_events: List[Event],
717
- stack: DialogueStack,
718
- step: CallFlowStep,
719
- tracker: DialogueStateTracker,
687
+ def _run_call_step(
688
+ initial_events: List[Event], stack: DialogueStack, step: CallFlowStep
720
689
  ) -> FlowStepResult:
721
690
  structlogger.debug("flow.step.run.call")
722
- if step.is_calling_mcp_tool():
723
- return await call_mcp_tool(initial_events, stack, step, tracker)
724
- elif step.is_calling_agent():
725
- return await run_agent(initial_events, stack, step, tracker)
726
- else:
727
- stack.push(
728
- UserFlowStackFrame(
729
- flow_id=step.call,
730
- frame_type=FlowStackFrameType.CALL,
731
- ),
732
- )
733
- return ContinueFlowWithNextStep(events=initial_events)
691
+ stack.push(
692
+ UserFlowStackFrame(
693
+ flow_id=step.call,
694
+ frame_type=FlowStackFrameType.CALL,
695
+ ),
696
+ )
697
+ return ContinueFlowWithNextStep(events=initial_events)
734
698
 
735
699
 
736
700
  def _run_link_step(
@@ -868,306 +832,3 @@ def _append_global_silence_timeout_event(
868
832
  AvailableEndpoints.get_instance().interaction_handling.global_silence_timeout,
869
833
  )
870
834
  )
871
-
872
-
873
- def _reset_slots_covered_by_exit_if(
874
- exit_conditions: List[str], tracker: DialogueStateTracker
875
- ) -> None:
876
- """Reset the slots covered by the exit_if condition."""
877
- reset_slot_names = get_slot_names_from_exit_conditions(exit_conditions)
878
- for slot_name in reset_slot_names:
879
- if tracker.slots.get(slot_name) is not None:
880
- tracker.update(SlotSet(slot_name, None))
881
-
882
-
883
- async def run_agent(
884
- initial_events: List[Event],
885
- stack: DialogueStack,
886
- step: CallFlowStep,
887
- tracker: DialogueStateTracker,
888
- ) -> FlowStepResult:
889
- """Run an agent call step."""
890
- structlogger.debug(
891
- "flow.step.run_agent", agent_id=step.call, step_id=step.id, flow_id=step.flow_id
892
- )
893
-
894
- final_events = initial_events
895
- agent_stack_frame = tracker.stack.find_agent_stack_frame_by_agent(
896
- agent_id=step.call
897
- )
898
-
899
- if (
900
- agent_stack_frame
901
- and agent_stack_frame == stack.top()
902
- and agent_stack_frame.state == AgentState.INTERRUPTED
903
- ):
904
- structlogger.debug(
905
- "flow.step.run_agent.resume_interrupted_agent",
906
- agent_id=step.call,
907
- step_id=step.id,
908
- flow_id=step.flow_id,
909
- )
910
- # The agent was previously interrupted when waiting for user input.
911
- # Now we're back to the agent execution step and need to output the last message
912
- # from the agent (user input request) again and wait for user input
913
- cast(AgentStackFrame, stack.top()).state = AgentState.WAITING_FOR_INPUT
914
- tracker.update_stack(stack)
915
- utterance = (
916
- agent_stack_frame.metadata.get(AGENT_METADATA_AGENT_RESPONSE_KEY, "")
917
- if agent_stack_frame.metadata
918
- else ""
919
- )
920
- final_events.append(AgentResumed(agent_id=step.call, flow_id=step.flow_id))
921
- return PauseFlowReturnPrediction(
922
- _create_agent_request_user_input_prediction(utterance, final_events)
923
- )
924
-
925
- agent_input_metadata = (
926
- agent_stack_frame.metadata
927
- if agent_stack_frame and agent_stack_frame.metadata
928
- else {}
929
- )
930
- if step.exit_if:
931
- # TODO: this is a temporary fix to reset the slots covered by the exit_if
932
- if (
933
- agent_stack_frame
934
- and agent_stack_frame.frame_id == f"restart_agent_{step.call}"
935
- ):
936
- # when restarting an agent, we need to reset the slots covered by the
937
- # exit_if condition so that the agent can run again.
938
- _reset_slots_covered_by_exit_if(step.exit_if, tracker)
939
- agent_input_metadata[AGENT_METADATA_EXIT_IF_KEY] = step.exit_if
940
- agent_input = AgentInput(
941
- id=step.call,
942
- user_message=tracker.latest_message.text or ""
943
- if tracker.latest_message
944
- else "",
945
- slots=_filter_slots_for_agent(tracker.current_slot_values()),
946
- conversation_history=tracker_as_readable_transcript(tracker),
947
- events=tracker.current_state().get("events") or [],
948
- metadata=agent_input_metadata,
949
- )
950
-
951
- final_events.append(AgentStarted(step.call, step.flow_id))
952
-
953
- protocol_type = get_protocol_type(step, AvailableAgents.get_agent_config(step.call))
954
- # send the input to the agent and wait for a response
955
- structlogger.debug(
956
- "flow.step.run_agent.agent_input",
957
- agent_name=step.call,
958
- step_id=step.id,
959
- flow_id=step.flow_id,
960
- agent_input=agent_input,
961
- )
962
- output: AgentOutput = await _call_agent_with_retry(
963
- agent_name=step.call,
964
- protocol_type=protocol_type,
965
- agent_input=agent_input,
966
- max_retries=MAX_AGENT_RETRIES,
967
- )
968
- structlogger.debug(
969
- "flow.step.run_agent.agent_response",
970
- agent_name=step.call,
971
- step_id=step.id,
972
- flow_id=step.flow_id,
973
- agent_response=output,
974
- )
975
-
976
- # add the set slot events returned by the agent to the list of final events
977
- if output.events:
978
- final_events.extend(output.events)
979
-
980
- if output.status == AgentStatus.INPUT_REQUIRED:
981
- output.metadata = output.metadata or {}
982
- output.metadata[AGENT_METADATA_AGENT_RESPONSE_KEY] = (
983
- output.response_message or ""
984
- )
985
- output.metadata[AGENT_METADATA_TOOL_RESULTS_KEY] = output.tool_results or []
986
-
987
- top_stack_frame = stack.top()
988
- # update the agent stack frame if it is already on the stack
989
- # otherwise push a new one
990
- if isinstance(top_stack_frame, AgentStackFrame):
991
- top_stack_frame.state = AgentState.WAITING_FOR_INPUT
992
- top_stack_frame.metadata = output.metadata
993
- top_stack_frame.step_id = step.id
994
- top_stack_frame.agent_id = step.call
995
- top_stack_frame.flow_id = step.flow_id
996
- else:
997
- stack.push(
998
- AgentStackFrame(
999
- flow_id=step.flow_id,
1000
- agent_id=step.call,
1001
- state=AgentState.WAITING_FOR_INPUT,
1002
- step_id=step.id,
1003
- metadata=output.metadata,
1004
- )
1005
- )
1006
-
1007
- action_prediction = _create_agent_request_user_input_prediction(
1008
- output.response_message, final_events
1009
- )
1010
- return PauseFlowReturnPrediction(action_prediction)
1011
- elif output.status == AgentStatus.COMPLETED:
1012
- structlogger.debug(
1013
- "flow.step.run_agent.completed",
1014
- agent_name=step.call,
1015
- step_id=step.id,
1016
- flow_id=step.flow_id,
1017
- )
1018
- remove_agent_stack_frame(stack, step.call)
1019
- agent_completed_event = AgentCompleted(agent_id=step.call, flow_id=step.flow_id)
1020
- final_events.append(agent_completed_event)
1021
- if output.response_message:
1022
- # for open-ended agents we want to utter the last agent message
1023
-
1024
- return PauseFlowReturnPrediction(
1025
- _create_send_text_prediction(output.response_message, final_events)
1026
- )
1027
- else:
1028
- return ContinueFlowWithNextStep(events=final_events)
1029
- elif output.status == AgentStatus.FATAL_ERROR:
1030
- # the agent failed, trigger pattern_internal_error
1031
- structlogger.error(
1032
- "flow.step.run_agent.fatal_error",
1033
- agent_name=step.call,
1034
- step_id=step.id,
1035
- flow_id=step.flow_id,
1036
- error_message=output.error_message,
1037
- )
1038
- remove_agent_stack_frame(stack, step.call)
1039
- final_events.append(
1040
- AgentCancelled(
1041
- agent_id=step.call, flow_id=step.flow_id, reason=output.error_message
1042
- )
1043
- )
1044
- stack.push(InternalErrorPatternFlowStackFrame())
1045
- return ContinueFlowWithNextStep(events=final_events)
1046
- else:
1047
- structlogger.error(
1048
- "flow.step.run_agent.unknown_status",
1049
- agent_name=step.call,
1050
- step_id=step.id,
1051
- flow_id=step.flow_id,
1052
- status=output.status,
1053
- )
1054
- remove_agent_stack_frame(stack, step.call)
1055
- final_events.append(AgentCancelled(agent_id=step.call, flow_id=step.flow_id))
1056
- stack.push(InternalErrorPatternFlowStackFrame())
1057
- return ContinueFlowWithNextStep(events=final_events)
1058
-
1059
-
1060
- def remove_agent_stack_frame(stack: DialogueStack, agent_id: str) -> None:
1061
- """Finishes the agentic loop by popping the agent stack frame from the
1062
- provided `stack`. The `tracker.stack` is NOT modified.
1063
- """
1064
- agent_stack_frame = stack.find_agent_stack_frame_by_agent(agent_id)
1065
- if not agent_stack_frame:
1066
- return
1067
-
1068
- while removed_frame := stack.pop():
1069
- structlogger.debug(
1070
- "flow_executor.remove_agent_stack_frame",
1071
- removed_frame=removed_frame,
1072
- )
1073
- if removed_frame == agent_stack_frame:
1074
- break
1075
-
1076
-
1077
- def _create_action_prediction(
1078
- action_name: str, message: Optional[str], events: Optional[List[Event]]
1079
- ) -> FlowActionPrediction:
1080
- """Create a prediction for an action with a text message."""
1081
- action_metadata = {
1082
- ACTION_METADATA_MESSAGE_KEY: {
1083
- ACTION_METADATA_TEXT_KEY: message,
1084
- }
1085
- }
1086
- return FlowActionPrediction(
1087
- action_name,
1088
- 1.0,
1089
- events=events if events else [],
1090
- metadata=action_metadata,
1091
- )
1092
-
1093
-
1094
- def _create_agent_request_user_input_prediction(
1095
- message: Optional[str], events: Optional[List[Event]]
1096
- ) -> FlowActionPrediction:
1097
- """Create a prediction for requesting user input from the agent
1098
- and waiting for it.
1099
- """
1100
- return _create_action_prediction(
1101
- ACTION_AGENT_REQUEST_USER_INPUT_NAME, message, events
1102
- )
1103
-
1104
-
1105
- def _create_send_text_prediction(
1106
- message: Optional[str], events: Optional[List[Event]]
1107
- ) -> FlowActionPrediction:
1108
- """Create a prediction for sending a text message to the user."""
1109
- return _create_action_prediction(ACTION_SEND_TEXT_NAME, message, events)
1110
-
1111
-
1112
- async def _call_agent_with_retry(
1113
- agent_name: str,
1114
- protocol_type: ProtocolType,
1115
- agent_input: AgentInput,
1116
- max_retries: int,
1117
- ) -> AgentOutput:
1118
- """Call an agent with retries in case of recoverable errors."""
1119
- for attempt in range(max_retries):
1120
- if attempt > 0:
1121
- structlogger.debug(
1122
- "flow_executor.call_agent_with_retry.retrying",
1123
- agent_name=agent_name,
1124
- attempt=attempt + 1,
1125
- num_retries=max_retries,
1126
- )
1127
-
1128
- agent_response: AgentOutput = await AgentManager().run_agent(
1129
- agent_name=agent_name, protocol_type=protocol_type, context=agent_input
1130
- )
1131
- if agent_response.status != AgentStatus.RECOVERABLE_ERROR:
1132
- return agent_response
1133
-
1134
- structlogger.warning(
1135
- "flow_executor.call_agent_with_retry.recoverable_error",
1136
- agent_name=agent_name,
1137
- attempt=attempt + 1,
1138
- num_retries=max_retries,
1139
- error_message=agent_response.error_message,
1140
- )
1141
- if attempt < max_retries - 1:
1142
- # exponential backoff - wait longer with each retry
1143
- # 1 second, 2 seconds, 4 seconds, etc.
1144
- await asyncio.sleep(min(2**attempt, MAX_AGENT_RETRY_DELAY_SECONDS))
1145
-
1146
- # we exhausted all retries, return fatal error
1147
- structlogger.warning(
1148
- "flow_executor.call_agent_with_retry.exhausted_retries",
1149
- agent_name=agent_name,
1150
- num_retries=max_retries,
1151
- )
1152
- return AgentOutput(
1153
- id=agent_name,
1154
- status=AgentStatus.FATAL_ERROR,
1155
- error_message="Exhausted all retries for agent call.",
1156
- )
1157
-
1158
-
1159
- def _filter_slots_for_agent(slots: Dict[str, Any]) -> Dict[str, Any]:
1160
- """Filter out slots that should not be forwarded to agents.
1161
-
1162
- Args:
1163
- slots: The full slot dictionary from the tracker.
1164
-
1165
- Returns:
1166
- A copy of the slot dictionary excluding slots listed in
1167
- `SLOTS_EXCLUDED_FOR_AGENT`.
1168
- """
1169
- return {
1170
- key: value
1171
- for key, value in slots.items()
1172
- if key not in SLOTS_EXCLUDED_FOR_AGENT
1173
- }