Exemple #1
0
    def decode(self, obj: bytes) -> Message:
        """
        Decode the message.

        :param obj: the bytes object
        :return: the message
        """
        json_msg = json.loads(obj.decode("utf-8"))
        performative = GymMessage.Performative(json_msg["performative"])
        new_body = copy.copy(json_msg)
        new_body["performative"] = performative

        if performative == GymMessage.Performative.ACT:
            action_bytes = base64.b64decode(json_msg["action"])
            action = pickle.loads(action_bytes)  # nosec
            new_body["action"] = action
            new_body["step_id"] = json_msg["step_id"]
        elif performative == GymMessage.Performative.PERCEPT:
            # observation, reward and info are gym implementation specific, done is boolean
            observation_bytes = base64.b64decode(json_msg["observation"])
            observation = pickle.loads(observation_bytes)  # nosec
            new_body["observation"] = observation
            reward_bytes = base64.b64decode(json_msg["reward"])
            reward = pickle.loads(reward_bytes)  # nosec
            new_body["reward"] = reward
            info_bytes = base64.b64decode(json_msg["info"])
            info = pickle.loads(info_bytes)  # nosec
            new_body["info"] = info
            new_body["step_id"] = json_msg["step_id"]

        gym_message = GymMessage(performative=performative, body=new_body)
        return gym_message
Exemple #2
0
    def _decode_percept(self, envelope: Envelope,
                        expected_step_id: int) -> Message:
        """
        Receive the response from the gym environment in the form of an envelope and decode it.

        The response is a PERCEPT message containing the usual 'observation', 'reward', 'done', 'info' parameters.

        :param expected_step_id: the expected step id
        :return: a message received as a response to the action performed in apply_action.
        """
        if envelope is not None:
            if envelope.protocol_id == PublicId.from_str("fetchai/gym:0.1.0"):
                gym_msg = GymSerializer().decode(envelope.message)
                gym_msg_performative = GymMessage.Performative(
                    gym_msg.get("performative"))
                gym_msg_step_id = gym_msg.get("step_id")
                if (gym_msg_performative == GymMessage.Performative.PERCEPT
                        and gym_msg_step_id == expected_step_id):
                    return gym_msg
                else:
                    raise ValueError(
                        "Unexpected performative or no step_id: {}".format(
                            gym_msg_performative))
            else:
                raise ValueError("Unknown protocol_id: {}".format(
                    envelope.protocol_id))
        else:
            raise ValueError("Missing envelope.")
Exemple #3
0
    def decode(obj: bytes) -> Message:
        """
        Decode bytes into a 'Gym' message.

        :param obj: the bytes object.
        :return: the 'Gym' message.
        """
        message_pb = ProtobufMessage()
        gym_pb = gym_pb2.GymMessage()
        message_pb.ParseFromString(obj)
        message_id = message_pb.dialogue_message.message_id
        dialogue_reference = (
            message_pb.dialogue_message.dialogue_starter_reference,
            message_pb.dialogue_message.dialogue_responder_reference,
        )
        target = message_pb.dialogue_message.target

        gym_pb.ParseFromString(message_pb.dialogue_message.content)
        performative = gym_pb.WhichOneof("performative")
        performative_id = GymMessage.Performative(str(performative))
        performative_content = dict()  # type: Dict[str, Any]
        if performative_id == GymMessage.Performative.ACT:
            pb2_action = gym_pb.act.action
            action = AnyObject.decode(pb2_action)
            performative_content["action"] = action
            step_id = gym_pb.act.step_id
            performative_content["step_id"] = step_id
        elif performative_id == GymMessage.Performative.PERCEPT:
            step_id = gym_pb.percept.step_id
            performative_content["step_id"] = step_id
            pb2_observation = gym_pb.percept.observation
            observation = AnyObject.decode(pb2_observation)
            performative_content["observation"] = observation
            reward = gym_pb.percept.reward
            performative_content["reward"] = reward
            done = gym_pb.percept.done
            performative_content["done"] = done
            pb2_info = gym_pb.percept.info
            info = AnyObject.decode(pb2_info)
            performative_content["info"] = info
        elif performative_id == GymMessage.Performative.STATUS:
            content = gym_pb.status.content
            content_dict = dict(content)
            performative_content["content"] = content_dict
        elif performative_id == GymMessage.Performative.RESET:
            pass
        elif performative_id == GymMessage.Performative.CLOSE:
            pass
        else:
            raise ValueError(
                "Performative not valid: {}.".format(performative_id))

        return GymMessage(message_id=message_id,
                          dialogue_reference=dialogue_reference,
                          target=target,
                          performative=performative,
                          **performative_content)
Exemple #4
0
    def handle_gym_message(self, envelope: Envelope) -> None:
        """
        Forward a message to gym.

        :param envelope: the envelope
        :return: None
        """
        gym_message = GymSerializer().decode(envelope.message)
        performative = gym_message.get("performative")
        if GymMessage.Performative(
                performative) == GymMessage.Performative.ACT:
            action = gym_message.get("action")
            step_id = gym_message.get("step_id")
            observation, reward, done, info = self.gym_env.step(
                action)  # type: ignore
            msg = GymMessage(
                performative=GymMessage.Performative.PERCEPT,
                observation=observation,
                reward=reward,
                done=done,
                info=info,
                step_id=step_id,
            )
            msg_bytes = GymSerializer().encode(msg)
            envelope = Envelope(
                to=envelope.sender,
                sender=DEFAULT_GYM,
                protocol_id=GymMessage.protocol_id,
                message=msg_bytes,
            )
            self._send(envelope)
        elif GymMessage.Performative(
                performative) == GymMessage.Performative.RESET:
            self.gym_env.reset()  # type: ignore
        elif GymMessage.Performative(
                performative) == GymMessage.Performative.CLOSE:
            self.gym_env.close()  # type: ignore