示例#1
0
    def on_unidentified_dialogue(self, msg: AgentMessage) -> None:
        """
        React to an unidentified dialogue.

        :param msg: agent message

        :return: None
        """
        logger.debug("[{}]: Unidentified dialogue.".format(self.agent_name))
        result = ByteMessage(
            msg.msg_id + 1, msg.dialogue_id, msg.destination,
            b'This message belongs to an unidentified dialogue.', Context())
        self.out_box.out_queue.put(result)
示例#2
0
    def on_decline(self, msg_id: int, dialogue_id: int, origin: str,
                   target: int) -> None:
        """
        Handle a Decline.

        :param msg_id: the message id
        :param dialogue_id: the dialogue id
        :param origin: the public key of the sending agent
        :param target: the message id targetted by this message

        :return: None
        """
        self.in_queue.put(
            Decline(msg_id, dialogue_id, origin, target, Context()))
示例#3
0
    def on_message(self, msg_id: int, dialogue_id: int, origin: str,
                   content: bytes) -> None:
        """
        Handle a message.

        :param msg_id: the message id
        :param dialogue_id: the dialogue id
        :param origin: the public key of the sending agent
        :param content: the message body

        :return: None
        """
        self.in_queue.put(
            ByteMessage(msg_id, dialogue_id, origin, content, Context()))
示例#4
0
    def on_propose(self, msg_id: int, dialogue_id: int, origin: str,
                   target: int, proposals: PROPOSE_TYPES) -> None:
        """
        Handle a Propose.

        :param msg_id: the message id
        :param dialogue_id: the dialogue id
        :param origin: the public key of the sending agent
        :param target: the message id targetted by this message
        :param proposals: the proposals

        :return: None
        """
        self.in_queue.put(
            Propose(msg_id, dialogue_id, origin, target, proposals, Context()))
示例#5
0
    def on_cfp(self, msg_id: int, dialogue_id: int, origin: str, target: int,
               query: CFP_TYPES) -> None:
        """
        Handle a CFP.

        :param msg_id: the message id
        :param dialogue_id: the dialogue id
        :param origin: the public key of the sending agent
        :param target: the message id targetted by this message
        :param query: the query

        :return: None
        """
        self.in_queue.put(
            CFP(msg_id, dialogue_id, origin, target, query, Context()))
