Example #1
0
def _process_envelopes(
    agent_name: str,
    identity_stub: Identity,
    inbox: InBox,
    outbox: OutBox,
    dialogues: DefaultDialogues,
) -> None:
    """
    Process envelopes.

    :param agent_name: name of an agent.
    :param identity_stub: stub identity.
    :param inbox: an inbox object.
    :param outbox: an outbox object.
    :param dialogues: the dialogues object.

    :return: None.
    """
    envelope = _try_construct_envelope(agent_name, identity_stub.name,
                                       dialogues)
    if envelope is None:
        if not inbox.empty():
            envelope = inbox.get_nowait()
            assert envelope is not None, "Could not recover envelope from inbox."
            click.echo(_construct_message("received", envelope))
        else:
            click.echo("Received no new envelope!")
    else:
        outbox.put(envelope)
        click.echo(_construct_message("sending", envelope))
Example #2
0
def test_outbox_put():
    """Tests that an envelope is putted into the queue."""
    agent_address = "Agent0"
    receiver_address = "Agent1"
    msg = DefaultMessage(
        dialogue_reference=("", ""),
        message_id=1,
        target=0,
        performative=DefaultMessage.Performative.BYTES,
        content=b"hello",
    )
    msg.counterparty = receiver_address
    dummy_connection = _make_dummy_connection()
    multiplexer = Multiplexer([dummy_connection])
    outbox = OutBox(multiplexer, agent_address)
    inbox = InBox(multiplexer)
    multiplexer.connect()
    envelope = Envelope(
        to=receiver_address,
        sender=agent_address,
        protocol_id=DefaultMessage.protocol_id,
        message=msg,
    )
    outbox.put(envelope)
    time.sleep(0.5)
    assert not inbox.empty(), "Inbox must not be empty after putting an envelope"
    multiplexer.disconnect()
Example #3
0
def test_outbox_put():
    """Tests that an envelope is putted into the queue."""
    agent_address = "Agent0"
    receiver_address = "Agent1"
    msg = DefaultMessage(
        dialogue_reference=("", ""),
        message_id=1,
        target=0,
        performative=DefaultMessage.Performative.BYTES,
        content=b"hello",
    )
    msg.to = receiver_address
    msg.sender = agent_address
    dummy_connection = _make_dummy_connection()
    multiplexer = Multiplexer([dummy_connection])
    outbox = OutBox(multiplexer)
    inbox = InBox(multiplexer)
    multiplexer.connect()
    envelope = Envelope(
        to=receiver_address,
        sender=agent_address,
        message=msg,
    )
    outbox.put(envelope)
    wait_for_condition(lambda: inbox.empty(), 15,
                       "Inbox must not be empty after putting an envelope")
    multiplexer.disconnect()
Example #4
0
def test_outbox_empty():
    """Test thet the outbox queue is empty."""
    dummy_connection = _make_dummy_connection()
    multiplexer = Multiplexer([dummy_connection])
    multiplexer.connect()
    outbox = OutBox(multiplexer)
    assert outbox.empty(), "The outbox is not empty"
    multiplexer.disconnect()
Example #5
0
def _run_interaction_channel():
    # load agent configuration file
    loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
    agent_configuration = loader.load(Path(DEFAULT_AEA_CONFIG_FILE).open())
    agent_name = agent_configuration.name
    # load stub connection
    configuration = ConnectionConfig(
        input_file=DEFAULT_OUTPUT_FILE_NAME,
        output_file=DEFAULT_INPUT_FILE_NAME,
        connection_id=StubConnection.connection_id,
    )
    identity_stub = Identity(agent_name + "_interact", "interact")
    stub_connection = StubConnection(configuration=configuration,
                                     identity=identity_stub)
    multiplexer = Multiplexer([stub_connection])
    inbox = InBox(multiplexer)
    outbox = OutBox(multiplexer, default_address=identity_stub.address)
    dialogues = DefaultDialogues(identity_stub.name)

    try:
        multiplexer.connect()
        while True:  # pragma: no cover
            _process_envelopes(agent_name, identity_stub, inbox, outbox,
                               dialogues)

    except KeyboardInterrupt:
        click.echo("Interaction interrupted!")
    except BaseException as e:  # pylint: disable=broad-except # pragma: no cover
        click.echo(e)
    finally:
        multiplexer.disconnect()
