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
@@ -45,30 +45,29 @@ DEFAULT_LLM_CONFIG = {
45
45
  TIMEOUT_CONFIG_KEY: 7,
46
46
  }
47
47
 
48
- # TODO: only load the agent prompt template in cases where agents are actually used
49
48
  MODEL_PROMPT_MAPPER = {
50
49
  f"{OPENAI_PROVIDER}/{MODEL_NAME_GPT_4O_2024_11_20}": (
51
- "agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
50
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
52
51
  ),
53
52
  f"{AZURE_OPENAI_PROVIDER}/{MODEL_NAME_GPT_4O_2024_11_20}": (
54
- "agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
53
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
55
54
  ),
56
55
  f"{AWS_BEDROCK_PROVIDER}/anthropic.{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}-v1:0": (
57
- "agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2"
56
+ "command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2"
58
57
  ),
59
58
  f"{ANTHROPIC_PROVIDER}/{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}": (
60
- "agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2"
59
+ "command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2"
61
60
  ),
62
61
  }
63
62
 
64
63
  # When model is not configured, then we use the default prompt template
65
64
  DEFAULT_COMMAND_PROMPT_TEMPLATE_FILE_NAME = (
66
- "agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
65
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
67
66
  )
68
67
  # When the configured model is not found in the model prompt mapper, then we use the
69
68
  # fallback prompt template
70
69
  FALLBACK_COMMAND_PROMPT_TEMPLATE_FILE_NAME = (
71
- "agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
70
+ "command_prompt_v2_gpt_4o_2024_11_20_template.jinja2"
72
71
  )
73
72
 
74
73
 
@@ -44,26 +44,25 @@ DEFAULT_LLM_CONFIG = {
44
44
  TIMEOUT_CONFIG_KEY: 7,
45
45
  }
46
46
 
47
- # TODO: only load the agent prompt template in cases where agents are actually used
48
47
  DEFAULT_COMMAND_PROMPT_TEMPLATE_FILE_NAME = (
49
- "agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
48
+ "command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
50
49
  )
51
50
  FALLBACK_COMMAND_PROMPT_TEMPLATE_FILE_NAME = (
52
- "agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
51
+ "command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
53
52
  )
54
53
  MODEL_PROMPT_MAPPER = {
55
54
  f"{OPENAI_PROVIDER}/{MODEL_NAME_GPT_4O_2024_11_20}": (
56
- "agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
55
+ "command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
57
56
  ),
58
57
  f"{AZURE_OPENAI_PROVIDER}/{MODEL_NAME_GPT_4O_2024_11_20}": (
59
- "agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
58
+ "command_prompt_v3_gpt_4o_2024_11_20_template.jinja2"
60
59
  ),
61
60
  f"{AWS_BEDROCK_PROVIDER}/anthropic."
62
61
  f"{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}-v1:0": (
63
- "agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2"
62
+ "command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2"
64
63
  ),
65
64
  f"{ANTHROPIC_PROVIDER}/{MODEL_NAME_CLAUDE_3_5_SONNET_20240620}": (
66
- "agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2"
65
+ "command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2"
67
66
  ),
68
67
  }
69
68
 
@@ -5,7 +5,6 @@ from typing import Any, Dict, List, Literal, Optional, Text
5
5
  import structlog
6
6
 
7
7
  import rasa.shared.utils.io
