rasa-pro 3.12.0.dev9__py3-none-any.whl → 3.12.0.dev11__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.
- rasa/cli/inspect.py +20 -1
- rasa/cli/shell.py +3 -3
- rasa/core/actions/action.py +20 -7
- rasa/core/actions/action_handle_digressions.py +142 -0
- rasa/core/actions/forms.py +10 -5
- rasa/core/channels/__init__.py +2 -0
- rasa/core/channels/voice_ready/audiocodes.py +42 -23
- rasa/core/channels/voice_stream/browser_audio.py +1 -0
- rasa/core/channels/voice_stream/call_state.py +7 -1
- rasa/core/channels/voice_stream/genesys.py +331 -0
- rasa/core/channels/voice_stream/tts/azure.py +2 -1
- rasa/core/channels/voice_stream/tts/cartesia.py +16 -3
- rasa/core/channels/voice_stream/twilio_media_streams.py +2 -1
- rasa/core/channels/voice_stream/voice_channel.py +2 -1
- rasa/core/migrate.py +2 -2
- rasa/core/policies/flows/flow_executor.py +36 -42
- rasa/core/run.py +4 -3
- rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -2
- rasa/dialogue_understanding/commands/cancel_flow_command.py +62 -4
- rasa/dialogue_understanding/commands/change_flow_command.py +2 -2
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -2
- rasa/dialogue_understanding/commands/clarify_command.py +2 -2
- rasa/dialogue_understanding/commands/correct_slots_command.py +11 -2
- rasa/dialogue_understanding/commands/handle_digressions_command.py +150 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +2 -2
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -2
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -2
- rasa/dialogue_understanding/commands/set_slot_command.py +7 -15
- rasa/dialogue_understanding/commands/skip_question_command.py +2 -2
- rasa/dialogue_understanding/commands/start_flow_command.py +43 -2
- rasa/dialogue_understanding/commands/utils.py +1 -1
- rasa/dialogue_understanding/constants.py +1 -0
- rasa/dialogue_understanding/generator/command_generator.py +110 -73
- rasa/dialogue_understanding/generator/command_parser.py +1 -1
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +161 -3
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +10 -2
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +44 -3
- rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +40 -40
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +11 -19
- rasa/dialogue_understanding/generator/utils.py +32 -1
- rasa/dialogue_understanding/patterns/correction.py +13 -1
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +62 -2
- rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
- rasa/dialogue_understanding/processor/command_processor.py +115 -28
- rasa/dialogue_understanding/utils.py +31 -0
- rasa/dialogue_understanding_test/README.md +50 -0
- rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +3 -3
- rasa/model_service.py +4 -0
- rasa/model_training.py +24 -27
- rasa/shared/core/constants.py +28 -3
- rasa/shared/core/domain.py +13 -20
- rasa/shared/core/events.py +13 -2
- rasa/shared/core/flows/flow.py +17 -0
- rasa/shared/core/flows/flows_yaml_schema.json +38 -0
- rasa/shared/core/flows/steps/collect.py +18 -1
- rasa/shared/core/flows/utils.py +16 -1
- rasa/shared/core/slot_mappings.py +144 -108
- rasa/shared/core/slots.py +23 -2
- rasa/shared/core/trackers.py +3 -1
- rasa/shared/nlu/constants.py +1 -0
- rasa/shared/providers/llm/_base_litellm_client.py +0 -40
- rasa/shared/utils/llm.py +1 -86
- rasa/shared/utils/schemas/domain.yml +0 -1
- rasa/telemetry.py +43 -13
- rasa/utils/common.py +0 -1
- rasa/validator.py +189 -82
- rasa/version.py +1 -1
- {rasa_pro-3.12.0.dev9.dist-info → rasa_pro-3.12.0.dev11.dist-info}/METADATA +1 -1
- {rasa_pro-3.12.0.dev9.dist-info → rasa_pro-3.12.0.dev11.dist-info}/RECORD +72 -68
- {rasa_pro-3.12.0.dev9.dist-info → rasa_pro-3.12.0.dev11.dist-info}/NOTICE +0 -0
- {rasa_pro-3.12.0.dev9.dist-info → rasa_pro-3.12.0.dev11.dist-info}/WHEEL +0 -0
- {rasa_pro-3.12.0.dev9.dist-info → rasa_pro-3.12.0.dev11.dist-info}/entry_points.txt +0 -0
rasa/shared/core/events.py
CHANGED
|
@@ -1032,6 +1032,7 @@ class SlotSet(Event):
|
|
|
1032
1032
|
value: Optional[Any] = None,
|
|
1033
1033
|
timestamp: Optional[float] = None,
|
|
1034
1034
|
metadata: Optional[Dict[Text, Any]] = None,
|
|
1035
|
+
filled_by: Optional[str] = None,
|
|
1035
1036
|
) -> None:
|
|
1036
1037
|
"""Creates event to set slot.
|
|
1037
1038
|
|
|
@@ -1043,6 +1044,7 @@ class SlotSet(Event):
|
|
|
1043
1044
|
"""
|
|
1044
1045
|
self.key = key
|
|
1045
1046
|
self.value = value
|
|
1047
|
+
self._filled_by = filled_by
|
|
1046
1048
|
super().__init__(timestamp, metadata)
|
|
1047
1049
|
|
|
1048
1050
|
def __repr__(self) -> Text:
|
|
@@ -1060,6 +1062,14 @@ class SlotSet(Event):
|
|
|
1060
1062
|
|
|
1061
1063
|
return (self.key, self.value) == (other.key, other.value)
|
|
1062
1064
|
|
|
1065
|
+
@property
|
|
1066
|
+
def filled_by(self) -> Optional[str]:
|
|
1067
|
+
return self._filled_by
|
|
1068
|
+
|
|
1069
|
+
@filled_by.setter
|
|
1070
|
+
def filled_by(self, value: str) -> None:
|
|
1071
|
+
self._filled_by = value
|
|
1072
|
+
|
|
1063
1073
|
def as_story_string(self) -> Text:
|
|
1064
1074
|
"""Returns text representation of event."""
|
|
1065
1075
|
props = json.dumps({self.key: self.value}, ensure_ascii=False)
|
|
@@ -1081,7 +1091,7 @@ class SlotSet(Event):
|
|
|
1081
1091
|
def as_dict(self) -> Dict[Text, Any]:
|
|
1082
1092
|
"""Returns serialized event."""
|
|
1083
1093
|
d = super().as_dict()
|
|
1084
|
-
d.update({"name": self.key, "value": self.value})
|
|
1094
|
+
d.update({"name": self.key, "value": self.value, "filled_by": self.filled_by})
|
|
1085
1095
|
return d
|
|
1086
1096
|
|
|
1087
1097
|
@classmethod
|
|
@@ -1092,13 +1102,14 @@ class SlotSet(Event):
|
|
|
1092
1102
|
parameters.get("value"),
|
|
1093
1103
|
parameters.get("timestamp"),
|
|
1094
1104
|
parameters.get("metadata"),
|
|
1105
|
+
filled_by=parameters.get("filled_by"),
|
|
1095
1106
|
)
|
|
1096
1107
|
except KeyError as e:
|
|
1097
1108
|
raise ValueError(f"Failed to parse set slot event. {e}")
|
|
1098
1109
|
|
|
1099
1110
|
def apply_to(self, tracker: "DialogueStateTracker") -> None:
|
|
1100
1111
|
"""Applies event to current conversation state."""
|
|
1101
|
-
tracker._set_slot(self.key, self.value)
|
|
1112
|
+
tracker._set_slot(self.key, self.value, self.filled_by)
|
|
1102
1113
|
|
|
1103
1114
|
|
|
1104
1115
|
class Restarted(AlwaysEqualEventMixin):
|
rasa/shared/core/flows/flow.py
CHANGED
|
@@ -11,6 +11,10 @@ from pypred import Predicate
|
|
|
11
11
|
|
|
12
12
|
import rasa.shared.utils.io
|
|
13
13
|
from rasa.shared.constants import RASA_DEFAULT_FLOW_PATTERN_PREFIX
|
|
14
|
+
from rasa.shared.core.constants import (
|
|
15
|
+
KEY_ASK_CONFIRM_DIGRESSIONS,
|
|
16
|
+
KEY_BLOCK_DIGRESSIONS,
|
|
17
|
+
)
|
|
14
18
|
from rasa.shared.core.flows.flow_path import FlowPath, FlowPathsList, PathNode
|
|
15
19
|
from rasa.shared.core.flows.flow_step import FlowStep
|
|
16
20
|
from rasa.shared.core.flows.flow_step_links import (
|
|
@@ -33,6 +37,7 @@ from rasa.shared.core.flows.steps.constants import (
|
|
|
33
37
|
START_STEP,
|
|
34
38
|
)
|
|
35
39
|
from rasa.shared.core.flows.steps.continuation import ContinueFlowStep
|
|
40
|
+
from rasa.shared.core.flows.utils import extract_digression_prop
|
|
36
41
|
from rasa.shared.core.slots import Slot
|
|
37
42
|
|
|
38
43
|
structlogger = structlog.get_logger()
|
|
@@ -62,6 +67,10 @@ class Flow:
|
|
|
62
67
|
"""The path to the file where the flow is stored."""
|
|
63
68
|
persisted_slots: List[str] = field(default_factory=list)
|
|
64
69
|
"""The list of slots that should be persisted after the flow ends."""
|
|
70
|
+
ask_confirm_digressions: List[str] = field(default_factory=list)
|
|
71
|
+
"""The flow ids for which the assistant should ask for confirmation."""
|
|
72
|
+
block_digressions: List[str] = field(default_factory=list)
|
|
73
|
+
"""The flow ids that the assistant should block from digressing to."""
|
|
65
74
|
|
|
66
75
|
@staticmethod
|
|
67
76
|
def from_json(
|
|
@@ -98,6 +107,10 @@ class Flow:
|
|
|
98
107
|
# data. When the model is trained, take the provided file_path.
|
|
99
108
|
file_path=data.get("file_path") if "file_path" in data else file_path,
|
|
100
109
|
persisted_slots=data.get("persisted_slots", []),
|
|
110
|
+
ask_confirm_digressions=extract_digression_prop(
|
|
111
|
+
KEY_ASK_CONFIRM_DIGRESSIONS, data
|
|
112
|
+
),
|
|
113
|
+
block_digressions=extract_digression_prop(KEY_BLOCK_DIGRESSIONS, data),
|
|
101
114
|
)
|
|
102
115
|
|
|
103
116
|
def get_full_name(self) -> str:
|
|
@@ -172,6 +185,10 @@ class Flow:
|
|
|
172
185
|
data["file_path"] = self.file_path
|
|
173
186
|
if self.persisted_slots:
|
|
174
187
|
data["persisted_slots"] = self.persisted_slots
|
|
188
|
+
if self.ask_confirm_digressions:
|
|
189
|
+
data[KEY_ASK_CONFIRM_DIGRESSIONS] = self.ask_confirm_digressions
|
|
190
|
+
if self.block_digressions:
|
|
191
|
+
data[KEY_BLOCK_DIGRESSIONS] = self.block_digressions
|
|
175
192
|
|
|
176
193
|
return data
|
|
177
194
|
|
|
@@ -217,6 +217,12 @@
|
|
|
217
217
|
"reset_after_flow_ends": {
|
|
218
218
|
"type": "boolean"
|
|
219
219
|
},
|
|
220
|
+
"ask_confirm_digressions": {
|
|
221
|
+
"$ref": "#/$defs/ask_confirm_digressions"
|
|
222
|
+
},
|
|
223
|
+
"block_digressions": {
|
|
224
|
+
"$ref": "#/$defs/block_digressions"
|
|
225
|
+
},
|
|
220
226
|
"utter": {
|
|
221
227
|
"type": "string"
|
|
222
228
|
},
|
|
@@ -247,6 +253,32 @@
|
|
|
247
253
|
}
|
|
248
254
|
}
|
|
249
255
|
},
|
|
256
|
+
"ask_confirm_digressions": {
|
|
257
|
+
"oneOf": [
|
|
258
|
+
{
|
|
259
|
+
"type": "boolean"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"type": "array",
|
|
263
|
+
"items": {
|
|
264
|
+
"type": "string"
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
},
|
|
269
|
+
"block_digressions": {
|
|
270
|
+
"oneOf": [
|
|
271
|
+
{
|
|
272
|
+
"type": "boolean"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"type": "array",
|
|
276
|
+
"items": {
|
|
277
|
+
"type": "string"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
},
|
|
250
282
|
"flow": {
|
|
251
283
|
"required": [
|
|
252
284
|
"steps",
|
|
@@ -282,6 +314,12 @@
|
|
|
282
314
|
},
|
|
283
315
|
"persisted_slots": {
|
|
284
316
|
"$ref": "#/$defs/persisted_slots"
|
|
317
|
+
},
|
|
318
|
+
"ask_confirm_digressions": {
|
|
319
|
+
"$ref": "#/$defs/ask_confirm_digressions"
|
|
320
|
+
},
|
|
321
|
+
"block_digressions": {
|
|
322
|
+
"$ref": "#/$defs/block_digressions"
|
|
285
323
|
}
|
|
286
324
|
}
|
|
287
325
|
},
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
4
|
from typing import Any, Dict, List, Set, Text
|
|
5
5
|
|
|
6
6
|
from rasa.shared.constants import ACTION_ASK_PREFIX, UTTER_ASK_PREFIX
|
|
7
|
+
from rasa.shared.core.constants import (
|
|
8
|
+
KEY_ASK_CONFIRM_DIGRESSIONS,
|
|
9
|
+
KEY_BLOCK_DIGRESSIONS,
|
|
10
|
+
)
|
|
7
11
|
from rasa.shared.core.flows.flow_step import FlowStep
|
|
12
|
+
from rasa.shared.core.flows.utils import extract_digression_prop
|
|
8
13
|
|
|
9
14
|
|
|
10
15
|
@dataclass
|
|
@@ -59,6 +64,10 @@ class CollectInformationFlowStep(FlowStep):
|
|
|
59
64
|
"""Whether to always ask the question even if the slot is already filled."""
|
|
60
65
|
reset_after_flow_ends: bool = True
|
|
61
66
|
"""Whether to reset the slot value at the end of the flow."""
|
|
67
|
+
ask_confirm_digressions: List[str] = field(default_factory=list)
|
|
68
|
+
"""The flow id digressions for which the assistant should ask for confirmation."""
|
|
69
|
+
block_digressions: List[str] = field(default_factory=list)
|
|
70
|
+
"""The flow id digressions that should be blocked during the flow step."""
|
|
62
71
|
|
|
63
72
|
@classmethod
|
|
64
73
|
def from_json(
|
|
@@ -86,6 +95,10 @@ class CollectInformationFlowStep(FlowStep):
|
|
|
86
95
|
SlotRejection.from_dict(rejection)
|
|
87
96
|
for rejection in data.get("rejections", [])
|
|
88
97
|
],
|
|
98
|
+
ask_confirm_digressions=extract_digression_prop(
|
|
99
|
+
KEY_ASK_CONFIRM_DIGRESSIONS, data
|
|
100
|
+
),
|
|
101
|
+
block_digressions=extract_digression_prop(KEY_BLOCK_DIGRESSIONS, data),
|
|
89
102
|
**base.__dict__,
|
|
90
103
|
)
|
|
91
104
|
|
|
@@ -101,6 +114,10 @@ class CollectInformationFlowStep(FlowStep):
|
|
|
101
114
|
data["ask_before_filling"] = self.ask_before_filling
|
|
102
115
|
data["reset_after_flow_ends"] = self.reset_after_flow_ends
|
|
103
116
|
data["rejections"] = [rejection.as_dict() for rejection in self.rejections]
|
|
117
|
+
data["ask_confirm_digressions"] = self.ask_confirm_digressions
|
|
118
|
+
data["block_digressions"] = (
|
|
119
|
+
self.block_digressions if self.block_digressions else False
|
|
120
|
+
)
|
|
104
121
|
|
|
105
122
|
return data
|
|
106
123
|
|
rasa/shared/core/flows/utils.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from typing import Set
|
|
1
|
+
from typing import Any, Dict, List, Set
|
|
2
2
|
|
|
3
3
|
from rasa.shared.utils.io import raise_deprecation_warning
|
|
4
4
|
|
|
5
5
|
RESET_PROPERTY_NAME = "reset_after_flow_ends"
|
|
6
6
|
PERSIST_PROPERTY_NAME = "persisted_slots"
|
|
7
|
+
ALL_LABEL = "ALL"
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def warn_deprecated_collect_step_config(flow_id: str, collect_step: str) -> None:
|
|
@@ -38,3 +39,17 @@ def get_invalid_slot_persistence_config_error_message(
|
|
|
38
39
|
f"are neither used in a collect step nor a set_slot step of the flow. "
|
|
39
40
|
f"Please remove such slots from the '{PERSIST_PROPERTY_NAME}' property."
|
|
40
41
|
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def extract_digression_prop(prop: str, data: Dict[str, Any]) -> List[str]:
|
|
45
|
+
"""Extracts the digression property from the data.
|
|
46
|
+
|
|
47
|
+
There can be two types of properties: ask_confirm_digressions and
|
|
48
|
+
block_digressions.
|
|
49
|
+
"""
|
|
50
|
+
digression_property = data.get(prop, [])
|
|
51
|
+
|
|
52
|
+
if isinstance(digression_property, bool):
|
|
53
|
+
digression_property = [ALL_LABEL] if digression_property else []
|
|
54
|
+
|
|
55
|
+
return digression_property
|