Ejemplo n.º 1
0
    def __init__(
        self,
        agent: AbstractAgent,
        loop_mode: Optional[str] = None,
        loop: Optional[AbstractEventLoop] = None,
        threaded: bool = False,
    ) -> None:
        """
        Init runtime.

        :param agent: Agent to run.
        :param loop_mode: agent main loop mode.
        :param loop: optional event loop. if not provided a new one will be created.
        :return: None
        """
        Runnable.__init__(self, threaded=threaded, loop=loop if not threaded else None)
        logger = get_logger(__name__, agent.name)
        WithLogger.__init__(self, logger=logger)
        self._agent: AbstractAgent = agent
        self._state: AsyncState = AsyncState(RuntimeStates.stopped, RuntimeStates)
        self._state.add_callback(self._log_runtime_state)

        self._multiplexer: AsyncMultiplexer = self._get_multiplexer_instance()
        self._task_manager = TaskManager()
        self._decision_maker: Optional[DecisionMaker] = None

        self._loop_mode = loop_mode or self.DEFAULT_RUN_LOOP
        self.main_loop: BaseAgentLoop = self._get_main_loop_instance(self._loop_mode)
Ejemplo n.º 2
0
def test_get_logger():
    """Test the get_logger function."""
    module_path = "some.dotted.module.path"
    agent_name = "agent_name"
    expected_name = "some.agent_name.dotted.module.path"
    logger = get_logger(module_path, agent_name)
    assert logger.name == expected_name
Ejemplo n.º 3
0
    def __init__(self, agent_name: str = "standalone"):
        """
        Initialize the registry.

        :param agent_name: the name of the agent
        """
        logger = get_logger(__name__, agent_name)
        super().__init__(logger)
Ejemplo n.º 4
0
    def from_config(
        cls,
        configuration: ConnectionConfig,
        identity: Identity,
        crypto_store: CryptoStore,
        data_dir: str,
        **kwargs: Any,
    ) -> "Connection":
        """
        Load a connection from a configuration.

        :param configuration: the connection configuration.
        :param identity: the identity object.
        :param crypto_store: object to access the connection crypto objects.
        :param data_dir: the directory of the AEA project data.
        :return: an instance of the concrete connection class.
        """
        configuration = cast(ConnectionConfig, configuration)
        directory = cast(Path, configuration.directory)
        load_aea_package(configuration)
        connection_module_path = directory / "connection.py"
        if not (connection_module_path.exists() and connection_module_path.is_file()):
            raise AEAComponentLoadException(
                "Connection module '{}' not found.".format(connection_module_path)
            )
        connection_module = load_module(
            "connection_module", directory / "connection.py"
        )
        classes = inspect.getmembers(connection_module, inspect.isclass)
        connection_class_name = cast(str, configuration.class_name)
        connection_classes = list(
            filter(lambda x: re.match(connection_class_name, x[0]), classes)
        )
        name_to_class = dict(connection_classes)
        logger = get_logger(__name__, identity.name)
        logger.debug("Processing connection {}".format(connection_class_name))
        connection_class = name_to_class.get(connection_class_name, None)
        if connection_class is None:
            raise AEAComponentLoadException(
                "Connection class '{}' not found.".format(connection_class_name)
            )
        try:
            connection = connection_class(
                configuration=configuration,
                data_dir=data_dir,
                identity=identity,
                crypto_store=crypto_store,
                **kwargs,
            )
        except Exception as e:  # pragma: nocover # pylint: disable=broad-except
            e_str = parse_exception(e)
            raise AEAInstantiationException(
                f"An error occured during instantiation of connection {configuration.public_id}/{configuration.class_name}:\n{e_str}"
            )
        return connection