8
- from rasa.core.available_agents import AvailableAgents
9
8
  from rasa.dialogue_understanding.commands import (
10
9
  CannotHandleCommand,
11
10
  Command,
@@ -45,7 +44,6 @@ from rasa.shared.constants import (
45
44
  PROMPT_TEMPLATE_CONFIG_KEY,
46
45
  ROUTE_TO_CALM_SLOT,
47
46
  )
48
- from rasa.shared.core.events import AgentCompleted
49
47
  from rasa.shared.core.flows import FlowsList
50
48
  from rasa.shared.core.trackers import DialogueStateTracker
51
49
  from rasa.shared.exceptions import ProviderClientAPIException
@@ -398,15 +396,13 @@ class SingleStepBasedLLMCommandGenerator(LLMBasedCommandGenerator, ABC):
398
396
  current_slot_allowed_values = allowed_values_for_slot(
399
397
  tracker.slots.get(current_slot)
400
398
  )
401
- current_conversation = tracker_as_readable_transcript(
402
- tracker, highlight_agent_turns=True
403
- )
399
+ current_conversation = tracker_as_readable_transcript(tracker)
404
400
  latest_user_message = sanitize_message_for_prompt(message.get(TEXT))
405
401
  current_conversation += f"\nUSER: {latest_user_message}"
406
402
 
407
403
  inputs = {
408
404
  "available_flows": self.prepare_flows_for_template(
409
- startable_flows, tracker, add_agent_info=True
405
+ startable_flows, tracker
410
406
  ),
411
407
  "current_conversation": current_conversation,
412
408
  "flow_slots": flow_slots,
@@ -416,10 +412,6 @@ class SingleStepBasedLLMCommandGenerator(LLMBasedCommandGenerator, ABC):
416
412
  "current_slot_type": current_slot_type,
417
413
  "current_slot_allowed_values": current_slot_allowed_values,
418
414
  "user_message": latest_user_message,
419
- "active_agent": self._get_active_agent(tracker, top_flow.id)
420
- if top_flow
421
- else None,
422
- "completed_agents": self._get_completed_agents(tracker),
423
415
  }
424
416
 
425
417
  return self.compile_template(self.prompt_template).render(**inputs)
@@ -467,34 +459,3 @@ class SingleStepBasedLLMCommandGenerator(LLMBasedCommandGenerator, ABC):
467
459
  ) -> Optional[str]:
468
460
  """Get the prompt template from the config or the default prompt template."""
469
461
  pass
470
-
471
- def _get_active_agent(
472
- self, tracker: DialogueStateTracker, active_flow_id: str
473
- ) -> Optional[Dict[str, Any]]:
474
- agent_frame = tracker.stack.find_active_agent_stack_frame_for_flow(
475
- active_flow_id
476
- )
477
- if agent_frame:
478
- return self._get_agent_info(agent_frame.agent_id)
479
- return None
480
-
481
- def _get_completed_agents(
482
- self, tracker: DialogueStateTracker
483
- ) -> List[Dict[str, Any]]:
484
- completed_agents: List[Dict[str, Any]] = []
485
- for event in reversed(tracker.events):
486
- if isinstance(event, AgentCompleted):
487
- agent_info = self._get_agent_info(event.agent_id)
488
- if agent_info:
489
- completed_agents.append(agent_info)
490
- return completed_agents
491
-
492
- def _get_agent_info(self, agent_id: str) -> Optional[Dict[str, Any]]:
493
- agent_config = AvailableAgents.get_agent_config(agent_id)
494
- if agent_config is None:
495
- return None
496
-
497
- return {
498
- "name": agent_config.agent.name,
499
- "description": agent_config.agent.description,
500
- }
@@ -1,31 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from typing import Any, Dict, List, Optional, Text
4
+ from typing import Any, Dict
5
5
 
6
- from rasa.core.actions.action import Action
7
- from rasa.core.channels import OutputChannel
8
- from rasa.core.nlg import NaturalLanguageGenerator
9
6
  from rasa.dialogue_understanding.stack.frames import PatternFlowStackFrame
10
- from rasa.dialogue_understanding.stack.utils import top_user_flow_frame
11
7
  from rasa.shared.constants import RASA_DEFAULT_FLOW_PATTERN_PREFIX
12
- from rasa.shared.core.constants import (
13
- ACTION_ASK_INTERRUPTED_FLOW_TO_CONTINUE,
14
- ACTION_CANCEL_INTERRUPTED_FLOW,
15
- ACTION_CONTINUE_INTERRUPTED_FLOW,
16
- ACTION_SET_INTERRUPTED_FLOWS,
17
- )
18
- from rasa.shared.core.domain import Domain
19
- from rasa.shared.core.events import Event, SlotSet
20
- from rasa.shared.core.trackers import DialogueStateTracker
21
8
 
