def __init__( self, domain: Union[Text, Domain, None] = None, policies: Union[PolicyEnsemble, List[Policy], None] = None, interpreter: Optional[NaturalLanguageInterpreter] = None, generator: Union[EndpointConfig, NaturalLanguageGenerator, None] = None, tracker_store: Optional[TrackerStore] = None, lock_store: Optional[LockStore] = None, action_endpoint: Optional[EndpointConfig] = None, fingerprint: Optional[Text] = None, model_directory: Optional[Text] = None, model_server: Optional[EndpointConfig] = None, remote_storage: Optional[Text] = None, path_to_model_archive: Optional[Text] = None, ): # Initializing variables with the passed parameters. self.domain = self._create_domain(domain) self.policy_ensemble = self._create_ensemble(policies) PolicyEnsemble.check_domain_ensemble_compatibility( self.policy_ensemble, self.domain ) self.interpreter = rasa.core.interpreter.create_interpreter(interpreter) self.nlg = NaturalLanguageGenerator.create(generator, self.domain) self.tracker_store = self.create_tracker_store(tracker_store, self.domain) self.lock_store = self._create_lock_store(lock_store) self.action_endpoint = action_endpoint self._set_fingerprint(fingerprint) self.model_directory = model_directory self.model_server = model_server self.remote_storage = remote_storage self.path_to_model_archive = path_to_model_archive
def test_policy_loading_load_returns_wrong_type(tmpdir): original_policy_ensemble = PolicyEnsemble([LoadReturnsWrongTypePolicy()]) original_policy_ensemble.train([], None) original_policy_ensemble.persist(str(tmpdir)) with pytest.raises(Exception): PolicyEnsemble.load(str(tmpdir))
def test_policy_loading_load_returns_wrong_type(tmp_path: Path): original_policy_ensemble = PolicyEnsemble([LoadReturnsWrongTypePolicy()]) original_policy_ensemble.train([], None, RegexInterpreter()) original_policy_ensemble.persist(str(tmp_path)) with pytest.raises(Exception): PolicyEnsemble.load(str(tmp_path))
def test_policy_loading_no_kwargs_with_no_context(tmp_path: Path, capsys: CaptureFixture): original_policy_ensemble = PolicyEnsemble([PolicyWithoutLoadKwargs()]) original_policy_ensemble.train([], None, RegexInterpreter()) original_policy_ensemble.persist(str(tmp_path)) with pytest.warns(FutureWarning): PolicyEnsemble.load(str(tmp_path))
def test_two_stage_fallback_without_deny_suggestion(domain, policy_config): with pytest.raises(InvalidDomain) as execinfo: Agent( domain=Domain.from_dict(domain), policies=PolicyEnsemble.from_dict(policy_config), ) assert "The intent 'out_of_scope' must be present" in str(execinfo.value)
def load(cls, path: Text, interpreter: Optional[NaturalLanguageInterpreter] = None, generator: Union[EndpointConfig, 'NLG'] = None, tracker_store: Optional['TrackerStore'] = None, action_endpoint: Optional[EndpointConfig] = None ) -> 'Agent': """Load a persisted model from the passed path.""" if not path: raise ValueError("You need to provide a valid directory where " "to load the agent from when calling " "`Agent.load`.") if os.path.isfile(path): raise ValueError("You are trying to load a MODEL from a file " "('{}'), which is not possible. \n" "The persisted path should be a directory " "containing the various model files. \n\n" "If you want to load training data instead of " "a model, use `agent.load_data(...)` " "instead.".format(path)) domain = Domain.load(os.path.join(path, "domain.yml")) ensemble = PolicyEnsemble.load(path) if path else None # ensures the domain hasn't changed between test and train domain.compare_with_specification(path) return cls(domain=domain, policies=ensemble, interpreter=interpreter, generator=generator, tracker_store=tracker_store, action_endpoint=action_endpoint)
async def test_agent_with_model_server_in_thread( model_server: TestClient, default_domain: Domain, unpacked_trained_rasa_model: Text): model_endpoint_config = EndpointConfig.from_dict({ "url": model_server.make_url("/model"), "wait_time_between_pulls": 2 }) agent = Agent() agent = await rasa.core.agent.load_from_server( agent, model_server=model_endpoint_config) await asyncio.sleep(5) assert agent.fingerprint == "somehash" assert agent.domain.as_dict() == default_domain.as_dict() expected_policies = PolicyEnsemble.load_metadata( str(Path(unpacked_trained_rasa_model, "core")))["policy_names"] agent_policies = { rasa.shared.utils.common.module_path_from_instance(p) for p in agent.policy_ensemble.policies } assert agent_policies == set(expected_policies) assert model_server.app.number_of_model_requests == 1 jobs.kill_scheduler()
def test_forms_with_suited_policy(): policy_config = {"policies": [{"name": RulePolicy.__name__}]} # Doesn't raise Agent( domain=Domain.from_dict({"forms": {"restaurant_form": {}}}), policies=PolicyEnsemble.from_dict(policy_config), )
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("Found new model with fingerprint {}. Loading..." "".format(fingerprint)) stack_model_directory = _get_stack_model_directory(model_directory) if stack_model_directory: from rasa.core.interpreter import RasaNLUInterpreter nlu_model = os.path.join(stack_model_directory, "nlu") core_model = os.path.join(stack_model_directory, "core") interpreter = RasaNLUInterpreter(model_directory=nlu_model) else: interpreter = agent.interpreter core_model = model_directory domain_path = os.path.join(os.path.abspath(core_model), "domain.yml") domain = Domain.load(domain_path) # noinspection PyBroadException try: policy_ensemble = PolicyEnsemble.load(core_model) agent.update_model(domain, policy_ensemble, fingerprint, interpreter) 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.")
def test_form_without_form_policy(policy_config: Dict[Text, List[Text]]): with pytest.raises(InvalidDomain) as execinfo: Agent( domain=Domain.from_dict({"forms": ["restaurant_form"]}), policies=PolicyEnsemble.from_dict(policy_config), ) assert "haven't added the FormPolicy" in str(execinfo.value)
def test_ensemble_from_dict(): def check_memoization(p): assert p.max_history == 5 assert p.priority == 3 def check_rule(p): assert p.max_history == DEFAULT_MAX_HISTORY assert p.priority == 1 ensemble_dict = { "policies": [ {"max_history": 5, "priority": 3, "name": "MemoizationPolicy"}, {"name": "RulePolicy", "priority": 1}, ] } ensemble = PolicyEnsemble.from_dict(ensemble_dict) # Check if all policies are present assert len(ensemble) == 2 # MemoizationPolicy is parent of RulePolicy assert any( [ isinstance(p, MemoizationPolicy) and not isinstance(p, RulePolicy) for p in ensemble ] ) assert any([isinstance(p, RulePolicy) for p in ensemble]) # Verify policy configurations for policy in ensemble: if isinstance(policy, MemoizationPolicy): if isinstance(policy, RulePolicy): check_rule(policy) else: check_memoization(policy)
def test_rule_policy_valid(domain: Dict[Text, Any], policy_config: Dict[Text, Any]): # no exception should be thrown Agent( domain=Domain.from_dict(domain), policies=PolicyEnsemble.from_dict(policy_config), )
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...") core_path, nlu_path = get_model_subdirectories(model_directory) if nlu_path: from rasa.core.interpreter import RasaNLUInterpreter interpreter = RasaNLUInterpreter(model_directory=nlu_path) else: interpreter = (agent.interpreter if agent.interpreter is not None else RegexInterpreter()) 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.")
def test_trigger_without_mapping_policy(domain, policy_config): with pytest.raises(InvalidDomain) as execinfo: Agent( domain=Domain.from_dict(domain), policies=PolicyEnsemble.from_dict(policy_config), ) assert "haven't added the MappingPolicy" in str(execinfo.value)
def test_policy_loading_no_kwargs_with_context(tmp_path: Path): original_policy_ensemble = PolicyEnsemble([PolicyWithoutLoadKwargs()]) original_policy_ensemble.train([], None, RegexInterpreter()) original_policy_ensemble.persist(str(tmp_path)) with pytest.raises(UnsupportedDialogueModelError) as execinfo: PolicyEnsemble.load(str(tmp_path), new_config={"policies": [{}]}) assert "`PolicyWithoutLoadKwargs.load` does not accept `**kwargs`" in str( execinfo.value)
def load( cls, model_path: Union[Text, Path], interpreter: Optional[NaturalLanguageInterpreter] = None, generator: Union[EndpointConfig, NaturalLanguageGenerator] = None, tracker_store: Optional[TrackerStore] = None, lock_store: Optional[LockStore] = None, action_endpoint: Optional[EndpointConfig] = None, model_server: Optional[EndpointConfig] = None, remote_storage: Optional[Text] = None, path_to_model_archive: Optional[Text] = None, ) -> "Agent": """Load a persisted model from the passed path.""" try: if not model_path: raise ModelNotFound("No path specified.") if not os.path.exists(model_path): raise ModelNotFound(f"No file or directory at '{model_path}'.") if os.path.isfile(model_path): model_path = get_model(str(model_path)) except ModelNotFound as e: raise ModelNotFound( f"You are trying to load a model from '{model_path}', " f"which is not possible. \n" f"The model path should be a 'tar.gz' file or a directory " f"containing the various model files in the sub-directories " f"'core' and 'nlu'. \n\n" f"If you want to load training data instead of a model, use " f"`agent.load_data(...)` instead. {e}" ) core_model, nlu_model = get_model_subdirectories(model_path) if not interpreter and nlu_model: interpreter = rasa.core.interpreter.create_interpreter(nlu_model) domain = None ensemble = None if core_model: domain = Domain.load(os.path.join(core_model, DEFAULT_DOMAIN_PATH)) ensemble = PolicyEnsemble.load(core_model) if core_model else None # ensures the domain hasn't changed between test and train domain.compare_with_specification(core_model) return cls( domain=domain, policies=ensemble, interpreter=interpreter, generator=generator, tracker_store=tracker_store, lock_store=lock_store, action_endpoint=action_endpoint, model_directory=model_path, model_server=model_server, remote_storage=remote_storage, path_to_model_archive=path_to_model_archive, )
def test_form_without_form_policy(domain: Dict[Text, Any], policy_config: Dict[Text, Any]): with pytest.raises(InvalidDomain) as execinfo: Agent( domain=Domain.from_dict(domain), policies=PolicyEnsemble.from_dict(policy_config), ) assert "haven't added the FormPolicy" in str(execinfo.value)
def test_policy_loading_simple(tmpdir): original_policy_ensemble = PolicyEnsemble([WorkingPolicy()]) original_policy_ensemble.train([], None) original_policy_ensemble.persist(str(tmpdir)) loaded_policy_ensemble = PolicyEnsemble.load(str(tmpdir)) assert original_policy_ensemble.policies == loaded_policy_ensemble.policies
def test_policy_loading_simple(tmp_path: Path): original_policy_ensemble = PolicyEnsemble([WorkingPolicy()]) original_policy_ensemble.train([], None, RegexInterpreter()) original_policy_ensemble.persist(str(tmp_path)) loaded_policy_ensemble = PolicyEnsemble.load(str(tmp_path)) assert original_policy_ensemble.policies == loaded_policy_ensemble.policies
def test_rule_policy_without_fallback_action_present(domain: Dict[Text, Any], policy_config: Dict[Text, Any]): with pytest.raises(InvalidDomain) as execinfo: Agent( domain=Domain.from_dict(domain), policies=PolicyEnsemble.from_dict(policy_config), ) assert RulePolicy.__name__ in execinfo.value.message
def test_ensemble_from_dict(): def check_memoization(p): assert p.max_history == 5 assert p.priority == 3 def check_fallback(p): assert p.fallback_action_name == "action_default_fallback" assert p.nlu_threshold == 0.7 assert p.core_threshold == 0.7 assert p.priority == 2 def check_form(p): assert p.priority == 1 ensemble_dict = { "policies": [ { "max_history": 5, "priority": 3, "name": "MemoizationPolicy" }, { "core_threshold": 0.7, "priority": 2, "name": "FallbackPolicy", "nlu_threshold": 0.7, "fallback_action_name": "action_default_fallback", }, { "name": "FormPolicy", "priority": 1 }, ] } ensemble = PolicyEnsemble.from_dict(ensemble_dict) # Check if all policies are present assert len(ensemble) == 3 # MemoizationPolicy is parent of FormPolicy assert any([ isinstance(p, MemoizationPolicy) and not isinstance(p, FormPolicy) for p in ensemble ]) assert any([isinstance(p, FallbackPolicy) for p in ensemble]) assert any([isinstance(p, FormPolicy) for p in ensemble]) # Verify policy configurations for policy in ensemble: if isinstance(policy, MemoizationPolicy): if isinstance(policy, FormPolicy): check_form(policy) else: check_memoization(policy) elif isinstance(policy, FallbackPolicy): check_fallback(policy)
def load( cls, model_path: Text, interpreter: Optional[NaturalLanguageInterpreter] = None, generator: Union[EndpointConfig, NaturalLanguageGenerator] = None, tracker_store: Optional[TrackerStore] = None, action_endpoint: Optional[EndpointConfig] = None, model_server: Optional[EndpointConfig] = None, remote_storage: Optional[Text] = None, ) -> "Agent": """Load a persisted model from the passed path.""" try: if not model_path: raise ModelNotFound("No path specified.") elif not os.path.exists(model_path): raise ModelNotFound( "No file or directory at '{}'.".format(model_path)) elif os.path.isfile(model_path): model_path = get_model(model_path) except ModelNotFound: raise ValueError( "You are trying to load a MODEL from '{}', which is not possible. \n" "The model path should be a 'tar.gz' file or a directory " "containing the various model files in the sub-directories 'core' " "and 'nlu'. \n\nIf you want to load training data instead of " "a model, use `agent.load_data(...)` instead.".format( model_path)) core_model, nlu_model = get_model_subdirectories(model_path) if not interpreter and os.path.exists(nlu_model): interpreter = NaturalLanguageInterpreter.create(nlu_model) domain = None ensemble = None if os.path.exists(core_model): domain = Domain.load(os.path.join(core_model, DEFAULT_DOMAIN_PATH)) ensemble = PolicyEnsemble.load(core_model) if core_model else None # ensures the domain hasn't changed between test and train domain.compare_with_specification(core_model) return cls( domain=domain, policies=ensemble, interpreter=interpreter, generator=generator, tracker_store=tracker_store, action_endpoint=action_endpoint, model_directory=model_path, model_server=model_server, remote_storage=remote_storage, )
def test_from_dict_does_not_change_passed_dict_parameter(): config = { "policies": [ { "name": "TEDPolicy", "featurizer": [ { "name": "MaxHistoryTrackerFeaturizer", "max_history": 5, "state_featurizer": [{"name": "BinarySingleStateFeaturizer"}], } ], } ] } config_copy = copy.deepcopy(config) PolicyEnsemble.from_dict(config_copy) assert config == config_copy
def load(config_file: Union[Text, Dict]) -> List["Policy"]: """Load policy data stored in the specified file.""" from rasa.core.policies.ensemble import PolicyEnsemble config_data = {} if isinstance(config_file, str) and os.path.isfile(config_file): config_data = rasa.shared.utils.io.read_model_configuration(config_file) elif isinstance(config_file, Dict): config_data = config_file return PolicyEnsemble.from_dict(config_data)
def __init__( self, domain: Union[Text, Domain, None] = None, policies: Union[PolicyEnsemble, List[Policy], None] = None, interpreter: Optional[NaturalLanguageInterpreter] = None, generator: Union[EndpointConfig, NaturalLanguageGenerator, None] = None, tracker_store: Optional[TrackerStore] = None, lock_store: Optional[LockStore] = None, action_endpoint: Optional[EndpointConfig] = None, fingerprint: Optional[Text] = None, model_directory: Optional[Text] = None, model_server: Optional[EndpointConfig] = None, remote_storage: Optional[Text] = None, path_to_model_archive: Optional[Text] = None, ): print("Agent", policies) # Initializing variables with the passed parameters. self.domain = self._create_domain(domain) self.policy_ensemble = self._create_ensemble(policies) if self.domain is not None: self.domain.add_requested_slot() self.domain.add_knowledge_base_slots() self.domain.add_categorical_slot_default_value() PolicyEnsemble.check_domain_ensemble_compatibility( self.policy_ensemble, self.domain ) self.interpreter = NaturalLanguageInterpreter.create(interpreter) self.nlg = NaturalLanguageGenerator.create(generator, self.domain) self.tracker_store = self.create_tracker_store(tracker_store, self.domain) self.lock_store = self._create_lock_store(lock_store) self.action_endpoint = action_endpoint self._set_fingerprint(fingerprint) self.model_directory = model_directory self.model_server = model_server self.remote_storage = remote_storage self.path_to_model_archive = path_to_model_archive
def load(config_file: Optional[Text]) -> List["Policy"]: """Load policy data stored in the specified file.""" from rasa.core.policies.ensemble import PolicyEnsemble if config_file and os.path.isfile(config_file): config_data = rasa.utils.io.read_config_file(config_file) else: raise ValueError("You have to provide a valid path to a config file. " "The file '{}' could not be found." "".format(os.path.abspath(config_file))) return PolicyEnsemble.from_dict(config_data)
def load( cls, unpacked_model_path: Text, interpreter: Optional[NaturalLanguageInterpreter] = None, generator: Union[EndpointConfig, "NLG"] = None, tracker_store: Optional["TrackerStore"] = None, action_endpoint: Optional[EndpointConfig] = None, model_server: Optional[EndpointConfig] = None, remote_storage: Optional[Text] = None, ) -> "Agent": """Load a persisted model from the passed path.""" if not os.path.exists(unpacked_model_path) or not os.path.isdir( unpacked_model_path ): raise ValueError( "You are trying to load a MODEL from " "('{}'), which is not possible. \n" "The persisted path should be a directory " "containing the various model files in the " "sub-directories 'core' and 'nlu'. \n\n" "If you want to load training data instead of " "a model, use `agent.load_data(...)` " "instead.".format(unpacked_model_path) ) core_model, nlu_model = get_model_subdirectories(unpacked_model_path) if not interpreter and os.path.exists(nlu_model): interpreter = NaturalLanguageInterpreter.create(nlu_model) domain = None ensemble = None if os.path.exists(core_model): domain = Domain.load(os.path.join(core_model, DEFAULT_DOMAIN_PATH)) ensemble = PolicyEnsemble.load(core_model) if core_model else None # ensures the domain hasn't changed between test and train domain.compare_with_specification(core_model) return cls( domain=domain, policies=ensemble, interpreter=interpreter, generator=generator, tracker_store=tracker_store, action_endpoint=action_endpoint, model_directory=unpacked_model_path, model_server=model_server, remote_storage=remote_storage, )
def test_policy_loading_load_returns_none(tmp_path: Path, caplog: LogCaptureFixture): original_policy_ensemble = PolicyEnsemble([LoadReturnsNonePolicy()]) original_policy_ensemble.train([], None, RegexInterpreter()) original_policy_ensemble.persist(str(tmp_path)) with caplog.at_level(logging.WARNING): ensemble = PolicyEnsemble.load(str(tmp_path)) assert (caplog.records.pop().msg == "Failed to load policy tests.core.test_ensemble." "LoadReturnsNonePolicy: load returned None") assert len(ensemble.policies) == 0
def __init__( self, domain: Union[Text, Domain, None] = None, policies: Union[PolicyEnsemble, List[Policy], None] = None, interpreter: Optional[NaturalLanguageInterpreter] = None, generator: Union[EndpointConfig, NaturalLanguageGenerator, None] = None, tracker_store: Optional[TrackerStore] = None, action_endpoint: Optional[EndpointConfig] = None, fingerprint: Optional[Text] = None, model_directory: Optional[Text] = None, model_server: Optional[EndpointConfig] = None, remote_storage: Optional[Text] = None, ): # Initializing variables with the passed parameters. self.domain = self._create_domain(domain) self.policy_ensemble = self._create_ensemble(policies) if self.domain is not None: self.domain.add_requested_slot() PolicyEnsemble.check_domain_ensemble_compatibility( self.policy_ensemble, self.domain) self.interpreter = NaturalLanguageInterpreter.create(interpreter) self.nlg = NaturalLanguageGenerator.create(generator, self.domain) self.tracker_store = self.create_tracker_store(tracker_store, self.domain) self.action_endpoint = action_endpoint self.conversations_in_processing = {} self._set_fingerprint(fingerprint) self.model_directory = model_directory self.model_server = model_server self.remote_storage = remote_storage
def load(config_file: Optional[Union[Text, Dict]]) -> List["Policy"]: """Load policy data stored in the specified file.""" from rasa.core.policies.ensemble import PolicyEnsemble if not config_file: raise FileNotFoundException( f"The provided configuration file path does not seem to be valid. " f"The file '{os.path.abspath(config_file)}' could not be found.") config_data = {} if isinstance(config_file, str) and os.path.isfile(config_file): config_data = rasa.shared.utils.io.read_config_file(config_file) elif isinstance(config_file, Dict): config_data = config_file return PolicyEnsemble.from_dict(config_data)