示例#6
0
    def _on_services_search_result(self, agent_pbks: List[str],
                                   is_searching_for_sellers: bool) -> None:
        """
        Process the search result for services.

        :param agent_pbks: the agent public keys matching the search query
        :param is_searching_for_sellers: whether it is searching for sellers or not

        :return: None
        """
        agent_pbks_set = set(agent_pbks)
        if self.crypto.public_key in agent_pbks_set:
            agent_pbks_set.remove(self.crypto.public_key)
        agent_pbks = list(agent_pbks_set)
        searched_for = 'sellers' if is_searching_for_sellers else 'buyers'
        logger.debug("[{}]: Found potential {}: {}".format(
            self.agent_name, searched_for, agent_pbks))

        query = self.game_instance.build_services_query(
            is_searching_for_sellers)
        if query is None:
            response = 'demanding' if is_searching_for_sellers else 'supplying'
            logger.debug("[{}]: No longer {} any goods...".format(
                self.agent_name, response))
            return
        for agent_pbk in agent_pbks:
            dialogue = self.game_instance.dialogues.create_self_initiated(
                agent_pbk, self.crypto.public_key,
                not is_searching_for_sellers)
            cfp = CFP(STARTING_MESSAGE_ID, dialogue.dialogue_label.dialogue_id,
                      agent_pbk, STARTING_MESSAGE_TARGET, query, Context())
            logger.debug(
                "[{}]: send_cfp_as_{}: msg_id={}, dialogue_id={}, destination={}, target={}, query={}"
                .format(self.agent_name, dialogue.role, cfp.msg_id,
                        cfp.dialogue_id, cfp.destination, cfp.target, query))
            dialogue.outgoing_extend([cfp])
            self.out_box.out_queue.put(cfp)
    def on_cfp(self, cfp: CFP, dialogue: Dialogue) -> Union[Propose, Decline]:
        """
        Handle a CFP.

        :param cfp: the CFP
        :param dialogue: the dialogue

        :return: a Propose or a Decline
        """
        goods_description = self.game_instance.get_service_description(is_supply=dialogue.is_seller)
        new_msg_id = cfp.msg_id + 1
        if not cfp.query.check(goods_description):
            logger.debug("[{}]: Current holdings do not satisfy CFP query.".format(self.agent_name))
            logger.debug("[{}]: sending to {} a Decline{}".format(self.agent_name, cfp.destination,
                                                                  pprint.pformat({
                                                                      "msg_id": new_msg_id,
                                                                      "dialogue_id": cfp.dialogue_id,
                                                                      "origin": cfp.destination,
                                                                      "target": cfp.msg_id
                                                                  })))
            response = Decline(new_msg_id, cfp.dialogue_id, cfp.destination, cfp.msg_id, Context())
            self.game_instance.stats_manager.add_dialogue_endstate(EndState.DECLINED_CFP, dialogue.is_self_initiated)
        else:
            proposals = [random.choice(self.game_instance.get_proposals(cfp.query, dialogue.is_seller))]
            self.game_instance.lock_manager.store_proposals(proposals, new_msg_id, dialogue, cfp.destination, dialogue.is_seller, self.crypto)
            logger.debug("[{}]: sending to {} a Propose{}".format(self.agent_name, cfp.destination,
                                                                  pprint.pformat({
                                                                      "msg_id": new_msg_id,
                                                                      "dialogue_id": cfp.dialogue_id,
                                                                      "origin": cfp.destination,
                                                                      "target": cfp.msg_id,
                                                                      "propose": proposals[0].values  # TODO fix if more than one proposal!
                                                                  })))
            response = Propose(new_msg_id, cfp.dialogue_id, cfp.destination, cfp.msg_id, proposals, Context())
        return response
    def _on_initial_accept(self, accept: Accept, dialogue: Dialogue) -> Union[List[Decline], List[Union[OutContainer, Accept]]]:
        """
        Handle an initial Accept.

        :param accept: the accept
        :param dialogue: the dialogue

        :return: a Deline or an Accept and a Transaction (in OutContainer
        """
        transaction = self.game_instance.lock_manager.pop_pending_proposal(dialogue, accept.target)
        new_msg_id = accept.msg_id + 1
        results = []
        if self._is_profitable_transaction(transaction, dialogue):
            if self.game_instance.strategy.is_world_modeling:
                self.game_instance.world_state.update_on_initial_accept(transaction)
            logger.debug("[{}]: Locking the current state (as {}).".format(self.agent_name, dialogue.role))
            self.game_instance.lock_manager.add_lock(transaction, as_seller=dialogue.is_seller)
            results.append(OutContainer(message=transaction.serialize(), message_id=STARTING_MESSAGE_ID, dialogue_id=accept.dialogue_id, destination=self.game_instance.controller_pbk))
            results.append(Accept(new_msg_id, accept.dialogue_id, accept.destination, accept.msg_id, Context()))
        else:
            logger.debug("[{}]: Decline the accept (as {}).".format(self.agent_name, dialogue.role))
            results.append(Decline(new_msg_id, accept.dialogue_id, accept.destination, accept.msg_id, Context()))
            self.game_instance.stats_manager.add_dialogue_endstate(EndState.DECLINED_ACCEPT, dialogue.is_self_initiated)
        return results
    def on_propose(self, propose: Propose, dialogue: Dialogue) -> Union[Accept, Decline]:
        """
        Handle a Propose.

        :param propose: the Propose
        :param dialogue: the dialogue

        :return: an Accept or a Decline
        """
        logger.debug("[{}]: on propose as {}.".format(self.agent_name, dialogue.role))
        proposal = propose.proposals[0]
        transaction_id = generate_transaction_id(self.crypto.public_key, propose.destination, dialogue.dialogue_label, dialogue.is_seller)
        transaction = Transaction.from_proposal(proposal,
                                                transaction_id,
                                                is_sender_buyer=not dialogue.is_seller,
                                                counterparty=propose.destination,
                                                sender=self.crypto.public_key,
                                                crypto=self.crypto)
        new_msg_id = propose.msg_id + 1
        if self._is_profitable_transaction(transaction, dialogue):
            logger.debug("[{}]: Accepting propose (as {}).".format(self.agent_name, dialogue.role))
            self.game_instance.lock_manager.add_lock(transaction, as_seller=dialogue.is_seller)
            self.game_instance.lock_manager.add_pending_initial_acceptance(dialogue, new_msg_id, transaction)
            result = Accept(new_msg_id, propose.dialogue_id, propose.destination, propose.msg_id, Context())
        else:
            logger.debug("[{}]: Declining propose (as {})".format(self.agent_name, dialogue.role))
            result = Decline(new_msg_id, propose.dialogue_id, propose.destination, propose.msg_id, Context())
            self.game_instance.stats_manager.add_dialogue_endstate(EndState.DECLINED_PROPOSE, dialogue.is_self_initiated)
        return result