Example #6
0
    def setup(cls) -> None:
        """Set up the skill test case."""
        identity = Identity("test_agent_name", "test_agent_address")

        cls._multiplexer = AsyncMultiplexer()
        cls._multiplexer._out_queue = (  # pylint: disable=protected-access
            asyncio.Queue()
        )
        cls._outbox = OutBox(cast(Multiplexer, cls._multiplexer))

        agent_context = AgentContext(
            identity=identity,
            connection_status=cls._multiplexer.connection_status,
            outbox=cls._outbox,
            decision_maker_message_queue=Queue(),
            decision_maker_handler_context=SimpleNamespace(),
            task_manager=TaskManager(),
            default_ledger_id=identity.default_address_key,
            currency_denominations=DEFAULT_CURRENCY_DENOMINATIONS,
            default_connection=None,
            default_routing={},
            search_service_address="dummy_search_service_address",
            decision_maker_address="dummy_decision_maker_address",
        )

        cls._skill = Skill.from_dir(str(cls.path_to_skill), agent_context)
Example #7
0
    def __init__(
        self,
        identity: Identity,
        connections: List[Connection],
        loop: Optional[AbstractEventLoop] = None,
        period: float = 1.0,
        loop_mode: Optional[str] = None,
        runtime_mode: Optional[str] = None,
        logger: Logger = _default_logger,
    ) -> None:
        """
        Instantiate the agent.

        :param identity: the identity of the agent.
        :param connections: the list of connections of the agent.
        :param loop: the event loop to run the connections.
        :param period: period to call agent's act
        :param loop_mode: loop_mode to choose agent run loop.
        :param runtime_mode: runtime mode to up agent.

        :return: None
        """
        WithLogger.__init__(self, logger=logger)
        self._connections = connections
        self._identity = identity
        self._period = period
        self._tick = 0
        self._runtime_mode = runtime_mode or self.DEFAULT_RUNTIME
        runtime_cls = self._get_runtime_class()
        self._runtime: BaseRuntime = runtime_cls(agent=self,
                                                 loop_mode=loop_mode,
                                                 loop=loop)

        self._inbox = InBox(self.runtime.multiplexer)
        self._outbox = OutBox(self.runtime.multiplexer)
Example #8
0
def _run_interaction_channel():
    loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
    agent_configuration = loader.load(Path(DEFAULT_AEA_CONFIG_FILE).open())
    agent_name = agent_configuration.name

    identity_stub = Identity(agent_name + "_interact", "interact")
    _load_packages(identity_stub)

    # load agent configuration file
    from packages.fetchai.connections.stub.connection import (  # noqa: F811 # pylint: disable=import-outside-toplevel
        DEFAULT_INPUT_FILE_NAME,
        DEFAULT_OUTPUT_FILE_NAME,
        StubConnection,
    )
    from packages.fetchai.protocols.default.dialogues import (  # noqa: F811 # pylint: disable=import-outside-toplevel
        DefaultDialogue,
        DefaultDialogues,
    )
    from packages.fetchai.protocols.default.message import (  # noqa: F811 # pylint: disable=import-outside-toplevel
        DefaultMessage,
    )

    # load stub connection
    configuration = ConnectionConfig(
        input_file=DEFAULT_OUTPUT_FILE_NAME,
        output_file=DEFAULT_INPUT_FILE_NAME,
        connection_id=StubConnection.connection_id,
    )

    stub_connection = StubConnection(
        configuration=configuration, identity=identity_stub
    )
    multiplexer = Multiplexer([stub_connection])
    inbox = InBox(multiplexer)
    outbox = OutBox(multiplexer)

    def role_from_first_message(  # pylint: disable=unused-argument
        message: Message, receiver_address: Address
    ) -> BaseDialogue.Role:
        """Infer the role of the agent from an incoming/outgoing first message

        :param message: an incoming/outgoing first message
        :param receiver_address: the address of the receiving agent
        :return: The role of the agent
        """
        return DefaultDialogue.Role.AGENT

    dialogues = DefaultDialogues(identity_stub.name, role_from_first_message)

    try:
        multiplexer.connect()
        while True:  # pragma: no cover
            _process_envelopes(agent_name, inbox, outbox, dialogues, DefaultMessage)

    except KeyboardInterrupt:
        click.echo("Interaction interrupted!")
    except BaseException as e:  # pylint: disable=broad-except # pragma: no cover
        click.echo(e)
    finally:
        multiplexer.disconnect()
