rasa-pro 3.13.5__py3-none-any.whl → 3.14.0.dev20250731__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/train.py +2 -2
- rasa/core/actions/action.py +27 -37
- rasa/core/actions/action_run_slot_rejections.py +1 -1
- rasa/core/channels/studio_chat.py +67 -20
- rasa/core/channels/voice_ready/twilio_voice.py +1 -1
- rasa/core/channels/voice_stream/audiocodes.py +7 -4
- rasa/core/channels/voice_stream/browser_audio.py +19 -1
- rasa/core/channels/voice_stream/genesys.py +14 -11
- rasa/core/channels/voice_stream/jambonz.py +11 -9
- rasa/core/channels/voice_stream/twilio_media_streams.py +12 -11
- rasa/core/channels/voice_stream/util.py +11 -1
- rasa/core/channels/voice_stream/voice_channel.py +18 -16
- rasa/core/nlg/contextual_response_rephraser.py +6 -7
- rasa/core/nlg/generator.py +21 -5
- rasa/core/nlg/response.py +43 -6
- rasa/core/nlg/translate.py +8 -0
- rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
- rasa/e2e_test/e2e_test_schema.yml +3 -3
- rasa/model_manager/model_api.py +1 -1
- rasa/model_manager/socket_bridge.py +7 -0
- rasa/shared/utils/common.py +2 -1
- rasa/utils/licensing.py +21 -10
- rasa/utils/plotting.py +1 -1
- rasa/version.py +1 -1
- {rasa_pro-3.13.5.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/METADATA +9 -9
- {rasa_pro-3.13.5.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/RECORD +29 -29
- {rasa_pro-3.13.5.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.5.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.5.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/entry_points.txt +0 -0
rasa/cli/train.py
CHANGED
|
@@ -15,7 +15,7 @@ from rasa.core.nlg.contextual_response_rephraser import ContextualResponseRephra
|
|
|
15
15
|
from rasa.core.nlg.generator import NaturalLanguageGenerator
|
|
16
16
|
from rasa.core.train import do_compare_training
|
|
17
17
|
from rasa.engine.validation import validate_api_type_config_key_usage
|
|
18
|
-
from rasa.exceptions import
|
|
18
|
+
from rasa.exceptions import DetailedRasaException
|
|
19
19
|
from rasa.shared.constants import (
|
|
20
20
|
CONFIG_MANDATORY_KEYS,
|
|
21
21
|
CONFIG_MANDATORY_KEYS_CORE,
|
|
@@ -82,7 +82,7 @@ def _check_nlg_endpoint_validity(endpoint: Union[Path, str]) -> None:
|
|
|
82
82
|
ContextualResponseRephraser.__name__,
|
|
83
83
|
)
|
|
84
84
|
NaturalLanguageGenerator.create(endpoints.nlg)
|
|
85
|
-
except
|
|
85
|
+
except DetailedRasaException as e:
|
|
86
86
|
structlogger.error(
|
|
87
87
|
e.code,
|
|
88
88
|
event_info=e.info,
|
rasa/core/actions/action.py
CHANGED
|
@@ -23,11 +23,9 @@ from rasa.core.constants import (
|
|
|
23
23
|
KEY_IS_COEXISTENCE_ASSISTANT,
|
|
24
24
|
UTTER_SOURCE_METADATA_KEY,
|
|
25
25
|
)
|
|
26
|
-
from rasa.core.nlg.translate import get_translated_buttons, get_translated_text
|
|
27
26
|
from rasa.core.policies.policy import PolicyPrediction
|
|
28
27
|
from rasa.core.utils import add_bot_utterance_metadata
|
|
29
28
|
from rasa.e2e_test.constants import KEY_STUB_CUSTOM_ACTIONS
|
|
30
|
-
from rasa.engine.language import Language
|
|
31
29
|
from rasa.nlu.constants import (
|
|
32
30
|
RESPONSE_SELECTOR_DEFAULT_INTENT,
|
|
33
31
|
RESPONSE_SELECTOR_PREDICTION_KEY,
|
|
@@ -84,7 +82,6 @@ from rasa.shared.core.events import (
|
|
|
84
82
|
UserUttered,
|
|
85
83
|
)
|
|
86
84
|
from rasa.shared.core.flows import FlowsList
|
|
87
|
-
from rasa.shared.core.flows.constants import KEY_TRANSLATION
|
|
88
85
|
from rasa.shared.core.slot_mappings import (
|
|
89
86
|
SlotFillingManager,
|
|
90
87
|
extract_slot_value,
|
|
@@ -251,36 +248,25 @@ def action_for_name_or_text(
|
|
|
251
248
|
return RemoteAction(action_name_or_text, action_endpoint)
|
|
252
249
|
|
|
253
250
|
|
|
254
|
-
def create_bot_utterance(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
251
|
+
def create_bot_utterance(message: Dict[Text, Any]) -> BotUttered:
|
|
252
|
+
"""Create BotUttered event from message."""
|
|
253
|
+
bot_message = BotUttered(
|
|
254
|
+
text=message.pop(TEXT, None),
|
|
255
|
+
data={
|
|
256
|
+
ELEMENTS: message.pop(ELEMENTS, None),
|
|
257
|
+
QUICK_REPLIES: message.pop(QUICK_REPLIES, None),
|
|
258
|
+
BUTTONS: message.pop(BUTTONS, None),
|
|
259
|
+
# for legacy / compatibility reasons we need to set the image
|
|
260
|
+
# to be the attachment if there is no other attachment (the
|
|
261
|
+
# `.get` is intentional - no `pop` as we still need the image`
|
|
262
|
+
# property to set it in the following line)
|
|
263
|
+
ATTACHMENT: message.pop(ATTACHMENT, None) or message.get(IMAGE, None),
|
|
264
|
+
IMAGE: message.pop(IMAGE, None),
|
|
265
|
+
CUSTOM: message.pop(CUSTOM, None),
|
|
266
|
+
},
|
|
267
|
+
metadata=message,
|
|
268
268
|
)
|
|
269
|
-
|
|
270
|
-
data = {
|
|
271
|
-
ELEMENTS: message_copy.pop(ELEMENTS, None),
|
|
272
|
-
QUICK_REPLIES: message_copy.pop(QUICK_REPLIES, None),
|
|
273
|
-
BUTTONS: buttons,
|
|
274
|
-
# for legacy / compatibility reasons we need to set the image
|
|
275
|
-
# to be the attachment if there is no other attachment (the
|
|
276
|
-
# `.get` is intentional - no `pop` as we still need the image`
|
|
277
|
-
# property to set it in the following line)
|
|
278
|
-
ATTACHMENT: message_copy.pop(ATTACHMENT, None) or message_copy.get(IMAGE, None),
|
|
279
|
-
IMAGE: message_copy.pop(IMAGE, None),
|
|
280
|
-
CUSTOM: message_copy.pop(CUSTOM, None),
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return BotUttered(text=text, data=data, metadata=message_copy)
|
|
269
|
+
return bot_message
|
|
284
270
|
|
|
285
271
|
|
|
286
272
|
class Action:
|
|
@@ -393,7 +379,7 @@ class ActionBotResponse(Action):
|
|
|
393
379
|
message = add_bot_utterance_metadata(
|
|
394
380
|
message, self.utter_action, nlg, domain, tracker
|
|
395
381
|
)
|
|
396
|
-
return [create_bot_utterance(message
|
|
382
|
+
return [create_bot_utterance(message)]
|
|
397
383
|
|
|
398
384
|
def name(self) -> Text:
|
|
399
385
|
"""Returns action name."""
|
|
@@ -427,7 +413,7 @@ class ActionEndToEndResponse(Action):
|
|
|
427
413
|
) -> List[Event]:
|
|
428
414
|
"""Runs action (see parent class for full docstring)."""
|
|
429
415
|
message = {"text": self.action_text}
|
|
430
|
-
return [create_bot_utterance(message
|
|
416
|
+
return [create_bot_utterance(message)]
|
|
431
417
|
|
|
432
418
|
def event_for_successful_execution(
|
|
433
419
|
self,
|
|
@@ -893,7 +879,10 @@ class RemoteAction(Action):
|
|
|
893
879
|
generated_response = response.pop("response", None)
|
|
894
880
|
if generated_response is not None:
|
|
895
881
|
draft = await nlg.generate(
|
|
896
|
-
generated_response,
|
|
882
|
+
generated_response,
|
|
883
|
+
tracker,
|
|
884
|
+
output_channel.name(),
|
|
885
|
+
**response,
|
|
897
886
|
)
|
|
898
887
|
if not draft:
|
|
899
888
|
continue
|
|
@@ -1068,6 +1057,7 @@ def _revert_rephrasing_events() -> List[Event]:
|
|
|
1068
1057
|
]
|
|
1069
1058
|
|
|
1070
1059
|
|
|
1060
|
+
# TODO: this should be removed, e.g. it uses a hardcoded message and no translation
|
|
1071
1061
|
class ActionDefaultAskAffirmation(Action):
|
|
1072
1062
|
"""Default implementation which asks the user to affirm his intent.
|
|
1073
1063
|
|
|
@@ -1119,7 +1109,7 @@ class ActionDefaultAskAffirmation(Action):
|
|
|
1119
1109
|
"utter_action": self.name(),
|
|
1120
1110
|
}
|
|
1121
1111
|
|
|
1122
|
-
return [create_bot_utterance(message
|
|
1112
|
+
return [create_bot_utterance(message)]
|
|
1123
1113
|
|
|
1124
1114
|
|
|
1125
1115
|
class ActionDefaultAskRephrase(ActionBotResponse):
|
|
@@ -1155,7 +1145,7 @@ class ActionSendText(Action):
|
|
|
1155
1145
|
|
|
1156
1146
|
should_send_text = metadata_copy.get("should_send_text", True)
|
|
1157
1147
|
if should_send_text:
|
|
1158
|
-
return [create_bot_utterance(message
|
|
1148
|
+
return [create_bot_utterance(message)]
|
|
1159
1149
|
return []
|
|
1160
1150
|
|
|
1161
1151
|
|
|
@@ -216,6 +216,6 @@ class ActionRunSlotRejections(Action):
|
|
|
216
216
|
message = add_bot_utterance_metadata(
|
|
217
217
|
message, utterance, nlg, domain, tracker
|
|
218
218
|
)
|
|
219
|
-
events.append(create_bot_utterance(message
|
|
219
|
+
events.append(create_bot_utterance(message))
|
|
220
220
|
|
|
221
221
|
return events
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import audioop
|
|
3
5
|
import base64
|
|
@@ -32,6 +34,7 @@ from rasa.core.channels.voice_stream.voice_channel import (
|
|
|
32
34
|
VoiceInputChannel,
|
|
33
35
|
VoiceOutputChannel,
|
|
34
36
|
)
|
|
37
|
+
from rasa.core.exceptions import AgentNotReady
|
|
35
38
|
from rasa.hooks import hookimpl
|
|
36
39
|
from rasa.plugin import plugin_manager
|
|
37
40
|
from rasa.shared.core.constants import ACTION_LISTEN_NAME
|
|
@@ -42,7 +45,7 @@ if TYPE_CHECKING:
|
|
|
42
45
|
from sanic import Sanic, Websocket # type: ignore[attr-defined]
|
|
43
46
|
from socketio import AsyncServer
|
|
44
47
|
|
|
45
|
-
from rasa.core.channels.channel import
|
|
48
|
+
from rasa.core.channels.channel import UserMessage
|
|
46
49
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
47
50
|
|
|
48
51
|
|
|
@@ -179,7 +182,9 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
179
182
|
self._register_tracker_update_hook()
|
|
180
183
|
|
|
181
184
|
@classmethod
|
|
182
|
-
def from_credentials(
|
|
185
|
+
def from_credentials(
|
|
186
|
+
cls, credentials: Optional[Dict[Text, Any]]
|
|
187
|
+
) -> "StudioChatInput":
|
|
183
188
|
"""Creates a StudioChatInput channel from credentials."""
|
|
184
189
|
credentials = credentials or {}
|
|
185
190
|
|
|
@@ -199,6 +204,13 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
199
204
|
metadata_key=credentials.get("metadata_key", "metadata"),
|
|
200
205
|
)
|
|
201
206
|
|
|
207
|
+
async def emit(self, event: str, data: Dict, room: str) -> None:
|
|
208
|
+
"""Emits an event to the websocket."""
|
|
209
|
+
if not self.sio:
|
|
210
|
+
structlogger.error("studio_chat.emit.sio_not_initialized")
|
|
211
|
+
return
|
|
212
|
+
await self.sio.emit(event, data, room=room)
|
|
213
|
+
|
|
202
214
|
def _register_tracker_update_hook(self) -> None:
|
|
203
215
|
plugin_manager().register(StudioTrackerUpdatePlugin(self))
|
|
204
216
|
|
|
@@ -208,10 +220,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
208
220
|
|
|
209
221
|
async def publish_tracker_update(self, sender_id: str, tracker_dump: Dict) -> None:
|
|
210
222
|
"""Publishes a tracker update notification to the websocket."""
|
|
211
|
-
|
|
212
|
-
structlogger.error("studio_chat.on_tracker_updated.sio_not_initialized")
|
|
213
|
-
return
|
|
214
|
-
await self.sio.emit("tracker", tracker_dump, room=sender_id)
|
|
223
|
+
await self.emit("tracker", tracker_dump, room=sender_id)
|
|
215
224
|
|
|
216
225
|
async def on_message_proxy(
|
|
217
226
|
self,
|
|
@@ -224,8 +233,15 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
224
233
|
"""
|
|
225
234
|
await on_new_message(message)
|
|
226
235
|
|
|
227
|
-
if not self.agent:
|
|
236
|
+
if not self.agent or not self.agent.is_ready():
|
|
228
237
|
structlogger.error("studio_chat.on_message_proxy.agent_not_initialized")
|
|
238
|
+
await self.emit_error(
|
|
239
|
+
"The Rasa Pro model could not be loaded. "
|
|
240
|
+
"Please check the training and deployment logs "
|
|
241
|
+
"for more information.",
|
|
242
|
+
message.sender_id,
|
|
243
|
+
AgentNotReady("The Rasa Pro model could not be loaded."),
|
|
244
|
+
)
|
|
229
245
|
return
|
|
230
246
|
|
|
231
247
|
tracker = await self.agent.tracker_store.retrieve(message.sender_id)
|
|
@@ -235,6 +251,17 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
235
251
|
|
|
236
252
|
await self.on_tracker_updated(tracker)
|
|
237
253
|
|
|
254
|
+
async def emit_error(self, message: str, room: str, e: Exception) -> None:
|
|
255
|
+
await self.emit(
|
|
256
|
+
"error",
|
|
257
|
+
{
|
|
258
|
+
"message": message,
|
|
259
|
+
"error": str(e),
|
|
260
|
+
"exception": str(type(e).__name__),
|
|
261
|
+
},
|
|
262
|
+
room=room,
|
|
263
|
+
)
|
|
264
|
+
|
|
238
265
|
async def handle_tracker_update(self, sid: str, data: Dict) -> None:
|
|
239
266
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
240
267
|
|
|
@@ -251,21 +278,41 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
251
278
|
structlogger.error("studio_chat.sio.domain_not_initialized")
|
|
252
279
|
return None
|
|
253
280
|
|
|
254
|
-
|
|
255
|
-
tracker = DialogueStateTracker.from_dict(
|
|
256
|
-
data["sender_id"], data["events"], domain.slots
|
|
257
|
-
)
|
|
281
|
+
tracker: Optional[DialogueStateTracker] = None
|
|
258
282
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
output_channel = self.get_output_channel()
|
|
283
|
+
async with self.agent.lock_store.lock(data["sender_id"]):
|
|
284
|
+
try:
|
|
285
|
+
tracker = DialogueStateTracker.from_dict(
|
|
286
|
+
data["sender_id"], data["events"], domain.slots
|
|
287
|
+
)
|
|
265
288
|
|
|
266
|
-
|
|
289
|
+
# will override an existing tracker with the same id!
|
|
267
290
|
await self.agent.tracker_store.save(tracker)
|
|
268
291
|
|
|
292
|
+
processor = self.agent.processor
|
|
293
|
+
if processor and does_need_action_prediction(tracker):
|
|
294
|
+
output_channel = self.get_output_channel()
|
|
295
|
+
|
|
296
|
+
await processor._run_prediction_loop(output_channel, tracker)
|
|
297
|
+
await self.agent.tracker_store.save(tracker)
|
|
298
|
+
except Exception as e:
|
|
299
|
+
structlogger.error(
|
|
300
|
+
"studio_chat.sio.handle_tracker_update.error",
|
|
301
|
+
error=e,
|
|
302
|
+
sender_id=data["sender_id"],
|
|
303
|
+
)
|
|
304
|
+
await self.emit_error(
|
|
305
|
+
"An error occurred while updating the conversation.",
|
|
306
|
+
data["sender_id"],
|
|
307
|
+
e,
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
if not tracker:
|
|
311
|
+
# in case the tracker couldn't be updated, we retrieve the prior
|
|
312
|
+
# version and use that to populate the update
|
|
313
|
+
tracker = await self.agent.tracker_store.get_or_create_tracker(
|
|
314
|
+
data["sender_id"]
|
|
315
|
+
)
|
|
269
316
|
await self.on_tracker_updated(tracker)
|
|
270
317
|
|
|
271
318
|
def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
|
|
@@ -275,7 +322,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
275
322
|
async def collect_call_parameters(
|
|
276
323
|
self, channel_websocket: "Websocket"
|
|
277
324
|
) -> Optional[CallParameters]:
|
|
278
|
-
"""Voice method to collect call parameters"""
|
|
325
|
+
"""Voice method to collect call parameters."""
|
|
279
326
|
session_id = channel_websocket.session_id
|
|
280
327
|
return CallParameters(session_id, "local", "local", stream_id=session_id)
|
|
281
328
|
|
|
@@ -305,7 +352,7 @@ class StudioChatInput(SocketIOInput, VoiceInputChannel):
|
|
|
305
352
|
def create_output_channel(
|
|
306
353
|
self, voice_websocket: "Websocket", tts_engine: TTSEngine
|
|
307
354
|
) -> VoiceOutputChannel:
|
|
308
|
-
"""Create a voice output channel"""
|
|
355
|
+
"""Create a voice output channel."""
|
|
309
356
|
return StudioVoiceOutputChannel(
|
|
310
357
|
voice_websocket,
|
|
311
358
|
tts_engine,
|
|
@@ -30,7 +30,7 @@ TWILIO_VOICE_PATH = "webhooks/twilio_voice/webhook"
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def map_call_params(form: RequestParameters) -> CallParameters:
|
|
33
|
-
"""Map the
|
|
33
|
+
"""Map the Twilio Voice parameters to the CallParameters dataclass."""
|
|
34
34
|
return CallParameters(
|
|
35
35
|
call_id=form.get("CallSid"),
|
|
36
36
|
user_phone=form.get("Caller"),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import base64
|
|
3
5
|
import hmac
|
|
@@ -21,6 +23,7 @@ from rasa.core.channels.voice_stream.call_state import (
|
|
|
21
23
|
call_state,
|
|
22
24
|
)
|
|
23
25
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
26
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
24
27
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
25
28
|
ContinueConversationAction,
|
|
26
29
|
EndConversationAction,
|
|
@@ -127,10 +130,10 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
|
|
|
127
130
|
def from_credentials(
|
|
128
131
|
cls,
|
|
129
132
|
credentials: Optional[Dict[str, Any]],
|
|
130
|
-
) ->
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return
|
|
133
|
+
) -> AudiocodesVoiceInputChannel:
|
|
134
|
+
cls.validate_basic_credentials(credentials)
|
|
135
|
+
new_creds = repack_voice_credentials(credentials)
|
|
136
|
+
return cls(**new_creds)
|
|
134
137
|
|
|
135
138
|
def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
|
|
136
139
|
return RasaAudioBytes(base64.b64decode(input_bytes))
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import audioop
|
|
2
4
|
import base64
|
|
3
5
|
import json
|
|
4
6
|
import uuid
|
|
5
|
-
from typing import Any, Awaitable, Callable, Optional, Tuple
|
|
7
|
+
from typing import Any, Awaitable, Callable, Dict, Optional, Tuple
|
|
6
8
|
|
|
7
9
|
import structlog
|
|
8
10
|
from sanic import ( # type: ignore[attr-defined]
|
|
@@ -18,6 +20,7 @@ from rasa.core.channels.voice_ready.utils import CallParameters
|
|
|
18
20
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
19
21
|
from rasa.core.channels.voice_stream.call_state import call_state
|
|
20
22
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
23
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
21
24
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
22
25
|
ContinueConversationAction,
|
|
23
26
|
EndConversationAction,
|
|
@@ -49,6 +52,12 @@ class BrowserAudioOutputChannel(VoiceOutputChannel):
|
|
|
49
52
|
|
|
50
53
|
|
|
51
54
|
class BrowserAudioInputChannel(VoiceInputChannel):
|
|
55
|
+
def __init__(
|
|
56
|
+
self, server_url: str, asr_config: Dict[str, Any], tts_config: Dict[str, Any]
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Initializes the browser audio input channel."""
|
|
59
|
+
super().__init__(server_url, asr_config, tts_config)
|
|
60
|
+
|
|
52
61
|
@classmethod
|
|
53
62
|
def name(cls) -> str:
|
|
54
63
|
return "browser_audio"
|
|
@@ -62,6 +71,15 @@ class BrowserAudioInputChannel(VoiceInputChannel):
|
|
|
62
71
|
call_id = f"inspect-{uuid.uuid4()}"
|
|
63
72
|
return CallParameters(call_id, "local", "local", stream_id=call_id)
|
|
64
73
|
|
|
74
|
+
@classmethod
|
|
75
|
+
def from_credentials(
|
|
76
|
+
cls,
|
|
77
|
+
credentials: Optional[Dict[str, Any]],
|
|
78
|
+
) -> BrowserAudioInputChannel:
|
|
79
|
+
cls.validate_basic_credentials(credentials)
|
|
80
|
+
new_creds = repack_voice_credentials(credentials)
|
|
81
|
+
return cls(**new_creds)
|
|
82
|
+
|
|
65
83
|
def map_input_message(
|
|
66
84
|
self,
|
|
67
85
|
message: Any,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import base64
|
|
3
5
|
import hashlib
|
|
@@ -21,6 +23,7 @@ from rasa.core.channels.voice_stream.call_state import (
|
|
|
21
23
|
call_state,
|
|
22
24
|
)
|
|
23
25
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
26
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
24
27
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
25
28
|
ContinueConversationAction,
|
|
26
29
|
EndConversationAction,
|
|
@@ -54,7 +57,7 @@ logger = structlog.get_logger(__name__)
|
|
|
54
57
|
|
|
55
58
|
|
|
56
59
|
def map_call_params(data: Dict[Text, Any]) -> CallParameters:
|
|
57
|
-
"""Map the
|
|
60
|
+
"""Map the Genesys parameters to the CallParameters dataclass."""
|
|
58
61
|
parameters = data["parameters"]
|
|
59
62
|
participant = parameters["participant"]
|
|
60
63
|
# sent as {"ani": "tel:+491604697810"}
|
|
@@ -107,7 +110,7 @@ class GenesysInputChannel(VoiceInputChannel):
|
|
|
107
110
|
def from_credentials(
|
|
108
111
|
cls,
|
|
109
112
|
credentials: Optional[Dict[str, Any]],
|
|
110
|
-
) ->
|
|
113
|
+
) -> GenesysInputChannel:
|
|
111
114
|
"""Create a channel from credentials dictionary.
|
|
112
115
|
|
|
113
116
|
Args:
|
|
@@ -121,21 +124,21 @@ class GenesysInputChannel(VoiceInputChannel):
|
|
|
121
124
|
Returns:
|
|
122
125
|
GenesysInputChannel instance
|
|
123
126
|
"""
|
|
124
|
-
|
|
127
|
+
cls.validate_credentials(credentials)
|
|
128
|
+
new_creds = repack_voice_credentials(credentials)
|
|
129
|
+
return cls(**new_creds)
|
|
125
130
|
|
|
126
|
-
|
|
131
|
+
@classmethod
|
|
132
|
+
def validate_credentials(cls, credentials: Optional[Dict[str, Any]]) -> None:
|
|
133
|
+
"""Validate the credentials for the Genesys voice channel."""
|
|
134
|
+
cls.validate_basic_credentials(credentials)
|
|
127
135
|
if not credentials.get("api_key"): # type: ignore[union-attr]
|
|
128
136
|
raise InvalidConfigException(
|
|
129
137
|
"No API key given for Genesys voice channel (api_key)."
|
|
130
138
|
)
|
|
131
139
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
channel.client_secret = credentials.get("client_secret") # type: ignore[union-attr,attr-defined]
|
|
135
|
-
|
|
136
|
-
return channel # type: ignore[return-value]
|
|
137
|
-
|
|
138
|
-
def _ensure_channel_data_initialized(self) -> None:
|
|
140
|
+
@staticmethod
|
|
141
|
+
def _ensure_channel_data_initialized() -> None:
|
|
139
142
|
"""Initialize Genesys-specific channel data if not already present.
|
|
140
143
|
|
|
141
144
|
Genesys requires the server and client each maintain a
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import audioop
|
|
2
4
|
import json
|
|
3
5
|
import uuid
|
|
@@ -20,6 +22,7 @@ from rasa.core.channels.voice_ready.utils import (
|
|
|
20
22
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
21
23
|
from rasa.core.channels.voice_stream.call_state import call_state
|
|
22
24
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
25
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
23
26
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
24
27
|
ContinueConversationAction,
|
|
25
28
|
EndConversationAction,
|
|
@@ -35,7 +38,7 @@ JAMBONZ_STREAMS_WEBSOCKET_PATH = "webhooks/jambonz_stream/websocket"
|
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
def map_call_params(data: Dict[Text, str]) -> CallParameters:
|
|
38
|
-
"""Map the
|
|
41
|
+
"""Map the Jambonz stream parameters to the CallParameters dataclass."""
|
|
39
42
|
call_sid = data.get("callSid", "None")
|
|
40
43
|
from_number = data.get("from", "Unknown")
|
|
41
44
|
to_number = data.get("to")
|
|
@@ -94,7 +97,7 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
94
97
|
@classmethod
|
|
95
98
|
def from_credentials(
|
|
96
99
|
cls, credentials: Optional[Dict[Text, Any]]
|
|
97
|
-
) ->
|
|
100
|
+
) -> JambonzStreamInputChannel:
|
|
98
101
|
"""Create a channel from credentials dictionary.
|
|
99
102
|
|
|
100
103
|
Args:
|
|
@@ -109,19 +112,18 @@ class JambonzStreamInputChannel(VoiceInputChannel):
|
|
|
109
112
|
JambonzStreamInputChannel instance
|
|
110
113
|
"""
|
|
111
114
|
# Get common credentials from parent
|
|
112
|
-
|
|
115
|
+
cls.validate_credentials(credentials)
|
|
116
|
+
new_creds = repack_voice_credentials(credentials)
|
|
117
|
+
return cls(**new_creds)
|
|
113
118
|
|
|
119
|
+
@classmethod
|
|
120
|
+
def validate_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> None:
|
|
121
|
+
cls.validate_basic_credentials(credentials)
|
|
114
122
|
# Check optional basic auth credentials
|
|
115
123
|
username = credentials.get("username") # type: ignore[union-attr]
|
|
116
124
|
password = credentials.get("password") # type: ignore[union-attr]
|
|
117
125
|
validate_username_password_credentials(username, password, "Jambonz Stream")
|
|
118
126
|
|
|
119
|
-
# Update channel with auth credentials
|
|
120
|
-
channel.username = username # type: ignore[attr-defined]
|
|
121
|
-
channel.password = password # type: ignore[attr-defined]
|
|
122
|
-
|
|
123
|
-
return channel # type: ignore[return-value]
|
|
124
|
-
|
|
125
127
|
def _websocket_stream_url(self) -> str:
|
|
126
128
|
"""Returns the websocket stream URL."""
|
|
127
129
|
# depending on the config value, the url might contain http as a
|
|
@@ -26,6 +26,7 @@ from rasa.core.channels.voice_ready.utils import (
|
|
|
26
26
|
from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
|
|
27
27
|
from rasa.core.channels.voice_stream.call_state import call_state
|
|
28
28
|
from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine
|
|
29
|
+
from rasa.core.channels.voice_stream.util import repack_voice_credentials
|
|
29
30
|
from rasa.core.channels.voice_stream.voice_channel import (
|
|
30
31
|
ContinueConversationAction,
|
|
31
32
|
EndConversationAction,
|
|
@@ -120,20 +121,20 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
|
|
|
120
121
|
cls,
|
|
121
122
|
credentials: Optional[Dict[str, Any]],
|
|
122
123
|
) -> VoiceInputChannel:
|
|
123
|
-
credentials
|
|
124
|
+
cls.validate_credentials(credentials)
|
|
125
|
+
new_creds = repack_voice_credentials(credentials)
|
|
126
|
+
return cls(**new_creds)
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
@classmethod
|
|
129
|
+
def validate_credentials(
|
|
130
|
+
cls,
|
|
131
|
+
credentials: Optional[Dict[str, Any]],
|
|
132
|
+
) -> None:
|
|
133
|
+
cls.validate_basic_credentials(credentials)
|
|
134
|
+
username = credentials.get("username") if credentials else None
|
|
135
|
+
password = credentials.get("password") if credentials else None
|
|
127
136
|
validate_username_password_credentials(username, password, "TwilioMediaStreams")
|
|
128
137
|
|
|
129
|
-
return cls(
|
|
130
|
-
credentials["server_url"],
|
|
131
|
-
credentials["asr"],
|
|
132
|
-
credentials["tts"],
|
|
133
|
-
username=username,
|
|
134
|
-
password=password,
|
|
135
|
-
)
|
|
136
|
-
|
|
137
138
|
@classmethod
|
|
138
139
|
def name(cls) -> str:
|
|
139
140
|
return "twilio_media_streams"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import audioop
|
|
2
2
|
import wave
|
|
3
3
|
from dataclasses import asdict, dataclass
|
|
4
|
-
from typing import Optional, Type, TypeVar
|
|
4
|
+
from typing import Dict, Optional, Type, TypeVar
|
|
5
5
|
|
|
6
6
|
import structlog
|
|
7
7
|
|
|
@@ -55,3 +55,13 @@ class MergeableConfig:
|
|
|
55
55
|
@classmethod
|
|
56
56
|
def from_dict(cls: Type[T], data: dict[str, Optional[str]]) -> T:
|
|
57
57
|
return cls(**data)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def repack_voice_credentials(
|
|
61
|
+
credentials: Dict[str, str],
|
|
62
|
+
) -> Dict[str, str]:
|
|
63
|
+
"""Repack voice credentials to ensure they are in the correct format."""
|
|
64
|
+
new_creds = {**credentials}
|
|
65
|
+
new_creds["asr_config"] = new_creds.pop("asr", None)
|
|
66
|
+
new_creds["tts_config"] = new_creds.pop("tts", None)
|
|
67
|
+
return new_creds
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import asyncio
|
|
2
4
|
import copy
|
|
3
5
|
from dataclasses import asdict, dataclass
|
|
@@ -348,29 +350,29 @@ class VoiceInputChannel(InputChannel):
|
|
|
348
350
|
call_state.silence_timeout_watcher = None # type: ignore[attr-defined]
|
|
349
351
|
|
|
350
352
|
@classmethod
|
|
351
|
-
def
|
|
352
|
-
|
|
353
|
-
credentials: Optional[Dict[str, Any]],
|
|
354
|
-
) -> InputChannel:
|
|
353
|
+
def validate_basic_credentials(cls, credentials: Optional[Dict[str, Any]]) -> None:
|
|
354
|
+
"""Validate the basic credentials for the voice channel."""
|
|
355
355
|
if not credentials:
|
|
356
356
|
cls.raise_missing_credentials_exception()
|
|
357
|
-
|
|
358
|
-
if not credentials.get("server_url"):
|
|
359
|
-
raise InvalidConfigException("No server_url provided in credentials.")
|
|
360
|
-
if not credentials.get("asr"):
|
|
357
|
+
if not isinstance(credentials, dict):
|
|
361
358
|
raise InvalidConfigException(
|
|
362
|
-
"
|
|
359
|
+
"Credentials must be a dictionary for voice channel."
|
|
363
360
|
)
|
|
364
|
-
|
|
361
|
+
|
|
362
|
+
required_keys = {"server_url", "asr", "tts"}
|
|
363
|
+
credentials_keys = set(credentials.keys())
|
|
364
|
+
if not required_keys.issubset(credentials_keys):
|
|
365
|
+
missing_fields = required_keys - credentials_keys
|
|
365
366
|
raise InvalidConfigException(
|
|
366
|
-
"
|
|
367
|
+
f"Missing required fields in credentials: {', '.join(missing_fields)} "
|
|
368
|
+
f"for channel {cls.name()}"
|
|
367
369
|
)
|
|
368
370
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
371
|
+
@classmethod
|
|
372
|
+
def from_credentials(
|
|
373
|
+
cls, credentials: Optional[Dict[str, Any]]
|
|
374
|
+
) -> VoiceInputChannel:
|
|
375
|
+
raise NotImplementedError
|
|
374
376
|
|
|
375
377
|
def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
|
|
376
378
|
raise NotImplementedError
|
|
@@ -224,8 +224,10 @@ class ContextualResponseRephraser(
|
|
|
224
224
|
|
|
225
225
|
@measure_llm_latency
|
|
226
226
|
async def _generate_llm_response(self, prompt: str) -> Optional[LLMResponse]:
|
|
227
|
-
"""Use LLM to generate a response
|
|
228
|
-
|
|
227
|
+
"""Use LLM to generate a response.
|
|
228
|
+
|
|
229
|
+
Returns an LLMResponse object containing both the generated text
|
|
230
|
+
(choices) and metadata.
|
|
229
231
|
|
|
230
232
|
Args:
|
|
231
233
|
prompt: The prompt to send to the LLM.
|
|
@@ -406,12 +408,9 @@ class ContextualResponseRephraser(
|
|
|
406
408
|
Returns:
|
|
407
409
|
The generated response.
|
|
408
410
|
"""
|
|
409
|
-
|
|
410
|
-
stack_context = tracker.stack.current_context()
|
|
411
|
-
templated_response = self.generate_from_slots(
|
|
411
|
+
templated_response = await super().generate(
|
|
412
412
|
utter_action=utter_action,
|
|
413
|
-
|
|
414
|
-
stack_context=stack_context,
|
|
413
|
+
tracker=tracker,
|
|
415
414
|
output_channel=output_channel,
|
|
416
415
|
**kwargs,
|
|
417
416
|
)
|
rasa/core/nlg/generator.py
CHANGED
|
@@ -6,6 +6,8 @@ from pypred import Predicate
|
|
|
6
6
|
|
|
7
7
|
import rasa.shared.utils.common
|
|
8
8
|
import rasa.shared.utils.io
|
|
9
|
+
from rasa.core.nlg.translate import has_translation
|
|
10
|
+
from rasa.engine.language import Language
|
|
9
11
|
from rasa.shared.constants import CHANNEL, RESPONSE_CONDITION
|
|
10
12
|
from rasa.shared.core.domain import Domain
|
|
11
13
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
@@ -131,11 +133,23 @@ class ResponseVariationFilter:
|
|
|
131
133
|
|
|
132
134
|
return True
|
|
133
135
|
|
|
136
|
+
def _filter_by_language(
|
|
137
|
+
self, responses: List[Dict[Text, Any]], language: Optional[Language] = None
|
|
138
|
+
) -> List[Dict[Text, Any]]:
|
|
139
|
+
if not language:
|
|
140
|
+
return responses
|
|
141
|
+
|
|
142
|
+
if filtered := [r for r in responses if has_translation(r, language)]:
|
|
143
|
+
return filtered
|
|
144
|
+
# if no translation is found, return the original response variations
|
|
145
|
+
return responses
|
|
146
|
+
|
|
134
147
|
def responses_for_utter_action(
|
|
135
148
|
self,
|
|
136
149
|
utter_action: Text,
|
|
137
150
|
output_channel: Text,
|
|
138
151
|
filled_slots: Dict[Text, Any],
|
|
152
|
+
language: Optional[Language] = None,
|
|
139
153
|
) -> List[Dict[Text, Any]]:
|
|
140
154
|
"""Returns array of responses that fit the channel, action and condition."""
|
|
141
155
|
# filter responses without a condition
|
|
@@ -176,16 +190,16 @@ class ResponseVariationFilter:
|
|
|
176
190
|
)
|
|
177
191
|
|
|
178
192
|
if conditional_channel:
|
|
179
|
-
return conditional_channel
|
|
193
|
+
return self._filter_by_language(conditional_channel, language)
|
|
180
194
|
|
|
181
195
|
if default_channel:
|
|
182
|
-
return default_channel
|
|
196
|
+
return self._filter_by_language(default_channel, language)
|
|
183
197
|
|
|
184
198
|
if conditional_no_channel:
|
|
185
|
-
return conditional_no_channel
|
|
199
|
+
return self._filter_by_language(conditional_no_channel, language)
|
|
186
200
|
|
|
187
201
|
if default_no_channel:
|
|
188
|
-
return default_no_channel
|
|
202
|
+
return self._filter_by_language(default_no_channel, language)
|
|
189
203
|
|
|
190
204
|
# if there is no response variation selected,
|
|
191
205
|
# return the internal error response to prevent
|
|
@@ -198,7 +212,9 @@ class ResponseVariationFilter:
|
|
|
198
212
|
f"a default variation and that all the conditions are valid. "
|
|
199
213
|
f"Returning the internal error response.",
|
|
200
214
|
)
|
|
201
|
-
return self.
|
|
215
|
+
return self._filter_by_language(
|
|
216
|
+
self.responses.get("utter_internal_error_rasa", []), language
|
|
217
|
+
)
|
|
202
218
|
|
|
203
219
|
def get_response_variation_id(
|
|
204
220
|
self,
|
rasa/core/nlg/response.py
CHANGED
|
@@ -5,8 +5,11 @@ from typing import Any, Dict, List, Optional, Text
|
|
|
5
5
|
from rasa.core.constants import DEFAULT_TEMPLATE_ENGINE, TEMPLATE_ENGINE_CONFIG_KEY
|
|
6
6
|
from rasa.core.nlg import interpolator
|
|
7
7
|
from rasa.core.nlg.generator import NaturalLanguageGenerator, ResponseVariationFilter
|
|
8
|
-
from rasa.
|
|
8
|
+
from rasa.core.nlg.translate import get_translated_buttons, get_translated_text
|
|
9
|
+
from rasa.engine.language import Language
|
|
10
|
+
from rasa.shared.constants import BUTTONS, RESPONSE_CONDITION, TEXT
|
|
9
11
|
from rasa.shared.core.domain import RESPONSE_KEYS_TO_INTERPOLATE
|
|
12
|
+
from rasa.shared.core.flows.constants import KEY_TRANSLATION
|
|
10
13
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
11
14
|
from rasa.shared.nlu.constants import METADATA
|
|
12
15
|
|
|
@@ -30,7 +33,11 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
30
33
|
|
|
31
34
|
# noinspection PyUnusedLocal
|
|
32
35
|
def _random_response_for(
|
|
33
|
-
self,
|
|
36
|
+
self,
|
|
37
|
+
utter_action: Text,
|
|
38
|
+
output_channel: Text,
|
|
39
|
+
filled_slots: Dict[Text, Any],
|
|
40
|
+
language: Optional[Language] = None,
|
|
34
41
|
) -> Optional[Dict[Text, Any]]:
|
|
35
42
|
"""Select random response for the utter action from available ones.
|
|
36
43
|
|
|
@@ -42,7 +49,7 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
42
49
|
if utter_action in self.responses:
|
|
43
50
|
response_filter = ResponseVariationFilter(self.responses)
|
|
44
51
|
suitable_responses = response_filter.responses_for_utter_action(
|
|
45
|
-
utter_action, output_channel, filled_slots
|
|
52
|
+
utter_action, output_channel, filled_slots, language
|
|
46
53
|
)
|
|
47
54
|
|
|
48
55
|
if suitable_responses:
|
|
@@ -75,9 +82,36 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
75
82
|
"""Generate a response for the requested utter action."""
|
|
76
83
|
filled_slots = tracker.current_slot_values()
|
|
77
84
|
stack_context = tracker.stack.current_context()
|
|
78
|
-
|
|
79
|
-
utter_action,
|
|
85
|
+
response = self.generate_from_slots(
|
|
86
|
+
utter_action,
|
|
87
|
+
filled_slots,
|
|
88
|
+
stack_context,
|
|
89
|
+
output_channel,
|
|
90
|
+
tracker.current_language,
|
|
91
|
+
**kwargs,
|
|
80
92
|
)
|
|
93
|
+
if response is not None:
|
|
94
|
+
return self.translate_response(response, tracker.current_language)
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
def translate_response(
|
|
98
|
+
self, response: Dict[Text, Any], language: Optional[Language] = None
|
|
99
|
+
) -> Dict[Text, Any]:
|
|
100
|
+
message_copy = copy.deepcopy(response)
|
|
101
|
+
|
|
102
|
+
text = get_translated_text(
|
|
103
|
+
text=message_copy.pop(TEXT, None),
|
|
104
|
+
translation=message_copy.pop(KEY_TRANSLATION, {}),
|
|
105
|
+
language=language,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
buttons = get_translated_buttons(
|
|
109
|
+
buttons=message_copy.pop(BUTTONS, None), language=language
|
|
110
|
+
)
|
|
111
|
+
message_copy[TEXT] = text
|
|
112
|
+
if buttons:
|
|
113
|
+
message_copy[BUTTONS] = buttons
|
|
114
|
+
return message_copy
|
|
81
115
|
|
|
82
116
|
def generate_from_slots(
|
|
83
117
|
self,
|
|
@@ -85,12 +119,15 @@ class TemplatedNaturalLanguageGenerator(NaturalLanguageGenerator):
|
|
|
85
119
|
filled_slots: Dict[Text, Any],
|
|
86
120
|
stack_context: Dict[Text, Any],
|
|
87
121
|
output_channel: Text,
|
|
122
|
+
language: Optional[Language] = None,
|
|
88
123
|
**kwargs: Any,
|
|
89
124
|
) -> Optional[Dict[Text, Any]]:
|
|
90
125
|
"""Generate a response for the requested utter action."""
|
|
91
126
|
# Fetching a random response for the passed utter action
|
|
92
127
|
r = copy.deepcopy(
|
|
93
|
-
self._random_response_for(
|
|
128
|
+
self._random_response_for(
|
|
129
|
+
utter_action, output_channel, filled_slots, language
|
|
130
|
+
)
|
|
94
131
|
)
|
|
95
132
|
# Filling the slots in the response with placeholders and returning the response
|
|
96
133
|
if r is not None:
|
rasa/core/nlg/translate.py
CHANGED
|
@@ -23,6 +23,14 @@ def get_translated_text(
|
|
|
23
23
|
return translation.get(language_code, text)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def has_translation(
|
|
27
|
+
message: Dict[Text, Any], language: Optional[Language] = None
|
|
28
|
+
) -> bool:
|
|
29
|
+
"""Check if the message has a translation for the given language."""
|
|
30
|
+
language_code = language.code if language else None
|
|
31
|
+
return language_code in message.get(KEY_TRANSLATION, {})
|
|
32
|
+
|
|
33
|
+
|
|
26
34
|
def get_translated_buttons(
|
|
27
35
|
buttons: Optional[List[Dict[Text, Any]]], language: Optional[Language] = None
|
|
28
36
|
) -> Optional[List[Dict[Text, Any]]]:
|
|
@@ -5,12 +5,12 @@ mapping:
|
|
|
5
5
|
sequence:
|
|
6
6
|
- type: map
|
|
7
7
|
mapping:
|
|
8
|
-
regex;(^[a-zA-Z_]+[a-zA-Z0-9_]*$):
|
|
8
|
+
regex;(^[a-zA-Z_]+[a-zA-Z0-9_\-]*$):
|
|
9
9
|
type: "seq"
|
|
10
10
|
sequence:
|
|
11
11
|
- type: map
|
|
12
12
|
mapping:
|
|
13
|
-
regex;(^[a-zA-Z_]+[a-zA-Z0-9_]*$):
|
|
13
|
+
regex;(^[a-zA-Z_]+[a-zA-Z0-9_\-]*$):
|
|
14
14
|
type: any
|
|
15
15
|
|
|
16
16
|
metadata:
|
|
@@ -129,7 +129,7 @@ mapping:
|
|
|
129
129
|
type: "seq"
|
|
130
130
|
sequence:
|
|
131
131
|
- type: "str"
|
|
132
|
-
pattern: ^[a-zA-Z_]+[a-zA-Z0-9_]*$
|
|
132
|
+
pattern: ^[a-zA-Z_]+[a-zA-Z0-9_\-]*$
|
|
133
133
|
metadata:
|
|
134
134
|
type: "str"
|
|
135
135
|
pattern: ^[a-zA-Z_]+[a-zA-Z0-9_]*$
|
|
@@ -5,12 +5,12 @@ mapping:
|
|
|
5
5
|
sequence:
|
|
6
6
|
- type: map
|
|
7
7
|
mapping:
|
|
8
|
-
regex;(^[a-zA-Z_]+[a-zA-Z0-9_]*$):
|
|
8
|
+
regex;(^[a-zA-Z_]+[a-zA-Z0-9_\-]*$):
|
|
9
9
|
type: "seq"
|
|
10
10
|
sequence:
|
|
11
11
|
- type: map
|
|
12
12
|
mapping:
|
|
13
|
-
regex;(^[a-zA-Z_]+[a-zA-Z0-9_]*$):
|
|
13
|
+
regex;(^[a-zA-Z_]+[a-zA-Z0-9_\-]*$):
|
|
14
14
|
type: any
|
|
15
15
|
|
|
16
16
|
metadata:
|
|
@@ -129,7 +129,7 @@ mapping:
|
|
|
129
129
|
type: "seq"
|
|
130
130
|
sequence:
|
|
131
131
|
- type: "str"
|
|
132
|
-
pattern: ^[a-zA-Z_]+[a-zA-Z0-9_]*$
|
|
132
|
+
pattern: ^[a-zA-Z_]+[a-zA-Z0-9_\-]*$
|
|
133
133
|
metadata:
|
|
134
134
|
type: "str"
|
|
135
135
|
pattern: ^[a-zA-Z_]+[a-zA-Z0-9_]*$
|
rasa/model_manager/model_api.py
CHANGED
|
@@ -571,7 +571,7 @@ def external_blueprint() -> Blueprint:
|
|
|
571
571
|
"""Create a blueprint for the model manager API."""
|
|
572
572
|
from rasa.core.channels.socketio import SocketBlueprint
|
|
573
573
|
|
|
574
|
-
sio = AsyncServer(async_mode="sanic", cors_allowed_origins=
|
|
574
|
+
sio = AsyncServer(async_mode="sanic", cors_allowed_origins="*")
|
|
575
575
|
bp = SocketBlueprint(sio, "", "model_api_external")
|
|
576
576
|
|
|
577
577
|
create_bridge_server(sio, running_bots)
|
|
@@ -131,6 +131,13 @@ async def create_bridge_client(
|
|
|
131
131
|
structlogger.debug("model_runner.bot_message", deployment_id=deployment_id)
|
|
132
132
|
await sio.emit("bot_message", data, room=sid)
|
|
133
133
|
|
|
134
|
+
@client.event # type: ignore[misc]
|
|
135
|
+
async def error(data: Dict[str, Any]) -> None:
|
|
136
|
+
structlogger.debug(
|
|
137
|
+
"model_runner.bot_error", deployment_id=deployment_id, data=data
|
|
138
|
+
)
|
|
139
|
+
await sio.emit("error", data, room=sid)
|
|
140
|
+
|
|
134
141
|
@client.event # type: ignore[misc]
|
|
135
142
|
async def tracker(data: Dict[str, Any]) -> None:
|
|
136
143
|
await sio.emit("tracker", json.loads(data), room=sid)
|
rasa/shared/utils/common.py
CHANGED
|
@@ -373,7 +373,8 @@ def validate_environment(
|
|
|
373
373
|
importlib.import_module(p)
|
|
374
374
|
except ImportError:
|
|
375
375
|
raise MissingDependencyException(
|
|
376
|
-
f"Missing
|
|
376
|
+
f"Missing dependency for {component_name}: {p}. "
|
|
377
|
+
f"Please ensure the correct package is installed."
|
|
377
378
|
)
|
|
378
379
|
|
|
379
380
|
|
rasa/utils/licensing.py
CHANGED
|
@@ -20,7 +20,8 @@ from rasa.shared.utils.cli import print_error_and_exit
|
|
|
20
20
|
if typing.TYPE_CHECKING:
|
|
21
21
|
from rasa.core.tracker_stores.tracker_store import TrackerStore
|
|
22
22
|
|
|
23
|
-
LICENSE_ENV_VAR = "
|
|
23
|
+
LICENSE_ENV_VAR = "RASA_LICENSE"
|
|
24
|
+
LICENSE_ENV_VAR_LEGACY = "RASA_PRO_LICENSE"
|
|
24
25
|
ALGORITHM = "RS256"
|
|
25
26
|
# deepcode ignore HardcodedKey: This is a public key - not a security issue.
|
|
26
27
|
PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
|
|
@@ -265,12 +266,22 @@ class License:
|
|
|
265
266
|
|
|
266
267
|
def retrieve_license_from_env() -> Text:
|
|
267
268
|
"""Return the license found in the env var."""
|
|
269
|
+
# Check environment variables first
|
|
270
|
+
license_value = os.environ.get(LICENSE_ENV_VAR) or os.environ.get(
|
|
271
|
+
LICENSE_ENV_VAR_LEGACY
|
|
272
|
+
)
|
|
273
|
+
if license_value:
|
|
274
|
+
return license_value
|
|
275
|
+
|
|
276
|
+
# Fall back to .env file
|
|
268
277
|
stored_env_values = dotenv_values(".env")
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
278
|
+
license_value = stored_env_values.get(LICENSE_ENV_VAR) or stored_env_values.get(
|
|
279
|
+
LICENSE_ENV_VAR_LEGACY
|
|
280
|
+
)
|
|
281
|
+
if license_value:
|
|
282
|
+
return license_value
|
|
283
|
+
|
|
284
|
+
raise LicenseNotFoundException()
|
|
274
285
|
|
|
275
286
|
|
|
276
287
|
def is_license_expiring_soon(license: License) -> bool:
|
|
@@ -297,15 +308,15 @@ def validate_license_from_env(product_area: Text = PRODUCT_AREA) -> None:
|
|
|
297
308
|
except LicenseNotFoundException:
|
|
298
309
|
structlogger.error("license.not_found.error")
|
|
299
310
|
raise SystemExit(
|
|
300
|
-
f"A Rasa
|
|
301
|
-
f"Please set the
|
|
311
|
+
f"A Rasa license is required. "
|
|
312
|
+
f"Please set the environment variable "
|
|
302
313
|
f"`{LICENSE_ENV_VAR}` to a valid license string. "
|
|
303
314
|
)
|
|
304
315
|
except LicenseValidationException as e:
|
|
305
316
|
structlogger.error("license.validation.error", error=e)
|
|
306
317
|
raise SystemExit(
|
|
307
|
-
f"Failed to validate Rasa
|
|
308
|
-
f"which was read from
|
|
318
|
+
f"Failed to validate Rasa license "
|
|
319
|
+
f"which was read from environment variable `{LICENSE_ENV_VAR}`. "
|
|
309
320
|
f"Please ensure `{LICENSE_ENV_VAR}` is set to a valid license string. "
|
|
310
321
|
)
|
|
311
322
|
|
rasa/utils/plotting.py
CHANGED
|
@@ -99,7 +99,7 @@ def plot_confusion_matrix(
|
|
|
99
99
|
zmax = confusion_matrix.max() if len(confusion_matrix) > 0 else 1
|
|
100
100
|
plt.clf()
|
|
101
101
|
if not color_map:
|
|
102
|
-
color_map = plt.cm.Blues
|
|
102
|
+
color_map = plt.cm.get_cmap("Blues")
|
|
103
103
|
plt.imshow(
|
|
104
104
|
confusion_matrix,
|
|
105
105
|
interpolation="nearest",
|
rasa/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: rasa-pro
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.14.0.dev20250731
|
|
4
4
|
Summary: State-of-the-art open-core Conversational AI framework for Enterprises that natively leverages generative AI for effortless assistant development.
|
|
5
5
|
Keywords: nlp,machine-learning,machine-learning-library,bot,bots,botkit,rasa conversational-agents,conversational-ai,chatbot,chatbot-framework,bot-framework
|
|
6
6
|
Author: Rasa Technologies GmbH
|
|
@@ -41,11 +41,11 @@ Requires-Dist: colorhash (>=2.0,<2.1.0)
|
|
|
41
41
|
Requires-Dist: confluent-kafka (>=2.10.0,<3.0.0)
|
|
42
42
|
Requires-Dist: cryptography (>=44.0.1)
|
|
43
43
|
Requires-Dist: cvg-python-sdk (>=0.5.1,<0.6.0)
|
|
44
|
-
Requires-Dist: dask (>=2024.
|
|
44
|
+
Requires-Dist: dask (>=2024.8.0,<2024.9.0)
|
|
45
45
|
Requires-Dist: demoji (>=1.1.0,<2.0.0)
|
|
46
46
|
Requires-Dist: diskcache (>=5.6.3,<5.7.0)
|
|
47
47
|
Requires-Dist: dnspython (==2.6.1)
|
|
48
|
-
Requires-Dist: faiss-cpu (>=1.
|
|
48
|
+
Requires-Dist: faiss-cpu (>=1.11.0,<1.12.0)
|
|
49
49
|
Requires-Dist: fbmessenger (>=6.0.0,<6.1.0)
|
|
50
50
|
Requires-Dist: github3.py (>=3.2.0,<3.3.0) ; extra == "gh-release-notes"
|
|
51
51
|
Requires-Dist: gitpython (>=3.1.41,<3.2.0) ; extra == "full"
|
|
@@ -65,7 +65,7 @@ Requires-Dist: langchain (>=0.2.17,<0.3.0)
|
|
|
65
65
|
Requires-Dist: langchain-community (>=0.2.19,<0.3.0)
|
|
66
66
|
Requires-Dist: langcodes (>=3.5.0,<4.0.0)
|
|
67
67
|
Requires-Dist: litellm (>=1.69.0,<1.70.0)
|
|
68
|
-
Requires-Dist: matplotlib (>=3.
|
|
68
|
+
Requires-Dist: matplotlib (>=3.9.4,<3.10.0)
|
|
69
69
|
Requires-Dist: mattermostwrapper (>=2.2,<2.3)
|
|
70
70
|
Requires-Dist: networkx (>=3.1,<3.2)
|
|
71
71
|
Requires-Dist: numpy (>=1.26.4,<1.27.0)
|
|
@@ -99,7 +99,7 @@ Requires-Dist: pyyaml (>=6.0)
|
|
|
99
99
|
Requires-Dist: qdrant-client (>=1.9.1,<1.10.0)
|
|
100
100
|
Requires-Dist: questionary (>=1.10.0,<2.1.0)
|
|
101
101
|
Requires-Dist: randomname (>=0.2.1,<0.3.0)
|
|
102
|
-
Requires-Dist: rasa-sdk (==3.
|
|
102
|
+
Requires-Dist: rasa-sdk (==3.14.0.dev2)
|
|
103
103
|
Requires-Dist: redis (>=4.6.0,<6.0)
|
|
104
104
|
Requires-Dist: regex (>=2024.7.24,<2024.8.0)
|
|
105
105
|
Requires-Dist: requests (>=2.32.3,<2.33.0)
|
|
@@ -111,13 +111,13 @@ Requires-Dist: sanic (>=22.12,<22.13)
|
|
|
111
111
|
Requires-Dist: sanic-cors (>=2.2.0,<2.3.0)
|
|
112
112
|
Requires-Dist: sanic-jwt (>=1.8.0,<2.0.0)
|
|
113
113
|
Requires-Dist: sanic-routing (>=22.8.0,<23.0.0)
|
|
114
|
-
Requires-Dist: scikit-learn (>=1.
|
|
114
|
+
Requires-Dist: scikit-learn (>=1.6.1,<1.7.0)
|
|
115
115
|
Requires-Dist: scipy (>=1.13.1,<1.14.0)
|
|
116
116
|
Requires-Dist: sentencepiece[sentencepiece] (>=0.1.99,<0.2.0) ; extra == "transformers" or extra == "full"
|
|
117
117
|
Requires-Dist: sentry-sdk (>=2.8.0,<3)
|
|
118
118
|
Requires-Dist: setuptools (>=78.1.1,<78.2.0)
|
|
119
|
-
Requires-Dist: sklearn-crfsuite (>=0.
|
|
120
|
-
Requires-Dist: skops (>=0.
|
|
119
|
+
Requires-Dist: sklearn-crfsuite (>=0.5.0,<0.6.0)
|
|
120
|
+
Requires-Dist: skops (>=0.11.0,<0.12.0)
|
|
121
121
|
Requires-Dist: slack-sdk (>=3.27.1,<3.28.0)
|
|
122
122
|
Requires-Dist: spacy (>=3.5.4,<4.0.0) ; extra == "spacy" or extra == "full"
|
|
123
123
|
Requires-Dist: structlog (>=23.1.0,<23.2.0)
|
|
@@ -135,7 +135,7 @@ Requires-Dist: tensorflow-metal (==1.1.0) ; (sys_platform == "darwin" and platfo
|
|
|
135
135
|
Requires-Dist: tensorflow-text (==2.14.0) ; sys_platform != "win32" and platform_machine != "arm64" and platform_machine != "aarch64"
|
|
136
136
|
Requires-Dist: tensorflow_hub (>=0.13.0,<0.14.0)
|
|
137
137
|
Requires-Dist: terminaltables (>=3.1.10,<3.2.0)
|
|
138
|
-
Requires-Dist: tiktoken (>=0.
|
|
138
|
+
Requires-Dist: tiktoken (>=0.9.0,<0.10.0)
|
|
139
139
|
Requires-Dist: tqdm (>=4.66.2,<5.0.0)
|
|
140
140
|
Requires-Dist: transformers (>=4.38.2,<4.39.0) ; extra == "transformers" or extra == "full"
|
|
141
141
|
Requires-Dist: twilio (>=8.4,<8.5)
|
|
@@ -72,19 +72,19 @@ rasa/cli/studio/train.py,sha256=R5TuZztfeBwvv83Q3VpdaHtK1oo5zdt6ImbZqfvHQxc,1485
|
|
|
72
72
|
rasa/cli/studio/upload.py,sha256=9j6-OC0uSa1decsjbIrHk952sIF_NZPnIYZHvWLOy-w,1695
|
|
73
73
|
rasa/cli/telemetry.py,sha256=mNMMbcgnNPZzeF1k-khN-7lAQFnkFx75VBwtnPfPI6k,3538
|
|
74
74
|
rasa/cli/test.py,sha256=JfzBh1_TAOnd346jVikSK94bTlUA-BLSAQ7XBRvL2TQ,8901
|
|
75
|
-
rasa/cli/train.py,sha256=
|
|
75
|
+
rasa/cli/train.py,sha256=jJO_l0FZrGBNbWBkupWqSiZJVC5MWm8VFGLFx3l-WAg,9839
|
|
76
76
|
rasa/cli/utils.py,sha256=NSoKe0-9RKahthznHjckRlw-SsdquuOT2uHZx4e-J4k,17557
|
|
77
77
|
rasa/cli/visualize.py,sha256=YmRAATAfxHpgE8_PknGyM-oIujwICNzVftTzz6iLNNc,1256
|
|
78
78
|
rasa/cli/x.py,sha256=T10e6bVUx5BadZOt3JJ4T5EByiR5jJ2hv5ExXOnt9F8,6839
|
|
79
79
|
rasa/constants.py,sha256=ddT6MLksS96Jeav0waBMu3Z5yocBPgC695-IYE9EbXM,1389
|
|
80
80
|
rasa/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
81
81
|
rasa/core/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
82
|
-
rasa/core/actions/action.py,sha256=
|
|
82
|
+
rasa/core/actions/action.py,sha256=OWA0k9JzRV8Jve_RL6REcGQe5rW_Iqs5bWFdQR7jLpQ,42790
|
|
83
83
|
rasa/core/actions/action_clean_stack.py,sha256=xUP-2ipPsPAnAiwP17c-ezmHPSrV4JSUZr-eSgPQwIs,2279
|
|
84
84
|
rasa/core/actions/action_exceptions.py,sha256=hghzXYN6VeHC-O_O7WiPesCNV86ZTkHgG90ZnQcbai8,724
|
|
85
85
|
rasa/core/actions/action_hangup.py,sha256=o5iklHG-F9IcRgWis5C6AumVXznxzAV3o9zdduhozEM,994
|
|
86
86
|
rasa/core/actions/action_repeat_bot_messages.py,sha256=T7bJH0fsxFQgbkCZZ5dnPi8v18-2X9QZZLfAHmmn7WI,3466
|
|
87
|
-
rasa/core/actions/action_run_slot_rejections.py,sha256=
|
|
87
|
+
rasa/core/actions/action_run_slot_rejections.py,sha256=RSSsPRf67kcybMdMUTd55vJt5TNTAN0OZxEqn3L1zhk,7213
|
|
88
88
|
rasa/core/actions/action_trigger_chitchat.py,sha256=krOPqCXBihxOskqmm05A4mFEm4lj4ohvzuddy7rELVQ,1084
|
|
89
89
|
rasa/core/actions/action_trigger_flow.py,sha256=IydYAGafTtoY6XSgCX124xJQhzudUg8JAICstqsV3VA,3487
|
|
90
90
|
rasa/core/actions/action_trigger_search.py,sha256=QfYqnaGRCqRYJ4msYsLAbnVYW5ija_tqhCcKIN8aEfw,1064
|
|
@@ -253,7 +253,7 @@ rasa/core/channels/rest.py,sha256=LWBYBdVzOz5Vv5tZCkB1QA7LxXJFTeC87CQLAi_ZGeI,73
|
|
|
253
253
|
rasa/core/channels/rocketchat.py,sha256=hajaH6549CjEYFM5jSapw1DQKBPKTXbn7cVSuZzknmI,5999
|
|
254
254
|
rasa/core/channels/slack.py,sha256=jVsTTUu9wUjukPoIsAhbee9o0QFUMCNlQHbR8LTcMBc,24406
|
|
255
255
|
rasa/core/channels/socketio.py,sha256=ZEavmx2on9AH73cuIFSGMKn1LHJhzcQVaqrFz7SH-CE,11348
|
|
256
|
-
rasa/core/channels/studio_chat.py,sha256=
|
|
256
|
+
rasa/core/channels/studio_chat.py,sha256=OI0h-EuKDCQ2cnda_K9bJsR1baCGL_oIaiFcGNuxpQg,20927
|
|
257
257
|
rasa/core/channels/telegram.py,sha256=TKVknsk3U9tYeY1a8bzlhqkltWmZfGSOvrcmwa9qozc,12499
|
|
258
258
|
rasa/core/channels/twilio.py,sha256=2BTQpyx0b0yPpc0A2BHYfxLPgodrLGLs8nq6i3lVGAM,5906
|
|
259
259
|
rasa/core/channels/vier_cvg.py,sha256=5O4yx0TDQIMppvlCxTOzmPB60CA-vqQXqWQ7upfrTO0,13496
|
|
@@ -261,7 +261,7 @@ rasa/core/channels/voice_ready/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
|
|
|
261
261
|
rasa/core/channels/voice_ready/audiocodes.py,sha256=72Ot378Wkey4rNMKV07R5J3lePMmPpxC-I9yDH9ig1g,22059
|
|
262
262
|
rasa/core/channels/voice_ready/jambonz.py,sha256=uGvdfnbscRLTCE9UrpiH3wbdWghdNKcWx2F5bvlMdQw,4691
|
|
263
263
|
rasa/core/channels/voice_ready/jambonz_protocol.py,sha256=E9iwvitSDpVkL7BxbckczF4b0a8lWZt-3zR4Innflow,13116
|
|
264
|
-
rasa/core/channels/voice_ready/twilio_voice.py,sha256=
|
|
264
|
+
rasa/core/channels/voice_ready/twilio_voice.py,sha256=L1lkm44DzdG6mHGFr9dXEorSqajViF6yC5OSupeyLpA,16226
|
|
265
265
|
rasa/core/channels/voice_ready/utils.py,sha256=8sDUDWHOxgEuSwNDJUQ15SnRlfnuCjEOF0rsokLIGZ8,1736
|
|
266
266
|
rasa/core/channels/voice_stream/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
267
267
|
rasa/core/channels/voice_stream/asr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -270,19 +270,19 @@ rasa/core/channels/voice_stream/asr/asr_event.py,sha256=skPwrkRrcsptmeWXu9q68i4B
|
|
|
270
270
|
rasa/core/channels/voice_stream/asr/azure.py,sha256=dUFxtNVVwGM2D1VyqQ5FWeSpKwUQekMXUxWZv6tPJ7w,6114
|
|
271
271
|
rasa/core/channels/voice_stream/asr/deepgram.py,sha256=VeVMWg05uL_epGGOZbUHXeIIhoBf0bxiWMp6QwNFe0A,5920
|
|
272
272
|
rasa/core/channels/voice_stream/audio_bytes.py,sha256=3V0QQplPD-kVfebaaeVcKgV7pwIJyjnTenujVD3y3sY,340
|
|
273
|
-
rasa/core/channels/voice_stream/audiocodes.py,sha256=
|
|
274
|
-
rasa/core/channels/voice_stream/browser_audio.py,sha256=
|
|
273
|
+
rasa/core/channels/voice_stream/audiocodes.py,sha256=uZ1H93R8n2yQDNUmhA93aSYE0laOO1_3PUIWFkLhnDE,12757
|
|
274
|
+
rasa/core/channels/voice_stream/browser_audio.py,sha256=qq34v_hIw1cXx3qlX4vX2UXGeRN991pyvX-s6QyRXtU,4568
|
|
275
275
|
rasa/core/channels/voice_stream/call_state.py,sha256=fbwVbT0ddE7AjTYjx-Mq5jBMEGXanbug5wlBwstaews,899
|
|
276
|
-
rasa/core/channels/voice_stream/genesys.py,sha256
|
|
277
|
-
rasa/core/channels/voice_stream/jambonz.py,sha256=
|
|
276
|
+
rasa/core/channels/voice_stream/genesys.py,sha256=Yhwt7U5jRHAxy7bRWeP35UIY5N5t562p7LUn50X10lw,17766
|
|
277
|
+
rasa/core/channels/voice_stream/jambonz.py,sha256=oHX5TrTa7RTdEjNSeiGGRGDs3-WwW6F7p3GpUNsjfJI,8662
|
|
278
278
|
rasa/core/channels/voice_stream/tts/__init__.py,sha256=Z-EAlRRqNCXYTSvhdT_PQnxcAqN7n_buJ34iQjf7DSg,248
|
|
279
279
|
rasa/core/channels/voice_stream/tts/azure.py,sha256=RIS8wBpnX8yWM17UxUo5ko4QrxExAn16TvjX-Gn_gkc,4673
|
|
280
280
|
rasa/core/channels/voice_stream/tts/cartesia.py,sha256=cH2eHicZ_NCWtDH-cn9Chq8SSm-1agJRy-ieDJCVlD4,5407
|
|
281
281
|
rasa/core/channels/voice_stream/tts/tts_cache.py,sha256=K4S2d8zWX2h2ylYALp7IdqFSkuTIqLvho--Yt0litb4,850
|
|
282
282
|
rasa/core/channels/voice_stream/tts/tts_engine.py,sha256=JMCWGHxT8QiqKoBeI6F4RX_-Q9EEqG3vUtkgOUnlt-w,1812
|
|
283
|
-
rasa/core/channels/voice_stream/twilio_media_streams.py,sha256=
|
|
284
|
-
rasa/core/channels/voice_stream/util.py,sha256=
|
|
285
|
-
rasa/core/channels/voice_stream/voice_channel.py,sha256=
|
|
283
|
+
rasa/core/channels/voice_stream/twilio_media_streams.py,sha256=2euSk_nlcFdyZkSqtn3vpYSq_lo4emnqApgO__Fk5gU,9134
|
|
284
|
+
rasa/core/channels/voice_stream/util.py,sha256=nbr0yUl0NIn4-94VUYjPEg_NB2kadcFCq-i9rRJMv4U,2323
|
|
285
|
+
rasa/core/channels/voice_stream/voice_channel.py,sha256=0sxD7NlI1u8HV3qLHL0g3KLG3sAixY4RL650Gn8V1FU,21627
|
|
286
286
|
rasa/core/channels/webexteams.py,sha256=z_o_jnc6B7hsHpd6XorImFkF43wB4yx_kiTPKAjPSuo,4805
|
|
287
287
|
rasa/core/concurrent_lock_store.py,sha256=aAZDAYUVffCx2J8wbJ05vTE3Xd9bQ4Dx13RZmCy3ohw,8285
|
|
288
288
|
rasa/core/constants.py,sha256=dEokmEf6XkOFA_xpuwjqwNtlZv-a5Tz5dLMRc7Vu4CU,4070
|
|
@@ -311,12 +311,12 @@ rasa/core/lock_store.py,sha256=wP_0S5bBNI0cnRPVOcGNZgD8usdzw4udT4ncP6CKy14,15443
|
|
|
311
311
|
rasa/core/migrate.py,sha256=h1dOpXxmVmZlbLVGy1yOU_Obp2KzRiOiL0iuEacA0Cg,14618
|
|
312
312
|
rasa/core/nlg/__init__.py,sha256=jZuQAhOUcxO-KqqHGqICHSY3oDeXlUiGr2trQDYfG6o,240
|
|
313
313
|
rasa/core/nlg/callback.py,sha256=lxBBZdjXHS54fn_pH_YUW8ApbFOBO-kYSY5bL4gR1p0,5218
|
|
314
|
-
rasa/core/nlg/contextual_response_rephraser.py,sha256=
|
|
315
|
-
rasa/core/nlg/generator.py,sha256=
|
|
314
|
+
rasa/core/nlg/contextual_response_rephraser.py,sha256=KDjhVlQ6l7o9weZTX3tGBtMhjb066WJ7mMvDAZanN6Y,14938
|
|
315
|
+
rasa/core/nlg/generator.py,sha256=VsaxPjKgErVABiQLa9ps7fc4qwubtdYoue96ZshBnl4,11616
|
|
316
316
|
rasa/core/nlg/interpolator.py,sha256=vI2ZyeKHkHESPScCbefrcRrY6mrClI0LNwvZ1GvS5Tk,5138
|
|
317
|
-
rasa/core/nlg/response.py,sha256=
|
|
317
|
+
rasa/core/nlg/response.py,sha256=SecKyoBQjEnZr4t-Gg5fkUpkozwGT2lzswIKgD63Dac,7248
|
|
318
318
|
rasa/core/nlg/summarize.py,sha256=ZlWj7DyJSTF0SRBv73kMWS8wkPmsZgX8woZiJFkgP-c,3195
|
|
319
|
-
rasa/core/nlg/translate.py,sha256=
|
|
319
|
+
rasa/core/nlg/translate.py,sha256=ZXRvysqXGdtHBJ7x3YkW6zfmnb9DuEGHCMTL41v-M8M,2112
|
|
320
320
|
rasa/core/persistor.py,sha256=7LCZHAwCM-xrUI38aaJ5dkxJvLdJXWI1TEUKsBo4_EE,21295
|
|
321
321
|
rasa/core/policies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
322
322
|
rasa/core/policies/ensemble.py,sha256=XoHxU0jcb_io_LBOpjJffylzqtGEB7CH9ivhRyO8pDc,12960
|
|
@@ -464,7 +464,7 @@ rasa/dialogue_understanding_test/constants.py,sha256=G63FEzswDUOonTxoXQicEJwI6IC
|
|
|
464
464
|
rasa/dialogue_understanding_test/du_test_case.py,sha256=4Z5Ei21OdqN2MEHEKz-NGzzv0zuPwUkOjzNjEWQhnVA,17038
|
|
465
465
|
rasa/dialogue_understanding_test/du_test_result.py,sha256=y9U_w_5aV8bGppmUHWgbNZG-9-TQGOm2xO0w38e1eUo,19457
|
|
466
466
|
rasa/dialogue_understanding_test/du_test_runner.py,sha256=WYxtuilwX8MKVHiczWAMBLAovicxDdpR5lNmd7cs2lc,11478
|
|
467
|
-
rasa/dialogue_understanding_test/du_test_schema.yml,sha256=
|
|
467
|
+
rasa/dialogue_understanding_test/du_test_schema.yml,sha256=nxezEXfnoc-oVZXDqHRg-Yk4fkDF3t2VatRRMdSSE2o,4773
|
|
468
468
|
rasa/dialogue_understanding_test/io.py,sha256=doMboRm9G6KaxmfsOYhsa2iz8zghh4bLMa3XTIV6DC0,16250
|
|
469
469
|
rasa/dialogue_understanding_test/test_case_simulation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
470
470
|
rasa/dialogue_understanding_test/test_case_simulation/exception.py,sha256=RJV8CfoGKmfpC3d28y7IBKfmcAZSm2Vs6p0GkiCHlcc,1034
|
|
@@ -484,7 +484,7 @@ rasa/e2e_test/e2e_test_converter_prompt.jinja2,sha256=EMy-aCd7jLARHmwAuZUGT5ABnN
|
|
|
484
484
|
rasa/e2e_test/e2e_test_coverage_report.py,sha256=UGQ3np2p_gtnhl17K5y886STiX9xBn95GVuN9LGIpGY,11344
|
|
485
485
|
rasa/e2e_test/e2e_test_result.py,sha256=qVurjFC4cAWIY7rOsc-A-4nIdcnnw98TaK86-bDwI7Y,1649
|
|
486
486
|
rasa/e2e_test/e2e_test_runner.py,sha256=nNEKGopReHKYPSvhG4VRhc5wK53RsO9t3emHUqBDrcA,47979
|
|
487
|
-
rasa/e2e_test/e2e_test_schema.yml,sha256=
|
|
487
|
+
rasa/e2e_test/e2e_test_schema.yml,sha256=0WG0I3baTRc76lff3UjQ8vGRzMUoV6qcE8r9adOAlCU,5638
|
|
488
488
|
rasa/e2e_test/llm_judge_prompts/answer_relevance_prompt_template.jinja2,sha256=6Ddszg4Y6sIvhH7C1jjEAArpzke48mfCOa2KUQYbNVA,2725
|
|
489
489
|
rasa/e2e_test/llm_judge_prompts/groundedness_prompt_template.jinja2,sha256=jCgDbZvWn5fncr4zvB5UQSK1VJu9xDQtpY4B8GKtlmA,8226
|
|
490
490
|
rasa/e2e_test/pykwalify_extensions.py,sha256=OGYKIKYJXd2S0NrWknoQuijyBQaE-oMLkfV_eMRkGSM,1331
|
|
@@ -562,9 +562,9 @@ rasa/markers/validate.py,sha256=dZvMTcDK_sji9OP8JY4kUcjeIScLF93C3CKTWK8DplI,708
|
|
|
562
562
|
rasa/model.py,sha256=cAbQXvfZXBKHAj79Z0-mCy29hSSWp2KaroScgDeTfJw,3489
|
|
563
563
|
rasa/model_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
564
564
|
rasa/model_manager/config.py,sha256=8upZP4CokMBy0imiiPvINJuLW4JOQ326dPiJ041jJUI,1231
|
|
565
|
-
rasa/model_manager/model_api.py,sha256=
|
|
565
|
+
rasa/model_manager/model_api.py,sha256=uY8gC4xSwb7OxnMU0hcT5fx6bGgoTURA3r6bhpxNJdk,23855
|
|
566
566
|
rasa/model_manager/runner_service.py,sha256=CfvkmCqk-syCqTxb4u3N44WvzXuWFlpomR9SvgzIFKs,9514
|
|
567
|
-
rasa/model_manager/socket_bridge.py,sha256=
|
|
567
|
+
rasa/model_manager/socket_bridge.py,sha256=luU0EzzuM77jthUZUWobW2dMocz-TM_DGrfUSUTqozk,5554
|
|
568
568
|
rasa/model_manager/studio_jwt_auth.py,sha256=uls2QiHUlUrR3fOzZssW4UaAMJMfnPMZeV1aDmZIT0E,2645
|
|
569
569
|
rasa/model_manager/trainer_service.py,sha256=aw3tp2736fILT5bYunkERPcWR5TjjyhThBXIktJfhqU,10628
|
|
570
570
|
rasa/model_manager/utils.py,sha256=rS0ST-rJMuZOna90r_Ioz7gOkZ8r8vm4XAhzI0iUZOA,2643
|
|
@@ -766,7 +766,7 @@ rasa/shared/providers/router/_base_litellm_router_client.py,sha256=JV9lYnhIG_CWM
|
|
|
766
766
|
rasa/shared/providers/router/router_client.py,sha256=5BBEg-_JtClOVxBy1hu-HceG329PsKs-2v_qbyX_vSo,2174
|
|
767
767
|
rasa/shared/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
768
768
|
rasa/shared/utils/cli.py,sha256=Md1KOje2v_gsY9xH7T-U_aKNZaI4D2zdpyt_gehbvs8,3034
|
|
769
|
-
rasa/shared/utils/common.py,sha256=
|
|
769
|
+
rasa/shared/utils/common.py,sha256=EBXsDolfddzXfyogLHg1bmZeKX4NWRpmyKaxsN07324,12416
|
|
770
770
|
rasa/shared/utils/configs.py,sha256=fHtoIwN7wwJ7rAu9w3tpXsBhaqdBhKzrHoiz9USH4qc,3482
|
|
771
771
|
rasa/shared/utils/constants.py,sha256=Y3lnqtSMacVXS47m_G2T3QUuBIAEoMPinmNVcbCt-R8,252
|
|
772
772
|
rasa/shared/utils/health_check/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -818,11 +818,11 @@ rasa/utils/converter.py,sha256=H4LHpoAK7MXMmvNZG_uSn0gbccCJvHtsA2-6Zya4u6M,1656
|
|
|
818
818
|
rasa/utils/endpoints.py,sha256=jX9xSI_3KJ-NpzymyfaO-Zj-ISaWbA4ql2Kx3NulBvE,10905
|
|
819
819
|
rasa/utils/io.py,sha256=LIAdQQqUPA-V_mdpgeQzPDzA4rmsdZLyVKc8j_0Z70Y,7161
|
|
820
820
|
rasa/utils/json_utils.py,sha256=SKtJzzsIRCAgNEQiBvWDDm9euMRBgJ-TyvCi2tXHH1w,1689
|
|
821
|
-
rasa/utils/licensing.py,sha256=
|
|
821
|
+
rasa/utils/licensing.py,sha256=SP_jm0S1hpwPGh9bQaJviBL0Eu4xuwToObWTZRLaouQ,20768
|
|
822
822
|
rasa/utils/log_utils.py,sha256=QR0R5Ezs9xOaESluelqdikViIypXSWVxCPJmJM4Ir3E,5440
|
|
823
823
|
rasa/utils/mapper.py,sha256=CZiD3fu7-W-OJgoB1R8JaOg-Hq13TK20D-zGVNgbF18,7726
|
|
824
824
|
rasa/utils/ml_utils.py,sha256=y4Czr9GdRBj-a2npXU8ED2qC9bzw5olRyqQEmu5BB8k,4185
|
|
825
|
-
rasa/utils/plotting.py,sha256=
|
|
825
|
+
rasa/utils/plotting.py,sha256=QT30kYXQxqAL8ZECjwOOvawuWALJ_rcO3rBZY5PWF-s,12272
|
|
826
826
|
rasa/utils/sanic_error_handler.py,sha256=nDL1hyBe8DRdXyXPJFCfWOn3GzTm--UypF7OT2KCra8,1152
|
|
827
827
|
rasa/utils/singleton.py,sha256=w1-sZeBPwe84bod-CuAf8IX8sMJ36pu2UYHHm0eF3wI,565
|
|
828
828
|
rasa/utils/tensorflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -846,9 +846,9 @@ rasa/utils/train_utils.py,sha256=ClJx-6x3-h3Vt6mskacgkcCUJTMXjFPe3zAcy_DfmaU,212
|
|
|
846
846
|
rasa/utils/url_tools.py,sha256=dZ1HGkVdWTJB7zYEdwoDIrEuyX9HE5WsxKKFVsXBLE0,1218
|
|
847
847
|
rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
|
|
848
848
|
rasa/validator.py,sha256=fhRlHQvuBkiup0FnNYmwRmqQwC3QpdCJt0TuvW4jMaI,83125
|
|
849
|
-
rasa/version.py,sha256=
|
|
850
|
-
rasa_pro-3.
|
|
851
|
-
rasa_pro-3.
|
|
852
|
-
rasa_pro-3.
|
|
853
|
-
rasa_pro-3.
|
|
854
|
-
rasa_pro-3.
|
|
849
|
+
rasa/version.py,sha256=TpGTo1xtM7rqFKmycAPbtN3f-ewZGifwUf7yNFsBwMQ,129
|
|
850
|
+
rasa_pro-3.14.0.dev20250731.dist-info/METADATA,sha256=jghym_xJcpu6LAhggqx7pIVEb3X19QIUSga6DIfQLBk,10575
|
|
851
|
+
rasa_pro-3.14.0.dev20250731.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
|
|
852
|
+
rasa_pro-3.14.0.dev20250731.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
853
|
+
rasa_pro-3.14.0.dev20250731.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
|
|
854
|
+
rasa_pro-3.14.0.dev20250731.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|