rasa-pro 3.11.17__py3-none-any.whl → 3.11.19__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rasa-pro might be problematic. Click here for more details.

Files changed (54) hide show
  1. rasa/core/channels/inspector/dist/assets/{arc-f09fea11.js → arc-6f1cf469.js} +1 -1
  2. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-95518007.js → blockDiagram-38ab4fdb-e4687a7a.js} +1 -1
  3. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-c91a4a08.js → c4Diagram-3d4e48cf-350db3c4.js} +1 -1
  4. rasa/core/channels/inspector/dist/assets/channel-e01523b7.js +1 -0
  5. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-27f7869b.js → classDiagram-70f12bd4-87791d92.js} +1 -1
  6. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-1ab94cdb.js → classDiagram-v2-f2320105-325a055a.js} +1 -1
  7. rasa/core/channels/inspector/dist/assets/clone-3bfaf7a0.js +1 -0
  8. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-a7900089.js → createText-2e5e7dd3-be863ae0.js} +1 -1
  9. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-3d5b2697.js → edges-e0da2a9e-ced68061.js} +1 -1
  10. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-443cc11b.js → erDiagram-9861fffd-60684f40.js} +1 -1
  11. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-8a6f8c52.js → flowDb-956e92f1-664e800c.js} +1 -1
  12. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-06a0b4f3.js → flowDiagram-66a62f08-6ebc9040.js} +1 -1
  13. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-ce3f0138.js +1 -0
  14. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-7a01e0b5.js → flowchart-elk-definition-4a651766-3a139e6d.js} +1 -1
  15. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-5f1289f2.js → ganttDiagram-c361ad54-b4446b93.js} +1 -1
  16. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-44409666.js → gitGraphDiagram-72cf32ee-0ca05d79.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/{graph-3c393c89.js → graph-d55c7150.js} +1 -1
  18. rasa/core/channels/inspector/dist/assets/{index-3862675e-4d0c4142.js → index-3862675e-21ec23d0.js} +1 -1
  19. rasa/core/channels/inspector/dist/assets/{index-b208b2c3.js → index-397b9bf3.js} +148 -148
  20. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-ae0fa7ff.js → infoDiagram-f8f76790-1dbec276.js} +1 -1
  21. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-5c3b08cc.js → journeyDiagram-49397b02-c59ccb68.js} +1 -1
  22. rasa/core/channels/inspector/dist/assets/{layout-b24c95cb.js → layout-084d6acb.js} +1 -1
  23. rasa/core/channels/inspector/dist/assets/{line-999a77c5.js → line-7e3445bc.js} +1 -1
  24. rasa/core/channels/inspector/dist/assets/{linear-81a792fd.js → linear-37acf20b.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-c574f712.js → mindmap-definition-fc14e90a-053067ef.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-1919891d.js → pieDiagram-8a3498a8-00feec2e.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-26e43d09.js → quadrantDiagram-120e2f19-7b0f9725.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-f4b22985.js → requirementDiagram-deff3bca-c23f6699.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-b957b472.js → sankeyDiagram-04a897e0-7d7264d7.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-1d8ca073.js → sequenceDiagram-704730f1-78c3fce6.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-c67b1b71.js → stateDiagram-587899a1-4a241b87.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-ee820f55.js → stateDiagram-v2-d93cdb3a-5c57975b.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-b162bdf3.js → styles-6aaf32cf-af1e4802.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-67a7b254.js → styles-9a916d00-1a8391b1.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-81a8ac73.js → styles-c10674c1-bbd035f8.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-ede42905.js → svgDrawCommon-08f97a94-e8aa007c.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-b0f41635.js → timeline-definition-85554ec2-adc8097c.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-d715dfb0.js → xychartDiagram-e933f94c-3dd24cea.js} +1 -1
  39. rasa/core/channels/inspector/dist/index.html +1 -1
  40. rasa/core/channels/inspector/package.json +4 -3
  41. rasa/core/channels/inspector/yarn.lock +12 -12
  42. rasa/core/policies/enterprise_search_policy.py +1 -1
  43. rasa/dialogue_understanding/commands/correct_slots_command.py +39 -11
  44. rasa/dialogue_understanding/processor/command_processor.py +153 -57
  45. rasa/dialogue_understanding/stack/utils.py +13 -3
  46. rasa/version.py +1 -1
  47. {rasa_pro-3.11.17.dist-info → rasa_pro-3.11.19.dist-info}/METADATA +4 -4
  48. {rasa_pro-3.11.17.dist-info → rasa_pro-3.11.19.dist-info}/RECORD +51 -51
  49. rasa/core/channels/inspector/dist/assets/channel-cc7720dc.js +0 -1
  50. rasa/core/channels/inspector/dist/assets/clone-3688e1f7.js +0 -1
  51. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-5055ec2d.js +0 -1
  52. {rasa_pro-3.11.17.dist-info → rasa_pro-3.11.19.dist-info}/NOTICE +0 -0
  53. {rasa_pro-3.11.17.dist-info → rasa_pro-3.11.19.dist-info}/WHEEL +0 -0
  54. {rasa_pro-3.11.17.dist-info → rasa_pro-3.11.19.dist-info}/entry_points.txt +0 -0
