rasa-pro 3.12.0.dev12__py3-none-any.whl → 3.12.0.dev13__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 (71) hide show
  1. rasa/cli/inspect.py +20 -1
  2. rasa/cli/shell.py +3 -3
  3. rasa/core/actions/action.py +20 -7
  4. rasa/core/actions/action_handle_digressions.py +142 -0
  5. rasa/core/actions/forms.py +10 -5
  6. rasa/core/channels/__init__.py +2 -0
  7. rasa/core/channels/voice_ready/audiocodes.py +42 -23
  8. rasa/core/channels/voice_stream/browser_audio.py +1 -0
  9. rasa/core/channels/voice_stream/call_state.py +7 -1
  10. rasa/core/channels/voice_stream/genesys.py +331 -0
  11. rasa/core/channels/voice_stream/tts/azure.py +2 -1
  12. rasa/core/channels/voice_stream/tts/cartesia.py +16 -3
  13. rasa/core/channels/voice_stream/twilio_media_streams.py +2 -1
  14. rasa/core/channels/voice_stream/voice_channel.py +2 -1
  15. rasa/core/migrate.py +2 -2
  16. rasa/core/policies/flows/flow_executor.py +36 -42
  17. rasa/core/run.py +4 -3
  18. rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -2
  19. rasa/dialogue_understanding/commands/cancel_flow_command.py +62 -4
  20. rasa/dialogue_understanding/commands/change_flow_command.py +2 -2
  21. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -2
  22. rasa/dialogue_understanding/commands/clarify_command.py +2 -2
  23. rasa/dialogue_understanding/commands/correct_slots_command.py +11 -2
  24. rasa/dialogue_understanding/commands/handle_digressions_command.py +150 -0
  25. rasa/dialogue_understanding/commands/human_handoff_command.py +2 -2
  26. rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -2
  27. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -2
  28. rasa/dialogue_understanding/commands/set_slot_command.py +7 -15
  29. rasa/dialogue_understanding/commands/skip_question_command.py +2 -2
  30. rasa/dialogue_understanding/commands/start_flow_command.py +43 -2
  31. rasa/dialogue_understanding/commands/utils.py +1 -1
  32. rasa/dialogue_understanding/constants.py +1 -0
  33. rasa/dialogue_understanding/generator/command_generator.py +110 -73
  34. rasa/dialogue_understanding/generator/command_parser.py +1 -1
  35. rasa/dialogue_understanding/generator/llm_based_command_generator.py +161 -3
  36. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +10 -2
  37. rasa/dialogue_understanding/generator/nlu_command_adapter.py +44 -3
  38. rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +53 -79
  39. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +11 -19
  40. rasa/dialogue_understanding/generator/utils.py +32 -1
  41. rasa/dialogue_understanding/patterns/correction.py +13 -1
  42. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +62 -2
  43. rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
  44. rasa/dialogue_understanding/processor/command_processor.py +115 -28
  45. rasa/dialogue_understanding/utils.py +31 -0
  46. rasa/dialogue_understanding_test/README.md +50 -0
  47. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +3 -3
  48. rasa/model_manager/warm_rasa_process.py +0 -1
  49. rasa/model_training.py +24 -27
  50. rasa/shared/core/constants.py +28 -3
  51. rasa/shared/core/domain.py +13 -20
  52. rasa/shared/core/events.py +13 -2
  53. rasa/shared/core/flows/flow.py +17 -0
  54. rasa/shared/core/flows/flows_yaml_schema.json +38 -0
  55. rasa/shared/core/flows/steps/collect.py +18 -1
  56. rasa/shared/core/flows/utils.py +16 -1
  57. rasa/shared/core/slot_mappings.py +144 -108
  58. rasa/shared/core/slots.py +23 -2
  59. rasa/shared/core/trackers.py +3 -1
  60. rasa/shared/nlu/constants.py +1 -0
  61. rasa/shared/utils/llm.py +1 -1
  62. rasa/shared/utils/schemas/domain.yml +0 -1
  63. rasa/telemetry.py +43 -13
  64. rasa/utils/common.py +0 -1
  65. rasa/validator.py +189 -82
  66. rasa/version.py +1 -1
  67. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0.dev13.dist-info}/METADATA +1 -1
  68. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0.dev13.dist-info}/RECORD +71 -67
  69. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0.dev13.dist-info}/NOTICE +0 -0
  70. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0.dev13.dist-info}/WHEEL +0 -0
  71. {rasa_pro-3.12.0.dev12.dist-info → rasa_pro-3.12.0.dev13.dist-info}/entry_points.txt +0 -0
