async def test_activate_and_immediate_deactivate(): slot_name = "num_people" slot_value = 5 tracker = DialogueStateTracker.from_events( sender_id="bla", evts=[ ActionExecuted(ACTION_LISTEN_NAME), UserUttered( "haha", {"name": "greet"}, entities=[{ "entity": slot_name, "value": slot_value }], ), ], ) form_name = "my form" action = FormAction(form_name, None) domain = f""" forms: - {form_name}: {slot_name}: - type: from_entity entity: {slot_name} slots: {slot_name}: type: unfeaturized """ domain = Domain.from_yaml(domain) events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert events == [ Form(form_name), SlotSet(slot_name, slot_value), SlotSet(REQUESTED_SLOT, None), Form(None), ]
def test_extract_requested_slot_default(): """Test default extraction of a slot value from entity with the same name.""" form = FormAction("some form", None) tracker = DialogueStateTracker.from_events( "default", [ SlotSet(REQUESTED_SLOT, "some_slot"), UserUttered("bla", entities=[{ "entity": "some_slot", "value": "some_value" }]), ActionExecuted(ACTION_LISTEN_NAME), ], ) slot_values = form.extract_requested_slot(tracker, Domain.empty()) assert slot_values == {"some_slot": "some_value"}
def _create_from_endpoint_config( endpoint_config: Optional[EndpointConfig] = None, domain: Optional[Domain] = None, event_broker: Optional[EventBroker] = None, ) -> "TrackerStore": """Given an endpoint configuration, create a proper tracker store object.""" domain = domain or Domain.empty() if endpoint_config is None or endpoint_config.type is None: # default tracker store if no type is set tracker_store = InMemoryTrackerStore(domain, event_broker) elif endpoint_config.type.lower() == "redis": tracker_store = RedisTrackerStore( domain=domain, host=endpoint_config.url, event_broker=event_broker, **endpoint_config.kwargs, ) elif endpoint_config.type.lower() == "mongod": tracker_store = MongoTrackerStore( domain=domain, host=endpoint_config.url, event_broker=event_broker, **endpoint_config.kwargs, ) elif endpoint_config.type.lower() == "sql": tracker_store = SQLTrackerStore( domain=domain, host=endpoint_config.url, event_broker=event_broker, **endpoint_config.kwargs, ) elif endpoint_config.type.lower() == "dynamo": tracker_store = DynamoTrackerStore( domain=domain, event_broker=event_broker, **endpoint_config.kwargs ) else: tracker_store = _load_from_module_string(domain, endpoint_config, event_broker) logger.debug(f"Connected to {tracker_store.__class__.__name__}.") return tracker_store
async def test_agent_train(trained_moodbot_path: Text): moodbot_domain = Domain.load("examples/moodbot/domain.yml") loaded = Agent.load(trained_moodbot_path) # test domain assert loaded.domain.action_names == moodbot_domain.action_names assert loaded.domain.intents == moodbot_domain.intents assert loaded.domain.entities == moodbot_domain.entities assert loaded.domain.templates == moodbot_domain.templates assert [s.name for s in loaded.domain.slots ] == [s.name for s in moodbot_domain.slots] # test policies assert isinstance(loaded.policy_ensemble, SimplePolicyEnsemble) assert [type(p) for p in loaded.policy_ensemble.policies] == [ TEDPolicy, MemoizationPolicy, MappingPolicy, ]
def test_extract_requested_slot_from_entity( mapping_not_intent: Optional[Text], mapping_intent: Optional[Text], mapping_role: Optional[Text], mapping_group: Optional[Text], entities: List[Dict[Text, Any]], intent: Text, expected_slot_values: Dict[Text, Text], ): """Test extraction of a slot value from entity with the different restrictions.""" form_name = "some form" form = FormAction(form_name, None) mapping = form.from_entity( entity="some_entity", role=mapping_role, group=mapping_group, intent=mapping_intent, not_intent=mapping_not_intent, ) domain = Domain.from_dict( {"forms": [{ form_name: { "some_slot": [mapping] } }]}) tracker = DialogueStateTracker.from_events( "default", [ SlotSet(REQUESTED_SLOT, "some_slot"), UserUttered("bla", intent={ "name": intent, "confidence": 1.0 }, entities=entities), ], ) slot_values = form.extract_requested_slot(tracker, domain) assert slot_values == expected_slot_values
def predict_action_probabilities( self, tracker: DialogueStateTracker, domain: Domain ) -> List[float]: """Predicts a fallback action. The fallback action is predicted if the NLU confidence is low or no other policy has a high-confidence prediction. """ nlu_data = tracker.latest_message.parse_data # if NLU interpreter does not provide confidence score, # it is set to 1.0 here in order # to not override standard behaviour nlu_confidence = nlu_data.get("intent", {}).get("confidence", 1.0) if tracker.latest_action_name == self.fallback_action_name: result = [0.0] * domain.num_actions idx = domain.index_for_action(ACTION_LISTEN_NAME) result[idx] = 1.0 elif self.should_nlu_fallback(nlu_confidence, tracker.latest_action_name): logger.debug( "NLU confidence {} is lower " "than NLU threshold {}. " "".format(nlu_confidence, self.nlu_threshold) ) result = self.fallback_scores(domain) else: # NLU confidence threshold is met, so # predict fallback action with confidence `core_threshold` # if this is the highest confidence in the ensemble, # the fallback action will be executed. logger.debug( "NLU confidence threshold met, confidence of " "fallback action set to core threshold ({}).".format( self.core_threshold ) ) result = self.fallback_scores(domain, self.core_threshold) return result
def _load_and_set_updated_model( agent: "Agent", model_directory: Text, fingerprint: Text ): """Load the persisted model into memory and set the model on the agent.""" logger.debug(f"Found new model with fingerprint {fingerprint}. Loading...") # bf mod core_path, nlu_paths = get_model_subdirectories(model_directory) interpreter = {} # If NLU models exist then create interpreter from them if len(nlu_paths): for lang, nlu_path in nlu_paths.items(): interpreter[lang] = NaturalLanguageInterpreter.create(os.path.join(model_directory, nlu_path)) # If no NLU models exist, then associate a RegexInterpreter to the language code found in the fingerprints, # that should correspond to the default language in Botfront. This is to make sure an interpreter is available # when training stories without NLU else: from rasa.model import fingerprint_from_path, FINGERPRINT_CONFIG_NLU_KEY models_fingerprint = fingerprint_from_path(model_directory) if len(models_fingerprint.get(FINGERPRINT_CONFIG_NLU_KEY).keys()): interpreter = {list(models_fingerprint.get(FINGERPRINT_CONFIG_NLU_KEY).keys())[0]: RegexInterpreter()} # /bf mod domain = None if core_path: domain_path = os.path.join(os.path.abspath(core_path), DEFAULT_DOMAIN_PATH) domain = Domain.load(domain_path) try: policy_ensemble = None if core_path: policy_ensemble = PolicyEnsemble.load(core_path) agent.update_model( domain, policy_ensemble, fingerprint, interpreter, model_directory ) logger.debug("Finished updating agent to new model.") except Exception: logger.exception( "Failed to load policy and update agent. " "The previous model will stay loaded instead." )
async def test_only_getting_e2e_conversation_tests_if_e2e_enabled( tmp_path: Path, test_stories_filename: Text, test_story: Text ): from rasa.core.training.structures import StoryGraph import rasa.core.training.loading as core_loading config = {"imports": ["bots/Bot A"]} config_path = str(tmp_path / "config.yml") utils.dump_obj_as_yaml_to_file(config_path, config) story_file = tmp_path / "bots" / "Bot A" / "data" / "stories.md" story_file.parent.mkdir(parents=True) rasa.shared.utils.io.write_text_file( """ ## story * greet - utter_greet """, story_file, ) story_test_file = ( tmp_path / "bots" / "Bot A" / DEFAULT_E2E_TESTS_PATH / test_stories_filename ) story_test_file.parent.mkdir(parents=True) rasa.shared.utils.io.write_text_file(test_story, story_test_file) selector = MultiProjectImporter(config_path) story_steps = await core_loading.load_data_from_resource( resource=str(story_test_file), domain=Domain.empty(), template_variables=None, use_e2e=True, exclusion_percentage=None, ) expected = StoryGraph(story_steps) actual = await selector.get_stories(use_e2e=True) assert expected.as_story_string() == actual.as_story_string()
async def test_2nd_affirm_successful(): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ # User sends message with low NLU confidence *_message_requiring_fallback(), ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User denies suggested intents UserUttered("hi", {"name": USER_INTENT_OUT_OF_SCOPE}), # Action asks user to rephrase *_two_stage_clarification_request(), # User rephrased with low confidence *_message_requiring_fallback(), *_two_stage_clarification_request(), # Actions asks user to affirm for the last time ActionExecuted(ACTION_LISTEN_NAME), # User affirms successfully UserUttered("hi", {"name": "greet"}), ], ) domain = Domain.empty() action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) for event in events: tracker.update(event) applied_events = tracker.applied_events() assert applied_events == [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("hi", {"name": "greet"}), ]
async def test_trigger_slot_mapping_applies( trigger_slot_mapping: Dict, expected_value: Text ): form_name = "some_form" entity_name = "some_slot" slot_filled_by_trigger_mapping = "other_slot" form = FormAction(form_name, None) domain = Domain.from_dict( { "forms": [ { form_name: { entity_name: [ { "type": "from_entity", "entity": entity_name, "intent": "some_intent", } ], slot_filled_by_trigger_mapping: [trigger_slot_mapping], } } ] } ) tracker = DialogueStateTracker.from_events( "default", [ SlotSet(REQUESTED_SLOT, "some_slot"), UserUttered( "bla", intent={"name": "greet", "confidence": 1.0}, entities=[{"entity": entity_name, "value": "some_value"}], ), ActionExecuted(ACTION_LISTEN_NAME), ], ) slot_values = form.extract_other_slots(tracker, domain) assert slot_values == {slot_filled_by_trigger_mapping: expected_value}
async def test_predict_action_listen_after_form(): form_name = "some_form" domain = Domain.from_yaml( f""" intents: - {GREET_INTENT_NAME} actions: - {UTTER_GREET_ACTION} - some-action slots: {REQUESTED_SLOT}: type: unfeaturized forms: - {form_name} """ ) policy = RulePolicy() policy.train([GREET_RULE], domain, RegexInterpreter()) form_conversation = DialogueStateTracker.from_events( "in a form", evts=[ # We are in an activate form ActionExecuted(form_name), Form(form_name), SlotSet(REQUESTED_SLOT, "some value"), ActionExecuted(ACTION_LISTEN_NAME), # User sends message as response to a requested slot UserUttered("haha", {"name": GREET_INTENT_NAME}), # Form is running again ActionExecuted(form_name), ], slots=domain.slots, ) # RulePolicy predicts action listen action_probabilities = policy.predict_action_probabilities( form_conversation, domain ) assert_predicted_action(action_probabilities, domain, ACTION_LISTEN_NAME)
async def test_fingerprinting_changed_response_text(project: Text): importer = _project_files(project) old_fingerprint = await model_fingerprint(importer) old_domain = await importer.get_domain() # Change NLG content but keep actions the same domain_with_changed_nlg = old_domain.as_dict() domain_with_changed_nlg[KEY_RESPONSES]["utter_greet"].append( {"text": "hi"}) domain_with_changed_nlg = Domain.from_dict(domain_with_changed_nlg) importer.get_domain = asyncio.coroutine(lambda: domain_with_changed_nlg) new_fingerprint = await model_fingerprint(importer) assert (old_fingerprint[FINGERPRINT_DOMAIN_WITHOUT_NLG_KEY] == new_fingerprint[FINGERPRINT_DOMAIN_WITHOUT_NLG_KEY]) assert old_fingerprint[FINGERPRINT_NLG_KEY] != new_fingerprint[ FINGERPRINT_NLG_KEY]
def __init__(self): """ self.stories : is graph of stories self.intents : is intents which define in NLU self.history_send_id : saved history of intent previous which classify user message belong intents self.states : is state of user """ with open(PATH_CONFIG, "r") as file_config: self.config = json.load(file_config) if PATH_CONFIG_GRAPH is None: logger.debug("path config not exits") else: with open(PATH_CONFIG_GRAPH, "rb") as file_config_graph: self.stories = pickle.load(file_config_graph) if PATH_DOMAIN is None: logger.debug("path domain not exits") else: self.intents = Domain.load(PATH_DOMAIN).intents self.history_send_id = {} self.states = {}
async def test_filter_intents_before_save_nlu_file(): # Test method interactive._filter_messages from random import choice greet = {"intent": "greet", "text_features": [0.5]} goodbye = {"intent": "goodbye", "text_features": [0.5]} test_msgs = [ Message("How are you?", greet), Message("I am inevitable", goodbye) ] domain_file = DEFAULT_DOMAIN_PATH_WITH_SLOTS domain = Domain.load(domain_file) intents = domain.intents msgs = test_msgs.copy() if intents: msgs.append(Message("/" + choice(intents), greet)) assert test_msgs == interactive._filter_messages(msgs)
def test_fallback_wins_over_mapping(): domain = Domain.load("data/test_domains/default.yml") events = [ ActionExecuted(ACTION_LISTEN_NAME), # Low confidence should trigger fallback utilities.user_uttered(USER_INTENT_RESTART, 0.0001), ] tracker = DialogueStateTracker.from_events("test", events, []) ensemble = SimplePolicyEnsemble([FallbackPolicy(), MappingPolicy()]) result, best_policy = ensemble.probabilities_using_best_policy( tracker, domain, RegexInterpreter() ) max_confidence_index = result.index(max(result)) index_of_fallback_policy = 0 next_action = domain.action_for_index(max_confidence_index, None) assert best_policy == f"policy_{index_of_fallback_policy}_{FallbackPolicy.__name__}" assert next_action.name() == ACTION_DEFAULT_FALLBACK_NAME
def _load_domain_and_policy_ensemble( core_path: Optional[Text], ) -> Tuple[Optional[Domain], Optional[PolicyEnsemble]]: """Load the domain and policy ensemble from the model at `core_path`. Args: core_path: Core model path. Returns: An instance of `Domain` and `PolicyEnsemble` if `core_path` is not `None`. """ policy_ensemble = None domain = None if core_path: policy_ensemble = PolicyEnsemble.load(core_path) domain_path = os.path.join(os.path.abspath(core_path), DEFAULT_DOMAIN_PATH) domain = Domain.load(domain_path) return domain, policy_ensemble
async def test_ask_for_slot(domain: Dict, expected_action: Text, monkeypatch: MonkeyPatch): slot_name = "sun" action_from_name = Mock(return_value=action.ActionListen()) endpoint_config = Mock() monkeypatch.setattr(action, action.action_from_name.__name__, action_from_name) form = FormAction("my_form", endpoint_config) await form._ask_for_slot( Domain.from_dict(domain), None, None, slot_name, DialogueStateTracker.from_events("dasd", []), ) action_from_name.assert_called_once_with(expected_action, endpoint_config, ANY)
async def model_fingerprint(file_importer: "TrainingDataImporter") -> Fingerprint: """Create a model fingerprint from its used configuration and training data. Args: file_importer: File importer which provides the training data and model config. Returns: The fingerprint. """ from rasa.core.domain import Domain import rasa import time config = await file_importer.get_config() domain = await file_importer.get_domain() stories = await file_importer.get_stories() nlu_data = await file_importer.get_nlu_data() domain_dict = domain.as_dict() templates = domain_dict.pop("templates") domain_without_nlg = Domain.from_dict(domain_dict) return { FINGERPRINT_CONFIG_KEY: _get_hash_of_config( config, exclude_keys=CONFIG_MANDATORY_KEYS ), FINGERPRINT_CONFIG_CORE_KEY: _get_hash_of_config( config, include_keys=CONFIG_MANDATORY_KEYS_CORE ), FINGERPRINT_CONFIG_NLU_KEY: _get_hash_of_config( config, include_keys=CONFIG_MANDATORY_KEYS_NLU ), FINGERPRINT_DOMAIN_WITHOUT_NLG_KEY: hash(domain_without_nlg), FINGERPRINT_NLG_KEY: get_dict_hash(templates), FINGERPRINT_NLU_DATA_KEY: hash(nlu_data), FINGERPRINT_STORIES_KEY: hash(stories), FINGERPRINT_TRAINED_AT_KEY: time.time(), FINGERPRINT_RASA_VERSION_KEY: rasa.__version__, }
def _best_policy_prediction( self, tracker: DialogueStateTracker, domain: Domain, interpreter: NaturalLanguageInterpreter, ) -> Tuple[Optional[List[float]], Optional[Text]]: """Finds the best policy prediction. Args: tracker: the :class:`rasa.core.trackers.DialogueStateTracker` domain: the :class:`rasa.core.domain.Domain` interpreter: Interpreter which may be used by the policies to create additional features. Returns: probabilities: the list of probabilities for the next actions policy_name: the name of the picked policy """ # find rejected action before running the policies # because some of them might add events rejected_action_name = None if len(tracker.events) > 0 and isinstance(tracker.events[-1], ActionExecutionRejected): rejected_action_name = tracker.events[-1].action_name predictions = { f"policy_{i}_{type(p).__name__}": self._get_prediction(p, tracker, domain, interpreter) for i, p in enumerate(self.policies) } if rejected_action_name: logger.debug( f"Execution of '{rejected_action_name}' was rejected. " f"Setting its confidence to 0.0 in all predictions.") for prediction in predictions.values(): prediction.probabilities[domain.index_for_action( rejected_action_name)] = 0.0 return self._pick_best_policy(predictions)
async def test_multi_skill_training(): example_directory = "data/test_multi_domain" config_file = os.path.join(example_directory, "config.yml") domain_file = os.path.join(example_directory, "domain.yml") files_of_root_project = os.path.join(example_directory, "data") trained_stack_model_path = await train_async( config=config_file, domain=domain_file, training_files=files_of_root_project) unpacked = model.unpack_model(trained_stack_model_path) domain_file = os.path.join(unpacked, "core", "domain.yml") domain = Domain.load(domain_file) expected_intents = { "greet", "goodbye", "affirm", "deny", "mood_great", "mood_unhappy", } assert all([i in domain.intents for i in expected_intents]) nlu_training_data_file = os.path.join(unpacked, "nlu", "training_data.json") nlu_training_data = RasaReader().read(nlu_training_data_file) assert expected_intents == nlu_training_data.intents expected_actions = [ "utter_greet", "utter_cheer_up", "utter_did_that_help", "utter_happy", "utter_goodbye", ] assert all([a in domain.action_names for a in expected_actions])
async def test_loop_without_deactivate(): expected_activation_events = [ ActionExecutionRejected("tada"), ActionExecuted("test"), ] expected_do_events = [ActionExecuted("do")] form_name = "my form" class MyLoop(LoopAction): def name(self) -> Text: return form_name async def activate(self, *args: Any) -> List[Event]: return expected_activation_events async def do(self, *args: Any) -> List[Event]: return expected_do_events async def deactivate(self, *args) -> List[Event]: raise ValueError("this shouldn't be called") async def is_done(self, *args) -> bool: return False tracker = DialogueStateTracker.from_events("some sender", []) domain = Domain.empty() action = MyLoop() actual = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert actual == [ ActiveLoop(form_name), *expected_activation_events, *expected_do_events, ]
async def test_form_unhappy_path_without_rule(): form_name = "some_form" other_intent = "bye" domain = Domain.from_yaml( f""" intents: - {GREET_INTENT_NAME} - {other_intent} actions: - {UTTER_GREET_ACTION} - some-action slots: {REQUESTED_SLOT}: type: unfeaturized forms: - {form_name} """ ) policy = RulePolicy() policy.train([GREET_RULE], domain, RegexInterpreter()) conversation_events = [ ActionExecuted(form_name), Form(form_name), SlotSet(REQUESTED_SLOT, "some value"), ActionExecuted(ACTION_LISTEN_NAME), UserUttered("haha", {"name": other_intent}), Form(form_name), ActionExecutionRejected(form_name), ] # Unhappy path is not handled. No rule matches. Let's hope ML fixes our problems 🤞 action_probabilities = policy.predict_action_probabilities( DialogueStateTracker.from_events( "casd", evts=conversation_events, slots=domain.slots ), domain, ) assert max(action_probabilities) == policy._core_fallback_threshold
def test_tracker_store_retrieve_with_events_from_previous_sessions( tracker_store_type: Type[TrackerStore], tracker_store_kwargs: Dict): tracker_store = tracker_store_type(Domain.empty(), **tracker_store_kwargs) tracker_store.load_events_from_previous_conversation_sessions = True conversation_id = uuid.uuid4().hex tracker = DialogueStateTracker.from_events( conversation_id, [ ActionExecuted(ACTION_SESSION_START_NAME), SessionStarted(), UserUttered("hi"), ActionExecuted(ACTION_SESSION_START_NAME), SessionStarted(), ], ) tracker_store.save(tracker) actual = tracker_store.retrieve(conversation_id) assert len(actual.events) == len(tracker.events)
def test_extract_requested_slot_from_entity_no_intent(): """Test extraction of a slot value from entity with the different name and any intent """ spec = { "name": "default_form", "slots": [{ "name": "some_slot", "filling": [{ "type": "from_entity", "entity": ["some_entity"] }] }] } form, tracker = new_form_and_tracker(spec, "some_slot") tracker.update(UserUttered(entities=[{"entity": "some_entity", "value": "some_value"}])) slot_values = form.extract_requested_slot(OutputChannel(), nlg, tracker, Domain.empty()) assert slot_values == {"some_slot": "some_value"}
def _get_old_tracker_store(endpoints_file: Text) -> TrackerStore: if (not endpoints_file or not os.path.isfile(endpoints_file) or not os.path.exists(endpoints_file)): print_error( "File '{}' was not found. Please specify a valid file with " "'--endpoints <file>'.".format(endpoints_file)) exit(1) endpoints = AvailableEndpoints.read_endpoints(endpoints_file) tracker_store = TrackerStore.find_tracker_store(Domain.empty(), endpoints.tracker_store) if not tracker_store or isinstance(tracker_store, InMemoryTrackerStore): print_error( "No valid tracker store config given. Please provide a valid " "tracker store configuration as it is described here: " "https://rasa.com/docs/core/0.14.4/tracker_stores/") exit(1) return tracker_store
def test_get_next_action_probabilities_pass_policy_predictions_without_interpreter_arg( predict_function: Callable, ): policy = TEDPolicy() policy.predict_action_probabilities = predict_function ensemble = SimplePolicyEnsemble(policies=[policy]) interpreter = Mock() domain = Domain.empty() processor = MessageProcessor( interpreter, ensemble, domain, InMemoryTrackerStore(domain), Mock() ) with pytest.warns(DeprecationWarning): processor._get_next_action_probabilities( DialogueStateTracker.from_events( "lala", [ActionExecuted(ACTION_LISTEN_NAME)] ) )
def probabilities_using_best_policy( self, tracker: DialogueStateTracker, domain: Domain, interpreter: NaturalLanguageInterpreter, **kwargs: Any, ) -> Tuple[Optional[List[float]], Optional[Text]]: """Predicts the next action the bot should take after seeing the tracker. Picks the best policy prediction based on probabilities and policy priority. Triggers fallback if `action_listen` is predicted after a user utterance. Args: tracker: the :class:`rasa.core.trackers.DialogueStateTracker` domain: the :class:`rasa.core.domain.Domain` interpreter: Interpreter which may be used by the policies to create additional features. Returns: best_probabilities: the list of probabilities for the next actions best_policy_name: the name of the picked policy """ probabilities, policy_name = self._best_policy_prediction( tracker, domain, interpreter ) if ( tracker.latest_action_name == ACTION_LISTEN_NAME and probabilities is not None and probabilities.index(max(probabilities)) == domain.index_for_action(ACTION_LISTEN_NAME) and self.is_not_memo_policy(policy_name, max(probabilities)) ): probabilities, policy_name = self._fallback_after_listen( domain, probabilities, policy_name ) logger.debug(f"Predicted next action using {policy_name}") return probabilities, policy_name
async def test_form_unhappy_path(): form_name = "some_form" domain = Domain.from_yaml(f""" intents: - {GREET_INTENT_NAME} actions: - {UTTER_GREET_ACTION} - some-action slots: {REQUESTED_SLOT}: type: unfeaturized forms: - {form_name} """) policy = RulePolicy() policy.train([GREET_RULE], domain, RegexInterpreter()) unhappy_form_conversation = DialogueStateTracker.from_events( "in a form", evts=[ # We are in an active form ActionExecuted(form_name), ActiveLoop(form_name), SlotSet(REQUESTED_SLOT, "some value"), # User responds to slot request ActionExecuted(ACTION_LISTEN_NAME), UserUttered("haha", {"name": GREET_INTENT_NAME}), # Form isn't happy with the answer and rejects execution ActionExecutionRejected(form_name), ], slots=domain.slots, ) # RulePolicy doesn't trigger form but FAQ action_probabilities = policy.predict_action_probabilities( unhappy_form_conversation, domain, RegexInterpreter()) assert_predicted_action(action_probabilities, domain, UTTER_GREET_ACTION)
async def get_response(self, request): """Train the engine. """ if self.config.get('domain') is None: self.config.setdefault( 'domain', Domain.from_file("data/" + self.config['skill-id'] + "/core/model")) self.config.setdefault( 'tracker_store', ArcusTrackerStore(self.config.get('domain'), self.asm)) domain = self.config.get('domain') tracker_store = self.config.get('tracker_store') nlg = NaturalLanguageGenerator.create(None, domain) policy_ensemble = SimplePolicyEnsemble.load("data/" + self.config['skill-id'] + "/core") interpreter = LocalNLUInterpreter(request) url = 'http://localhost:8080/api/v1/skill/generic_action' processor = MessageProcessor(interpreter, policy_ensemble, domain, tracker_store, nlg, action_endpoint=EndpointConfig(url), message_preprocessor=None) message_nlu = UserMessage(request['text'], None, request['user'], input_channel=request['channel']) result = await processor.handle_message(message_nlu) if result is not None and len(result) > 0: return {"text": result[0]['text']} else: _LOGGER.info(result) return {"text": "error"}
def test_load_domain_from_directory_tree(tmpdir_factory: TempdirFactory): root = tmpdir_factory.mktemp("Parent Bot") root_domain = {"actions": ["utter_root", "utter_root2"]} utils.dump_obj_as_yaml_to_file(root / "domain.yml", root_domain) subdirectory_1 = root / "Skill 1" subdirectory_1.mkdir() skill_1_domain = {"actions": ["utter_skill_1"]} utils.dump_obj_as_yaml_to_file(subdirectory_1 / "domain.yml", skill_1_domain) subdirectory_2 = root / "Skill 2" subdirectory_2.mkdir() skill_2_domain = {"actions": ["utter_skill_2"]} utils.dump_obj_as_yaml_to_file(subdirectory_2 / "domain.yml", skill_2_domain) subsubdirectory = subdirectory_2 / "Skill 2-1" subsubdirectory.mkdir() skill_2_1_domain = {"actions": ["utter_subskill", "utter_root"]} # Check if loading from `.yaml` also works utils.dump_obj_as_yaml_to_file(subsubdirectory / "domain.yaml", skill_2_1_domain) subsubdirectory_2 = subdirectory_2 / "Skill 2-2" subsubdirectory_2.mkdir() excluded_domain = {"actions": ["should not be loaded"]} utils.dump_obj_as_yaml_to_file(subsubdirectory_2 / "other_name.yaml", excluded_domain) actual = Domain.load(str(root)) expected = [ "utter_root", "utter_root2", "utter_skill_1", "utter_skill_2", "utter_subskill", ] assert set(actual.user_actions) == set(expected)