Ejemplo n.º 5
0
    def __init__(self, resources: Resources,
                 decision_maker_out_queue: AsyncFriendlyQueue) -> None:
        """
        Instantiate the filter.

        :param resources: the resources
        :param decision_maker_out_queue: the decision maker queue
        """
        logger = get_logger(__name__, resources.agent_name)
        WithLogger.__init__(self, logger=logger)
        self._resources = resources
        self._decision_maker_out_queue = decision_maker_out_queue
Ejemplo n.º 6
0
    def __init__(self, identity: Identity, wallet: Wallet, **kwargs):
        """
        Initialize the decision maker handler.

        :param identity: the identity
        :param wallet: the wallet
        :param logger: the logger
        :param kwargs: the key word arguments
        """
        logger = get_logger(__name__, identity.name)
        WithLogger.__init__(self, logger=logger)
        self._identity = identity
        self._wallet = wallet
        self._context = SimpleNamespace(**kwargs)
        self._message_out_queue = AsyncFriendlyQueue(
        )  # type: AsyncFriendlyQueue
Ejemplo n.º 7
0
    def __init__(
        self,
        agent: AbstractAgent,
        loop: Optional[AbstractEventLoop] = None,
        threaded: bool = False,
    ) -> None:
        """Init loop.

        :param agent: Agent or AEA to run.
        :param loop: optional asyncio event loop. if not specified a new loop will be created.
        """
        logger = get_logger(__name__, agent.name)
        WithLogger.__init__(self, logger)
        Runnable.__init__(self, loop=loop, threaded=threaded)

        self._agent: AbstractAgent = agent
        self._tasks: List[asyncio.Task] = []
        self._state: AsyncState = AsyncState(AgentLoopStates.initial)
        self._exceptions: List[Exception] = []
Ejemplo n.º 8
0
    def __init__(
        self,
        connections: Optional[Sequence[Connection]] = None,
        default_connection_index: int = 0,
        loop: Optional[AbstractEventLoop] = None,
        exception_policy: ExceptionPolicyEnum = ExceptionPolicyEnum.propagate,
        threaded: bool = False,
        agent_name: str = "standalone",
    ):
        """
        Initialize the connection multiplexer.

        :param connections: a sequence of connections.
        :param default_connection_index: the index of the connection to use as default.
            This information is used for envelopes which don't specify any routing context.
            If connections is None, this parameter is ignored.
        :param loop: the event loop to run the multiplexer. If None, a new event loop is created.
        :param agent_name: the name of the agent that owns the multiplexer, for logging purposes.
        """
        self._exception_policy: ExceptionPolicyEnum = exception_policy
        logger = get_logger(__name__, agent_name)
        WithLogger.__init__(self, logger=logger)
        Runnable.__init__(self, loop=loop, threaded=threaded)
        self._connections: List[Connection] = []
        self._id_to_connection: Dict[PublicId, Connection] = {}
        self._default_connection: Optional[Connection] = None
        self._initialize_connections_if_any(connections,
                                            default_connection_index)

        self._connection_status = MultiplexerStatus()

        self._in_queue = AsyncFriendlyQueue()  # type: AsyncFriendlyQueue
        self._out_queue = None  # type: Optional[asyncio.Queue]

        self._recv_loop_task = None  # type: Optional[asyncio.Task]
        self._send_loop_task = None  # type: Optional[asyncio.Task]
        self._default_routing = {}  # type: Dict[PublicId, PublicId]
        self._loop: asyncio.AbstractEventLoop = loop if loop is not None else asyncio.new_event_loop(
        )
        self._lock: asyncio.Lock = asyncio.Lock(loop=self._loop)
        self.set_loop(self._loop)
