rasa-pro 3.13.4__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/inspector/dist/assets/{arc-371401b1.js → arc-0b11fe30.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-3f126156.js → blockDiagram-38ab4fdb-9eef30a7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-12f22eb7.js → c4Diagram-3d4e48cf-03e94f28.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-51d02e9e.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-03b1d386.js → classDiagram-70f12bd4-95c09eba.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-84f69d63.js → classDiagram-v2-f2320105-38e8446c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-cc738fa6.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-ca47fd38.js → createText-2e5e7dd3-57dc3038.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-f837ca8a.js → edges-e0da2a9e-4bac0545.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-8717ac54.js → erDiagram-9861fffd-81795c90.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-94f38b83.js → flowDb-956e92f1-89489ae6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-b616f9fb.js → flowDiagram-66a62f08-cd152627.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-0c716443.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-f5d24bb8.js → flowchart-elk-definition-4a651766-3da369bc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-b43ba8d9.js → ganttDiagram-c361ad54-85ec16f8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-c3aafaa5.js → gitGraphDiagram-72cf32ee-495bc140.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-0d0a2c10.js → graph-1ec4d266.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-58ea0305.js → index-3862675e-0a0e97c9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-cce6f8a1.js → index-c804b295.js} +148 -148
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b8f60461.js → infoDiagram-f8f76790-4d54bcde.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-95be5545.js → journeyDiagram-49397b02-dc097114.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-da885b9b.js → layout-1a08981e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-f1c817d3.js → line-95f7f1d3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-d42801e6.js → linear-97e69543.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-a38923a6.js → mindmap-definition-fc14e90a-8c71ff03.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-ca6e71e9.js → pieDiagram-8a3498a8-f14c71c7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-b290dae9.js → quadrantDiagram-120e2f19-f1d3c9ff.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-03f02ceb.js → requirementDiagram-deff3bca-bfa2412f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-c49eee40.js → sankeyDiagram-04a897e0-53f2c97b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-b2cd6a3d.js → sequenceDiagram-704730f1-319d7c0e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-e53a2028.js → stateDiagram-587899a1-76a09418.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-e1982a03.js → stateDiagram-v2-d93cdb3a-a67f15d4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-d0226ca5.js → styles-6aaf32cf-0654e7c3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-0e21dc00.js → styles-9a916d00-1394bb9d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-9588494e.js → styles-c10674c1-e4c5bdae.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-be478d4f.js → svgDrawCommon-08f97a94-50957104.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-74631749.js → timeline-definition-85554ec2-b0885a6a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-a043552f.js → xychartDiagram-e933f94c-79e6541a.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/package.json +1 -1
- rasa/core/channels/inspector/yarn.lock +4 -4
- 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/commands/correct_slots_command.py +38 -0
- rasa/dialogue_understanding/processor/command_processor.py +127 -54
- rasa/dialogue_understanding/stack/utils.py +13 -3
- 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.4.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/METADATA +9 -9
- {rasa_pro-3.13.4.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/RECORD +73 -73
- rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +0 -1
- {rasa_pro-3.13.4.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.4.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.4.dist-info → rasa_pro-3.14.0.dev20250731.dist-info}/entry_points.txt +0 -0
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]]]:
|
|
@@ -269,6 +269,20 @@ class CorrectSlotsCommand(Command):
|
|
|
269
269
|
return []
|
|
270
270
|
|
|
271
271
|
structlogger.debug("correct_slots_command", command=self)
|
|
272
|
+
|
|
273
|
+
# check if the correct slot is referring to a slot of a flow on the stack
|
|
274
|
+
# the slot also needs to be part of a collect step in any of those flows
|
|
275
|
+
# if this is not the case, we don't want to correct the slot
|
|
276
|
+
for slot in self.corrected_slots:
|
|
277
|
+
if not self.should_correct_slot(slot, tracker, all_flows):
|
|
278
|
+
structlogger.warning(
|
|
279
|
+
"correct_slots_command.skip_correct_slot",
|
|
280
|
+
correct_slot=slot,
|
|
281
|
+
reason="The slot is not part of a collect step in any of the flows "
|
|
282
|
+
"on the stack. Skipping correction.",
|
|
283
|
+
)
|
|
284
|
+
return []
|
|
285
|
+
|
|
272
286
|
proposed_slots = self.corrected_slots_dict(tracker)
|
|
273
287
|
|
|
274
288
|
correction_frame = self.create_correction_frame(
|
|
@@ -293,3 +307,27 @@ class CorrectSlotsCommand(Command):
|
|
|
293
307
|
return False
|
|
294
308
|
|
|
295
309
|
return True
|
|
310
|
+
|
|
311
|
+
def should_correct_slot(
|
|
312
|
+
self, slot: CorrectedSlot, tracker: DialogueStateTracker, all_flows: FlowsList
|
|
313
|
+
) -> bool:
|
|
314
|
+
"""Checks if the slot should be corrected.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
slot: The slot to check.
|
|
318
|
+
tracker: The tracker.
|
|
319
|
+
all_flows: All flows in the assistant.
|
|
320
|
+
"""
|
|
321
|
+
# get all flows on the stack
|
|
322
|
+
flows_on_stack = utils.user_flows_on_the_stack(tracker.stack)
|
|
323
|
+
|
|
324
|
+
# check if the slot is part of a collect step in any of the flows on the stack
|
|
325
|
+
for flow_id in flows_on_stack:
|
|
326
|
+
flow = all_flows.flow_by_id(flow_id)
|
|
327
|
+
if flow is None:
|
|
328
|
+
continue
|
|
329
|
+
for collect_step in flow.get_collect_steps():
|
|
330
|
+
if collect_step.collect == slot.name:
|
|
331
|
+
return True
|
|
332
|
+
|
|
333
|
+
return False
|
|
@@ -37,7 +37,6 @@ from rasa.dialogue_understanding.stack.frames import (
|
|
|
37
37
|
BaseFlowStackFrame,
|
|
38
38
|
)
|
|
39
39
|
from rasa.dialogue_understanding.stack.utils import (
|
|
40
|
-
filled_slots_for_active_flow,
|
|
41
40
|
top_flow_frame,
|
|
42
41
|
top_user_flow_frame,
|
|
43
42
|
)
|
|
@@ -125,7 +124,8 @@ def validate_state_of_commands(commands: List[Command]) -> None:
|
|
|
125
124
|
# check that there is only at max one cancel flow command
|
|
126
125
|
if sum(isinstance(c, CancelFlowCommand) for c in commands) > 1:
|
|
127
126
|
structlogger.error(
|
|
128
|
-
"command_processor.validate_state_of_commands.
|
|
127
|
+
"command_processor.validate_state_of_commands."
|
|
128
|
+
"multiple_cancel_flow_commands",
|
|
129
129
|
commands=[command.__class__.__name__ for command in commands],
|
|
130
130
|
)
|
|
131
131
|
raise ValueError("There can only be one cancel flow command.")
|
|
@@ -136,7 +136,8 @@ def validate_state_of_commands(commands: List[Command]) -> None:
|
|
|
136
136
|
]
|
|
137
137
|
if free_form_answer_commands != commands[: len(free_form_answer_commands)]:
|
|
138
138
|
structlogger.error(
|
|
139
|
-
"command_processor.validate_state_of_commands.
|
|
139
|
+
"command_processor.validate_state_of_commands."
|
|
140
|
+
"free_form_answer_commands_not_at_beginning",
|
|
140
141
|
commands=[command.__class__.__name__ for command in commands],
|
|
141
142
|
)
|
|
142
143
|
raise ValueError(
|
|
@@ -146,7 +147,8 @@ def validate_state_of_commands(commands: List[Command]) -> None:
|
|
|
146
147
|
# check that there is at max only one correctslots command
|
|
147
148
|
if sum(isinstance(c, CorrectSlotsCommand) for c in commands) > 1:
|
|
148
149
|
structlogger.error(
|
|
149
|
-
"command_processor.validate_state_of_commands.
|
|
150
|
+
"command_processor.validate_state_of_commands."
|
|
151
|
+
"multiple_correct_slots_commands",
|
|
150
152
|
commands=[command.__class__.__name__ for command in commands],
|
|
151
153
|
)
|
|
152
154
|
raise ValueError("There can only be one correct slots command.")
|
|
@@ -230,11 +232,9 @@ def execute_commands(
|
|
|
230
232
|
|
|
231
233
|
events: List[Event] = flow_hash_events
|
|
232
234
|
|
|
233
|
-
# commands
|
|
234
|
-
#
|
|
235
|
-
|
|
236
|
-
# and then pushing the commands onto the stack in the reversed order.
|
|
237
|
-
reversed_commands = list(reversed(commands))
|
|
235
|
+
# reorder commands: in case there is no active flow, we want to make sure to
|
|
236
|
+
# run the start flow commands first.
|
|
237
|
+
final_commands = reorder_commands(commands, tracker)
|
|
238
238
|
|
|
239
239
|
# we need to keep track of the ValidateSlotPatternFlowStackFrame that
|
|
240
240
|
# should be pushed onto the stack before executing the StartFlowCommands.
|
|
@@ -245,7 +245,7 @@ def execute_commands(
|
|
|
245
245
|
|
|
246
246
|
validate_state_of_commands(commands)
|
|
247
247
|
|
|
248
|
-
for command in
|
|
248
|
+
for command in final_commands:
|
|
249
249
|
new_events = command.run_command_on_tracker(
|
|
250
250
|
tracker, all_flows, original_tracker
|
|
251
251
|
)
|
|
@@ -398,11 +398,11 @@ def clean_up_commands(
|
|
|
398
398
|
"""
|
|
399
399
|
domain = domain if domain else Domain.empty()
|
|
400
400
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
#
|
|
404
|
-
slots_so_far
|
|
405
|
-
|
|
401
|
+
# we consider all slots that were set in the tracker for potential corrections
|
|
402
|
+
# in the correct_slot_command we will check if a slot should actually be
|
|
403
|
+
# corrected
|
|
404
|
+
slots_so_far = set(
|
|
405
|
+
[event.key for event in tracker.events if isinstance(event, SlotSet)]
|
|
406
406
|
)
|
|
407
407
|
|
|
408
408
|
clean_commands: List[Command] = []
|
|
@@ -444,7 +444,8 @@ def clean_up_commands(
|
|
|
444
444
|
# drop a start flow command if the starting flow is equal
|
|
445
445
|
# to the currently active flow
|
|
446
446
|
structlogger.debug(
|
|
447
|
-
"command_processor.clean_up_commands.
|
|
447
|
+
"command_processor.clean_up_commands."
|
|
448
|
+
"skip_command_flow_already_active",
|
|
448
449
|
command=command,
|
|
449
450
|
)
|
|
450
451
|
continue
|
|
@@ -475,7 +476,8 @@ def clean_up_commands(
|
|
|
475
476
|
clean_commands = clean_up_clarify_command(clean_commands, commands, command)
|
|
476
477
|
if command not in clean_commands:
|
|
477
478
|
structlogger.debug(
|
|
478
|
-
"command_processor.clean_up_commands.
|
|
479
|
+
"command_processor.clean_up_commands."
|
|
480
|
+
"drop_clarify_given_other_commands",
|
|
479
481
|
command=command,
|
|
480
482
|
)
|
|
481
483
|
else:
|
|
@@ -577,10 +579,10 @@ def clean_up_slot_command(
|
|
|
577
579
|
The cleaned up commands.
|
|
578
580
|
"""
|
|
579
581
|
stack = tracker.stack
|
|
580
|
-
|
|
581
582
|
resulting_commands = commands_so_far[:]
|
|
582
|
-
|
|
583
583
|
slot = tracker.slots.get(command.name)
|
|
584
|
+
|
|
585
|
+
# if the slot is not in the domain, we cannot set it
|
|
584
586
|
if slot is None:
|
|
585
587
|
structlogger.debug(
|
|
586
588
|
"command_processor.clean_up_slot_command.skip_command_slot_not_in_domain",
|
|
@@ -593,6 +595,7 @@ def clean_up_slot_command(
|
|
|
593
595
|
)
|
|
594
596
|
return resulting_commands
|
|
595
597
|
|
|
598
|
+
# check if the slot should be set by the command
|
|
596
599
|
if not should_slot_be_set(slot, command, resulting_commands):
|
|
597
600
|
structlogger.debug(
|
|
598
601
|
"command_processor.clean_up_slot_command.skip_command.extractor_"
|
|
@@ -618,6 +621,7 @@ def clean_up_slot_command(
|
|
|
618
621
|
|
|
619
622
|
return resulting_commands
|
|
620
623
|
|
|
624
|
+
# check if the slot can be corrected by the LLM
|
|
621
625
|
if (
|
|
622
626
|
slot.filled_by == SetSlotExtractor.NLU.value
|
|
623
627
|
and command.extractor == SetSlotExtractor.LLM.value
|
|
@@ -646,49 +650,71 @@ def clean_up_slot_command(
|
|
|
646
650
|
resulting_commands.append(command)
|
|
647
651
|
return resulting_commands
|
|
648
652
|
|
|
649
|
-
if (
|
|
650
|
-
slot
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
"command_processor.clean_up_slot_command.skip_command_slot_already_set",
|
|
655
|
-
command=command,
|
|
656
|
-
)
|
|
653
|
+
if should_slot_be_corrected(command, tracker, stack, all_flows):
|
|
654
|
+
# if the slot was already set before, we need to convert it into
|
|
655
|
+
# a correction
|
|
656
|
+
return convert_set_slot_to_correction(command, resulting_commands)
|
|
657
|
+
else:
|
|
657
658
|
return resulting_commands
|
|
658
659
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
already_corrected_slots = top.corrected_slots
|
|
662
|
-
else:
|
|
663
|
-
already_corrected_slots = {}
|
|
660
|
+
resulting_commands.append(command)
|
|
661
|
+
return resulting_commands
|
|
664
662
|
|
|
665
|
-
if command.name in already_corrected_slots and str(
|
|
666
|
-
already_corrected_slots[command.name]
|
|
667
|
-
) == str(command.value):
|
|
668
|
-
structlogger.debug(
|
|
669
|
-
"command_processor.clean_up_slot_command"
|
|
670
|
-
".skip_command_slot_already_corrected",
|
|
671
|
-
command=command,
|
|
672
|
-
)
|
|
673
|
-
return resulting_commands
|
|
674
663
|
|
|
664
|
+
def should_slot_be_corrected(
|
|
665
|
+
command: SetSlotCommand,
|
|
666
|
+
tracker: DialogueStateTracker,
|
|
667
|
+
stack: DialogueStack,
|
|
668
|
+
all_flows: FlowsList,
|
|
669
|
+
) -> bool:
|
|
670
|
+
"""Check if a slot should be corrected."""
|
|
671
|
+
if (slot := tracker.slots.get(command.name)) is not None and str(slot.value) == str(
|
|
672
|
+
command.value
|
|
673
|
+
):
|
|
674
|
+
# the slot is already set to the same value, we don't need to set it again
|
|
675
675
|
structlogger.debug(
|
|
676
|
-
"command_processor.clean_up_slot_command.
|
|
676
|
+
"command_processor.clean_up_slot_command.skip_command_slot_already_set",
|
|
677
677
|
command=command,
|
|
678
678
|
)
|
|
679
|
+
return False
|
|
679
680
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
if isinstance(c, CorrectSlotsCommand):
|
|
684
|
-
c.corrected_slots.append(corrected_slot)
|
|
685
|
-
break
|
|
686
|
-
else:
|
|
687
|
-
resulting_commands.append(
|
|
688
|
-
CorrectSlotsCommand(corrected_slots=[corrected_slot])
|
|
689
|
-
)
|
|
681
|
+
top = top_flow_frame(stack)
|
|
682
|
+
if isinstance(top, CorrectionPatternFlowStackFrame):
|
|
683
|
+
already_corrected_slots = top.corrected_slots
|
|
690
684
|
else:
|
|
691
|
-
|
|
685
|
+
already_corrected_slots = {}
|
|
686
|
+
|
|
687
|
+
if command.name in already_corrected_slots and str(
|
|
688
|
+
already_corrected_slots[command.name]
|
|
689
|
+
) == str(command.value):
|
|
690
|
+
structlogger.debug(
|
|
691
|
+
"command_processor.clean_up_slot_command"
|
|
692
|
+
".skip_command_slot_already_corrected",
|
|
693
|
+
command=command,
|
|
694
|
+
)
|
|
695
|
+
return False
|
|
696
|
+
|
|
697
|
+
return True
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
def convert_set_slot_to_correction(
|
|
701
|
+
command: SetSlotCommand,
|
|
702
|
+
resulting_commands: List[Command],
|
|
703
|
+
) -> List[Command]:
|
|
704
|
+
"""Convert a set slot command to a correction command."""
|
|
705
|
+
structlogger.debug(
|
|
706
|
+
"command_processor.convert_set_slot_to_correction",
|
|
707
|
+
command=command,
|
|
708
|
+
)
|
|
709
|
+
|
|
710
|
+
# Group all corrections into one command
|
|
711
|
+
corrected_slot = CorrectedSlot(command.name, command.value, command.extractor)
|
|
712
|
+
for c in resulting_commands:
|
|
713
|
+
if isinstance(c, CorrectSlotsCommand):
|
|
714
|
+
c.corrected_slots.append(corrected_slot)
|
|
715
|
+
break
|
|
716
|
+
else:
|
|
717
|
+
resulting_commands.append(CorrectSlotsCommand(corrected_slots=[corrected_slot]))
|
|
692
718
|
|
|
693
719
|
return resulting_commands
|
|
694
720
|
|
|
@@ -747,7 +773,8 @@ def clean_up_chitchat_command(
|
|
|
747
773
|
0, CannotHandleCommand(RASA_PATTERN_CANNOT_HANDLE_CHITCHAT)
|
|
748
774
|
)
|
|
749
775
|
structlogger.warn(
|
|
750
|
-
"command_processor.clean_up_chitchat_command.
|
|
776
|
+
"command_processor.clean_up_chitchat_command."
|
|
777
|
+
"replace_chitchat_answer_with_cannot_handle",
|
|
751
778
|
command=resulting_commands[0], # no PII
|
|
752
779
|
pattern_chitchat_uses_action_trigger_chitchat=has_action_trigger_chitchat,
|
|
753
780
|
defined_intentless_policy_in_config=defines_intentless_policy,
|
|
@@ -850,3 +877,49 @@ def filter_cannot_handle_command(
|
|
|
850
877
|
for command in clean_commands
|
|
851
878
|
if not isinstance(command, CannotHandleCommand)
|
|
852
879
|
]
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
def reorder_commands(
|
|
883
|
+
commands: List[Command], tracker: DialogueStateTracker
|
|
884
|
+
) -> List[Command]:
|
|
885
|
+
"""Reorder commands.
|
|
886
|
+
|
|
887
|
+
In case there is no active flow, we want to make sure to run the start flow
|
|
888
|
+
commands first.
|
|
889
|
+
"""
|
|
890
|
+
reordered_commands = commands
|
|
891
|
+
|
|
892
|
+
top_flow_frame = top_user_flow_frame(tracker.stack)
|
|
893
|
+
|
|
894
|
+
if top_flow_frame is None:
|
|
895
|
+
# no active flow, we want to make sure to run the start flow commands first
|
|
896
|
+
start_flow_commands: List[Command] = [
|
|
897
|
+
command for command in commands if isinstance(command, StartFlowCommand)
|
|
898
|
+
]
|
|
899
|
+
|
|
900
|
+
# if there are no start flow commands, we can return the commands as they are
|
|
901
|
+
if not start_flow_commands:
|
|
902
|
+
reordered_commands = commands
|
|
903
|
+
|
|
904
|
+
# if there is just one start flow command, we want to run it first
|
|
905
|
+
# as the order of commands is reserved later,
|
|
906
|
+
# we need to add it to the end of the list
|
|
907
|
+
elif len(start_flow_commands) == 1:
|
|
908
|
+
reordered_commands = [
|
|
909
|
+
command for command in commands if command not in start_flow_commands
|
|
910
|
+
] + start_flow_commands
|
|
911
|
+
|
|
912
|
+
# if there are multiple start flow commands,
|
|
913
|
+
# we just make sure to move the first start flow command to the end of the list
|
|
914
|
+
# (due to the reverse execution order of commands) and keep the other commands
|
|
915
|
+
# as they are.
|
|
916
|
+
else:
|
|
917
|
+
reordered_commands = [
|
|
918
|
+
command for command in commands if command != start_flow_commands[-1]
|
|
919
|
+
] + [start_flow_commands[-1]]
|
|
920
|
+
|
|
921
|
+
# commands need to be reversed to make sure they end up in the right order
|
|
922
|
+
# on the stack. e.g. if there multiple start flow commands, the first one
|
|
923
|
+
# should be on top of the stack. this is achieved by reversing the list
|
|
924
|
+
# and then pushing the commands onto the stack in the reversed order.
|
|
925
|
+
return list(reversed(reordered_commands))
|
|
@@ -209,14 +209,24 @@ def get_collect_steps_excluding_ask_before_filling_for_active_flow(
|
|
|
209
209
|
All collect steps that are part of the current active flow,
|
|
210
210
|
excluding the collect steps that have to be asked before filling.
|
|
211
211
|
"""
|
|
212
|
-
|
|
212
|
+
active_primary_frame = top_user_flow_frame(dialogue_stack)
|
|
213
|
+
any_active_frame = top_user_flow_frame(
|
|
213
214
|
dialogue_stack, ignore_call_and_link_frames=False
|
|
214
215
|
)
|
|
215
|
-
|
|
216
|
+
|
|
217
|
+
active_flows = []
|
|
218
|
+
if any_active_frame:
|
|
219
|
+
active_flows.append(any_active_frame.flow(all_flows))
|
|
220
|
+
|
|
221
|
+
if active_primary_frame and active_primary_frame != any_active_frame:
|
|
222
|
+
active_flows.append(active_primary_frame.flow(all_flows))
|
|
223
|
+
|
|
224
|
+
if not active_flows:
|
|
216
225
|
return set()
|
|
217
|
-
|
|
226
|
+
|
|
218
227
|
return set(
|
|
219
228
|
step.collect
|
|
229
|
+
for active_flow in active_flows
|
|
220
230
|
for step in active_flow.get_collect_steps()
|
|
221
231
|
if not step.ask_before_filling
|
|
222
232
|
)
|
|
@@ -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)
|