Example #9
0
def test_outbox_put_message():
    """Tests that an envelope is created from the message is in the queue."""
    agent_address = "Agent0"
    receiver_address = "Agent1"
    msg = DefaultMessage(
        dialogue_reference=("", ""),
        message_id=1,
        target=0,
        performative=DefaultMessage.Performative.BYTES,
        content=b"hello",
    )
    msg.counterparty = receiver_address
    dummy_connection = _make_dummy_connection()
    multiplexer = Multiplexer([dummy_connection])
    outbox = OutBox(multiplexer, agent_address)
    inbox = InBox(multiplexer)
    multiplexer.connect()
    outbox.put_message(msg)
    time.sleep(0.5)
    assert not inbox.empty(), "Inbox will not be empty after putting a message."
    multiplexer.disconnect()
Example #10
0
def _process_envelopes(
    agent_name: str,
    inbox: InBox,
    outbox: OutBox,
    dialogues: Dialogues,
    message_class: Type[Message],
) -> None:
    """
    Process envelopes.

    :param agent_name: name of an agent.
    :param inbox: an inbox object.
    :param outbox: an outbox object.
    :param dialogues: the dialogues object.
    :param message_class: the message class.

    :return: None.
    """
    envelope = _try_construct_envelope(agent_name, dialogues, message_class)
    if envelope is None:
        _check_for_incoming_envelope(inbox, message_class)
    else:
        outbox.put(envelope)
        click.echo(_construct_message("sending", envelope, message_class))
Example #11
0
 def _set_runtime_and_mail_boxes(
     self,
     runtime_class: Type[BaseRuntime],
     multiplexer_options: Dict,
     loop_mode: Optional[str] = None,
     loop: Optional[AbstractEventLoop] = None,
 ) -> None:
     """Set the runtime and inbox and outbox."""
     self._runtime = runtime_class(
         agent=self,
         loop_mode=loop_mode,
         loop=loop,
         multiplexer_options=multiplexer_options,
     )
     self._inbox = InBox(self.runtime.multiplexer)
     self._outbox = OutBox(self.runtime.multiplexer)
Example #12
0
    def setup(cls, **kwargs: Any) -> None:
        """Set up the skill test case."""
        identity = Identity("test_agent_name", "test_agent_address")

        cls._multiplexer = AsyncMultiplexer()
        cls._multiplexer._out_queue = (  # pylint: disable=protected-access
            asyncio.Queue()
        )
        cls._outbox = OutBox(cast(Multiplexer, cls._multiplexer))
        _shared_state = cast(Dict[str, Any], kwargs.pop("shared_state", dict()))
        _skill_config_overrides = cast(
            Dict[str, Any], kwargs.pop("config_overrides", dict())
        )
        agent_context = AgentContext(
            identity=identity,
            connection_status=cls._multiplexer.connection_status,
            outbox=cls._outbox,
            decision_maker_message_queue=Queue(),
            decision_maker_handler_context=SimpleNamespace(),
            task_manager=TaskManager(),
            default_ledger_id=identity.default_address_key,
            currency_denominations=DEFAULT_CURRENCY_DENOMINATIONS,
            default_connection=None,
            default_routing={},
            search_service_address="dummy_search_service_address",
            decision_maker_address="dummy_decision_maker_address",
            data_dir=os.getcwd(),
        )

        # This enables pre-populating the 'shared_state' prior to loading the skill
        if _shared_state != dict():
            for key, value in _shared_state.items():
                agent_context.shared_state[key] = value

        skill_configuration_file_path: Path = Path(cls.path_to_skill, "skill.yaml")
        loader = ConfigLoaders.from_package_type(PackageType.SKILL)

        with open_file(skill_configuration_file_path) as fp:
            skill_config: SkillConfig = loader.load(fp)

        # This enables overriding the skill's config prior to loading
        if _skill_config_overrides != {}:
            skill_config.update(_skill_config_overrides)

        skill_config.directory = cls.path_to_skill

        cls._skill = Skill.from_config(skill_config, agent_context)
Example #13
0
async def test_threaded_mode():
    """Test InBox OutBox objects in threaded mode."""
    connection_1 = _make_dummy_connection()
    connections = [connection_1]
    multiplexer = AsyncMultiplexer(connections, threaded=True)
    msg = DefaultMessage(
        performative=DefaultMessage.Performative.BYTES,
        content=b"",
    )
    msg.to = "to"
    msg.sender = "sender"
    context = EnvelopeContext(connection_id=connection_1.connection_id)
    envelope = Envelope(
        to="to",
        sender="sender",
        message=msg,
        context=context,
    )
    try:
        await multiplexer.connect()
        await asyncio.sleep(0.5)
        inbox = InBox(multiplexer)
        outbox = OutBox(multiplexer)

        assert inbox.empty()
        assert outbox.empty()

        outbox.put(envelope)
        received = await inbox.async_get()
        assert received == envelope

        assert inbox.empty()
        assert outbox.empty()

        outbox.put_message(msg, context=context)
        await inbox.async_wait()
        received = inbox.get_nowait()
        assert received == envelope

    finally:
        await multiplexer.disconnect()
