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.
- README.md +396 -17
- rasa/api.py +9 -3
- rasa/cli/arguments/default_arguments.py +23 -2
- rasa/cli/arguments/run.py +15 -0
- rasa/cli/arguments/train.py +3 -9
- rasa/cli/e2e_test.py +1 -1
- rasa/cli/evaluate.py +1 -1
- rasa/cli/inspect.py +8 -4
- rasa/cli/llm_fine_tuning.py +12 -15
- rasa/cli/run.py +8 -1
- rasa/cli/studio/studio.py +8 -18
- rasa/cli/train.py +11 -53
- rasa/cli/utils.py +8 -10
- rasa/cli/x.py +1 -1
- rasa/constants.py +1 -1
- rasa/core/actions/action.py +2 -0
- rasa/core/actions/action_hangup.py +29 -0
- rasa/core/agent.py +2 -2
- rasa/core/brokers/kafka.py +3 -1
- rasa/core/brokers/pika.py +3 -1
- rasa/core/channels/__init__.py +8 -6
- rasa/core/channels/channel.py +21 -4
- rasa/core/channels/development_inspector.py +143 -46
- rasa/core/channels/inspector/README.md +1 -1
- rasa/core/channels/inspector/dist/assets/{arc-b6e548fe.js → arc-86942a71.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-fa03ac9e.js → c4Diagram-d0fbc5ce-b0290676.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-ee67392a.js → classDiagram-936ed81e-f6405f6e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-9b283fae.js → classDiagram-v2-c3cb15f1-ef61ac77.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{createText-62fc7601-8b6fcc2a.js → createText-62fc7601-f0411e58.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-22e77f4f.js → edges-f2ad444c-7dcc4f3b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-60ffc87f.js → erDiagram-9d236eb7-e0c092d7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-9dd802e4.js → flowDb-1972c806-fba2e3ce.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-5fa1912f.js → flowDiagram-7ea5b25a-7a70b71a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-24a5f41a.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-622a1fd2.js → flowchart-elk-definition-abe16c3d-00a59b68.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-e285a63a.js → ganttDiagram-9b5ea136-293c91fa.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-f237bdca.js → gitGraphDiagram-99d0ae7c-07b2d68c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-4b03d70e.js → index-2c4b9a3b-bc959fbd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-3a8a5a28.js +1317 -0
- rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-72a0fa5f.js → infoDiagram-736b4530-4a350f72.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-82218c41.js → journeyDiagram-df861f2b-af464fb7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-78cff630.js → layout-0071f036.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-5038b469.js → line-2f73cc83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-c4fc4098.js → linear-f014b4cc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-c33c8ea6.js → mindmap-definition-beec6740-d2426fb6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-a8d03059.js → pieDiagram-dbbf0591-776f01a2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-6a0e56b2.js → quadrantDiagram-4d7f4fd6-82e00b57.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-2dc7c7bd.js → requirementDiagram-6fc4c22a-ea13c6bb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-2360fe39.js → sankeyDiagram-8f13d901-1feca7e9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-41b9f9ad.js → sequenceDiagram-b655622a-070c61d2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-0aad326f.js → stateDiagram-59f0c015-24f46263.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-9847d984.js → stateDiagram-v2-2b26beab-c9056051.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-080da4f6-564d890e.js → styles-080da4f6-08abc34a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-38957613.js → styles-3dcbcfbf-bc74c25a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9c745c82-f0fc6921.js → styles-9c745c82-4e5d66de.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-ef3c5a77.js → svgDrawCommon-4835440b-849c4517.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-bf3e91c1.js → timeline-definition-5b62e21b-d0fb1598.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-4d4026c0.js → xychartDiagram-2b33534f-04d115e2.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +18 -17
- rasa/core/channels/inspector/index.html +17 -16
- rasa/core/channels/inspector/package.json +5 -1
- rasa/core/channels/inspector/src/App.tsx +117 -67
- rasa/core/channels/inspector/src/components/Chat.tsx +95 -0
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +11 -10
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +10 -25
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +1 -1
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +10 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +107 -41
- rasa/core/channels/inspector/src/helpers/utils.ts +92 -7
- rasa/core/channels/inspector/src/types.ts +21 -1
- rasa/core/channels/inspector/yarn.lock +94 -1
- rasa/core/channels/rest.py +51 -46
- rasa/core/channels/socketio.py +22 -0
- rasa/core/channels/{audiocodes.py → voice_ready/audiocodes.py} +110 -68
- rasa/core/channels/{voice_aware → voice_ready}/jambonz.py +11 -4
- rasa/core/channels/{voice_aware → voice_ready}/jambonz_protocol.py +57 -5
- rasa/core/channels/{twilio_voice.py → voice_ready/twilio_voice.py} +58 -7
- rasa/core/channels/{voice_aware → voice_ready}/utils.py +16 -0
- rasa/core/channels/voice_stream/asr/__init__.py +0 -0
- rasa/core/channels/voice_stream/asr/asr_engine.py +71 -0
- rasa/core/channels/voice_stream/asr/asr_event.py +13 -0
- rasa/core/channels/voice_stream/asr/deepgram.py +77 -0
- rasa/core/channels/voice_stream/audio_bytes.py +7 -0
- rasa/core/channels/voice_stream/tts/__init__.py +0 -0
- rasa/core/channels/voice_stream/tts/azure.py +100 -0
- rasa/core/channels/voice_stream/tts/cartesia.py +114 -0
- rasa/core/channels/voice_stream/tts/tts_cache.py +27 -0
- rasa/core/channels/voice_stream/tts/tts_engine.py +48 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +164 -0
- rasa/core/channels/voice_stream/util.py +57 -0
- rasa/core/channels/voice_stream/voice_channel.py +247 -0
- rasa/core/featurizers/single_state_featurizer.py +1 -22
- rasa/core/featurizers/tracker_featurizers.py +18 -115
- rasa/core/nlg/contextual_response_rephraser.py +11 -2
- rasa/{nlu → core}/persistor.py +16 -38
- rasa/core/policies/enterprise_search_policy.py +12 -15
- rasa/core/policies/flows/flow_executor.py +8 -18
- rasa/core/policies/intentless_policy.py +10 -15
- rasa/core/policies/ted_policy.py +33 -58
- rasa/core/policies/unexpected_intent_policy.py +7 -15
- rasa/core/processor.py +13 -64
- rasa/core/run.py +11 -1
- rasa/core/secrets_manager/constants.py +4 -0
- rasa/core/secrets_manager/factory.py +8 -0
- rasa/core/secrets_manager/vault.py +11 -1
- rasa/core/training/interactive.py +1 -1
- rasa/core/utils.py +1 -11
- rasa/dialogue_understanding/coexistence/llm_based_router.py +10 -10
- rasa/dialogue_understanding/commands/__init__.py +2 -0
- rasa/dialogue_understanding/commands/change_flow_command.py +0 -6
- rasa/dialogue_understanding/commands/session_end_command.py +61 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +0 -7
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +12 -3
- rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -28
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -19
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +4 -37
- rasa/e2e_test/aggregate_test_stats_calculator.py +1 -11
- rasa/e2e_test/assertions.py +6 -48
- rasa/e2e_test/e2e_test_runner.py +6 -9
- rasa/e2e_test/utils/e2e_yaml_utils.py +1 -1
- rasa/e2e_test/utils/io.py +1 -3
- rasa/engine/graph.py +3 -10
- rasa/engine/recipes/config_files/default_config.yml +0 -3
- rasa/engine/recipes/default_recipe.py +0 -1
- rasa/engine/recipes/graph_recipe.py +0 -1
- rasa/engine/runner/dask.py +2 -2
- rasa/engine/storage/local_model_storage.py +12 -42
- rasa/engine/storage/storage.py +1 -5
- rasa/engine/validation.py +1 -78
- rasa/keys +1 -0
- rasa/model_training.py +13 -16
- rasa/nlu/classifiers/diet_classifier.py +25 -38
- rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
- rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
- rasa/nlu/extractors/crf_entity_extractor.py +50 -93
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +16 -45
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +17 -52
- rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
- rasa/server.py +1 -1
- rasa/shared/constants.py +3 -12
- rasa/shared/core/constants.py +4 -0
- rasa/shared/core/domain.py +101 -47
- rasa/shared/core/events.py +29 -0
- rasa/shared/core/flows/flows_list.py +20 -11
- rasa/shared/core/flows/validation.py +25 -0
- rasa/shared/core/flows/yaml_flows_io.py +3 -24
- rasa/shared/importers/importer.py +40 -39
- rasa/shared/importers/multi_project.py +23 -11
- rasa/shared/importers/rasa.py +7 -2
- rasa/shared/importers/remote_importer.py +196 -0
- rasa/shared/importers/utils.py +3 -1
- rasa/shared/nlu/training_data/features.py +2 -120
- rasa/shared/nlu/training_data/training_data.py +18 -19
- rasa/shared/providers/_configs/azure_openai_client_config.py +3 -5
- rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -6
- rasa/shared/providers/llm/_base_litellm_client.py +11 -31
- rasa/shared/providers/llm/self_hosted_llm_client.py +3 -15
- rasa/shared/utils/common.py +3 -22
- rasa/shared/utils/io.py +0 -1
- rasa/shared/utils/llm.py +30 -27
- rasa/shared/utils/schemas/events.py +2 -0
- rasa/shared/utils/schemas/model_config.yml +0 -10
- rasa/shared/utils/yaml.py +44 -0
- rasa/studio/auth.py +5 -3
- rasa/studio/config.py +4 -13
- rasa/studio/constants.py +0 -1
- rasa/studio/data_handler.py +3 -10
- rasa/studio/upload.py +8 -17
- rasa/tracing/instrumentation/attribute_extractors.py +1 -1
- rasa/utils/io.py +66 -0
- rasa/utils/tensorflow/model_data.py +193 -2
- rasa/validator.py +0 -12
- rasa/version.py +1 -1
- rasa_pro-3.11.0a1.dist-info/METADATA +576 -0
- {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/RECORD +181 -164
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-a5d3e69d.js +0 -1040
- rasa/utils/tensorflow/feature_array.py +0 -366
- rasa_pro-3.10.16.dist-info/METADATA +0 -196
- /rasa/core/channels/{voice_aware → voice_ready}/__init__.py +0 -0
- /rasa/core/channels/{voice_native → voice_stream}/__init__.py +0 -0
- {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/NOTICE +0 -0
- {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0a1.dist-info}/WHEEL +0 -0
- {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
|
-
|
|
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
|
|
195
|
+
event_info=("Flow retrieval store isinaccessible."),
|
|
187
196
|
error=e,
|
|
188
197
|
)
|
|
189
198
|
raise
|
|
@@ -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\(
|
|
232
|
+
r"""SetSlot\((\"?[a-zA-Z_][a-zA-Z0-9_-]*?\"?), ?(.*)\)"""
|
|
241
233
|
)
|
|
242
|
-
start_flow_re = re.compile(r"StartFlow\(
|
|
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
|
|
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
|
-
|
|
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\(([
|
|
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
|
|
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
|
|
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)
|
rasa/e2e_test/assertions.py
CHANGED
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
rasa/e2e_test/e2e_test_runner.py
CHANGED
|
@@ -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
|
|
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
|
|
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}'.
|
|
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
|
|
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
|
|
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(
|
|
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.
|
|
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
|
|
@@ -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
|
)
|