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)
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
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)
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
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
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
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] = []
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)
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)
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()
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()