@@ -7,10 +7,10 @@
7
7
  resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf"
8
8
  integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
9
9
 
10
- "@adobe/css-tools@^4.3.1":
11
- version "4.3.1"
12
- resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.1.tgz#abfccb8ca78075a2b6187345c26243c1a0842f28"
13
- integrity sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==
10
+ "@adobe/css-tools@^4.3.1", "@adobe/css-tools@^4.3.2":
11
+ version "4.4.3"
12
+ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.3.tgz#beebbefb0264fdeb32d3052acae0e0d94315a9a2"
13
+ integrity sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==
14
14
 
15
15
  "@ampproject/remapping@^2.2.0":
16
16
  version "2.2.1"
@@ -2295,10 +2295,10 @@ available-typed-arrays@^1.0.5:
2295
2295
  resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
2296
2296
  integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
2297
2297
 
2298
- axios@1.7.4:
2299
- version "1.7.4"
2300
- resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
2301
- integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
2298
+ axios@1.8.2:
2299
+ version "1.8.2"
2300
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.2.tgz#fabe06e241dfe83071d4edfbcaa7b1c3a40f7979"
2301
+ integrity sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==
2302
2302
  dependencies:
2303
2303
  follow-redirects "^1.15.6"
2304
2304
  form-data "^4.0.0"
@@ -6054,10 +6054,10 @@ v8-to-istanbul@^9.0.1:
6054
6054
  "@types/istanbul-lib-coverage" "^2.0.1"
6055
6055
  convert-source-map "^2.0.0"
6056
6056
 
6057
- vite@4.5.2:
6058
- version "4.5.2"
6059
- resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.2.tgz#d6ea8610e099851dad8c7371599969e0f8b97e82"
6060
- integrity sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==
6057
+ vite@4.5.12:
6058
+ version "4.5.12"
6059
+ resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.12.tgz#48f48dbcf789722765e91bc32a99cb66c628eadc"
6060
+ integrity sha512-qrMwavANtSz91nDy3zEiUHMtL09x0mniQsSMvDkNxuCBM1W5vriJ22hEmwTth6DhLSWsZnHBT0yHFAQXt6efGA==
6061
6061
  dependencies:
6062
6062
  esbuild "^0.18.10"
6063
6063
  postcss "^8.4.27"
@@ -706,7 +706,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
706
706
  )
707
707
  print_error_and_exit(error_message)
708
708
 
709
- docs = glob.glob(os.path.join(docs_folder, "*.txt"), recursive=True)
709
+ docs = glob.glob(os.path.join(docs_folder, "**", "*.txt"), recursive=True)
710
710
  if not docs or len(docs) < 1:
711
711
  error_message = (
712
712
  f"Document source directory is empty: '{docs_folder}'. "
@@ -225,16 +225,6 @@ class CorrectSlotsCommand(Command):
225
225
  proposed_slots, all_flows, tracker
226
226
  )
227
227
 