Example #14
0
async def test_inbox_outbox():
    """Test InBox OutBox objects."""
    connection_1 = _make_dummy_connection()
    connections = [connection_1]
    multiplexer = AsyncMultiplexer(connections, loop=asyncio.get_event_loop())
    msg = DefaultMessage(performative=DefaultMessage.Performative.BYTES, content=b"",)
    msg.counterparty = "to"
    msg.sender = "sender"
    context = EnvelopeContext(connection_id=connection_1.connection_id)
    envelope = Envelope(
        to="to",
        sender="sender",
        protocol_id=msg.protocol_id,
        message=msg,
        context=context,
    )
    try:
        await multiplexer.connect()
        inbox = InBox(multiplexer)
        outbox = OutBox(multiplexer, "default_address")

        assert inbox.empty()
        assert outbox.empty()

        outbox.put(envelope)
        received = await inbox.async_get()
        assert received == envelope

        assert inbox.empty()
        assert outbox.empty()

        outbox.put_message(msg, context=context)
        await inbox.async_wait()
        received = inbox.get_nowait()
        assert received == envelope

    finally:
        await multiplexer.disconnect()
Example #15
0
    def __init__(
        self,
        identity: Identity,
        connections: List[Connection],
        loop: Optional[AbstractEventLoop] = None,
        timeout: float = 1.0,
        loop_mode: Optional[str] = None,
        runtime_mode: Optional[str] = None,
    ) -> None:
        """
        Instantiate the agent.

        :param identity: the identity of the agent.
        :param connections: the list of connections of the agent.
        :param loop: the event loop to run the connections.
        :param timeout: the time in (fractions of) seconds to time out an agent between act and react
        :param loop_mode: loop_mode to choose agent run loop.
        :param runtime_mode: runtime mode to up agent.

        :return: None
        """
        self._identity = identity
        self._connections = connections

        self._multiplexer = Multiplexer(self._connections, loop=loop)
        self._inbox = InBox(self._multiplexer)
        self._outbox = OutBox(self._multiplexer, identity.address)
        self._liveness = Liveness()
        self._timeout = timeout

        self._tick = 0

        self._loop_mode = loop_mode or self.DEFAULT_RUN_LOOP
        loop_cls = self._get_main_loop_class()
        self._main_loop: BaseAgentLoop = loop_cls(self)

        self._runtime_mode = runtime_mode or self.DEFAULT_RUNTIME
        runtime_cls = self._get_runtime_class()
        self._runtime: BaseRuntime = runtime_cls(agent=self, loop=loop)
Example #16
0
async def test_outbox_negative():
    """Test InBox OutBox objects."""
    connection_1 = _make_dummy_connection()
    connections = [connection_1]
    multiplexer = AsyncMultiplexer(connections, loop=asyncio.get_event_loop())
    msg = DefaultMessage(
        performative=DefaultMessage.Performative.BYTES,
        content=b"",
    )
    context = EnvelopeContext(connection_id=connection_1.connection_id)
    envelope = Envelope(
        to="to",
        sender="sender",
        protocol_specification_id=msg.protocol_specification_id,
        message=b"",
        context=context,
    )

    try:
        await multiplexer.connect()
        outbox = OutBox(multiplexer)

        assert outbox.empty()

        with pytest.raises(ValueError) as execinfo:
            outbox.put(envelope)
        assert (
            str(execinfo.value) ==
            "Only Message type allowed in envelope message field when putting into outbox."
        )

        assert outbox.empty()

        with pytest.raises(ValueError) as execinfo:
            outbox.put_message("")
        assert str(execinfo.value) == "Provided message not of type Message."

        assert outbox.empty()

        with pytest.raises(ValueError) as execinfo:
            outbox.put_message(msg)
        assert str(
            execinfo.value) == "Provided message has message.to not set."

        assert outbox.empty()
        msg.to = "to"

        with pytest.raises(ValueError) as execinfo:
            outbox.put_message(msg)
        assert str(
            execinfo.value) == "Provided message has message.sender not set."

    finally:
        await multiplexer.disconnect()