Ejemplo n.º 9
0
    def __init__(
        self,
        connections: Optional[Sequence[Connection]] = None,
        default_connection_index: int = 0,
        loop: Optional[AbstractEventLoop] = None,
        exception_policy: ExceptionPolicyEnum = ExceptionPolicyEnum.propagate,
        threaded: bool = False,
        agent_name: str = "standalone",
        default_routing: Optional[Dict[PublicId, PublicId]] = None,
        default_connection: Optional[PublicId] = None,
        protocols: Optional[List[Union[Protocol, Message]]] = None,
    ) -> None:
        """
        Initialize the connection multiplexer.

        :param connections: a sequence of connections.
        :param default_connection_index: the index of the connection to use as default.
            This information is used for envelopes which don't specify any routing context.
            If connections is None, this parameter is ignored.
        :param loop: the event loop to run the multiplexer. If None, a new event loop is created.
        :param agent_name: the name of the agent that owns the multiplexer, for logging purposes.
        """
        self._exception_policy: ExceptionPolicyEnum = exception_policy
        logger = get_logger(__name__, agent_name)
        WithLogger.__init__(self, logger=logger)
        Runnable.__init__(self, loop=loop, threaded=threaded)

        self._connections: List[Connection] = []
        self._id_to_connection: Dict[PublicId, Connection] = {}
        self._default_connection: Optional[Connection] = None

        connections = connections or []
        if not default_connection and connections:
            enforce(
                len(connections) - 1 >= default_connection_index,
                "default_connection_index os out of connections range!",
            )
            default_connection = connections[
                default_connection_index].connection_id

        if default_connection:
            enforce(
                bool([
                    i.connection_id.same_prefix(default_connection)
                    for i in connections
                ]),
                f"Default connection {default_connection} does not present in connections list!",
            )

        self._default_routing = {}  # type: Dict[PublicId, PublicId]

        self._setup(connections or [], default_routing, default_connection)

        self._connection_status = MultiplexerStatus()
        self._specification_id_to_protocol_id = {
            p.protocol_specification_id: p.protocol_id
            for p in protocols or []
        }

        self._in_queue = AsyncFriendlyQueue()  # type: AsyncFriendlyQueue
        self._out_queue = None  # type: Optional[asyncio.Queue]

        self._recv_loop_task = None  # type: Optional[asyncio.Task]
        self._send_loop_task = None  # type: Optional[asyncio.Task]

        self._loop: asyncio.AbstractEventLoop = loop if loop is not None else asyncio.new_event_loop(
        )
        self._lock: asyncio.Lock = asyncio.Lock(loop=self._loop)
        self.set_loop(self._loop)