22
9
  FLOW_PATTERN_CONTINUE_INTERRUPTED = (
23
10
  RASA_DEFAULT_FLOW_PATTERN_PREFIX + "continue_interrupted"
24
11
  )
25
- INTERRUPTED_FLOWS_SLOT = "interrupted_flows"
26
- INTERRUPTED_FLOW_TO_CONTINUE_SLOT = "interrupted_flow_to_continue"
27
- MULTIPLE_FLOWS_INTERRUPTED_SLOT = "multiple_flows_interrupted"
28
- CONFIRMATION_CONTINUE_INTERRUPTED_FLOW_SLOT = "confirmation_continue_interrupted_flow"
29
12
 
30
13
 
31
14
  @dataclass
@@ -66,148 +49,3 @@ class ContinueInterruptedPatternFlowStackFrame(PatternFlowStackFrame):
66
49
  and self.step_id == other.step_id
67
50
  and self.previous_flow_name == other.previous_flow_name
68
51
  )
69
-
70
-
71
- class ActionSetInterruptedFlows(Action):
72
- def name(self) -> str:
73
- return ACTION_SET_INTERRUPTED_FLOWS
74
-
75
- async def run(
76
- self,
77
- output_channel: OutputChannel,
78
- nlg: NaturalLanguageGenerator,
79
- tracker: DialogueStateTracker,
80
- domain: Domain,
81
- metadata: Optional[Dict[Text, Any]] = None,
82
- ) -> list[Event]:
83
- interrupted_flows_set = set()
84
- interrupted_user_flow_stack_frames = tracker.stack.get_all_user_flow_frames()
85
-
86
- for frame in interrupted_user_flow_stack_frames:
87
- interrupted_flows_set.add(frame.flow_id)
88
-
89
- interrupted_flows = list(interrupted_flows_set)
90
- multiple_flows_interrupted = len(interrupted_flows) > 1
91
-
92
- return [
93
- SlotSet(INTERRUPTED_FLOWS_SLOT, interrupted_flows),
94
- SlotSet(MULTIPLE_FLOWS_INTERRUPTED_SLOT, multiple_flows_interrupted),
95
- ]
96
-
97
-
98
- class ActionAskInterruptedFlowToContinue(Action):
99
- def name(self) -> str:
100
- return ACTION_ASK_INTERRUPTED_FLOW_TO_CONTINUE
101
-
102
- async def run(
103
- self,
104
- output_channel: OutputChannel,
105
- nlg: NaturalLanguageGenerator,
106
- tracker: DialogueStateTracker,
107
- domain: Domain,
108
- metadata: Optional[Dict[Text, Any]] = None,
109
- ) -> List[Event]:
110
- interrupted_flows = tracker.get_slot(INTERRUPTED_FLOWS_SLOT) or []
111
-
112
- buttons = [
113
- {
114
- "title": flow_id,
115
- "payload": f'/SetSlots{{"{INTERRUPTED_FLOW_TO_CONTINUE_SLOT}": '
116
- f'"{flow_id}"}}',
117
- }
118
- for flow_id in interrupted_flows or []
119
- ]
120
- buttons.append(
121
- {
122
- "title": "None of them",
123
- "payload": f'/SetSlots{{"{INTERRUPTED_FLOW_TO_CONTINUE_SLOT}": '
124
- f'"none"}}',
125
- }
126
- )
127
-
128
- await output_channel.send_text_with_buttons(
129
- tracker.sender_id,
130
- "You previously started several other tasks. "
131
- "Would you like to resume any of them?",
132
- buttons=buttons,
133
- )
134
-
135
- return []
136
-
137
-
138
- class ActionContinueInterruptedFlow(Action):
139
- def name(self) -> str:
140
- return ACTION_CONTINUE_INTERRUPTED_FLOW
141
-
142
- async def run(
143
- self,
144
- output_channel: OutputChannel,
145
- nlg: NaturalLanguageGenerator,
146
- tracker: DialogueStateTracker,
147
- domain: Domain,
148
- metadata: Optional[Dict[Text, Any]] = None,
149
- ) -> List[Event]:
150
- from rasa.dialogue_understanding.commands import StartFlowCommand
151
-
152
- # get all necessary slot values
153
- multiple = tracker.get_slot(MULTIPLE_FLOWS_INTERRUPTED_SLOT)
154
- selected_flow = tracker.get_slot(INTERRUPTED_FLOW_TO_CONTINUE_SLOT)
155
- interrupted_flows = tracker.get_slot(INTERRUPTED_FLOWS_SLOT) or []
156
-
157
- original_user_frame = top_user_flow_frame(tracker.stack)
158
-
159
- # case of multiple interrupted flows, where the user selected a flow to continue
160
- if multiple:
161
- flow_id = selected_flow if selected_flow else None
162
- # case of single interrupted flow, so there is only one flow to continue
163
- else:
164
- flow_id = interrupted_flows[0] if interrupted_flows else None
165
-
166
- event_list = []
167
- if flow_id:
168
- # TODO: refactor to avoid creating a StartFlowCommand first
169
- # resume the flow with the provided flow id
170
- start_flow_command = StartFlowCommand(flow_id)
171
- event_list = start_flow_command.resume_flow(
172
- tracker, tracker.stack, original_user_frame
173
- )
174
- else:
175
- await output_channel.send_text_message(
176
- tracker.sender_id,
177
- "You haven't selected a valid task to resume. "
178
- "Please specify the task you would like to continue.",
179
- )
180
-
181
- return event_list
182
-
183
-
184
- class ActionCancelInterruptedFlow(Action):
185
- def name(self) -> str:
186
- return ACTION_CANCEL_INTERRUPTED_FLOW
187
-
188
- async def run(
189
- self,
190
- output_channel: OutputChannel,
191
- nlg: NaturalLanguageGenerator,
192
- tracker: DialogueStateTracker,
193
- domain: Domain,
194
- metadata: Optional[Dict[Text, Any]] = None,
195
- ) -> List[Event]:
196
- from rasa.dialogue_understanding.commands import CancelFlowCommand
197
-
198
- interrupted_flows = tracker.get_slot(INTERRUPTED_FLOWS_SLOT) or []
199
-
200
- event_list = []
201
- for flow_id in interrupted_flows:
202
- # TODO: refactor to avoid creating a CancelFlowCommand first
203
- cancel_flow_command = CancelFlowCommand()
204
- event_list.extend(
205
- cancel_flow_command.cancel_flow(tracker, tracker.stack, flow_id)
206
- )
207
-
208
- return event_list + [
209
- SlotSet(INTERRUPTED_FLOWS_SLOT, None),
210
- SlotSet(INTERRUPTED_FLOW_TO_CONTINUE_SLOT, None),
211
- SlotSet(MULTIPLE_FLOWS_INTERRUPTED_SLOT, None),
212
- SlotSet(CONFIRMATION_CONTINUE_INTERRUPTED_FLOW_SLOT, None),
213
- ]
@@ -1,17 +1,6 @@
1
1
  version: "3.1"