228
- if not earliest_collect and not is_reset_only:
229
- # if we could not find any step in the flow, where the slots were
230
- # previously set, and we also don't want to reset the slots, do
231
- # not correct the slots.
232
- structlogger.debug(
233
- "command_executor.skip_correction",
234
- is_reset_only=is_reset_only,
235
- )
236
- return None
237
-
238
228
  return CorrectionPatternFlowStackFrame(
239
229
  is_reset_only=is_reset_only,
240
230
  corrected_slots=proposed_slots,
@@ -270,7 +260,21 @@ class CorrectSlotsCommand(Command):
270
260
  )
271
261
  return []
272
262
 
273
- structlogger.debug("command_executor.correct_slots", command=self)
263
+ structlogger.debug("correct_slots_command", command=self)
264
+
265
+ # check if the correct slot is referring to a slot of a flow on the stack
266
+ # the slot also needs to be part of a collect step in any of those flows
267
+ # if this is not the case, we don't want to correct the slot
268
+ for slot in self.corrected_slots:
269
+ if not self.should_correct_slot(slot, tracker, all_flows):
270
+ structlogger.warning(
271
+ "correct_slots_command.skip_correct_slot",
272
+ correct_slot=slot,
273
+ reason="The slot is not part of a collect step in any of the flows "
274
+ "on the stack. Skipping correction.",
275
+ )
276
+ return []
277
+
274
278
  proposed_slots = self.corrected_slots_dict(tracker)
275
279
 