rasa/telemetry.py CHANGED
@@ -15,7 +15,7 @@ from collections import defaultdict
15
15
  from datetime import datetime
16
16
  from functools import wraps
17
17
  from pathlib import Path
18
- from typing import Any, Callable, Dict, List, Optional, Text
18
+ from typing import Any, Callable, Dict, List, Optional, Text, Tuple
19
19
 
20
20
  import importlib_resources
21
21
  import requests
@@ -35,6 +35,7 @@ from rasa.constants import (
35
35
  )
36
36
  from rasa.engine.storage.local_model_storage import LocalModelStorage
37
37
  from rasa.shared.constants import (
38
+ ASSISTANT_ID_KEY,
38
39
  CONFIG_LANGUAGE_KEY,
39
40
  CONFIG_PIPELINE_KEY,
40
41
  CONFIG_POLICIES_KEY,
@@ -111,6 +112,7 @@ CI_ENVIRONMENT_TELL = [
111
112
  # https://rasa.com/docs/rasa-pro/telemetry/reference
112
113
  TRAINING_STARTED_EVENT = "Training Started"
113
114
  TRAINING_COMPLETED_EVENT = "Training Completed"
115
+ TRAINING_FAILED_EVENT = "Training Failed"
114
116
  TELEMETRY_DISABLED_EVENT = "Telemetry Disabled"
115
117
  TELEMETRY_DATA_SPLIT_EVENT = "Training Data Split"
116
118
  TELEMETRY_DATA_VALIDATED_EVENT = "Training Data Validated"
@@ -976,6 +978,7 @@ def track_model_training(
976
978
  "language": config.get(CONFIG_LANGUAGE_KEY),
977
979
  "training_id": training_id,
978
980
  "type": model_type,
981
+ "assistant_id": config.get(ASSISTANT_ID_KEY),
979
982
  "pipeline": config.get(CONFIG_PIPELINE_KEY),
980
983
  "policies": config.get(CONFIG_POLICIES_KEY),
981
984
  "train_schema": config.get(CONFIG_TRAIN_SCHEMA),
@@ -1021,13 +1024,28 @@ def track_model_training(
1021
1024
  tracking_data,
1022
1025
  )
1023
1026
  start = datetime.now()
1024
- yield
1027
+ try:
1028
+ yield
1029
+ except (Exception, SystemExit):
1030
+ runtime = datetime.now() - start
1031
+ _track(
1032
+ TRAINING_FAILED_EVENT,
1033
+ {
1034
+ "training_id": training_id,
1035
+ "assistant_id": config.get(ASSISTANT_ID_KEY),
1036
+ "type": model_type,
1037
+ "runtime": int(runtime.total_seconds()),
1038
+ },
1039
+ )
1040
+ raise
1041
+
1025
1042
  runtime = datetime.now() - start
1026
1043
 
1027
1044
  _track(
1028
1045
  TRAINING_COMPLETED_EVENT,
1029
1046
  {
1030
1047
  "training_id": training_id,
1048
+ "assistant_id": config.get(ASSISTANT_ID_KEY),
1031
1049
  "type": model_type,
1032
1050
  "runtime": int(runtime.total_seconds()),
1033
1051
  },
@@ -1326,24 +1344,28 @@ def track_server_start(
1326
1344
  """
1327
1345
  from rasa.core.utils import AvailableEndpoints
1328
1346
 
1329
- def project_fingerprint_from_model(
1347
+ def project_fingerprint_and_assistant_id_from_model(
1330
1348
  _model_directory: Optional[Text],
1331
- ) -> Optional[Text]:
1349
+ ) -> Tuple[Optional[Text], Optional[Text]]:
1332
1350
  """Gets project fingerprint from an app's loaded model."""
1333
1351
  if not model_directory:
1334
- return None
1352
+ return None, None
1335
1353
 
1336
1354
  try:
1337
1355
  model_archive = model.get_local_model(_model_directory)
1338
1356
  metadata = LocalModelStorage.metadata_from_archive(model_archive)
1339
1357
 
1340
- return metadata.project_fingerprint
1358
+ return metadata.project_fingerprint, metadata.assistant_id
1341
1359
  except Exception:
1342
- return None
1360
+ return None, None
1343
1361
 
1344
1362
  if not endpoints:
1345
1363
  endpoints = AvailableEndpoints()
1346
1364
 
1365
+ project, assistant_id = project_fingerprint_and_assistant_id_from_model(
1366
+ model_directory
1367
+ )
1368
+
1347
1369
  _track(
1348
1370
  TELEMETRY_SERVER_STARTED_EVENT,
1349
1371
  {
@@ -1365,7 +1387,8 @@ def track_server_start(
1365
1387
  "endpoints_event_broker": endpoints.event_broker.type
1366
1388
  if endpoints.event_broker
1367
1389
  else None,
1368
- "project": project_fingerprint_from_model(model_directory),
1390
+ "project": project,
1391
+ "assistant_id": assistant_id,
1369
1392
  },
1370
1393
  )
1371
1394
 
@@ -1383,23 +1406,30 @@ def track_project_init(path: Text) -> None:
1383
1406
 
1384
1407
 
1385
1408
  @ensure_telemetry_enabled
1386
- def track_shell_started(model_type: Text) -> None:
1409
+ def track_shell_started(model_type: Text, assistant_id: Text) -> None:
1387
1410
  """Track when a user starts a bot using rasa shell.
1388
1411
 
1389
1412
  Args:
1390
1413
  model_type: Type of the model, core / nlu or rasa.
1391
1414
  """
1392
- _track(TELEMETRY_SHELL_STARTED_EVENT, {"type": model_type})
1415
+ _track(
1416
+ TELEMETRY_SHELL_STARTED_EVENT,
1417
+ {"type": model_type, "assistant_id": assistant_id},
1418
+ )
1393
1419
 
1394
1420
 
1395
1421
  @ensure_telemetry_enabled
1396
- def track_inspect_started(model_type: Text) -> None:
1422
+ def track_inspect_started(channel: Text, assistant_id: Text) -> None:
1397
1423
  """Track when a user starts a bot using rasa inspect.
1398
1424
 
1399
1425
  Args:
1400
- model_type: Type of the model, core / nlu or rasa.
1426
+ channel: Type of channel used.
1427
+ assistant_id: ID of the assistant being inspected.
1401
1428
  """
1402
- _track(TELEMETRY_INSPECT_STARTED_EVENT, {"type": model_type})
1429
+ _track(
1430
+ TELEMETRY_INSPECT_STARTED_EVENT,
1431
+ {"type": channel, "assistant_id": assistant_id},
1432
+ )
1403
1433
 
1404
1434
 
1405
1435
  @ensure_telemetry_enabled
rasa/utils/common.py CHANGED
@@ -70,7 +70,6 @@ EXPECTED_WARNINGS: List[Tuple[Type[Warning], str]] = [
70
70
  "Converting sparse IndexedSlices.* to a dense Tensor of unknown "
71
71
  "shape. This may consume a large amount of memory.",
72
72
  ),
73
- (UserWarning, "Slot auto-fill has been removed in 3.0 .*"),
74
73
  # Cannot fix this deprecation warning since we need to support two
75
74
  # numpy versions as long as we keep python 37 around
76
75
  (DeprecationWarning, "the `interpolation=` argument to quantile was renamed"),
rasa/validator.py CHANGED
@@ -35,9 +35,7 @@ from rasa.shared.core.command_payload_reader import (
35
35
  CommandPayloadReader,
36
36
  )
37
37
  from rasa.shared.core.constants import (
38
- ACTIVE_LOOP,
39
- MAPPING_CONDITIONS,
40
- MAPPING_TYPE,
38
+ KEY_ALLOW_NLU_CORRECTION,
41
39
  SlotMappingType,
42
40
  )
43
41
  from rasa.shared.core.domain import (
@@ -45,13 +43,14 @@ from rasa.shared.core.domain import (
45
43
  Domain,
46
44
  )
47
45
  from rasa.shared.core.events import ActionExecuted, ActiveLoop, UserUttered
48
- from rasa.shared.core.flows import FlowsList
46
+ from rasa.shared.core.flows import Flow, FlowsList
49
47
  from rasa.shared.core.flows.flow_step_links import IfFlowStepLink
50
48
  from rasa.shared.core.flows.steps.action import ActionFlowStep
51
49
  from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
52
50
  from rasa.shared.core.flows.steps.link import LinkFlowStep
53
51
  from rasa.shared.core.flows.steps.set_slots import SetSlotsFlowStep
54
52
  from rasa.shared.core.flows.utils import (
53
+ ALL_LABEL,
55
54
  get_duplicate_slot_persistence_config_error_message,
56
55
  get_invalid_slot_persistence_config_error_message,
57
56
  warn_deprecated_collect_step_config,
@@ -518,9 +517,9 @@ class Validator:
518
517
 
519
518
  for slot in self.domain.slots:
520
519
  for mapping in slot.mappings:
521
- for condition in mapping.get(MAPPING_CONDITIONS, []):
522
- condition_active_loop = condition.get(ACTIVE_LOOP)
523
- mapping_type = SlotMappingType(mapping.get(MAPPING_TYPE))
520
+ for condition in mapping.conditions:
521
+ condition_active_loop = condition.active_loop
522
+ mapping_type = mapping.type
524
523
  if (
525
524
  condition_active_loop
526
525
  and condition_active_loop not in self.domain.form_names
@@ -1264,6 +1263,7 @@ class Validator:
1264
1263
  self.verify_unique_flows(),
1265
1264
  self.verify_predicates(),
1266
1265
  self.verify_slot_persistence_configuration(),
1266
+ self.verify_digression_configuration(),
1267
1267
  ]
1268
1268
 
1269
1269
  all_good = all(flow_validation_conditions)
@@ -1392,34 +1392,22 @@ class Validator:
1392
1392
 
1393
1393
  for slot in self.domain._user_slots:
1394
1394
  nlu_mappings = any(
1395
- [
1396
- SlotMappingType(
1397
- mapping.get("type", SlotMappingType.FROM_LLM.value)
1398
- ).is_predefined_type()
1399
- for mapping in slot.mappings
1400
- ]
1395
+ [mapping.type.is_predefined_type() for mapping in slot.mappings]
1401
1396
  )
1402
1397
  llm_mappings = any(
1403
- [
1404
- SlotMappingType(mapping.get("type", SlotMappingType.FROM_LLM.value))
1405
- == SlotMappingType.FROM_LLM
1406
- for mapping in slot.mappings
1407
- ]
1398
+ [mapping.type == SlotMappingType.FROM_LLM for mapping in slot.mappings]
1408
1399
  )
1409
- custom_mappings = any(
1400
+ controlled_mappings = any(
1410
1401
  [
1411
- SlotMappingType(mapping.get("type", SlotMappingType.FROM_LLM.value))
1412
- == SlotMappingType.CUSTOM
1402
+ mapping.type == SlotMappingType.CONTROLLED
1413
1403
  for mapping in slot.mappings
1414
1404
  ]
1415
1405
  )
1416
1406
 
1417
- all_good = self._slot_contains_all_mappings_types(
1418
- llm_mappings, nlu_mappings, custom_mappings, slot.name, all_good
1419
- )
1407
+ all_good = self._allow_nlu_correction_is_valid(slot, nlu_mappings, all_good)
1420
1408
 
1421
1409
  all_good = self._custom_action_name_is_defined_in_the_domain(
1422
- custom_mappings, slot, all_good
1410
+ controlled_mappings, slot, all_good
1423
1411
  )
1424
1412
 
1425
1413
  all_good = self._config_contains_nlu_command_adapter(
@@ -1433,23 +1421,45 @@ class Validator:
1433
1421
  return all_good
1434
1422
 
1435
1423
  @staticmethod
1436
- def _slot_contains_all_mappings_types(
1437
- llm_mappings: bool,
1438
- nlu_mappings: bool,
1439
- custom_mappings: bool,
1440
- slot_name: str,
1441
- all_good: bool,
1424
+ def _allow_nlu_correction_is_valid(
1425
+ slot: Slot, nlu_mappings: bool, all_good: bool
1442
1426
  ) -> bool:
1443
- if llm_mappings and (nlu_mappings or custom_mappings):
1427
+ """Verify that `allow_nlu_correction` property is used correctly in a `from_llm` mappings only.""" # noqa: E501
1428
+ if not slot.mappings:
1429
+ return all_good
1430
+
1431
+ invalid_usage = False
1432
+
1433
+ for mapping in slot.mappings:
1434
+ allow_nlu_correction = mapping.allow_nlu_correction
1435
+ if allow_nlu_correction and mapping.type != SlotMappingType.FROM_LLM:
1436
+ invalid_usage = True
1437
+
1438
+ if allow_nlu_correction and not nlu_mappings:
1439
+ structlogger.error(
1440
+ "validator.validate_slot_mappings_in_CALM.nlu_mappings_not_present",
1441
+ slot_name=slot.name,
1442
+ event_info=(
1443
+ f"The slot '{slot.name}' does not have any "
1444
+ f"NLU-based slot mappings. "
1445
+ f"The property `allow_nlu_correction` is only "
1446
+ f"applicable when the slot "
1447
+ f"contains both NLU-based and LLM-based slot mappings."
1448
+ ),
1449
+ )
1450
+ all_good = False
1451
+
1452
+ if invalid_usage:
1444
1453
  structlogger.error(
1445
- "validator.validate_slot_mappings_in_CALM.llm_and_nlu_mappings",
1446
- slot_name=slot_name,
1454
+ "validator.validate_slot_mappings_in_CALM.allow_nlu_correction",
1455
+ slot_name=slot.name,
1447
1456
  event_info=(
1448
- f"The slot '{slot_name}' has both LLM and "
1449
- f"NLU or custom slot mappings. "
1450
- f"Please make sure that the slot has only one type of mapping."
1457
+ f"The slot '{slot.name}' has at least 1 slot mapping with "
1458
+ f"'{KEY_ALLOW_NLU_CORRECTION}' set to 'true', but "
1459
+ f"the slot mapping type is not 'from_llm'. "
1460
+ f"Please set the slot mapping type to 'from_llm' "
1461
+ f"to allow the LLM to correct this slot."
1451
1462
  ),
1452
- docs_link=DOCS_URL_DOMAIN + "#calm-slot-mappings",
1453
1463
  )
1454
1464
  all_good = False
1455
1465
 
@@ -1457,55 +1467,32 @@ class Validator:
1457
1467
 
1458
1468
  def _custom_action_name_is_defined_in_the_domain(
1459
1469
  self,
1460
- custom_mappings: bool,
1470
+ controlled_mappings: bool,
1461
1471
  slot: Slot,
1462
1472
  all_good: bool,
1463
1473
  ) -> bool:
1464
- if not custom_mappings:
1465
- return all_good
1466
-
1467
- if not self.flows:
1468
- return all_good
1469
-
1470
- is_custom_action_defined = any(
1471
- [
1472
- mapping.get("action") is not None
1473
- and mapping.get("action") in self.domain.action_names_or_texts
1474
- for mapping in slot.mappings
1475
- ]
1476
- )
1477
-
1478
- if is_custom_action_defined:
1474
+ if not controlled_mappings:
1479
1475
  return all_good
1480
1476
 
1481
- slot_collected_by_flows = any(
1482
- [
1483
- step.collect == slot.name
1484
- for flow in self.flows.underlying_flows
1485
- for step in flow.steps
1486
- if isinstance(step, CollectInformationFlowStep)
1487
- ]
1488
- )
1489
-
1490
- if not slot_collected_by_flows:
1491
- # if the slot is not collected by any flow,
1492
- # it could be a DM1 custom slot
1493
- return all_good
1494
-
1495
- custom_action_ask_name = f"action_ask_{slot.name}"
1496
- if custom_action_ask_name not in self.domain.action_names_or_texts:
1497
- structlogger.error(
1498
- "validator.validate_slot_mappings_in_CALM.custom_action_not_in_domain",
1499
- slot_name=slot.name,
1500
- event_info=(
1501
- f"The slot '{slot.name}' has a custom slot mapping, but "
1502
- f"neither the action '{custom_action_ask_name}' nor "
1503
- f"another custom action are defined in the domain file. "
1504
- f"Please add one of the actions to your domain file."
1505
- ),
1506
- docs_link=DOCS_URL_DOMAIN + "#custom-slot-mappings",
1507
- )
1508
- all_good = False
1477
+ for mapping in slot.mappings:
1478
+ if (
1479
+ mapping.run_action_every_turn is not None
1480
+ and mapping.run_action_every_turn
1481
+ not in self.domain.action_names_or_texts
1482
+ ):
1483
+ structlogger.error(
1484
+ "validator.validate_slot_mappings_in_CALM.custom_action_not_in_domain",
1485
+ slot_name=slot.name,
1486
+ action_name=mapping.run_action_every_turn,
1487
+ event_info=(
1488
+ f"The slot '{slot.name}' has a custom action "
1489
+ f"'{mapping.run_action_every_turn}' "
1490
+ f"defined in its slot mappings, "
1491
+ f"but the action is not listed in the domain actions. "
1492
+ f"Please add the action to your domain file."
1493
+ ),
1494
+ )
1495
+ all_good = False
1509
1496
 
1510
1497
  return all_good
1511
1498
 
@@ -1658,3 +1645,123 @@ class Validator:
1658
1645
  )
1659
1646
 
1660
1647
  return all_good
1648
+
1649
+ def verify_digression_configuration(self) -> bool:
1650
+ """Validates the digression configuration in flows."""
1651
+ all_good = True
1652
+
1653
+ for flow in self.flows.underlying_flows:
1654
+ all_good = self._validate_ask_confirm_digressions(flow, all_good)
1655
+ all_good = self._validate_block_digressions(flow, all_good)
1656
+
1657
+ return all_good
1658
+
1659
+ def _validate_ask_confirm_digressions(self, flow: Flow, all_good: bool) -> bool:
1660
+ """Validates the ask_confirm_digressions configuration in a flow."""
1661
+ for flow_id in flow.ask_confirm_digressions:
1662
+ if flow_id == ALL_LABEL:
1663
+ continue
1664
+ if flow_id not in self.flows.flow_ids:
1665
+ structlogger.error(
1666
+ "validator.verify_digression_configuration.ask_confirm_digressions",
1667
+ flow=flow.id,
1668
+ event_info=(
1669
+ f"The flow '{flow_id}' is listed in the "
1670
+ f"`ask_confirm_digressions` configuration of flow "
1671
+ f"'{flow.id}', but it is not found in the "
1672
+ f"flows file. Please make sure that the flow id is correct."
1673
+ ),
1674
+ )
1675
+ all_good = False
1676
+
1677
+ if flow_id in flow.block_digressions:
1678
+ structlogger.error(
1679
+ "validator.verify_digression_configuration.overlap_digressions",
1680
+ flow=flow.id,
1681
+ event_info=(
1682
+ f"The flow '{flow_id}' is listed in both the "
1683
+ f"`ask_confirm_digressions` and `block_digressions` "
1684
+ f"configuration of flow '{flow.id}'. "
1685
+ f"Please make sure that the flow id is not listed in both "
1686
+ f"configurations."
1687
+ ),
1688
+ )
1689
+ all_good = False
1690
+
1691
+ for step in flow.get_collect_steps():
1692
+ for flow_id in step.ask_confirm_digressions:
1693
+ if flow_id == ALL_LABEL:
1694
+ continue
1695
+
1696
+ if flow_id not in self.flows.flow_ids:
1697
+ structlogger.error(
1698
+ "validator.verify_digression_configuration.ask_confirm_digressions",
1699
+ flow=flow.id,
1700
+ step_id=step.id,
1701
+ event_info=(
1702
+ f"The flow '{flow_id}' is listed in the "
1703
+ f"`ask_confirm_digressions` configuration of step "
1704
+ f"'{step.id}' in flow '{flow.id}', but it is "
1705
+ f"not found in the flows file. "
1706
+ f"Please make sure that the flow id is correct."
1707
+ ),
1708
+ )
1709
+ all_good = False
1710
+
1711
+ if flow_id in step.block_digressions:
1712
+ structlogger.error(
1713
+ "validator.verify_digression_configuration.overlap_digressions",
1714
+ flow=flow.id,
1715
+ step_id=step.id,
1716
+ event_info=(
1717
+ f"The flow '{flow_id}' is listed in both the "
1718
+ f"`ask_confirm_digressions` and `block_digressions` "
1719
+ f"configuration of step '{step.id}' in flow '{flow.id}'. "
1720
+ f"Please make sure that the flow id is not listed in both "
1721
+ f"configurations."
1722
+ ),
1723
+ )
1724
+ all_good = False
1725
+
1726
+ return all_good
1727
+
1728
+ def _validate_block_digressions(self, flow: Flow, all_good: bool) -> bool:
1729
+ """Validates the block_digressions configuration in a flow."""
1730
+ for flow_id in flow.block_digressions:
1731
+ if flow_id == ALL_LABEL:
1732
+ continue
1733
+
1734
+ if flow_id not in self.flows.flow_ids:
1735
+ structlogger.error(
1736
+ "validator.verify_digression_configuration.block_digressions",
1737
+ flow=flow.id,
1738
+ event_info=(
1739
+ f"The flow '{flow_id}' is listed in the `block_digressions` "
1740
+ f"configuration of flow '{flow.id}', but it is not found "
1741
+ f"in the flows file. Please make sure that the flow id "
1742
+ f"is correct."
1743
+ ),
1744
+ )
1745
+ all_good = False
1746
+
1747
+ for step in flow.get_collect_steps():
1748
+ for flow_id in step.block_digressions:
1749
+ if flow_id == ALL_LABEL:
1750
+ continue
1751
+
1752
+ if flow_id not in self.flows.flow_ids:
1753
+ structlogger.error(
1754
+ "validator.verify_digression_configuration.block_digressions",
1755
+ flow=flow.id,
1756
+ step_id=step.id,
1757
+ event_info=(
1758
+ f"The flow '{flow_id}' is listed in the "
1759
+ f"`block_digressions` configuration of step "
1760
+ f"'{step.id}' in flow '{flow.id}', but it is "
1761
+ f"not found in the flows file. "
1762
+ f"Please make sure that the flow id is correct."
1763
+ ),
1764
+ )
1765
+ all_good = False
1766
+
1767
+ return all_good
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.12.0.dev12"
3
+ __version__ = "3.12.0.dev13"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rasa-pro
3
- Version: 3.12.0.dev12
3
+ Version: 3.12.0.dev13
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
  Home-page: https://rasa.com
6
6
  Keywords: nlp,machine-learning,machine-learning-library,bot,bots,botkit,rasa conversational-agents,conversational-ai,chatbot,chatbot-framework,bot-framework