Files
wehub-resource-sync dc6079821b
Docs Tests / Check for file changes (push) Has been cancelled
Docs Tests / Test Documentation (push) Has been cancelled
Docs Tests / Documentation Linting Checks (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Has been cancelled
Continuous Integration / Check for file changes (push) Has been cancelled
Continuous Integration / Wait for docs tests (push) Has been cancelled
Continuous Integration / Code Quality (push) Has been cancelled
Continuous Integration / Check for changelog (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Upload coverage reports to codeclimate (push) Has been cancelled
Continuous Integration / Run Non-Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Run Broker Integration Tests (push) Has been cancelled
Continuous Integration / Run Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Build Docker base images and setup environment (push) Has been cancelled
Continuous Integration / Build Docker (default) (push) Has been cancelled
Continuous Integration / Build Docker (full) (push) Has been cancelled
Continuous Integration / Build Docker (mitie-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-de) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-it) (push) Has been cancelled
Continuous Integration / Deploy to PyPI (push) Has been cancelled
Continuous Integration / Notify Slack & Publish Release Notes (push) Has been cancelled
Publish Documentation / Evaluate release tag (push) Has been cancelled
Publish Documentation / Prebuild Docs (push) Has been cancelled
Publish Documentation / Preview Docs (push) Has been cancelled
Publish Documentation / Check for file changes (push) Has been cancelled
Publish Documentation / Publish Docs (push) Has been cancelled
Automatic PR Merger / mergepal (push) Has been cancelled
CI Github Actions / Run Tests (push) Has been cancelled
Semgrep / Semgrep Workflow Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:47 +08:00

223 lines
8.0 KiB
Python

import logging
from typing import List, Optional, Union, Text, Any, Dict
import rasa.shared.utils.common
import rasa.shared.utils.io
from rasa.shared.constants import CHANNEL, RESPONSE_CONDITION
from rasa.shared.core.domain import Domain
from rasa.utils.endpoints import EndpointConfig
from rasa.shared.core.trackers import DialogueStateTracker
logger = logging.getLogger(__name__)
class NaturalLanguageGenerator:
"""Generate bot utterances based on a dialogue state."""
async def generate(
self,
utter_action: Text,
tracker: "DialogueStateTracker",
output_channel: Text,
**kwargs: Any,
) -> Optional[Dict[Text, Any]]:
"""Generate a response for the requested utter action.
There are a lot of different methods to implement this, e.g. the
generation can be based on responses or be fully ML based by feeding
the dialogue state into a machine learning NLG model.
"""
raise NotImplementedError
@staticmethod
def create(
obj: Union["NaturalLanguageGenerator", EndpointConfig, None],
domain: Optional[Domain],
) -> "NaturalLanguageGenerator":
"""Factory to create a generator."""
if isinstance(obj, NaturalLanguageGenerator):
return obj
else:
return _create_from_endpoint_config(obj, domain)
def _create_from_endpoint_config(
endpoint_config: Optional[EndpointConfig] = None, domain: Optional[Domain] = None
) -> "NaturalLanguageGenerator":
"""Given an endpoint configuration, create a proper NLG object."""
domain = domain or Domain.empty()
if endpoint_config is None:
from rasa.core.nlg import TemplatedNaturalLanguageGenerator
# this is the default type if no endpoint config is set
nlg: "NaturalLanguageGenerator" = TemplatedNaturalLanguageGenerator(
domain.responses
)
elif endpoint_config.type is None or endpoint_config.type.lower() == "callback":
from rasa.core.nlg import CallbackNaturalLanguageGenerator
# this is the default type if no nlg type is set
nlg = CallbackNaturalLanguageGenerator(endpoint_config=endpoint_config)
elif endpoint_config.type.lower() == "response":
from rasa.core.nlg import TemplatedNaturalLanguageGenerator
nlg = TemplatedNaturalLanguageGenerator(domain.responses)
else:
nlg = _load_from_module_name_in_endpoint_config(endpoint_config, domain)
logger.debug(f"Instantiated NLG to '{nlg.__class__.__name__}'.")
return nlg
def _load_from_module_name_in_endpoint_config(
endpoint_config: EndpointConfig, domain: Domain
) -> "NaturalLanguageGenerator":
"""Initializes a custom natural language generator.
Args:
domain: defines the universe in which the assistant operates
endpoint_config: the specific natural language generator
"""
try:
nlg_class = rasa.shared.utils.common.class_from_module_path(
endpoint_config.type
)
return nlg_class(endpoint_config=endpoint_config, domain=domain)
except (AttributeError, ImportError) as e:
raise Exception(
f"Could not find a class based on the module path "
f"'{endpoint_config.type}'. Failed to create a "
f"`NaturalLanguageGenerator` instance. Error: {e}"
)
class ResponseVariationFilter:
"""Filters response variations based on the channel, action and condition."""
def __init__(self, responses: Dict[Text, List[Dict[Text, Any]]]) -> None:
self.responses = responses
@staticmethod
def _matches_filled_slots(
filled_slots: Dict[Text, Any], response: Dict[Text, Any]
) -> bool:
"""Checks if the conditional response variation matches the filled slots."""
constraints = response.get(RESPONSE_CONDITION, [])
for constraint in constraints:
name = constraint["name"]
value = constraint["value"]
filled_slots_value = filled_slots.get(name)
if isinstance(filled_slots_value, str) and isinstance(value, str):
if filled_slots_value.casefold() != value.casefold():
return False
# slot values can be of different data types
# such as int, float, bool, etc. hence, this check
# executes when slot values are not strings
elif filled_slots_value != value:
return False
return True
def responses_for_utter_action(
self,
utter_action: Text,
output_channel: Text,
filled_slots: Dict[Text, Any],
) -> List[Dict[Text, Any]]:
"""Returns array of responses that fit the channel, action and condition."""
# filter responses without a condition
default_responses = list(
filter(
lambda x: (x.get(RESPONSE_CONDITION) is None),
self.responses[utter_action],
)
)
# filter responses with a condition that matches the filled slots
conditional_responses = list(
filter(
lambda x: (
x.get(RESPONSE_CONDITION)
and self._matches_filled_slots(
filled_slots=filled_slots, response=x
)
),
self.responses[utter_action],
)
)
# filter conditional responses that match the channel
conditional_channel = list(
filter(lambda x: (x.get(CHANNEL) == output_channel), conditional_responses)
)
# filter conditional responses that don't match the channel
conditional_no_channel = list(
filter(lambda x: (x.get(CHANNEL) is None), conditional_responses)
)
# filter default responses that match the channel
default_channel = list(
filter(lambda x: (x.get(CHANNEL) == output_channel), default_responses)
)
# filter default responses that don't match the channel
default_no_channel = list(
filter(lambda x: (x.get(CHANNEL) is None), default_responses)
)
if conditional_channel:
return conditional_channel
if default_channel:
return default_channel
if conditional_no_channel:
return conditional_no_channel
return default_no_channel
def get_response_variation_id(
self,
utter_action: Text,
tracker: DialogueStateTracker,
output_channel: Text,
) -> Optional[Text]:
"""Returns the first matched response variation ID.
This ID corresponds to the response variation that fits
the channel, action and condition.
"""
filled_slots = tracker.current_slot_values()
if utter_action in self.responses:
eligible_variations = self.responses_for_utter_action(
utter_action, output_channel, filled_slots
)
response_ids_are_valid = self._validate_response_ids(eligible_variations)
if eligible_variations and response_ids_are_valid:
return eligible_variations[0].get("id")
return None
@staticmethod
def _validate_response_ids(response_variations: List[Dict[Text, Any]]) -> bool:
"""Checks that the response IDs of a particular utter_action are unique.
Args:
response_variations: The response variations to validate.
Returns:
True if the response IDs are unique, False otherwise.
"""
response_ids = set()
for response_variation in response_variations:
response_variation_id = response_variation.get("id")
if response_variation_id and response_variation_id in response_ids:
rasa.shared.utils.io.raise_warning(
f"Duplicate response id '{response_variation_id}' "
f"defined in the domain."
)
return False
response_ids.add(response_variation_id)
return True