def receive_other_performative(self, msg: KQMLPerformative): """Override of KQMLModule default... ping isn't currently supported by pykqml so we handle other to catch ping and otherwise throw an error. Arguments: msg (KQMLPerformative): other type of performative, if ping we reply with a ping update otherwise error """ if msg.head() == 'ping': LOGGER.info('Receive ping... %s', msg) reply_content = ( f'(update :sender {self.name} :content (:agent {self.name} ' f':uptime {self.uptime()} :status :OK :state {self.state} ' f':machine {gethostname()} :subscriptions {self.num_subs}))') self.reply_on_local_port(msg, performative(reply_content)) else: self.error_reply(msg, f'unexpected performative: {msg}')
def response_to_query(self, msg: KQMLPerformative, content: KQMLPerformative, results: Any, response_type: str): """Based on the response type, will create a properly formed reply with the results either input as patterns or bound to the arguments from the results. The reply is a tell which is then sent to Companions. Goes through the arguments and the results together to either bind a argument to the result or simple return the result in the place of that argument. The reply content is filled with these argument/result lists (they are listified before appending) before being added to the tell message and subsequently sent off to Companions. Arguments: msg (KQMLPerformative): the message being passed along to reply content (KQMLPerformative): query, starts with a predicate and the remainder is the arguments results (Any): The results of performing the query response_type (str): the given response type, if it is not given or is given to be pattern, the variable will be set to True, otherwise False """ LOGGER.debug('Responding to query: %s, %s, %s', msg, content, results) response_type = response_type is None or response_type == ':pattern' reply_content = KQMLList(content.head()) results_list = results if isinstance(results, list) else [results] result_index = 0 arg_len = len(content.data[1:]) for i, each in enumerate(content.data[1:]): # if argument is a variable, replace in the pattern or bind if str(each[0]) == '?': # if last argument and there's still more in results if i == arg_len and result_index < len(results_list) - 1: pattern = results_list[result_index:] # get remaining list else: pattern = results_list[result_index] reply_with = pattern if response_type else (each, pattern) reply_content.append(listify(reply_with)) result_index += 1 # if not a variable, replace in the pattern. Ignore for bind elif response_type: reply_content.append(each) # no need to wrap reply_content in parens, KQMLList will do that for us reply_msg = f'(tell :sender {self.name} :content {reply_content})' self.reply(msg, performative(reply_msg))