276
280
  correction_frame = self.create_correction_frame(
@@ -295,3 +299,27 @@ class CorrectSlotsCommand(Command):
295
299
  return False
296
300
 
297
301
  return True
302
+
303
+ def should_correct_slot(
304
+ self, slot: CorrectedSlot, tracker: DialogueStateTracker, all_flows: FlowsList
305
+ ) -> bool:
306
+ """Checks if the slot should be corrected.
307
+
308
+ Args:
309
+ slot: The slot to check.
310
+ tracker: The tracker.
311
+ all_flows: All flows in the assistant.
312
+ """
313
+ # get all flows on the stack
314
+ flows_on_stack = utils.user_flows_on_the_stack(tracker.stack)
315
+
316
+ # check if the slot is part of a collect step in any of the flows on the stack
317
+ for flow_id in flows_on_stack:
318
+ flow = all_flows.flow_by_id(flow_id)
319
+ if flow is None:
320
+ continue
321
+ for collect_step in flow.get_collect_steps():
322
+ if collect_step.collect == slot.name:
323
+ return True
324
+
325
+ return False
@@ -31,8 +31,9 @@ from rasa.dialogue_understanding.stack.frames import (
31
31
  BaseFlowStackFrame,
32
32
  )
33
33
  from rasa.dialogue_understanding.stack.utils import (
34
- filled_slots_for_active_flow,
35
34
  top_flow_frame,
35
+ filled_slots_for_active_flow,
36
+ top_user_flow_frame,
36
37
  )
37
38
  from rasa.engine.graph import ExecutionContext
38
39
  from rasa.shared.constants import (
@@ -113,8 +114,9 @@ def validate_state_of_commands(commands: List[Command]) -> None:
113
114
  # check that there is only at max one cancel flow command
114
115
  if sum(isinstance(c, CancelFlowCommand) for c in commands) > 1:
115
116
  structlogger.error(
116
- "command_processor.validate_state_of_commands.multiple_cancel_flow_commands",
117
- commands=commands,
117
+ "command_processor.validate_state_of_commands."
118
+ "multiple_cancel_flow_commands",
119
+ commands=[command.__class__.__name__ for command in commands],
118
120
  )
119
121
  raise ValueError("There can only be one cancel flow command.")
120
122
 
@@ -124,8 +126,9 @@ def validate_state_of_commands(commands: List[Command]) -> None:
124
126
  ]
125
127
  if free_form_answer_commands != commands[: len(free_form_answer_commands)]:
126
128
  structlogger.error(
127
- "command_processor.validate_state_of_commands.free_form_answer_commands_not_at_beginning",
128
- commands=commands,
129
+ "command_processor.validate_state_of_commands."
130
+ "free_form_answer_commands_not_at_beginning",
131
+ commands=[command.__class__.__name__ for command in commands],
129
132
  )
130
133
  raise ValueError(
131
134
  "Free form answer commands must be at start of the predicted command list."
@@ -134,8 +137,9 @@ def validate_state_of_commands(commands: List[Command]) -> None:
134
137
  # check that there is at max only one correctslots command
135
138
  if sum(isinstance(c, CorrectSlotsCommand) for c in commands) > 1:
136
139
  structlogger.error(
137
- "command_processor.validate_state_of_commands.multiple_correct_slots_commands",
138
- commands=commands,
140
+ "command_processor.validate_state_of_commands."
141
+ "multiple_correct_slots_commands",
142
+ commands=[command.__class__.__name__ for command in commands],
139
143
  )
140
144
  raise ValueError("There can only be one correct slots command.")
141
145
 
@@ -218,15 +222,13 @@ def execute_commands(
218
222
 
219
223
  events: List[Event] = flow_hash_events
220
224
 
221
- # commands need to be reversed to make sure they end up in the right order
222
- # on the stack. e.g. if there multiple start flow commands, the first one
223
- # should be on top of the stack. this is achieved by reversing the list
224
- # and then pushing the commands onto the stack in the reversed order.
225
- reversed_commands = list(reversed(commands))
225
+ # reorder commands: in case there is no active flow, we want to make sure to
226
+ # run the start flow commands first.
227
+ final_commands = reorder_commands(commands, tracker)
226
228
 
227
229
  validate_state_of_commands(commands)
228
230
 
229
- for command in reversed_commands:
231
+ for command in final_commands:
230
232
  new_events = command.run_command_on_tracker(
231
233
  tracker, all_flows, original_tracker
232
234
  )
@@ -354,14 +356,14 @@ def clean_up_commands(
354
356
  """
355
357
  domain = domain if domain else Domain.empty()
356
358
 
357
- slots_so_far, active_flow = filled_slots_for_active_flow(tracker, all_flows)
359
+ _, active_flow = filled_slots_for_active_flow(tracker, all_flows)
358
360
 
359
361
  clean_commands: List[Command] = []
360
362
 
361
363
  for command in commands:
362
364
  if isinstance(command, SetSlotCommand):
363
365
  clean_commands = clean_up_slot_command(
364
- clean_commands, command, tracker, all_flows, slots_so_far
366
+ clean_commands, command, tracker, all_flows
365
367
  )
366
368
 
367
369
  elif isinstance(command, CancelFlowCommand) and contains_command(
@@ -417,7 +419,8 @@ def clean_up_commands(
417
419
  clean_commands = clean_up_clarify_command(clean_commands, commands, command)
418
420
  if command not in clean_commands:
419
421
  structlogger.debug(
420
- "command_processor.clean_up_commands.drop_clarify_given_other_commands",
422
+ "command_processor.clean_up_commands."
423
+ "drop_clarify_given_other_commands",
421
424
  command=command,
422
425
  )
423
426
  else:
@@ -441,6 +444,25 @@ def clean_up_commands(
441
444
  return clean_commands
442
445
 
443
446
 
447
+ def _get_slots_eligible_for_correction(tracker: DialogueStateTracker) -> Set[str]:
448
+ """Get all slots that are eligible for correction.
449
+
450
+ # We consider all slots, which are not None, that were set in the tracker
451
+ # eligible for correction.
452
+ # In the correct_slot_command we will check if a slot should actually be
453
+ # corrected.
454
+ """
455
+ # get all slots that were set in the tracker
456
+ slots_so_far = set(
457
+ [event.key for event in tracker.events if isinstance(event, SlotSet)]
458
+ )
459
+
460
+ # filter out slots that are set to None (None = empty value)
461
+ slots_so_far = {slot for slot in slots_so_far if tracker.get_slot(slot) is not None}
462
+
463
+ return slots_so_far
464
+
465
+
444
466
  def ensure_max_number_of_command_type(
445
467
  commands: List[Command], command_type: Type[Command], n: int
446
468
  ) -> List[Command]:
@@ -500,7 +522,6 @@ def clean_up_slot_command(
500
522
  command: SetSlotCommand,
501
523
  tracker: DialogueStateTracker,
502
524
  all_flows: FlowsList,
503
- slots_so_far: Set[str],
504
525
  ) -> List[Command]:
505
526
  """Clean up a slot command.
506
527
 
@@ -513,16 +534,15 @@ def clean_up_slot_command(
513
534
  command: The command to clean up.
514
535
  tracker: The dialogue state tracker.
515
536
  all_flows: All flows.
516
- slots_so_far: The slots that have been filled so far.
517
537
 
518
538
  Returns:
519
539
  The cleaned up commands.
520
540
  """
521
541
  stack = tracker.stack
522
-
523
542
  resulting_commands = commands_so_far[:]
524
-
525
543
  slot = tracker.slots.get(command.name)
544
+
545
+ # if the slot is not in the domain, we cannot set it
526
546
  if slot is None:
527
547
  structlogger.debug(
528
548
  "command_processor.clean_up_slot_command.skip_command_slot_not_in_domain",
@@ -535,6 +555,7 @@ def clean_up_slot_command(
535
555
  )
536
556
  return resulting_commands
537
557
 
558
+ # check if the slot should be set by the command
538
559
  if not should_slot_be_set(slot, command):
539
560
  cannot_handle = CannotHandleCommand(
540
561
  reason="A command generator attempted to set a slot with a value extracted "
@@ -545,7 +566,13 @@ def clean_up_slot_command(
545
566
 
546
567
  return resulting_commands
547
568
 
548
- if command.name in slots_so_far and command.name != ROUTE_TO_CALM_SLOT:
569
+ # get all slots that were set in the tracker and are eligible for correction
570
+ slots_eligible_for_correction = _get_slots_eligible_for_correction(tracker)
571
+
572
+ if (
573
+ command.name in slots_eligible_for_correction
574
+ and command.name != ROUTE_TO_CALM_SLOT
575
+ ):
549
576
  current_collect_info = get_current_collect_step(stack, all_flows)
550
577
 
551
578
  if current_collect_info and current_collect_info.collect == command.name:
@@ -553,49 +580,71 @@ def clean_up_slot_command(
553
580
  resulting_commands.append(command)
554
581
  return resulting_commands
555
582
 
556
- if (slot := tracker.slots.get(command.name)) is not None and str(
557
- slot.value
558
- ) == str(command.value):
559
- # the slot is already set, we don't need to set it again
560
- structlogger.debug(
561
- "command_processor.clean_up_slot_command.skip_command_slot_already_set",
562
- command=command,
563
- )
583
+ if should_slot_be_corrected(command, tracker, stack, all_flows):
584
+ # if the slot was already set before, we need to convert it into
585
+ # a correction
586
+ return convert_set_slot_to_correction(command, resulting_commands)
587
+ else:
564
588
  return resulting_commands
565
589
 
566
- top = top_flow_frame(stack)
567
- if isinstance(top, CorrectionPatternFlowStackFrame):
568
- already_corrected_slots = top.corrected_slots
569
- else:
570
- already_corrected_slots = {}
590
+ resulting_commands.append(command)
591
+ return resulting_commands
571
592
 
572
- if command.name in already_corrected_slots and str(
573
- already_corrected_slots[command.name]
574
- ) == str(command.value):
575
- structlogger.debug(
576
- "command_processor.clean_up_slot_command"
577
- ".skip_command_slot_already_corrected",
578
- command=command,
579
- )
580
- return resulting_commands
581
593
 
594
+ def should_slot_be_corrected(
595
+ command: SetSlotCommand,
596
+ tracker: DialogueStateTracker,
597
+ stack: DialogueStack,
598
+ all_flows: FlowsList,
599
+ ) -> bool:
600
+ """Check if a slot should be corrected."""
601
+ if (slot := tracker.slots.get(command.name)) is not None and str(slot.value) == str(
602
+ command.value
603
+ ):
604
+ # the slot is already set to the same value, we don't need to set it again
582
605
  structlogger.debug(
583
- "command_processor.clean_up_slot_command.convert_command_to_correction",
606
+ "command_processor.clean_up_slot_command.skip_command_slot_already_set",
584
607
  command=command,
585
608
  )
609
+ return False
586
610
 
587
- # Group all corrections into one command
588
- corrected_slot = CorrectedSlot(command.name, command.value)
589
- for c in resulting_commands:
590
- if isinstance(c, CorrectSlotsCommand):
591
- c.corrected_slots.append(corrected_slot)
592
- break
593
- else:
594
- resulting_commands.append(
595
- CorrectSlotsCommand(corrected_slots=[corrected_slot])
596
- )
611
+ top = top_flow_frame(stack)
612
+ if isinstance(top, CorrectionPatternFlowStackFrame):
613
+ already_corrected_slots = top.corrected_slots
597
614
  else:
598
- resulting_commands.append(command)
615
+ already_corrected_slots = {}
616
+
617
+ if command.name in already_corrected_slots and str(
618
+ already_corrected_slots[command.name]
619
+ ) == str(command.value):
620
+ structlogger.debug(
621
+ "command_processor.clean_up_slot_command"
622
+ ".skip_command_slot_already_corrected",
623
+ command=command,
624
+ )
625
+ return False
626
+
627
+ return True
628
+
629
+
630
+ def convert_set_slot_to_correction(
631
+ command: SetSlotCommand,
632
+ resulting_commands: List[Command],
633
+ ) -> List[Command]:
634
+ """Convert a set slot command to a correction command."""
635
+ structlogger.debug(
636
+ "command_processor.convert_set_slot_to_correction",
637
+ command=command,
638
+ )
639
+
640
+ # Group all corrections into one command
641
+ corrected_slot = CorrectedSlot(command.name, command.value)
642
+ for c in resulting_commands:
643
+ if isinstance(c, CorrectSlotsCommand):
644
+ c.corrected_slots.append(corrected_slot)
645
+ break
646
+ else:
647
+ resulting_commands.append(CorrectSlotsCommand(corrected_slots=[corrected_slot]))
599
648
 
600
649
  return resulting_commands
601
650
 
@@ -654,8 +703,9 @@ def clean_up_chitchat_command(
654
703
  0, CannotHandleCommand(RASA_PATTERN_CANNOT_HANDLE_CHITCHAT)
655
704
  )
656
705
  structlogger.warn(
657
- "command_processor.clean_up_chitchat_command.replace_chitchat_answer_with_cannot_handle",
658
- command=resulting_commands[0],
706
+ "command_processor.clean_up_chitchat_command."
707
+ "replace_chitchat_answer_with_cannot_handle",
708
+ command=resulting_commands[0], # no PII
659
709
  pattern_chitchat_uses_action_trigger_chitchat=has_action_trigger_chitchat,
660
710
  defined_intentless_policy_in_config=defines_intentless_policy,
661
711
  )
@@ -731,3 +781,49 @@ def filter_cannot_handle_command(
731
781
  for command in clean_commands
732
782
  if not isinstance(command, CannotHandleCommand)
733
783
  ]
784
+
785
+
786
+ def reorder_commands(
787
+ commands: List[Command], tracker: DialogueStateTracker
788
+ ) -> List[Command]:
789
+ """Reorder commands.
790
+
791
+ In case there is no active flow, we want to make sure to run the start flow
792
+ commands first.
793
+ """
794
+ reordered_commands = commands
795
+
796
+ top_flow_frame = top_user_flow_frame(tracker.stack)
797
+
798
+ if top_flow_frame is None:
799
+ # no active flow, we want to make sure to run the start flow commands first
800
+ start_flow_commands: List[Command] = [
801
+ command for command in commands if isinstance(command, StartFlowCommand)
802
+ ]
803
+
804
+ # if there are no start flow commands, we can return the commands as they are
805
+ if not start_flow_commands:
806
+ reordered_commands = commands
807
+
808
+ # if there is just one start flow command, we want to run it first
809
+ # as the order of commands is reserved later,
810
+ # we need to add it to the end of the list
811
+ elif len(start_flow_commands) == 1:
812
+ reordered_commands = [
813
+ command for command in commands if command not in start_flow_commands
814
+ ] + start_flow_commands
815
+
816
+ # if there are multiple start flow commands,
817
+ # we just make sure to move the first start flow command to the end of the list
818
+ # (due to the reverse execution order of commands) and keep the other commands
819
+ # as they are.
820
+ else:
821
+ reordered_commands = [
822
+ command for command in commands if command != start_flow_commands[-1]
823
+ ] + [start_flow_commands[-1]]
824
+
825
+ # commands need to be reversed to make sure they end up in the right order
826
+ # on the stack. e.g. if there multiple start flow commands, the first one
827
+ # should be on top of the stack. this is achieved by reversing the list
828
+ # and then pushing the commands onto the stack in the reversed order.
829
+ return list(reversed(reordered_commands))
@@ -206,14 +206,24 @@ def get_collect_steps_excluding_ask_before_filling_for_active_flow(
206
206
  All collect steps that are part of the current active flow,
207
207
  excluding the collect steps that have to be asked before filling.
208
208
  """
209
- active_frame = top_user_flow_frame(
209
+ active_primary_frame = top_user_flow_frame(dialogue_stack)
210
+ any_active_frame = top_user_flow_frame(
210
211
  dialogue_stack, ignore_call_and_link_frames=False
211
212
  )
212
- if active_frame is None:
213
+
214
+ active_flows = []
215
+ if any_active_frame:
216
+ active_flows.append(any_active_frame.flow(all_flows))
217
+
218
+ if active_primary_frame and active_primary_frame != any_active_frame:
219
+ active_flows.append(active_primary_frame.flow(all_flows))
220
+
221
+ if not active_flows:
213
222
  return set()
214
- active_flow = active_frame.flow(all_flows)
223
+
215
224
  return set(
216
225
  step.collect
226
+ for active_flow in active_flows
217
227
  for step in active_flow.get_collect_steps()
218
228
  if not step.ask_before_filling
219
229
  )
rasa/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  # this file will automatically be changed,
2
2
  # do not add anything but the version number here!
3
- __version__ = "3.11.17"
3
+ __version__ = "3.11.19"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-pro
3
- Version: 3.11.17
3
+ Version: 3.11.19
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
@@ -62,7 +62,7 @@ Requires-Dist: jsonschema (>=4.22)
62
62
  Requires-Dist: keras (==2.14.0)
63
63
  Requires-Dist: langchain (>=0.2.17,<0.3.0)
64
64
  Requires-Dist: langchain-community (>=0.2.19,<0.3.0)
65
- Requires-Dist: litellm (>=1.64.1,<1.65.0)
65
+ Requires-Dist: litellm (>=1.69.0,<1.70.0)
66
66
  Requires-Dist: matplotlib (>=3.7,<3.8)
67
67
  Requires-Dist: mattermostwrapper (>=2.2,<2.3)
68
68
  Requires-Dist: mlflow (>=2.15.1,<3.0.0) ; extra == "mlflow"
@@ -81,7 +81,7 @@ Requires-Dist: portalocker (>=2.7.0,<3.0.0)
81
81
  Requires-Dist: presidio-analyzer (>=2.2.33,<2.2.34)
82
82
  Requires-Dist: presidio-anonymizer (>=2.2.354,<3.0.0)
83
83
  Requires-Dist: prompt-toolkit (>=3.0.28,<3.0.29)
84
- Requires-Dist: protobuf (>=4.23.3,<4.25.4)
84
+ Requires-Dist: protobuf (>=4.25.8,<4.26.0)
85
85
  Requires-Dist: psutil (>=5.9.5,<6.0.0)
86
86
  Requires-Dist: psycopg2-binary (>=2.9.9,<2.10.0)
87
87
  Requires-Dist: pycountry (>=22.3.5,<23.0.0)
@@ -116,7 +116,7 @@ Requires-Dist: scikit-learn (>=1.5.1,<1.6.0)
116
116
  Requires-Dist: scipy (>=1.13.1,<1.14.0)
117
117
  Requires-Dist: sentencepiece[sentencepiece] (>=0.1.99,<0.2.0) ; extra == "transformers" or extra == "full"
118
118
  Requires-Dist: sentry-sdk (>=2.8.0,<3)
119
- Requires-Dist: setuptools (>=78.1.0,<78.2.0)
119
+ Requires-Dist: setuptools (>=78.1.1,<78.2.0)
120
120
  Requires-Dist: sklearn-crfsuite (>=0.3.6,<0.4.0)
121
121
  Requires-Dist: skops (>=0.10.0,<0.11.0)
122
122
  Requires-Dist: slack-sdk (>=3.27.1,<3.28.0)