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
628 lines
20 KiB
Python
628 lines
20 KiB
Python
from typing import Dict, List, Text, Any
|
|
|
|
import logging
|
|
import pytest
|
|
from _pytest.logging import LogCaptureFixture
|
|
|
|
from rasa.core.nlg.response import TemplatedNaturalLanguageGenerator
|
|
from rasa.shared.constants import LATEST_TRAINING_DATA_FORMAT_VERSION
|
|
from rasa.shared.core.domain import Domain
|
|
from rasa.shared.core.slots import TextSlot, AnySlot, CategoricalSlot, BooleanSlot
|
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_with_no_slots():
|
|
responses = {
|
|
"utter_test": [
|
|
{
|
|
"text": "Conditional OS Response A",
|
|
"condition": [{"type": "slot", "name": "slot test", "value": "A"}],
|
|
"channel": "os",
|
|
},
|
|
{
|
|
"text": "Conditional Response A",
|
|
"condition": [{"type": "slot", "name": "slot test", "value": "A"}],
|
|
},
|
|
{
|
|
"text": "Conditional Response B",
|
|
"condition": [{"type": "slot", "name": "slot test", "value": "B"}],
|
|
},
|
|
{"text": "Default response"},
|
|
]
|
|
}
|
|
t = TemplatedNaturalLanguageGenerator(responses=responses)
|
|
no_slots_tracker = DialogueStateTracker(sender_id="nlg_test_default", slots=None)
|
|
default_response = await t.generate(
|
|
utter_action="utter_test", tracker=no_slots_tracker, output_channel=""
|
|
)
|
|
|
|
assert default_response.get("text") == "Default response"
|
|
|
|
|
|
async def test_nlg_when_multiple_conditions_satisfied():
|
|
responses = {
|
|
"utter_action": [
|
|
{
|
|
"text": "example A",
|
|
"condition": [{"type": "slot", "name": "test", "value": "A"}],
|
|
},
|
|
{
|
|
"text": "example B",
|
|
"condition": [{"type": "slot", "name": "test_another", "value": "B"}],
|
|
},
|
|
{
|
|
"text": "non matching example 1",
|
|
"condition": [
|
|
{"type": "slot", "name": "test_third_slot", "value": "C"}
|
|
],
|
|
},
|
|
{
|
|
"text": "non matching example 2",
|
|
"condition": [{"type": "slot", "name": "test", "value": "D"}],
|
|
},
|
|
]
|
|
}
|
|
|
|
t = TemplatedNaturalLanguageGenerator(responses=responses)
|
|
slot_a = TextSlot(
|
|
name="test", mappings=[{}], initial_value="A", influence_conversation=False
|
|
)
|
|
slot_b = TextSlot(
|
|
name="test_another",
|
|
mappings=[{}],
|
|
initial_value="B",
|
|
influence_conversation=False,
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="test_nlg", slots=[slot_a, slot_b])
|
|
resp = await t.generate(
|
|
utter_action="utter_action", tracker=tracker, output_channel=""
|
|
)
|
|
assert resp.get("text") in ["example A", "example B"]
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def test_slots() -> List[object]:
|
|
slot_a = CategoricalSlot(
|
|
name="test",
|
|
mappings=[{"type": "from_text", "value": ["cold", "hot"]}],
|
|
initial_value="Cold",
|
|
influence_conversation=False,
|
|
)
|
|
slot_b = BooleanSlot(
|
|
name="test2",
|
|
mappings=[{}],
|
|
initial_value=False,
|
|
influence_conversation=False,
|
|
)
|
|
slot_c = CategoricalSlot(
|
|
name="test3",
|
|
mappings=[{"type": "from_text", "value": ["cold", "hot"]}],
|
|
initial_value="hot",
|
|
influence_conversation=False,
|
|
)
|
|
return [slot_a, slot_b, slot_c]
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def test_responses() -> List[Dict[Text, List[Dict[Text, Any]]]]:
|
|
return [
|
|
{
|
|
"utter_action": [
|
|
{
|
|
"text": "example a",
|
|
"condition": [{"type": "slot", "name": "test", "value": "cold"}],
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"utter_action_multiple_conditions": [
|
|
{
|
|
"text": "example b",
|
|
"condition": [
|
|
{"type": "slot", "name": "test", "value": "cold"},
|
|
{"type": "slot", "name": "test2", "value": False},
|
|
{"type": "slot", "name": "test3", "value": "hot"},
|
|
],
|
|
}
|
|
]
|
|
},
|
|
]
|
|
|
|
|
|
async def test_nlg_slot_case_sensitivity(
|
|
test_slots: List[object],
|
|
test_responses: List[Dict[Text, List[Dict[Text, Any]]]],
|
|
):
|
|
utter_action = "utter_action"
|
|
t = TemplatedNaturalLanguageGenerator(responses=test_responses[0])
|
|
tracker = DialogueStateTracker(sender_id="test_nlg", slots=[test_slots[0]])
|
|
resp = await t.generate(
|
|
utter_action=utter_action, tracker=tracker, output_channel=""
|
|
)
|
|
assert resp.get("text") == test_responses[0][utter_action][0]["text"]
|
|
|
|
|
|
async def test_matches_filled_slots_multiple_conditions(
|
|
test_slots: List[object],
|
|
test_responses: List[Dict[Text, List[Dict[Text, Any]]]],
|
|
):
|
|
utter_action = "utter_action_multiple_conditions"
|
|
t = TemplatedNaturalLanguageGenerator(responses=test_responses[1])
|
|
tracker = DialogueStateTracker(sender_id="test_nlg", slots=test_slots)
|
|
resp = await t.generate(
|
|
utter_action=utter_action,
|
|
tracker=tracker,
|
|
output_channel="",
|
|
)
|
|
assert resp.get("text") == test_responses[1][utter_action][0]["text"]
|
|
|
|
|
|
async def test_matches_filled_slots_multiple_conditions_neg_match_boolean_slot(
|
|
test_slots: List[object], test_responses: List[Dict[Text, List[Dict[Text, Any]]]]
|
|
):
|
|
t = TemplatedNaturalLanguageGenerator(responses=test_responses[1])
|
|
test_slots[1].initial_value = True
|
|
tracker = DialogueStateTracker(sender_id="test_nlg", slots=test_slots)
|
|
resp = await t.generate(
|
|
utter_action="utter_action_multiple_conditions",
|
|
tracker=tracker,
|
|
output_channel="",
|
|
)
|
|
assert resp is None
|
|
|
|
|
|
async def test_matches_filled_slots_multiple_conditions_neg_match_in_first_slot(
|
|
test_slots: List[object], test_responses: List[Dict[Text, List[Dict[Text, Any]]]]
|
|
):
|
|
t = TemplatedNaturalLanguageGenerator(responses=test_responses[1])
|
|
test_slots[0].initial_value = "junk"
|
|
tracker = DialogueStateTracker(sender_id="test_nlg", slots=test_slots)
|
|
resp = await t.generate(
|
|
utter_action="utter_action_multiple_conditions",
|
|
tracker=tracker,
|
|
output_channel="",
|
|
)
|
|
assert resp is None
|
|
|
|
|
|
async def test_matches_filled_slots_multiple_conditions_neg_match_in_last_slot(
|
|
test_slots: List[object], test_responses: List[Dict[Text, List[Dict[Text, Any]]]]
|
|
):
|
|
t = TemplatedNaturalLanguageGenerator(responses=test_responses[1])
|
|
test_slots[2].initial_value = "junk"
|
|
tracker = DialogueStateTracker(sender_id="test_nlg", slots=test_slots)
|
|
resp = await t.generate(
|
|
utter_action="utter_action_multiple_conditions",
|
|
tracker=tracker,
|
|
output_channel="",
|
|
)
|
|
assert resp is None
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("slot_name", "slot_value", "response_variation"),
|
|
(("test", "A", "example one A"), ("test", "B", "example two B")),
|
|
)
|
|
async def test_nlg_conditional_response_variations_with_interpolated_slots(
|
|
slot_name: Text, slot_value: Any, response_variation: Text
|
|
):
|
|
responses = {
|
|
"utter_action": [
|
|
{
|
|
"text": "example one {test}",
|
|
"condition": [{"type": "slot", "name": "test", "value": "A"}],
|
|
},
|
|
{
|
|
"text": "example two {test}",
|
|
"condition": [{"type": "slot", "name": "test", "value": "B"}],
|
|
},
|
|
]
|
|
}
|
|
t = TemplatedNaturalLanguageGenerator(responses=responses)
|
|
slot = TextSlot(
|
|
name=slot_name,
|
|
mappings=[{}],
|
|
initial_value=slot_value,
|
|
influence_conversation=False,
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="nlg_interpolated", slots=[slot])
|
|
|
|
r = await t.generate(
|
|
utter_action="utter_action", tracker=tracker, output_channel=""
|
|
)
|
|
assert r.get("text") == response_variation
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("slot_name", "slot_value", "bot_message"),
|
|
(
|
|
(
|
|
"can_withdraw",
|
|
False,
|
|
"You are not allowed to withdraw any amounts. Please check permission.",
|
|
),
|
|
(
|
|
"account_type",
|
|
"secondary",
|
|
"Withdrawal was sent for approval to primary account holder.",
|
|
),
|
|
),
|
|
)
|
|
async def test_nlg_conditional_response_variations_with_yaml_single_condition(
|
|
slot_name: Text, slot_value: Any, bot_message: Text
|
|
):
|
|
domain = Domain.from_file(
|
|
path="data/test_domains/conditional_response_variations.yml"
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(responses=domain.responses)
|
|
|
|
slot = AnySlot(
|
|
name=slot_name,
|
|
mappings=[{}],
|
|
initial_value=slot_value,
|
|
influence_conversation=False,
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="conversation_id", slots=[slot])
|
|
|
|
r = await t.generate(
|
|
utter_action="utter_withdraw", tracker=tracker, output_channel=""
|
|
)
|
|
assert r.get("text") == bot_message
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_with_yaml_multi_constraints():
|
|
domain = Domain.from_file(
|
|
path="data/test_domains/conditional_response_variations.yml"
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(responses=domain.responses)
|
|
|
|
first_slot = CategoricalSlot(
|
|
name="account_type",
|
|
mappings=[{}],
|
|
initial_value="primary",
|
|
influence_conversation=False,
|
|
)
|
|
second_slot = BooleanSlot(
|
|
name="can_withdraw",
|
|
mappings=[{}],
|
|
initial_value=True,
|
|
influence_conversation=False,
|
|
)
|
|
tracker = DialogueStateTracker(
|
|
sender_id="conversation_id", slots=[first_slot, second_slot]
|
|
)
|
|
r = await t.generate(
|
|
utter_action="utter_withdraw", tracker=tracker, output_channel=""
|
|
)
|
|
assert r.get("text") == "Withdrawal has been approved."
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_with_yaml_and_channel():
|
|
domain = Domain.from_file(
|
|
path="data/test_domains/conditional_response_variations.yml"
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(responses=domain.responses)
|
|
|
|
slot = CategoricalSlot(
|
|
name="account_type",
|
|
mappings=[{}],
|
|
initial_value="primary",
|
|
influence_conversation=False,
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="conversation_id", slots=[slot])
|
|
|
|
r = await t.generate(
|
|
utter_action="utter_check_balance", tracker=tracker, output_channel="os"
|
|
)
|
|
assert (
|
|
r.get("text") == "As a primary account holder, you can now set-up "
|
|
"your access on mobile app too."
|
|
)
|
|
|
|
resp = await t.generate(
|
|
utter_action="utter_check_balance", tracker=tracker, output_channel="app"
|
|
)
|
|
assert resp.get("text") == "Welcome to your app account overview."
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("slot_name", "slot_value", "message"),
|
|
(
|
|
("test_bool", True, "example boolean"),
|
|
("test_int", 12, "example integer"),
|
|
("test_list", [], "example list"),
|
|
),
|
|
)
|
|
async def test_nlg_conditional_response_variations_with_diff_slot_types(
|
|
slot_name: Text, slot_value: Any, message: Text
|
|
):
|
|
responses = {
|
|
"utter_action": [
|
|
{
|
|
"text": "example boolean",
|
|
"condition": [{"type": "slot", "name": "test_bool", "value": True}],
|
|
},
|
|
{
|
|
"text": "example integer",
|
|
"condition": [{"type": "slot", "name": "test_int", "value": 12}],
|
|
},
|
|
{
|
|
"text": "example list",
|
|
"condition": [{"type": "slot", "name": "test_list", "value": []}],
|
|
},
|
|
]
|
|
}
|
|
t = TemplatedNaturalLanguageGenerator(responses=responses)
|
|
slot = AnySlot(
|
|
name=slot_name,
|
|
mappings=[{}],
|
|
initial_value=slot_value,
|
|
influence_conversation=False,
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="nlg_tracker", slots=[slot])
|
|
|
|
r = await t.generate(
|
|
utter_action="utter_action", tracker=tracker, output_channel=""
|
|
)
|
|
assert r.get("text") == message
|
|
|
|
|
|
async def test_nlg_non_matching_channel():
|
|
domain = Domain.from_yaml(
|
|
"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_hi:
|
|
- text: "Hello"
|
|
- text: "Hello Slack"
|
|
channel: "slack"
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=[])
|
|
r = await t.generate("utter_hi", tracker, "signal")
|
|
assert r.get("text") == "Hello"
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_with_none_slot():
|
|
domain = Domain.from_yaml(
|
|
f"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_action:
|
|
- text: "text A"
|
|
condition:
|
|
- type: slot
|
|
name: account
|
|
value: "A"
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
slot = AnySlot(
|
|
name="account", mappings=[{}], initial_value=None, influence_conversation=False
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=[slot])
|
|
r = await t.generate("utter_action", tracker, "")
|
|
assert r is None
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_with_slot_not_a_constraint():
|
|
domain = Domain.from_yaml(
|
|
f"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_action:
|
|
- text: "text A"
|
|
condition:
|
|
- type: slot
|
|
name: account
|
|
value: "A"
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
slot = TextSlot(
|
|
name="account", mappings=[{}], initial_value="B", influence_conversation=False
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=[slot])
|
|
r = await t.generate("utter_action", tracker, "")
|
|
assert r is None
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_with_null_slot():
|
|
domain = Domain.from_yaml(
|
|
f"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_action:
|
|
- text: "text for null"
|
|
condition:
|
|
- type: slot
|
|
name: account
|
|
value: null
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
slot = AnySlot(
|
|
name="account", mappings=[{}], initial_value=None, influence_conversation=False
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=[slot])
|
|
r = await t.generate("utter_action", tracker, "")
|
|
assert r.get("text") == "text for null"
|
|
|
|
tracker_no_slots = DialogueStateTracker(sender_id="new_test", slots=[])
|
|
r = await t.generate("utter_action", tracker_no_slots, "")
|
|
assert r.get("text") == "text for null"
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_channel_no_condition_met():
|
|
domain = Domain.from_yaml(
|
|
f"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_action:
|
|
- text: "example with channel"
|
|
condition:
|
|
- type: slot
|
|
name: test
|
|
value: A
|
|
channel: os
|
|
- text: "default"
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=[])
|
|
r = await t.generate("utter_action", tracker, "os")
|
|
assert r.get("text") == "default"
|
|
|
|
|
|
async def test_nlg_conditional_response_variation_condition_met_channel_mismatch():
|
|
domain = Domain.from_yaml(
|
|
f"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_action:
|
|
- text: "example with channel"
|
|
condition:
|
|
- type: slot
|
|
name: test
|
|
value: A
|
|
channel: os
|
|
- text: "app default"
|
|
channel: app
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
slot = TextSlot(
|
|
"test", mappings=[{}], initial_value="A", influence_conversation=False
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=[slot])
|
|
r = await t.generate("utter_action", tracker, "app")
|
|
assert r.get("text") == "app default"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"slots,channel,expected_response",
|
|
[
|
|
(
|
|
[
|
|
TextSlot(
|
|
"test",
|
|
mappings=[{}],
|
|
initial_value="B",
|
|
influence_conversation=False,
|
|
)
|
|
],
|
|
"app",
|
|
"condition example B no channel",
|
|
),
|
|
(
|
|
[
|
|
TextSlot(
|
|
"test",
|
|
mappings=[{}],
|
|
initial_value="C",
|
|
influence_conversation=False,
|
|
)
|
|
],
|
|
"",
|
|
"default",
|
|
),
|
|
(
|
|
[
|
|
TextSlot(
|
|
"test",
|
|
mappings=[{}],
|
|
initial_value="D",
|
|
influence_conversation=False,
|
|
)
|
|
],
|
|
"app",
|
|
"default",
|
|
),
|
|
],
|
|
)
|
|
async def test_nlg_conditional_edgecases(slots, channel, expected_response):
|
|
domain = Domain.from_yaml(
|
|
f"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_action:
|
|
- text: "condition example A with channel"
|
|
condition:
|
|
- type: slot
|
|
name: test
|
|
value: A
|
|
channel: app
|
|
|
|
- text: "condition example C with channel"
|
|
condition:
|
|
- type: slot
|
|
name: test
|
|
value: C
|
|
channel: app
|
|
|
|
- text: "condition example A no channel"
|
|
condition:
|
|
- type: slot
|
|
name: test
|
|
value: A
|
|
|
|
- text: "condition example B no channel"
|
|
condition:
|
|
- type: slot
|
|
name: test
|
|
value: B
|
|
|
|
- text: "default"
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=slots)
|
|
r = await t.generate("utter_action", tracker, channel)
|
|
assert r.get("text") == expected_response
|
|
|
|
|
|
async def test_nlg_conditional_response_variations_condition_logging(
|
|
caplog: LogCaptureFixture,
|
|
):
|
|
domain = Domain.from_yaml(
|
|
f"""
|
|
version: "{LATEST_TRAINING_DATA_FORMAT_VERSION}"
|
|
responses:
|
|
utter_action:
|
|
- text: "example"
|
|
condition:
|
|
- type: slot
|
|
name: test_A
|
|
value: A
|
|
- type: slot
|
|
name: test_B
|
|
value: B
|
|
- text: "default"
|
|
"""
|
|
)
|
|
t = TemplatedNaturalLanguageGenerator(domain.responses)
|
|
slot_A = TextSlot(
|
|
name="test_A", mappings=[{}], initial_value="A", influence_conversation=False
|
|
)
|
|
slot_B = TextSlot(
|
|
name="test_B", mappings=[{}], initial_value="B", influence_conversation=False
|
|
)
|
|
tracker = DialogueStateTracker(sender_id="test", slots=[slot_A, slot_B])
|
|
|
|
with caplog.at_level(logging.DEBUG):
|
|
await t.generate("utter_action", tracker=tracker, output_channel="")
|
|
|
|
assert any(
|
|
"Selecting response variation with conditions:" in message
|
|
for message in caplog.messages
|
|
)
|
|
assert any(
|
|
"[condition 1] type: slot | name: test_A | value: A" in message
|
|
for message in caplog.messages
|
|
)
|
|
assert any(
|
|
"[condition 2] type: slot | name: test_B | value: B" in message
|
|
for message in caplog.messages
|
|
)
|