def __init__(self): self.topic_tracker_type = None # TopicTracker may not be needed in simulate, if Settings.config.has_option("topictracker", "type"): self.topic_tracker_type = Settings.config.get( "topictracker", "type") else: self.topic_tracker_type = "keyword" # set it as a default if self.topic_tracker_type == "keyword": from RuleTopicTrackers import KeywordSpottingTopicTracker self.tt_model = KeywordSpottingTopicTracker() elif self.topic_tracker_type == 'switch': from RuleTopicTrackers import TextBasedSwitchTopicTracker self.tt_model = TextBasedSwitchTopicTracker() elif self.topic_tracker_type != None: try: # try to view the config string as a complete module path to the class to be instantiated components = self.topic_tracker_type.split('.') packageString = '.'.join(components[:-1]) classString = components[-1] mod = __import__(packageString, fromlist=[classString]) klass = getattr(mod, classString) self.tt_model = klass() except ImportError: logger.error('Unknown topic tracker "{}"'.format( self.topic_tracker_type)) else: self.tt_model = None # simulate for example, may just "cheat" # SINGLE DOMAIN SYSTEM: self.USE_SINGLE_DOMAIN = False if Settings.config.has_option("GENERAL", "singledomain"): self.USE_SINGLE_DOMAIN = Settings.config.getboolean( "GENERAL", "singledomain") if self.USE_SINGLE_DOMAIN: # will now be restricted to a single doman system: # Below Settings.config.get is safe -- all hubs have already checked config has this section domain = Settings.config.get("GENERAL", "domains") if "," in domain: logger.error( "It's confusing to specify more than 1 domain if you want to use single domain system" ) if domain not in OntologyUtils.available_domains: logger.error("Domain: " + domain + " not an available domain tag") else: self.singleDomain = domain else: # Maintain record of systems last acts in each domain, to facilitate returning to domain at later turns self.domainsLastAct = dict.fromkeys( OntologyUtils.available_domains, None) # NB: is for multidomain only
class TopicTrackingManager(object): ''' Interface for all topic tracking ''' def __init__(self): self.topic_tracker_type = None # TopicTracker may not be needed in simulate, if Settings.config.has_option("topictracker", "type"): self.topic_tracker_type = Settings.config.get( "topictracker", "type") if self.topic_tracker_type == "keyword": from RuleTopicTrackers import KeywordSpottingTopicTracker self.tt_model = KeywordSpottingTopicTracker() elif self.topic_tracker_type == 'switch': from RuleTopicTrackers import TextBasedSwitchTopicTracker self.tt_model = TextBasedSwitchTopicTracker() elif self.topic_tracker_type != None: try: # try to view the config string as a complete module path to the class to be instantiated components = self.topic_tracker_type.split('.') packageString = '.'.join(components[:-1]) classString = components[-1] mod = __import__(packageString, fromlist=[classString]) klass = getattr(mod, classString) self.tt_model = klass() except ImportError: logger.error('Unknown topic tracker "{}"'.format( self.topic_tracker_type)) else: self.tt_model = None # simulate for example, may just "cheat" # SINGLE DOMAIN SYSTEM: self.USE_SINGLE_DOMAIN = False if Settings.config.has_option("GENERAL", "singledomain"): self.USE_SINGLE_DOMAIN = Settings.config.getboolean( "GENERAL", "singledomain") if self.USE_SINGLE_DOMAIN: # will now be restricted to a single doman system: # Below Settings.config.get is safe -- all hubs have already checked config has this section domain = Settings.config.get("GENERAL", "domains") if "," in domain: logger.error( "It's confusing to specify more than 1 domain if you want to use single domain system" ) if domain not in OntologyUtils.available_domains: logger.error("Domain: " + domain + " not an available domain tag") else: self.singleDomain = domain else: # Maintain record of systems last acts in each domain, to facilitate returning to domain at later turns self.domainsLastAct = dict.fromkeys( OntologyUtils.available_domains, None) # NB: is for multidomain only def restart(self): ''' # Start with control where? Single domain --> with its manager, Multi-Domain --> with topicmanager ''' # restart and set operatingDomain if self.tt_model is not None: self.tt_model.restart() if self.USE_SINGLE_DOMAIN: self.operatingDomain = self.singleDomain else: self.operatingDomain = 'topicmanager' # control starts with this in the multi-domain system. self.previousDomain = None # no history in dialogue yet self.in_present_dialog = [ self.operatingDomain ] # record domains involved in present dialog. return def track_topic(self, userAct_hyps=None, domainString=None): ''' # CURRENT ASSUMPTION: ONLY ONE DOMAIN CAN BE ACTIVE IN EACH TURN. Sets member variables: operatingDomain ''' tt_domain = None # 1. Track topic: if self.USE_SINGLE_DOMAIN: tt_domain = self.operatingDomain # i.e nothing to do elif domainString is not None and "ood" != domainString: tt_domain = domainString elif self.tt_model is not None: if userAct_hyps is None: logger.error("Using topic tracker: " + self.topic_tracker_type + ", but no information for inference passed") else: tt_domain = self.tt_model.infer_domain( userActHyps=userAct_hyps) else: logger.error( "Must directly pass domain name or information for inference") # for ood handling identified outside of pydial, eg dialport if tt_domain is None and "ood" == domainString: tt_domain = domainString # 2. Update current and previous domains self.previousDomain = None # indicates we did not change domain [default assumption - will be changed below if we did] if tt_domain is not None: if isinstance(tt_domain, str) or isinstance(tt_domain, unicode): if tt_domain != self.operatingDomain: self.previousDomain = self.operatingDomain self.operatingDomain = tt_domain logger.info( 'TopicTracker believes we switched domains. From %s to %s' % (self.previousDomain, self.operatingDomain)) else: # NOTE: -- ASSUMED ABOVE THAT self.tt_output IS A SINGLE DOMAIN TAG (str) --> adjust when proper trackers # (ie ones giving distribution over domain labels for example) are added. logger.error( 'new topic tracker -- needs integrating: {}; {}; {}'. format(tt_domain, isinstance(tt_domain, str), type(tt_domain))) # else failed to recognise anything - refrain to old value, ie, do nothing logger.info('After user_act - domain is now: ' + self.operatingDomain) return self.operatingDomain # END OF FILE