rasa-pro 3.10.16__py3-none-any.whl → 3.11.0a1__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 (185) hide show
  1. README.md +396 -17
  2. rasa/api.py +9 -3
  3. rasa/cli/arguments/default_arguments.py +23 -2
  4. rasa/cli/arguments/run.py +15 -0
  5. rasa/cli/arguments/train.py +3 -9
  6. rasa/cli/e2e_test.py +1 -1
  7. rasa/cli/evaluate.py +1 -1
  8. rasa/cli/inspect.py +8 -4
  9. rasa/cli/llm_fine_tuning.py +12 -15
  10. rasa/cli/run.py +8 -1
  11. rasa/cli/studio/studio.py +8 -18
  12. rasa/cli/train.py +11 -53
  13. rasa/cli/utils.py +8 -10
  14. rasa/cli/x.py +1 -1
  15. rasa/constants.py +1 -1
  16. rasa/core/actions/action.py +2 -0
  17. rasa/core/actions/action_hangup.py +29 -0
  18. rasa/core/agent.py +2 -2
  19. rasa/core/brokers/kafka.py +3 -1
  20. rasa/core/brokers/pika.py +3 -1
  21. rasa/core/channels/__init__.py +8 -6
  22. rasa/core/channels/channel.py +21 -4
  23. rasa/core/channels/development_inspector.py +143 -46
  24. rasa/core/channels/inspector/README.md +1 -1
  25. rasa/core/channels/inspector/dist/assets/{arc-b6e548fe.js → arc-86942a71.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-fa03ac9e.js → c4Diagram-d0fbc5ce-b0290676.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-ee67392a.js → classDiagram-936ed81e-f6405f6e.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-9b283fae.js → classDiagram-v2-c3cb15f1-ef61ac77.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-8b6fcc2a.js → createText-62fc7601-f0411e58.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-22e77f4f.js → edges-f2ad444c-7dcc4f3b.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-60ffc87f.js → erDiagram-9d236eb7-e0c092d7.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-9dd802e4.js → flowDb-1972c806-fba2e3ce.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-5fa1912f.js → flowDiagram-7ea5b25a-7a70b71a.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-24a5f41a.js +1 -0
  35. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-622a1fd2.js → flowchart-elk-definition-abe16c3d-00a59b68.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-e285a63a.js → ganttDiagram-9b5ea136-293c91fa.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-f237bdca.js → gitGraphDiagram-99d0ae7c-07b2d68c.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-4b03d70e.js → index-2c4b9a3b-bc959fbd.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/index-3a8a5a28.js +1317 -0
  40. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-72a0fa5f.js → infoDiagram-736b4530-4a350f72.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-82218c41.js → journeyDiagram-df861f2b-af464fb7.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{layout-78cff630.js → layout-0071f036.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{line-5038b469.js → line-2f73cc83.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{linear-c4fc4098.js → linear-f014b4cc.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-c33c8ea6.js → mindmap-definition-beec6740-d2426fb6.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-a8d03059.js → pieDiagram-dbbf0591-776f01a2.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-6a0e56b2.js → quadrantDiagram-4d7f4fd6-82e00b57.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-2dc7c7bd.js → requirementDiagram-6fc4c22a-ea13c6bb.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-2360fe39.js → sankeyDiagram-8f13d901-1feca7e9.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-41b9f9ad.js → sequenceDiagram-b655622a-070c61d2.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-0aad326f.js → stateDiagram-59f0c015-24f46263.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-9847d984.js → stateDiagram-v2-2b26beab-c9056051.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-564d890e.js → styles-080da4f6-08abc34a.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-38957613.js → styles-3dcbcfbf-bc74c25a.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-f0fc6921.js → styles-9c745c82-4e5d66de.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-ef3c5a77.js → svgDrawCommon-4835440b-849c4517.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-bf3e91c1.js → timeline-definition-5b62e21b-d0fb1598.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-4d4026c0.js → xychartDiagram-2b33534f-04d115e2.js} +1 -1
  59. rasa/core/channels/inspector/dist/index.html +18 -17
  60. rasa/core/channels/inspector/index.html +17 -16
  61. rasa/core/channels/inspector/package.json +5 -1
  62. rasa/core/channels/inspector/src/App.tsx +117 -67
  63. rasa/core/channels/inspector/src/components/Chat.tsx +95 -0
  64. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +11 -10
  65. rasa/core/channels/inspector/src/components/DialogueStack.tsx +10 -25
  66. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +1 -1
  67. rasa/core/channels/inspector/src/helpers/formatters.test.ts +10 -0
  68. rasa/core/channels/inspector/src/helpers/formatters.ts +107 -41
  69. rasa/core/channels/inspector/src/helpers/utils.ts +92 -7
  70. rasa/core/channels/inspector/src/types.ts +21 -1
  71. rasa/core/channels/inspector/yarn.lock +94 -1
  72. rasa/core/channels/rest.py +51 -46
  73. rasa/core/channels/socketio.py +22 -0
  74. rasa/core/channels/{audiocodes.py → voice_ready/audiocodes.py} +110 -68
  75. rasa/core/channels/{voice_aware → voice_ready}/jambonz.py +11 -4
  76. rasa/core/channels/{voice_aware → voice_ready}/jambonz_protocol.py +57 -5
  77. rasa/core/channels/{twilio_voice.py → voice_ready/twilio_voice.py} +58 -7
  78. rasa/core/channels/{voice_aware → voice_ready}/utils.py +16 -0
  79. rasa/core/channels/voice_stream/asr/__init__.py +0 -0
  80. rasa/core/channels/voice_stream/asr/asr_engine.py +71 -0
  81. rasa/core/channels/voice_stream/asr/asr_event.py +13 -0
  82. rasa/core/channels/voice_stream/asr/deepgram.py +77 -0
  83. rasa/core/channels/voice_stream/audio_bytes.py +7 -0
  84. rasa/core/channels/voice_stream/tts/__init__.py +0 -0
  85. rasa/core/channels/voice_stream/tts/azure.py +100 -0
  86. rasa/core/channels/voice_stream/tts/cartesia.py +114 -0
  87. rasa/core/channels/voice_stream/tts/tts_cache.py +27 -0
  88. rasa/core/channels/voice_stream/tts/tts_engine.py +48 -0
  89. rasa/core/channels/voice_stream/twilio_media_streams.py +164 -0
  90. rasa/core/channels/voice_stream/util.py +57 -0
  91. rasa/core/channels/voice_stream/voice_channel.py +247 -0
  92. rasa/core/featurizers/single_state_featurizer.py +1 -22
  93. rasa/core/featurizers/tracker_featurizers.py +18 -115
  94. rasa/core/nlg/contextual_response_rephraser.py +11 -2
  95. rasa/{nlu → core}/persistor.py +16 -38
  96. rasa/core/policies/enterprise_search_policy.py +12 -15
  97. rasa/core/policies/flows/flow_executor.py +8 -18
  98. rasa/core/policies/intentless_policy.py +10 -15
  99. rasa/core/policies/ted_policy.py +33 -58
  100. rasa/core/policies/unexpected_intent_policy.py +7 -15
  101. rasa/core/processor.py +13 -64
  102. rasa/core/run.py +11 -1
  103. rasa/core/secrets_manager/constants.py +4 -0
  104. rasa/core/secrets_manager/factory.py +8 -0
  105. rasa/core/secrets_manager/vault.py +11 -1
  106. rasa/core/training/interactive.py +1 -1
  107. rasa/core/utils.py +1 -11
  108. rasa/dialogue_understanding/coexistence/llm_based_router.py +10 -10
  109. rasa/dialogue_understanding/commands/__init__.py +2 -0
  110. rasa/dialogue_understanding/commands/change_flow_command.py +0 -6
  111. rasa/dialogue_understanding/commands/session_end_command.py +61 -0
  112. rasa/dialogue_understanding/generator/flow_retrieval.py +0 -7
  113. rasa/dialogue_understanding/generator/llm_based_command_generator.py +12 -3
  114. rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
  115. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -28
  116. rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -19
  117. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +4 -37
  118. rasa/e2e_test/aggregate_test_stats_calculator.py +1 -11
  119. rasa/e2e_test/assertions.py +6 -48
  120. rasa/e2e_test/e2e_test_runner.py +6 -9
  121. rasa/e2e_test/utils/e2e_yaml_utils.py +1 -1
  122. rasa/e2e_test/utils/io.py +1 -3
  123. rasa/engine/graph.py +3 -10
  124. rasa/engine/recipes/config_files/default_config.yml +0 -3
  125. rasa/engine/recipes/default_recipe.py +0 -1
  126. rasa/engine/recipes/graph_recipe.py +0 -1
  127. rasa/engine/runner/dask.py +2 -2
  128. rasa/engine/storage/local_model_storage.py +12 -42
  129. rasa/engine/storage/storage.py +1 -5
  130. rasa/engine/validation.py +1 -78
  131. rasa/keys +1 -0
  132. rasa/model_training.py +13 -16
  133. rasa/nlu/classifiers/diet_classifier.py +25 -38
  134. rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
  135. rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
  136. rasa/nlu/extractors/crf_entity_extractor.py +50 -93
  137. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +16 -45
  138. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +17 -52
  139. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
  140. rasa/server.py +1 -1
  141. rasa/shared/constants.py +3 -12
  142. rasa/shared/core/constants.py +4 -0
  143. rasa/shared/core/domain.py +101 -47
  144. rasa/shared/core/events.py +29 -0
  145. rasa/shared/core/flows/flows_list.py +20 -11
  146. rasa/shared/core/flows/validation.py +25 -0
  147. rasa/shared/core/flows/yaml_flows_io.py +3 -24
  148. rasa/shared/importers/importer.py +40 -39
  149. rasa/shared/importers/multi_project.py +23 -11
  150. rasa/shared/importers/rasa.py +7 -2
  151. rasa/shared/importers/remote_importer.py +196 -0
  152. rasa/shared/importers/utils.py +3 -1
  153. rasa/shared/nlu/training_data/features.py +2 -120
  154. rasa/shared/nlu/training_data/training_data.py +18 -19
  155. rasa/shared/providers/_configs/azure_openai_client_config.py +3 -5
  156. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -6
  157. rasa/shared/providers/llm/_base_litellm_client.py +11 -31
  158. rasa/shared/providers/llm/self_hosted_llm_client.py +3 -15
  159. rasa/shared/utils/common.py +3 -22
  160. rasa/shared/utils/io.py +0 -1
  161. rasa/shared/utils/llm.py +30 -27
  162. rasa/shared/utils/schemas/events.py +2 -0
  163. rasa/shared/utils/schemas/model_config.yml +0 -10
  164. rasa/shared/utils/yaml.py +44 -0
  165. rasa/studio/auth.py +5 -3
  166. rasa/studio/config.py +4 -13
  167. rasa/studio/constants.py +0 -1
  168. rasa/studio/data_handler.py +3 -10
  169. rasa/studio/upload.py +8 -17
  170. rasa/tracing/instrumentation/attribute_extractors.py +1 -1
  171. rasa/utils/io.py +66 -0
  172. rasa/utils/tensorflow/model_data.py +193 -2
  173. rasa/validator.py +0 -12
  174. rasa/version.py +1 -1
  175. rasa_pro-3.11.0a1.dist-info/METADATA +576 -0
  176. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/RECORD +181 -164
  177. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +0 -1
  178. rasa/core/channels/inspector/dist/assets/index-a5d3e69d.js +0 -1040
  179. rasa/utils/tensorflow/feature_array.py +0 -366
  180. rasa_pro-3.10.16.dist-info/METADATA +0 -196
  181. /rasa/core/channels/{voice_aware → voice_ready}/__init__.py +0 -0
  182. /rasa/core/channels/{voice_native → voice_stream}/__init__.py +0 -0
  183. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/NOTICE +0 -0
  184. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/WHEEL +0 -0
  185. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/entry_points.txt +0 -0
@@ -36,9 +36,3 @@ class ChangeFlowCommand(Command):
36
36
  # the change flow command is not actually pushing anything to the tracker,
37
37
  # but it is predicted by the MultiStepLLMCommandGenerator and used internally
38
38
  return []
39
-
40
- def __eq__(self, other: Any) -> bool:
41
- return isinstance(other, ChangeFlowCommand)
42
-
43
- def __hash__(self) -> int:
44
- return hash(self.command())
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, Dict, List
5
+ from rasa.dialogue_understanding.commands import Command
6
+ from rasa.shared.core.events import Event, SessionEnded
7
+ from rasa.shared.core.flows import FlowsList
8
+ from rasa.shared.core.trackers import DialogueStateTracker
9
+
10
+
11
+ @dataclass
12
+ class SessionEndCommand(Command):
13
+ """A command to indicate the end of a session."""
14
+
15
+ @classmethod
16
+ def command(cls) -> str:
17
+ """Returns the command type."""
18
+ return "session end"
19
+
20
+ @classmethod
21
+ def from_dict(cls, data: Dict[str, Any]) -> SessionEndCommand:
22
+ """Converts the dictionary to a command.
23
+
24
+ Returns:
25
+ The converted dictionary.
26
+ """
27
+ return SessionEndCommand()
28
+
29
+ def run_command_on_tracker(
30
+ self,
31
+ tracker: DialogueStateTracker,
32
+ all_flows: FlowsList,
33
+ original_tracker: DialogueStateTracker,
34
+ ) -> List[Event]:
35
+ """Runs the command on the tracker.
36
+
37
+ Args:
38
+ tracker: The tracker to run the command on.
39
+ all_flows: All flows in the assistant.
40
+ original_tracker: The tracker before any command was executed.
41
+
42
+ Returns:
43
+ The events to apply to the tracker.
44
+ """
45
+ metadata = {"_reason": "user disconnected"}
46
+
47
+ # Add metadata sent by the channel connector, if available
48
+ if tracker.latest_message:
49
+ user_metadata = tracker.latest_message.metadata or {}
50
+ metadata.update(user_metadata)
51
+
52
+ return [SessionEnded(metadata=metadata)]
53
+
54
+ def __hash__(self) -> int:
55
+ return hash(self.command())
56
+
57
+ def __eq__(self, other: object) -> bool:
58
+ if not isinstance(other, SessionEndCommand):
59
+ return False
60
+
61
+ return True
@@ -50,7 +50,6 @@ from rasa.shared.utils.llm import (
50
50
  USER,
51
51
  get_prompt_template,
52
52
  allowed_values_for_slot,
53
- try_instantiate_embedder,
54
53
  )
55
54
 
56
55
  DEFAULT_FLOW_DOCUMENT_TEMPLATE = importlib.resources.read_text(
@@ -143,12 +142,6 @@ class FlowRetrieval:
143
142
  """Load flow retrieval with previously populated FAISS vector store."""
144
143
  # initialize base flow retrieval
145
144
  flow_retrieval = FlowRetrieval(config, model_storage, resource)
146
- try_instantiate_embedder(
147
- flow_retrieval.config.get(EMBEDDINGS_CONFIG_KEY),
148
- DEFAULT_EMBEDDINGS_CONFIG,
149
- "flow_retrieval.load",
150
- FlowRetrieval.__name__,
151
- )
152
145
  # load vector store
153
146
  vector_store = cls._load_vector_store(
154
147
  flow_retrieval.config, model_storage, resource
@@ -2,6 +2,7 @@ from abc import ABC, abstractmethod
2
2
  from functools import lru_cache
3
3
  from typing import Dict, Any, List, Optional, Tuple, Union, Text
4
4
 
5
+ import os
5
6
  import structlog
6
7
  from jinja2 import Template
7
8
 
@@ -22,6 +23,7 @@ from rasa.engine.graph import GraphComponent, ExecutionContext
22
23
  from rasa.engine.recipes.default_recipe import DefaultV1Recipe
23
24
  from rasa.engine.storage.resource import Resource
24
25
  from rasa.engine.storage.storage import ModelStorage
26
+ from rasa.shared.constants import LLM_API_HEALTH_CHECK_ENV_VAR
25
27
  from rasa.shared.core.domain import Domain
26
28
  from rasa.shared.core.flows import FlowStep, Flow, FlowsList
27
29
  from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
@@ -33,6 +35,7 @@ from rasa.shared.nlu.training_data.message import Message
33
35
  from rasa.shared.nlu.training_data.training_data import TrainingData
34
36
  from rasa.shared.utils.llm import (
35
37
  allowed_values_for_slot,
38
+ llm_api_health_check,
36
39
  llm_factory,
37
40
  try_instantiate_llm_client,
38
41
  )
@@ -169,12 +172,18 @@ class LLMBasedCommandGenerator(GraphComponent, CommandGenerator, ABC):
169
172
  store.
170
173
  """
171
174
  # Validate llm configuration
172
- try_instantiate_llm_client(
175
+ llm_client = try_instantiate_llm_client(
173
176
  self.config.get(LLM_CONFIG_KEY),
174
177
  DEFAULT_LLM_CONFIG,
175
178
  "llm_based_command_generator.train",
176
- "LLMBasedCommandGenerator",
179
+ LLMBasedCommandGenerator.__name__,
177
180
  )
181
+ if os.getenv(LLM_API_HEALTH_CHECK_ENV_VAR, "true").lower() == "true":
182
+ llm_api_health_check(
183
+ llm_client,
184
+ "llm_based_command_generator.train",
185
+ LLMBasedCommandGenerator.__name__,
186
+ )
178
187
 
179
188
  # flow retrieval is populated with only user-defined flows
180
189
  try:
@@ -183,7 +192,7 @@ class LLMBasedCommandGenerator(GraphComponent, CommandGenerator, ABC):
183
192
  except Exception as e:
184
193
  structlogger.error(
185
194
  "llm_based_command_generator.train.failed",
186
- event_info="Flow retrieval store is inaccessible.",
195
+ event_info=("Flow retrieval store isinaccessible."),
187
196
  error=e,
188
197
  )
189
198
  raise
@@ -1,4 +1,4 @@
1
- from typing import Dict, Any, Optional, Text
1
+ from typing import Any, Dict, Optional, Text
2
2
 
3
3
  import structlog
4
4
  from deprecated import deprecated # type: ignore[import]
@@ -24,7 +24,6 @@ from rasa.dialogue_understanding.generator.constants import (
24
24
  LLM_CONFIG_KEY,
25
25
  USER_INPUT_CONFIG_KEY,
26
26
  FLOW_RETRIEVAL_KEY,
27
- DEFAULT_LLM_CONFIG,
28
27
  )
29
28
  from rasa.dialogue_understanding.generator.flow_retrieval import FlowRetrieval
30
29
  from rasa.dialogue_understanding.generator.llm_based_command_generator import (
@@ -54,7 +53,6 @@ from rasa.shared.utils.llm import (
54
53
  tracker_as_readable_transcript,
55
54
  sanitize_message_for_prompt,
56
55
  allowed_values_for_slot,
57
- try_instantiate_llm_client,
58
56
  )
59
57
 
60
58
  # multistep template keys
@@ -143,12 +141,6 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
143
141
  prompts = cls._load_prompt_templates(model_storage, resource)
144
142
  # init base command generator
145
143
  command_generator = cls(config, model_storage, resource, prompts)
146
- try_instantiate_llm_client(
147
- command_generator.config.get(LLM_CONFIG_KEY),
148
- DEFAULT_LLM_CONFIG,
149
- "multi_step_llm_command_generator.load",
150
- MultiStepLLMCommandGenerator.__name__,
151
- )
152
144
  # load flow retrieval if enabled
153
145
  if command_generator.enabled_flow_retrieval:
154
146
  command_generator.flow_retrieval = cls.load_flow_retrival(
@@ -237,9 +229,9 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
237
229
  commands: List[Command] = []
238
230
 
239
231
  slot_set_re = re.compile(
240
- r"""SetSlot\(['"]?([a-zA-Z_][a-zA-Z0-9_-]*)['"]?, ?['"]?(.*)['"]?\)"""
232
+ r"""SetSlot\((\"?[a-zA-Z_][a-zA-Z0-9_-]*?\"?), ?(.*)\)"""
241
233
  )
242
- start_flow_re = re.compile(r"StartFlow\(['\"]?([a-zA-Z0-9_-]+)['\"]?\)")
234
+ start_flow_re = re.compile(r"StartFlow\(([a-zA-Z0-9_-]+?)\)")
243
235
  change_flow_re = re.compile(r"ChangeFlow\(\)")
244
236
  cancel_flow_re = re.compile(r"CancelFlow\(\)")
245
237
  chitchat_re = re.compile(r"ChitChat\(\)")
@@ -288,19 +280,9 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
288
280
  commands.append(HumanHandoffCommand())
289
281
  elif match := clarify_re.search(action):
290
282
  options = sorted([opt.strip() for opt in match.group(1).split(",")])
291
- # Remove surrounding quotes if present
292
- cleaned_options = []
293
- for flow in options:
294
- if (flow.startswith('"') and flow.endswith('"')) or (
295
- flow.startswith("'") and flow.endswith("'")
296
- ):
297
- cleaned_options.append(flow[1:-1])
298
- else:
299
- cleaned_options.append(flow)
300
- # check if flow is valid
301
283
  valid_options = [
302
284
  flow
303
- for flow in cleaned_options
285
+ for flow in options
304
286
  if flow in flows.user_flow_ids
305
287
  and flow not in user_flows_on_the_stack(tracker.stack)
306
288
  ]
@@ -311,13 +293,6 @@ class MultiStepLLMCommandGenerator(LLMBasedCommandGenerator):
311
293
  elif change_flow_re.search(action):
312
294
  commands.append(ChangeFlowCommand())
313
295
 
314
- if not commands:
315
- structlogger.debug(
316
- "multi_step_llm_command_generator.parse_commands",
317
- message="No commands were parsed from the LLM actions.",
318
- actions=actions,
319
- )
320
-
321
296
  return commands
322
297
 
323
298
  ### Helper methods
@@ -19,7 +19,6 @@ from rasa.engine.storage.storage import ModelStorage
19
19
  from rasa.shared.constants import ROUTE_TO_CALM_SLOT
20
20
  from rasa.shared.core.domain import Domain
21
21
  from rasa.shared.core.flows.flows_list import FlowsList
22
- from rasa.shared.core.flows.steps import CollectInformationFlowStep
23
22
  from rasa.shared.core.slot_mappings import (
24
23
  SlotFillingManager,
25
24
  extract_slot_value,
@@ -218,24 +217,7 @@ def _issue_set_slot_commands(
218
217
  commands: List[Command] = []
219
218
  domain = domain if domain else Domain.empty()
220
219
  slot_filling_manager = SlotFillingManager(domain, tracker, message)
221
-
222
- # only use slots that don't have ask_before_filling set to True
223
- available_slot_names = flows.available_slot_names(ask_before_filling=False)
224
-
225
- # check if the current step is a CollectInformationFlowStep
226
- # in case it has ask_before_filling set to True, we need to add the
227
- # slot to the available_slot_names
228
- if tracker.active_flow:
229
- flow = flows.flow_by_id(tracker.active_flow)
230
- step_id = tracker.current_step_id
231
- if flow is not None:
232
- current_step = flow.step_by_id(step_id)
233
- if (
234
- current_step
235
- and isinstance(current_step, CollectInformationFlowStep)
236
- and current_step.ask_before_filling
237
- ):
238
- available_slot_names.add(current_step.collect)
220
+ available_slot_names = flows.available_slot_names()
239
221
 
240
222
  for _, slot in tracker.slots.items():
241
223
  # if a slot is not collected in available flows,
@@ -21,7 +21,6 @@ from rasa.dialogue_understanding.generator.constants import (
21
21
  LLM_CONFIG_KEY,
22
22
  USER_INPUT_CONFIG_KEY,
23
23
  FLOW_RETRIEVAL_KEY,
24
- DEFAULT_LLM_CONFIG,
25
24
  )
26
25
  from rasa.dialogue_understanding.generator.flow_retrieval import (
27
26
  FlowRetrieval,
@@ -49,7 +48,6 @@ from rasa.shared.utils.llm import (
49
48
  get_prompt_template,
50
49
  tracker_as_readable_transcript,
51
50
  sanitize_message_for_prompt,
52
- try_instantiate_llm_client,
53
51
  )
54
52
  from rasa.utils.log_utils import log_llm
55
53
 
@@ -138,12 +136,6 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
138
136
  )
139
137
  # init base command generator
140
138
  command_generator = cls(config, model_storage, resource, prompt_template)
141
- try_instantiate_llm_client(
142
- command_generator.config.get(LLM_CONFIG_KEY),
143
- DEFAULT_LLM_CONFIG,
144
- "single_step_llm_command_generator.load",
145
- SingleStepLLMCommandGenerator.__name__,
146
- )
147
139
  # load flow retrieval if enabled
148
140
  if command_generator.enabled_flow_retrieval:
149
141
  command_generator.flow_retrieval = cls.load_flow_retrival(
@@ -193,12 +185,6 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
193
185
 
194
186
  if not commands:
195
187
  # no commands are parsed or there's an invalid command
196
- structlogger.warning(
197
- "single_step_llm_command_generator.predict_commands",
198
- message="No commands were predicted as the LLM response could "
199
- "not be parsed or the LLM responded with an invalid command."
200
- "Returning a CannotHandleCommand instead.",
201
- )
202
188
  commands = [CannotHandleCommand()]
203
189
 
204
190
  if tracker.has_coexistence_routing_slot:
@@ -299,16 +285,14 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
299
285
 
300
286
  commands: List[Command] = []
301
287
 
302
- slot_set_re = re.compile(
303
- r"""SetSlot\(['"]?([a-zA-Z_][a-zA-Z0-9_-]*)['"]?, ?['"]?(.*)['"]?\)"""
304
- )
305
- start_flow_re = re.compile(r"StartFlow\(['\"]?([a-zA-Z0-9_-]+)['\"]?\)")
288
+ slot_set_re = re.compile(r"""SetSlot\(([a-zA-Z_][a-zA-Z0-9_-]*?), ?(.*)\)""")
289
+ start_flow_re = re.compile(r"StartFlow\(([a-zA-Z0-9_-]+?)\)")
306
290
  cancel_flow_re = re.compile(r"CancelFlow\(\)")
307
291
  chitchat_re = re.compile(r"ChitChat\(\)")
308
292
  skip_question_re = re.compile(r"SkipQuestion\(\)")
309
293
  knowledge_re = re.compile(r"SearchAndReply\(\)")
310
294
  humand_handoff_re = re.compile(r"HumanHandoff\(\)")
311
- clarify_re = re.compile(r"Clarify\(([\"\'a-zA-Z0-9_, ]+)\)")
295
+ clarify_re = re.compile(r"Clarify\(([a-zA-Z0-9_, ]+)\)")
312
296
 
313
297
  for action in actions.strip().splitlines():
314
298
  if match := slot_set_re.search(action):
@@ -337,31 +321,14 @@ class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
337
321
  commands.append(HumanHandoffCommand())
338
322
  elif match := clarify_re.search(action):
339
323
  options = sorted([opt.strip() for opt in match.group(1).split(",")])
340
- # Remove surrounding quotes if present
341
- cleaned_options = []
342
- for flow in options:
343
- if (flow.startswith('"') and flow.endswith('"')) or (
344
- flow.startswith("'") and flow.endswith("'")
345
- ):
346
- cleaned_options.append(flow[1:-1])
347
- else:
348
- cleaned_options.append(flow)
349
- # check if flow is valid
350
324
  valid_options = [
351
- flow for flow in cleaned_options if flow in flows.user_flow_ids
325
+ flow for flow in options if flow in flows.user_flow_ids
352
326
  ]
353
327
  if len(set(valid_options)) == 1:
354
328
  commands.extend(cls.start_flow_by_name(valid_options[0], flows))
355
329
  elif len(valid_options) > 1:
356
330
  commands.append(ClarifyCommand(valid_options))
357
331
 
358
- if not commands:
359
- structlogger.debug(
360
- "single_step_llm_command_generator.parse_commands",
361
- message="No commands were parsed from the LLM actions.",
362
- actions=actions,
363
- )
364
-
365
332
  return commands
366
333
 
367
334
  @classmethod
@@ -35,7 +35,6 @@ class AggregateTestStatsCalculator:
35
35
  self.test_cases = test_cases
36
36
 
37
37
  self.failed_assertion_set: Set["Assertion"] = set()
38
- self.failed_test_cases_without_assertion_failure: Set[str] = set()
39
38
  self.passed_count_mapping = {
40
39
  subclass_type: 0
41
40
  for subclass_type in _get_all_assertion_subclasses().keys()
@@ -90,14 +89,8 @@ class AggregateTestStatsCalculator:
90
89
  passed_test_case_names = [
91
90
  passed.test_case.name for passed in self.passed_results
92
91
  ]
93
- # We filter out test cases that failed without an assertion failure
94
- filtered_test_cases = [
95
- test_case
96
- for test_case in self.test_cases
97
- if test_case.name not in self.failed_test_cases_without_assertion_failure
98
- ]
99
92
 
100
- for test_case in filtered_test_cases:
93
+ for test_case in self.test_cases:
101
94
  if test_case.name in passed_test_case_names:
102
95
  for step in test_case.steps:
103
96
  if step.assertions is None:
@@ -125,9 +118,6 @@ class AggregateTestStatsCalculator:
125
118
  "no_assertion_failure_in_failed_result",
126
119
  test_case=failed.test_case.name,
127
120
  )
128
- self.failed_test_cases_without_assertion_failure.add(
129
- failed.test_case.name
130
- )
131
121
  continue
132
122
 
133
123
  self.failed_assertion_set.add(failed.assertion_failure.assertion)
@@ -452,11 +452,6 @@ class ActionExecutedAssertion(Assertion):
452
452
  **kwargs: Any,
453
453
  ) -> Tuple[Optional[AssertionFailure], Optional[Event]]:
454
454
  """Run the action executed assertion on the given events for that user turn."""
455
- step_index = kwargs.get("step_index")
456
- original_turn_events, turn_events = _get_turn_events_based_on_step_index(
457
- step_index, turn_events, prior_events
458
- )
459
-
460
455
  try:
461
456
  matching_event = next(
462
457
  event
@@ -469,7 +464,7 @@ class ActionExecutedAssertion(Assertion):
469
464
  error_message += assertion_order_error_message
470
465
 
471
466
  return self._generate_assertion_failure(
472
- error_message, prior_events, original_turn_events, self.line
467
+ error_message, prior_events, turn_events, self.line
473
468
  )
474
469
 
475
470
  return None, matching_event
@@ -524,11 +519,6 @@ class SlotWasSetAssertion(Assertion):
524
519
  """Run the slot_was_set assertion on the given events for that user turn."""
525
520
  matching_event = None
526
521
 
527
- step_index = kwargs.get("step_index")
528
- original_turn_events, turn_events = _get_turn_events_based_on_step_index(
529
- step_index, turn_events, prior_events
530
- )
531
-
532
522
  for slot in self.slots:
533
523
  matching_events = [
534
524
  event
@@ -567,7 +557,7 @@ class SlotWasSetAssertion(Assertion):
567
557
  error_message += assertion_order_error_message
568
558
 
569
559
  return self._generate_assertion_failure(
570
- error_message, prior_events, original_turn_events, slot.line
560
+ error_message, prior_events, turn_events, slot.line
571
561
  )
572
562
 
573
563
  return None, matching_event
@@ -605,11 +595,6 @@ class SlotWasNotSetAssertion(Assertion):
605
595
  """Run the slot_was_not_set assertion on the given events for that user turn."""
606
596
  matching_event = None
607
597
 
608
- step_index = kwargs.get("step_index")
609
- original_turn_events, turn_events = _get_turn_events_based_on_step_index(
610
- step_index, turn_events, prior_events
611
- )
612
-
613
598
  for slot in self.slots:
614
599
  matching_events = [
615
600
  event
@@ -645,7 +630,7 @@ class SlotWasNotSetAssertion(Assertion):
645
630
  error_message += assertion_order_error_message
646
631
 
647
632
  return self._generate_assertion_failure(
648
- error_message, prior_events, original_turn_events, slot.line
633
+ error_message, prior_events, turn_events, slot.line
649
634
  )
650
635
 
651
636
  return None, matching_event
@@ -738,11 +723,6 @@ class BotUtteredAssertion(Assertion):
738
723
  """Run the bot_uttered assertion on the given events for that user turn."""
739
724
  matching_event = None
740
725
 
741
- step_index = kwargs.get("step_index")
742
- original_turn_events, turn_events = _get_turn_events_based_on_step_index(
743
- step_index, turn_events, prior_events
744
- )
745
-
746
726
  if self.utter_name is not None:
747
727
  try:
748
728
  matching_event = next(
@@ -756,7 +736,7 @@ class BotUtteredAssertion(Assertion):
756
736
  error_message += assertion_order_error_message
757
737
 
758
738
  return self._generate_assertion_failure(
759
- error_message, prior_events, original_turn_events, self.line
739
+ error_message, prior_events, turn_events, self.line
760
740
  )
761
741
 
762
742
  if self.text_matches is not None:
@@ -776,7 +756,7 @@ class BotUtteredAssertion(Assertion):
776
756
  error_message += assertion_order_error_message
777
757
 
778
758
  return self._generate_assertion_failure(
779
- error_message, prior_events, original_turn_events, self.line
759
+ error_message, prior_events, turn_events, self.line
780
760
  )
781
761
 
782
762
  if self.buttons:
@@ -792,7 +772,7 @@ class BotUtteredAssertion(Assertion):
792
772
  )
793
773
  error_message += assertion_order_error_message
794
774
  return self._generate_assertion_failure(
795
- error_message, prior_events, original_turn_events, self.line
775
+ error_message, prior_events, turn_events, self.line
796
776
  )
797
777
 
798
778
  return None, matching_event
@@ -1199,25 +1179,3 @@ def _find_matching_generative_events(turn_events: List[Event]) -> List[BotUttere
1199
1179
  and event.metadata.get(UTTER_SOURCE_METADATA_KEY)
1200
1180
  in ELIGIBLE_UTTER_SOURCE_METADATA
1201
1181
  ]
1202
-
1203
-
1204
- def _get_turn_events_based_on_step_index(
1205
- step_index: int, turn_events: List[Event], prior_events: List[Event]
1206
- ) -> Tuple[List[Event], List[Event]]:
1207
- """Get the turn events based on the step index.
1208
-
1209
- For the first step, we need to include the prior events as well
1210
- in the same user turn. For the subsequent steps, we only need the
1211
- events that follow the user uttered event on which the tracker
1212
- was originally sliced by.
1213
-
1214
- Returns:
1215
- List[Event]: The copy of turn_events
1216
- List[Event]: The turn events based on the step index
1217
-
1218
- """
1219
- original_turn_events = turn_events[:]
1220
- if step_index == 0:
1221
- return original_turn_events, prior_events + turn_events
1222
-
1223
- return original_turn_events, turn_events
@@ -16,6 +16,7 @@ import rasa.shared.utils.io
16
16
  from rasa.core.channels import CollectingOutputChannel, UserMessage
17
17
  from rasa.core.constants import ACTIVE_FLOW_METADATA_KEY, STEP_ID_METADATA_KEY
18
18
  from rasa.core.exceptions import AgentNotReady
19
+ from rasa.core.persistor import StorageType
19
20
  from rasa.core.utils import AvailableEndpoints
20
21
  from rasa.e2e_test.constants import TEST_CASE_NAME, TEST_FILE_NAME
21
22
  from rasa.e2e_test.e2e_config import create_llm_judge_config
@@ -34,7 +35,6 @@ from rasa.e2e_test.e2e_test_result import (
34
35
  TestResult,
35
36
  )
36
37
  from rasa.llm_fine_tuning.conversations import Conversation
37
- from rasa.nlu.persistor import StorageType
38
38
  from rasa.shared.constants import RASA_DEFAULT_FLOW_PATTERN_PREFIX
39
39
  from rasa.shared.core.events import (
40
40
  ActionExecuted,
@@ -136,7 +136,7 @@ class E2ETestRunner:
136
136
  return turns
137
137
 
138
138
  tracker = await self.agent.processor.fetch_tracker_with_initial_session(
139
- sender_id, output_channel=collector
139
+ sender_id
140
140
  )
141
141
  # turn -1 i used to contain events that happen during
142
142
  # the start of the session and before the first user message
@@ -190,11 +190,11 @@ class E2ETestRunner:
190
190
  error=f"Message handling timed out for user message '{step.text}'.",
191
191
  exc_info=True,
192
192
  )
193
- except Exception as exc:
193
+ except Exception:
194
194
  structlogger.error(
195
195
  "e2e_test_runner.run_prediction_loop",
196
196
  error=f"An exception occurred while handling "
197
- f"user message '{step.text}'. Error: {exc}",
197
+ f"user message '{step.text}'.",
198
198
  )
199
199
  tracker = await self.agent.tracker_store.retrieve(sender_id) # type: ignore[assignment]
200
200
  turns[position], event_cursor = self.get_actual_step_output(
@@ -442,7 +442,7 @@ class E2ETestRunner:
442
442
  assertion_failure_found = False
443
443
  input_metadata = input_metadata if input_metadata else []
444
444
 
445
- for index, step in enumerate(test_case.steps):
445
+ for step in test_case.steps:
446
446
  if not step.assertions:
447
447
  structlogger.debug(
448
448
  "e2e_test_runner.run_assertions.no_assertions.skipping_step",
@@ -490,7 +490,6 @@ class E2ETestRunner:
490
490
  assertion_order_error_message=assertion_order_error_msg,
491
491
  llm_judge_config=self.llm_judge_config,
492
492
  step_text=step.text,
493
- step_index=index,
494
493
  )
495
494
 
496
495
  if assertion_failure:
@@ -827,7 +826,7 @@ class E2ETestRunner:
827
826
  return
828
827
 
829
828
  tracker = await self.agent.processor.fetch_tracker_with_initial_session(
830
- sender_id, output_channel=CollectingOutputChannel()
829
+ sender_id
831
830
  )
832
831
 
833
832
  for fixture in fixtures:
@@ -1156,8 +1155,6 @@ class E2ETestRunner:
1156
1155
  flow_paths_stack
1157
1156
  and self.agent.domain
1158
1157
  and self.agent.domain.is_custom_action(event.action_name)
1159
- and STEP_ID_METADATA_KEY in event.metadata
1160
- and ACTIVE_FLOW_METADATA_KEY in event.metadata
1161
1158
  ):
1162
1159
  flow_paths_stack[-1].nodes.append(self._create_path_node(event))
1163
1160
 
@@ -45,7 +45,7 @@ class E2ETestYAMLWriter:
45
45
 
46
46
  yaml_data = ruamel.yaml.safe_load(tests)
47
47
 
48
- test_cases_yaml = {KEY_TEST_CASES: yaml_data}
48
+ test_cases_yaml = [{KEY_TEST_CASES: yaml_data}]
49
49
  with open(output_file, "w") as outfile:
50
50
  yaml = ruamel.yaml.YAML()
51
51
  yaml.dump(test_cases_yaml, outfile)
rasa/e2e_test/utils/io.py CHANGED
@@ -346,7 +346,7 @@ def read_test_cases(path: str) -> TestSuite:
346
346
  beta_flag_verified = False
347
347
 
348
348
  for test_file in test_files:
349
- test_file_content = parse_raw_yaml(Path(test_file).read_text(encoding="utf-8"))
349
+ test_file_content = parse_raw_yaml(Path(test_file).read_text())
350
350
 
351
351
  validate_yaml_data_using_schema_with_assertions(
352
352
  yaml_data=test_file_content, schema_content=e2e_test_schema
@@ -506,8 +506,6 @@ def transform_results_output_to_yaml(yaml_string: str) -> str:
506
506
  result.append(s)
507
507
  elif s.startswith("\n"):
508
508
  result.append(s.strip())
509
- elif s.strip().startswith("#"):
510
- continue
511
509
  else:
512
510
  result.append(s)
513
511
  return "".join(result)
rasa/engine/graph.py CHANGED
@@ -67,14 +67,6 @@ class SchemaNode:
67
67
  is_input: bool = False
68
68
  resource: Optional[Resource] = None
69
69
 
70
- def matches_type(self, node_type: Type, include_subtypes: bool = True) -> bool:
71
- """Checks if schema node's 'uses' is of specified node type.
72
- By default, it also checks for subtypes of the specified node type.
73
- """
74
- return (self.uses is node_type) or (
75
- include_subtypes and issubclass(self.uses, node_type)
76
- )
77
-
78
70
 
79
71
  @dataclass
80
72
  class GraphSchema:
@@ -174,7 +166,9 @@ class GraphSchema:
174
166
  By default, it also checks for subtypes of the specified node type.
175
167
  """
176
168
  for node in self.nodes.values():
177
- if node.matches_type(node_type, include_subtypes):
169
+ if (node.uses is node_type) or (
170
+ include_subtypes and issubclass(node.uses, node_type)
171
+ ):
178
172
  return True
179
173
  return False
180
174
 
@@ -640,4 +634,3 @@ class GraphModelConfiguration:
640
634
  language: Optional[Text]
641
635
  core_target: Optional[Text]
642
636
  nlu_target: Optional[Text]
643
- spaces: Optional[Dict[Text, Text]] = None
@@ -35,9 +35,6 @@ pipeline:
35
35
  policies:
36
36
  - name: MemoizationPolicy
37
37
  - name: RulePolicy
38
- - name: UnexpecTEDIntentPolicy
39
- max_history: 5
40
- epochs: 100
41
38
  - name: TEDPolicy
42
39
  max_history: 5
43
40
  epochs: 100
@@ -233,7 +233,6 @@ class DefaultV1Recipe(Recipe):
233
233
  training_type=training_type,
234
234
  assistant_id=config.get(ASSISTANT_ID_KEY),
235
235
  language=config.get("language"),
236
- spaces=config.get("spaces"),
237
236
  core_target=core_target,
238
237
  nlu_target=f"run_{RegexMessageHandler.__name__}",
239
238
  )