Ejemplo n.º 10
0
    def __init__(
        self,
        identity: Identity,
        wallet: Wallet,
        resources: Resources,
        loop: Optional[AbstractEventLoop] = None,
        period: float = 0.05,
        execution_timeout: float = 0,
        max_reactions: int = 20,
        decision_maker_handler_class: Optional[
            Type[DecisionMakerHandler]] = None,
        skill_exception_policy: ExceptionPolicyEnum = ExceptionPolicyEnum.
        propagate,
        connection_exception_policy: ExceptionPolicyEnum = ExceptionPolicyEnum.
        propagate,
        loop_mode: Optional[str] = None,
        runtime_mode: Optional[str] = None,
        default_ledger: Optional[str] = None,
        currency_denominations: Optional[Dict[str, str]] = None,
        default_connection: Optional[PublicId] = None,
        default_routing: Optional[Dict[PublicId, PublicId]] = None,
        connection_ids: Optional[Collection[PublicId]] = None,
        search_service_address: str = DEFAULT_SEARCH_SERVICE_ADDRESS,
        **kwargs,
    ) -> None:
        """
        Instantiate the agent.

        :param identity: the identity of the agent
        :param wallet: the wallet of the agent.
        :param resources: the resources (protocols and skills) of the agent.
        :param loop: the event loop to run the connections.
        :param period: period to call agent's act
        :param execution_timeout: amount of time to limit single act/handle to execute.
        :param max_reactions: the processing rate of envelopes per tick (i.e. single loop).
        :param decision_maker_handler_class: the class implementing the decision maker handler to be used.
        :param skill_exception_policy: the skill exception policy enum
        :param loop_mode: loop_mode to choose agent run loop.
        :param runtime_mode: runtime mode (async, threaded) to run AEA in.
        :param default_ledger: default ledger id
        :param currency_denominations: mapping from ledger id to currency denomination
        :param default_connection: public id to the default connection
        :param default_routing: dictionary for default routing.
        :param connection_ids: active connection ids. Default: consider all the ones in the resources.
        :param search_service_address: the address of the search service used.
        :param kwargs: keyword arguments to be attached in the agent context namespace.

        :return: None
        """

        self._skills_exception_policy = skill_exception_policy
        self._connection_exception_policy = connection_exception_policy

        aea_logger = AgentLoggerAdapter(
            logger=get_logger(__name__, identity.name),
            agent_name=identity.name,
        )

        super().__init__(
            identity=identity,
            connections=[],
            loop=loop,
            period=period,
            loop_mode=loop_mode,
            runtime_mode=runtime_mode,
            logger=cast(Logger, aea_logger),
        )

        self.max_reactions = max_reactions

        if decision_maker_handler_class is None:
            from aea.decision_maker.default import (  # isort:skip  # pylint: disable=import-outside-toplevel
                DecisionMakerHandler as DefaultDecisionMakerHandler, )

            decision_maker_handler_class = DefaultDecisionMakerHandler
        decision_maker_handler = decision_maker_handler_class(
            identity=identity, wallet=wallet)
        self.runtime.set_decision_maker(decision_maker_handler)

        default_ledger_id = (default_ledger if default_ledger is not None else
                             identity.default_address_key)
        currency_denominations = (currency_denominations
                                  if currency_denominations is not None else
                                  DEFAULT_CURRENCY_DENOMINATIONS)
        self._context = AgentContext(
            self.identity,
            self.runtime.multiplexer.connection_status,
            self.outbox,
            self.runtime.decision_maker.message_in_queue,
            decision_maker_handler.context,
            self.runtime.task_manager,
            default_ledger_id,
            currency_denominations,
            default_connection,
            default_routing if default_routing is not None else {},
            search_service_address,
            decision_maker_handler.self_address,
            **kwargs,
        )
        self._execution_timeout = execution_timeout
        self._connection_ids = connection_ids
        self._resources = resources
        self._filter = Filter(self.resources,
                              self.runtime.decision_maker.message_out_queue)

        self._setup_loggers()