2
2
  responses:
3
3
 
4
- utter_ask_continue_interrupted_flow:
5
- - text: "Would you like to continue with {{ context.previous_flow_name }}?"
6
- metadata:
7
- rephrase: True
8
- template: jinja
9
- buttons:
10
- - title: "Yes"
11
- payload: "/SetSlots(confirmation_continue_interrupted_flow=true)"
12
- - title: "No"
13
- payload: "/SetSlots(confirmation_continue_interrupted_flow=false)"
14
-
15
4
  utter_ask_rephrase:
16
5
  - text: I’m sorry I am unable to understand you, could you please rephrase?
17
6
 
@@ -64,6 +53,12 @@ responses:
64
53
  rephrase: True
65
54
  template: jinja
66
55
 
56
+ utter_flow_continue_interrupted:
57
+ - text: "Let's continue with {{ context.previous_flow_name }}."
58
+ metadata:
59
+ rephrase: True
60
+ template: jinja
61
+
67
62
  utter_free_chitchat_response:
68
63
  - text: "Sorry, I'm not able to answer that right now."
69
64
  metadata:
@@ -129,19 +124,6 @@ slots:
129
124
  type: float
130
125
  initial_value: 0.0
131
126
  max_value: 1000000
132
- interrupted_flows:
133
- type: list
134
- multiple_flows_interrupted:
135
- type: bool
136
- initial_value: false
137
- confirmation_continue_interrupted_flow:
138
- type: bool
139
- initial_value: null
140
- mappings:
141
- - type: controlled
142
- interrupted_flow_to_continue:
143
- type: text
144
- initial_value: null
145
127
 
