def test_from_json_and_to_json(self, skill_path): """Test the 'from_json' method and 'to_json' work correctly.""" f = open(skill_path) original_json = yaml.safe_load(f) expected_config = SkillConfig.from_json(original_json) assert isinstance(expected_config, SkillConfig) expected_json = expected_config.json actual_config = SkillConfig.from_json(expected_json) actual_json = actual_config.json assert expected_json == actual_json
def setup(self) -> None: """Set test cae instance.""" agent_name = "MyAgent" builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(DEFAULT_LEDGER, COSMOS_PRIVATE_KEY_PATH) self.handler_called = 0 def handler_func(*args, **kwargs): self.handler_called += 1 skill_context = SkillContext() handler_cls = make_handler_cls_from_funcion(handler_func) behaviour_cls = make_behaviour_cls_from_funcion(handler_func) self.handler = handler_cls(name="handler1", skill_context=skill_context) self.behaviour = behaviour_cls(name="behaviour1", skill_context=skill_context) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, handlers={"handler": self.handler}, behaviours={"behaviour": self.behaviour}, ) skill_context._skill = test_skill # weird hack builder.add_component_instance(test_skill) self.aea = builder.build() self.aea_tool = AeaTool(self.aea)
def make_skill( cls, config: SkillConfig = None, context: SkillContext = None, handlers: Optional[Dict[str, Type[Handler]]] = None, ) -> Skill: """ Make a skill from optional config, context, handlers dict. :param config: SkillConfig :param context: SkillContext :param handlers: dict of handler types to add to skill :return: Skill """ handlers = handlers or {} context = context or SkillContext() config = config or SkillConfig( name="skill_{}".format(uuid.uuid4().hex[0:5]), author="fetchai") handlers_instances = { name: handler_cls(name=name, skill_context=context) for name, handler_cls in handlers.items() } skill = Skill(configuration=config, skill_context=context, handlers=handlers_instances) return skill
def test_handle_internal_message_new_handlers_with_error(self): """Test handle internal message when an error happens while registering a new handler.""" skill = Skill( SkillConfig("name", "author", "0.1.0"), handlers={}, behaviours={}, models={}, ) self.resources.add_skill(skill) new_handler = DummyHandler(name="dummy2", skill_context=skill.skill_context) with unittest.mock.patch.object(self.resources.handler_registry, "register", side_effect=ValueError): with unittest.mock.patch.object(aea.registries.filter.logger, "warning") as mock_logger_warning: skill.skill_context.new_handlers.put(new_handler) self.filter.handle_internal_messages() mock_logger_warning.assert_called_with( "Error when trying to add a new handler: ") assert self.decision_make_queue.empty() assert len(self.resources.handler_registry.fetch_all()) == 0 # restore previous state self.resources.component_registry.unregister(skill.component_id)
def test_storage_access_from_behaviour(): """Test storage access from behaviour component.""" builder = AEABuilder() builder.set_name("aea_1") builder.add_private_key(DEFAULT_LEDGER) skill_context = SkillContext() behaviour = TBehaviour(name="behaviour", skill_context=skill_context) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, handlers={}, behaviours={"behaviour": behaviour}, ) builder.add_component_instance(test_skill) builder.set_storage_uri("sqlite://:memory:") aea = builder.build() skill_context.set_agent_context(aea.context) aea.runtime._threaded = True aea.runtime.start() try: wait_for_condition(lambda: aea.is_running, timeout=10) wait_for_condition(lambda: behaviour.counter > 0, timeout=10) col = skill_context.storage.get_sync_collection(behaviour.COL_NAME) assert col.get(behaviour.OBJ_ID) == behaviour.OBJ_BODY finally: aea.runtime.stop() aea.runtime.wait_completed(sync=True, timeout=10)
def test_remove_component_success(): """Test remove registered component.""" dep_manager = _DependenciesManager() protocol = ProtocolConfig("a_protocol", "author", "0.1.0") skill = SkillConfig("skill", "author", "0.1.0", protocols=[protocol.public_id]) dep_manager.add_component(protocol) dep_manager.add_component(skill) dep_manager.remove_component(skill.component_id)
def test_from_json_and_to_json(self): """Test the 'from_json' method and 'to_json' work correctly.""" f = open(os.path.join(CUR_PATH, "data", "dummy_skill", "skill.yaml")) expected_json = yaml.safe_load(f) config = SkillConfig.from_json(expected_json) assert isinstance(config, SkillConfig) actual_json = config.json assert expected_json == actual_json
def test_remove_component_depends_on_fail(): """Test component remove fails cause dependency.""" dep_manager = _DependenciesManager() protocol = ProtocolConfig("a_protocol", "author", "0.1.0") dep_manager.add_component(protocol) dep_manager.add_component( SkillConfig("skill", "author", "0.1.0", protocols=[protocol.public_id]) ) with pytest.raises( ValueError, match=r"Cannot remove component .* of type .*. Other components depends on it: .*", ): dep_manager.remove_component(protocol.component_id)
def make_skill(agent, handlers=None, behaviours=None) -> Skill: """Construct skill instance for agent from behaviours.""" handlers = handlers or {} behaviours = behaviours or {} config = SkillConfig(name="test_skill", author="fetchai") skill_context = SkillContext(agent.context) skill = Skill(configuration=config, skill_context=skill_context) for name, handler_cls in handlers.items(): handler = handler_cls(name=name, skill_context=skill_context) skill.handlers.update({handler.name: handler}) for name, behaviour_cls in behaviours.items(): behaviour = behaviour_cls(name=name, skill_context=skill_context) skill.behaviours.update({behaviour.name: behaviour}) return skill
def setup_class(cls): """Set up the test class.""" cls.expected_custom_component_configuration = dict(foo="bar") cls.skill_config = SkillConfig( name="skill_name", author="author", version="0.1.0", ) cls.skill_config.protocols = {cls.old_protocol_id} cls.skill_config.contracts = {cls.old_contract_id} cls.skill_config.connections = {cls.old_connection_id} cls.skill_config.skills = {cls.old_skill_id} replace_component_ids(cls.skill_config, cls.replacements)
def test_storage_access_from_handler(): """Test storage access from handler component.""" builder = AEABuilder() builder.set_name("aea_1") builder.add_private_key(DEFAULT_LEDGER) skill_context = SkillContext() handler = THandler(name="behaviour", skill_context=skill_context) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, handlers={"handler": handler}, behaviours={}, ) builder.add_component_instance(test_skill) builder.set_storage_uri("sqlite://:memory:") aea = builder.build() skill_context.set_agent_context(aea.context) aea.runtime._threaded = True aea.runtime.start() msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) msg.to = aea.identity.address msg.sender = aea.identity.address envelope = Envelope(to=msg.to, sender=msg.sender, message=msg,) try: wait_for_condition(lambda: aea.is_running, timeout=10) aea.runtime.multiplexer.in_queue.put(envelope) wait_for_condition(lambda: handler.counter > 0, timeout=10) col = skill_context.storage.get_sync_collection(handler.COL_NAME) assert col.get(handler.OBJ_ID) == handler.OBJ_BODY finally: aea.runtime.stop() aea.runtime.wait_completed(sync=True, timeout=10)
def test_handle_internal_message_new_behaviours(self): """Test handle internal message when there are new behaviours to register.""" skill = Skill( SkillConfig("name", "author", "0.1.0"), handlers={}, behaviours={}, models={}, ) self.resources.add_skill(skill) new_behaviour = DummyBehaviour(name="dummy2", skill_context=skill.skill_context) skill.skill_context.new_behaviours.put(new_behaviour) self.filter.handle_internal_messages() assert self.decision_make_queue.empty() assert len(self.resources.behaviour_registry.fetch_all()) == 1 # restore previous state self.resources.remove_skill(skill.public_id) assert len(self.resources.behaviour_registry.fetch_all()) == 0
def prepare(self, function: Callable) -> None: """Prepare aea_tool for testing. :param function: function be called on react handle or/and Behaviour.act :return: None """ agent_name = "MyAgent" builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(FetchAICrypto.identifier, FETCHAI_PRIVATE_KEY_PATH) self.function_finished = False def handler_func(*args, **kwargs): function() self.function_finished = True skill_context = SkillContext() handler_cls = make_handler_cls_from_funcion(handler_func) behaviour_cls = make_behaviour_cls_from_funcion(handler_func) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, handlers={ "handler1": handler_cls(name="handler1", skill_context=skill_context) }, behaviours={ "behaviour1": behaviour_cls(name="behaviour1", skill_context=skill_context) }, ) skill_context._skill = test_skill # weird hack builder._add_component_to_resources(test_skill) aea = builder.build() self.aea_tool = AeaTool(aea) self.aea_tool.put_inbox(AeaTool.dummy_envelope())
def setup_class(cls): """Set the tests up.""" skill_context = SkillContext() skill_config = SkillConfig(name="simple_skill", author="fetchai", version="0.1.0") class MyHandler(Handler): def setup(self): pass def handle(self, message: Message): pass def teardown(self): pass class MyBehaviour(Behaviour): def setup(self): pass def act(self): pass def teardown(self): pass cls.handler_name = "some_handler" cls.handler = MyHandler(skill_context=skill_context, name=cls.handler_name) cls.model_name = "some_model" cls.model = Model(skill_context=skill_context, name=cls.model_name) cls.behaviour_name = "some_behaviour" cls.behaviour = MyBehaviour(skill_context=skill_context, name=cls.behaviour_name) cls.skill = Skill( skill_config, skill_context, handlers={cls.handler.name: cls.handler}, models={cls.model.name: cls.model}, behaviours={cls.behaviour.name: cls.behaviour}, )
def _builder(self, agent_name="agent1", act_func=None) -> AEABuilder: """Build an aea instance.""" builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(FetchAICrypto.identifier, FETCHAI_PRIVATE_KEY_PATH) skill_context = SkillContext() act_func = act_func or (lambda self: self) behaviour_cls = make_behaviour_cls_from_funcion(act_func) behaviour = behaviour_cls(name="behaviour", skill_context=skill_context) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, behaviours={"behaviour": behaviour}, ) skill_context._skill = test_skill # weird hack builder.add_component_instance(test_skill) builder.set_runtime_mode("async") return builder
def prepare(self, function: Callable) -> None: """Prepare aea_tool for testing. :param function: function be called on react handle or/and Behaviour.act :return: None """ agent_name = "MyAgent" builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(DEFAULT_LEDGER, FETCHAI_PRIVATE_KEY_PATH) self.function_finished = False def handler_func(*args, **kwargs): function() self.function_finished = True skill_context = SkillContext() handler_cls = make_handler_cls_from_funcion(handler_func) behaviour_cls = make_behaviour_cls_from_funcion(handler_func) self.behaviour = behaviour_cls(name="behaviour1", skill_context=skill_context) test_skill = Skill( SkillConfig(name="test_skill", author="fetchai"), skill_context=skill_context, handlers={ "handler1": handler_cls(name="handler1", skill_context=skill_context) }, behaviours={"behaviour1": self.behaviour}, ) skill_context._skill = test_skill # weird hack builder.add_component_instance(test_skill) aea = builder.build() self.aea_tool = AeaTool(aea) self.envelope = AeaTool.dummy_envelope() self.aea_tool.aea.runtime.main_loop._setup()
def test_generated_protocol_end_to_end(self): """Test that a generated protocol could be used in exchanging messages between two agents.""" agent_name_1 = "my_aea_1" agent_name_2 = "my_aea_2" builder_1 = AEABuilder() builder_1.set_name(agent_name_1) builder_1.add_private_key(FetchAICrypto.identifier, self.private_key_path_1) builder_1.set_default_ledger(FetchAICrypto.identifier) builder_1.set_default_connection( PublicId.from_str("fetchai/oef:0.3.0")) builder_1.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa")) builder_1.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder_1.add_component( ComponentType.PROTOCOL, Path(ROOT_DIR, "tests", "data", "generator", "t_protocol"), skip_consistency_check=True, ) builder_1.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "oef")) builder_2 = AEABuilder() builder_2.set_name(agent_name_2) builder_2.add_private_key(FetchAICrypto.identifier, self.private_key_path_2) builder_2.set_default_ledger(FetchAICrypto.identifier) builder_2.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa")) builder_2.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder_2.set_default_connection( PublicId.from_str("fetchai/oef:0.3.0")) builder_2.add_component( ComponentType.PROTOCOL, Path(ROOT_DIR, "tests", "data", "generator", "t_protocol"), skip_consistency_check=True, ) builder_2.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "oef")) # create AEAs aea_1 = builder_1.build( connection_ids=[PublicId.from_str("fetchai/oef:0.3.0")]) aea_2 = builder_2.build( connection_ids=[PublicId.from_str("fetchai/oef:0.3.0")]) # message 1 message = TProtocolMessage( message_id=1, dialogue_reference=(str(0), ""), target=0, performative=TProtocolMessage.Performative.PERFORMATIVE_PT, content_bytes=b"some bytes", content_int=42, content_float=42.7, content_bool=True, content_str="some string", ) encoded_message_in_bytes = TProtocolSerializer().encode(message) envelope = Envelope( to=aea_2.identity.address, sender=aea_1.identity.address, protocol_id=TProtocolMessage.protocol_id, message=encoded_message_in_bytes, ) # message 2 message_2 = TProtocolMessage( message_id=2, dialogue_reference=(str(0), ""), target=1, performative=TProtocolMessage.Performative.PERFORMATIVE_PT, content_bytes=b"some other bytes", content_int=43, content_float=43.7, content_bool=False, content_str="some other string", ) encoded_message_2_in_bytes = TProtocolSerializer().encode(message_2) # add handlers to AEA resources] skill_context_1 = SkillContext(aea_1.context) skill_1 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_1) skill_context_1._skill = skill_1 agent_1_handler = Agent1Handler(skill_context=skill_context_1, name="fake_handler_1") aea_1.resources._handler_registry.register( ( PublicId.from_str("fetchai/fake_skill:0.1.0"), TProtocolMessage.protocol_id, ), agent_1_handler, ) skill_context_2 = SkillContext(aea_2.context) skill_2 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_2) skill_context_2._skill = skill_2 agent_2_handler = Agent2Handler( encoded_messsage=encoded_message_2_in_bytes, skill_context=skill_context_2, name="fake_handler_2", ) aea_2.resources._handler_registry.register( ( PublicId.from_str("fetchai/fake_skill:0.1.0"), TProtocolMessage.protocol_id, ), agent_2_handler, ) # Start threads t_1 = Thread(target=aea_1.start) t_2 = Thread(target=aea_2.start) try: t_1.start() t_2.start() time.sleep(1.0) aea_1.outbox.put(envelope) time.sleep(5.0) assert (agent_2_handler.handled_message.message_id == message.message_id ), "Message from Agent 1 to 2: message ids do not match" assert ( agent_2_handler.handled_message.dialogue_reference == message.dialogue_reference ), "Message from Agent 1 to 2: dialogue references do not match" assert ( agent_2_handler.handled_message.dialogue_reference[0] == message.dialogue_reference[0] ), "Message from Agent 1 to 2: dialogue reference[0]s do not match" assert ( agent_2_handler.handled_message.dialogue_reference[1] == message.dialogue_reference[1] ), "Message from Agent 1 to 2: dialogue reference[1]s do not match" assert (agent_2_handler.handled_message.target == message.target ), "Message from Agent 1 to 2: targets do not match" assert (agent_2_handler.handled_message.performative == message.performative ), "Message from Agent 1 to 2: performatives do not match" assert (agent_2_handler.handled_message.content_bytes == message.content_bytes ), "Message from Agent 1 to 2: content_bytes do not match" assert (agent_2_handler.handled_message.content_int == message.content_int ), "Message from Agent 1 to 2: content_int do not match" # floats do not seem to lose some precision when serialised then deserialised using protobuf # assert agent_2_handler.handled_message.content_float == message.content_float, "Message from Agent 1 to 2: content_float do not match" assert (agent_2_handler.handled_message.content_bool == message.content_bool ), "Message from Agent 1 to 2: content_bool do not match" assert (agent_2_handler.handled_message.content_str == message.content_str ), "Message from Agent 1 to 2: content_str do not match" assert ( agent_1_handler.handled_message.message_id == message_2.message_id ), "Message from Agent 1 to 2: dialogue references do not match" assert ( agent_1_handler.handled_message.dialogue_reference == message_2.dialogue_reference ), "Message from Agent 2 to 1: dialogue references do not match" assert ( agent_1_handler.handled_message.dialogue_reference[0] == message_2.dialogue_reference[0] ), "Message from Agent 2 to 1: dialogue reference[0]s do not match" assert ( agent_1_handler.handled_message.dialogue_reference[1] == message_2.dialogue_reference[1] ), "Message from Agent 2 to 1: dialogue reference[1]s do not match" assert (agent_1_handler.handled_message.target == message_2.target ), "Message from Agent 2 to 1: targets do not match" assert (agent_1_handler.handled_message.performative == message_2.performative ), "Message from Agent 2 to 1: performatives do not match" assert (agent_1_handler.handled_message.content_bytes == message_2.content_bytes ), "Message from Agent 2 to 1: content_bytes do not match" assert (agent_1_handler.handled_message.content_int == message_2.content_int ), "Message from Agent 2 to 1: content_int do not match" # floats do not seem to lose some precision when serialised then deserialised using protobuf # assert agent_1_handler.handled_message.content_float == message_2.content_float, "Message from Agent 2 to 1: content_float do not match" assert (agent_1_handler.handled_message.content_bool == message_2.content_bool ), "Message from Agent 2 to 1: content_bool do not match" assert (agent_1_handler.handled_message.content_str == message_2.content_str ), "Message from Agent 2 to 1: content_str do not match" time.sleep(2.0) finally: aea_1.stop() aea_2.stop() t_1.join() t_2.join()
def run(): # Create a private key create_private_key(CosmosCrypto.identifier, private_key_file=COSMOS_PRIVATE_KEY_FILE_1) # Instantiate the builder and build the AEA # By default, the default protocol, error skill and stub connection are added builder = AEABuilder() builder.set_name("my_aea") builder.add_private_key(CosmosCrypto.identifier, COSMOS_PRIVATE_KEY_FILE_1) # Create our AEA my_aea = builder.build() # add a simple skill with handler skill_context = SkillContext(my_aea.context) skill_config = SkillConfig(name="simple_skill", author="fetchai", version="0.1.0") signing_handler = SigningHandler(skill_context=skill_context, name="signing_handler") signing_dialogues_model = SigningDialogues(skill_context=skill_context, name="signing_dialogues") simple_skill = Skill( skill_config, skill_context, handlers={signing_handler.name: signing_handler}, models={signing_dialogues_model.name: signing_dialogues_model}, ) my_aea.resources.add_skill(simple_skill) # create a second identity create_private_key(CosmosCrypto.identifier, private_key_file=COSMOS_PRIVATE_KEY_FILE_2) counterparty_wallet = Wallet( {CosmosCrypto.identifier: COSMOS_PRIVATE_KEY_FILE_2}) counterparty_identity = Identity( name="counterparty_aea", addresses=counterparty_wallet.addresses, default_address_key=CosmosCrypto.identifier, ) # create signing message for decision maker to sign terms = Terms( ledger_id=CosmosCrypto.identifier, sender_address=my_aea.identity.address, counterparty_address=counterparty_identity.address, amount_by_currency_id={"FET": -1}, quantities_by_good_id={"some_service": 1}, nonce="some_nonce", fee_by_currency_id={"FET": 0}, ) signing_dialogues = cast(SigningDialogues, skill_context.signing_dialogues) stub_transaction = LedgerApis.get_transfer_transaction( terms.ledger_id, terms.sender_address, terms.counterparty_address, terms.sender_payable_amount, terms.sender_fee, terms.nonce, ) signing_msg = SigningMessage( performative=SigningMessage.Performative.SIGN_TRANSACTION, dialogue_reference=signing_dialogues. new_self_initiated_dialogue_reference(), skill_callback_ids=(str(skill_context.skill_id), ), raw_transaction=RawTransaction(CosmosCrypto.identifier, stub_transaction), terms=terms, skill_callback_info={"some_info_key": "some_info_value"}, ) signing_msg.counterparty = "decision_maker" signing_dialogue = cast(Optional[SigningDialogue], signing_dialogues.update(signing_msg)) assert signing_dialogue is not None my_aea.context.decision_maker_message_queue.put_nowait(signing_msg) # Set the AEA running in a different thread try: logger.info("STARTING AEA NOW!") t = Thread(target=my_aea.start) t.start() # Let it run long enough to interact with the decision maker time.sleep(1) finally: # Shut down the AEA logger.info("STOPPING AEA NOW!") my_aea.stop() t.join()
def test_gym(self, pytestconfig): """Run the gym skill sequence.""" if pytestconfig.getoption("ci"): pytest.skip("Skipping the test since it doesn't work in CI.") # add packages folder packages_src = os.path.join(self.cwd, 'packages') packages_dst = os.path.join(os.getcwd(), 'packages') shutil.copytree(packages_src, packages_dst) # create agent result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "create", self.agent_name], standalone_mode=False) assert result.exit_code == 0 agent_dir_path = os.path.join(self.t, self.agent_name) os.chdir(agent_dir_path) # add packages and install dependencies result = self.runner.invoke(cli, [*CLI_LOG_OPTION, "add", "skill", "gym"], standalone_mode=False) assert result.exit_code == 0 result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "add", "connection", "gym"], standalone_mode=False) assert result.exit_code == 0 result = self.runner.invoke(cli, [*CLI_LOG_OPTION, "install"], standalone_mode=False) assert result.exit_code == 0 # add gyms folder from examples gyms_src = os.path.join(self.cwd, 'examples', 'gym_ex', 'gyms') gyms_dst = os.path.join(self.t, self.agent_name, 'gyms') shutil.copytree(gyms_src, gyms_dst) # change config file of gym connection file_src = os.path.join(self.cwd, 'tests', 'test_packages', 'test_skills', 'data', 'connection.yaml') file_dst = os.path.join(self.t, self.agent_name, 'connections', 'gym', 'connection.yaml') shutil.copyfile(file_src, file_dst) # change number of training steps skill_config_path = Path(self.t, self.agent_name, "skills", "gym", "skill.yaml") skill_config = SkillConfig.from_json( yaml.safe_load(open(skill_config_path))) skill_config.tasks.read("GymTask").args["nb_steps"] = 100 yaml.safe_dump(skill_config.json, open(skill_config_path, "w")) process = subprocess.Popen( [sys.executable, '-m', 'aea.cli', "run", "--connections", "gym"], stdout=subprocess.PIPE, env=os.environ.copy()) # check the gym run ends time.sleep(10.0) process.send_signal(signal.SIGINT) process.wait(timeout=5) assert process.returncode == 0 poll = process.poll() if poll is None: process.terminate() process.wait(2) os.chdir(self.t) self.result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "delete", self.agent_name], standalone_mode=False)
def run(): # Create a private key create_private_key(CosmosCrypto.identifier) # Ensure the input and output files do not exist initially if os.path.isfile(INPUT_FILE): os.remove(INPUT_FILE) if os.path.isfile(OUTPUT_FILE): os.remove(OUTPUT_FILE) # Instantiate the builder and build the AEA # By default, the default protocol, error skill and stub connection are added builder = AEABuilder() builder.set_name("my_aea") builder.add_private_key(CosmosCrypto.identifier, COSMOS_PRIVATE_KEY_FILE) # Add the echo skill (assuming it is present in the local directory 'packages') builder.add_skill("./packages/fetchai/skills/echo") # create skill and handler manually from aea.protocols.base import Message from aea.protocols.default.message import DefaultMessage from aea.skills.base import Handler class DummyHandler(Handler): """Dummy handler to handle messages.""" SUPPORTED_PROTOCOL = DefaultMessage.protocol_id def setup(self) -> None: """Noop setup.""" def teardown(self) -> None: """Noop teardown.""" def handle(self, message: Message) -> None: """Handle incoming message.""" self.context.logger.info("You got a message: {}".format( str(message))) config = SkillConfig(name="test_skill", author="fetchai") skill = Skill(configuration=config) dummy_handler = DummyHandler(name="dummy_handler", skill_context=skill.skill_context) skill.handlers.update({dummy_handler.name: dummy_handler}) builder.add_component_instance(skill) # Create our AEA my_aea = builder.build() # Set the AEA running in a different thread try: t = Thread(target=my_aea.start) t.start() # Wait for everything to start up time.sleep(4) # Create a message inside an envelope and get the stub connection to pass it on to the echo skill message_text = ( "my_aea,other_agent,fetchai/default:0.3.0,\x08\x01*\x07\n\x05hello," ) with open(INPUT_FILE, "w") as f: f.write(message_text) print("input message: " + message_text) # Wait for the envelope to get processed time.sleep(4) # Read the output envelope generated by the echo skill with open(OUTPUT_FILE, "r") as f: print("output message: " + f.readline()) finally: # Shut down the AEA my_aea.stop() t.join() t = None
def test_generated_protocol_end_to_end(self): """Test that a generated protocol could be used in exchanging messages between two agents.""" agent_name_1 = "my_aea_1" agent_name_2 = "my_aea_2" builder_1 = AEABuilder() builder_1.set_name(agent_name_1) builder_1.add_private_key(DEFAULT_LEDGER, self.private_key_path_1) builder_1.set_default_ledger(DEFAULT_LEDGER) builder_1.set_default_connection(OEF_CONNECTION_PUBLIC_ID) builder_1.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa") ) builder_1.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search") ) builder_1.add_component( ComponentType.PROTOCOL, Path(PATH_TO_T_PROTOCOL), skip_consistency_check=True, ) builder_1.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "oef") ) builder_2 = AEABuilder() builder_2.set_name(agent_name_2) builder_2.add_private_key(DEFAULT_LEDGER, self.private_key_path_2) builder_2.set_default_ledger(DEFAULT_LEDGER) builder_2.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa") ) builder_2.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search") ) builder_2.set_default_connection(OEF_CONNECTION_PUBLIC_ID) builder_2.add_component( ComponentType.PROTOCOL, Path(PATH_TO_T_PROTOCOL), skip_consistency_check=True, ) builder_2.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "oef") ) # create AEAs aea_1 = builder_1.build(connection_ids=[OEF_CONNECTION_PUBLIC_ID]) aea_2 = builder_2.build(connection_ids=[OEF_CONNECTION_PUBLIC_ID]) # dialogues def role_from_first_message_1( 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 TProtocolDialogue.Role.ROLE_1 agent_1_dialogues = TProtocolDialogues( self_address=aea_1.identity.address, role_from_first_message=role_from_first_message_1, ) def role_from_first_message_1( 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 TProtocolDialogue.Role.ROLE_2 agent_2_dialogues = TProtocolDialogues( self_address=aea_2.identity.address, role_from_first_message=role_from_first_message_1, ) # messages message_1, aea_1_dialogue = agent_1_dialogues.create( counterparty=aea_2.identity.address, performative=TProtocolMessage.Performative.PERFORMATIVE_PT, content_bytes=b"some bytes", content_int=42, content_float=42.7, content_bool=True, content_str="some string", ) message_1 = cast(TProtocolMessage, message_1) message_2, aea_2_dialogue = agent_2_dialogues.create( counterparty=aea_1.identity.address, performative=TProtocolMessage.Performative.PERFORMATIVE_PT, content_bytes=b"some other bytes", content_int=43, content_float=43.7, content_bool=False, content_str="some other string", ) message_2 = cast(TProtocolMessage, message_2) # add handlers to AEA resources skill_context_1 = SkillContext(aea_1.context) skill_1 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_1) skill_context_1._skill = skill_1 agent_1_handler = Agent1Handler( skill_context=skill_context_1, name="fake_handler_1", dialogues=agent_1_dialogues, ) aea_1.resources._handler_registry.register( ( PublicId.from_str("fetchai/fake_skill:0.1.0"), TProtocolMessage.protocol_id, ), agent_1_handler, ) skill_context_2 = SkillContext(aea_2.context) skill_2 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_2) skill_context_2._skill = skill_2 agent_2_handler = Agent2Handler( message=message_2, dialogues=agent_2_dialogues, skill_context=skill_context_2, name="fake_handler_2", ) aea_2.resources._handler_registry.register( ( PublicId.from_str("fetchai/fake_skill:0.1.0"), TProtocolMessage.protocol_id, ), agent_2_handler, ) # Start threads t_1 = Thread(target=aea_1.start) t_2 = Thread(target=aea_2.start) try: t_1.start() t_2.start() time.sleep(1.0) aea_1.outbox.put_message(message_1) time.sleep(5.0) assert ( agent_2_handler.handled_message.message_id == message_1.message_id ), "Message from Agent 1 to 2: message ids do not match" assert ( agent_2_handler.handled_message.dialogue_reference == message_1.dialogue_reference ), "Message from Agent 1 to 2: dialogue references do not match" assert ( agent_2_handler.handled_message.dialogue_reference[0] == message_1.dialogue_reference[0] ), "Message from Agent 1 to 2: dialogue reference[0]s do not match" assert ( agent_2_handler.handled_message.dialogue_reference[1] == message_1.dialogue_reference[1] ), "Message from Agent 1 to 2: dialogue reference[1]s do not match" assert ( agent_2_handler.handled_message.target == message_1.target ), "Message from Agent 1 to 2: targets do not match" assert ( agent_2_handler.handled_message.performative == message_1.performative ), "Message from Agent 1 to 2: performatives do not match" assert ( agent_2_handler.handled_message.content_bytes == message_1.content_bytes ), "Message from Agent 1 to 2: content_bytes do not match" assert ( agent_2_handler.handled_message.content_int == message_1.content_int ), "Message from Agent 1 to 2: content_int do not match" # assert ( # agent_2_handler.handled_message.content_float == message_1.content_float # noqa: E800 # ), "Message from Agent 1 to 2: content_float do not match" assert ( agent_2_handler.handled_message.content_bool == message_1.content_bool ), "Message from Agent 1 to 2: content_bool do not match" assert ( agent_2_handler.handled_message.content_str == message_1.content_str ), "Message from Agent 1 to 2: content_str do not match" assert ( agent_1_handler.handled_message.message_id == message_2.message_id ), "Message from Agent 1 to 2: dialogue references do not match" assert ( agent_1_handler.handled_message.dialogue_reference == message_2.dialogue_reference ), "Message from Agent 2 to 1: dialogue references do not match" assert ( agent_1_handler.handled_message.dialogue_reference[0] == message_2.dialogue_reference[0] ), "Message from Agent 2 to 1: dialogue reference[0]s do not match" assert ( agent_1_handler.handled_message.dialogue_reference[1] == message_2.dialogue_reference[1] ), "Message from Agent 2 to 1: dialogue reference[1]s do not match" assert ( agent_1_handler.handled_message.target == message_2.target ), "Message from Agent 2 to 1: targets do not match" assert ( agent_1_handler.handled_message.performative == message_2.performative ), "Message from Agent 2 to 1: performatives do not match" assert ( agent_1_handler.handled_message.content_bytes == message_2.content_bytes ), "Message from Agent 2 to 1: content_bytes do not match" assert ( agent_1_handler.handled_message.content_int == message_2.content_int ), "Message from Agent 2 to 1: content_int do not match" # assert ( # agent_1_handler.handled_message.content_float == message_2.content_float # noqa: E800 # ), "Message from Agent 2 to 1: content_float do not match" assert ( agent_1_handler.handled_message.content_bool == message_2.content_bool ), "Message from Agent 2 to 1: content_bool do not match" assert ( agent_1_handler.handled_message.content_str == message_2.content_str ), "Message from Agent 2 to 1: content_str do not match" time.sleep(2.0) finally: aea_1.stop() aea_2.stop() t_1.join() t_2.join()
def ipfs_hashing( package_hashes: Dict[str, str], target_dir: str, package_type: str, package_name: str, ipfs_hash_only: IPFSHashOnly, ): """Hashes a package and its components.""" print("Processing package {} of type {}".format(package_name, package_type)) # load config file to get ignore patterns, dump again immediately to impose ordering if package_type == "agents": config = AgentConfig.from_json( yaml.safe_load(open(Path(target_dir, DEFAULT_AEA_CONFIG_FILE)))) yaml_dump(config.json, open(Path(target_dir, DEFAULT_AEA_CONFIG_FILE), "w")) elif package_type == "connections": config = ConnectionConfig.from_json( yaml.safe_load( open(Path(target_dir, DEFAULT_CONNECTION_CONFIG_FILE)))) yaml_dump(config.json, open(Path(target_dir, DEFAULT_CONNECTION_CONFIG_FILE), "w")) elif package_type == "contracts": config = ContractConfig.from_json( yaml.safe_load(open(Path(target_dir, DEFAULT_CONTRACT_CONFIG_FILE)))) yaml_dump(config.json, open(Path(target_dir, DEFAULT_CONTRACT_CONFIG_FILE), "w")) elif package_type == "protocols": config = ProtocolConfig.from_json( yaml.safe_load(open(Path(target_dir, DEFAULT_PROTOCOL_CONFIG_FILE)))) yaml_dump(config.json, open(Path(target_dir, DEFAULT_PROTOCOL_CONFIG_FILE), "w")) elif package_type == "skills": config = SkillConfig.from_json( yaml.safe_load(open(Path(target_dir, DEFAULT_SKILL_CONFIG_FILE)))) yaml_dump(config.json, open(Path(target_dir, DEFAULT_SKILL_CONFIG_FILE), "w")) config = yaml.safe_load(next(Path(target_dir).glob("*.yaml")).open()) ignore_patterns = config.get("fingerprint_ignore_patterns", []) if package_type != "agents": # hash inner components fingerprints_dict = _compute_fingerprint(Path(target_dir), ignore_patterns) # confirm ipfs only generates same hash: for file_name, ipfs_hash in fingerprints_dict.items(): path = os.path.join(target_dir, file_name) ipfsho_hash = ipfs_hash_only.get(path) if ipfsho_hash != ipfs_hash: print("WARNING, hashes don't match for: {}".format(path)) # update fingerprints file_name = package_type[:-1] + ".yaml" yaml_path = os.path.join(target_dir, file_name) file = open(yaml_path, mode="r") # read all lines at once whole_file = file.read() # close the file file.close() file = open(yaml_path, mode="r") # find and replace # TODO this can be simplified after https://github.com/fetchai/agents-aea/issues/932 existing = "" fingerprint_block = False for line in file: if line.find("fingerprint:") == 0: existing += line fingerprint_block = True elif fingerprint_block: if line.find(" ") == 0: # still inside fingerprint block existing += line else: # fingerprint block has ended break if len(fingerprints_dict) > 0: replacement = "fingerprint:\n" ordered_fingerprints_dict = collections.OrderedDict( sorted(fingerprints_dict.items())) for file_name, ipfs_hash in ordered_fingerprints_dict.items(): replacement += " " + file_name + ": " + ipfs_hash + "\n" else: replacement = "fingerprint: {}\n" whole_file = whole_file.replace(existing, replacement) # close the file file.close() # update fingerprints with open(yaml_path, "w") as f: f.write(whole_file) # hash again to get outer hash (this time all files): # TODO we still need to ignore some files result_list = client.add(target_dir) for result_dict in result_list: if package_name == result_dict["Name"]: key = os.path.join(AUTHOR, package_type, package_name) package_hashes[key] = result_dict["Hash"]
async def test_end_to_end_aea_aca(self): # AEA components ledger_apis = LedgerApis({}, FetchAICrypto.identifier) wallet = Wallet({FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE}) identity = Identity( name="my_aea_1", address=wallet.addresses.get(FetchAICrypto.identifier), default_address_key=FetchAICrypto.identifier, ) http_client_connection = HTTPClientConnection( address=self.aea_address, provider_address=self.aca_admin_address, provider_port=self.aca_admin_port, ) resources = Resources() # create AEA aea = AEA(identity, [http_client_connection], wallet, ledger_apis, resources) # Add http protocol to AEA resources http_protocol_configuration = ProtocolConfig.from_json( yaml.safe_load( open( os.path.join( self.cwd, "packages", "fetchai", "protocols", "http", "protocol.yaml", )))) http_protocol = Protocol(http_protocol_configuration, HttpSerializer()) resources.add_protocol(http_protocol) # Request message & envelope request_http_message = HttpMessage( dialogue_reference=("", ""), target=0, message_id=1, performative=HttpMessage.Performative.REQUEST, method="GET", url="http://{}:{}/status".format(self.aca_admin_address, self.aca_admin_port), headers="", version="", bodyy=b"", ) request_envelope = Envelope( to="ACA", sender="AEA", protocol_id=HTTP_PROTOCOL_PUBLIC_ID, message=HttpSerializer().encode(request_http_message), ) # add a simple skill with handler skill_context = SkillContext(aea.context) skill_config = SkillConfig(name="simple_skill", author="fetchai", version="0.1.0") aea_handler = AEAHandler(skill_context=skill_context, name="aea_handler") simple_skill = Skill(skill_config, skill_context, handlers={aea_handler.name: aea_handler}) resources.add_skill(simple_skill) # add error skill to AEA error_skill = Skill.from_dir(os.path.join(AEA_DIR, "skills", "error")) resources.add_skill(error_skill) # start AEA thread t_aea = Thread(target=aea.start) try: t_aea.start() time.sleep(1.0) aea.outbox.put(request_envelope) time.sleep(5.0) assert (aea_handler.handled_message.performative == HttpMessage.Performative.RESPONSE) assert aea_handler.handled_message.version == "" assert aea_handler.handled_message.status_code == 200 assert aea_handler.handled_message.status_text == "OK" assert aea_handler.handled_message.headers is not None assert aea_handler.handled_message.version is not None finally: aea.stop() t_aea.join()
def run(): # Create a private key create_private_key(FetchAICrypto.identifier, private_key_file=FETCHAI_PRIVATE_KEY_FILE_1) # Instantiate the builder and build the AEA # By default, the default protocol, error skill and stub connection are added builder = AEABuilder() builder.set_name("my_aea") builder.add_private_key(FetchAICrypto.identifier, FETCHAI_PRIVATE_KEY_FILE_1) builder.add_ledger_api_config(FetchAICrypto.identifier, {"network": "testnet"}) # Create our AEA my_aea = builder.build() # Generate some wealth for the default address try_generate_testnet_wealth(FetchAICrypto.identifier, my_aea.identity.address) # add a simple skill with handler skill_context = SkillContext(my_aea.context) skill_config = SkillConfig(name="simple_skill", author="fetchai", version="0.1.0") tx_handler = TransactionHandler(skill_context=skill_context, name="transaction_handler") simple_skill = Skill(skill_config, skill_context, handlers={tx_handler.name: tx_handler}) my_aea.resources.add_skill(simple_skill) # create a second identity create_private_key(FetchAICrypto.identifier, private_key_file=FETCHAI_PRIVATE_KEY_FILE_2) counterparty_wallet = Wallet( {FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE_2}) counterparty_identity = Identity( name="counterparty_aea", addresses=counterparty_wallet.addresses, default_address_key=FetchAICrypto.identifier, ) # create tx message for decision maker to process fetchai_ledger_api = my_aea.context.ledger_apis.apis[ FetchAICrypto.identifier] tx_nonce = fetchai_ledger_api.generate_tx_nonce( my_aea.identity.address, counterparty_identity.address) tx_msg = TransactionMessage( performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT, skill_callback_ids=[skill_config.public_id], tx_id="transaction0", tx_sender_addr=my_aea.identity.address, tx_counterparty_addr=counterparty_identity.address, tx_amount_by_currency_id={"FET": -1}, tx_sender_fee=1, tx_counterparty_fee=0, tx_quantities_by_good_id={}, ledger_id=FetchAICrypto.identifier, info={"some_info_key": "some_info_value"}, tx_nonce=tx_nonce, ) my_aea.context.decision_maker_message_queue.put_nowait(tx_msg) # Set the AEA running in a different thread try: logger.info("STARTING AEA NOW!") t = Thread(target=my_aea.start) t.start() # Let it run long enough to interact with the weather station time.sleep(20) finally: # Shut down the AEA logger.info("STOPPING AEA NOW!") my_aea.stop() t.join()
async def test_end_to_end_aea_aca(self): """Test the end to end aea aca interaction.""" # AEA components wallet = Wallet({DEFAULT_LEDGER: DEFAULT_PRIVATE_KEY_FILE}) identity = Identity( name="my_aea_1", address=wallet.addresses.get(DEFAULT_LEDGER), default_address_key=DEFAULT_LEDGER, ) configuration = ConnectionConfig( host=self.aca_admin_address, port=self.aca_admin_port, connection_id=HTTPClientConnection.connection_id, ) http_client_connection = HTTPClientConnection( configuration=configuration, identity=identity, ) resources = Resources() resources.add_connection(http_client_connection) # create AEA aea = AEA(identity, wallet, resources) # Add http protocol to AEA resources http_protocol_configuration = ProtocolConfig.from_json( yaml.safe_load( open( os.path.join( self.cwd, "packages", "fetchai", "protocols", "http", "protocol.yaml", )))) http_protocol = Protocol(http_protocol_configuration, HttpMessage.serializer()) resources.add_protocol(http_protocol) # Request message & envelope request_http_message = HttpMessage( dialogue_reference=("", ""), target=0, message_id=1, performative=HttpMessage.Performative.REQUEST, method="GET", url="http://{}:{}/status".format(self.aca_admin_address, self.aca_admin_port), headers="", version="", body=b"", ) request_http_message.to = "ACA" request_envelope = Envelope( to="ACA", sender="AEA", protocol_id=HttpMessage.protocol_id, message=request_http_message, ) # add a simple skill with handler skill_context = SkillContext(aea.context) skill_config = SkillConfig(name="simple_skill", author="fetchai", version="0.1.0") aea_handler = AEAHandler(skill_context=skill_context, name="aea_handler") simple_skill = Skill(skill_config, skill_context, handlers={aea_handler.name: aea_handler}) resources.add_skill(simple_skill) # add error skill to AEA error_skill = Skill.from_dir(os.path.join(AEA_DIR, "skills", "error"), agent_context=aea.context) resources.add_skill(error_skill) # start AEA thread t_aea = Thread(target=aea.start) try: t_aea.start() time.sleep(1.0) aea.outbox.put(request_envelope) time.sleep(5.0) assert (aea_handler.handled_message.performative == HttpMessage.Performative.RESPONSE) assert aea_handler.handled_message.version == "" assert aea_handler.handled_message.status_code == 200 assert aea_handler.handled_message.status_text == "OK" assert aea_handler.handled_message.headers is not None assert aea_handler.handled_message.version is not None finally: aea.stop() t_aea.join()
def _make_skill(id_): return AEATestWrapper.make_skill( config=SkillConfig(name=f"sc{id_}", author="fetchai"), handlers={"dummy_handler": DummyHandler}, )
def test_gym(self, pytestconfig): """Run the gym skill sequence.""" if pytestconfig.getoption("ci"): pytest.skip("Skipping the test since it doesn't work in CI.") # add packages folder packages_src = os.path.join(self.cwd, "packages") packages_dst = os.path.join(self.t, "packages") shutil.copytree(packages_src, packages_dst) result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "init", "--author", AUTHOR], standalone_mode=False) assert result.exit_code == 0 # create agent result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "create", self.agent_name], standalone_mode=False) assert result.exit_code == 0 agent_dir_path = os.path.join(self.t, self.agent_name) os.chdir(agent_dir_path) # add packages and install dependencies result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "add", "skill", "fetchai/gym:0.1.0"], standalone_mode=False, ) assert result.exit_code == 0 result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "add", "connection", "fetchai/gym:0.1.0"], standalone_mode=False, ) assert result.exit_code == 0 result = self.runner.invoke(cli, [*CLI_LOG_OPTION, "install"], standalone_mode=False) assert result.exit_code == 0 # add gyms folder from examples gyms_src = os.path.join(self.cwd, "examples", "gym_ex", "gyms") gyms_dst = os.path.join(self.t, self.agent_name, "gyms") shutil.copytree(gyms_src, gyms_dst) # change config file of gym connection file_src = os.path.join(ROOT_DIR, "tests", "data", "gym-connection.yaml") file_dst = os.path.join( self.t, self.agent_name, "vendor", "fetchai", "connections", "gym", "connection.yaml", ) shutil.copyfile(file_src, file_dst) # change number of training steps skill_config_path = Path(self.t, self.agent_name, "vendor", "fetchai", "skills", "gym", "skill.yaml") skill_config = SkillConfig.from_json( yaml.safe_load(open(skill_config_path))) skill_config.handlers.read("gym").args["nb_steps"] = 20 yaml.safe_dump(skill_config.json, open(skill_config_path, "w")) try: process = subprocess.Popen( # nosec [ sys.executable, "-m", "aea.cli", "run", "--connections", "fetchai/gym:0.1.0", ], stdout=subprocess.PIPE, env=os.environ.copy(), ) time.sleep(10.0) # TODO: check the run ends properly finally: process.send_signal(signal.SIGINT) process.wait(timeout=5) if not process.returncode == 0: poll = process.poll() if poll is None: process.terminate() process.wait(2) os.chdir(self.t) result = self.runner.invoke( cli, [*CLI_LOG_OPTION, "delete", self.agent_name], standalone_mode=False) assert result.exit_code == 0
def test_generated_protocol_end_to_end(self): """Test that a generated protocol could be used in exchanging messages between two agents.""" agent_name_1 = "my_aea_1" agent_name_2 = "my_aea_2" builder_1 = AEABuilder() builder_1.set_name(agent_name_1) builder_1.add_private_key(DEFAULT_LEDGER, self.private_key_path_1) builder_1.set_default_ledger(DEFAULT_LEDGER) builder_1.set_default_connection(PublicId.from_str("fetchai/oef:0.7.0")) builder_1.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa") ) builder_1.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search") ) builder_1.add_component( ComponentType.PROTOCOL, Path(PATH_TO_T_PROTOCOL), skip_consistency_check=True, ) builder_1.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "oef") ) builder_2 = AEABuilder() builder_2.set_name(agent_name_2) builder_2.add_private_key(DEFAULT_LEDGER, self.private_key_path_2) builder_2.set_default_ledger(DEFAULT_LEDGER) builder_2.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa") ) builder_2.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search") ) builder_2.set_default_connection(PublicId.from_str("fetchai/oef:0.7.0")) builder_2.add_component( ComponentType.PROTOCOL, Path(PATH_TO_T_PROTOCOL), skip_consistency_check=True, ) builder_2.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "oef") ) # create AEAs aea_1 = builder_1.build(connection_ids=[PublicId.from_str("fetchai/oef:0.7.0")]) aea_2 = builder_2.build(connection_ids=[PublicId.from_str("fetchai/oef:0.7.0")]) # dialogues dialogue_label_1 = DialogueLabel( (str(1), ""), aea_2.identity.address, aea_1.identity.address ) aea_1_dialogue = TProtocolDialogue( dialogue_label_1, aea_1.identity.address, TProtocolDialogue.Role.ROLE_1 ) dialogue_label_2 = DialogueLabel( (str(1), str(1)), aea_1.identity.address, aea_1.identity.address ) aea_2_dialogue = TProtocolDialogue( dialogue_label_2, aea_2.identity.address, TProtocolDialogue.Role.ROLE_2 ) # message 1 message_1 = TProtocolMessage( message_id=1, dialogue_reference=(str(1), ""), target=0, performative=TProtocolMessage.Performative.PERFORMATIVE_PT, content_bytes=b"some bytes", content_int=42, content_float=42.7, content_bool=True, content_str="some string", ) message_1.counterparty = aea_2.identity.address message_1.is_incoming = False # message 2 message_2 = TProtocolMessage( message_id=2, dialogue_reference=(str(1), str(1)), target=1, performative=TProtocolMessage.Performative.PERFORMATIVE_PT, content_bytes=b"some other bytes", content_int=43, content_float=43.7, content_bool=False, content_str="some other string", ) message_2.counterparty = aea_1.identity.address message_2.is_incoming = False # add handlers to AEA resources skill_context_1 = SkillContext(aea_1.context) skill_1 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_1) skill_context_1._skill = skill_1 agent_1_handler = Agent1Handler( skill_context=skill_context_1, name="fake_handler_1", dialogue=aea_1_dialogue, ) aea_1.resources._handler_registry.register( ( PublicId.from_str("fetchai/fake_skill:0.1.0"), TProtocolMessage.protocol_id, ), agent_1_handler, ) skill_context_2 = SkillContext(aea_2.context) skill_2 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_2) skill_context_2._skill = skill_2 agent_2_handler = Agent2Handler( message=message_2, dialogue=aea_2_dialogue, skill_context=skill_context_2, name="fake_handler_2", ) aea_2.resources._handler_registry.register( ( PublicId.from_str("fetchai/fake_skill:0.1.0"), TProtocolMessage.protocol_id, ), agent_2_handler, ) # Start threads t_1 = Thread(target=aea_1.start) t_2 = Thread(target=aea_2.start) try: t_1.start() t_2.start() time.sleep(1.0) aea_1_dialogue.update(message_1) aea_1.outbox.put_message(message_1) time.sleep(5.0) assert ( agent_2_handler.handled_message.message_id == message_1.message_id ), "Message from Agent 1 to 2: message ids do not match" assert ( agent_2_handler.handled_message.dialogue_reference == message_1.dialogue_reference ), "Message from Agent 1 to 2: dialogue references do not match" assert ( agent_2_handler.handled_message.dialogue_reference[0] == message_1.dialogue_reference[0] ), "Message from Agent 1 to 2: dialogue reference[0]s do not match" assert ( agent_2_handler.handled_message.dialogue_reference[1] == message_1.dialogue_reference[1] ), "Message from Agent 1 to 2: dialogue reference[1]s do not match" assert ( agent_2_handler.handled_message.target == message_1.target ), "Message from Agent 1 to 2: targets do not match" assert ( agent_2_handler.handled_message.performative == message_1.performative ), "Message from Agent 1 to 2: performatives do not match" assert ( agent_2_handler.handled_message.content_bytes == message_1.content_bytes ), "Message from Agent 1 to 2: content_bytes do not match" assert ( agent_2_handler.handled_message.content_int == message_1.content_int ), "Message from Agent 1 to 2: content_int do not match" # assert ( # agent_2_handler.handled_message.content_float == message_1.content_float # ), "Message from Agent 1 to 2: content_float do not match" assert ( agent_2_handler.handled_message.content_bool == message_1.content_bool ), "Message from Agent 1 to 2: content_bool do not match" assert ( agent_2_handler.handled_message.content_str == message_1.content_str ), "Message from Agent 1 to 2: content_str do not match" assert ( agent_1_handler.handled_message.message_id == message_2.message_id ), "Message from Agent 1 to 2: dialogue references do not match" assert ( agent_1_handler.handled_message.dialogue_reference == message_2.dialogue_reference ), "Message from Agent 2 to 1: dialogue references do not match" assert ( agent_1_handler.handled_message.dialogue_reference[0] == message_2.dialogue_reference[0] ), "Message from Agent 2 to 1: dialogue reference[0]s do not match" assert ( agent_1_handler.handled_message.dialogue_reference[1] == message_2.dialogue_reference[1] ), "Message from Agent 2 to 1: dialogue reference[1]s do not match" assert ( agent_1_handler.handled_message.target == message_2.target ), "Message from Agent 2 to 1: targets do not match" assert ( agent_1_handler.handled_message.performative == message_2.performative ), "Message from Agent 2 to 1: performatives do not match" assert ( agent_1_handler.handled_message.content_bytes == message_2.content_bytes ), "Message from Agent 2 to 1: content_bytes do not match" assert ( agent_1_handler.handled_message.content_int == message_2.content_int ), "Message from Agent 2 to 1: content_int do not match" # assert ( # agent_1_handler.handled_message.content_float == message_2.content_float # ), "Message from Agent 2 to 1: content_float do not match" assert ( agent_1_handler.handled_message.content_bool == message_2.content_bool ), "Message from Agent 2 to 1: content_bool do not match" assert ( agent_1_handler.handled_message.content_str == message_2.content_str ), "Message from Agent 2 to 1: content_str do not match" time.sleep(2.0) finally: aea_1.stop() aea_2.stop() t_1.join() t_2.join()