Ejemplo n.º 11
0
    def __init__(
        self,
        identity: Identity,
        wallet: Wallet,
        resources: Resources,
        data_dir: str,
        loop: Optional[AbstractEventLoop] = None,
        period: float = 0.05,
        execution_timeout: float = 0,
        max_reactions: int = 20,
        error_handler_class: Optional[Type[AbstractErrorHandler]] = None,
        decision_maker_handler_class: Optional[
            Type[DecisionMakerHandler]] = None,
        skill_exception_policy: ExceptionPolicyEnum = ExceptionPolicyEnum.
        propagate,
        connection_exception_policy: ExceptionPolicyEnum = ExceptionPolicyEnum.
        propagate,
        loop_mode: Optional[str] = None,
        runtime_mode: Optional[str] = None,
        default_ledger: Optional[str] = None,
        currency_denominations: Optional[Dict[str, str]] = None,
        default_connection: Optional[PublicId] = None,
        default_routing: Optional[Dict[PublicId, PublicId]] = None,
        connection_ids: Optional[Collection[PublicId]] = None,
        search_service_address: str = DEFAULT_SEARCH_SERVICE_ADDRESS,
        storage_uri: Optional[str] = None,
        **kwargs: Any,
    ) -> None:
        """
        Instantiate the agent.

        :param identity: the identity of the agent
        :param wallet: the wallet of the agent.
        :param resources: the resources (protocols and skills) of the agent.
        :param data_dir: directory where to put local files.
        :param loop: the event loop to run the connections.
        :param period: period to call agent's act
        :param execution_timeout: amount of time to limit single act/handle to execute.
        :param max_reactions: the processing rate of envelopes per tick (i.e. single loop).
        :param decision_maker_handler_class: the class implementing the decision maker handler to be used.
        :param skill_exception_policy: the skill exception policy enum
        :param loop_mode: loop_mode to choose agent run loop.
        :param runtime_mode: runtime mode (async, threaded) to run AEA in.
        :param default_ledger: default ledger id
        :param currency_denominations: mapping from ledger id to currency denomination
        :param default_connection: public id to the default connection
        :param default_routing: dictionary for default routing.
        :param connection_ids: active connection ids. Default: consider all the ones in the resources.
        :param search_service_address: the address of the search service used.
        :param storage_uri: optional uri to set generic storage
        :param kwargs: keyword arguments to be attached in the agent context namespace.
        :return: None
        """

        self._skills_exception_policy = skill_exception_policy
        self._connection_exception_policy = connection_exception_policy

        aea_logger = AgentLoggerAdapter(
            logger=get_logger(__name__, identity.name),
            agent_name=identity.name,
        )

        self._resources = resources

        super().__init__(
            identity=identity,
            connections=[],
            loop=loop,
            period=period,
            loop_mode=loop_mode,
            runtime_mode=runtime_mode,
            storage_uri=storage_uri,
            logger=cast(Logger, aea_logger),
        )

        default_routing = default_routing if default_routing is not None else {}
        connection_ids = connection_ids or []
        connections = [
            c for c in self.resources.get_all_connections()
            if (not connection_ids) or (c.connection_id in connection_ids)
        ]

        if not bool(self.resources.get_all_connections()):
            self.logger.warning(
                "Resource's connections list is empty! Instantiating AEA without connections..."
            )
        elif bool(self.resources.get_all_connections()
                  ) and not bool(connections):
            self.logger.warning(  # pragma: nocover
                "No connection left after filtering! Instantiating AEA without connections..."
            )

        self._set_runtime_and_mail_boxes(
            runtime_class=self._get_runtime_class(),
            loop_mode=loop_mode,
            loop=loop,
            multiplexer_options=dict(
                connections=connections,
                default_routing=default_routing,
                default_connection=default_connection,
                protocols=self.resources.get_all_protocols(),
            ),
        )

        self.max_reactions = max_reactions

        if decision_maker_handler_class is None:
            from aea.decision_maker.default import (  # isort:skip  # pylint: disable=import-outside-toplevel
                DecisionMakerHandler as DefaultDecisionMakerHandler, )

            decision_maker_handler_class = DefaultDecisionMakerHandler
        decision_maker_handler = decision_maker_handler_class(
            identity=identity, wallet=wallet)
        self.runtime.set_decision_maker(decision_maker_handler)

        if error_handler_class is None:
            error_handler_class = DefaultErrorHandler
        self._error_handler_class = error_handler_class
        default_ledger_id = (default_ledger if default_ledger is not None else
                             identity.default_address_key)
        currency_denominations = (currency_denominations
                                  if currency_denominations is not None else
                                  DEFAULT_CURRENCY_DENOMINATIONS)
        self._context = AgentContext(
            self.identity,
            self.runtime.multiplexer.connection_status,
            self.outbox,
            self.runtime.decision_maker.message_in_queue,
            decision_maker_handler.context,
            self.runtime.task_manager,
            default_ledger_id,
            currency_denominations,
            default_connection,
            default_routing,
            search_service_address,
            decision_maker_handler.self_address,
            data_dir,
            storage_callable=lambda: self.runtime.storage,
            build_dir=self.get_build_dir(),
            **kwargs,
        )
        self._execution_timeout = execution_timeout
        self._filter = Filter(self.resources,
                              self.runtime.decision_maker.message_out_queue)

        self._setup_loggers()