146
128
  flows:
147
129
  pattern_cancel_flow:
@@ -228,33 +210,7 @@ flows:
228
210
  description: Conversation repair flow for managing when users switch between different flows
229
211
  name: pattern continue interrupted
230
212
  steps:
231
- - action: action_set_interrupted_flows
232
- - noop: true
233
- next:
234
- - if: slots.multiple_flows_interrupted
235
- then:
236
- - collect: interrupted_flow_to_continue
237
- description: "Fill this slot with the name of the flow the user wants to continue. If the user does not want to continue any of the interrupted flows, fill this slot with 'none'."
238
- next:
239
- - if: slots.interrupted_flow_to_continue != "none"
240
- then:
241
- - action: action_continue_interrupted_flow
242
- next: END
243
- - else:
244
- - action: action_cancel_interrupted_flow
245
- next: END
246
- - else:
247
- - collect: confirmation_continue_interrupted_flow
248
- description: "If the user wants to continue the interrupted flow, fill this slot with true. If the user does not want to continue the interrupted flow, fill this slot with false."
249
- utter: utter_ask_continue_interrupted_flow
250
- next:
251
- - if: slots.confirmation_continue_interrupted_flow
252
- then:
253
- - action: action_continue_interrupted_flow
254
- next: END
255
- - else:
256
- - action: action_cancel_interrupted_flow
257
- next: END
213
+ - action: utter_flow_continue_interrupted
258
214
 
259
215
  pattern_correction:
260
216
  description: Conversation repair flow for managing user input changes or error corrections
@@ -8,13 +8,6 @@ from typing import Any, Callable, Dict, List, Optional
8
8
  import jsonpatch
9
9
  import structlog
10
10
 
11
- from rasa.dialogue_understanding.stack.frames.flow_stack_frame import (
12
- AgentStackFrame,
13
- AgentState,
14
- FlowStackFrameType,
15
- UserFlowStackFrame,
16
- )
17
-
18
11
  if typing.TYPE_CHECKING:
19
12
  from rasa.dialogue_understanding.stack.frames import DialogueStackFrame
20
13
 
@@ -98,42 +91,6 @@ class DialogueStack:
98
91
  """
99
92
  return self.frames.pop()
100
93
 
101
- def move_frames_to_top(self, frames_to_move: List["DialogueStackFrame"]) -> None:
102
- """Moves specified frames to top of stack while preserving their relative order.
103
-
104
- Args:
105
- frames_to_move: The frames to move to the top of the stack.
106
- """
107
- # Get frames that are not being moved
108
- frames_to_keep = [frame for frame in self.frames if frame not in frames_to_move]
109
-
110
- # Reorder: keep frames first, then moved frames
111
- self.frames = frames_to_keep + frames_to_move
112
-
113
- # set all frames to interrupt except for LINK and CALL
114
- for frame in self.frames:
115
- if (
116
- isinstance(frame, UserFlowStackFrame)
117
- and frame.frame_type == FlowStackFrameType.LINK
118
- ):
119
- continue
120
- if (
121
- isinstance(frame, UserFlowStackFrame)
122
- and frame.frame_type == FlowStackFrameType.CALL
123
- ):
124
- continue
125
- if (
126
- isinstance(frame, UserFlowStackFrame)
127
- and frame.frame_type == FlowStackFrameType.REGULAR
128
- ):
129
- frame.frame_type = FlowStackFrameType.INTERRUPT
130
-
131
- # set the first frame to regular
132
- for frame in self.frames:
133
- if isinstance(frame, UserFlowStackFrame):
134
- frame.frame_type = FlowStackFrameType.REGULAR
135
- return
136
-
137
94
  def current_context(self) -> Dict[str, Any]:
138
95
  """Returns the context of the topmost frame.
139
96
 
@@ -152,7 +109,7 @@ class DialogueStack:
152
109
  """Returns the topmost frame from the stack.
153
110
 
154
111
  Args:
155
- ignore: The ID of the flow to ignore. Picks the top most
112
+ ignore_frame: The ID of the flow to ignore. Picks the top most
156
113
  frame that has a different flow ID.
157
114
 
158
115
  Returns:
@@ -179,8 +136,7 @@ class DialogueStack:
179
136
  patch_dump: The patch to apply to the stack.
180
137
 
181
138
  Returns:
182
- The updated stack.
183
- """
139
+ The updated stack."""
184
140
  patch = jsonpatch.JsonPatch.from_string(patch_dump)
185
141
  dialogue_stack_dump = patch.apply(self.as_dict())
186
142
  return DialogueStack.from_dict(dialogue_stack_dump)
@@ -221,80 +177,3 @@ class DialogueStack:
221
177
  if patch:
222
178
  return patch.to_string()
223
179
  return None
224
-
225
- def _find_agent_frame_by_predicate(
226
- self, predicate: Callable[[AgentStackFrame], bool]
227
- ) -> List[AgentStackFrame]:
228
- stack_frames: List[AgentStackFrame] = []
229
- for stack_frame in reversed(self.frames):
230
- if isinstance(stack_frame, AgentStackFrame) and predicate(stack_frame):
231
- stack_frames.append(stack_frame)
232
- return stack_frames
233
-
234
- def find_active_agent_frame(self) -> Optional[AgentStackFrame]:
235
- stack_frames = self._find_agent_frame_by_predicate(
236
- lambda frame: frame.state == AgentState.WAITING_FOR_INPUT
237
- )
238
- if stack_frames:
239
- return stack_frames[0]
240
- return None
241
-
242
- def find_agent_stack_frame_by_agent(
243
- self, agent_id: str
244
- ) -> Optional[AgentStackFrame]:
245
- """Get the agent stack frame for a specific agent ID.
246
-
247
- May also include the agent stack frame in the INTERRUPTED state.
248
- """
249
- stack_frames = self._find_agent_frame_by_predicate(
250
- lambda frame: frame.agent_id == agent_id
251
- )
252
- if stack_frames:
253
- return stack_frames[0]
254
- return None
255
-
256
- def find_active_agent_stack_frame_for_flow(
257
- self, flow_id: str
258
- ) -> Optional[AgentStackFrame]:
259
- """Get the agent stack frame of a specific flow."""
260
- stack_frames = self._find_agent_frame_by_predicate(
261
- lambda frame: frame.flow_id == flow_id
262
- )
263
- for stack_frame in stack_frames:
264
- if stack_frame.state == AgentState.WAITING_FOR_INPUT:
265
- return stack_frame
266
- return None
267
-
268
- def get_active_agent_id(self) -> Optional[typing.Text]:
269
- agent_frame = self.find_active_agent_frame()
270
- if agent_frame:
271
- return agent_frame.agent_id
272
- return None
273
-
274
- def agent_is_active(self) -> bool:
275
- return self.find_active_agent_frame() is not None
276
-
277
- def get_all_user_flow_frames(
278
- self, ignore_call_and_link_frames: bool = True
279
- ) -> List[UserFlowStackFrame]:
280
- """Get all user flow frames from the dialogue stack.
281
-
282
- Args:
283
- ignore_call_and_link_frames: Whether to ignore user frames of type `call`
284
- and `link`. By default, these frames are ignored.
285
-
286
- Returns:
287
- A list of all user flow frames in the dialogue stack.
288
- """
289
- return [
290
- frame
291
- for frame in self.frames
292
- if isinstance(frame, UserFlowStackFrame)
293
- and (
294
- not ignore_call_and_link_frames
295
- or (
296
- frame.frame_type != FlowStackFrameType.CALL
297
- and frame.frame_type != FlowStackFrameType.LINK
298
- )
299
- )
300
- ]
@@ -94,18 +94,6 @@ class InvalidFlowStepIdException(Exception):
94
94
  super().__init__(f"Invalid flow step ID '{step_id}' for flow '{flow_id}'.")
95
95
 
96
96
 
97
- class InvalidAgentState(RasaException):
98
- """Raised if the agent state is invalid."""
99
-
100
- def __init__(self, invalid_state: str) -> None:
101
- """Creates a `InvalidAgentState`.
102
-
103
- Args:
104
- invalid_state: The invalid agent state.
105
- """
106
- super().__init__(f"Invalid agent state '{invalid_state}'.")
107
-
108
-
109
97
  @dataclass
110
98
  class BaseFlowStackFrame(DialogueStackFrame):
111
99
  flow_id: str = "" # needed to avoid "default arg before non-default" error
@@ -183,48 +171,3 @@ class UserFlowStackFrame(BaseFlowStackFrame):
183
171
  step_id=data["step_id"],
184
172
  frame_type=FlowStackFrameType.from_str(data.get("frame_type")),
185
173
  )
186
-
187
-
188
- class AgentState(str, Enum):
189
- INTERRUPTED = "interrupted"
190
- WAITING_FOR_INPUT = "waiting_for_input"
191
-
192
- @staticmethod
193
- def from_str(state: Optional[str]) -> AgentState:
194
- if state == AgentState.WAITING_FOR_INPUT.value:
195
- return AgentState.WAITING_FOR_INPUT
196
- elif state == AgentState.INTERRUPTED.value:
197
- return AgentState.INTERRUPTED
198
- else:
199
- raise InvalidAgentState(state)
200
-
201
-
202
- @dataclass
203
- class AgentStackFrame(BaseFlowStackFrame):
204
- agent_id: str = ""
205
- state: AgentState = AgentState.WAITING_FOR_INPUT
206
- metadata: Optional[Dict[str, Any]] = None
207
-
208
- @classmethod
209
- def type(cls) -> str:
210
- """Returns the type of the frame."""
211
- return "agent"
212
-
213
- @staticmethod
214
- def from_dict(data: Dict[str, Any]) -> AgentStackFrame:
215
- """Creates a `AgentStackFrame` from a dictionary.
216
-
217
- Args:
218
- data: The dictionary to create the `AgentStackFrame` from.
219
-
220
- Returns:
221
- The created `AgentStackFrame`.
222
- """
223
- return AgentStackFrame(
224
- frame_id=data["frame_id"],
225
- flow_id=data["flow_id"],
226
- step_id=data["step_id"],
227
- agent_id=data["agent_id"],
228
- state=AgentState.from_str(data["state"]),
229
- metadata=data.get("metadata"),
230
- )
@@ -198,9 +198,8 @@ def end_top_user_flow(stack: DialogueStack) -> DialogueStack:
198
198
  def get_collect_steps_excluding_ask_before_filling_for_active_flow(
199
199
  dialogue_stack: DialogueStack, all_flows: FlowsList
200
200
  ) -> Set[str]:
201
- """Get all collect steps that are part of the current flow.
202
-
203
- Collect steps that have to be asked before filling are not considered.
201
+ """Get all collect steps that are part of the current flow, without
202
+ considering the collect steps that has to be asked before filling.
204
203
 
205
204
  Args:
206
205
  dialogue_stack: The dialogue stack.