@@ -277,10 +277,10 @@ The following steps create **Faber_AEA** from scratch:
aea create aries_faber
cd aries_faber
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
-aea add connection fetchai/http_client:0.8.0
-aea add connection fetchai/webhook:0.6.0
-aea add skill fetchai/aries_faber:0.6.0
+aea add connection fetchai/soef:0.9.0
+aea add connection fetchai/http_client:0.9.0
+aea add connection fetchai/webhook:0.7.0
+aea add skill fetchai/aries_faber:0.7.0
```
diff --git a/docs/build-aea-programmatically.md b/docs/build-aea-programmatically.md
index 84d4b854a0..407925e113 100644
--- a/docs/build-aea-programmatically.md
+++ b/docs/build-aea-programmatically.md
@@ -48,7 +48,7 @@ We will use the stub connection to pass envelopes in and out of the AEA. Ensure
```
## Initialise the AEA
-We use the `AEABuilder` to readily build an AEA. By default, the `AEABuilder` adds the `fetchai/default:0.5.0` protocol, the `fetchai/stub:0.9.0` connection and the `fetchai/error:0.5.0` skill.
+We use the `AEABuilder` to readily build an AEA. By default, the `AEABuilder` adds the `fetchai/default:0.6.0` protocol, the `fetchai/stub:0.9.0` connection and the `fetchai/error:0.6.0` skill.
``` python
# Instantiate the builder and build the AEA
# By default, the default protocol, error skill and stub connection are added
@@ -121,7 +121,7 @@ We run the AEA from a different thread so that we can still use the main thread
We use the input and output text files to send an envelope to our AEA and receive a response (from the echo skill)
``` python
# Create a message inside an envelope and get the stub connection to pass it on to the echo skill
- message_text = b"my_aea,other_agent,fetchai/default:0.5.0,\x08\x01\x12\x011*\x07\n\x05hello,"
+ message_text = b"my_aea,other_agent,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello,"
with open(INPUT_FILE, "wb") as f:
write_with_lock(f, message_text)
print(b"input message: " + message_text)
@@ -147,8 +147,8 @@ Finally stop our AEA and wait for it to finish
## Running the AEA
If you now run this python script file, you should see this output:
- input message: my_aea,other_agent,fetchai/default:0.5.0,\x08\x01*\x07\n\x05hello
- output message: other_agent,my_aea,fetchai/default:0.5.0,...\x05hello
+ input message: my_aea,other_agent,fetchai/default:0.6.0,\x08\x01*\x07\n\x05hello
+ output message: other_agent,my_aea,fetchai/default:0.6.0,...\x05hello
## Entire code listing
@@ -239,7 +239,7 @@ def run():
time.sleep(4)
# Create a message inside an envelope and get the stub connection to pass it on to the echo skill
- message_text = b"my_aea,other_agent,fetchai/default:0.5.0,\x08\x01\x12\x011*\x07\n\x05hello,"
+ message_text = b"my_aea,other_agent,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello,"
with open(INPUT_FILE, "wb") as f:
write_with_lock(f, message_text)
print(b"input message: " + message_text)
diff --git a/docs/car-park-skills.md b/docs/car-park-skills.md
index 922097bfc9..b7fed86aa3 100644
--- a/docs/car-park-skills.md
+++ b/docs/car-park-skills.md
@@ -68,7 +68,7 @@ The following steps create the car detector from scratch:
aea create car_detector
cd car_detector
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/carpark_detection:0.12.0
aea install
@@ -78,8 +78,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `car_detector/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
@@ -102,7 +102,7 @@ The following steps create the car data client from scratch:
aea create car_data_buyer
cd car_data_buyer
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/carpark_client:0.12.0
aea install
@@ -112,8 +112,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `car_data_buyer/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
diff --git a/docs/cli-vs-programmatic-aeas.md b/docs/cli-vs-programmatic-aeas.md
index 6fae1bc689..b4a3513300 100644
--- a/docs/cli-vs-programmatic-aeas.md
+++ b/docs/cli-vs-programmatic-aeas.md
@@ -124,8 +124,8 @@ def run():
# specify the default routing for some protocols
default_routing = {
- PublicId.from_str("fetchai/ledger_api:0.3.0"): LedgerConnection.connection_id,
- PublicId.from_str("fetchai/oef_search:0.6.0"): SOEFConnection.connection_id,
+ PublicId.from_str("fetchai/ledger_api:0.4.0"): LedgerConnection.connection_id,
+ PublicId.from_str("fetchai/oef_search:0.7.0"): SOEFConnection.connection_id,
}
default_connection = P2PLibp2pConnection.connection_id
@@ -192,7 +192,7 @@ def run():
api_key=API_KEY,
soef_addr=SOEF_ADDR,
soef_port=SOEF_PORT,
- restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.6.0")},
+ restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.7.0")},
connection_id=SOEFConnection.connection_id,
)
soef_connection = SOEFConnection(configuration=configuration, identity=identity)
diff --git a/docs/config.md b/docs/config.md
index e95ddab7d8..9cc4e49ae8 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -24,9 +24,9 @@ connections: # The list of connection public
- fetchai/stub:0.9.0
contracts: [] # The list of contract public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
protocols: # The list of protocol public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills: # The list of skill public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
default_connection: fetchai/p2p_libp2p:0.10.0 # The default connection used for envelopes sent by the AEA (must satisfy PUBLIC_ID_REGEX).
default_ledger: fetchai # The default ledger identifier the AEA project uses (must satisfy LEDGER_ID_REGEX)
logging_config: # The logging configurations the AEA project uses
diff --git a/docs/connect-a-frontend.md b/docs/connect-a-frontend.md
index 93d5b1a49b..6c1559b9bc 100644
--- a/docs/connect-a-frontend.md
+++ b/docs/connect-a-frontend.md
@@ -3,7 +3,7 @@ This demo discusses the options we have to connect a front-end to the AEA. The f
## Case 1
-The first option we have is to create a `Connection` that will handle the incoming requests from the rest API. In this scenario, the rest API communicates with the AEA and requests are handled by the `HTTP Server` Connection package. The rest API should send CRUD requests to the `HTTP Server` Connection (`fetchai/http_server:0.8.0`) which translates these into Envelopes to be consumed by the correct skill.
+The first option we have is to create a `Connection` that will handle the incoming requests from the rest API. In this scenario, the rest API communicates with the AEA and requests are handled by the `HTTP Server` Connection package. The rest API should send CRUD requests to the `HTTP Server` Connection (`fetchai/http_server:0.9.0`) which translates these into Envelopes to be consumed by the correct skill.
## Case 2
The other option we have is to create a stand-alone `Multiplexer` with a `P2P` connection (`fetchai/p2p_libp2p:0.10.0`). In this scenario, the front-end needs to incorporate a Multiplexer with an `P2P` Connection. Then the Agent Communication Network can be used to send Envelopes from the AEA to the front-end.
\ No newline at end of file
diff --git a/docs/contract.md b/docs/contract.md
index 48ef8864e9..fdb0297a25 100644
--- a/docs/contract.md
+++ b/docs/contract.md
@@ -32,7 +32,7 @@ contract_api_msg = ContractApiMessage(
),
)
```
-This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `raw_transaction` message will be returned with the matching raw transaction. To send this transaction to the ledger for processing, we first sign the message with the decision maker and then send the signed transaction to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.3.0` protocol.
+This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `raw_transaction` message will be returned with the matching raw transaction. To send this transaction to the ledger for processing, we first sign the message with the decision maker and then send the signed transaction to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.4.0` protocol.
- the `get_raw_transaction` message is used to request any transaction for a specific contract which changes state in the contract. For instance, to request a transaction for the creation of token in the deployed `erc1155` smart contract wrapped in the `fetchai/erc1155:0.10.0` package, we send the following message to the `fetchai/ledger:0.6.0`:
@@ -52,7 +52,7 @@ contract_api_msg = ContractApiMessage(
),
)
```
-This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `raw_transaction` message will be returned with the matching raw transaction. For this to be executed correctly, the `fetchai/erc1155:0.10.0` contract package needs to implement the `get_create_batch_transaction` method with the specified key word arguments. Similarly to above, to send this transaction to the ledger for processing, we first sign the message with the decision maker and then send the signed transaction to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.3.0` protocol.
+This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `raw_transaction` message will be returned with the matching raw transaction. For this to be executed correctly, the `fetchai/erc1155:0.10.0` contract package needs to implement the `get_create_batch_transaction` method with the specified key word arguments. Similarly to above, to send this transaction to the ledger for processing, we first sign the message with the decision maker and then send the signed transaction to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.4.0` protocol.
- the `get_raw_message` message is used to request any contract method call for a specific contract which does not change state in the contract. For instance, to request a call to get a hash from some input data in the deployed `erc1155` smart contract wrapped in the `fetchai/erc1155:0.10.0` package, we send the following message to the `fetchai/ledger:0.6.0`:
@@ -77,7 +77,7 @@ contract_api_msg = ContractApiMessage(
),
)
```
-This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `raw_message` message will be returned with the matching raw message. For this to be executed correctly, the `fetchai/erc1155:0.10.0` contract package needs to implement the `get_hash_single` method with the specified key word arguments. We can then send the raw message to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.3.0` protocol. In this case, signing is not required.
+This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `raw_message` message will be returned with the matching raw message. For this to be executed correctly, the `fetchai/erc1155:0.10.0` contract package needs to implement the `get_hash_single` method with the specified key word arguments. We can then send the raw message to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.4.0` protocol. In this case, signing is not required.
- the `get_state` message is used to request any contract method call to query state in the deployed contract. For instance, to request a call to get the balances in the deployed `erc1155` smart contract wrapped in the `fetchai/erc1155:0.10.0` package, we send the following message to the `fetchai/ledger:0.6.0`:
@@ -95,7 +95,7 @@ contract_api_msg = ContractApiMessage(
),
)
```
-This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `state` message will be returned with the matching state. For this to be executed correctly, the `fetchai/erc1155:0.10.0` contract package needs to implement the `get_balance` method with the specified key word arguments. We can then send the raw message to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.3.0` protocol. In this case, signing is not required.
+This message will be handled by the `fetchai/ledger:0.6.0` connection and then a `state` message will be returned with the matching state. For this to be executed correctly, the `fetchai/erc1155:0.10.0` contract package needs to implement the `get_balance` method with the specified key word arguments. We can then send the raw message to the `fetchai/ledger:0.6.0` connection using the `fetchai/ledger_api:0.4.0` protocol. In this case, signing is not required.
## Developing your own
diff --git a/docs/core-components-1.md b/docs/core-components-1.md
index b0aa84b8df..d7500f3322 100644
--- a/docs/core-components-1.md
+++ b/docs/core-components-1.md
@@ -32,7 +32,7 @@ An `Envelope` is the core object
* `Dialogues`, which define rules over `Message` sequences.
-The framework provides one default `Protocol`, called `default` (current version `fetchai/default:0.5.0`). This `Protocol` provides a bare-bones implementation for an AEA `Protocol` which includes a `DefaultMessage` class and associated `DefaultSerializer` and `DefaultDialogue` classes.
+The framework provides one default `Protocol`, called `default` (current version `fetchai/default:0.6.0`). This `Protocol` provides a bare-bones implementation for an AEA `Protocol` which includes a `DefaultMessage` class and associated `DefaultSerializer` and `DefaultDialogue` classes.
Additional `Protocols` - i.e. a new type of interaction - can be added as packages and generated with the protocol generator. For more details on `Protocols` also read the `Protocol` guide here.
diff --git a/docs/deployment.md b/docs/deployment.md
index 92f8c93ab3..e8fea42914 100644
--- a/docs/deployment.md
+++ b/docs/deployment.md
@@ -28,7 +28,7 @@ Finally, we run it:
docker run -it aea-deploy:latest
```
-This will run the `fetchai/my_first_aea:0.11.0` demo project. You can edit `entrypoint.sh` to run whatever project you would like.
+This will run the `fetchai/my_first_aea:0.12.0` demo project. You can edit `entrypoint.sh` to run whatever project you would like.
##Â Deployment
diff --git a/docs/erc1155-skills.md b/docs/erc1155-skills.md
index 6b197156c4..1c2cd8fd5a 100644
--- a/docs/erc1155-skills.md
+++ b/docs/erc1155-skills.md
@@ -40,7 +40,7 @@ Create the AEA that will deploy the contract.
aea create erc1155_deployer
cd erc1155_deployer
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/erc1155_deploy:0.14.0
aea install
@@ -51,8 +51,8 @@ Then update the agent config (`aea-config.yaml`) with the default routing:
``` yaml
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
And change the default ledger:
@@ -95,7 +95,7 @@ Create the AEA that will get some tokens from the deployer.
aea create erc1155_client
cd erc1155_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/erc1155_client:0.13.0
aea install
@@ -106,8 +106,8 @@ Then update the agent config (`aea-config.yaml`) with the default routing:
``` yaml
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
And change the default ledger:
diff --git a/docs/generic-skills-step-by-step.md b/docs/generic-skills-step-by-step.md
index c71c402ba4..2e9c7318ab 100644
--- a/docs/generic-skills-step-by-step.md
+++ b/docs/generic-skills-step-by-step.md
@@ -1314,10 +1314,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
service_registration:
@@ -2776,11 +2776,11 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
skills: []
behaviours:
search:
@@ -2881,8 +2881,8 @@ aea add-key fetchai fetchai_private_key.txt --connection
Both in `my_generic_seller/aea-config.yaml` and `my_generic_buyer/aea-config.yaml`, and
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
### Fund the buyer AEA
@@ -2899,9 +2899,9 @@ Add the remaining packages for the seller AEA, then run it:
``` bash
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
-aea add protocol fetchai/fipa:0.6.0
+aea add protocol fetchai/fipa:0.7.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
aea run
@@ -2915,10 +2915,10 @@ Add the remaining packages for the buyer AEA:
``` bash
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
-aea add protocol fetchai/fipa:0.6.0
-aea add protocol fetchai/signing:0.3.0
+aea add protocol fetchai/fipa:0.7.0
+aea add protocol fetchai/signing:0.4.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
```
diff --git a/docs/generic-skills.md b/docs/generic-skills.md
index b76ce18333..6774d0f47b 100644
--- a/docs/generic-skills.md
+++ b/docs/generic-skills.md
@@ -72,7 +72,7 @@ The following steps create the seller from scratch:
aea create my_seller_aea
cd my_seller_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/generic_seller:0.13.0
aea install
@@ -82,8 +82,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `my_seller_aea/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
@@ -106,7 +106,7 @@ The following steps create the buyer from scratch:
aea create my_buyer_aea
cd my_buyer_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/generic_buyer:0.12.0
aea install
@@ -116,8 +116,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `my_buyer_aea/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
diff --git a/docs/http-connection-and-skill.md b/docs/http-connection-and-skill.md
index 2455fee6d7..dcf01bac81 100644
--- a/docs/http-connection-and-skill.md
+++ b/docs/http-connection-and-skill.md
@@ -14,13 +14,13 @@ cd my_aea
Add the http server connection package
``` bash
-aea add connection fetchai/http_server:0.8.0
+aea add connection fetchai/http_server:0.9.0
```
Update the default connection:
``` bash
-aea config set agent.default_connection fetchai/http_server:0.8.0
+aea config set agent.default_connection fetchai/http_server:0.9.0
```
Modify the `api_spec_path`:
@@ -166,7 +166,7 @@ handlers:
Finally, we run the fingerprinter:
``` bash
-aea fingerprint skill fetchai/http_echo:0.6.0
+aea fingerprint skill fetchai/http_echo:0.7.0
```
Note, you will have to replace the author name with your author handle.
diff --git a/docs/language-agnostic-definition.md b/docs/language-agnostic-definition.md
index 3b0d059ef9..7d93b5429d 100644
--- a/docs/language-agnostic-definition.md
+++ b/docs/language-agnostic-definition.md
@@ -50,7 +50,7 @@ The format for the above fields, except `message`, is specified below. For those
This section is incomplete, and will be updated soon!
-
It SHOULD implement the `fetchai/default:0.5.0` protocol which satisfies the following protobuf schema:
+
It SHOULD implement the `fetchai/default:0.6.0` protocol which satisfies the following protobuf schema:
``` proto
syntax = "proto3";
@@ -100,7 +100,7 @@ message DefaultMessage{
It MUST have an identity in the form of, at a minimum, an address derived from a public key and its associated private key (where the eliptic curve must be of type SECP256k1).
-
It SHOULD implement handling of errors using the `fetchai/default:0.5.0` protocol. The protobuf schema is given above.
+
It SHOULD implement handling of errors using the `fetchai/default:0.6.0` protocol. The protobuf schema is given above.
It MUST implement the following principles when handling messages:
diff --git a/docs/logging.md b/docs/logging.md
index a183b4378c..8f0e4c0230 100644
--- a/docs/logging.md
+++ b/docs/logging.md
@@ -25,9 +25,9 @@ connections:
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
default_connection: fetchai/stub:0.9.0
default_ledger: fetchai
logging_config:
diff --git a/docs/ml-skills.md b/docs/ml-skills.md
index 6f34264db6..cf399e6cda 100644
--- a/docs/ml-skills.md
+++ b/docs/ml-skills.md
@@ -75,7 +75,7 @@ The following steps create the data provider from scratch:
aea create ml_data_provider
cd ml_data_provider
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/ml_data_provider:0.12.0
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
@@ -85,8 +85,8 @@ aea install
In `ml_data_provider/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
@@ -109,7 +109,7 @@ The following steps create the model trainer from scratch:
aea create ml_model_trainer
cd ml_model_trainer
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/ml_train:0.12.0
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
@@ -119,8 +119,8 @@ aea install
In `ml_model_trainer/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
diff --git a/docs/multiplexer-standalone.md b/docs/multiplexer-standalone.md
index b3e21b32ac..e8b3ed436e 100644
--- a/docs/multiplexer-standalone.md
+++ b/docs/multiplexer-standalone.md
@@ -61,7 +61,7 @@ We use the input and output text files to send an envelope to our agent and rece
``` python
# Create a message inside an envelope and get the stub connection to pass it into the multiplexer
message_text = (
- "multiplexer,some_agent,fetchai/default:0.5.0,\x08\x01*\x07\n\x05hello,"
+ "multiplexer,some_agent,fetchai/default:0.6.0,\x08\x01*\x07\n\x05hello,"
)
with open(INPUT_FILE, "w") as f:
write_with_lock(f, message_text)
@@ -159,7 +159,7 @@ def run():
# Create a message inside an envelope and get the stub connection to pass it into the multiplexer
message_text = (
- "multiplexer,some_agent,fetchai/default:0.5.0,\x08\x01*\x07\n\x05hello,"
+ "multiplexer,some_agent,fetchai/default:0.6.0,\x08\x01*\x07\n\x05hello,"
)
with open(INPUT_FILE, "w") as f:
write_with_lock(f, message_text)
diff --git a/docs/oef-ledger.md b/docs/oef-ledger.md
index a9d27aac1d..7b73b5202d 100644
--- a/docs/oef-ledger.md
+++ b/docs/oef-ledger.md
@@ -53,7 +53,7 @@ When it is live you will see the sentence 'A thing of beauty is a joy forever...
To view the `OEF search and communication node` logs for debugging, navigate to `data/oef-logs`.
-To connect to an `OEF search and communication node` an AEA uses the `OEFConnection` connection package (`fetchai/oef:0.9.0`).
+To connect to an `OEF search and communication node` an AEA uses the `OEFConnection` connection package (`fetchai/oef:0.10.0`).
If you experience any problems launching the `OEF search and communication node` then consult this guide.
diff --git a/docs/orm-integration.md b/docs/orm-integration.md
index d170c326c4..4a879de4ce 100644
--- a/docs/orm-integration.md
+++ b/docs/orm-integration.md
@@ -72,7 +72,7 @@ The following steps create the seller from scratch:
aea create my_thermometer_aea
cd my_thermometer_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer:0.12.0
aea install
@@ -82,8 +82,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `my_thermometer_aea/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
@@ -107,7 +107,7 @@ The following steps create the car data client from scratch:
aea create my_thermometer_client
cd my_thermometer_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer_client:0.11.0
aea install
@@ -117,8 +117,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `my_buyer_aea/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
diff --git a/docs/protocol.md b/docs/protocol.md
index 67c23aeba0..8108395dd0 100644
--- a/docs/protocol.md
+++ b/docs/protocol.md
@@ -66,9 +66,9 @@ The developer can generate custom protocols with the SOEF search node to register and unregister their own services and search for services registered by other agents.
+The `fetchai/oef_search:0.7.0` protocol is used by AEAs to interact with an SOEF search node to register and unregister their own services and search for services registered by other agents.
-The `fetchai/oef_search:0.6.0` protocol definition includes an `OefSearchMessage` with the following message types:
+The `fetchai/oef_search:0.7.0` protocol definition includes an `OefSearchMessage` with the following message types:
``` python
class Performative(Enum):
@@ -231,7 +231,7 @@ oef_msg = OefSearchMessage(
)
```
-* The SOEF search node will respond with a message, say `msg` of type `OefSearchMessage`, of performative `OefSearchMessage.Performative.SEARCH_RESULT`. To access the tuple of agents which match the query, simply use `msg.agents`. In particular, this will return the agent addresses matching the query. The agent address can then be used to send a message to the agent utilising the P2P agent communication network and any protocol other than `fetchai/oef_search:0.6.0`.
+* The SOEF search node will respond with a message, say `msg` of type `OefSearchMessage`, of performative `OefSearchMessage.Performative.SEARCH_RESULT`. To access the tuple of agents which match the query, simply use `msg.agents`. In particular, this will return the agent addresses matching the query. The agent address can then be used to send a message to the agent utilising the P2P agent communication network and any protocol other than `fetchai/oef_search:0.7.0`.
* If the SOEF search node encounters any errors with the messages you send, it will return an `OefSearchMessage` of performative `OefSearchMessage.Performative.OEF_ERROR` and indicate the error operation encountered:
``` python
@@ -246,11 +246,11 @@ class OefErrorOperation(Enum):
OTHER = 10000
```
-## `fetchai/fipa:0.6.0` protocol
+## `fetchai/fipa:0.7.0` protocol
This protocol provides classes and functions necessary for communication between AEAs via a variant of the FIPA Agent Communication Language.
-The `fetchai/fipa:0.6.0` protocol definition includes a `FipaMessage` with the following performatives:
+The `fetchai/fipa:0.7.0` protocol definition includes a `FipaMessage` with the following performatives:
``` python
class Performative(Enum):
@@ -283,9 +283,9 @@ def __init__(
)
```
-The `fetchai/fipa:0.6.0` protocol also defines a `FipaDialogue` class which specifies the valid reply structure and provides other helper methods to maintain dialogues.
+The `fetchai/fipa:0.7.0` protocol also defines a `FipaDialogue` class which specifies the valid reply structure and provides other helper methods to maintain dialogues.
-For examples of the usage of the `fetchai/fipa:0.6.0` protocol check out the generic skills step by step guide.
+For examples of the usage of the `fetchai/fipa:0.7.0` protocol check out the generic skills step by step guide.
### Fipa dialogue
diff --git a/docs/questions-and-answers.md b/docs/questions-and-answers.md
index bb76fa60d7..9b0a634e69 100644
--- a/docs/questions-and-answers.md
+++ b/docs/questions-and-answers.md
@@ -72,7 +72,7 @@ You can find more details about the CLI commands here
When a new AEA is created, is the `vendor` folder populated with some default packages?
-All AEA projects by default hold the `fetchai/stub:0.9.0` connection, the `fetchai/default:0.5.0` protocol and the `fetchai/error:0.5.0` skill. These (as all other packages installed from the registry) are placed in the vendor's folder.
+All AEA projects by default hold the `fetchai/stub:0.9.0` connection, the `fetchai/default:0.6.0` protocol and the `fetchai/error:0.6.0` skill. These (as all other packages installed from the registry) are placed in the vendor's folder.
You can find more details about the file structure here
diff --git a/docs/quickstart.md b/docs/quickstart.md
index f6a03ebd07..beae01bce4 100644
--- a/docs/quickstart.md
+++ b/docs/quickstart.md
@@ -101,7 +101,7 @@ AEA configurations successfully initialized: {'author': 'fetchai'}
The echo skill is a simple demo that introduces you to the main business logic components of an AEA. The fastest way to create your first AEA is to fetch it!
``` bash
-aea fetch fetchai/my_first_aea:0.11.0
+aea fetch fetchai/my_first_aea:0.12.0
cd my_first_aea
```
@@ -121,9 +121,9 @@ cd my_first_aea
Second, add the echo skill to the project.
``` bash
-aea add skill fetchai/echo:0.7.0
+aea add skill fetchai/echo:0.8.0
```
-This copies the `fetchai/echo:0.7.0` skill code containing the "behaviours", and "handlers" into the project, ready to run. The identifier of the skill `fetchai/echo:0.7.0` consists of the name of the author of the skill, followed by the skill name and its version.
+This copies the `fetchai/echo:0.8.0` skill code containing the "behaviours", and "handlers" into the project, ready to run. The identifier of the skill `fetchai/echo:0.8.0` consists of the name of the author of the skill, followed by the skill name and its version.
## Communication via envelopes and messages
@@ -149,7 +149,7 @@ TO,SENDER,PROTOCOL_ID,ENCODED_MESSAGE,
For example:
``` bash
-recipient_aea,sender_aea,fetchai/default:0.5.0,\x08\x01\x12\x011*\x07\n\x05hello,
+recipient_aea,sender_aea,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello,
```
## Run the AEA
@@ -212,7 +212,7 @@ info: Echo Behaviour: act method called.
Optionally, from a different terminal and same directory (i.e. the `my_first_aea` project), we send the AEA a message wrapped in an envelope via the input file.
``` bash
-echo 'my_first_aea,sender_aea,fetchai/default:0.5.0,\x08\x01\x12\x011*\x07\n\x05hello,' >> input_file
+echo 'my_first_aea,sender_aea,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello,' >> input_file
```
You will see the `Echo Handler` dealing with the envelope and responding with the same message to the `output_file`, and also decoding the Base64 encrypted message in this case.
diff --git a/docs/simple-oef-usage.md b/docs/simple-oef-usage.md
index 2b52ef796f..450f96d605 100644
--- a/docs/simple-oef-usage.md
+++ b/docs/simple-oef-usage.md
@@ -1,12 +1,12 @@
You can use the SOEF in the agent framework by using the SOEF connection as a package in your agent project.
## Add the SOEF package
-Check out the CLI guide on details how to add a connection. You will want to add the `fetchai/soef:0.8.0` connection package.
+Check out the CLI guide on details how to add a connection. You will want to add the `fetchai/soef:0.9.0` connection package.
## Register your agent and its services
### Register agent location
-To register your agent's location, you have to send a message in the `fetchai/oef_search:0.6.0` protocol to the SOEF connection.
+To register your agent's location, you have to send a message in the `fetchai/oef_search:0.7.0` protocol to the SOEF connection.
First, define a data model for location data:
``` python
diff --git a/docs/skill-guide.md b/docs/skill-guide.md
index 6309c2ff87..28bbc38848 100644
--- a/docs/skill-guide.md
+++ b/docs/skill-guide.md
@@ -329,7 +329,7 @@ fingerprint: {}
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
my_search_behaviour:
@@ -373,14 +373,14 @@ Ensure, you use the correct author name to reference your skill (here we use `fe
Our AEA does not have the oef protocol yet so let's add it.
``` bash
-aea add protocol fetchai/oef_search:0.6.0
+aea add protocol fetchai/oef_search:0.7.0
```
This adds the protocol to our AEA and makes it available on the path `packages.fetchai.protocols...`.
We also need to add the soef and p2p connections and install the AEA's dependencies:
``` bash
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/p2p_libp2p:0.10.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
@@ -389,7 +389,7 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
Finally, in the `aea-config.yaml` add the following lines:
``` yaml
default_routing:
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
This will ensure that search requests are processed by the correct connection.
@@ -803,7 +803,7 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
service:
diff --git a/docs/skill.md b/docs/skill.md
index 5b8e529d27..debb1d34ee 100644
--- a/docs/skill.md
+++ b/docs/skill.md
@@ -262,7 +262,7 @@ handlers:
models: {}
dependencies: {}
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
```
@@ -275,7 +275,7 @@ All AEAs have a default `error` skill that contains error handling code for a nu
* Envelopes with decoding errors
* Invalid messages with respect to the registered protocol
-The error skill relies on the `fetchai/default:0.5.0` protocol which provides error codes for the above.
+The error skill relies on the `fetchai/default:0.6.0` protocol which provides error codes for the above.
diff --git a/docs/tac-skills-contract.md b/docs/tac-skills-contract.md
index 3a7feb913d..0ef6ee0985 100644
--- a/docs/tac-skills-contract.md
+++ b/docs/tac-skills-contract.md
@@ -114,7 +114,7 @@ The following steps create the controller from scratch:
aea create tac_controller_contract
cd tac_controller_contract
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_control_contract:0.9.0
aea install
@@ -179,7 +179,7 @@ Build participant one:
``` bash
cd tac_participant_one
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
@@ -194,7 +194,7 @@ Then, build participant two:
``` bash
cd tac_participant_two
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
diff --git a/docs/tac-skills.md b/docs/tac-skills.md
index c70415a668..bb9680e042 100644
--- a/docs/tac-skills.md
+++ b/docs/tac-skills.md
@@ -113,9 +113,9 @@ The following steps create the controller from scratch:
aea create tac_controller
cd tac_controller
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
-aea add skill fetchai/tac_control:0.7.0
+aea add skill fetchai/tac_control:0.8.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
aea config set agent.default_ledger fetchai
@@ -124,7 +124,7 @@ aea config set agent.default_ledger fetchai
In `tac_controller/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
@@ -153,7 +153,7 @@ Build participant one:
``` bash
cd tac_participant_one
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
@@ -165,15 +165,15 @@ aea config set agent.default_ledger fetchai
In `tac_participant_one/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
Then, build participant two:
``` bash
cd tac_participant_two
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
@@ -185,8 +185,8 @@ aea config set agent.default_ledger fetchai
In `tac_participant_two/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
diff --git a/docs/thermometer-skills.md b/docs/thermometer-skills.md
index f6d24d01f5..bbaed90239 100644
--- a/docs/thermometer-skills.md
+++ b/docs/thermometer-skills.md
@@ -75,7 +75,7 @@ The following steps create the thermometer AEA from scratch:
aea create my_thermometer_aea
cd my_thermometer_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer:0.12.0
aea install
@@ -85,8 +85,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `my_thermometer_aea/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
@@ -109,7 +109,7 @@ The following steps create the thermometer client from scratch:
aea create my_thermometer_client
cd my_thermometer_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer_client:0.11.0
aea install
@@ -119,8 +119,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `my_thermometer_aea/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
diff --git a/docs/weather-skills.md b/docs/weather-skills.md
index fc1ce3c493..3b1a2db8b7 100644
--- a/docs/weather-skills.md
+++ b/docs/weather-skills.md
@@ -74,7 +74,7 @@ The following steps create the weather station from scratch:
aea create my_weather_station
cd my_weather_station
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/weather_station:0.12.0
aea install
@@ -84,8 +84,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `weather_station/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
@@ -109,7 +109,7 @@ The following steps create the weather client from scratch:
aea create my_weather_client
cd my_weather_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/weather_client:0.11.0
aea install
@@ -119,8 +119,8 @@ aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
In `my_weather_client/aea-config.yaml` add
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
diff --git a/packages/fetchai/agents/aries_alice/aea-config.yaml b/packages/fetchai/agents/aries_alice/aea-config.yaml
index 0ad1aa0a90..7efbe1b67a 100644
--- a/packages/fetchai/agents/aries_alice/aea-config.yaml
+++ b/packages/fetchai/agents/aries_alice/aea-config.yaml
@@ -7,19 +7,19 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/http_client:0.8.0
+- fetchai/http_client:0.9.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
-- fetchai/webhook:0.6.0
+- fetchai/webhook:0.7.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/http:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/http:0.6.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/aries_alice:0.7.0
-- fetchai/error:0.5.0
+- fetchai/aries_alice:0.8.0
+- fetchai/error:0.6.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: fetchai
logging_config:
@@ -28,5 +28,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/http:0.5.0: fetchai/http_client:0.8.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/http:0.6.0: fetchai/http_client:0.9.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/aries_faber/aea-config.yaml b/packages/fetchai/agents/aries_faber/aea-config.yaml
index 7d043ca849..60858d53c7 100644
--- a/packages/fetchai/agents/aries_faber/aea-config.yaml
+++ b/packages/fetchai/agents/aries_faber/aea-config.yaml
@@ -7,20 +7,20 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/http_client:0.8.0
+- fetchai/http_client:0.9.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
-- fetchai/webhook:0.6.0
+- fetchai/webhook:0.7.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/http:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/http:0.6.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/aries_faber:0.6.0
-- fetchai/error:0.5.0
-default_connection: fetchai/http_client:0.8.0
+- fetchai/aries_faber:0.7.0
+- fetchai/error:0.6.0
+default_connection: fetchai/http_client:0.9.0
default_ledger: fetchai
logging_config:
disable_existing_loggers: false
@@ -28,5 +28,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/http:0.5.0: fetchai/http_client:0.8.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/http:0.6.0: fetchai/http_client:0.9.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/car_data_buyer/aea-config.yaml b/packages/fetchai/agents/car_data_buyer/aea-config.yaml
index 2a40202d91..d4300cd29e 100644
--- a/packages/fetchai/agents/car_data_buyer/aea-config.yaml
+++ b/packages/fetchai/agents/car_data_buyer/aea-config.yaml
@@ -10,17 +10,17 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/carpark_client:0.12.0
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_buyer:0.12.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: fetchai
@@ -30,5 +30,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/car_detector/aea-config.yaml b/packages/fetchai/agents/car_detector/aea-config.yaml
index e2bd0d8eb7..b63aafca67 100644
--- a/packages/fetchai/agents/car_detector/aea-config.yaml
+++ b/packages/fetchai/agents/car_detector/aea-config.yaml
@@ -9,17 +9,17 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/carpark_detection:0.12.0
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_seller:0.13.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: fetchai
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/erc1155_client/aea-config.yaml b/packages/fetchai/agents/erc1155_client/aea-config.yaml
index d168178040..19ad7cf3c4 100644
--- a/packages/fetchai/agents/erc1155_client/aea-config.yaml
+++ b/packages/fetchai/agents/erc1155_client/aea-config.yaml
@@ -9,20 +9,20 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
- fetchai/contract_api:0.5.0
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
skills:
- fetchai/erc1155_client:0.13.0
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: ethereum
logging_config:
@@ -32,5 +32,5 @@ private_key_paths: {}
registry_path: ../packages
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/erc1155_deployer/aea-config.yaml b/packages/fetchai/agents/erc1155_deployer/aea-config.yaml
index 6a60e30ba2..abc22baa84 100644
--- a/packages/fetchai/agents/erc1155_deployer/aea-config.yaml
+++ b/packages/fetchai/agents/erc1155_deployer/aea-config.yaml
@@ -9,20 +9,20 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
- fetchai/contract_api:0.5.0
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
skills:
- fetchai/erc1155_deploy:0.14.0
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: ethereum
logging_config:
@@ -32,5 +32,5 @@ private_key_paths: {}
registry_path: ../packages
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/generic_buyer/aea-config.yaml b/packages/fetchai/agents/generic_buyer/aea-config.yaml
index 6e20d189fa..b0482b5822 100644
--- a/packages/fetchai/agents/generic_buyer/aea-config.yaml
+++ b/packages/fetchai/agents/generic_buyer/aea-config.yaml
@@ -9,16 +9,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_buyer:0.12.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: fetchai
@@ -28,5 +28,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/generic_seller/aea-config.yaml b/packages/fetchai/agents/generic_seller/aea-config.yaml
index 2e3394d829..e53783701c 100644
--- a/packages/fetchai/agents/generic_seller/aea-config.yaml
+++ b/packages/fetchai/agents/generic_seller/aea-config.yaml
@@ -10,16 +10,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_seller:0.13.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: fetchai
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/gym_aea/aea-config.yaml b/packages/fetchai/agents/gym_aea/aea-config.yaml
index 69a7d2fc18..d18a4ad991 100644
--- a/packages/fetchai/agents/gym_aea/aea-config.yaml
+++ b/packages/fetchai/agents/gym_aea/aea-config.yaml
@@ -12,10 +12,10 @@ connections:
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
- fetchai/gym:0.6.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/gym:0.8.0
default_connection: fetchai/gym:0.8.0
default_ledger: fetchai
diff --git a/packages/fetchai/agents/ml_data_provider/aea-config.yaml b/packages/fetchai/agents/ml_data_provider/aea-config.yaml
index ffb8c1b082..d6c4f22331 100644
--- a/packages/fetchai/agents/ml_data_provider/aea-config.yaml
+++ b/packages/fetchai/agents/ml_data_provider/aea-config.yaml
@@ -9,16 +9,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/ledger_api:0.3.0
-- fetchai/ml_trade:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/ledger_api:0.4.0
+- fetchai/ml_trade:0.6.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_seller:0.13.0
- fetchai/ml_data_provider:0.12.0
default_connection: fetchai/p2p_libp2p:0.10.0
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/ml_model_trainer/aea-config.yaml b/packages/fetchai/agents/ml_model_trainer/aea-config.yaml
index 262eaa4b24..b6c7e4f8c6 100644
--- a/packages/fetchai/agents/ml_model_trainer/aea-config.yaml
+++ b/packages/fetchai/agents/ml_model_trainer/aea-config.yaml
@@ -9,16 +9,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/ledger_api:0.3.0
-- fetchai/ml_trade:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/ledger_api:0.4.0
+- fetchai/ml_trade:0.6.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_buyer:0.12.0
- fetchai/ml_train:0.12.0
default_connection: fetchai/p2p_libp2p:0.10.0
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/my_first_aea/aea-config.yaml b/packages/fetchai/agents/my_first_aea/aea-config.yaml
index 91e5e4786a..cab085b44c 100644
--- a/packages/fetchai/agents/my_first_aea/aea-config.yaml
+++ b/packages/fetchai/agents/my_first_aea/aea-config.yaml
@@ -1,6 +1,6 @@
agent_name: my_first_aea
author: fetchai
-version: 0.11.0
+version: 0.12.0
description: A simple agent to demo the echo skill.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
@@ -10,10 +10,10 @@ connections:
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills:
-- fetchai/echo:0.7.0
-- fetchai/error:0.5.0
+- fetchai/echo:0.8.0
+- fetchai/error:0.6.0
default_connection: fetchai/stub:0.9.0
default_ledger: fetchai
logging_config:
diff --git a/packages/fetchai/agents/simple_service_registration/aea-config.yaml b/packages/fetchai/agents/simple_service_registration/aea-config.yaml
index 7762008c7a..6e6d8adceb 100644
--- a/packages/fetchai/agents/simple_service_registration/aea-config.yaml
+++ b/packages/fetchai/agents/simple_service_registration/aea-config.yaml
@@ -8,15 +8,15 @@ fingerprint: ''
fingerprint_ignore_patterns: []
connections:
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/simple_service_registration:0.10.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: fetchai
@@ -26,4 +26,4 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/tac_controller/aea-config.yaml b/packages/fetchai/agents/tac_controller/aea-config.yaml
index 3470e8a73f..9ce1d7381f 100644
--- a/packages/fetchai/agents/tac_controller/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller/aea-config.yaml
@@ -8,16 +8,16 @@ fingerprint: {}
fingerprint_ignore_patterns: []
connections:
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/oef_search:0.6.0
-- fetchai/tac:0.6.0
+- fetchai/default:0.6.0
+- fetchai/oef_search:0.7.0
+- fetchai/tac:0.7.0
skills:
-- fetchai/error:0.5.0
-- fetchai/tac_control:0.7.0
+- fetchai/error:0.6.0
+- fetchai/tac_control:0.8.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: fetchai
logging_config:
@@ -26,4 +26,4 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index caa12bbff0..0a4302ca0b 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -8,19 +8,19 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/oef:0.9.0
+- fetchai/oef:0.10.0
- fetchai/stub:0.9.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/oef_search:0.6.0
-- fetchai/tac:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/oef_search:0.7.0
+- fetchai/tac:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/tac_control_contract:0.9.0
-default_connection: fetchai/oef:0.9.0
+default_connection: fetchai/oef:0.10.0
default_ledger: ethereum
logging_config:
disable_existing_loggers: false
diff --git a/packages/fetchai/agents/tac_participant/aea-config.yaml b/packages/fetchai/agents/tac_participant/aea-config.yaml
index e4180ff1a9..0c2333eece 100644
--- a/packages/fetchai/agents/tac_participant/aea-config.yaml
+++ b/packages/fetchai/agents/tac_participant/aea-config.yaml
@@ -9,17 +9,17 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/oef_search:0.6.0
-- fetchai/tac:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/oef_search:0.7.0
+- fetchai/tac:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/tac_negotiation:0.10.0
- fetchai/tac_participation:0.9.0
default_connection: fetchai/p2p_libp2p:0.10.0
@@ -30,5 +30,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/thermometer_aea/aea-config.yaml b/packages/fetchai/agents/thermometer_aea/aea-config.yaml
index f212ebdf5c..f3e7d966b4 100644
--- a/packages/fetchai/agents/thermometer_aea/aea-config.yaml
+++ b/packages/fetchai/agents/thermometer_aea/aea-config.yaml
@@ -9,16 +9,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_seller:0.13.0
- fetchai/thermometer:0.12.0
default_connection: fetchai/p2p_libp2p:0.10.0
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/thermometer_client/aea-config.yaml b/packages/fetchai/agents/thermometer_client/aea-config.yaml
index 02f51acf56..64aa7e7bc6 100644
--- a/packages/fetchai/agents/thermometer_client/aea-config.yaml
+++ b/packages/fetchai/agents/thermometer_client/aea-config.yaml
@@ -9,16 +9,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_buyer:0.12.0
- fetchai/thermometer_client:0.11.0
default_connection: fetchai/p2p_libp2p:0.10.0
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/weather_client/aea-config.yaml b/packages/fetchai/agents/weather_client/aea-config.yaml
index 894da78b40..a86fbf5abb 100644
--- a/packages/fetchai/agents/weather_client/aea-config.yaml
+++ b/packages/fetchai/agents/weather_client/aea-config.yaml
@@ -9,16 +9,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_buyer:0.12.0
- fetchai/weather_client:0.11.0
default_connection: fetchai/p2p_libp2p:0.10.0
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/agents/weather_station/aea-config.yaml b/packages/fetchai/agents/weather_station/aea-config.yaml
index ee6630c2f1..0b892a4102 100644
--- a/packages/fetchai/agents/weather_station/aea-config.yaml
+++ b/packages/fetchai/agents/weather_station/aea-config.yaml
@@ -9,16 +9,16 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
- fetchai/generic_seller:0.13.0
- fetchai/weather_station:0.12.0
default_connection: fetchai/p2p_libp2p:0.10.0
@@ -29,5 +29,5 @@ logging_config:
private_key_paths: {}
registry_path: ../packages
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
diff --git a/packages/fetchai/connections/http_client/README.md b/packages/fetchai/connections/http_client/README.md
index f4080b1cc0..0686f336e5 100644
--- a/packages/fetchai/connections/http_client/README.md
+++ b/packages/fetchai/connections/http_client/README.md
@@ -4,4 +4,4 @@ This connection wraps an HTTP client. It consumes messages from the AEA, transla
## Usage
-First, add the connection to your AEA project (`aea add connection fetchai/http_client:0.8.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server.
+First, add the connection to your AEA project (`aea add connection fetchai/http_client:0.9.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server.
diff --git a/packages/fetchai/connections/http_client/connection.py b/packages/fetchai/connections/http_client/connection.py
index 72ed44788f..3c86c22d22 100644
--- a/packages/fetchai/connections/http_client/connection.py
+++ b/packages/fetchai/connections/http_client/connection.py
@@ -47,7 +47,7 @@
NOT_FOUND = 404
REQUEST_TIMEOUT = 408
SERVER_ERROR = 500
-PUBLIC_ID = PublicId.from_str("fetchai/http_client:0.8.0")
+PUBLIC_ID = PublicId.from_str("fetchai/http_client:0.9.0")
logger = logging.getLogger("aea.packages.fetchai.connections.http_client")
diff --git a/packages/fetchai/connections/http_client/connection.yaml b/packages/fetchai/connections/http_client/connection.yaml
index 462f0c8937..dd5d64ad4c 100644
--- a/packages/fetchai/connections/http_client/connection.yaml
+++ b/packages/fetchai/connections/http_client/connection.yaml
@@ -1,25 +1,25 @@
name: http_client
author: fetchai
-version: 0.8.0
+version: 0.9.0
type: connection
description: The HTTP_client connection that wraps a web-based client connecting to
a RESTful API specification.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmXfZJPAh4Ujt3xj8xzd6ng6HbrpJQUuvjWe8DNQSwSKWU
+ README.md: QmV5yDm9hsPKzhW3xA8GgViryhbwGEcRSqxwtrEzFm1fuQ
__init__.py: QmPdKAks8A6XKAgZiopJzPZYXJumTeUqChd8UorqmLQQPU
- connection.py: QmW9DVSJwTdD8BkjiZc8fYa2ndHVCy6HepFpmnX8H8TVMH
+ connection.py: QmPWU31DeNecH9Ch62hFZ5a1peEk5p7UXYj2qRgm3TBLFD
fingerprint_ignore_patterns: []
protocols:
-- fetchai/http:0.5.0
+- fetchai/http:0.6.0
class_name: HTTPClientConnection
config:
host: 127.0.0.1
port: 8000
excluded_protocols: []
restricted_to_protocols:
-- fetchai/http:0.5.0
+- fetchai/http:0.6.0
dependencies:
aiohttp:
version: '>=3.6.2,<3.7'
diff --git a/packages/fetchai/connections/http_server/README.md b/packages/fetchai/connections/http_server/README.md
index 80680ce445..20aee30556 100644
--- a/packages/fetchai/connections/http_server/README.md
+++ b/packages/fetchai/connections/http_server/README.md
@@ -4,4 +4,4 @@ This connection wraps an HTTP server. It consumes requests from clients, transla
## Usage
-First, add the connection to your AEA project (`aea add connection fetchai/http_server:0.8.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server. Optionally, provide a path to an [OpenAPI spec](https://swagger.io/docs/specification/about/) for request validation.
\ No newline at end of file
+First, add the connection to your AEA project (`aea add connection fetchai/http_server:0.9.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server. Optionally, provide a path to an [OpenAPI spec](https://swagger.io/docs/specification/about/) for request validation.
\ No newline at end of file
diff --git a/packages/fetchai/connections/http_server/connection.py b/packages/fetchai/connections/http_server/connection.py
index 9655657e13..c906ca6960 100644
--- a/packages/fetchai/connections/http_server/connection.py
+++ b/packages/fetchai/connections/http_server/connection.py
@@ -66,7 +66,7 @@
_default_logger = logging.getLogger("aea.packages.fetchai.connections.http_server")
RequestId = DialogueLabel
-PUBLIC_ID = PublicId.from_str("fetchai/http_server:0.8.0")
+PUBLIC_ID = PublicId.from_str("fetchai/http_server:0.9.0")
class HttpDialogues(BaseHttpDialogues):
diff --git a/packages/fetchai/connections/http_server/connection.yaml b/packages/fetchai/connections/http_server/connection.yaml
index 9f5b628ccb..d9db65c7dd 100644
--- a/packages/fetchai/connections/http_server/connection.yaml
+++ b/packages/fetchai/connections/http_server/connection.yaml
@@ -1,18 +1,18 @@
name: http_server
author: fetchai
-version: 0.8.0
+version: 0.9.0
type: connection
description: The HTTP server connection that wraps http server implementing a RESTful
API specification.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmTmQcnUPKaDHHJHngBFXnUVPdgBLanP9DbjVHZT55Scfn
+ README.md: QmUeXiba13kjgsW8EMYvWnMYb6GzSirTPyr3L2dLU4J9gT
__init__.py: Qmb6JEAkJeb5JweqrSGiGoQp1vGXqddjGgb9WMkm2phTgA
- connection.py: QmNxiS2h8QhqraJTiNdrGtM7BNCxiFfZvgdaWK9T1ghgxj
+ connection.py: QmPjqaEpWNRM412ZbxCN2dp3qUM1jTEYmhABbYUDejTm6w
fingerprint_ignore_patterns: []
protocols:
-- fetchai/http:0.5.0
+- fetchai/http:0.6.0
class_name: HTTPServerConnection
config:
api_spec_path: ''
@@ -20,7 +20,7 @@ config:
port: 8000
excluded_protocols: []
restricted_to_protocols:
-- fetchai/http:0.5.0
+- fetchai/http:0.6.0
dependencies:
aiohttp:
version: '>=3.6.2,<3.7'
diff --git a/packages/fetchai/connections/ledger/README.md b/packages/fetchai/connections/ledger/README.md
index 807387e685..0da1b56662 100644
--- a/packages/fetchai/connections/ledger/README.md
+++ b/packages/fetchai/connections/ledger/README.md
@@ -2,7 +2,7 @@
The ledger connection wraps the APIs needed to interact with multiple ledgers, including smart contracts deployed on those ledgers.
-The AEA communicates with the ledger connection via the `fetchai/ledger_api:0.3.0` and `fetchai/contract_api:0.5.0` protocols.
+The AEA communicates with the ledger connection via the `fetchai/ledger_api:0.4.0` and `fetchai/contract_api:0.5.0` protocols.
The connection uses the ledger apis registered in the ledger api registry.
diff --git a/packages/fetchai/connections/ledger/connection.yaml b/packages/fetchai/connections/ledger/connection.yaml
index abf2098efc..63641cb273 100644
--- a/packages/fetchai/connections/ledger/connection.yaml
+++ b/packages/fetchai/connections/ledger/connection.yaml
@@ -6,7 +6,7 @@ description: A connection to interact with any ledger API and contract API.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmfQN7UK1M4pBUzKVzPannPLVi8iiULKHNtJ7XpoWpjqfc
+ README.md: QmY6YCoxyUXSwQzFvNPKd3nfHaoMsjCLCZAvTGSGwZnZbP
__init__.py: QmZvYZ5ECcWwqiNGh8qNTg735wu51HqaLxTSifUxkQ4KGj
base.py: QmNnSBVmVgdDFwzqDUncwLHeyDfMEfmvujJdKbdGNGH4Be
connection.py: Qmdibf99GzdFjFCcoTX7AiiBVWznKvPZWvur8cngSRNdye
@@ -15,7 +15,7 @@ fingerprint:
fingerprint_ignore_patterns: []
protocols:
- fetchai/contract_api:0.5.0
-- fetchai/ledger_api:0.3.0
+- fetchai/ledger_api:0.4.0
class_name: LedgerConnection
config:
ledger_apis:
@@ -27,5 +27,5 @@ config:
excluded_protocols: []
restricted_to_protocols:
- fetchai/contract_api:0.5.0
-- fetchai/ledger_api:0.3.0
+- fetchai/ledger_api:0.4.0
dependencies: {}
diff --git a/packages/fetchai/connections/local/connection.py b/packages/fetchai/connections/local/connection.py
index 53c10fe68c..db08d23349 100644
--- a/packages/fetchai/connections/local/connection.py
+++ b/packages/fetchai/connections/local/connection.py
@@ -47,7 +47,7 @@
RESPONSE_TARGET = MESSAGE_ID
RESPONSE_MESSAGE_ID = MESSAGE_ID + 1
STUB_DIALOGUE_ID = 0
-PUBLIC_ID = PublicId.from_str("fetchai/local:0.8.0")
+PUBLIC_ID = PublicId.from_str("fetchai/local:0.9.0")
class OefSearchDialogues(BaseOefSearchDialogues):
@@ -181,7 +181,7 @@ async def _handle_envelope(self, envelope: Envelope) -> None:
:param envelope: the envelope
:return: None
"""
- if envelope.protocol_id == ProtocolId.from_str("fetchai/oef_search:0.6.0"):
+ if envelope.protocol_id == ProtocolId.from_str("fetchai/oef_search:0.7.0"):
await self._handle_oef_message(envelope)
else:
await self._handle_agent_message(envelope)
diff --git a/packages/fetchai/connections/local/connection.yaml b/packages/fetchai/connections/local/connection.yaml
index 625d62d1ef..4f86525679 100644
--- a/packages/fetchai/connections/local/connection.yaml
+++ b/packages/fetchai/connections/local/connection.yaml
@@ -1,6 +1,6 @@
name: local
author: fetchai
-version: 0.8.0
+version: 0.9.0
type: connection
description: The local connection provides a stub for an OEF node.
license: Apache-2.0
@@ -8,10 +8,10 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmbK7MtyAVqh2LmSh9TY6yBZqfWaAXURP4rQGATyP2hTKC
__init__.py: QmeeoX5E38Ecrb1rLdeFyyxReHLrcJoETnBcPbcNWVbiKG
- connection.py: QmXtme7q9RZaLb53Gjsv2GcBg1XfrPGZprzxu2eNHyFdFY
+ connection.py: QmUVta4sBNBna7bmhpa1aV8nfHrUQ6e8GsV5758GJT5BT9
fingerprint_ignore_patterns: []
protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
class_name: OEFLocalConnection
config: {}
excluded_protocols: []
diff --git a/packages/fetchai/connections/oef/README.md b/packages/fetchai/connections/oef/README.md
index 4e30cbd2ba..3f6b09fce2 100644
--- a/packages/fetchai/connections/oef/README.md
+++ b/packages/fetchai/connections/oef/README.md
@@ -4,4 +4,4 @@ Connection to interact with an OEF node (https://fetchai.github.io/oef-sdk-pytho
## Usage
-Register/unregister services, perform searches using `fetchai/oef_search:0.6.0` protocol and send messages of any protocol to other agents connected to the same node.
\ No newline at end of file
+Register/unregister services, perform searches using `fetchai/oef_search:0.7.0` protocol and send messages of any protocol to other agents connected to the same node.
\ No newline at end of file
diff --git a/packages/fetchai/connections/oef/connection.py b/packages/fetchai/connections/oef/connection.py
index 124d6ad822..b99a6ff66f 100644
--- a/packages/fetchai/connections/oef/connection.py
+++ b/packages/fetchai/connections/oef/connection.py
@@ -59,7 +59,7 @@
STUB_MESSAGE_ID = 0
STUB_DIALOGUE_ID = 0
DEFAULT_OEF = "oef"
-PUBLIC_ID = PublicId.from_str("fetchai/oef:0.9.0")
+PUBLIC_ID = PublicId.from_str("fetchai/oef:0.10.0")
class OefSearchDialogue(BaseOefSearchDialogue):
@@ -411,7 +411,7 @@ def send(self, envelope: Envelope) -> None:
)
raise ValueError("Cannot send message.")
- if envelope.protocol_id == PublicId.from_str("fetchai/oef_search:0.6.0"):
+ if envelope.protocol_id == PublicId.from_str("fetchai/oef_search:0.7.0"):
self.send_oef_message(envelope)
else:
self.send_default_message(envelope)
diff --git a/packages/fetchai/connections/oef/connection.yaml b/packages/fetchai/connections/oef/connection.yaml
index 807f12d66e..d788e1ffa1 100644
--- a/packages/fetchai/connections/oef/connection.yaml
+++ b/packages/fetchai/connections/oef/connection.yaml
@@ -1,20 +1,20 @@
name: oef
author: fetchai
-version: 0.9.0
+version: 0.10.0
type: connection
description: The oef connection provides a wrapper around the OEF SDK for connection
with the OEF search and communication node.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmVHWxThR1u9a4BEm89oCxUTPGnN6PznvNgo6oZLqDD3n5
+ README.md: Qma1rPtWWsKVgrutuRKqtP4uCzhs6ZDRbwLFaH5DF75KZs
__init__.py: QmUAen8tmoBHuCerjA3FSGKJRLG6JYyUS3chuWzPxKYzez
- connection.py: QmfDKjDageCc4Pxdqokw7s2foEgwrWnoexcdHL9PcVWS45
+ connection.py: QmNgAS6quG3NJtrTBQa6d4g4s1oMuFpXUiPb5FY2d85tX9
object_translator.py: QmZbRaJgFC1RKDA8hox6xTpqmrpTbp8SyYQoKarTmS5HwG
fingerprint_ignore_patterns: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/oef_search:0.7.0
class_name: OEFConnection
config:
addr: 127.0.0.1
diff --git a/packages/fetchai/connections/p2p_stub/README.md b/packages/fetchai/connections/p2p_stub/README.md
index f72f38a289..5116ec9244 100644
--- a/packages/fetchai/connections/p2p_stub/README.md
+++ b/packages/fetchai/connections/p2p_stub/README.md
@@ -4,6 +4,6 @@ Simple file based connection to perform interaction between multiple local agent
## Usage
-First, add the connection to your AEA project: `aea add connection fetchai/p2p_stub:0.6.0`.
+First, add the connection to your AEA project: `aea add connection fetchai/p2p_stub:0.7.0`.
Optionally, in the `connection.yaml` file under `config` set the `namespace_dir` to the desired file path. The `p2p_stub` connection reads encoded envelopes from its input file and writes encoded envelopes to its output file. Multiple agents can be pointed to the same `namespace_dir` and are then able to exchange envelopes via the file system.
diff --git a/packages/fetchai/connections/p2p_stub/connection.py b/packages/fetchai/connections/p2p_stub/connection.py
index 868ef46cb8..b24e1ceebf 100644
--- a/packages/fetchai/connections/p2p_stub/connection.py
+++ b/packages/fetchai/connections/p2p_stub/connection.py
@@ -29,7 +29,7 @@
from aea.mail.base import Envelope
-PUBLIC_ID = PublicId.from_str("fetchai/p2p_stub:0.6.0")
+PUBLIC_ID = PublicId.from_str("fetchai/p2p_stub:0.7.0")
class P2PStubConnection(StubConnection):
diff --git a/packages/fetchai/connections/p2p_stub/connection.yaml b/packages/fetchai/connections/p2p_stub/connection.yaml
index cd89b62ea5..94f70002ba 100644
--- a/packages/fetchai/connections/p2p_stub/connection.yaml
+++ b/packages/fetchai/connections/p2p_stub/connection.yaml
@@ -1,15 +1,15 @@
name: p2p_stub
author: fetchai
-version: 0.6.0
+version: 0.7.0
type: connection
description: The stub p2p connection implements a local p2p connection allowing agents
to communicate with each other through files created in the namespace directory.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmbAStnFJj6jMTwqNu7DG9dt2uy5JGrGhKtCbYuAhWLBCk
+ README.md: QmW9vG1qAt8hjycMMK6LUFNaDp52KnakgjbRrTCMCRTnNW
__init__.py: QmW9XFKGsea4u3fupkFMcQutgsjqusCMBMyTcTmLLmQ4tR
- connection.py: QmVcCQYuXoXbYUVDi3BBarf6fxeg9GjKYkr814CMGUq3UW
+ connection.py: QmbeuHyjBW7PjEuZXGr9BsLTmV5WEe6YE9sNYszX7iirek
fingerprint_ignore_patterns: []
protocols: []
class_name: P2PStubConnection
diff --git a/packages/fetchai/connections/soef/README.md b/packages/fetchai/connections/soef/README.md
index 14c6d3d3f1..10cdfc89b8 100644
--- a/packages/fetchai/connections/soef/README.md
+++ b/packages/fetchai/connections/soef/README.md
@@ -4,6 +4,6 @@ The SOEF connection is used to connect to an SOEF node. The SOEF provides OEF se
## Usage
-First, add the connection to your AEA project: `aea add connection fetchai/soef:0.8.0`. Then ensure the `config` in `connection.yaml` matches your need. In particular, make sure `chain_identifier` matches your `default_ledger`.
+First, add the connection to your AEA project: `aea add connection fetchai/soef:0.9.0`. Then ensure the `config` in `connection.yaml` matches your need. In particular, make sure `chain_identifier` matches your `default_ledger`.
-To register/unregister services and perform searches use the `fetchai/oef_search:0.6.0` protocol
\ No newline at end of file
+To register/unregister services and perform searches use the `fetchai/oef_search:0.7.0` protocol
\ No newline at end of file
diff --git a/packages/fetchai/connections/soef/connection.py b/packages/fetchai/connections/soef/connection.py
index b6dd3a9a14..61764a7a6a 100644
--- a/packages/fetchai/connections/soef/connection.py
+++ b/packages/fetchai/connections/soef/connection.py
@@ -64,7 +64,7 @@
_default_logger = logging.getLogger("aea.packages.fetchai.connections.oef")
-PUBLIC_ID = PublicId.from_str("fetchai/soef:0.8.0")
+PUBLIC_ID = PublicId.from_str("fetchai/soef:0.9.0")
NOT_SPECIFIED = object()
@@ -1095,7 +1095,7 @@ def __init__(self, **kwargs):
if kwargs.get("configuration") is None: # pragma: nocover
kwargs["excluded_protocols"] = kwargs.get("excluded_protocols") or []
kwargs["restricted_to_protocols"] = kwargs.get("excluded_protocols") or [
- PublicId.from_str("fetchai/oef_search:0.6.0")
+ PublicId.from_str("fetchai/oef_search:0.7.0")
]
super().__init__(**kwargs)
diff --git a/packages/fetchai/connections/soef/connection.yaml b/packages/fetchai/connections/soef/connection.yaml
index 5e40dea962..1c74d5b68d 100644
--- a/packages/fetchai/connections/soef/connection.yaml
+++ b/packages/fetchai/connections/soef/connection.yaml
@@ -1,17 +1,17 @@
name: soef
author: fetchai
-version: 0.8.0
+version: 0.9.0
type: connection
description: The soef connection provides a connection api to the simple OEF.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmWwjETX39APP9RD5oVPeeCiDnUoDvjAcoVe2FK2Jc6anM
+ README.md: QmS9zorTodmaRyaxocELEwEqHEPowKoG9wgSAak7s59rZD
__init__.py: Qmd5VBGFJHXFe1H45XoUh5mMSYBwvLSViJuGFeMgbPdQts
- connection.py: QmYzSA9zWn4r3kdBxvV1TGeqb1oGKCuvHruoH8Nkexneb7
+ connection.py: QmQ1yNBGWB8driD2bFokLYjmKUJ2FWQhPfWxYLGEHCAfC8
fingerprint_ignore_patterns: []
protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
class_name: SOEFConnection
config:
api_key: TwiCIriSl0mLahw17pyqoA
@@ -20,6 +20,6 @@ config:
soef_port: 9002
excluded_protocols: []
restricted_to_protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
dependencies:
defusedxml: {}
diff --git a/packages/fetchai/connections/tcp/README.md b/packages/fetchai/connections/tcp/README.md
index e2487613c0..1b933ee4af 100644
--- a/packages/fetchai/connections/tcp/README.md
+++ b/packages/fetchai/connections/tcp/README.md
@@ -4,4 +4,4 @@ A simple TCP client/server connection to use the TCP protocol for sending and re
## Usage
-Add the connection to your AEA project: `aea add connection fetchai/tcp:0.7.0`.
+Add the connection to your AEA project: `aea add connection fetchai/tcp:0.8.0`.
diff --git a/packages/fetchai/connections/tcp/base.py b/packages/fetchai/connections/tcp/base.py
index dc5bddd500..48be8f5012 100644
--- a/packages/fetchai/connections/tcp/base.py
+++ b/packages/fetchai/connections/tcp/base.py
@@ -31,7 +31,7 @@
logger = logging.getLogger("aea.packages.fetchai.connections.tcp")
-PUBLIC_ID = PublicId.from_str("fetchai/tcp:0.7.0")
+PUBLIC_ID = PublicId.from_str("fetchai/tcp:0.8.0")
class TCPConnection(Connection, ABC):
diff --git a/packages/fetchai/connections/tcp/connection.yaml b/packages/fetchai/connections/tcp/connection.yaml
index 0e740d4432..92863a30ee 100644
--- a/packages/fetchai/connections/tcp/connection.yaml
+++ b/packages/fetchai/connections/tcp/connection.yaml
@@ -1,14 +1,14 @@
name: tcp
author: fetchai
-version: 0.7.0
+version: 0.8.0
type: connection
description: The tcp connection implements a tcp server and client.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmVtv8cSd49aAYHFjbCdmvJJoD4mPCuG5PR7QKXxcAquJw
+ README.md: Qmf1JEZWHRcP8jecLrQ4tGxCdmYLEzhnRJqpZqJmpfNDxZ
__init__.py: QmTxAtQ9ffraStxxLAkvmWxyGhoV3jE16Sw6SJ9xzTthLb
- base.py: Qmf3rJCzi6dmEXa87X1HpZRqWvuirAykeTnNyEt5SKzLJ9
+ base.py: QmT8ZwAGWNAibUvnucaM2jiPu6ixPfaG14YKuXSaRp6b2b
connection.py: QmcQnyUagAhE7UsSBxiBSqsuF4mTMdU26LZLhUhdq5QygR
tcp_client.py: QmfTTuC41Wp8dRBeNJWXKa6ryu98TRT8H3oSCFmvfypCEy
tcp_server.py: QmZ8tNfGzqNepjjspMfjWdwsGX2Afj56nSEdyAJfdHcHqS
diff --git a/packages/fetchai/connections/webhook/README.md b/packages/fetchai/connections/webhook/README.md
index 306c158e06..562a56a87f 100644
--- a/packages/fetchai/connections/webhook/README.md
+++ b/packages/fetchai/connections/webhook/README.md
@@ -4,4 +4,4 @@ An HTTP webhook connection which registers a webhook and waits for incoming requ
## Usage
-First, add the connection to your AEA project: `aea add connection fetchai/webhook:0.6.0`. Then ensure the `config` in `connection.yaml` matches your need. In particular, set `webhook_address`, `webhook_port` and `webhook_url_path` appropriately.
+First, add the connection to your AEA project: `aea add connection fetchai/webhook:0.7.0`. Then ensure the `config` in `connection.yaml` matches your need. In particular, set `webhook_address`, `webhook_port` and `webhook_url_path` appropriately.
diff --git a/packages/fetchai/connections/webhook/connection.py b/packages/fetchai/connections/webhook/connection.py
index 18d65e6d1a..a3b923a14d 100644
--- a/packages/fetchai/connections/webhook/connection.py
+++ b/packages/fetchai/connections/webhook/connection.py
@@ -42,7 +42,7 @@
NOT_FOUND = 404
REQUEST_TIMEOUT = 408
SERVER_ERROR = 500
-PUBLIC_ID = PublicId.from_str("fetchai/webhook:0.6.0")
+PUBLIC_ID = PublicId.from_str("fetchai/webhook:0.7.0")
_default_logger = logging.getLogger("aea.packages.fetchai.connections.webhook")
diff --git a/packages/fetchai/connections/webhook/connection.yaml b/packages/fetchai/connections/webhook/connection.yaml
index ca03a8df41..f89110fe3f 100644
--- a/packages/fetchai/connections/webhook/connection.yaml
+++ b/packages/fetchai/connections/webhook/connection.yaml
@@ -1,17 +1,17 @@
name: webhook
author: fetchai
-version: 0.6.0
+version: 0.7.0
type: connection
description: The webhook connection that wraps a webhook functionality.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmQDqfKKsksKsUqdqTcYe8P8Fw3MGovVuZBFHPbhupkkxf
+ README.md: QmX8P6hQej8CDXxbALfad9199k63JQAY7YQ23cDr9fQirG
__init__.py: QmWUKSmXaBgGMvKgdmzKmMjCx43BnrfW6og2n3afNoAALq
- connection.py: QmVZv722GNjJkXxQSnvVBQgWCTnG2uBfAVAkgvn2E5qWzX
+ connection.py: QmRxk2Kf7vufXvQA6chasUzAQaqQKoojWd1EHNLxhb8UoJ
fingerprint_ignore_patterns: []
protocols:
-- fetchai/http:0.5.0
+- fetchai/http:0.6.0
class_name: WebhookConnection
config:
webhook_address: 127.0.0.1
@@ -19,7 +19,7 @@ config:
webhook_url_path: /some/url/path
excluded_protocols: []
restricted_to_protocols:
-- fetchai/http:0.5.0
+- fetchai/http:0.6.0
dependencies:
aiohttp:
version: ==3.6.2
diff --git a/packages/fetchai/protocols/fipa/README.md b/packages/fetchai/protocols/fipa/README.md
index 186a559a8e..fd4f8577de 100644
--- a/packages/fetchai/protocols/fipa/README.md
+++ b/packages/fetchai/protocols/fipa/README.md
@@ -10,7 +10,7 @@ This is a protocol for two agents to negotiate over a fixed set of resources.
---
name: fipa
author: fetchai
-version: 0.6.0
+version: 0.7.0
description: A protocol for FIPA ACL.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
diff --git a/packages/fetchai/protocols/fipa/message.py b/packages/fetchai/protocols/fipa/message.py
index 57f781e3ac..84fb9195d4 100644
--- a/packages/fetchai/protocols/fipa/message.py
+++ b/packages/fetchai/protocols/fipa/message.py
@@ -40,7 +40,7 @@
class FipaMessage(Message):
"""A protocol for FIPA ACL."""
- protocol_id = ProtocolId.from_str("fetchai/fipa:0.6.0")
+ protocol_id = ProtocolId.from_str("fetchai/fipa:0.7.0")
Description = CustomDescription
diff --git a/packages/fetchai/protocols/fipa/protocol.yaml b/packages/fetchai/protocols/fipa/protocol.yaml
index 93295d63a5..20f15ddbad 100644
--- a/packages/fetchai/protocols/fipa/protocol.yaml
+++ b/packages/fetchai/protocols/fipa/protocol.yaml
@@ -1,18 +1,18 @@
name: fipa
author: fetchai
-version: 0.6.0
+version: 0.7.0
type: protocol
description: A protocol for FIPA ACL.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmRwxwzxfhotek7WUbyAeufBvoHpWbDwfUVMy3FKitiHKy
+ README.md: QmZAX3MEPFvQSmDqu1mLoEe3gWxfkH2VDFHN3dB99A4Z5d
__init__.py: QmR6pcWX14FsQip4eYJRNeiQdrNMPj6y4m6Tsgd6hd7yU6
custom_types.py: Qmf72KRbkNsxxAHwMtkmJc5TRL23fU7AuzJAdSTftckwJQ
dialogues.py: QmWaciW35ZTVeTeLWeyp3hjehKkWB5ZY7Di8N8cDH8Mjwb
fipa.proto: QmP7JqnuQSQ9BDcKkscrTydKEX4wFBoyFaY1bkzGkamcit
fipa_pb2.py: QmZMkefJLrb3zJKoimb6a9tdpxDBhc8rR2ghimqg7gZ471
- message.py: QmSnzY8G89gUsgo21wF2TxnjZr7czba9a7HEfLpWg9tqQq
+ message.py: Qmc32ZmhrmT7FX6EVPwR899BkN8HMivtRHpnkQWkRThXYU
serialization.py: QmQMb8F8hJm1gkJFSPPCtDAoxSX3bFkshtzRgDWfWB8ynd
fingerprint_ignore_patterns: []
dependencies:
diff --git a/packages/fetchai/protocols/http/README.md b/packages/fetchai/protocols/http/README.md
index fc76580aa9..a0997cc18a 100644
--- a/packages/fetchai/protocols/http/README.md
+++ b/packages/fetchai/protocols/http/README.md
@@ -10,7 +10,7 @@ This is a protocol for interacting with a client/server via HTTP requests and re
---
name: http
author: fetchai
-version: 0.5.0
+version: 0.6.0
description: A protocol for HTTP requests and responses.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
diff --git a/packages/fetchai/protocols/http/message.py b/packages/fetchai/protocols/http/message.py
index e1facfecc5..94ea11e63b 100644
--- a/packages/fetchai/protocols/http/message.py
+++ b/packages/fetchai/protocols/http/message.py
@@ -35,7 +35,7 @@
class HttpMessage(Message):
"""A protocol for HTTP requests and responses."""
- protocol_id = ProtocolId.from_str("fetchai/http:0.5.0")
+ protocol_id = ProtocolId.from_str("fetchai/http:0.6.0")
class Performative(Message.Performative):
"""Performatives for the http protocol."""
diff --git a/packages/fetchai/protocols/http/protocol.yaml b/packages/fetchai/protocols/http/protocol.yaml
index 9fd9a926a5..87cb1647ff 100644
--- a/packages/fetchai/protocols/http/protocol.yaml
+++ b/packages/fetchai/protocols/http/protocol.yaml
@@ -1,17 +1,17 @@
name: http
author: fetchai
-version: 0.5.0
+version: 0.6.0
type: protocol
description: A protocol for HTTP requests and responses.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmY7fxhyNBgwU7uc6LKtCN4aSQ4bym5BwqtwRAfwPokULN
+ README.md: QmYCacuyAELFigc3AvDAD5vm4iGZjan6QEk3dbksGvtFcM
__init__.py: QmWzgWYrnS7PhjYrrx2mykLoaCbb7rDnVRcDqifsRukTy4
dialogues.py: QmdwTehjCppcxyDid8m6zuHY5YwprUhato88R9Zdm9aXaM
http.proto: QmdTUTvvxGxMxSTB67AXjMUSDLdsxBYiSuJNVxHuLKB1jS
http_pb2.py: QmYYKqdwiueq54EveL9WXn216FXLSQ6XGJJHoiJxwJjzHC
- message.py: QmcZaEZbRbcx5U5KVEi2QTr6BVyHGDXcRrSqKhpngXRZ15
+ message.py: QmPB7CZ8hzvoN4s1sDLPiWdYfhKPVKQDM2jMPZtbW5TCAJ
serialization.py: QmTq34k2PD6Ybhk8x1EboY3UcNp8r3H6Tb3egZsWJN9nFv
fingerprint_ignore_patterns: []
dependencies:
diff --git a/packages/fetchai/protocols/ledger_api/README.md b/packages/fetchai/protocols/ledger_api/README.md
index c7d736e30f..8d45d848d3 100644
--- a/packages/fetchai/protocols/ledger_api/README.md
+++ b/packages/fetchai/protocols/ledger_api/README.md
@@ -10,7 +10,7 @@ This is a protocol for interacting with ledger APIs.
---
name: ledger_api
author: fetchai
-version: 0.3.0
+version: 0.4.0
description: A protocol for ledger APIs requests and responses.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
diff --git a/packages/fetchai/protocols/ledger_api/message.py b/packages/fetchai/protocols/ledger_api/message.py
index ef64a3fcf8..414cde154a 100644
--- a/packages/fetchai/protocols/ledger_api/message.py
+++ b/packages/fetchai/protocols/ledger_api/message.py
@@ -49,7 +49,7 @@
class LedgerApiMessage(Message):
"""A protocol for ledger APIs requests and responses."""
- protocol_id = ProtocolId.from_str("fetchai/ledger_api:0.3.0")
+ protocol_id = ProtocolId.from_str("fetchai/ledger_api:0.4.0")
RawTransaction = CustomRawTransaction
diff --git a/packages/fetchai/protocols/ledger_api/protocol.yaml b/packages/fetchai/protocols/ledger_api/protocol.yaml
index b08f57e1c4..30e6f0e21e 100644
--- a/packages/fetchai/protocols/ledger_api/protocol.yaml
+++ b/packages/fetchai/protocols/ledger_api/protocol.yaml
@@ -1,18 +1,18 @@
name: ledger_api
author: fetchai
-version: 0.3.0
+version: 0.4.0
type: protocol
description: A protocol for ledger APIs requests and responses.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmSoo6ds8mKhtoG8CBbu9rb9yj7sqeeuBfcU7CLj584uRX
+ README.md: QmRxa7K9cDbKyBMK5yWuoAPc3dKB1jinUv78dkbPJfstjM
__init__.py: QmX6ta6j6ust7qhVk1kZygzZK3gTTg7hSCBbSMKUxJgWgG
custom_types.py: QmWRrvFStMhVJy8P2WD6qjDgk14ZnxErN7XymxUtof7HQo
dialogues.py: QmRtWkAfR9WTvygMJ36R758RzdY2mGQs2fgtHCfjxmeaHy
ledger_api.proto: QmfLcv7jJcGJ1gAdCMqsyxJcRud7RaTWteSXHL5NvGuViP
ledger_api_pb2.py: QmQhM848REJTDKDoiqxkTniChW8bNNm66EtwMRkvVdbMry
- message.py: QmNnb5uwsWZjQizDnuTwCAw1sGmmiARLeesTVDE4nLJi7j
+ message.py: QmQz3Kf3JqQ8Zv7Y2TM8HQ3vHASn6EPc2zfdF9EfXZERNi
serialization.py: QmRuTqH9t9JtsnpWX5wpC438DdRxWKiqAB2u9fvQ2oy1GE
fingerprint_ignore_patterns: []
dependencies:
diff --git a/packages/fetchai/protocols/ml_trade/README.md b/packages/fetchai/protocols/ml_trade/README.md
index 068774302c..0a2dbf8448 100644
--- a/packages/fetchai/protocols/ml_trade/README.md
+++ b/packages/fetchai/protocols/ml_trade/README.md
@@ -10,7 +10,7 @@ This is a protocol for trading data for training and prediction purposes.
---
name: ml_trade
author: fetchai
-version: 0.5.0
+version: 0.6.0
description: A protocol for trading data for training and prediction purposes.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
diff --git a/packages/fetchai/protocols/ml_trade/message.py b/packages/fetchai/protocols/ml_trade/message.py
index 7cf62d08ed..b4cd6b46a3 100644
--- a/packages/fetchai/protocols/ml_trade/message.py
+++ b/packages/fetchai/protocols/ml_trade/message.py
@@ -40,7 +40,7 @@
class MlTradeMessage(Message):
"""A protocol for trading data for training and prediction purposes."""
- protocol_id = ProtocolId.from_str("fetchai/ml_trade:0.5.0")
+ protocol_id = ProtocolId.from_str("fetchai/ml_trade:0.6.0")
Description = CustomDescription
diff --git a/packages/fetchai/protocols/ml_trade/protocol.yaml b/packages/fetchai/protocols/ml_trade/protocol.yaml
index b519b0114f..fc84c1f186 100644
--- a/packages/fetchai/protocols/ml_trade/protocol.yaml
+++ b/packages/fetchai/protocols/ml_trade/protocol.yaml
@@ -1,16 +1,16 @@
name: ml_trade
author: fetchai
-version: 0.5.0
+version: 0.6.0
type: protocol
description: A protocol for trading data for training and prediction purposes.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmSRtzACMh3x3LSjYqWXWTpYpE4C7G8EHbW4zQQoMFFZ4K
+ README.md: QmdL1CDvD1fQH112oqefGxiTB4RXRxRYr9vfZMXEZDS1Dj
__init__.py: QmcCS9uUQTTS2w85dTNiN5rQ14wyBhmBkr7pPPPcbLphcn
custom_types.py: QmPa6mxbN8WShsniQxJACfzAPRjGzYLbUFGoVU4N9DewUw
dialogues.py: QmVvP34aKWEtHrKmccNMvEdDnx5B7xpE5aEGzr6GU2u8UK
- message.py: QmZ8HzNw27TdxoZBHRf1YJheACo7kU6n1497DYgxjbCwZu
+ message.py: Qmb1Z2wXMR1SVGFVezRaPogyhnmvrGmdY9ZEU4pr2vRKiq
ml_trade.proto: QmeB21MQduEGQCrtiYZQzPpRqHL4CWEkvvcaKZ9GsfE8f6
ml_trade_pb2.py: QmZVvugPysR1og6kWCJkvo3af2s9pQRHfuj4BptE7gU1EU
serialization.py: QmTamQzo8ZNM6T7QnsA7qNzs2uJ7CHTUczzCsHwU9Q6Z5K
diff --git a/packages/fetchai/protocols/oef_search/README.md b/packages/fetchai/protocols/oef_search/README.md
index 9ab8c67a1f..4972b642e2 100644
--- a/packages/fetchai/protocols/oef_search/README.md
+++ b/packages/fetchai/protocols/oef_search/README.md
@@ -11,7 +11,7 @@ It allows for registering of agents and services, and searching of agents and se
---
name: oef_search
author: fetchai
-version: 0.6.0
+version: 0.7.0
description: A protocol for interacting with an OEF search service.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
diff --git a/packages/fetchai/protocols/oef_search/message.py b/packages/fetchai/protocols/oef_search/message.py
index 824e80d505..75bb56b7a7 100644
--- a/packages/fetchai/protocols/oef_search/message.py
+++ b/packages/fetchai/protocols/oef_search/message.py
@@ -46,7 +46,7 @@
class OefSearchMessage(Message):
"""A protocol for interacting with an OEF search service."""
- protocol_id = ProtocolId.from_str("fetchai/oef_search:0.6.0")
+ protocol_id = ProtocolId.from_str("fetchai/oef_search:0.7.0")
AgentsInfo = CustomAgentsInfo
diff --git a/packages/fetchai/protocols/oef_search/protocol.yaml b/packages/fetchai/protocols/oef_search/protocol.yaml
index 4ab18b4d2f..ebf61fc6c5 100644
--- a/packages/fetchai/protocols/oef_search/protocol.yaml
+++ b/packages/fetchai/protocols/oef_search/protocol.yaml
@@ -1,16 +1,16 @@
name: oef_search
author: fetchai
-version: 0.6.0
+version: 0.7.0
type: protocol
description: A protocol for interacting with an OEF search service.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmaGSTqxvQFKccBnLovhBbfSH3C3Sorrj7kFyZqW9qptLa
+ README.md: QmUYKYTTvPQWDHgB2N8LLKquwgGEA8vEoDYroCEEcGSugy
__init__.py: Qmdr5ks5X4YtnpH6yKUcNu9uouyv3EGmrKFhyvNH7ZBjvT
custom_types.py: QmYAkKYj9gGHaij7uTejoJe9KRhNcsU4sJC1utMfhUYhg3
dialogues.py: QmQPLnW3jAs6tLLmhkX4C7texGRHM9bfdjs83dUH5TkJ4v
- message.py: QmWFvjX7spNHQx6QQevBRXmFyJBuenyAPYAjxVLYvKdC7B
+ message.py: QmRTyiB6yaN1rwvZ412dMNdTwRGy3U3HSC4xN8k5La3Nr1
oef_search.proto: QmNU8WsxT6XNFFneKKeDaZkNn3CEFDfZQkmKv9TyhyxzDB
oef_search_pb2.py: QmSAFT1xxYRzJU6h1aFVDuYcx672sZ2vzV6c2ico7f4BLK
serialization.py: QmU3ipyvogbpkFuQki6xqscdiPahDVYw4sBaPHaH3LVvwJ
diff --git a/packages/fetchai/protocols/tac/README.md b/packages/fetchai/protocols/tac/README.md
index 7f10c50f17..286ad842ef 100644
--- a/packages/fetchai/protocols/tac/README.md
+++ b/packages/fetchai/protocols/tac/README.md
@@ -10,7 +10,7 @@ This is a protocol for participating in a Trading Agent Competition (TAC).
---
name: tac
author: fetchai
-version: 0.6.0
+version: 0.7.0
description: The tac protocol implements the messages an AEA needs to participate
in the TAC.
license: Apache-2.0
diff --git a/packages/fetchai/protocols/tac/message.py b/packages/fetchai/protocols/tac/message.py
index 29a6c32f5c..c06c9e6a50 100644
--- a/packages/fetchai/protocols/tac/message.py
+++ b/packages/fetchai/protocols/tac/message.py
@@ -37,7 +37,7 @@
class TacMessage(Message):
"""The tac protocol implements the messages an AEA needs to participate in the TAC."""
- protocol_id = ProtocolId.from_str("fetchai/tac:0.6.0")
+ protocol_id = ProtocolId.from_str("fetchai/tac:0.7.0")
ErrorCode = CustomErrorCode
diff --git a/packages/fetchai/protocols/tac/protocol.yaml b/packages/fetchai/protocols/tac/protocol.yaml
index d33f7cc5c9..cc916bf083 100644
--- a/packages/fetchai/protocols/tac/protocol.yaml
+++ b/packages/fetchai/protocols/tac/protocol.yaml
@@ -1,17 +1,17 @@
name: tac
author: fetchai
-version: 0.6.0
+version: 0.7.0
type: protocol
description: The tac protocol implements the messages an AEA needs to participate
in the TAC.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmVhm6VBbggxjTe3PEhCBfTomWekNa5buYy3sY7YYN6Er6
+ README.md: QmcUpwxG2ZzdwMeMGGTVyJgsRVbrCUKtYB2qqLy4YsuBez
__init__.py: QmSAC7PGra9fig8RhhF1j3XEVpgie9UZNNYPc2AB9Kx9xJ
custom_types.py: QmXQATfnvuCpt4FicF4QcqCcLj9PQNsSHjCBvVQknWpyaN
dialogues.py: QmTxHrcGujP1RUYvfJygZyQoUwmDg2GBWfmbR3tWUSbyop
- message.py: QmfNRtqEpLyAf4knnTecsiNxzehqwWjk8agfg9oe2XvCt3
+ message.py: QmWD79nj4kcMPN9xuDkgSDXnwgDnT6XE1WcdfBKsKKPqTP
serialization.py: QmTk2Jp19dQ4SJdjSHAr8wbxw4rQSMheSuf1XzXG8CaoB4
tac.proto: QmdpPZNhUW593qVNVoSTWZgd9R69bmBbw6Y9xjzYpvuDvV
tac_pb2.py: QmUwW3kixKwD2o1RRdq4NoNoihPb5BXKKRngWXztq32fea
diff --git a/packages/fetchai/skills/aries_alice/skill.yaml b/packages/fetchai/skills/aries_alice/skill.yaml
index 10baa733fa..ac08ddc5a1 100644
--- a/packages/fetchai/skills/aries_alice/skill.yaml
+++ b/packages/fetchai/skills/aries_alice/skill.yaml
@@ -1,6 +1,6 @@
name: aries_alice
author: fetchai
-version: 0.7.0
+version: 0.8.0
type: skill
description: The aries_alice skill implements the alice player in the aries cloud
agent demo
@@ -16,9 +16,9 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/http:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/http:0.6.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
alice:
diff --git a/packages/fetchai/skills/aries_faber/skill.yaml b/packages/fetchai/skills/aries_faber/skill.yaml
index 1841b6823a..97410686ed 100644
--- a/packages/fetchai/skills/aries_faber/skill.yaml
+++ b/packages/fetchai/skills/aries_faber/skill.yaml
@@ -1,6 +1,6 @@
name: aries_faber
author: fetchai
-version: 0.6.0
+version: 0.7.0
type: skill
description: The aries_faber skill implements the faber player in the aries cloud
agent demo
@@ -16,9 +16,9 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/http:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/http:0.6.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
faber:
diff --git a/packages/fetchai/skills/carpark_client/skill.yaml b/packages/fetchai/skills/carpark_client/skill.yaml
index 9b81cf6b92..97a1234d50 100644
--- a/packages/fetchai/skills/carpark_client/skill.yaml
+++ b/packages/fetchai/skills/carpark_client/skill.yaml
@@ -16,10 +16,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_buyer:0.12.0
behaviours:
diff --git a/packages/fetchai/skills/carpark_detection/skill.yaml b/packages/fetchai/skills/carpark_detection/skill.yaml
index 57a671e830..1aaadad48e 100644
--- a/packages/fetchai/skills/carpark_detection/skill.yaml
+++ b/packages/fetchai/skills/carpark_detection/skill.yaml
@@ -18,10 +18,10 @@ fingerprint_ignore_patterns:
- temp_files_placeholder/*
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_seller:0.13.0
behaviours:
diff --git a/packages/fetchai/skills/echo/skill.yaml b/packages/fetchai/skills/echo/skill.yaml
index e83fba6fd6..977f02e359 100644
--- a/packages/fetchai/skills/echo/skill.yaml
+++ b/packages/fetchai/skills/echo/skill.yaml
@@ -1,6 +1,6 @@
name: echo
author: fetchai
-version: 0.7.0
+version: 0.8.0
type: skill
description: The echo skill implements simple echo functionality.
license: Apache-2.0
@@ -14,7 +14,7 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills: []
behaviours:
echo:
diff --git a/packages/fetchai/skills/erc1155_client/skill.yaml b/packages/fetchai/skills/erc1155_client/skill.yaml
index 8f419f4185..8825d73db8 100644
--- a/packages/fetchai/skills/erc1155_client/skill.yaml
+++ b/packages/fetchai/skills/erc1155_client/skill.yaml
@@ -18,11 +18,11 @@ contracts:
- fetchai/erc1155:0.10.0
protocols:
- fetchai/contract_api:0.5.0
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
skills: []
behaviours:
search:
diff --git a/packages/fetchai/skills/erc1155_deploy/skill.yaml b/packages/fetchai/skills/erc1155_deploy/skill.yaml
index a69c4d2d60..3023314d4a 100644
--- a/packages/fetchai/skills/erc1155_deploy/skill.yaml
+++ b/packages/fetchai/skills/erc1155_deploy/skill.yaml
@@ -18,11 +18,11 @@ contracts:
- fetchai/erc1155:0.10.0
protocols:
- fetchai/contract_api:0.5.0
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
skills: []
behaviours:
service_registration:
diff --git a/packages/fetchai/skills/generic_buyer/skill.yaml b/packages/fetchai/skills/generic_buyer/skill.yaml
index 3d6c91eef6..786d8ef236 100644
--- a/packages/fetchai/skills/generic_buyer/skill.yaml
+++ b/packages/fetchai/skills/generic_buyer/skill.yaml
@@ -15,10 +15,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
search:
diff --git a/packages/fetchai/skills/generic_seller/skill.yaml b/packages/fetchai/skills/generic_seller/skill.yaml
index 942e3dfa32..2a435a6efc 100644
--- a/packages/fetchai/skills/generic_seller/skill.yaml
+++ b/packages/fetchai/skills/generic_seller/skill.yaml
@@ -16,10 +16,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
service_registration:
diff --git a/packages/fetchai/skills/http_echo/skill.yaml b/packages/fetchai/skills/http_echo/skill.yaml
index 1866ee9702..d9ee0961c5 100644
--- a/packages/fetchai/skills/http_echo/skill.yaml
+++ b/packages/fetchai/skills/http_echo/skill.yaml
@@ -1,6 +1,6 @@
name: http_echo
author: fetchai
-version: 0.6.0
+version: 0.7.0
type: skill
description: The http echo skill prints out the content of received http messages
and responds with success.
@@ -14,7 +14,7 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/http:0.5.0
+- fetchai/http:0.6.0
skills: []
behaviours: {}
handlers:
diff --git a/packages/fetchai/skills/ml_data_provider/skill.yaml b/packages/fetchai/skills/ml_data_provider/skill.yaml
index a4cdf26aed..ae4d9a6241 100644
--- a/packages/fetchai/skills/ml_data_provider/skill.yaml
+++ b/packages/fetchai/skills/ml_data_provider/skill.yaml
@@ -16,10 +16,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/ledger_api:0.3.0
-- fetchai/ml_trade:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/ledger_api:0.4.0
+- fetchai/ml_trade:0.6.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_seller:0.13.0
behaviours:
diff --git a/packages/fetchai/skills/ml_train/skill.yaml b/packages/fetchai/skills/ml_train/skill.yaml
index 5f20f79b17..1d84f5e241 100644
--- a/packages/fetchai/skills/ml_train/skill.yaml
+++ b/packages/fetchai/skills/ml_train/skill.yaml
@@ -19,10 +19,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/ledger_api:0.3.0
-- fetchai/ml_trade:0.5.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/ledger_api:0.4.0
+- fetchai/ml_trade:0.6.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_buyer:0.12.0
behaviours:
diff --git a/packages/fetchai/skills/simple_service_registration/skill.yaml b/packages/fetchai/skills/simple_service_registration/skill.yaml
index ebd93696c0..83bb6ec2e4 100644
--- a/packages/fetchai/skills/simple_service_registration/skill.yaml
+++ b/packages/fetchai/skills/simple_service_registration/skill.yaml
@@ -15,7 +15,7 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
service:
diff --git a/packages/fetchai/skills/tac_control/skill.yaml b/packages/fetchai/skills/tac_control/skill.yaml
index 8c6978739b..d79d945a4f 100644
--- a/packages/fetchai/skills/tac_control/skill.yaml
+++ b/packages/fetchai/skills/tac_control/skill.yaml
@@ -1,6 +1,6 @@
name: tac_control
author: fetchai
-version: 0.7.0
+version: 0.8.0
type: skill
description: The tac control skill implements the logic for an AEA to control an instance
of the TAC.
@@ -18,8 +18,8 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
-- fetchai/tac:0.6.0
+- fetchai/oef_search:0.7.0
+- fetchai/tac:0.7.0
skills: []
behaviours:
tac:
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index 360abaaf9b..3c667d87a6 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -18,8 +18,8 @@ fingerprint_ignore_patterns: []
contracts:
- fetchai/erc1155:0.10.0
protocols:
-- fetchai/oef_search:0.6.0
-- fetchai/tac:0.6.0
+- fetchai/oef_search:0.7.0
+- fetchai/tac:0.7.0
skills: []
behaviours:
contract:
diff --git a/packages/fetchai/skills/tac_negotiation/skill.yaml b/packages/fetchai/skills/tac_negotiation/skill.yaml
index 267b3e3a04..ff609eb1bd 100644
--- a/packages/fetchai/skills/tac_negotiation/skill.yaml
+++ b/packages/fetchai/skills/tac_negotiation/skill.yaml
@@ -19,8 +19,8 @@ fingerprint_ignore_patterns: []
contracts:
- fetchai/erc1155:0.10.0
protocols:
-- fetchai/fipa:0.6.0
-- fetchai/oef_search:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/tac_participation:0.9.0
behaviours:
diff --git a/packages/fetchai/skills/tac_participation/skill.yaml b/packages/fetchai/skills/tac_participation/skill.yaml
index 74cd860e52..018167aae6 100644
--- a/packages/fetchai/skills/tac_participation/skill.yaml
+++ b/packages/fetchai/skills/tac_participation/skill.yaml
@@ -17,8 +17,8 @@ fingerprint_ignore_patterns: []
contracts:
- fetchai/erc1155:0.10.0
protocols:
-- fetchai/oef_search:0.6.0
-- fetchai/tac:0.6.0
+- fetchai/oef_search:0.7.0
+- fetchai/tac:0.7.0
skills: []
behaviours:
tac_search:
diff --git a/packages/fetchai/skills/thermometer/skill.yaml b/packages/fetchai/skills/thermometer/skill.yaml
index 1e1194ec55..cfd58afabc 100644
--- a/packages/fetchai/skills/thermometer/skill.yaml
+++ b/packages/fetchai/skills/thermometer/skill.yaml
@@ -15,10 +15,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_seller:0.13.0
behaviours:
diff --git a/packages/fetchai/skills/thermometer_client/skill.yaml b/packages/fetchai/skills/thermometer_client/skill.yaml
index 8f53b3b101..cdcb6fe238 100644
--- a/packages/fetchai/skills/thermometer_client/skill.yaml
+++ b/packages/fetchai/skills/thermometer_client/skill.yaml
@@ -16,10 +16,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_buyer:0.12.0
behaviours:
diff --git a/packages/fetchai/skills/weather_client/skill.yaml b/packages/fetchai/skills/weather_client/skill.yaml
index c0f0253f86..074dc33692 100644
--- a/packages/fetchai/skills/weather_client/skill.yaml
+++ b/packages/fetchai/skills/weather_client/skill.yaml
@@ -15,10 +15,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_buyer:0.12.0
behaviours:
diff --git a/packages/fetchai/skills/weather_station/skill.yaml b/packages/fetchai/skills/weather_station/skill.yaml
index 4dc6ece6a5..fde55e17ea 100644
--- a/packages/fetchai/skills/weather_station/skill.yaml
+++ b/packages/fetchai/skills/weather_station/skill.yaml
@@ -19,10 +19,10 @@ fingerprint_ignore_patterns:
- '*.db'
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills:
- fetchai/generic_seller:0.13.0
behaviours:
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 06d740acae..24e36d42a3 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -1,72 +1,72 @@
-fetchai/agents/aries_alice,QmSzfcX1hnJ4raTS4yREwSEKQastCHM4Z9a6irY5Es3Toc
-fetchai/agents/aries_faber,QmaJEpXeh1rKsYyggoj5L2S3N37AAJdMuZxVQExyyKUDqx
-fetchai/agents/car_data_buyer,QmYNak5SGrrfkfp28Zm2osp5xKeFTBJPTPXruh2zTpcYH4
-fetchai/agents/car_detector,QmPDuvJLVi1kfobAEnHMouobZCBniwrxRnZiGRQt5KJHYi
-fetchai/agents/erc1155_client,QmQQmTrnLuVAqeez4vuL1pFLT8sNtHJWZCp9NTXcJvcupS
-fetchai/agents/erc1155_deployer,QmVa7cpE6dzhRA9RRnLvcXjftUs4ELDxh5MsvsZBVsK9BL
-fetchai/agents/generic_buyer,QmSsZKZos8qgQFBkqLdPb12dBXKGsfrkVMs6nuqJswJvx2
-fetchai/agents/generic_seller,QmdRy5T4qCF6njPBk7ZhWmKJrLJAte2aXCHsAURNXpb4R2
-fetchai/agents/gym_aea,QmUtKrUwVt63iKZxjncrBSz6eZ9g4RGWFM49qtA4JtFMCm
-fetchai/agents/ml_data_provider,QmQtHQkYgNivnP1WuBbpnRLFKtjZbhRyeZFBW64GXXqhEy
-fetchai/agents/ml_model_trainer,Qmbk9YkJ7AX4VPcxS1anFU1sEgcU8oZn5fbSv2KuErBWMW
-fetchai/agents/my_first_aea,QmdYThnxTmqZizzvJvYH1HmnT5HKn5MsprkkHA8k3dgDPZ
-fetchai/agents/simple_service_registration,QmWKm97p72CSV9A9i4yrVi5ucWhw2jqAurbBE8xkuwHLSQ
-fetchai/agents/tac_controller,QmSLFA3m31SB45De8SEYixvAGkPcpv6dqtKKkssTW97HpB
-fetchai/agents/tac_controller_contract,QmXY3FHDmK8RYh6Hb4aodxzjuG1d5iggn6UtnoJph8wvVE
-fetchai/agents/tac_participant,Qme3EP7MYHKre7GK2X5jZ4Pq973DaJPfpPXZX64gtp5iUk
-fetchai/agents/thermometer_aea,QmZzUqFVaDNGfwPnq5EvfPKNoMSfGzgpBic2z8HHWfu1RE
-fetchai/agents/thermometer_client,QmfMjh5gCDrdipCDYYrAr7jRDXJ2CpfWFij9t6J4EKdXYT
-fetchai/agents/weather_client,QmXyXQHxeJyBFSXLU2GZnV49t17iwnNLWWpUEFqMTAb8AE
-fetchai/agents/weather_station,QmW4kSbF5eKuh4itMJ8xKonaPejutaMp2GyobcN7V4zJR8
+fetchai/agents/aries_alice,Qme8sHgd9CZbBEbnS9zwDs53mYZM4EDpJf5RzQnE2QMy35
+fetchai/agents/aries_faber,QmVQXALXYg5M1Qbqznc4PqM5i4jDt8rFeHvDrq7DcoJx3B
+fetchai/agents/car_data_buyer,QmWk7So9UabsjTEKCkecYN9xwkwJxm4m78GA5VRYcWsQwe
+fetchai/agents/car_detector,QmbUnQ95vMmrL7ootzabP5hKr1iR2srJy3QWg6H2wr9Qib
+fetchai/agents/erc1155_client,QmYUsNAEr2dmx6CP9Jkd33eJMuSQL1uiBADivuUzM8tgiE
+fetchai/agents/erc1155_deployer,QmcbNaXp8vN2Vzbqy4vSKXj27WJK1sBcRf2HtL4eacTnac
+fetchai/agents/generic_buyer,Qme5rHfbeEhmia2RM4vjbiwk1h1o2JiiyyfYZze9jG3mUD
+fetchai/agents/generic_seller,QmPVuku1Cefn76S8rN6GsqdVz12AhbcK6hFMdDMYxsjiAM
+fetchai/agents/gym_aea,QmPP3rtaUY3jdzn1HXjV4dPyY2wYetbbNCqFCQbzbH1GRS
+fetchai/agents/ml_data_provider,QmZFTtD54jcwY8ozmhsdHHZqc2RNX9FZ8dfV8SgYJE9QYM
+fetchai/agents/ml_model_trainer,QmeZmVsNLUw7TP73s5cSomPnwggcrimXHh1RhrPRUDkoQ3
+fetchai/agents/my_first_aea,QmcHnFYQCyXnAM2pN2M4HqLNGJpWApUP7PuiKaPcLkxbas
+fetchai/agents/simple_service_registration,QmWtA9eDYnGKkg5hov887LRJSXTXovb9pp4NJzU7JMq5Lg
+fetchai/agents/tac_controller,QmaG56sZaJRm8DwJXXt9Ci18Va8NfXx6v8vEGKPJngKL4q
+fetchai/agents/tac_controller_contract,QmdaEL2THaQNNvvDqEhB3iN2mZva1g7RdyhhWV5mTDrbus
+fetchai/agents/tac_participant,QmQxN75ZFVEgizNHa3sqd2zHSnmPvRwS8PCv5FAsJBDnZw
+fetchai/agents/thermometer_aea,QmQ8KgTrt5fH8ZRDpioKGmeyUyc2EUkan4D5KzoFnCwxcG
+fetchai/agents/thermometer_client,QmUY6rmZnufWWmwfSi1m5gR6vD1ZowXpchpUJXgAH6xdNP
+fetchai/agents/weather_client,QmeMHc9hqpciJiRWrAJJszvyjTCs9rgsKC5S1nJRKV9sxQ
+fetchai/agents/weather_station,QmdJcUYuaTbb2J5k9jPcG215bJhKFQUQqJPhiaNoirijJ1
fetchai/connections/gym,Qmack3EaCW6ARrHrtCnJmL3kR2xrHutJmgD8uoRVGFz6kH
-fetchai/connections/http_client,QmfSuWhrseBCVcmzwKmqFDC6qX3ryFzfx2uuUTb8HPGuEd
-fetchai/connections/http_server,QmcqvHZbzGX1zdfwVTpqq5j6ugJhpuKEcrWkCW6JJrLJSC
-fetchai/connections/ledger,Qmb7dP2cQcYdYMthh5P7EwipNops9CKn2N3TBGNgwNnA2u
-fetchai/connections/local,Qmconur9cKrzYY1113AukHUPhgxUjzFrHExWnVpPBV8cRx
-fetchai/connections/oef,QmNpYX8XX6uXbFmBDi3s3W9qA48bRcrJatqSHAXDjhLwax
+fetchai/connections/http_client,QmaCa98anLuMAduNWtnApEwLWBcqdVkNBREBZ9T5VPSaUm
+fetchai/connections/http_server,QmT6JV2sB1rv7XZgx1bEpMjfQJAtpq775D2n8yvzKzSXYK
+fetchai/connections/ledger,QmYzBWDgAETzBr8PGPyKvdDMJMGPSo3KFiKVP9MmkVGfd9
+fetchai/connections/local,QmNXMDuB7vfGrhv2Q4R8REDicSUgXfVPd7x1tAP3847jsr
+fetchai/connections/oef,QmT6nbEYgjHPTwoXqV5FNeg7SUaraXGQGUhGeVGEhqXVDg
fetchai/connections/p2p_libp2p,QmbPgTY8am7PgLoP3ksaHyuwZzfFGXN4cBrvjV9byramEh
fetchai/connections/p2p_libp2p_client,QmSbfL2DT9L1oooKn2pme1tjivEzkzaiRqJ4zahB4Jb27b
-fetchai/connections/p2p_stub,QmaP81r3ZCqKdL925fbRB8YKxHYaVBR1yW3iwzaErUYDSC
+fetchai/connections/p2p_stub,QmecGYtXsb7HA2dSWrw2ARNTPFqZsKXAbVroBo57cdUQSG
fetchai/connections/scaffold,QmNUta43nLexAHaXLgmLQYEjntLXSV6MLNvc6Q2CTx7eBS
-fetchai/connections/soef,QmNLzoPJXUrFLoTKSy8WgF1ivedTyXrKXwd4tmA8mxn7As
+fetchai/connections/soef,QmRTHKvUhxiGjs3wWZKadWCD5fq6zG2m4sdhmyEbvADEaR
fetchai/connections/stub,QmSuUAA2k1E1M9dpeAgkWpfKdssjqghSDfFfrQzC9ZLKbD
-fetchai/connections/tcp,QmQZBeN6EqH61GMLwuHqAw3LzdyKi7uj7zJtJ5ekYDpY4n
-fetchai/connections/webhook,QmXLbSSUSbsgqk3Zwo7sfBob5nKL6MLA4MCTQ3BXA2Bex3
+fetchai/connections/tcp,QmPADQqZJQ4cw1ecdMC2wR7NwFCdk7MYzvmyP62nbfGk7E
+fetchai/connections/webhook,QmWcm3WGxcm5JvhuYRyauQp5wmzFAkV61e2aYpDvYmNvWd
fetchai/contracts/erc1155,QmWu22zW9AVMBVySwF413JMiT5dcWsLsU2gk1KvFYWAwPq
fetchai/contracts/scaffold,QmTKkXifQKq5sTVdVKeD9UGnDwdJoEAoJDjY6qUPt9Bsv2
fetchai/protocols/contract_api,QmZbbYPdpewfBfLWBQNGzjYr45ZDYJ5PqL5TMrMxa7PrjZ
-fetchai/protocols/default,QmaU6VsHxLfrFxcnBAzXNmYA7yQ23kRY1Ddq5pq4NsVhyu
-fetchai/protocols/fipa,QmYtTLb4Gk7eHo2Q8VwYZomTdUoa5N37a22Dnh4bjpTvxt
+fetchai/protocols/default,QmNjse6y7aBhtT2WZh3t7JYuGb4dYd2BmJzcYK3BeX641t
+fetchai/protocols/fipa,QmXdUfENAXFUntcybMjWvo816ccxG1Rf4DEv41TQVC85XM
fetchai/protocols/gym,QmWv9Hi8cDypDYPLJTbbgXGmw6jvzZLUB2idbMTFdbDDqM
-fetchai/protocols/http,QmWDjfvkAGGt6eA1Ja6sXeBeGqE3vtNbGBwnVhGPJrEq4g
-fetchai/protocols/ledger_api,QmQERKQhT9JQNvy6vvT2xsQpv4GnEdvwGdFx7J6AY1j3hw
-fetchai/protocols/ml_trade,QmVrv8SnxKoRM5pZLWNB3tZP9VggvDK4ygDqy6DmweFKQH
-fetchai/protocols/oef_search,QmYPsjL1m3KUbT9UFSUickf19ydK6DLTNXT1sqtftJA1py
+fetchai/protocols/http,QmePja5ZBEv6nN7FfnURzgPa445vK9GQ2rdBPugZMVbkWR
+fetchai/protocols/ledger_api,QmS1zebL2Q6qPL8B6tD9iCLmXSCgAXSnCFmfeHAqGDdWa3
+fetchai/protocols/ml_trade,QmZoHGtvrAr5z4FrL7BTyKew2eQBudCJXwTpPciwrmcpuP
+fetchai/protocols/oef_search,QmWiRygk9JHtCJ6FbSK49uwkCzsSu6wJVqc27iQEwGphFR
fetchai/protocols/scaffold,QmaQJxMae5XaHKDc838pcGEKhhYSUyKHGWiMfU6zEcVHsy
-fetchai/protocols/signing,QmaaX5WnjhFE4BKR99B2KN3yY9DmnHnavbUpzb8EQ612T3
-fetchai/protocols/state_update,QmeczT1eBFtY2Kr9ZcpzATJRmjDgqKSGhi3x1arCbhXTb6
-fetchai/protocols/tac,QmYryedEw85W99BYM8exZSERbkzHXPag6hp6HQtmmJppJ7
-fetchai/skills/aries_alice,QmXFSjt8FSHMnw4yjsmw4SVxKRj9N1i5aPcnmPpyoh3Bu1
-fetchai/skills/aries_faber,QmX3k9N3VmUE8bYaZ4KCq1Ny3ANTVw7sN8nuCRLDZcTTZK
-fetchai/skills/carpark_client,QmdfgS34Q7mo7yZ4uThZePudEoPgsmybC66YdVZAXYEybv
-fetchai/skills/carpark_detection,QmXwpLqW72SNbfEXrkHXCq6wucmsx6eTUTn9aZzXJaB8Gw
-fetchai/skills/echo,QmPu8BeKw5DRYdjHqVWqQnXjW1ZgRBjVthGmVerHLBmJPA
-fetchai/skills/erc1155_client,QmPceeYCnt1PC9dDv9EN9dHfzfFUESSZdEsKGTcesEVpsR
-fetchai/skills/erc1155_deploy,QmYyerCPVQg7zUagT6FxZEthdSFrLXKMG5LtJbCYnRPALN
-fetchai/skills/error,QmanfpyCmvUkqG9xsEyWULvi1ZZzqvggvs9LnQvSjuRhLb
-fetchai/skills/generic_buyer,Qmdx6M3y9gRCPJv5Lp8YnJP9nqJCgYAyp4gggqw9V85rY3
-fetchai/skills/generic_seller,Qmf1SYiBVfF6NYSir7ES9reSBpAGqtN9GkULH3fpBjatNZ
+fetchai/protocols/signing,Qmazm8bkwpPVV7BiJZx2Aha96AcmAxwiYbjgYGwvcgXGYi
+fetchai/protocols/state_update,QmS1xuSYYgHkQq8Ww2btsS88rTXXjhchyStzUfcWYQKNda
+fetchai/protocols/tac,QmY6N5spfcwikq3pb99mdYAEieECqmtawbcitGJRicDh7H
+fetchai/skills/aries_alice,QmefZJ27H36RZYgA6eEcnbv8yNPyf3YYXnBm5E88C8xBLQ
+fetchai/skills/aries_faber,QmYAQ8gVsokPsXHd7RDXb8KCkmH7XpB8JC7VMx3QrJX3Uh
+fetchai/skills/carpark_client,QmYjZXvq2h2DCXZF2ba9W5cvJAvsRFvBrw7h7EwcvWThfW
+fetchai/skills/carpark_detection,QmRLr3ALHF1iLFFpUmXHKZmMwbFz5vfph8qCv7rKQpte2r
+fetchai/skills/echo,QmYKGMNs5NU7ycWXRBQnKrfBcg5HPnUnH13K1YFnPLQgW6
+fetchai/skills/erc1155_client,Qmd6KJbis7Me39teeHA8y3JZHQrS1hjovMxhqiwViRZhgc
+fetchai/skills/erc1155_deploy,QmYbL8hgHTsEh7PkUJhK6pfENPai5XDtq6eH2RWQsARMKS
+fetchai/skills/error,QmTFECCHQHaSN3wP16EYgKeqgSgxBvfCRwX7F5uvxfkN3a
+fetchai/skills/generic_buyer,QmXFFS6V4ZaNWNqVdx5TnaqU5DizQDd9aWjbE9ACqCZsEU
+fetchai/skills/generic_seller,QmQivEfxdFGkWmaw9iMHJmEmgVv1TAAqihNT9CM8x3XzV2
fetchai/skills/gym,QmUqB5EJafEGWX5xkTngAgXW2857RnCEk6St2HE5x9hgtZ
-fetchai/skills/http_echo,QmQk7NbMpMRT3GEKtPVkWFv2UzwJHajU27qQV9UHKV1xPz
-fetchai/skills/ml_data_provider,QmZS1fm9ZCmZ1quW1LH2K9tdBPWL2woHBdJ1N912vL7BsV
-fetchai/skills/ml_train,QmRgu8MwTF8CWfGTudkRPc6bGkQy3P8tLNmWYXCLcJiehg
+fetchai/skills/http_echo,QmQDMH3L5F5AzTDurwZkSd8S4LCyPVJhtrqrXe1KCa9NGk
+fetchai/skills/ml_data_provider,QmaKyLjyvcj35bCHaKKo15MeF7k48hKPCfFbrtvXCogYwV
+fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
-fetchai/skills/simple_service_registration,QmR3SLTfRxyqUQGpBkq3nGbB6Cfm9fXzXgaknJDGNe1Mkr
-fetchai/skills/tac_control,QmWtrSiEfdPocyDFHwADj2xmPCeP29iFhdcbfgWrRfT68b
-fetchai/skills/tac_control_contract,QmbhmoLPCWY7sKBDnN3qVxtnzsE8tXCJFEZsXyJBKwnfYL
-fetchai/skills/tac_negotiation,QmYHjhKPCNQ83gsthbW7qYygrLzuFUy3tiqwhwtieHdXEu
-fetchai/skills/tac_participation,Qmdh6sM8GPf53Kbr9HGPBvUD5goz4fYnFLwLLcdqo5pedn
-fetchai/skills/thermometer,Qmf2ntUbVmfawJw8AU2nfUf2m9Nrn8Qg6CQZNg1ECrcitc
-fetchai/skills/thermometer_client,QmP5vL38Nw4pkJ6y1UVvMwmBWazenMzSs2afHEfTzNqLEb
-fetchai/skills/weather_client,QmYDzApib8cgGnaQVfsibV7sfKNQzrDTeTFiYAakfUyoSb
-fetchai/skills/weather_station,QmXF23jHpe56wXr8HfBUgYBR63zRaHFsLkCWaWfXvb2mHi
+fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
+fetchai/skills/tac_control,QmP1T3wDa1e7Q692KkBuqtws9M2da3kdn5dNkB1WNPemuq
+fetchai/skills/tac_control_contract,QmSn9k1rLmfoq2wtKpQqfnSiKpka6pJ23pATsG4bw63Eh9
+fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
+fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
+fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
+fetchai/skills/thermometer_client,QmXBkiJU23UVygpX5Zz34DaCNiKKGxkgJMs3RfLEPLSdTH
+fetchai/skills/weather_client,QmWohsaia5um76sce6gXN9jMeuHve26v6dm4xWHdwRaGA3
+fetchai/skills/weather_station,QmdcFK1rBSMbNVLXLwFyNizCfa77xUCUkEeBpvJChQurDV
diff --git a/tests/conftest.py b/tests/conftest.py
index 8e125d7ae3..6eda95ebaa 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -198,7 +198,7 @@
UNKNOWN_SKILL_PUBLIC_ID = PublicId("unknown_author", "unknown_skill", "0.1.0")
LOCAL_CONNECTION_PUBLIC_ID = PublicId("fetchai", "local", "0.1.0")
P2P_CLIENT_CONNECTION_PUBLIC_ID = PublicId("fetchai", "p2p_client", "0.1.0")
-HTTP_CLIENT_CONNECTION_PUBLIC_ID = PublicId.from_str("fetchai/http_client:0.8.0")
+HTTP_CLIENT_CONNECTION_PUBLIC_ID = PublicId.from_str("fetchai/http_client:0.9.0")
HTTP_PROTOCOL_PUBLIC_ID = PublicId("fetchai", "http", "0.1.0")
STUB_CONNECTION_PUBLIC_ID = DEFAULT_CONNECTION
DUMMY_PROTOCOL_PUBLIC_ID = PublicId("dummy_author", "dummy", "0.1.0")
diff --git a/tests/data/aea-config.example.yaml b/tests/data/aea-config.example.yaml
index 9ac1a74f99..7c690e3e7e 100644
--- a/tests/data/aea-config.example.yaml
+++ b/tests/data/aea-config.example.yaml
@@ -7,16 +7,16 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/oef:0.9.0
+- fetchai/oef:0.10.0
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
-- fetchai/default:0.5.0
-- fetchai/tac:0.6.0
-- fetchai/fipa:0.6.0
+- fetchai/oef_search:0.7.0
+- fetchai/default:0.6.0
+- fetchai/tac:0.7.0
+- fetchai/fipa:0.7.0
skills:
-- fetchai/echo:0.7.0
-default_connection: fetchai/oef:0.9.0
+- fetchai/echo:0.8.0
+default_connection: fetchai/oef:0.10.0
default_ledger: cosmos
logging_config:
disable_existing_loggers: false
diff --git a/tests/data/aea-config.example_w_keys.yaml b/tests/data/aea-config.example_w_keys.yaml
index dd6aed732d..bb2da28530 100644
--- a/tests/data/aea-config.example_w_keys.yaml
+++ b/tests/data/aea-config.example_w_keys.yaml
@@ -7,16 +7,16 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/oef:0.9.0
+- fetchai/oef:0.10.0
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
-- fetchai/default:0.5.0
-- fetchai/tac:0.6.0
-- fetchai/fipa:0.6.0
+- fetchai/oef_search:0.7.0
+- fetchai/default:0.6.0
+- fetchai/tac:0.7.0
+- fetchai/fipa:0.7.0
skills:
-- fetchai/echo:0.7.0
-default_connection: fetchai/oef:0.9.0
+- fetchai/echo:0.8.0
+default_connection: fetchai/oef:0.10.0
default_ledger: cosmos
logging_config:
disable_existing_loggers: false
diff --git a/tests/data/dependencies_skill/skill.yaml b/tests/data/dependencies_skill/skill.yaml
index ecafdddd87..b8005667c3 100644
--- a/tests/data/dependencies_skill/skill.yaml
+++ b/tests/data/dependencies_skill/skill.yaml
@@ -10,7 +10,7 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills: []
behaviours: {}
handlers: {}
diff --git a/tests/data/dummy_aea/aea-config.yaml b/tests/data/dummy_aea/aea-config.yaml
index 3dc734de13..5c038adebf 100644
--- a/tests/data/dummy_aea/aea-config.yaml
+++ b/tests/data/dummy_aea/aea-config.yaml
@@ -7,17 +7,17 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/local:0.8.0
+- fetchai/local:0.9.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/oef_search:0.7.0
skills:
- dummy_author/dummy:0.1.0
-- fetchai/error:0.5.0
-default_connection: fetchai/local:0.8.0
+- fetchai/error:0.6.0
+default_connection: fetchai/local:0.9.0
default_ledger: cosmos
logging_config:
disable_existing_loggers: false
diff --git a/tests/data/dummy_connection/connection.yaml b/tests/data/dummy_connection/connection.yaml
index c403c1a98c..606cb1eb8c 100644
--- a/tests/data/dummy_connection/connection.yaml
+++ b/tests/data/dummy_connection/connection.yaml
@@ -14,7 +14,7 @@ class_name: DummyConnection
config: {}
excluded_protocols: []
restricted_to_protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
dependencies:
dep1:
version: ==1.0.0
diff --git a/tests/data/dummy_skill/skill.yaml b/tests/data/dummy_skill/skill.yaml
index a90fe3a4b6..4e8dd1ef71 100644
--- a/tests/data/dummy_skill/skill.yaml
+++ b/tests/data/dummy_skill/skill.yaml
@@ -16,7 +16,7 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills: []
behaviours:
dummy:
diff --git a/tests/data/hashes.csv b/tests/data/hashes.csv
index 8e4ba4b05d..f068b6b33c 100644
--- a/tests/data/hashes.csv
+++ b/tests/data/hashes.csv
@@ -1,6 +1,6 @@
-dummy_author/agents/dummy_aea,QmeFNeXh5vk81YwPnPY9qmBA5wrHeH8VsHkDcv6TqHvmFn
-dummy_author/skills/dummy_skill,QmQpimGAQ56nihemchgE29Mfan57YdGixj3kat69FGkrjK
-fetchai/connections/dummy_connection,QmT7zw62fDK1mmwYqTvw4pWqFg8Fc1DYQHUxcxd7sqZiLu
+dummy_author/agents/dummy_aea,QmaFcsXAx9mCjPnYEzATwGJyBFJRgCHftfYmKCfZtSGSLw
+dummy_author/skills/dummy_skill,QmTBZg36AhCipACz8x7eJsA5CHKqUQN1SwT3n8zX6n9XNF
+fetchai/connections/dummy_connection,QmWegP8qsY6Ngdh9xorMDCSA1UBjt4CrrPeVWQqyVfHvob
fetchai/contracts/dummy_contract,QmPMs9VDGZGF8xJ8XBYLVb1xK5XAgiaJr5Gwcq7Vr3TUyu
-fetchai/skills/dependencies_skill,QmaLBgnwTXdTzue7H3UbVuKmPxaqoK4Azpj85tKTdQi29j
+fetchai/skills/dependencies_skill,Qmdn8AArsVSXPut57BXBjkctMYsFYeNnwUuRNe6cuTpbMu
fetchai/skills/exception_skill,QmT2RiM95EVbXTD31zU6pKKoERkrCLuyxpAJfkm3dTsTp2
diff --git a/tests/test_aea.py b/tests/test_aea.py
index 57e5dca9aa..943b7e5be4 100644
--- a/tests/test_aea.py
+++ b/tests/test_aea.py
@@ -160,10 +160,10 @@ def test_react():
builder.add_connection(
Path(ROOT_DIR, "packages", "fetchai", "connections", "local")
)
- local_connection_id = PublicId.from_str("fetchai/local:0.8.0")
+ local_connection_id = PublicId.from_str("fetchai/local:0.9.0")
builder.set_default_connection(local_connection_id)
builder.add_skill(Path(CUR_PATH, "data", "dummy_skill"))
- agent = builder.build(connection_ids=[PublicId.from_str("fetchai/local:0.8.0")])
+ agent = builder.build(connection_ids=[PublicId.from_str("fetchai/local:0.9.0")])
# This is a temporary workaround to feed the local node to the OEF Local connection
# TODO remove it.
local_connection = agent.resources.get_connection(local_connection_id)
@@ -212,10 +212,10 @@ def test_handle():
builder.add_connection(
Path(ROOT_DIR, "packages", "fetchai", "connections", "local")
)
- local_connection_id = PublicId.from_str("fetchai/local:0.8.0")
+ local_connection_id = PublicId.from_str("fetchai/local:0.9.0")
builder.set_default_connection(local_connection_id)
builder.add_skill(Path(CUR_PATH, "data", "dummy_skill"))
- aea = builder.build(connection_ids=[PublicId.from_str("fetchai/local:0.8.0")])
+ aea = builder.build(connection_ids=[PublicId.from_str("fetchai/local:0.9.0")])
# This is a temporary workaround to feed the local node to the OEF Local connection
# TODO remove it.
local_connection = aea.resources.get_connection(local_connection_id)
@@ -310,10 +310,10 @@ def test_initialize_aea_programmatically():
builder.add_connection(
Path(ROOT_DIR, "packages", "fetchai", "connections", "local")
)
- local_connection_id = PublicId.from_str("fetchai/local:0.8.0")
+ local_connection_id = PublicId.from_str("fetchai/local:0.9.0")
builder.set_default_connection(local_connection_id)
builder.add_skill(Path(CUR_PATH, "data", "dummy_skill"))
- aea = builder.build(connection_ids=[PublicId.from_str("fetchai/local:0.8.0")])
+ aea = builder.build(connection_ids=[PublicId.from_str("fetchai/local:0.9.0")])
local_connection = aea.resources.get_connection(local_connection_id)
local_connection._local_node = node
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index c7f15be116..60c1c3858b 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -96,7 +96,7 @@ def test_add_package_already_existing():
builder.add_component(ComponentType.PROTOCOL, fipa_package_path)
expected_message = re.escape(
- "Component 'fetchai/fipa:0.6.0' of type 'protocol' already added."
+ "Component 'fetchai/fipa:0.7.0' of type 'protocol' already added."
)
with pytest.raises(AEAException, match=expected_message):
builder.add_component(ComponentType.PROTOCOL, fipa_package_path)
@@ -106,12 +106,12 @@ def test_when_package_has_missing_dependency():
"""Test the case when the builder tries to load the packages, but fails because of a missing dependency."""
builder = AEABuilder()
expected_message = re.escape(
- "Package 'fetchai/oef:0.9.0' of type 'connection' cannot be added. "
- "Missing dependencies: ['(protocol, fetchai/oef_search:0.6.0)']"
+ "Package 'fetchai/oef:0.10.0' of type 'connection' cannot be added. "
+ "Missing dependencies: ['(protocol, fetchai/oef_search:0.7.0)']"
)
with pytest.raises(AEAException, match=expected_message):
- # connection "fetchai/oef:0.9.0" requires
- # "fetchai/oef_search:0.6.0" and "fetchai/fipa:0.6.0" protocols.
+ # connection "fetchai/oef:0.10.0" requires
+ # "fetchai/oef_search:0.7.0" and "fetchai/fipa:0.7.0" protocols.
builder.add_component(
ComponentType.CONNECTION,
Path(ROOT_DIR) / "packages" / "fetchai" / "connections" / "oef",
diff --git a/tests/test_cli/test_add/test_connection.py b/tests/test_cli/test_add/test_connection.py
index 47cbef9433..97a6118774 100644
--- a/tests/test_cli/test_add/test_connection.py
+++ b/tests/test_cli/test_add/test_connection.py
@@ -57,7 +57,7 @@ def setup_class(cls):
cls.connection_name = "http_client"
cls.connection_author = "fetchai"
cls.connection_version = "0.3.0"
- cls.connection_id = "fetchai/http_client:0.8.0"
+ cls.connection_id = "fetchai/http_client:0.9.0"
# copy the 'packages' directory in the parent of the agent folder.
shutil.copytree(Path(CUR_PATH, "..", "packages"), Path(cls.t, "packages"))
@@ -148,7 +148,7 @@ def setup_class(cls):
cls.connection_name = "http_client"
cls.connection_author = "fetchai"
cls.connection_version = "0.3.0"
- cls.connection_id = "fetchai/http_client:0.8.0"
+ cls.connection_id = "fetchai/http_client:0.9.0"
# copy the 'packages' directory in the parent of the agent folder.
shutil.copytree(Path(CUR_PATH, "..", "packages"), Path(cls.t, "packages"))
@@ -345,7 +345,7 @@ def setup_class(cls):
cls.agent_name = "myagent"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
- cls.connection_id = "fetchai/http_client:0.8.0"
+ cls.connection_id = "fetchai/http_client:0.9.0"
cls.connection_name = "http_client"
# copy the 'packages' directory in the parent of the agent folder.
@@ -413,7 +413,7 @@ def setup_class(cls):
cls.agent_name = "myagent"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
- cls.connection_id = "fetchai/http_client:0.8.0"
+ cls.connection_id = "fetchai/http_client:0.9.0"
cls.connection_name = "http_client"
# copy the 'packages' directory in the parent of the agent folder.
diff --git a/tests/test_cli/test_add/test_skill.py b/tests/test_cli/test_add/test_skill.py
index 01d3a980ed..a2355f93e0 100644
--- a/tests/test_cli/test_add/test_skill.py
+++ b/tests/test_cli/test_add/test_skill.py
@@ -60,7 +60,7 @@ def setup_class(cls):
cls.agent_name = "myagent"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
- cls.skill_id = PublicId.from_str("fetchai/error:0.5.0")
+ cls.skill_id = PublicId.from_str("fetchai/error:0.6.0")
cls.skill_name = cls.skill_id.name
cls.skill_author = cls.skill_id.author
cls.skill_version = cls.skill_id.version
@@ -142,7 +142,7 @@ def setup_class(cls):
cls.agent_name = "myagent"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
- cls.skill_id = PublicId.from_str("fetchai/echo:0.7.0")
+ cls.skill_id = PublicId.from_str("fetchai/echo:0.8.0")
cls.skill_name = cls.skill_id.name
cls.skill_author = cls.skill_id.author
cls.skill_version = cls.skill_id.version
@@ -337,7 +337,7 @@ def setup_class(cls):
cls.agent_name = "myagent"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
- cls.skill_id = "fetchai/echo:0.7.0"
+ cls.skill_id = "fetchai/echo:0.8.0"
cls.skill_name = "echo"
# copy the 'packages' directory in the parent of the agent folder.
@@ -409,7 +409,7 @@ def setup_class(cls):
cls.agent_name = "myagent"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
- cls.skill_id = "fetchai/echo:0.7.0"
+ cls.skill_id = "fetchai/echo:0.8.0"
cls.skill_name = "echo"
# copy the 'packages' directory in the parent of the agent folder.
@@ -487,7 +487,7 @@ class TestAddSkillFromRemoteRegistry(AEATestCaseEmpty):
def test_add_skill_from_remote_registry_positive(self):
"""Test add skill from Registry positive result."""
self.run_cli_command(
- *["remove", "protocol", "fetchai/default:0.5.0"], cwd=self._get_cwd()
+ *["remove", "protocol", "fetchai/default:0.6.0"], cwd=self._get_cwd()
)
self.add_item("skill", "fetchai/echo:0.3.0", local=False)
diff --git a/tests/test_cli/test_interact.py b/tests/test_cli/test_interact.py
index 9d8adb5697..abd4b995da 100644
--- a/tests/test_cli/test_interact.py
+++ b/tests/test_cli/test_interact.py
@@ -201,7 +201,7 @@ class TestInteractEcho(AEATestCaseEmpty):
@pytest.mark.integration
def test_interact(self):
"""Test the 'aea interact' command with the echo skill."""
- self.add_item("skill", "fetchai/echo:0.7.0")
+ self.add_item("skill", "fetchai/echo:0.8.0")
self.run_agent()
process = self.run_interaction()
@@ -209,7 +209,7 @@ def test_interact(self):
process,
[
"Starting AEA interaction channel...",
- "Provide message of protocol fetchai/default:0.5.0 for performative bytes",
+ "Provide message of protocol fetchai/default:0.6.0 for performative bytes",
],
timeout=10,
is_terminating=False,
@@ -225,9 +225,9 @@ def test_interact(self):
"Sending envelope:",
f"to: {self.agent_name}",
f"sender: {self.agent_name}_interact",
- "protocol_id: fetchai/default:0.5.0",
+ "protocol_id: fetchai/default:0.6.0",
"message_id=1,target=0,performative=bytes,content=b'hello')",
- "Provide message of protocol fetchai/default:0.5.0 for performative bytes:",
+ "Provide message of protocol fetchai/default:0.6.0 for performative bytes:",
],
timeout=10,
is_terminating=False,
@@ -243,9 +243,9 @@ def test_interact(self):
"Received envelope:",
f"to: {self.agent_name}_interact",
f"sender: {self.agent_name}",
- "protocol_id: fetchai/default:0.5.0",
+ "protocol_id: fetchai/default:0.6.0",
"message_id=2,target=1,performative=bytes,content=b'hello')",
- "Provide message of protocol fetchai/default:0.5.0 for performative bytes:",
+ "Provide message of protocol fetchai/default:0.6.0 for performative bytes:",
],
timeout=10,
is_terminating=False,
@@ -259,7 +259,7 @@ def test_interact(self):
[
"Interrupting input, checking inbox ...",
"Received no new envelope!",
- "Provide message of protocol fetchai/default:0.5.0 for performative bytes:",
+ "Provide message of protocol fetchai/default:0.6.0 for performative bytes:",
],
timeout=10,
is_terminating=False,
diff --git a/tests/test_cli/test_remove/test_connection.py b/tests/test_cli/test_remove/test_connection.py
index 3e4b5f69b0..2ed0523fbd 100644
--- a/tests/test_cli/test_remove/test_connection.py
+++ b/tests/test_cli/test_remove/test_connection.py
@@ -47,7 +47,7 @@ def setup_class(cls):
cls.t = tempfile.mkdtemp()
# copy the 'packages' directory in the parent of the agent folder.
shutil.copytree(Path(CUR_PATH, "..", "packages"), Path(cls.t, "packages"))
- cls.connection_id = "fetchai/http_client:0.8.0"
+ cls.connection_id = "fetchai/http_client:0.9.0"
cls.connection_name = "http_client"
os.chdir(cls.t)
@@ -109,7 +109,7 @@ def setup_class(cls):
cls.agent_name = "myagent"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
- cls.connection_id = "fetchai/local:0.8.0"
+ cls.connection_id = "fetchai/local:0.9.0"
os.chdir(cls.t)
result = cls.runner.invoke(
@@ -164,7 +164,7 @@ def setup_class(cls):
cls.t = tempfile.mkdtemp()
# copy the 'packages' directory in the parent of the agent folder.
shutil.copytree(Path(CUR_PATH, "..", "packages"), Path(cls.t, "packages"))
- cls.connection_id = "fetchai/http_client:0.8.0"
+ cls.connection_id = "fetchai/http_client:0.9.0"
cls.connection_name = "http_client"
os.chdir(cls.t)
diff --git a/tests/test_cli/test_run.py b/tests/test_cli/test_run.py
index b263fe0677..d4f258cce7 100644
--- a/tests/test_cli/test_run.py
+++ b/tests/test_cli/test_run.py
@@ -76,7 +76,7 @@ def test_run():
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.9.0"],
)
assert result.exit_code == 0
@@ -87,7 +87,7 @@ def test_run():
"config",
"set",
"agent.default_connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
)
assert result.exit_code == 0
@@ -168,9 +168,9 @@ def test_run_with_default_connection():
@pytest.mark.parametrize(
argnames=["connection_ids"],
argvalues=[
- ["fetchai/http_client:0.8.0,{}".format(str(DEFAULT_CONNECTION))],
- ["'fetchai/http_client:0.8.0, {}'".format(str(DEFAULT_CONNECTION))],
- ["fetchai/http_client:0.8.0,,{},".format(str(DEFAULT_CONNECTION))],
+ ["fetchai/http_client:0.9.0,{}".format(str(DEFAULT_CONNECTION))],
+ ["'fetchai/http_client:0.9.0, {}'".format(str(DEFAULT_CONNECTION))],
+ ["fetchai/http_client:0.9.0,,{},".format(str(DEFAULT_CONNECTION))],
],
)
def test_run_multiple_connections(connection_ids):
@@ -195,7 +195,7 @@ def test_run_multiple_connections(connection_ids):
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.9.0"],
)
assert result.exit_code == 0
@@ -251,7 +251,7 @@ def test_run_unknown_private_key():
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.9.0"],
)
assert result.exit_code == 0
result = runner.invoke(
@@ -261,7 +261,7 @@ def test_run_unknown_private_key():
"config",
"set",
"agent.default_connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
)
assert result.exit_code == 0
@@ -290,7 +290,7 @@ def test_run_unknown_private_key():
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.9.0"],
standalone_mode=False,
)
@@ -326,7 +326,7 @@ def test_run_fet_private_key_config():
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.9.0"],
)
assert result.exit_code == 0
@@ -350,7 +350,7 @@ def test_run_fet_private_key_config():
error_msg = ""
try:
- cli.main([*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.8.0"])
+ cli.main([*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.9.0"])
except SystemExit as e:
error_msg = str(e)
@@ -385,7 +385,7 @@ def test_run_ethereum_private_key_config():
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.9.0"],
)
assert result.exit_code == 0
@@ -409,7 +409,7 @@ def test_run_ethereum_private_key_config():
error_msg = ""
try:
- cli.main([*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.8.0"])
+ cli.main([*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.9.0"])
except SystemExit as e:
error_msg = str(e)
@@ -447,7 +447,7 @@ def test_run_with_install_deps():
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.9.0"],
)
assert result.exit_code == 0
result = runner.invoke(
@@ -457,7 +457,7 @@ def test_run_with_install_deps():
"config",
"set",
"agent.default_connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
)
assert result.exit_code == 0
@@ -473,7 +473,7 @@ def test_run_with_install_deps():
"run",
"--install-deps",
"--connections",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
env=os.environ,
maxread=10000,
@@ -519,7 +519,7 @@ def test_run_with_install_deps_and_requirement_file():
result = runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.8.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "connection", "fetchai/http_client:0.9.0"],
)
assert result.exit_code == 0
result = runner.invoke(
@@ -529,7 +529,7 @@ def test_run_with_install_deps_and_requirement_file():
"config",
"set",
"agent.default_connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
)
assert result.exit_code == 0
@@ -549,7 +549,7 @@ def test_run_with_install_deps_and_requirement_file():
"run",
"--install-deps",
"--connections",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
env=os.environ,
maxread=10000,
@@ -607,7 +607,7 @@ def setup_class(cls):
"add",
"--local",
"connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
standalone_mode=False,
)
@@ -624,7 +624,7 @@ def setup_class(cls):
try:
cli.main(
- [*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.8.0"]
+ [*CLI_LOG_OPTION, "run", "--connections", "fetchai/http_client:0.9.0"]
)
except SystemExit as e:
cls.exit_code = e.code
@@ -874,7 +874,7 @@ def setup_class(cls):
"""Set the test up."""
cls.runner = CliRunner()
cls.agent_name = "myagent"
- cls.connection_id = PublicId.from_str("fetchai/http_client:0.8.0")
+ cls.connection_id = PublicId.from_str("fetchai/http_client:0.9.0")
cls.connection_name = cls.connection_id.name
cls.connection_author = cls.connection_id.author
cls.cwd = os.getcwd()
@@ -908,7 +908,7 @@ def setup_class(cls):
"config",
"set",
"agent.default_connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
)
assert result.exit_code == 0
@@ -967,7 +967,7 @@ def setup_class(cls):
"""Set the test up."""
cls.runner = CliRunner()
cls.agent_name = "myagent"
- cls.connection_id = PublicId.from_str("fetchai/http_client:0.8.0")
+ cls.connection_id = PublicId.from_str("fetchai/http_client:0.9.0")
cls.connection_author = cls.connection_id.author
cls.connection_name = cls.connection_id.name
cls.cwd = os.getcwd()
@@ -1001,7 +1001,7 @@ def setup_class(cls):
"config",
"set",
"agent.default_connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
)
assert result.exit_code == 0
@@ -1059,7 +1059,7 @@ def setup_class(cls):
"""Set the test up."""
cls.runner = CliRunner()
cls.agent_name = "myagent"
- cls.connection_id = "fetchai/http_client:0.8.0"
+ cls.connection_id = "fetchai/http_client:0.9.0"
cls.connection_name = "http_client"
cls.cwd = os.getcwd()
cls.t = tempfile.mkdtemp()
@@ -1092,7 +1092,7 @@ def setup_class(cls):
"config",
"set",
"agent.default_connection",
- "fetchai/http_client:0.8.0",
+ "fetchai/http_client:0.9.0",
],
)
assert result.exit_code == 0
@@ -1246,7 +1246,7 @@ def setup_class(cls):
result = cls.runner.invoke(
cli,
- [*CLI_LOG_OPTION, "add", "--local", "protocol", "fetchai/fipa:0.6.0"],
+ [*CLI_LOG_OPTION, "add", "--local", "protocol", "fetchai/fipa:0.7.0"],
standalone_mode=False,
)
assert result.exit_code == 0
diff --git a/tests/test_cli/test_search.py b/tests/test_cli/test_search.py
index ebcad61cad..606f70e860 100644
--- a/tests/test_cli/test_search.py
+++ b/tests/test_cli/test_search.py
@@ -363,8 +363,8 @@ def test_exit_code_equal_to_zero(self):
def test_correct_output(self,):
"""Test that the command has printed the correct output.."""
- public_id_echo = PublicId.from_str("fetchai/echo:0.7.0")
- public_id_error = PublicId.from_str("fetchai/error:0.5.0")
+ public_id_echo = PublicId.from_str("fetchai/echo:0.8.0")
+ public_id_error = PublicId.from_str("fetchai/error:0.6.0")
expected = (
'Searching for ""...\n'
"Skills found:\n\n"
@@ -445,8 +445,8 @@ def test_exit_code_equal_to_zero(self):
def test_correct_output(self,):
"""Test that the command has printed the correct output.."""
- public_id_echo = PublicId.from_str("fetchai/echo:0.7.0")
- public_id_error = PublicId.from_str("fetchai/error:0.5.0")
+ public_id_echo = PublicId.from_str("fetchai/echo:0.8.0")
+ public_id_error = PublicId.from_str("fetchai/error:0.6.0")
expected = (
'Searching for ""...\n'
"Skills found:\n\n"
diff --git a/tests/test_cli/test_utils/test_utils.py b/tests/test_cli/test_utils/test_utils.py
index 341dc18c3f..90b33bee2e 100644
--- a/tests/test_cli/test_utils/test_utils.py
+++ b/tests/test_cli/test_utils/test_utils.py
@@ -280,7 +280,7 @@ class FindItemLocallyTestCase(TestCase):
)
def test_find_item_locally_bad_config(self, *mocks):
"""Test find_item_locally for bad config result."""
- public_id = PublicIdMock.from_str("fetchai/echo:0.7.0")
+ public_id = PublicIdMock.from_str("fetchai/echo:0.8.0")
with self.assertRaises(ClickException) as cm:
find_item_locally(ContextMock(), "skill", public_id)
@@ -294,7 +294,7 @@ def test_find_item_locally_bad_config(self, *mocks):
)
def test_find_item_locally_cant_find(self, from_conftype_mock, *mocks):
"""Test find_item_locally for can't find result."""
- public_id = PublicIdMock.from_str("fetchai/echo:0.7.0")
+ public_id = PublicIdMock.from_str("fetchai/echo:0.8.0")
with self.assertRaises(ClickException) as cm:
find_item_locally(ContextMock(), "skill", public_id)
@@ -313,7 +313,7 @@ class FindItemInDistributionTestCase(TestCase):
)
def testfind_item_in_distribution_bad_config(self, *mocks):
"""Test find_item_in_distribution for bad config result."""
- public_id = PublicIdMock.from_str("fetchai/echo:0.7.0")
+ public_id = PublicIdMock.from_str("fetchai/echo:0.8.0")
with self.assertRaises(ClickException) as cm:
find_item_in_distribution(ContextMock(), "skill", public_id)
@@ -322,7 +322,7 @@ def testfind_item_in_distribution_bad_config(self, *mocks):
@mock.patch("aea.cli.utils.package_utils.Path.exists", return_value=False)
def testfind_item_in_distribution_not_found(self, *mocks):
"""Test find_item_in_distribution for not found result."""
- public_id = PublicIdMock.from_str("fetchai/echo:0.7.0")
+ public_id = PublicIdMock.from_str("fetchai/echo:0.8.0")
with self.assertRaises(ClickException) as cm:
find_item_in_distribution(ContextMock(), "skill", public_id)
@@ -336,7 +336,7 @@ def testfind_item_in_distribution_not_found(self, *mocks):
)
def testfind_item_in_distribution_cant_find(self, from_conftype_mock, *mocks):
"""Test find_item_locally for can't find result."""
- public_id = PublicIdMock.from_str("fetchai/echo:0.7.0")
+ public_id = PublicIdMock.from_str("fetchai/echo:0.8.0")
with self.assertRaises(ClickException) as cm:
find_item_in_distribution(ContextMock(), "skill", public_id)
diff --git a/tests/test_cli_gui/test_run_agent.py b/tests/test_cli_gui/test_run_agent.py
index cdf4611e31..1912b998f1 100644
--- a/tests/test_cli_gui/test_run_agent.py
+++ b/tests/test_cli_gui/test_run_agent.py
@@ -63,7 +63,7 @@ def test_create_and_run_agent():
response_add = app.post(
"api/agent/" + agent_id + "/connection",
content_type="application/json",
- data=json.dumps("fetchai/local:0.8.0"),
+ data=json.dumps("fetchai/local:0.9.0"),
)
assert response_add.status_code == 201
diff --git a/tests/test_connections/test_stub.py b/tests/test_connections/test_stub.py
index 113b9936d6..d6c9346796 100644
--- a/tests/test_connections/test_stub.py
+++ b/tests/test_connections/test_stub.py
@@ -140,11 +140,11 @@ def test_reception_b(self):
def test_reception_c(self):
"""Test that the connection receives what has been enqueued in the input file."""
- encoded_envelope = b"0x5E22777dD831A459535AA4306AceC9cb22eC4cB5,default_oef,fetchai/oef_search:0.6.0,\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468dB8Ab79549B49C88DC991990E7910891dbd,"
+ encoded_envelope = b"0x5E22777dD831A459535AA4306AceC9cb22eC4cB5,default_oef,fetchai/oef_search:0.7.0,\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468dB8Ab79549B49C88DC991990E7910891dbd,"
expected_envelope = Envelope(
to="0x5E22777dD831A459535AA4306AceC9cb22eC4cB5",
sender="default_oef",
- protocol_id=PublicId.from_str("fetchai/oef_search:0.6.0"),
+ protocol_id=PublicId.from_str("fetchai/oef_search:0.7.0"),
message=b"\x08\x02\x12\x011\x1a\x011 \x01:,\n*0x32468dB8Ab79549B49C88DC991990E7910891dbd",
)
with open(self.input_file_path, "ab+") as f:
diff --git a/tests/test_docs/test_agent_vs_aea/agent_code_block.py b/tests/test_docs/test_agent_vs_aea/agent_code_block.py
index e219fd1420..0a7f29ac47 100644
--- a/tests/test_docs/test_agent_vs_aea/agent_code_block.py
+++ b/tests/test_docs/test_agent_vs_aea/agent_code_block.py
@@ -113,7 +113,7 @@ def run():
# Create a message inside an envelope and get the stub connection to pass it into the agent
message_text = (
- b"my_agent,other_agent,fetchai/default:0.5.0,\x08\x01*\x07\n\x05hello,"
+ b"my_agent,other_agent,fetchai/default:0.6.0,\x08\x01*\x07\n\x05hello,"
)
with open(INPUT_FILE, "wb") as f:
write_with_lock(f, message_text)
diff --git a/tests/test_docs/test_agent_vs_aea/test_agent_vs_aea.py b/tests/test_docs/test_agent_vs_aea/test_agent_vs_aea.py
index 154f9bf84d..65ff225dc2 100644
--- a/tests/test_docs/test_agent_vs_aea/test_agent_vs_aea.py
+++ b/tests/test_docs/test_agent_vs_aea/test_agent_vs_aea.py
@@ -61,7 +61,7 @@ def test_run_agent(self):
assert os.path.exists(Path(self.t, "input_file"))
message_text = (
- b"other_agent,my_agent,fetchai/default:0.5.0,\x08\x01*\x07\n\x05hello,"
+ b"other_agent,my_agent,fetchai/default:0.6.0,\x08\x01*\x07\n\x05hello,"
)
path = os.path.join(self.t, "output_file")
with open(path, "rb") as file:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-aries-cloud-agent-demo.md b/tests/test_docs/test_bash_yaml/md_files/bash-aries-cloud-agent-demo.md
index 0c2e6b7738..17edd0104d 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-aries-cloud-agent-demo.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-aries-cloud-agent-demo.md
@@ -22,10 +22,10 @@ cd aries_alice
aea create aries_alice
cd aries_alice
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
-aea add connection fetchai/http_client:0.8.0
-aea add connection fetchai/webhook:0.6.0
-aea add skill fetchai/aries_alice:0.7.0
+aea add connection fetchai/soef:0.9.0
+aea add connection fetchai/http_client:0.9.0
+aea add connection fetchai/webhook:0.7.0
+aea add skill fetchai/aries_alice:0.8.0
```
``` bash
aea config set vendor.fetchai.skills.aries_alice.models.strategy.args.admin_host 127.0.0.1
@@ -61,10 +61,10 @@ cd aries_faber
aea create aries_faber
cd aries_faber
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
-aea add connection fetchai/http_client:0.8.0
-aea add connection fetchai/webhook:0.6.0
-aea add skill fetchai/aries_faber:0.6.0
+aea add connection fetchai/soef:0.9.0
+aea add connection fetchai/http_client:0.9.0
+aea add connection fetchai/webhook:0.7.0
+aea add skill fetchai/aries_faber:0.7.0
```
``` bash
aea config set vendor.fetchai.skills.aries_faber.models.strategy.args.admin_host 127.0.0.1
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-car-park-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-car-park-skills.md
index de141063dc..526aada233 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-car-park-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-car-park-skills.md
@@ -7,7 +7,7 @@ aea install
aea create car_detector
cd car_detector
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/carpark_detection:0.12.0
aea install
@@ -22,7 +22,7 @@ aea install
aea create car_data_buyer
cd car_data_buyer
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/carpark_client:0.12.0
aea install
@@ -54,13 +54,13 @@ aea delete car_data_buyer
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-config.md b/tests/test_docs/test_bash_yaml/md_files/bash-config.md
index 0041a7c21b..0032df43c0 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-config.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-config.md
@@ -17,9 +17,9 @@ connections: # The list of connection public
- fetchai/stub:0.9.0
contracts: [] # The list of contract public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
protocols: # The list of protocol public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills: # The list of skill public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
default_connection: fetchai/p2p_libp2p:0.10.0 # The default connection used for envelopes sent by the AEA (must satisfy PUBLIC_ID_REGEX).
default_ledger: fetchai # The default ledger identifier the AEA project uses (must satisfy LEDGER_ID_REGEX)
logging_config: # The logging configurations the AEA project uses
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-erc1155-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-erc1155-skills.md
index d44f8d086b..5dba54b5a9 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-erc1155-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-erc1155-skills.md
@@ -7,7 +7,7 @@ aea install
aea create erc1155_deployer
cd erc1155_deployer
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/erc1155_deploy:0.14.0
aea install
@@ -33,7 +33,7 @@ aea install
aea create erc1155_client
cd erc1155_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/erc1155_client:0.13.0
aea install
@@ -76,14 +76,14 @@ aea delete erc1155_client
``` yaml
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills-step-by-step.md b/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills-step-by-step.md
index 760425d948..d0349421f3 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills-step-by-step.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills-step-by-step.md
@@ -49,19 +49,19 @@ aea generate-wealth fetchai --sync
```
``` bash
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
-aea add protocol fetchai/fipa:0.6.0
+aea add protocol fetchai/fipa:0.7.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
aea run
```
``` bash
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
-aea add protocol fetchai/fipa:0.6.0
-aea add protocol fetchai/signing:0.3.0
+aea add protocol fetchai/fipa:0.7.0
+aea add protocol fetchai/signing:0.4.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
```
@@ -91,10 +91,10 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
service_registration:
@@ -160,11 +160,11 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/default:0.5.0
-- fetchai/fipa:0.6.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
skills: []
behaviours:
search:
@@ -225,8 +225,8 @@ addr: ${OEF_ADDR: 127.0.0.1}
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills.md
index 6f01f1085c..f4454ad427 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-generic-skills.md
@@ -7,7 +7,7 @@ aea install
aea create my_seller_aea
cd my_seller_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/generic_seller:0.13.0
aea install
@@ -22,7 +22,7 @@ aea install
aea create my_buyer_aea
cd my_buyer_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/generic_buyer:0.12.0
aea install
@@ -62,13 +62,13 @@ aea delete my_buyer_aea
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
models:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-http-connection-and-skill.md b/tests/test_docs/test_bash_yaml/md_files/bash-http-connection-and-skill.md
index c456c45c1e..2c64e18ca6 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-http-connection-and-skill.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-http-connection-and-skill.md
@@ -3,10 +3,10 @@ aea create my_aea
cd my_aea
```
``` bash
-aea add connection fetchai/http_server:0.8.0
+aea add connection fetchai/http_server:0.9.0
```
``` bash
-aea config set agent.default_connection fetchai/http_server:0.8.0
+aea config set agent.default_connection fetchai/http_server:0.9.0
```
``` bash
aea config set vendor.fetchai.connections.http_server.config.api_spec_path "../examples/http_ex/petstore.yaml"
@@ -18,7 +18,7 @@ aea install
aea scaffold skill http_echo
```
``` bash
-aea fingerprint skill fetchai/http_echo:0.6.0
+aea fingerprint skill fetchai/http_echo:0.7.0
```
``` bash
aea run
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-logging.md b/tests/test_docs/test_bash_yaml/md_files/bash-logging.md
index 569ad3f700..2482123a70 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-logging.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-logging.md
@@ -15,9 +15,9 @@ connections:
- fetchai/stub:0.9.0
contracts: []
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
skills:
-- fetchai/error:0.5.0
+- fetchai/error:0.6.0
default_connection: fetchai/stub:0.9.0
default_ledger: fetchai
logging_config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md
index 901ad6cab9..8d369d30e1 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md
@@ -7,7 +7,7 @@ aea install
aea create ml_data_provider
cd ml_data_provider
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/ml_data_provider:0.12.0
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
@@ -22,7 +22,7 @@ aea install
aea create ml_model_trainer
cd ml_model_trainer
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/ml_train:0.12.0
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
@@ -54,13 +54,13 @@ aea delete ml_model_trainer
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-orm-integration.md b/tests/test_docs/test_bash_yaml/md_files/bash-orm-integration.md
index 9984fab6fd..d62b6c9dcb 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-orm-integration.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-orm-integration.md
@@ -7,7 +7,7 @@ aea install
aea create my_thermometer_aea
cd my_thermometer_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer:0.12.0
aea install
@@ -22,7 +22,7 @@ aea install
aea create my_thermometer_client
cd my_thermometer_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer_client:0.11.0
aea install
@@ -63,13 +63,13 @@ aea delete my_thermometer_client
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
models:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-p2p-connection.md b/tests/test_docs/test_bash_yaml/md_files/bash-p2p-connection.md
index e316c52cb9..422262bf4b 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-p2p-connection.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-p2p-connection.md
@@ -54,8 +54,8 @@ config:
```
``` yaml
default_routing:
- ? "fetchai/oef_search:0.6.0"
- : "fetchai/oef:0.9.0"
+ ? "fetchai/oef_search:0.7.0"
+ : "fetchai/oef:0.10.0"
```
``` yaml
config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md b/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md
index bb68980c7a..fd9adbf3d6 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md
@@ -41,7 +41,7 @@ v0.6.1
AEA configurations successfully initialized: {'author': 'fetchai'}
```
``` bash
-aea fetch fetchai/my_first_aea:0.11.0
+aea fetch fetchai/my_first_aea:0.12.0
cd my_first_aea
```
``` bash
@@ -49,13 +49,13 @@ aea create my_first_aea
cd my_first_aea
```
``` bash
-aea add skill fetchai/echo:0.7.0
+aea add skill fetchai/echo:0.8.0
```
``` bash
TO,SENDER,PROTOCOL_ID,ENCODED_MESSAGE,
```
``` bash
-recipient_aea,sender_aea,fetchai/default:0.5.0,\x08\x01\x12\x011*\x07\n\x05hello,
+recipient_aea,sender_aea,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello,
```
``` bash
aea run
@@ -92,7 +92,7 @@ info: Echo Behaviour: act method called.
info: Echo Behaviour: act method called.
```
``` bash
-echo 'my_first_aea,sender_aea,fetchai/default:0.5.0,\x08\x01\x12\x011*\x07\n\x05hello,' >> input_file
+echo 'my_first_aea,sender_aea,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello,' >> input_file
```
``` bash
info: Echo Behaviour: act method called.
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-skill-guide.md b/tests/test_docs/test_bash_yaml/md_files/bash-skill-guide.md
index d132e978f1..2cf8e232b9 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-skill-guide.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-skill-guide.md
@@ -6,10 +6,10 @@ aea scaffold skill my_search
aea fingerprint skill fetchai/my_search:0.1.0
```
``` bash
-aea add protocol fetchai/oef_search:0.6.0
+aea add protocol fetchai/oef_search:0.7.0
```
``` bash
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/p2p_libp2p:0.10.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
@@ -45,7 +45,7 @@ fingerprint: {}
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
my_search_behaviour:
@@ -72,7 +72,7 @@ dependencies: {}
```
``` yaml
default_routing:
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
name: simple_service_registration
@@ -91,7 +91,7 @@ fingerprint:
fingerprint_ignore_patterns: []
contracts: []
protocols:
-- fetchai/oef_search:0.6.0
+- fetchai/oef_search:0.7.0
skills: []
behaviours:
service:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-skill.md b/tests/test_docs/test_bash_yaml/md_files/bash-skill.md
index 16c892b336..ef0ab5fad6 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-skill.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-skill.md
@@ -16,5 +16,5 @@ handlers:
models: {}
dependencies: {}
protocols:
-- fetchai/default:0.5.0
+- fetchai/default:0.6.0
```
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md
index dba8940de7..0003698f96 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md
@@ -7,7 +7,7 @@ aea install
aea create tac_controller_contract
cd tac_controller_contract
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_control_contract:0.9.0
aea install
@@ -43,7 +43,7 @@ aea create tac_participant_two
``` bash
cd tac_participant_one
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
@@ -56,7 +56,7 @@ aea config set vendor.fetchai.skills.tac_negotiation.models.strategy.args.is_con
``` bash
cd tac_participant_two
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
@@ -124,5 +124,5 @@ models:
class_name: Transactions
args:
pending_transaction_timeout: 30
-protocols: ['fetchai/oef_search:0.6.0', 'fetchai/fipa:0.6.0']
+protocols: ['fetchai/oef_search:0.7.0', 'fetchai/fipa:0.7.0']
```
\ No newline at end of file
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
index 1eb1768963..b21b9cf691 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
@@ -7,9 +7,9 @@ aea install
aea create tac_controller
cd tac_controller
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
-aea add skill fetchai/tac_control:0.7.0
+aea add skill fetchai/tac_control:0.8.0
aea install
aea config set agent.default_connection fetchai/p2p_libp2p:0.10.0
aea config set agent.default_ledger fetchai
@@ -27,7 +27,7 @@ aea create tac_participant_two
``` bash
cd tac_participant_one
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
@@ -38,7 +38,7 @@ aea config set agent.default_ledger fetchai
``` bash
cd tac_participant_two
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/tac_participation:0.9.0
aea add skill fetchai/tac_negotiation:0.10.0
@@ -68,17 +68,17 @@ aea delete tac_participant_two
```
``` yaml
default_routing:
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md
index 61fe285d41..f592063fc2 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md
@@ -7,7 +7,7 @@ aea install
aea create my_thermometer_aea
cd my_thermometer_aea
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer:0.12.0
aea install
@@ -22,7 +22,7 @@ aea install
aea create my_thermometer_client
cd my_thermometer_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/thermometer_client:0.11.0
aea install
@@ -54,13 +54,13 @@ aea delete my_thermometer_client
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
config:
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md
index c138469064..f1057e4bd7 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md
@@ -7,7 +7,7 @@ aea install
aea create my_weather_station
cd my_weather_station
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/weather_station:0.12.0
aea install
@@ -22,7 +22,7 @@ aea install
aea create my_weather_client
cd my_weather_client
aea add connection fetchai/p2p_libp2p:0.10.0
-aea add connection fetchai/soef:0.8.0
+aea add connection fetchai/soef:0.9.0
aea add connection fetchai/ledger:0.6.0
aea add skill fetchai/weather_client:0.11.0
aea install
@@ -54,13 +54,13 @@ aea delete my_weather_client
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
default_routing:
- fetchai/ledger_api:0.3.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
```
``` yaml
config:
diff --git a/tests/test_docs/test_build_aea_programmatically/programmatic_aea.py b/tests/test_docs/test_build_aea_programmatically/programmatic_aea.py
index bdbac810af..656673d69d 100644
--- a/tests/test_docs/test_build_aea_programmatically/programmatic_aea.py
+++ b/tests/test_docs/test_build_aea_programmatically/programmatic_aea.py
@@ -100,7 +100,7 @@ def handle(self, message: Message) -> None:
time.sleep(4)
# Create a message inside an envelope and get the stub connection to pass it on to the echo skill
- message_text = b"my_aea,other_agent,fetchai/default:0.5.0,\x08\x01\x12\x011*\x07\n\x05hello,"
+ message_text = b"my_aea,other_agent,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello,"
with open(INPUT_FILE, "wb") as f:
write_with_lock(f, message_text)
print(b"input message: " + message_text)
diff --git a/tests/test_docs/test_build_aea_programmatically/test_programmatic_aea.py b/tests/test_docs/test_build_aea_programmatically/test_programmatic_aea.py
index 290a7a7295..bdb7052a06 100644
--- a/tests/test_docs/test_build_aea_programmatically/test_programmatic_aea.py
+++ b/tests/test_docs/test_build_aea_programmatically/test_programmatic_aea.py
@@ -59,7 +59,7 @@ def test_run_agent(self):
assert os.path.exists(Path(self.t, "output_file"))
assert os.path.exists(Path(self.t, DEFAULT_PRIVATE_KEY_FILE))
- message_text_1 = b"other_agent,my_aea,fetchai/default:0.5.0,"
+ message_text_1 = b"other_agent,my_aea,fetchai/default:0.6.0,"
message_text_2 = b"\x01*\x07\n\x05hello,"
path = os.path.join(self.t, "output_file")
with open(path, "rb") as file:
diff --git a/tests/test_docs/test_cli_vs_programmatic_aeas/programmatic_aea.py b/tests/test_docs/test_cli_vs_programmatic_aeas/programmatic_aea.py
index 79428e901d..4785ffb54d 100644
--- a/tests/test_docs/test_cli_vs_programmatic_aeas/programmatic_aea.py
+++ b/tests/test_docs/test_cli_vs_programmatic_aeas/programmatic_aea.py
@@ -78,8 +78,8 @@ def run():
# specify the default routing for some protocols
default_routing = {
- PublicId.from_str("fetchai/ledger_api:0.3.0"): LedgerConnection.connection_id,
- PublicId.from_str("fetchai/oef_search:0.6.0"): SOEFConnection.connection_id,
+ PublicId.from_str("fetchai/ledger_api:0.4.0"): LedgerConnection.connection_id,
+ PublicId.from_str("fetchai/oef_search:0.7.0"): SOEFConnection.connection_id,
}
default_connection = P2PLibp2pConnection.connection_id
@@ -146,7 +146,7 @@ def run():
api_key=API_KEY,
soef_addr=SOEF_ADDR,
soef_port=SOEF_PORT,
- restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.6.0")},
+ restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.7.0")},
connection_id=SOEFConnection.connection_id,
)
soef_connection = SOEFConnection(configuration=configuration, identity=identity)
diff --git a/tests/test_docs/test_docs_protocol.py b/tests/test_docs/test_docs_protocol.py
index 1bec995f56..00a6ce763f 100644
--- a/tests/test_docs/test_docs_protocol.py
+++ b/tests/test_docs/test_docs_protocol.py
@@ -69,7 +69,7 @@ def test_custom_protocol(self):
)
def test_oef_search_protocol(self):
- """Test the fetchai/oef_search:0.6.0 protocol documentation."""
+ """Test the fetchai/oef_search:0.7.0 protocol documentation."""
# this is the offset of code blocks for the section under testing
offset = 4
@@ -106,7 +106,7 @@ def test_oef_search_protocol(self):
compare_enum_classes(ExpectedOefErrorOperation, ActualOefErrorOperation)
def test_fipa_protocol(self):
- """Test the fetchai/fipa:0.6.0 documentation."""
+ """Test the fetchai/fipa:0.7.0 documentation."""
offset = 15
locals_dict = {"Enum": Enum}
compile_and_exec(self.code_blocks[offset]["text"], locals_dict=locals_dict)
diff --git a/tests/test_docs/test_multiplexer_standalone/multiplexer_standalone.py b/tests/test_docs/test_multiplexer_standalone/multiplexer_standalone.py
index 53c69f4f8b..69d4cfaebc 100644
--- a/tests/test_docs/test_multiplexer_standalone/multiplexer_standalone.py
+++ b/tests/test_docs/test_multiplexer_standalone/multiplexer_standalone.py
@@ -65,7 +65,7 @@ def run():
# Create a message inside an envelope and get the stub connection to pass it into the multiplexer
message_text = (
- "multiplexer,some_agent,fetchai/default:0.5.0,\x08\x01*\x07\n\x05hello,"
+ "multiplexer,some_agent,fetchai/default:0.6.0,\x08\x01*\x07\n\x05hello,"
)
with open(INPUT_FILE, "w") as f:
write_with_lock(f, message_text)
diff --git a/tests/test_docs/test_multiplexer_standalone/test_multiplexer_standalone.py b/tests/test_docs/test_multiplexer_standalone/test_multiplexer_standalone.py
index b67134a50c..62dfe2ab8a 100644
--- a/tests/test_docs/test_multiplexer_standalone/test_multiplexer_standalone.py
+++ b/tests/test_docs/test_multiplexer_standalone/test_multiplexer_standalone.py
@@ -58,7 +58,7 @@ def test_run_agent(self):
assert os.path.exists(Path(self.t, "output.txt"))
message_text = (
- "some_agent,multiplexer,fetchai/default:0.5.0,\x08\x01*\x07\n\x05hello,"
+ "some_agent,multiplexer,fetchai/default:0.6.0,\x08\x01*\x07\n\x05hello,"
)
path = os.path.join(str(self.t), "output.txt")
with open(path, "r", encoding="utf-8") as file:
diff --git a/tests/test_docs/test_orm_integration/test_orm_integration.py b/tests/test_docs/test_orm_integration/test_orm_integration.py
index 5b3448a617..c82b6eb22a 100644
--- a/tests/test_docs/test_orm_integration/test_orm_integration.py
+++ b/tests/test_docs/test_orm_integration/test_orm_integration.py
@@ -126,8 +126,8 @@ def test_orm_integration_docs_example(self):
self.create_agents(seller_aea_name, buyer_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -139,7 +139,7 @@ def test_orm_integration_docs_example(self):
# Setup seller
self.set_agent_context(seller_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/thermometer:0.12.0")
@@ -185,7 +185,7 @@ def test_orm_integration_docs_example(self):
# Setup Buyer
self.set_agent_context(buyer_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/thermometer_client:0.11.0")
diff --git a/tests/test_docs/test_skill_guide/test_skill_guide.py b/tests/test_docs/test_skill_guide/test_skill_guide.py
index 87fcc76cad..c48519f435 100644
--- a/tests/test_docs/test_skill_guide/test_skill_guide.py
+++ b/tests/test_docs/test_skill_guide/test_skill_guide.py
@@ -94,7 +94,7 @@ def test_update_skill_and_run(self):
self.force_set_config(setting_path, COSMOS)
default_routing = {
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# replace location
@@ -108,7 +108,7 @@ def test_update_skill_and_run(self):
skill_id = AUTHOR + "/" + skill_name + ":" + DEFAULT_VERSION
self.scaffold_item("skill", skill_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
setting_path = "agent.default_routing"
self.force_set_config(setting_path, default_routing)
diff --git a/tests/test_packages/test_connections/test_http_server/test_http_server.py b/tests/test_packages/test_connections/test_http_server/test_http_server.py
index a3db1f3fe9..7f8ce4bc3d 100644
--- a/tests/test_packages/test_connections/test_http_server/test_http_server.py
+++ b/tests/test_packages/test_connections/test_http_server/test_http_server.py
@@ -119,7 +119,7 @@ def setup(self):
ROOT_DIR, "tests", "data", "petstore_sim.yaml"
)
self.connection_id = HTTPServerConnection.connection_id
- self.protocol_id = PublicId.from_str("fetchai/http:0.5.0")
+ self.protocol_id = PublicId.from_str("fetchai/http:0.6.0")
self.configuration = ConnectionConfig(
host=self.host,
diff --git a/tests/test_packages/test_connections/test_http_server/test_http_server_and_client.py b/tests/test_packages/test_connections/test_http_server/test_http_server_and_client.py
index 7998701578..6dc25ac3c2 100644
--- a/tests/test_packages/test_connections/test_http_server/test_http_server_and_client.py
+++ b/tests/test_packages/test_connections/test_http_server/test_http_server_and_client.py
@@ -53,7 +53,7 @@ def setup_server(self):
self.host = get_host()
self.port = get_unused_tcp_port()
self.connection_id = HTTPServerConnection.connection_id
- self.protocol_id = PublicId.from_str("fetchai/http:0.5.0")
+ self.protocol_id = PublicId.from_str("fetchai/http:0.6.0")
self.configuration = ConnectionConfig(
host=self.host,
diff --git a/tests/test_packages/test_connections/test_soef/test_soef.py b/tests/test_packages/test_connections/test_soef/test_soef.py
index 7f887bea0d..4666c67b9b 100644
--- a/tests/test_packages/test_connections/test_soef/test_soef.py
+++ b/tests/test_packages/test_connections/test_soef/test_soef.py
@@ -120,7 +120,7 @@ def setup(self):
api_key="TwiCIriSl0mLahw17pyqoA",
soef_addr="soef.fetch.ai",
soef_port=9002,
- restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.6.0")},
+ restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.7.0")},
connection_id=SOEFConnection.connection_id,
)
self.connection = SOEFConnection(
@@ -661,7 +661,7 @@ def test_chain_identifier_fail(self):
api_key="TwiCIriSl0mLahw17pyqoA",
soef_addr="soef.fetch.ai",
soef_port=9002,
- restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.6.0")},
+ restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.7.0")},
connection_id=SOEFConnection.connection_id,
chain_identifier=chain_identifier,
)
@@ -679,7 +679,7 @@ def test_chain_identifier_ok(self):
api_key="TwiCIriSl0mLahw17pyqoA",
soef_addr="soef.fetch.ai",
soef_port=9002,
- restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.6.0")},
+ restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.7.0")},
connection_id=SOEFConnection.connection_id,
chain_identifier=chain_identifier,
)
diff --git a/tests/test_packages/test_connections/test_soef/test_soef_integration.py b/tests/test_packages/test_connections/test_soef/test_soef_integration.py
index 0ab0ef729a..d3680d26f2 100644
--- a/tests/test_packages/test_connections/test_soef/test_soef_integration.py
+++ b/tests/test_packages/test_connections/test_soef/test_soef_integration.py
@@ -66,7 +66,7 @@ def make_multiplexer_and_dialogues() -> Tuple[Multiplexer, OefSearchDialogues, C
api_key="TwiCIriSl0mLahw17pyqoA",
soef_addr="soef.fetch.ai",
soef_port=9002,
- restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.6.0")},
+ restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.7.0")},
connection_id=SOEFConnection.connection_id,
)
soef_connection = SOEFConnection(configuration=configuration, identity=identity,)
diff --git a/tests/test_packages/test_connections/test_webhook/test_webhook.py b/tests/test_packages/test_connections/test_webhook/test_webhook.py
index 83b37b13fd..1c40eabdc6 100644
--- a/tests/test_packages/test_connections/test_webhook/test_webhook.py
+++ b/tests/test_packages/test_connections/test_webhook/test_webhook.py
@@ -164,7 +164,7 @@ async def test_send(self):
envelope = Envelope(
to="addr",
sender="my_id",
- protocol_id=PublicId.from_str("fetchai/http:0.5.0"),
+ protocol_id=PublicId.from_str("fetchai/http:0.6.0"),
message=http_message,
)
with patch.object(self.webhook_connection.logger, "warning") as mock_logger:
diff --git a/tests/test_packages/test_skills/test_carpark.py b/tests/test_packages/test_skills/test_carpark.py
index a95f7128b1..28d3996b69 100644
--- a/tests/test_packages/test_skills/test_carpark.py
+++ b/tests/test_packages/test_skills/test_carpark.py
@@ -51,8 +51,8 @@ def test_carpark(self):
self.create_agents(carpark_aea_name, carpark_client_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -64,7 +64,7 @@ def test_carpark(self):
# Setup agent one
self.set_agent_context(carpark_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/carpark_detection:0.12.0")
@@ -99,7 +99,7 @@ def test_carpark(self):
# Setup agent two
self.set_agent_context(carpark_client_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/carpark_client:0.12.0")
@@ -226,8 +226,8 @@ def test_carpark(self):
self.create_agents(carpark_aea_name, carpark_client_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -239,7 +239,7 @@ def test_carpark(self):
# Setup agent one
self.set_agent_context(carpark_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/carpark_detection:0.12.0")
@@ -277,7 +277,7 @@ def test_carpark(self):
# Setup agent two
self.set_agent_context(carpark_client_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/carpark_client:0.12.0")
diff --git a/tests/test_packages/test_skills/test_echo.py b/tests/test_packages/test_skills/test_echo.py
index 5a8826f941..9a59110501 100644
--- a/tests/test_packages/test_skills/test_echo.py
+++ b/tests/test_packages/test_skills/test_echo.py
@@ -65,7 +65,7 @@ class TestEchoSkill(AEATestCaseEmpty):
def test_echo(self):
"""Run the echo skill sequence."""
- self.add_item("skill", "fetchai/echo:0.7.0")
+ self.add_item("skill", "fetchai/echo:0.8.0")
process = self.run_agent()
is_running = self.is_running(process)
diff --git a/tests/test_packages/test_skills/test_erc1155.py b/tests/test_packages/test_skills/test_erc1155.py
index f785a87681..30b13cded6 100644
--- a/tests/test_packages/test_skills/test_erc1155.py
+++ b/tests/test_packages/test_skills/test_erc1155.py
@@ -56,9 +56,9 @@ def test_generic(self):
# add ethereum ledger in both configuration files
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
"fetchai/contract_api:0.5.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -71,7 +71,7 @@ def test_generic(self):
self.set_agent_context(deploy_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.set_config("agent.default_ledger", ETHEREUM)
setting_path = "agent.default_routing"
@@ -115,7 +115,7 @@ def test_generic(self):
self.set_agent_context(client_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.set_config("agent.default_ledger", ETHEREUM)
setting_path = "agent.default_routing"
diff --git a/tests/test_packages/test_skills/test_generic.py b/tests/test_packages/test_skills/test_generic.py
index d320798742..77c13b6cb9 100644
--- a/tests/test_packages/test_skills/test_generic.py
+++ b/tests/test_packages/test_skills/test_generic.py
@@ -50,8 +50,8 @@ def test_generic(self, pytestconfig):
self.create_agents(seller_aea_name, buyer_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -63,7 +63,7 @@ def test_generic(self, pytestconfig):
# prepare seller agent
self.set_agent_context(seller_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/generic_seller:0.13.0")
@@ -102,7 +102,7 @@ def test_generic(self, pytestconfig):
# prepare buyer agent
self.set_agent_context(buyer_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/generic_buyer:0.12.0")
@@ -231,8 +231,8 @@ def test_generic(self, pytestconfig):
self.create_agents(seller_aea_name, buyer_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -244,7 +244,7 @@ def test_generic(self, pytestconfig):
# prepare seller agent
self.set_agent_context(seller_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/generic_seller:0.13.0")
@@ -286,7 +286,7 @@ def test_generic(self, pytestconfig):
# prepare buyer agent
self.set_agent_context(buyer_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/generic_buyer:0.12.0")
diff --git a/tests/test_packages/test_skills/test_http_echo.py b/tests/test_packages/test_skills/test_http_echo.py
index 6052165361..1385db73cb 100644
--- a/tests/test_packages/test_skills/test_http_echo.py
+++ b/tests/test_packages/test_skills/test_http_echo.py
@@ -36,9 +36,9 @@ class TestHttpEchoSkill(AEATestCaseEmpty):
def test_echo(self):
"""Run the echo skill sequence."""
- self.add_item("connection", "fetchai/http_server:0.8.0")
- self.add_item("skill", "fetchai/http_echo:0.6.0")
- self.set_config("agent.default_connection", "fetchai/http_server:0.8.0")
+ self.add_item("connection", "fetchai/http_server:0.9.0")
+ self.add_item("skill", "fetchai/http_echo:0.7.0")
+ self.set_config("agent.default_connection", "fetchai/http_server:0.9.0")
self.set_config(
"vendor.fetchai.connections.http_server.config.api_spec_path", API_SPEC_PATH
)
diff --git a/tests/test_packages/test_skills/test_ml_skills.py b/tests/test_packages/test_skills/test_ml_skills.py
index 3ed1c80747..9d7aaa4e37 100644
--- a/tests/test_packages/test_skills/test_ml_skills.py
+++ b/tests/test_packages/test_skills/test_ml_skills.py
@@ -64,8 +64,8 @@ def test_ml_skills(self, pytestconfig):
self.create_agents(data_provider_aea_name, model_trainer_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -77,7 +77,7 @@ def test_ml_skills(self, pytestconfig):
# prepare data provider agent
self.set_agent_context(data_provider_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/ml_data_provider:0.12.0")
@@ -112,7 +112,7 @@ def test_ml_skills(self, pytestconfig):
# prepare model trainer agent
self.set_agent_context(model_trainer_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/ml_train:0.12.0")
@@ -241,8 +241,8 @@ def test_ml_skills(self, pytestconfig):
self.create_agents(data_provider_aea_name, model_trainer_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -254,7 +254,7 @@ def test_ml_skills(self, pytestconfig):
# prepare data provider agent
self.set_agent_context(data_provider_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/ml_data_provider:0.12.0")
@@ -292,7 +292,7 @@ def test_ml_skills(self, pytestconfig):
# prepare model trainer agent
self.set_agent_context(model_trainer_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/ml_train:0.12.0")
diff --git a/tests/test_packages/test_skills/test_tac.py b/tests/test_packages/test_skills/test_tac.py
index a2397ffcbc..1ff948a692 100644
--- a/tests/test_packages/test_skills/test_tac.py
+++ b/tests/test_packages/test_skills/test_tac.py
@@ -61,15 +61,15 @@ def test_tac(self):
)
default_routing = {
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# prepare tac controller for test
self.set_agent_context(tac_controller_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
- self.add_item("skill", "fetchai/tac_control:0.7.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
+ self.add_item("skill", "fetchai/tac_control:0.8.0")
self.set_config("agent.default_ledger", FETCHAI)
setting_path = "agent.default_routing"
self.force_set_config(setting_path, default_routing)
@@ -96,8 +96,8 @@ def test_tac(self):
self.force_set_config(setting_path, COSMOS)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# prepare agents for test
@@ -108,7 +108,7 @@ def test_tac(self):
self.set_agent_context(agent_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/tac_participation:0.9.0")
self.add_item("skill", "fetchai/tac_negotiation:0.10.0")
diff --git a/tests/test_packages/test_skills/test_thermometer.py b/tests/test_packages/test_skills/test_thermometer.py
index 0d87abf663..d78f337397 100644
--- a/tests/test_packages/test_skills/test_thermometer.py
+++ b/tests/test_packages/test_skills/test_thermometer.py
@@ -51,8 +51,8 @@ def test_thermometer(self):
self.create_agents(thermometer_aea_name, thermometer_client_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -64,7 +64,7 @@ def test_thermometer(self):
# add packages for agent one and run it
self.set_agent_context(thermometer_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/thermometer:0.12.0")
@@ -96,7 +96,7 @@ def test_thermometer(self):
# add packages for agent two and run it
self.set_agent_context(thermometer_client_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/thermometer_client:0.11.0")
@@ -227,8 +227,8 @@ def test_thermometer(self):
self.create_agents(thermometer_aea_name, thermometer_client_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -240,7 +240,7 @@ def test_thermometer(self):
# add packages for agent one and run it
self.set_agent_context(thermometer_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/thermometer:0.12.0")
@@ -275,7 +275,7 @@ def test_thermometer(self):
# add packages for agent two and run it
self.set_agent_context(thermometer_client_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/thermometer_client:0.11.0")
diff --git a/tests/test_packages/test_skills/test_weather.py b/tests/test_packages/test_skills/test_weather.py
index 76f159df7a..7b6b15d03a 100644
--- a/tests/test_packages/test_skills/test_weather.py
+++ b/tests/test_packages/test_skills/test_weather.py
@@ -50,8 +50,8 @@ def test_weather(self):
self.create_agents(weather_station_aea_name, weather_client_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -63,7 +63,7 @@ def test_weather(self):
# prepare agent one (weather station)
self.set_agent_context(weather_station_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/weather_station:0.12.0")
@@ -98,7 +98,7 @@ def test_weather(self):
# prepare agent two (weather client)
self.set_agent_context(weather_client_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/weather_client:0.11.0")
@@ -222,8 +222,8 @@ def test_weather(self):
self.create_agents(weather_station_aea_name, weather_client_aea_name)
default_routing = {
- "fetchai/ledger_api:0.3.0": "fetchai/ledger:0.6.0",
- "fetchai/oef_search:0.6.0": "fetchai/soef:0.8.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
}
# generate random location
@@ -235,7 +235,7 @@ def test_weather(self):
# add packages for agent one
self.set_agent_context(weather_station_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/weather_station:0.12.0")
@@ -272,7 +272,7 @@ def test_weather(self):
# add packages for agent two
self.set_agent_context(weather_client_aea_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
- self.add_item("connection", "fetchai/soef:0.8.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/weather_client:0.11.0")
diff --git a/tests/test_protocols/test_generator/test_end_to_end.py b/tests/test_protocols/test_generator/test_end_to_end.py
index c91a16a3c7..1fc3d6d87c 100644
--- a/tests/test_protocols/test_generator/test_end_to_end.py
+++ b/tests/test_protocols/test_generator/test_end_to_end.py
@@ -75,7 +75,7 @@ def test_generated_protocol_end_to_end(self):
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.9.0"))
+ builder_1.set_default_connection(PublicId.from_str("fetchai/oef:0.10.0"))
builder_1.add_protocol(
Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa")
)
@@ -101,7 +101,7 @@ def test_generated_protocol_end_to_end(self):
builder_2.add_protocol(
Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")
)
- builder_2.set_default_connection(PublicId.from_str("fetchai/oef:0.9.0"))
+ builder_2.set_default_connection(PublicId.from_str("fetchai/oef:0.10.0"))
builder_2.add_component(
ComponentType.PROTOCOL,
Path(PATH_TO_T_PROTOCOL),
@@ -112,8 +112,12 @@ def test_generated_protocol_end_to_end(self):
)
# create AEAs
- aea_1 = builder_1.build(connection_ids=[PublicId.from_str("fetchai/oef:0.9.0")])
- aea_2 = builder_2.build(connection_ids=[PublicId.from_str("fetchai/oef:0.9.0")])
+ aea_1 = builder_1.build(
+ connection_ids=[PublicId.from_str("fetchai/oef:0.10.0")]
+ )
+ aea_2 = builder_2.build(
+ connection_ids=[PublicId.from_str("fetchai/oef:0.10.0")]
+ )
# dialogues
def role_from_first_message_1(
diff --git a/tests/test_registries/test_base.py b/tests/test_registries/test_base.py
index 35c145764a..693b2f2875 100644
--- a/tests/test_registries/test_base.py
+++ b/tests/test_registries/test_base.py
@@ -153,7 +153,7 @@ def setup_class(cls):
cls.expected_protocol_ids = {
DEFAULT_PROTOCOL,
- PublicId.from_str("fetchai/fipa:0.6.0"),
+ PublicId.from_str("fetchai/fipa:0.7.0"),
}
def test_fetch_all(self):
diff --git a/tests/test_test_tools/test_testcases.py b/tests/test_test_tools/test_testcases.py
index 0a4567d923..eee7a70b28 100644
--- a/tests/test_test_tools/test_testcases.py
+++ b/tests/test_test_tools/test_testcases.py
@@ -102,7 +102,7 @@ def fn():
def test_fetch_and_delete(self):
"""Fetch and delete agent from repo."""
agent_name = "some_agent_for_tests"
- self.fetch_agent("fetchai/my_first_aea:0.11.0", agent_name)
+ self.fetch_agent("fetchai/my_first_aea:0.12.0", agent_name)
assert os.path.exists(agent_name)
self.delete_agents(agent_name)
assert not os.path.exists(agent_name)
@@ -110,7 +110,7 @@ def test_fetch_and_delete(self):
def test_diff(self):
"""Test difference_to_fetched_agent."""
agent_name = "some_agent_for_tests2"
- self.fetch_agent("fetchai/my_first_aea:0.11.0", agent_name)
+ self.fetch_agent("fetchai/my_first_aea:0.12.0", agent_name)
self.run_cli_command(
"config", "set", "agent.default_ledger", "test_ledger", cwd=agent_name
)
@@ -119,7 +119,7 @@ def test_diff(self):
)
assert b"test_ledger" in result.stdout_bytes
diff = self.difference_to_fetched_agent(
- "fetchai/my_first_aea:0.11.0", agent_name
+ "fetchai/my_first_aea:0.12.0", agent_name
)
assert diff
assert "test_ledger" in diff[1]
@@ -127,9 +127,9 @@ def test_diff(self):
def test_no_diff(self):
"""Test no difference for two aea configs."""
agent_name = "some_agent_for_tests3"
- self.fetch_agent("fetchai/my_first_aea:0.11.0", agent_name)
+ self.fetch_agent("fetchai/my_first_aea:0.12.0", agent_name)
diff = self.difference_to_fetched_agent(
- "fetchai/my_first_aea:0.11.0", agent_name
+ "fetchai/my_first_aea:0.12.0", agent_name
)
assert not diff
@@ -168,10 +168,10 @@ class TestAddAndRejectComponent(AEATestCaseEmpty):
def test_add_and_eject(self):
"""Test add/reject components."""
- result = self.add_item("skill", "fetchai/echo:0.7.0", local=True)
+ result = self.add_item("skill", "fetchai/echo:0.8.0", local=True)
assert result.exit_code == 0
- result = self.eject_item("skill", "fetchai/echo:0.7.0")
+ result = self.eject_item("skill", "fetchai/echo:0.8.0")
assert result.exit_code == 0
@@ -218,7 +218,7 @@ class TestSendReceiveEnvelopesSkill(AEATestCaseEmpty):
def test_send_receive_envelope(self):
"""Run the echo skill sequence."""
- self.add_item("skill", "fetchai/echo:0.7.0")
+ self.add_item("skill", "fetchai/echo:0.8.0")
process = self.run_agent()
is_running = self.is_running(process)
From ea6e546349038cf07e3592ddb79cdafdf975dd0c Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 22 Sep 2020 16:31:59 +0200
Subject: [PATCH 052/131] Avoid public ids with 'latest' version are stored in
configuration files.
---
aea/cli/add.py | 2 +-
aea/configurations/schemas/definitions.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/aea/cli/add.py b/aea/cli/add.py
index 093a881751..ae3c86133c 100644
--- a/aea/cli/add.py
+++ b/aea/cli/add.py
@@ -128,7 +128,7 @@ def add_item(ctx: Context, item_type: str, item_public_id: PublicId) -> None:
raise click.ClickException("Failed to add an item with incorrect fingerprint.")
_add_item_deps(ctx, item_type, item_config)
- register_item(ctx, item_type, item_public_id)
+ register_item(ctx, item_type, item_config.public_id)
def _add_item_deps(ctx: Context, item_type: str, item_config) -> None:
diff --git a/aea/configurations/schemas/definitions.json b/aea/configurations/schemas/definitions.json
index 6f956b5d10..c723ad8584 100644
--- a/aea/configurations/schemas/definitions.json
+++ b/aea/configurations/schemas/definitions.json
@@ -79,7 +79,7 @@
},
"public_id": {
"type": "string",
- "pattern": "^[a-zA-Z0-9_]*/[a-zA-Z_][a-zA-Z0-9_]*:(latest|(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)$"
+ "pattern": "^[a-zA-Z0-9_]*/[a-zA-Z_][a-zA-Z0-9_]*:(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
},
"version_specifiers": {
"type": "string",
From ad675454b3a03e8a36916d4ad0cd472e67faa946 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 22 Sep 2020 16:43:53 +0200
Subject: [PATCH 053/131] make isort to skip recursive links
---
setup.cfg | 3 +++
1 file changed, 3 insertions(+)
diff --git a/setup.cfg b/setup.cfg
index 66cc5a801c..37bfb84bfa 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -36,6 +36,9 @@ line_length=88
order_by_type=False
case_sensitive=True
lines_after_imports=2
+skip =
+ tests/data/dummy_aea/vendor/
+ tests/data/dummy_aea/skills/dummy
skip_glob = **/*_pb2.py
known_first_party=aea
known_packages=packages
From 5e9f1d6b66ed12edb4b067a83ad3e924a832df45 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Tue, 22 Sep 2020 21:08:41 +0100
Subject: [PATCH 054/131] add docs for generic command usage
---
aea/registries/base.py | 8 ++++++--
docs/simple-oef-usage.md | 31 ++++++++++++++++++++++++++++++-
2 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/aea/registries/base.py b/aea/registries/base.py
index 6daffeea9b..2d32db2864 100644
--- a/aea/registries/base.py
+++ b/aea/registries/base.py
@@ -142,13 +142,17 @@ def register( # pylint: disable=arguments-differ,unused-argument
raise ValueError(f"Item already registered with item id '{public_id}'")
self._public_id_to_item[public_id] = item
- def unregister(self, public_id: PublicId) -> None:
+ def unregister( # pylint: disable=arguments-differ
+ self, public_id: PublicId
+ ) -> None:
"""Unregister an item."""
if public_id not in self._public_id_to_item:
raise ValueError(f"No item registered with item id '{public_id}'")
self._public_id_to_item.pop(public_id)
- def fetch(self, public_id: PublicId) -> Optional[Item]:
+ def fetch( # pylint: disable=arguments-differ
+ self, public_id: PublicId
+ ) -> Optional[Item]:
"""
Fetch an item associated with a public id.
diff --git a/docs/simple-oef-usage.md b/docs/simple-oef-usage.md
index 450f96d605..db1a22de30 100644
--- a/docs/simple-oef-usage.md
+++ b/docs/simple-oef-usage.md
@@ -154,4 +154,33 @@ message = OefSearchMessage(
)
```
-In case of error you will received a message with `OefSearchMessage.Performative.OEF_ERROR`. In case of successful search you will receive a message with performative `OefSearchMessage.Performative.SEARCH_RESULT` and the list of matched agents addresses.
\ No newline at end of file
+In case of error you will received a message with `OefSearchMessage.Performative.OEF_ERROR`. In case of successful search you will receive a message with performative `OefSearchMessage.Performative.SEARCH_RESULT` and the list of matched agents addresses.
+
+## Generic command
+
+To send a generic command request to the SOEF use the following (here on the example of setting a declared name):
+``` python
+import urllib
+
+AGENT_GENERIC_COMMAND_MODEL = DataModel(
+ "generic_command",
+ [
+ Attribute("command", str, True, "Command name to execute."),
+ Attribute("parameters", str, False, "Url encoded parameters string."),
+ ],
+ "A data model to describe the generic soef command.",
+)
+
+declared_name = "new_declared_name"
+service_description = Description(
+ {
+ "command": "set_declared_name",
+ "parameters": urllib.parse.urlencode({"name": declared_name}),
+ },
+ data_model=AGENT_GENERIC_COMMAND_MODEL,
+)
+message = OefSearchMessage(
+ performative=OefSearchMessage.Performative.REGISTER_SERVICE,
+ service_description=service_description,
+)
+```
\ No newline at end of file
From eab7b9f552876d6d96fbf60e269497beae69f347 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Tue, 22 Sep 2020 22:46:23 +0100
Subject: [PATCH 055/131] small fixes to configs and soef
---
aea/cli/utils/config.py | 4 +++-
aea/configurations/base.py | 2 +-
docs/tac-skills.md | 5 +++--
.../tac_controller_contract/aea-config.yaml | 20 +++++++++++++++++++
.../fetchai/connections/soef/connection.py | 2 +-
.../fetchai/connections/soef/connection.yaml | 2 +-
.../fetchai/skills/tac_control/skill.yaml | 1 -
packages/hashes.csv | 4 ++--
8 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/aea/cli/utils/config.py b/aea/cli/utils/config.py
index 71bc9b50ff..cddfa28a32 100644
--- a/aea/cli/utils/config.py
+++ b/aea/cli/utils/config.py
@@ -46,7 +46,7 @@
_get_default_configuration_file_name_from_type,
)
from aea.configurations.loader import ConfigLoader, ConfigLoaders
-from aea.exceptions import AEAException
+from aea.exceptions import AEAException, AEAEnforceError
def try_to_load_agent_config(
@@ -83,6 +83,8 @@ def try_to_load_agent_config(
DEFAULT_AEA_CONFIG_FILE
)
)
+ except AEAEnforceError as e:
+ raise click.ClickException(str(e))
def _init_cli_config() -> None:
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 1a68f8de41..0d664ada0b 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -1105,7 +1105,7 @@ class SkillConfig(ComponentConfiguration):
default_configuration_filename = DEFAULT_SKILL_CONFIG_FILE
package_type = PackageType.SKILL
- configurable_fields = {"handlers", "behaviours", "models"}
+ configurable_fields = {"handlers", "behaviours", "models", "is_abstract"}
def __init__(
self,
diff --git a/docs/tac-skills.md b/docs/tac-skills.md
index c70415a668..7813d82cb9 100644
--- a/docs/tac-skills.md
+++ b/docs/tac-skills.md
@@ -206,8 +206,9 @@ aea add-key fetchai fetchai_private_key.txt --connection
Navigate to the tac controller project, then use the command line to get and set the start time (set it to at least two minutes in the future):
``` bash
-aea config get vendor.fetchai.skills.tac_control.models.parameters.args.start_time
-aea config set vendor.fetchai.skills.tac_control.models.parameters.args.start_time '01 01 2020 00:01'
+aea config get vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time
+aea config set vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time '01 01 2020 00:01'
+aea config set vendor.fetchai.skills.tac_control.is_abstract false --type bool
```
### Update the connection params
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index 5e20c223bc..78c49b9a9a 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -36,3 +36,23 @@ default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
fetchai/ledger_api:0.5.0: fetchai/ledger:0.6.0
fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+...
+---
+author: fetchai
+name: soef
+version: 0.8.0
+type: connection
+config:
+ api_key: TwiCIriSl0mLahw17pyqoA
+ chain_identifier: ethereum
+ soef_addr: soef.fetch.ai
+ soef_port: 9002
+...
+---
+author: fetchai
+name: tac_control
+version: 0.7.0
+type: skill
+is_abstract: true
+...
+
\ No newline at end of file
diff --git a/packages/fetchai/connections/soef/connection.py b/packages/fetchai/connections/soef/connection.py
index 622543e773..4d35f8bf9f 100644
--- a/packages/fetchai/connections/soef/connection.py
+++ b/packages/fetchai/connections/soef/connection.py
@@ -820,7 +820,7 @@ async def _register_agent(self) -> None:
unique_token = child.text
if not (len(unique_page_address) > 0 and len(unique_token) > 0):
raise SOEFException.error(
- "Agent registration error - page address or token not received"
+ f"Agent registration error - page address or token not received. Response text: {response_text}"
)
self.logger.debug("Registering agent")
params = {"token": unique_token}
diff --git a/packages/fetchai/connections/soef/connection.yaml b/packages/fetchai/connections/soef/connection.yaml
index f11cd94684..f9a8051241 100644
--- a/packages/fetchai/connections/soef/connection.yaml
+++ b/packages/fetchai/connections/soef/connection.yaml
@@ -8,7 +8,7 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmWwjETX39APP9RD5oVPeeCiDnUoDvjAcoVe2FK2Jc6anM
__init__.py: Qmd5VBGFJHXFe1H45XoUh5mMSYBwvLSViJuGFeMgbPdQts
- connection.py: QmfK5khjQuqewKVuqyedgmToQvRbh69oT8f5WcSvzvvjJL
+ connection.py: QmTcFbNone1bWPiAAAbVNfB1LEdTGMHv2s4iJBTAbuFJFv
fingerprint_ignore_patterns: []
protocols:
- fetchai/oef_search:0.6.0
diff --git a/packages/fetchai/skills/tac_control/skill.yaml b/packages/fetchai/skills/tac_control/skill.yaml
index 222032e936..db890e4335 100644
--- a/packages/fetchai/skills/tac_control/skill.yaml
+++ b/packages/fetchai/skills/tac_control/skill.yaml
@@ -73,4 +73,3 @@ models:
class_name: TacDialogues
dependencies:
numpy: {}
-is_abstract: true
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 90e6d12884..18edf9fbda 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -28,7 +28,7 @@ fetchai/connections/p2p_libp2p,QmVXSnhCn37mgacK7iG1HENbEkSvSZMMaf9RTFCUUDa2C9
fetchai/connections/p2p_libp2p_client,QmVEwABjAPTZcA4BaAgn8BnzUCpHQbSzc4pJ6mdR4bW222
fetchai/connections/p2p_stub,QmX8EWvFok3UAdqXGgir4TrhfDj2kLhfjuXRg82b6G6XtW
fetchai/connections/scaffold,QmNUta43nLexAHaXLgmLQYEjntLXSV6MLNvc6Q2CTx7eBS
-fetchai/connections/soef,QmQWyjmHg6HWsLEuighe2vrWQSKBZAXvoXSXF33XhaVyE8
+fetchai/connections/soef,QmQ9EoLHBwmhnfbsaTBWYaf6NHKx2uCC9q7F95zwySmtYU
fetchai/connections/stub,QmSuUAA2k1E1M9dpeAgkWpfKdssjqghSDfFfrQzC9ZLKbD
fetchai/connections/tcp,QmU93B7yajCHwXsgDXXhv1uSuXi7VmFBhdahcFosbrr6nA
fetchai/connections/webhook,QmaJunWQT1ypkqGnzrj5gYjjQBywjTHJmyktCZXZsa8hv8
@@ -62,7 +62,7 @@ fetchai/skills/ml_data_provider,QmdgxfES4XpmREpp9QqPQRMH9TvTF9nZ21zKM5RHLGCLke
fetchai/skills/ml_train,QmbRQZz1MPXXuWyNW3BqhcsZKtZPhYakxGkVrBswNTgfk9
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmeckN8mcKLeqmJoQfdYqPsJ49nbxxwBhYPhjkTS99v1De
-fetchai/skills/tac_control,QmTcQU7qs8toZMB4KgpxbcBiQj8Eucytq48XP4tGGTYPDD
+fetchai/skills/tac_control,QmebwggsT7Shux6S2qw9Rg7WC1MF2rdbWUYmDz8ChrGf21
fetchai/skills/tac_control_contract,QmahExwhU8sYaZC7PGD1ShrPNdzAM4AEPZ6eGhsrQk8umk
fetchai/skills/tac_negotiation,QmRCZWxUh6mkaBsa1CYNk3fmNKzSVxfiqwYGbzU1E3672F
fetchai/skills/tac_participation,QmWBATSrN9J3XoqMJ89iniMnMDZZpLqoenWTigukaDasQG
From 2d71d1772a287c5b3bbb19cc14117ae99fb9feee Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 23 Sep 2020 12:53:44 +0200
Subject: [PATCH 056/131] update generate_ipfs_hashes script to support
multipaged yamls
---
.../agents/tac_controller_contract/aea-config.yaml | 8 ++------
packages/hashes.csv | 2 +-
scripts/generate_ipfs_hashes.py | 10 +++++-----
3 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index 78c49b9a9a..e4e41fa851 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -36,10 +36,9 @@ default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
fetchai/ledger_api:0.5.0: fetchai/ledger:0.6.0
fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
-...
---
-author: fetchai
name: soef
+author: fetchai
version: 0.8.0
type: connection
config:
@@ -47,12 +46,9 @@ config:
chain_identifier: ethereum
soef_addr: soef.fetch.ai
soef_port: 9002
-...
---
-author: fetchai
name: tac_control
+author: fetchai
version: 0.7.0
type: skill
is_abstract: true
-...
-
\ No newline at end of file
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 0b9c68e00b..ea255ffa61 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -12,7 +12,7 @@ fetchai/agents/ml_model_trainer,QmeZmVsNLUw7TP73s5cSomPnwggcrimXHh1RhrPRUDkoQ3
fetchai/agents/my_first_aea,QmcHnFYQCyXnAM2pN2M4HqLNGJpWApUP7PuiKaPcLkxbas
fetchai/agents/simple_service_registration,QmWtA9eDYnGKkg5hov887LRJSXTXovb9pp4NJzU7JMq5Lg
fetchai/agents/tac_controller,QmaG56sZaJRm8DwJXXt9Ci18Va8NfXx6v8vEGKPJngKL4q
-fetchai/agents/tac_controller_contract,QmWQRysyhhATUqxRxrAqvEvcdjzCiDGkZDzp7f7yvRTAz4
+fetchai/agents/tac_controller_contract,QmebUjsztRPpidkaDLdxDqM3JGbQG3Rb5Li8CSwyrnLMWp
fetchai/agents/tac_participant,QmQxN75ZFVEgizNHa3sqd2zHSnmPvRwS8PCv5FAsJBDnZw
fetchai/agents/thermometer_aea,QmQ8KgTrt5fH8ZRDpioKGmeyUyc2EUkan4D5KzoFnCwxcG
fetchai/agents/thermometer_client,QmUY6rmZnufWWmwfSi1m5gR6vD1ZowXpchpUJXgAH6xdNP
diff --git a/scripts/generate_ipfs_hashes.py b/scripts/generate_ipfs_hashes.py
index 017b7deb42..4813357fe5 100755
--- a/scripts/generate_ipfs_hashes.py
+++ b/scripts/generate_ipfs_hashes.py
@@ -41,7 +41,6 @@
from typing import Collection, Dict, List, Optional, Tuple, Type, cast
import ipfshttpclient
-import yaml
from aea.configurations.base import (
AgentConfig,
@@ -53,6 +52,7 @@
SkillConfig,
_compute_fingerprint,
)
+from aea.configurations.loader import ConfigLoaders
from aea.helpers.base import yaml_dump, yaml_dump_all
@@ -254,10 +254,10 @@ def load_configuration(
configuration_filepath = (
package_path / configuration_class.default_configuration_filename
)
- configuration_obj = cast(
- PackageConfiguration,
- configuration_class.from_json(yaml.safe_load(configuration_filepath.open())),
- )
+
+ loader = ConfigLoaders.from_package_type(package_type)
+ with configuration_filepath.open() as fp:
+ configuration_obj = loader.load(fp)
configuration_obj._directory = package_path # pylint: disable=protected-access
return cast(PackageConfiguration, configuration_obj)
From 07bea7bbdf09c920a6a0eb90c67d34e0b6974f0a Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 23 Sep 2020 14:02:50 +0200
Subject: [PATCH 057/131] update check_package_dependencies script to
accomodate multi-paged yamls
---
.../tac_controller_contract/aea-config.yaml | 16 ++++++-------
.../skills/tac_control_contract/skill.yaml | 10 ++++----
scripts/check_package_dependencies.py | 24 ++++++++++++++++---
3 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index e4e41fa851..07f496c969 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -10,20 +10,20 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
-- fetchai/soef:0.8.0
+- fetchai/soef:0.9.0
- fetchai/stub:0.9.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
- fetchai/contract_api:0.5.0
-- fetchai/default:0.5.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
-- fetchai/tac:0.6.0
+- fetchai/default:0.6.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
+- fetchai/tac:0.7.0
skills:
-- fetchai/error:0.5.0
-- fetchai/tac_control:0.7.0
+- fetchai/error:0.6.0
+- fetchai/tac_control:0.8.0
- fetchai/tac_control_contract:0.9.0
default_connection: fetchai/p2p_libp2p:0.10.0
default_ledger: ethereum
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index 24ade8c708..7f0c33ec9e 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -20,12 +20,12 @@ contracts:
- fetchai/erc1155:0.10.0
protocols:
- fetchai/contract_api:0.5.0
-- fetchai/ledger_api:0.3.0
-- fetchai/oef_search:0.6.0
-- fetchai/signing:0.3.0
-- fetchai/tac:0.6.0
+- fetchai/ledger_api:0.4.0
+- fetchai/oef_search:0.7.0
+- fetchai/signing:0.4.0
+- fetchai/tac:0.7.0
skills:
-- fetchai/tac_control:0.7.0
+- fetchai/tac_control:0.8.0
behaviours:
tac:
args: {}
diff --git a/scripts/check_package_dependencies.py b/scripts/check_package_dependencies.py
index 882030b6e8..8904b9675b 100755
--- a/scripts/check_package_dependencies.py
+++ b/scripts/check_package_dependencies.py
@@ -30,7 +30,7 @@
from functools import partial
from itertools import chain
from pathlib import Path
-from typing import Set
+from typing import Dict, Set
import yaml
@@ -88,7 +88,7 @@ def get_public_id_from_yaml(configuration_file: Path):
:param configuration_file: the path to the config yaml
"""
- data = yaml.safe_load(configuration_file.open())
+ data = unified_yaml_load(configuration_file)
author = data["author"]
# handle the case when it's a package or agent config file.
name = data["name"] if "name" in data else data["agent_name"]
@@ -118,6 +118,24 @@ def handle_dependency_not_found(e: DependencyNotFound):
print(f"Missing: {pprint.pformat(sorted_missing)}")
+def unified_yaml_load(configuration_file: Path) -> Dict:
+ """
+ Load YAML file, unified (both single- and multi-paged).
+
+ :param configuration_file: the configuration file path.
+ :return: the data.
+ """
+ package_type = configuration_file.parent.parent.name
+ with configuration_file.open() as fp:
+ if package_type != "agents":
+ return yaml.safe_load(fp)
+ # when it is an agent configuration file,
+ # we are interested only in the first page of the YAML,
+ # because the dependencies are contained only there.
+ data = yaml.safe_load_all(fp)
+ return list(data)[0]
+
+
def check_dependencies(configuration_file: Path, all_packages_ids: Set[PackageId]):
"""
Check dependencies of configuration file.
@@ -126,7 +144,7 @@ def check_dependencies(configuration_file: Path, all_packages_ids: Set[PackageId
:param all_packages_ids: all the package ids.
:return: None
"""
- data = yaml.safe_load(configuration_file.open())
+ data = unified_yaml_load(configuration_file)
def _add_package_type(package_type, public_id_str):
return PackageId(package_type, PublicId.from_str(public_id_str))
From f87d67c4b2a10d1eebbf4520fff9bc35373f71f8 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 23 Sep 2020 14:07:09 +0200
Subject: [PATCH 058/131] update 'check_package_versions_in_docs'
---
scripts/check_package_versions_in_docs.py | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/scripts/check_package_versions_in_docs.py b/scripts/check_package_versions_in_docs.py
index 33ddb38144..e89d59d6fa 100755
--- a/scripts/check_package_versions_in_docs.py
+++ b/scripts/check_package_versions_in_docs.py
@@ -29,7 +29,7 @@
import sys
from itertools import chain
from pathlib import Path
-from typing import Callable, Set
+from typing import Callable, Dict, Set
import yaml
@@ -92,13 +92,31 @@ def default_config_file_paths():
yield item
+def unified_yaml_load(configuration_file: Path) -> Dict:
+ """
+ Load YAML file, unified (both single- and multi-paged).
+
+ :param configuration_file: the configuration file path.
+ :return: the data.
+ """
+ package_type = configuration_file.parent.parent.name
+ with configuration_file.open() as fp:
+ if package_type != "agents":
+ return yaml.safe_load(fp)
+ # when it is an agent configuration file,
+ # we are interested only in the first page of the YAML,
+ # because the dependencies are contained only there.
+ data = yaml.safe_load_all(fp)
+ return list(data)[0]
+
+
def get_public_id_from_yaml(configuration_file: Path):
"""
Get the public id from yaml.
:param configuration_file: the path to the config yaml
"""
- data = yaml.safe_load(configuration_file.open())
+ data = unified_yaml_load(configuration_file)
author = data["author"]
# handle the case when it's a package or agent config file.
name = data["name"] if "name" in data else data["agent_name"]
From 087a3dce49d7d5d4dae647d405c4c8296f0a95d5 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 23 Sep 2020 14:13:36 +0200
Subject: [PATCH 059/131] fix versions in tac_controller_contract agent
---
.../fetchai/agents/tac_controller_contract/aea-config.yaml | 4 ++--
packages/hashes.csv | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index 07f496c969..efbe561f76 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -39,7 +39,7 @@ default_routing:
---
name: soef
author: fetchai
-version: 0.8.0
+version: 0.9.0
type: connection
config:
api_key: TwiCIriSl0mLahw17pyqoA
@@ -49,6 +49,6 @@ config:
---
name: tac_control
author: fetchai
-version: 0.7.0
+version: 0.8.0
type: skill
is_abstract: true
diff --git a/packages/hashes.csv b/packages/hashes.csv
index ea255ffa61..37510f2a00 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -12,7 +12,7 @@ fetchai/agents/ml_model_trainer,QmeZmVsNLUw7TP73s5cSomPnwggcrimXHh1RhrPRUDkoQ3
fetchai/agents/my_first_aea,QmcHnFYQCyXnAM2pN2M4HqLNGJpWApUP7PuiKaPcLkxbas
fetchai/agents/simple_service_registration,QmWtA9eDYnGKkg5hov887LRJSXTXovb9pp4NJzU7JMq5Lg
fetchai/agents/tac_controller,QmaG56sZaJRm8DwJXXt9Ci18Va8NfXx6v8vEGKPJngKL4q
-fetchai/agents/tac_controller_contract,QmebUjsztRPpidkaDLdxDqM3JGbQG3Rb5Li8CSwyrnLMWp
+fetchai/agents/tac_controller_contract,QmXhKdptR5aW4TAx9J4auFGqwR3TpiTzdpsKp8KRHL7w7B
fetchai/agents/tac_participant,QmQxN75ZFVEgizNHa3sqd2zHSnmPvRwS8PCv5FAsJBDnZw
fetchai/agents/thermometer_aea,QmQ8KgTrt5fH8ZRDpioKGmeyUyc2EUkan4D5KzoFnCwxcG
fetchai/agents/thermometer_client,QmUY6rmZnufWWmwfSi1m5gR6vD1ZowXpchpUJXgAH6xdNP
@@ -63,7 +63,7 @@ fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
fetchai/skills/tac_control,QmTgw37facaPnt9RQcHNPzFasDmgG1PktEo2ZHfNqPjXet
-fetchai/skills/tac_control_contract,QmbQgPstHthGrNE4tFyreFhp4K1HzGzEdtEcxPtGpeJT1N
+fetchai/skills/tac_control_contract,QmTLPBLPZKdQRreeMbeuppRNJnGUr7YSqh7RULnEKkrKFy
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
From 1b93527b99c4348435e442310581c41a25786c56 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 23 Sep 2020 14:42:29 +0200
Subject: [PATCH 060/131] make 'is_abstract' a configurable field for skills
---
aea/aea_builder.py | 12 ++++++------
aea/configurations/base.py | 2 ++
tests/test_aea_builder.py | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index a3570bbdef..3eb5421f15 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -1365,6 +1365,12 @@ def _load_and_add_components(
for configuration in self._package_dependency_manager.get_components_by_type(
component_type
).values():
+ configuration = deepcopy(configuration)
+ configuration.update(
+ self._custom_component_configurations.get(
+ configuration.component_id, {}
+ )
+ )
if configuration.is_abstract_component:
load_aea_package(configuration)
continue
@@ -1376,12 +1382,6 @@ def _load_and_add_components(
logging.Logger, make_logger(configuration, agent_name)
)
else:
- configuration = deepcopy(configuration)
- configuration.update(
- self._custom_component_configurations.get(
- configuration.component_id, {}
- )
- )
_logger = make_logger(configuration, agent_name)
component = load_component_from_config(
configuration, logger=_logger, **kwargs
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 09671d7c89..d59c28b5bd 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -1333,6 +1333,8 @@ def update(self, data: Dict) -> None:
model_config = SkillComponentConfiguration.from_json(model_data)
self.models.update(model_id, model_config)
+ self.is_abstract = data.get("is_abstract", self.is_abstract)
+
class AgentConfig(PackageConfiguration):
"""Class to represent the agent configuration file."""
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index 60c1c3858b..0bffd7927a 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -654,6 +654,43 @@ def test_from_project(self):
assert dummy_model.config == self.expected_model_args
+class TestFromAEAProjectMakeSkillAbstract(AEATestCase):
+ """Test builder set from project dir, to make a skill 'abstract'."""
+
+ path_to_aea = Path(CUR_PATH) / "data" / "dummy_aea"
+
+ def _add_dummy_skill_config(self):
+ """Add custom stub connection config."""
+ cwd = self._get_cwd()
+ aea_config_file = Path(cwd, DEFAULT_AEA_CONFIG_FILE)
+ configuration = aea_config_file.read_text()
+ # here we change all the dummy skill configurations
+ configuration += dedent(
+ f"""
+ ---
+ name: dummy
+ author: dummy_author
+ version: 0.1.0
+ type: skill
+ is_abstract: true
+ ...
+ """
+ )
+ aea_config_file.write_text(configuration)
+
+ def test_from_project(self):
+ """Test builder set from project dir."""
+ self._add_dummy_skill_config()
+ builder = AEABuilder.from_aea_project(Path(self._get_cwd()))
+ with cd(self._get_cwd()):
+ aea = builder.build()
+
+ dummy_skill = aea.resources.get_skill(
+ PublicId("dummy_author", "dummy", "0.1.0")
+ )
+ assert dummy_skill is None, "Shouldn't have found the skill in Resources."
+
+
class TestFromAEAProjectCustomConfigFailsWhenComponentNotDeclared(AEATestCaseEmpty):
"""Test builder set from project dir with custom component config fails when the component is not declared in the agent configuration."""
From 63d0d7b70127dbd73c44175a9bf8e0fea3629ab9 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 23 Sep 2020 14:51:30 +0200
Subject: [PATCH 061/131] update custom component config only for non-instance
components in builder
---
aea/aea_builder.py | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index 3eb5421f15..ee5b77abe8 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -1365,16 +1365,6 @@ def _load_and_add_components(
for configuration in self._package_dependency_manager.get_components_by_type(
component_type
).values():
- configuration = deepcopy(configuration)
- configuration.update(
- self._custom_component_configurations.get(
- configuration.component_id, {}
- )
- )
- if configuration.is_abstract_component:
- load_aea_package(configuration)
- continue
-
if configuration in self._component_instances[component_type].keys():
component = self._component_instances[component_type][configuration]
if configuration.component_type != ComponentType.SKILL:
@@ -1382,6 +1372,15 @@ def _load_and_add_components(
logging.Logger, make_logger(configuration, agent_name)
)
else:
+ configuration = deepcopy(configuration)
+ configuration.update(
+ self._custom_component_configurations.get(
+ configuration.component_id, {}
+ )
+ )
+ if configuration.is_abstract_component:
+ load_aea_package(configuration)
+ continue
_logger = make_logger(configuration, agent_name)
component = load_component_from_config(
configuration, logger=_logger, **kwargs
From f5ee060be0b882f12feceeccefa371b6959745ef Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 15:14:14 +0100
Subject: [PATCH 062/131] fix tests
---
docs/tac-skills-contract.md | 4 ++--
docs/tac-skills.md | 1 -
packages/fetchai/skills/tac_control_contract/dialogues.py | 2 +-
packages/fetchai/skills/tac_control_contract/skill.yaml | 2 +-
packages/hashes.csv | 2 +-
tests/test_aea_builder.py | 2 +-
6 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/docs/tac-skills-contract.md b/docs/tac-skills-contract.md
index 0ef6ee0985..75f3f7e628 100644
--- a/docs/tac-skills-contract.md
+++ b/docs/tac-skills-contract.md
@@ -217,8 +217,8 @@ Similar to how you funded the controller, fund both tac participants.
Navigate to the tac controller project, then use the command line to get and set the start time (set it to at least five minutes - better 10 - in the future):
``` bash
-aea config get vendor.fetchai.skills.tac_control_contract.models.parameters.args.start_time
-aea config set vendor.fetchai.skills.tac_control_contract.models.parameters.args.start_time '01 01 2020 00:01'
+aea config get vendor.fetchai.skills.tac_control_contract.models.parameters.args.registration_start_time
+aea config set vendor.fetchai.skills.tac_control_contract.models.parameters.args.registration_start_time '01 01 2020 00:01'
```
### Run the AEAs
diff --git a/docs/tac-skills.md b/docs/tac-skills.md
index 75aa76e58e..873c72ddf8 100644
--- a/docs/tac-skills.md
+++ b/docs/tac-skills.md
@@ -208,7 +208,6 @@ Navigate to the tac controller project, then use the command line to get and set
``` bash
aea config get vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time
aea config set vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time '01 01 2020 00:01'
-aea config set vendor.fetchai.skills.tac_control.is_abstract false --type bool
```
### Update the connection params
diff --git a/packages/fetchai/skills/tac_control_contract/dialogues.py b/packages/fetchai/skills/tac_control_contract/dialogues.py
index be35d63101..9e2b5c2588 100644
--- a/packages/fetchai/skills/tac_control_contract/dialogues.py
+++ b/packages/fetchai/skills/tac_control_contract/dialogues.py
@@ -124,7 +124,7 @@ def __init__(
self._callable = None # type: Optional[ContractApiDialogue.Callable]
@property
- def callable(self) -> Callable:
+ def callable(self) -> "Callable":
"""Get the callable."""
if self._callable is None:
raise ValueError("Callable not set!")
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index 7f0c33ec9e..73c3ff5b53 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -10,7 +10,7 @@ fingerprint:
README.md: QmUiw6Dt97mXLzSizbnMNTsfLy3edGXKdYTNR5bke6sFsm
__init__.py: QmW9WBy1sNYVKpymGnpJY2pW5MEqGgVga2kBFUT9S34Yt5
behaviours.py: QmYcW84nnvCuv2HeDntixfWnFuJA2k9xqrhCWdmVFerLPv
- dialogues.py: QmPNoMrAPBQb8ib5uwxxMXd8U8nG81uXt4no6WStS3pNob
+ dialogues.py: QmPJyBPETi7MggXLMKHWeYsAZbckxK2UFpci19dw3xwHDn
game.py: QmQwskD5DBVNv1ouRpqGNLb3zQ5krLUcR6XXHUcJ5EVc8L
handlers.py: QmSzNcZ3s3RjVm7mCXBhGjA379nwv3Tm9viEmw193WcNTd
helpers.py: QmX3iv37Z5CmGupCtikc4muTpJyQ9zvjeLbNKDLF7iPhSZ
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 37510f2a00..f2278b6f3a 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -63,7 +63,7 @@ fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
fetchai/skills/tac_control,QmTgw37facaPnt9RQcHNPzFasDmgG1PktEo2ZHfNqPjXet
-fetchai/skills/tac_control_contract,QmTLPBLPZKdQRreeMbeuppRNJnGUr7YSqh7RULnEKkrKFy
+fetchai/skills/tac_control_contract,QmYX4gNaGbx1EAuASwhpSgTdLYwUzuzajtKTuqvNFR9f2Q
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index 0bffd7927a..ff6a6b85e7 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -666,7 +666,7 @@ def _add_dummy_skill_config(self):
configuration = aea_config_file.read_text()
# here we change all the dummy skill configurations
configuration += dedent(
- f"""
+ """
---
name: dummy
author: dummy_author
From b3b65bb3f88601985dd84a16e71c4a2f79a61feb Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 16:20:54 +0100
Subject: [PATCH 063/131] add additional pylint options
---
.pylintrc | 7 +++--
aea/aea.py | 2 +-
aea/cli_gui/__init__.py | 2 +-
aea/crypto/cosmos.py | 4 ---
aea/helpers/async_utils.py | 2 +-
aea/helpers/exec_timeout.py | 2 +-
aea/helpers/search/generic.py | 2 +-
.../generator/extract_specification.py | 2 +-
aea/test_tools/test_cases.py | 2 +-
.../fetchai/connections/soef/connection.py | 29 ++++++++++---------
scripts/whitelist.py | 1 -
.../test_connections/test_soef/models.py | 12 ++++----
12 files changed, 32 insertions(+), 35 deletions(-)
diff --git a/.pylintrc b/.pylintrc
index 9b2784db56..eebe04c217 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -2,7 +2,7 @@
ignore-patterns=serialization.py,message.py,__main__.py,.*_pb2.py
[MESSAGES CONTROL]
-disable=C0103,C0201,C0301,C0302,C0330,W0105,W0107,W0707,W1202,W1203,R0902,R0913,R0914,R0801,R0904,R0903,R0911,R0912,R0901,R0916,R1702,R0915,R1725
+disable=C0103,C0201,C0301,C0302,C0330,W0105,W0107,W0707,W1202,W1203,R0902,R0913,R0914,R0801,R0904,R0911,R0912,R0901,R0916,R1702,R0915
## Eventually resolve these:
# W0707: raise-missing-from
@@ -10,14 +10,12 @@ disable=C0103,C0201,C0301,C0302,C0330,W0105,W0107,W0707,W1202,W1203,R0902,R0913,
# R0913: too-many-arguments
# R0914: too-many-locals
# R0904: too-many-public-methods
-# R0903: too-few-public-methods
# R0911: too-many-return-statements
# R0912: too-many-branches
# R0901: too-many-ancestors
# R0916: too-many-boolean-expressions
# R1702: too-many-nested-blocks
# R0915: too-many-statements
-# R1725: super-with-arguments
# decide on a logging policy:
# W1202: logging-format-interpolation
# W1203: logging-fstring-interpolation
@@ -34,3 +32,6 @@ disable=C0103,C0201,C0301,C0302,C0330,W0105,W0107,W0707,W1202,W1203,R0902,R0913,
[IMPORTS]
ignored-modules=aiohttp,defusedxml,gym,fetch,matplotlib,memory_profiler,numpy,oef,openapi_core,psutil,tensorflow,temper,skimage,vyper,web3
+
+[DESIGN]
+min-public-methods=1
\ No newline at end of file
diff --git a/aea/aea.py b/aea/aea.py
index bb3ff4c5e2..89a5022189 100644
--- a/aea/aea.py
+++ b/aea/aea.py
@@ -341,7 +341,7 @@ def get_message_handlers(self) -> List[Tuple[Callable[[Any], None], Callable]]:
:return: List of tuples of callables: handler and coroutine to get a message
"""
- return super(AEA, self).get_message_handlers() + [
+ return super().get_message_handlers() + [
(self.filter.handle_internal_message, self.filter.get_internal_message,),
]
diff --git a/aea/cli_gui/__init__.py b/aea/cli_gui/__init__.py
index e9a490bbf9..2690348e64 100644
--- a/aea/cli_gui/__init__.py
+++ b/aea/cli_gui/__init__.py
@@ -70,7 +70,7 @@
max_log_lines = 100
-class AppContext:
+class AppContext: # pylint: disable=too-few-public-methods
"""Store useful global information about the app.
Can't add it into the app object itself because mypy complains.
diff --git a/aea/crypto/cosmos.py b/aea/crypto/cosmos.py
index d0a94db085..59533cd3d9 100644
--- a/aea/crypto/cosmos.py
+++ b/aea/crypto/cosmos.py
@@ -864,10 +864,6 @@ class CosmosApi(_CosmosApi, CosmosHelper):
"""Class to interact with the Cosmos SDK via a HTTP APIs."""
-class CosmWasmCLIWrapper:
- """Wrapper of the CosmWasm CLI."""
-
-
""" Equivalent to:
@dataclass
diff --git a/aea/helpers/async_utils.py b/aea/helpers/async_utils.py
index 3adb111db1..0723a00b58 100644
--- a/aea/helpers/async_utils.py
+++ b/aea/helpers/async_utils.py
@@ -474,6 +474,6 @@ def __init__(self, getters: List[Tuple[Callable[[Any], None], Callable]]):
:param getters: List of tuples of handler and couroutine to be awaiteed for an item.
"""
- super(HandlerItemGetter, self).__init__(
+ super().__init__(
[self._make_getter(handler, getter) for handler, getter in getters]
)
diff --git a/aea/helpers/exec_timeout.py b/aea/helpers/exec_timeout.py
index 674e80e79b..b6b605cb18 100644
--- a/aea/helpers/exec_timeout.py
+++ b/aea/helpers/exec_timeout.py
@@ -136,7 +136,7 @@ def _remove_timeout_watch(self) -> None:
raise NotImplementedError # pragma: nocover
-class ExecTimeoutSigAlarm(BaseExecTimeout):
+class ExecTimeoutSigAlarm(BaseExecTimeout): # pylint: disable=too-few-public-methods
"""
ExecTimeout context manager implementation using signals and SIGALARM.
diff --git a/aea/helpers/search/generic.py b/aea/helpers/search/generic.py
index 5891d71a3a..ec9abd8c3d 100644
--- a/aea/helpers/search/generic.py
+++ b/aea/helpers/search/generic.py
@@ -28,7 +28,7 @@
SUPPORTED_TYPES = {"str": str, "int": int, "float": float, "bool": bool}
-class GenericDataModel(DataModel):
+class GenericDataModel(DataModel): # pylint: disable=too-few-public-methods
"""Generic data model."""
def __init__(self, data_model_name: str, data_model_attributes: Dict[str, Any]):
diff --git a/aea/protocols/generator/extract_specification.py b/aea/protocols/generator/extract_specification.py
index e3f42cf45c..550c3d5dc1 100644
--- a/aea/protocols/generator/extract_specification.py
+++ b/aea/protocols/generator/extract_specification.py
@@ -143,7 +143,7 @@ def _specification_type_to_python_type(specification_type: str) -> str:
return python_type
-class PythonicProtocolSpecification:
+class PythonicProtocolSpecification: # pylint: disable=too-few-public-methods
"""This class represents a protocol specification in python."""
def __init__(self) -> None:
diff --git a/aea/test_tools/test_cases.py b/aea/test_tools/test_cases.py
index 55e1b9d2bc..d058f4d1f9 100644
--- a/aea/test_tools/test_cases.py
+++ b/aea/test_tools/test_cases.py
@@ -798,7 +798,7 @@ def teardown_class(cls):
@pytest.mark.integration
-class UseOef:
+class UseOef: # pylint: disable=too-few-public-methods
"""Inherit from this class to launch an OEF node."""
@pytest.fixture(autouse=True)
diff --git a/packages/fetchai/connections/soef/connection.py b/packages/fetchai/connections/soef/connection.py
index 0a0f6c4a28..66a39a80b3 100644
--- a/packages/fetchai/connections/soef/connection.py
+++ b/packages/fetchai/connections/soef/connection.py
@@ -26,6 +26,7 @@
from concurrent.futures._base import CancelledError as ConcurrentCancelledError
from concurrent.futures.thread import ThreadPoolExecutor
from contextlib import suppress
+from enum import Enum
from typing import Callable, Dict, List, Optional, Set, Type, Union, cast
from urllib import parse
from uuid import uuid4
@@ -80,16 +81,16 @@
]
-class ModelNames:
+class ModelNames(Enum):
"""Enum of supported data models."""
- location_agent = "location_agent"
- set_service_key = "set_service_key"
- remove_service_key = "remove_service_key"
- personality_agent = "personality_agent"
- search_model = "search_model"
- ping = "ping"
- generic_command = "generic_command"
+ LOCATION_AGENT = "location_agent"
+ SET_SERVICE_KEY = "set_service_key"
+ REMOVE_SERVICE_KEY = "remove_service_key"
+ PERSONALITY_AGENT = "personality_agent"
+ SEARCH_MODEL = "search_model"
+ PING = "ping"
+ GENERIC_COMMAND = "generic_command"
class SOEFException(Exception):
@@ -511,7 +512,7 @@ async def _ping_handler(
:return None
"""
- self._check_data_model(service_description, ModelNames.ping)
+ self._check_data_model(service_description, ModelNames.PING.value)
await self._ping_command()
async def _generic_command_handler(
@@ -531,7 +532,7 @@ async def _generic_command_handler(
"""not connected."""
return
- self._check_data_model(service_description, ModelNames.generic_command)
+ self._check_data_model(service_description, ModelNames.GENERIC_COMMAND.value)
command = service_description.values.get("command", None)
params = service_description.values.get("parameters", {})
@@ -593,7 +594,7 @@ async def _set_service_key_handler(
:param service_description: Service description
:return None
"""
- self._check_data_model(service_description, ModelNames.set_service_key)
+ self._check_data_model(service_description, ModelNames.SET_SERVICE_KEY.value)
key = service_description.values.get("key", None)
value = service_description.values.get("value", NOT_SPECIFIED)
@@ -654,7 +655,7 @@ async def _remove_service_key_handler(
:param service_description: Service description
:return None
"""
- self._check_data_model(service_description, ModelNames.remove_service_key)
+ self._check_data_model(service_description, ModelNames.REMOVE_SERVICE_KEY.value)
key = service_description.values.get("key", None)
if key is None: # pragma: nocover
@@ -683,7 +684,7 @@ async def _register_location_handler(
:param service_description: Service description
:return None
"""
- self._check_data_model(service_description, ModelNames.location_agent)
+ self._check_data_model(service_description, ModelNames.LOCATION_AGENT.value)
agent_location = service_description.values.get("location", None)
@@ -761,7 +762,7 @@ async def _set_personality_piece_handler(
:param piece: the piece to be set
:param value: the value to be set
"""
- self._check_data_model(service_description, ModelNames.personality_agent)
+ self._check_data_model(service_description, ModelNames.PERSONALITY_AGENT.value)
piece = service_description.values.get("piece", None)
value = service_description.values.get("value", None)
diff --git a/scripts/whitelist.py b/scripts/whitelist.py
index 296f020813..9547a8a7fa 100644
--- a/scripts/whitelist.py
+++ b/scripts/whitelist.py
@@ -78,7 +78,6 @@
_.try_execute_wasm_query # unused method (aea/crypto/cosmos.py:571)
_.get_last_code_id # unused method (aea/crypto/cosmos.py:837)
_.get_contract_address # unused method (aea/crypto/cosmos.py:849)
-CosmWasmCLIWrapper # unused class (aea/crypto/cosmos.py:863)
CosmosFaucetApi # unused class (aea/crypto/cosmos.py:867)
testnet_name # unused variable (aea/crypto/cosmos.py:871)
EthereumFaucetApi # unused class (aea/crypto/ethereum.py:507)
diff --git a/tests/test_packages/test_connections/test_soef/models.py b/tests/test_packages/test_connections/test_soef/models.py
index 0f523d5807..aab233f1b1 100644
--- a/tests/test_packages/test_connections/test_soef/models.py
+++ b/tests/test_packages/test_connections/test_soef/models.py
@@ -24,7 +24,7 @@
AGENT_LOCATION_MODEL = DataModel(
- ModelNames.location_agent,
+ ModelNames.LOCATION_AGENT.value,
[
Attribute("location", Location, True, "The location where the agent is."),
Attribute("disclosure_accuracy", str, False, "Optional disclosure accuracy."),
@@ -34,7 +34,7 @@
AGENT_PERSONALITY_MODEL = DataModel(
- ModelNames.personality_agent,
+ ModelNames.PERSONALITY_AGENT.value,
[
Attribute("piece", str, True, "The personality piece key."),
Attribute("value", str, True, "The personality piece value."),
@@ -44,7 +44,7 @@
SET_SERVICE_KEY_MODEL = DataModel(
- ModelNames.set_service_key,
+ ModelNames.SET_SERVICE_KEY.value,
[
Attribute("key", str, True, "Service key name."),
Attribute("value", str, True, "Service key value."),
@@ -54,12 +54,12 @@
REMOVE_SERVICE_KEY_MODEL = DataModel(
- ModelNames.remove_service_key,
+ ModelNames.REMOVE_SERVICE_KEY.value,
[Attribute("key", str, True, "Service key name.")],
"A data model to remove service key.",
)
-PING_MODEL = DataModel(ModelNames.ping, [], "A data model for ping command.",)
+PING_MODEL = DataModel(ModelNames.PING.value, [], "A data model for ping command.",)
SEARCH_MODEL = DataModel(
@@ -70,7 +70,7 @@
AGENT_GENERIC_COMMAND_MODEL = DataModel(
- ModelNames.generic_command,
+ ModelNames.GENERIC_COMMAND.value,
[
Attribute("command", str, True, "Command name to execute."),
Attribute("parameters", str, False, "Url encoded parameters string."),
From 5c674907cfc5769636a4a78996e235151429ff10 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 19:57:37 +0100
Subject: [PATCH 064/131] fix docs tests
---
aea/cli/utils/config.py | 2 +-
packages/fetchai/connections/soef/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
.../test_bash_yaml/md_files/bash-tac-skills-contract.md | 5 +++--
tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md | 4 ++--
tests/test_packages/test_connections/test_soef/models.py | 2 +-
6 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/aea/cli/utils/config.py b/aea/cli/utils/config.py
index 4850c71eba..9ca1237d60 100644
--- a/aea/cli/utils/config.py
+++ b/aea/cli/utils/config.py
@@ -82,7 +82,7 @@ def try_to_load_agent_config(
)
)
except AEAEnforceError as e:
- raise click.ClickException(str(e))
+ raise click.ClickException(str(e)) # pragma: nocover
def _init_cli_config() -> None:
diff --git a/packages/fetchai/connections/soef/connection.yaml b/packages/fetchai/connections/soef/connection.yaml
index 82f6d15805..da4a8d5dc4 100644
--- a/packages/fetchai/connections/soef/connection.yaml
+++ b/packages/fetchai/connections/soef/connection.yaml
@@ -8,7 +8,7 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmS9zorTodmaRyaxocELEwEqHEPowKoG9wgSAak7s59rZD
__init__.py: Qmd5VBGFJHXFe1H45XoUh5mMSYBwvLSViJuGFeMgbPdQts
- connection.py: QmToZaADzMNpPZr6SMhM4ACwCP3iLi3XfmXxx4F89NxZe5
+ connection.py: QmRTPeJ8aTDuWs28EM7vbBEDbZ75XqqzCo8zhSNXEGmeK3
fingerprint_ignore_patterns: []
protocols:
- fetchai/oef_search:0.7.0
diff --git a/packages/hashes.csv b/packages/hashes.csv
index f2278b6f3a..0dbe4d6617 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -28,7 +28,7 @@ fetchai/connections/p2p_libp2p,QmbPgTY8am7PgLoP3ksaHyuwZzfFGXN4cBrvjV9byramEh
fetchai/connections/p2p_libp2p_client,QmSbfL2DT9L1oooKn2pme1tjivEzkzaiRqJ4zahB4Jb27b
fetchai/connections/p2p_stub,QmecGYtXsb7HA2dSWrw2ARNTPFqZsKXAbVroBo57cdUQSG
fetchai/connections/scaffold,QmNUta43nLexAHaXLgmLQYEjntLXSV6MLNvc6Q2CTx7eBS
-fetchai/connections/soef,QmWgtvW6vvXKhmmAS1n61LZ4rhFnuLcUM61XLW47WiuBfd
+fetchai/connections/soef,Qme2vP55mGemMKMWdHKGUaC1nW88ZEdD55qgdY9a984T7i
fetchai/connections/stub,QmSuUAA2k1E1M9dpeAgkWpfKdssjqghSDfFfrQzC9ZLKbD
fetchai/connections/tcp,QmPADQqZJQ4cw1ecdMC2wR7NwFCdk7MYzvmyP62nbfGk7E
fetchai/connections/webhook,QmWcm3WGxcm5JvhuYRyauQp5wmzFAkV61e2aYpDvYmNvWd
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md
index 0003698f96..e7d2030463 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills-contract.md
@@ -67,8 +67,9 @@ aea config set vendor.fetchai.skills.tac_participation.models.game.args.is_using
aea config set vendor.fetchai.skills.tac_negotiation.models.strategy.args.is_contract_tx 'True' --type bool
```
``` bash
-aea config get vendor.fetchai.skills.tac_control_contract.models.parameters.args.start_time
-aea config set vendor.fetchai.skills.tac_control_contract.models.parameters.args.start_time '01 01 2020 00:01'
+aea config get vendor.fetchai.skills.tac_control_contract.models.parameters.args.registration_start_time
+aea config set vendor.fetchai.skills.tac_control_contract.models.parameters.args.registration_start_time '01 01 2020 00:01'
+```
```
``` bash
aea launch tac_controller_contract tac_participant_one tac_participant_two
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
index b21b9cf691..f2ef4b05a6 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
@@ -52,8 +52,8 @@ aea add-key fetchai fetchai_private_key.txt
aea add-key fetchai fetchai_private_key.txt --connection
```
``` bash
-aea config get vendor.fetchai.skills.tac_control.models.parameters.args.start_time
-aea config set vendor.fetchai.skills.tac_control.models.parameters.args.start_time '01 01 2020 00:01'
+aea config get vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time
+aea config set vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time '01 01 2020 00:01'
```
``` bash
aea run
diff --git a/tests/test_packages/test_connections/test_soef/models.py b/tests/test_packages/test_connections/test_soef/models.py
index aab233f1b1..29beaae8fa 100644
--- a/tests/test_packages/test_connections/test_soef/models.py
+++ b/tests/test_packages/test_connections/test_soef/models.py
@@ -63,7 +63,7 @@
SEARCH_MODEL = DataModel(
- ModelNames.search_model,
+ ModelNames.SEARCH_MODEL.value,
[Attribute("location", Location, True, "The location where the agent is.")],
"A data model to perform search.",
)
From 1e7828248a554eb9ac01f7a3e4ba2bc91199163b Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 20:04:46 +0100
Subject: [PATCH 065/131] enable max-public-methods check and resolve issues
---
.pylintrc | 6 +++---
packages/fetchai/skills/carpark_detection/database.py | 2 +-
packages/fetchai/skills/carpark_detection/skill.yaml | 2 +-
packages/hashes.csv | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.pylintrc b/.pylintrc
index eebe04c217..83401493fb 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -2,14 +2,13 @@
ignore-patterns=serialization.py,message.py,__main__.py,.*_pb2.py
[MESSAGES CONTROL]
-disable=C0103,C0201,C0301,C0302,C0330,W0105,W0107,W0707,W1202,W1203,R0902,R0913,R0914,R0801,R0904,R0911,R0912,R0901,R0916,R1702,R0915
+disable=C0103,C0201,C0301,C0302,C0330,W0105,W0107,W0707,W1202,W1203,R0902,R0913,R0914,R0801,R0911,R0912,R0901,R0916,R1702,R0915
## Eventually resolve these:
# W0707: raise-missing-from
# R0902: too-many-instance-attributes
# R0913: too-many-arguments
# R0914: too-many-locals
-# R0904: too-many-public-methods
# R0911: too-many-return-statements
# R0912: too-many-branches
# R0901: too-many-ancestors
@@ -34,4 +33,5 @@ disable=C0103,C0201,C0301,C0302,C0330,W0105,W0107,W0707,W1202,W1203,R0902,R0913,
ignored-modules=aiohttp,defusedxml,gym,fetch,matplotlib,memory_profiler,numpy,oef,openapi_core,psutil,tensorflow,temper,skimage,vyper,web3
[DESIGN]
-min-public-methods=1
\ No newline at end of file
+min-public-methods=1
+max-public-methods=35
diff --git a/packages/fetchai/skills/carpark_detection/database.py b/packages/fetchai/skills/carpark_detection/database.py
index 31dd90e8f9..245d4c0155 100644
--- a/packages/fetchai/skills/carpark_detection/database.py
+++ b/packages/fetchai/skills/carpark_detection/database.py
@@ -33,7 +33,7 @@
)
-class DetectionDatabase:
+class DetectionDatabase: # pylint: disable=too-many-public-methods
"""Communicate between the database and the python objects."""
def __init__(
diff --git a/packages/fetchai/skills/carpark_detection/skill.yaml b/packages/fetchai/skills/carpark_detection/skill.yaml
index 1aaadad48e..4d5e40c87a 100644
--- a/packages/fetchai/skills/carpark_detection/skill.yaml
+++ b/packages/fetchai/skills/carpark_detection/skill.yaml
@@ -10,7 +10,7 @@ fingerprint:
README.md: QmcwNhv5N8m4ZtWvXY5eMDeL5ciivryDZPtGWXMFfTbYR7
__init__.py: QmQoECB7dpCDCG3xCnBsoMy6oqgSdu69CzRcAcuZuyapnQ
behaviours.py: QmTNboU3YH8DehWnpZmoiDUCncpNmqoSVt1Yp4j7NsgY2S
- database.py: QmcZ7zomRfpVakRQBaDFzkuAN8noEWkHo2LLxUMNpF1xUp
+ database.py: QmPQqzgsmFKBSMoYbuEpEMnikmkEadaT9VrD8ics5Het2b
dialogues.py: QmPXfUWDxnHDaHQqsgtVhJ2v9dEgGWLtvEHKFvvFcDXGms
handlers.py: QmbkmEP9K4Qu2MsRtnkdx3PGNbSW46qi48bCHVCUJHpcQF
strategy.py: QmUCmsvvKqRsM4nFuhsUUTfCnZ6zPffXytD3PjMjFdqHdU
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 0dbe4d6617..76ae3305fb 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -49,7 +49,7 @@ fetchai/protocols/tac,QmY6N5spfcwikq3pb99mdYAEieECqmtawbcitGJRicDh7H
fetchai/skills/aries_alice,QmefZJ27H36RZYgA6eEcnbv8yNPyf3YYXnBm5E88C8xBLQ
fetchai/skills/aries_faber,QmYAQ8gVsokPsXHd7RDXb8KCkmH7XpB8JC7VMx3QrJX3Uh
fetchai/skills/carpark_client,QmYjZXvq2h2DCXZF2ba9W5cvJAvsRFvBrw7h7EwcvWThfW
-fetchai/skills/carpark_detection,QmRLr3ALHF1iLFFpUmXHKZmMwbFz5vfph8qCv7rKQpte2r
+fetchai/skills/carpark_detection,QmV5qPay1FMk3tsygygRL4ThsBRxFL5nZe7x5NrXFXpSJN
fetchai/skills/echo,QmYKGMNs5NU7ycWXRBQnKrfBcg5HPnUnH13K1YFnPLQgW6
fetchai/skills/erc1155_client,Qmd6KJbis7Me39teeHA8y3JZHQrS1hjovMxhqiwViRZhgc
fetchai/skills/erc1155_deploy,QmZHDmFaxJmieLaCUJKBwp1EsTEAAxbFvFkfLjL4fVyhfK
From a42c51d0a59e09468c723c2702693edf2fd9bed6 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 21:35:23 +0100
Subject: [PATCH 066/131] attempt to fix tac control skill
---
packages/fetchai/skills/tac_control/parameters.py | 2 +-
packages/fetchai/skills/tac_control/skill.yaml | 5 +++--
packages/hashes.csv | 2 +-
tests/test_packages/test_skills/test_tac.py | 6 +++---
4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/packages/fetchai/skills/tac_control/parameters.py b/packages/fetchai/skills/tac_control/parameters.py
index f4bfe793b9..a490fa92c9 100644
--- a/packages/fetchai/skills/tac_control/parameters.py
+++ b/packages/fetchai/skills/tac_control/parameters.py
@@ -207,7 +207,7 @@ def nb_goods(self) -> int:
@property
def nb_currencies(self) -> int:
"""Currency number for a TAC instance."""
- return self._nb_goods
+ return self._nb_currencies
@property
def currency_id_to_name(self) -> Dict[str, str]:
diff --git a/packages/fetchai/skills/tac_control/skill.yaml b/packages/fetchai/skills/tac_control/skill.yaml
index e62dd6ce2d..85cb506acc 100644
--- a/packages/fetchai/skills/tac_control/skill.yaml
+++ b/packages/fetchai/skills/tac_control/skill.yaml
@@ -14,7 +14,7 @@ fingerprint:
game.py: QmTovmW5vuhUcnvW4wQQcbPpiUFLLvMH7LaeTZYVvjqLcF
handlers.py: QmSjwPKEN83C2gQS4WVH8uaHMv5ze7EJ9S8ugmRcKnSwnW
helpers.py: QmQXrtqV3h4oU5cDwWKhtNiTTAGLNZGhjoVnDvGj7mGwpe
- parameters.py: QmbdCERZFXWjP4ov7uLvmFGxvrTep3RwiQauXevLcJNLbY
+ parameters.py: QmeviKY6o3H2FYNFaB9PibZGZc1CwMgLbrCbPoSmZDsikv
fingerprint_ignore_patterns: []
contracts:
- fetchai/erc1155:0.10.0
@@ -58,7 +58,8 @@ models:
lower_bound_factor: 1
min_nb_agents: 2
money_endowment: 2000000
- nb_goods: 10
+ nb_currencies: 1
+ nb_goods: 9
registration_start_time: 01 01 2020 00:01
registration_timeout: 60
service_data:
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 76ae3305fb..7800832144 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -62,7 +62,7 @@ fetchai/skills/ml_data_provider,QmaKyLjyvcj35bCHaKKo15MeF7k48hKPCfFbrtvXCogYwV
fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
-fetchai/skills/tac_control,QmTgw37facaPnt9RQcHNPzFasDmgG1PktEo2ZHfNqPjXet
+fetchai/skills/tac_control,QmPFxFsYqRZvz7BRStWLV9Fo4Wd77iTNBWuBSU2VZeqrwL
fetchai/skills/tac_control_contract,QmYX4gNaGbx1EAuASwhpSgTdLYwUzuzajtKTuqvNFR9f2Q
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
diff --git a/tests/test_packages/test_skills/test_tac.py b/tests/test_packages/test_skills/test_tac.py
index 1ff948a692..f9e319525c 100644
--- a/tests/test_packages/test_skills/test_tac.py
+++ b/tests/test_packages/test_skills/test_tac.py
@@ -47,7 +47,7 @@ class TestTacSkills(AEATestCaseMany):
@pytest.mark.integration
@pytest.mark.flaky(
- reruns=MAX_FLAKY_RERUNS_INTEGRATION
+ reruns=0
) # cause possible network issues
def test_tac(self):
"""Run the tac skills sequence."""
@@ -143,10 +143,10 @@ def test_tac(self):
self.set_agent_context(tac_controller_name)
now = datetime.datetime.now().strftime("%d %m %Y %H:%M")
now_min = datetime.datetime.strptime(now, "%d %m %Y %H:%M")
- fut = now_min + datetime.timedelta(0, 120)
+ fut = now_min # + datetime.timedelta(0, 120)
start_time = fut.strftime("%d %m %Y %H:%M")
setting_path = (
- "vendor.fetchai.skills.tac_control.models.parameters.args.start_time"
+ "vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time"
)
self.set_config(setting_path, start_time)
tac_controller_process = self.run_agent()
From 84785415cd80bb2ce3cc7ced06566ad747ee5c2b Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 22:08:06 +0100
Subject: [PATCH 067/131] update tac protocol
---
packages/fetchai/protocols/tac/README.md | 2 +-
packages/fetchai/protocols/tac/dialogues.py | 1 +
packages/fetchai/protocols/tac/protocol.yaml | 4 ++--
packages/hashes.csv | 2 +-
tests/test_packages/test_skills/test_tac.py | 6 ++----
5 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/packages/fetchai/protocols/tac/README.md b/packages/fetchai/protocols/tac/README.md
index 286ad842ef..4a7397b04e 100644
--- a/packages/fetchai/protocols/tac/README.md
+++ b/packages/fetchai/protocols/tac/README.md
@@ -71,7 +71,7 @@ initiation: [register]
reply:
register: [tac_error, game_data, cancelled]
unregister: [tac_error]
- transaction: [transaction_confirmation, tac_error, cancelled]
+ transaction: [transaction, transaction_confirmation, tac_error, cancelled]
cancelled: []
game_data: [transaction, transaction_confirmation, cancelled]
transaction_confirmation: [transaction, transaction_confirmation, cancelled]
diff --git a/packages/fetchai/protocols/tac/dialogues.py b/packages/fetchai/protocols/tac/dialogues.py
index 250ae33e75..fb09acd3fa 100644
--- a/packages/fetchai/protocols/tac/dialogues.py
+++ b/packages/fetchai/protocols/tac/dialogues.py
@@ -66,6 +66,7 @@ class TacDialogue(Dialogue):
),
TacMessage.Performative.TRANSACTION: frozenset(
{
+ TacMessage.Performative.TRANSACTION,
TacMessage.Performative.TRANSACTION_CONFIRMATION,
TacMessage.Performative.TAC_ERROR,
TacMessage.Performative.CANCELLED,
diff --git a/packages/fetchai/protocols/tac/protocol.yaml b/packages/fetchai/protocols/tac/protocol.yaml
index cc916bf083..7b320ff557 100644
--- a/packages/fetchai/protocols/tac/protocol.yaml
+++ b/packages/fetchai/protocols/tac/protocol.yaml
@@ -7,10 +7,10 @@ description: The tac protocol implements the messages an AEA needs to participat
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
- README.md: QmcUpwxG2ZzdwMeMGGTVyJgsRVbrCUKtYB2qqLy4YsuBez
+ README.md: QmSZJ6wsgqjYN6cqWQKShj2xpruYMCxbK1m6TKk4V4Aopn
__init__.py: QmSAC7PGra9fig8RhhF1j3XEVpgie9UZNNYPc2AB9Kx9xJ
custom_types.py: QmXQATfnvuCpt4FicF4QcqCcLj9PQNsSHjCBvVQknWpyaN
- dialogues.py: QmTxHrcGujP1RUYvfJygZyQoUwmDg2GBWfmbR3tWUSbyop
+ dialogues.py: QmQvuivrjhVFu7pjSFfv6FrWwVeBC7p8Hm3P4gjCnVx5Ym
message.py: QmWD79nj4kcMPN9xuDkgSDXnwgDnT6XE1WcdfBKsKKPqTP
serialization.py: QmTk2Jp19dQ4SJdjSHAr8wbxw4rQSMheSuf1XzXG8CaoB4
tac.proto: QmdpPZNhUW593qVNVoSTWZgd9R69bmBbw6Y9xjzYpvuDvV
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 7800832144..382daea0fa 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -45,7 +45,7 @@ fetchai/protocols/oef_search,QmWiRygk9JHtCJ6FbSK49uwkCzsSu6wJVqc27iQEwGphFR
fetchai/protocols/scaffold,QmaQJxMae5XaHKDc838pcGEKhhYSUyKHGWiMfU6zEcVHsy
fetchai/protocols/signing,Qmazm8bkwpPVV7BiJZx2Aha96AcmAxwiYbjgYGwvcgXGYi
fetchai/protocols/state_update,QmS1xuSYYgHkQq8Ww2btsS88rTXXjhchyStzUfcWYQKNda
-fetchai/protocols/tac,QmY6N5spfcwikq3pb99mdYAEieECqmtawbcitGJRicDh7H
+fetchai/protocols/tac,QmYuMW1tNE5eLdKEo5T6uyTYmVmGuavQLT4xx3hDaGNLJJ
fetchai/skills/aries_alice,QmefZJ27H36RZYgA6eEcnbv8yNPyf3YYXnBm5E88C8xBLQ
fetchai/skills/aries_faber,QmYAQ8gVsokPsXHd7RDXb8KCkmH7XpB8JC7VMx3QrJX3Uh
fetchai/skills/carpark_client,QmYjZXvq2h2DCXZF2ba9W5cvJAvsRFvBrw7h7EwcvWThfW
diff --git a/tests/test_packages/test_skills/test_tac.py b/tests/test_packages/test_skills/test_tac.py
index f9e319525c..b74dbb2f4a 100644
--- a/tests/test_packages/test_skills/test_tac.py
+++ b/tests/test_packages/test_skills/test_tac.py
@@ -47,7 +47,7 @@ class TestTacSkills(AEATestCaseMany):
@pytest.mark.integration
@pytest.mark.flaky(
- reruns=0
+ reruns=MAX_FLAKY_RERUNS_INTEGRATION
) # cause possible network issues
def test_tac(self):
"""Run the tac skills sequence."""
@@ -145,9 +145,7 @@ def test_tac(self):
now_min = datetime.datetime.strptime(now, "%d %m %Y %H:%M")
fut = now_min # + datetime.timedelta(0, 120)
start_time = fut.strftime("%d %m %Y %H:%M")
- setting_path = (
- "vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time"
- )
+ setting_path = "vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time"
self.set_config(setting_path, start_time)
tac_controller_process = self.run_agent()
From 3c79fc24e729da18e90c7dc72e078f5aca713fac Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 22:38:21 +0100
Subject: [PATCH 068/131] mute cancel error in stub connection
---
aea/connections/stub/connection.py | 3 +++
aea/connections/stub/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/aea/connections/stub/connection.py b/aea/connections/stub/connection.py
index a80267f0c9..9797a9094d 100644
--- a/aea/connections/stub/connection.py
+++ b/aea/connections/stub/connection.py
@@ -251,6 +251,9 @@ async def receive(self, *args, **kwargs) -> Optional["Envelope"]:
try:
return await self.in_queue.get()
+ except CancelledError: # pragma: no cover
+ self.logger.debug("Receive cancelled.")
+ return None
except Exception: # pylint: disable=broad-except
logger.exception("Stub connection receive error:")
return None
diff --git a/aea/connections/stub/connection.yaml b/aea/connections/stub/connection.yaml
index 743ee3598a..d9bb0817dd 100644
--- a/aea/connections/stub/connection.yaml
+++ b/aea/connections/stub/connection.yaml
@@ -8,7 +8,7 @@ license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
__init__.py: QmWwepN9Fy9gHAp39vUGFSLdnB9JZjdyE3STnbowSUhJkC
- connection.py: QmTSESVFvsDc9iq2QM3YdZju3yHqTA3wHbLkAzHXEFY17Z
+ connection.py: QmVjZwuNd6JLRDp2DzZxbLwF5feSrGiULWowZSan9Caogk
readme.md: QmXSAtxSY7C2YkvUxeVnpqCJY9uJYZxZBmuUcE4zjFXcXz
fingerprint_ignore_patterns: []
protocols: []
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 382daea0fa..29718482ad 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -29,7 +29,7 @@ fetchai/connections/p2p_libp2p_client,QmSbfL2DT9L1oooKn2pme1tjivEzkzaiRqJ4zahB4J
fetchai/connections/p2p_stub,QmecGYtXsb7HA2dSWrw2ARNTPFqZsKXAbVroBo57cdUQSG
fetchai/connections/scaffold,QmNUta43nLexAHaXLgmLQYEjntLXSV6MLNvc6Q2CTx7eBS
fetchai/connections/soef,Qme2vP55mGemMKMWdHKGUaC1nW88ZEdD55qgdY9a984T7i
-fetchai/connections/stub,QmSuUAA2k1E1M9dpeAgkWpfKdssjqghSDfFfrQzC9ZLKbD
+fetchai/connections/stub,QmWarW8MTJ3CHRgXdkbwKK7DyDKzvQKdZeb95uy8kSnxrT
fetchai/connections/tcp,QmPADQqZJQ4cw1ecdMC2wR7NwFCdk7MYzvmyP62nbfGk7E
fetchai/connections/webhook,QmWcm3WGxcm5JvhuYRyauQp5wmzFAkV61e2aYpDvYmNvWd
fetchai/contracts/erc1155,QmWu22zW9AVMBVySwF413JMiT5dcWsLsU2gk1KvFYWAwPq
From 70ee5aa4bd79ddbf3a4f7c9fac15e9de5f27be88 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 22:47:45 +0100
Subject: [PATCH 069/131] fix yaml loading in scripts and fix tac test
---
scripts/deploy_to_registry.py | 22 +++++++++++++++++++--
scripts/update_package_versions.py | 20 ++++++++++++++++++-
tests/test_packages/test_skills/test_tac.py | 2 +-
3 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/scripts/deploy_to_registry.py b/scripts/deploy_to_registry.py
index 97729d068a..769139bd04 100644
--- a/scripts/deploy_to_registry.py
+++ b/scripts/deploy_to_registry.py
@@ -25,7 +25,7 @@
import sys
from itertools import chain
from pathlib import Path
-from typing import Set
+from typing import Dict, Set
import yaml
from click.testing import CliRunner
@@ -51,13 +51,31 @@ def default_config_file_paths():
yield item
+def unified_yaml_load(configuration_file: Path) -> Dict:
+ """
+ Load YAML file, unified (both single- and multi-paged).
+
+ :param configuration_file: the configuration file path.
+ :return: the data.
+ """
+ package_type = configuration_file.parent.parent.name
+ with configuration_file.open() as fp:
+ if package_type != "agents":
+ return yaml.safe_load(fp)
+ # when it is an agent configuration file,
+ # we are interested only in the first page of the YAML,
+ # because the dependencies are contained only there.
+ data = yaml.safe_load_all(fp)
+ return list(data)[0]
+
+
def get_public_id_from_yaml(configuration_file: Path):
"""
Get the public id from yaml.
:param configuration_file: the path to the config yaml
"""
- data = yaml.safe_load(configuration_file.open())
+ data = unified_yaml_load(configuration_file)
author = data["author"]
# handle the case when it's a package or agent config file.
name = data["name"] if "name" in data else data["agent_name"]
diff --git a/scripts/update_package_versions.py b/scripts/update_package_versions.py
index a93f1067f0..e0ef1d5010 100644
--- a/scripts/update_package_versions.py
+++ b/scripts/update_package_versions.py
@@ -196,13 +196,31 @@ def get_configuration_file_path(type_: str, name: str) -> Path:
sys.exit(1)
+def unified_yaml_load(configuration_file: Path) -> Dict:
+ """
+ Load YAML file, unified (both single- and multi-paged).
+
+ :param configuration_file: the configuration file path.
+ :return: the data.
+ """
+ package_type = configuration_file.parent.parent.name
+ with configuration_file.open() as fp:
+ if package_type != "agents":
+ return yaml.safe_load(fp)
+ # when it is an agent configuration file,
+ # we are interested only in the first page of the YAML,
+ # because the dependencies are contained only there.
+ data = yaml.safe_load_all(fp)
+ return list(data)[0]
+
+
def get_public_id_from_yaml(configuration_file_path: Path) -> PublicId:
"""
Get the public id from yaml.
:param configuration_file_path: the path to the config yaml
"""
- data = yaml.safe_load(configuration_file_path.open())
+ data = unified_yaml_load(configuration_file_path)
author = data["author"]
# handle the case when it's a package or agent config file.
name = data["name"] if "name" in data else data["agent_name"]
diff --git a/tests/test_packages/test_skills/test_tac.py b/tests/test_packages/test_skills/test_tac.py
index b74dbb2f4a..88a8c90156 100644
--- a/tests/test_packages/test_skills/test_tac.py
+++ b/tests/test_packages/test_skills/test_tac.py
@@ -143,7 +143,7 @@ def test_tac(self):
self.set_agent_context(tac_controller_name)
now = datetime.datetime.now().strftime("%d %m %Y %H:%M")
now_min = datetime.datetime.strptime(now, "%d %m %Y %H:%M")
- fut = now_min # + datetime.timedelta(0, 120)
+ fut = now_min + datetime.timedelta(0, 60)
start_time = fut.strftime("%d %m %Y %H:%M")
setting_path = "vendor.fetchai.skills.tac_control.models.parameters.args.registration_start_time"
self.set_config(setting_path, start_time)
From 2cd1b88039efc9f5f9851717fc2160629764cf07 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 22:50:51 +0100
Subject: [PATCH 070/131] bump stub connection
---
aea/configurations/constants.py | 2 +-
aea/connections/stub/connection.py | 2 +-
aea/connections/stub/connection.yaml | 6 +--
aea/connections/stub/readme.md | 2 +-
docs/build-aea-programmatically.md | 2 +-
docs/config.md | 2 +-
docs/core-components-1.md | 2 +-
docs/logging.md | 4 +-
docs/package-imports.md | 2 +-
docs/questions-and-answers.md | 2 +-
docs/quickstart.md | 4 +-
.../agents/aries_alice/aea-config.yaml | 2 +-
.../agents/aries_faber/aea-config.yaml | 2 +-
.../agents/car_data_buyer/aea-config.yaml | 2 +-
.../agents/car_detector/aea-config.yaml | 2 +-
.../agents/erc1155_client/aea-config.yaml | 2 +-
.../agents/erc1155_deployer/aea-config.yaml | 2 +-
.../agents/generic_buyer/aea-config.yaml | 2 +-
.../agents/generic_seller/aea-config.yaml | 2 +-
.../fetchai/agents/gym_aea/aea-config.yaml | 2 +-
.../agents/ml_data_provider/aea-config.yaml | 2 +-
.../agents/ml_model_trainer/aea-config.yaml | 2 +-
.../agents/my_first_aea/aea-config.yaml | 4 +-
.../aea-config.yaml | 2 +-
.../agents/tac_controller/aea-config.yaml | 2 +-
.../tac_controller_contract/aea-config.yaml | 2 +-
.../agents/tac_participant/aea-config.yaml | 2 +-
.../agents/thermometer_aea/aea-config.yaml | 2 +-
.../agents/thermometer_client/aea-config.yaml | 2 +-
.../agents/weather_client/aea-config.yaml | 2 +-
.../agents/weather_station/aea-config.yaml | 2 +-
packages/hashes.csv | 42 +++++++++----------
tests/test_aea_builder.py | 2 +-
tests/test_cli/test_get_multiaddress.py | 22 +++++-----
tests/test_configurations/test_aea_config.py | 2 +-
.../test_bash_yaml/md_files/bash-config.md | 2 +-
.../test_bash_yaml/md_files/bash-logging.md | 4 +-
.../md_files/bash-package-imports.md | 2 +-
.../md_files/bash-quickstart.md | 2 +-
39 files changed, 75 insertions(+), 75 deletions(-)
diff --git a/aea/configurations/constants.py b/aea/configurations/constants.py
index 5cfb525c7b..169bb58945 100644
--- a/aea/configurations/constants.py
+++ b/aea/configurations/constants.py
@@ -26,7 +26,7 @@
from aea.crypto.helpers import PRIVATE_KEY_PATH_SCHEMA
-DEFAULT_CONNECTION = PublicId.from_str("fetchai/stub:0.9.0")
+DEFAULT_CONNECTION = PublicId.from_str("fetchai/stub:0.10.0")
DEFAULT_PROTOCOL = PublicId.from_str("fetchai/default:0.6.0")
DEFAULT_SKILL = PublicId.from_str("fetchai/error:0.6.0")
DEFAULT_LEDGER = FetchAICrypto.identifier
diff --git a/aea/connections/stub/connection.py b/aea/connections/stub/connection.py
index 9797a9094d..63f718e25b 100644
--- a/aea/connections/stub/connection.py
+++ b/aea/connections/stub/connection.py
@@ -44,7 +44,7 @@
DEFAULT_OUTPUT_FILE_NAME = "./output_file"
SEPARATOR = b","
-PUBLIC_ID = PublicId.from_str("fetchai/stub:0.9.0")
+PUBLIC_ID = PublicId.from_str("fetchai/stub:0.10.0")
def _encode(e: Envelope, separator: bytes = SEPARATOR):
diff --git a/aea/connections/stub/connection.yaml b/aea/connections/stub/connection.yaml
index d9bb0817dd..4f7c8c820c 100644
--- a/aea/connections/stub/connection.yaml
+++ b/aea/connections/stub/connection.yaml
@@ -1,6 +1,6 @@
name: stub
author: fetchai
-version: 0.9.0
+version: 0.10.0
type: connection
description: The stub connection implements a connection stub which reads/writes messages
from/to file.
@@ -8,8 +8,8 @@ license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint:
__init__.py: QmWwepN9Fy9gHAp39vUGFSLdnB9JZjdyE3STnbowSUhJkC
- connection.py: QmVjZwuNd6JLRDp2DzZxbLwF5feSrGiULWowZSan9Caogk
- readme.md: QmXSAtxSY7C2YkvUxeVnpqCJY9uJYZxZBmuUcE4zjFXcXz
+ connection.py: QmRSc6Edy9u9yQMRtvs7MZeq1NRDT57gRy6T19QVLdCkus
+ readme.md: QmQ2Y2sk2xnH45KzxdMna1pUXDGQ5S32fJk1qwdTSfAGc2
fingerprint_ignore_patterns: []
protocols: []
class_name: StubConnection
diff --git a/aea/connections/stub/readme.md b/aea/connections/stub/readme.md
index 839993ec33..177d94c9ef 100644
--- a/aea/connections/stub/readme.md
+++ b/aea/connections/stub/readme.md
@@ -2,6 +2,6 @@
A simple connection for communication with an AEA, using the file system as a point of data exchange.
## Usage
-First, add the connection to your AEA project: `aea add connection fetchai/stub:0.9.0`. (If you have created your AEA project with `aea create` then the connection will already be available by default.)
+First, add the connection to your AEA project: `aea add connection fetchai/stub:0.10.0`. (If you have created your AEA project with `aea create` then the connection will already be available by default.)
Optionally, in the `connection.yaml` file under `config` set the `input_file` and `output_file` to the desired file path. The `stub` connection reads encoded envelopes from the `input_file` and writes encoded envelopes to the `output_file`.
diff --git a/docs/build-aea-programmatically.md b/docs/build-aea-programmatically.md
index 407925e113..5c162b7651 100644
--- a/docs/build-aea-programmatically.md
+++ b/docs/build-aea-programmatically.md
@@ -48,7 +48,7 @@ We will use the stub connection to pass envelopes in and out of the AEA. Ensure
```
## Initialise the AEA
-We use the `AEABuilder` to readily build an AEA. By default, the `AEABuilder` adds the `fetchai/default:0.6.0` protocol, the `fetchai/stub:0.9.0` connection and the `fetchai/error:0.6.0` skill.
+We use the `AEABuilder` to readily build an AEA. By default, the `AEABuilder` adds the `fetchai/default:0.6.0` protocol, the `fetchai/stub:0.10.0` connection and the `fetchai/error:0.6.0` skill.
``` python
# Instantiate the builder and build the AEA
# By default, the default protocol, error skill and stub connection are added
diff --git a/docs/config.md b/docs/config.md
index 9cc4e49ae8..6e4435706e 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -21,7 +21,7 @@ aea_version: '>=0.6.0, <0.7.0' # AEA framework version(s) compa
fingerprint: {} # Fingerprint of AEA project components.
fingerprint_ignore_patterns: [] # Ignore pattern for the fingerprinting tool.
connections: # The list of connection public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX)
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: [] # The list of contract public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
protocols: # The list of protocol public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
- fetchai/default:0.6.0
diff --git a/docs/core-components-1.md b/docs/core-components-1.md
index d7500f3322..e549fc63b4 100644
--- a/docs/core-components-1.md
+++ b/docs/core-components-1.md
@@ -42,7 +42,7 @@ Protocol specific `Messages`, wrapped in `Envelopes`, are sent and received to o
A `Connection` wraps an SDK or API and provides an interface to network, ledgers and other services. Where necessary, a `Connection` is responsible for translating between the framework specific `Envelope` with its contained `Message` and the external service or third-party protocol (e.g. `HTTP`).
-The framework provides one default `Connection`, called `stub` (current version `fetchai/stub:0.9.0`). It implements an I/O reader and writer to send `Messages` to the agent from a local file.
+The framework provides one default `Connection`, called `stub` (current version `fetchai/stub:0.10.0`). It implements an I/O reader and writer to send `Messages` to the agent from a local file.
Additional `Connections` can be added as packages. For more details on `Connections` also read the `Connection` guide here.
diff --git a/docs/logging.md b/docs/logging.md
index 8f0e4c0230..db47eac014 100644
--- a/docs/logging.md
+++ b/docs/logging.md
@@ -22,13 +22,13 @@ aea_version: 0.6.0
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
skills:
- fetchai/error:0.6.0
-default_connection: fetchai/stub:0.9.0
+default_connection: fetchai/stub:0.10.0
default_ledger: fetchai
logging_config:
disable_existing_loggers: false
diff --git a/docs/package-imports.md b/docs/package-imports.md
index b6202ee219..b30e656e0d 100644
--- a/docs/package-imports.md
+++ b/docs/package-imports.md
@@ -47,7 +47,7 @@ The `aea-config.yaml` is the top level configuration file of an AEA. It defines
For the AEA to use a package, the `public_id` for the package must be listed in the `aea-config.yaml` file, e.g.
``` yaml
connections:
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
```
The above shows a part of the `aea-config.yaml`. If you see the connections, you will see that we follow a pattern of `author/name_package:version` to identify each package, also referred to as `public_id`. Here the `author` is the author of the package.
diff --git a/docs/questions-and-answers.md b/docs/questions-and-answers.md
index 9b0a634e69..8a99afb531 100644
--- a/docs/questions-and-answers.md
+++ b/docs/questions-and-answers.md
@@ -72,7 +72,7 @@ You can find more details about the CLI commands here
When a new AEA is created, is the `vendor` folder populated with some default packages?
-All AEA projects by default hold the `fetchai/stub:0.9.0` connection, the `fetchai/default:0.6.0` protocol and the `fetchai/error:0.6.0` skill. These (as all other packages installed from the registry) are placed in the vendor's folder.
+All AEA projects by default hold the `fetchai/stub:0.10.0` connection, the `fetchai/default:0.6.0` protocol and the `fetchai/error:0.6.0` skill. These (as all other packages installed from the registry) are placed in the vendor's folder.
You can find more details about the file structure here
diff --git a/docs/quickstart.md b/docs/quickstart.md
index beae01bce4..42f57ff4ad 100644
--- a/docs/quickstart.md
+++ b/docs/quickstart.md
@@ -154,7 +154,7 @@ recipient_aea,sender_aea,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello
## Run the AEA
-Run the AEA with the default `fetchai/stub:0.9.0` connection.
+Run the AEA with the default `fetchai/stub:0.10.0` connection.
``` bash
aea run
@@ -163,7 +163,7 @@ aea run
or
``` bash
-aea run --connections fetchai/stub:0.9.0
+aea run --connections fetchai/stub:0.10.0
```
You will see the echo skill running in the terminal window.
diff --git a/packages/fetchai/agents/aries_alice/aea-config.yaml b/packages/fetchai/agents/aries_alice/aea-config.yaml
index 7efbe1b67a..9be95df03d 100644
--- a/packages/fetchai/agents/aries_alice/aea-config.yaml
+++ b/packages/fetchai/agents/aries_alice/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/http_client:0.9.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
- fetchai/webhook:0.7.0
contracts: []
protocols:
diff --git a/packages/fetchai/agents/aries_faber/aea-config.yaml b/packages/fetchai/agents/aries_faber/aea-config.yaml
index 60858d53c7..ab87ebe399 100644
--- a/packages/fetchai/agents/aries_faber/aea-config.yaml
+++ b/packages/fetchai/agents/aries_faber/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/http_client:0.9.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
- fetchai/webhook:0.7.0
contracts: []
protocols:
diff --git a/packages/fetchai/agents/car_data_buyer/aea-config.yaml b/packages/fetchai/agents/car_data_buyer/aea-config.yaml
index d4300cd29e..10463565e5 100644
--- a/packages/fetchai/agents/car_data_buyer/aea-config.yaml
+++ b/packages/fetchai/agents/car_data_buyer/aea-config.yaml
@@ -11,7 +11,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/car_detector/aea-config.yaml b/packages/fetchai/agents/car_detector/aea-config.yaml
index b63aafca67..6351d2f41c 100644
--- a/packages/fetchai/agents/car_detector/aea-config.yaml
+++ b/packages/fetchai/agents/car_detector/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/erc1155_client/aea-config.yaml b/packages/fetchai/agents/erc1155_client/aea-config.yaml
index 19ad7cf3c4..a38ca8c0ae 100644
--- a/packages/fetchai/agents/erc1155_client/aea-config.yaml
+++ b/packages/fetchai/agents/erc1155_client/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
diff --git a/packages/fetchai/agents/erc1155_deployer/aea-config.yaml b/packages/fetchai/agents/erc1155_deployer/aea-config.yaml
index abc22baa84..0e8764b869 100644
--- a/packages/fetchai/agents/erc1155_deployer/aea-config.yaml
+++ b/packages/fetchai/agents/erc1155_deployer/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
diff --git a/packages/fetchai/agents/generic_buyer/aea-config.yaml b/packages/fetchai/agents/generic_buyer/aea-config.yaml
index b0482b5822..2be2666c1f 100644
--- a/packages/fetchai/agents/generic_buyer/aea-config.yaml
+++ b/packages/fetchai/agents/generic_buyer/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/generic_seller/aea-config.yaml b/packages/fetchai/agents/generic_seller/aea-config.yaml
index e53783701c..4c9a7ad097 100644
--- a/packages/fetchai/agents/generic_seller/aea-config.yaml
+++ b/packages/fetchai/agents/generic_seller/aea-config.yaml
@@ -11,7 +11,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/gym_aea/aea-config.yaml b/packages/fetchai/agents/gym_aea/aea-config.yaml
index d18a4ad991..357713694e 100644
--- a/packages/fetchai/agents/gym_aea/aea-config.yaml
+++ b/packages/fetchai/agents/gym_aea/aea-config.yaml
@@ -9,7 +9,7 @@ fingerprint: {}
fingerprint_ignore_patterns: []
connections:
- fetchai/gym:0.8.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/ml_data_provider/aea-config.yaml b/packages/fetchai/agents/ml_data_provider/aea-config.yaml
index d6c4f22331..6edfe08859 100644
--- a/packages/fetchai/agents/ml_data_provider/aea-config.yaml
+++ b/packages/fetchai/agents/ml_data_provider/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/ml_model_trainer/aea-config.yaml b/packages/fetchai/agents/ml_model_trainer/aea-config.yaml
index b6c7e4f8c6..70796a0f06 100644
--- a/packages/fetchai/agents/ml_model_trainer/aea-config.yaml
+++ b/packages/fetchai/agents/ml_model_trainer/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/my_first_aea/aea-config.yaml b/packages/fetchai/agents/my_first_aea/aea-config.yaml
index cab085b44c..a855b3aa89 100644
--- a/packages/fetchai/agents/my_first_aea/aea-config.yaml
+++ b/packages/fetchai/agents/my_first_aea/aea-config.yaml
@@ -7,14 +7,14 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
skills:
- fetchai/echo:0.8.0
- fetchai/error:0.6.0
-default_connection: fetchai/stub:0.9.0
+default_connection: fetchai/stub:0.10.0
default_ledger: fetchai
logging_config:
disable_existing_loggers: false
diff --git a/packages/fetchai/agents/simple_service_registration/aea-config.yaml b/packages/fetchai/agents/simple_service_registration/aea-config.yaml
index 6e6d8adceb..e58f388a4b 100644
--- a/packages/fetchai/agents/simple_service_registration/aea-config.yaml
+++ b/packages/fetchai/agents/simple_service_registration/aea-config.yaml
@@ -9,7 +9,7 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/tac_controller/aea-config.yaml b/packages/fetchai/agents/tac_controller/aea-config.yaml
index 9ce1d7381f..442993e0b4 100644
--- a/packages/fetchai/agents/tac_controller/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller/aea-config.yaml
@@ -9,7 +9,7 @@ fingerprint_ignore_patterns: []
connections:
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index efbe561f76..8b7256a5ed 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -11,7 +11,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
diff --git a/packages/fetchai/agents/tac_participant/aea-config.yaml b/packages/fetchai/agents/tac_participant/aea-config.yaml
index 0c2333eece..c5e96b4791 100644
--- a/packages/fetchai/agents/tac_participant/aea-config.yaml
+++ b/packages/fetchai/agents/tac_participant/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts:
- fetchai/erc1155:0.10.0
protocols:
diff --git a/packages/fetchai/agents/thermometer_aea/aea-config.yaml b/packages/fetchai/agents/thermometer_aea/aea-config.yaml
index f3e7d966b4..a3ed35fd38 100644
--- a/packages/fetchai/agents/thermometer_aea/aea-config.yaml
+++ b/packages/fetchai/agents/thermometer_aea/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/thermometer_client/aea-config.yaml b/packages/fetchai/agents/thermometer_client/aea-config.yaml
index 64aa7e7bc6..22a8eacc24 100644
--- a/packages/fetchai/agents/thermometer_client/aea-config.yaml
+++ b/packages/fetchai/agents/thermometer_client/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/weather_client/aea-config.yaml b/packages/fetchai/agents/weather_client/aea-config.yaml
index a86fbf5abb..44841b8f5f 100644
--- a/packages/fetchai/agents/weather_client/aea-config.yaml
+++ b/packages/fetchai/agents/weather_client/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/fetchai/agents/weather_station/aea-config.yaml b/packages/fetchai/agents/weather_station/aea-config.yaml
index 0b892a4102..aab1c30c5c 100644
--- a/packages/fetchai/agents/weather_station/aea-config.yaml
+++ b/packages/fetchai/agents/weather_station/aea-config.yaml
@@ -10,7 +10,7 @@ connections:
- fetchai/ledger:0.6.0
- fetchai/p2p_libp2p:0.10.0
- fetchai/soef:0.9.0
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 29718482ad..56e70841c7 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -1,23 +1,23 @@
-fetchai/agents/aries_alice,Qme8sHgd9CZbBEbnS9zwDs53mYZM4EDpJf5RzQnE2QMy35
-fetchai/agents/aries_faber,QmVQXALXYg5M1Qbqznc4PqM5i4jDt8rFeHvDrq7DcoJx3B
-fetchai/agents/car_data_buyer,QmWk7So9UabsjTEKCkecYN9xwkwJxm4m78GA5VRYcWsQwe
-fetchai/agents/car_detector,QmbUnQ95vMmrL7ootzabP5hKr1iR2srJy3QWg6H2wr9Qib
-fetchai/agents/erc1155_client,QmYUsNAEr2dmx6CP9Jkd33eJMuSQL1uiBADivuUzM8tgiE
-fetchai/agents/erc1155_deployer,QmcbNaXp8vN2Vzbqy4vSKXj27WJK1sBcRf2HtL4eacTnac
-fetchai/agents/generic_buyer,Qme5rHfbeEhmia2RM4vjbiwk1h1o2JiiyyfYZze9jG3mUD
-fetchai/agents/generic_seller,QmPVuku1Cefn76S8rN6GsqdVz12AhbcK6hFMdDMYxsjiAM
-fetchai/agents/gym_aea,QmPP3rtaUY3jdzn1HXjV4dPyY2wYetbbNCqFCQbzbH1GRS
-fetchai/agents/ml_data_provider,QmZFTtD54jcwY8ozmhsdHHZqc2RNX9FZ8dfV8SgYJE9QYM
-fetchai/agents/ml_model_trainer,QmeZmVsNLUw7TP73s5cSomPnwggcrimXHh1RhrPRUDkoQ3
-fetchai/agents/my_first_aea,QmcHnFYQCyXnAM2pN2M4HqLNGJpWApUP7PuiKaPcLkxbas
-fetchai/agents/simple_service_registration,QmWtA9eDYnGKkg5hov887LRJSXTXovb9pp4NJzU7JMq5Lg
-fetchai/agents/tac_controller,QmaG56sZaJRm8DwJXXt9Ci18Va8NfXx6v8vEGKPJngKL4q
-fetchai/agents/tac_controller_contract,QmXhKdptR5aW4TAx9J4auFGqwR3TpiTzdpsKp8KRHL7w7B
-fetchai/agents/tac_participant,QmQxN75ZFVEgizNHa3sqd2zHSnmPvRwS8PCv5FAsJBDnZw
-fetchai/agents/thermometer_aea,QmQ8KgTrt5fH8ZRDpioKGmeyUyc2EUkan4D5KzoFnCwxcG
-fetchai/agents/thermometer_client,QmUY6rmZnufWWmwfSi1m5gR6vD1ZowXpchpUJXgAH6xdNP
-fetchai/agents/weather_client,QmeMHc9hqpciJiRWrAJJszvyjTCs9rgsKC5S1nJRKV9sxQ
-fetchai/agents/weather_station,QmdJcUYuaTbb2J5k9jPcG215bJhKFQUQqJPhiaNoirijJ1
+fetchai/agents/aries_alice,QmYHiYqWNEhmzhBNQCE6cUzRBtnmPbbC5yT47rSZLnoGgk
+fetchai/agents/aries_faber,QmTSTfkJW1UtKtsRjboCQa7BGXrBPJsaKmAwZ5B1vgMwPp
+fetchai/agents/car_data_buyer,QmNuEJZWSZrS4JSbuRHaRg82kQGjMJxYTrWFwHTBQFmE46
+fetchai/agents/car_detector,QmebrWVrc9DiQW5SMqz7M2MU7wjRb5qMK1VqhemUoErjVk
+fetchai/agents/erc1155_client,QmbeW3bPTgxRtromSt8EArKZU1Mmx2pSP497Kyx2WYTCsy
+fetchai/agents/erc1155_deployer,QmWGF4m36HZvWpa49AE6cQmWpxrWvrCu7PL5wKkGUQYKsK
+fetchai/agents/generic_buyer,QmfMAT5Vk7vengDfMiH5D2iajAhmtWMUWM2CaVKz5ucxRG
+fetchai/agents/generic_seller,Qmb9PnhRUkc2jBMpDhEeeuqhxHYu8v3ANxXXrat2z9gCU5
+fetchai/agents/gym_aea,QmU4dvEtznNgVpGjo9ptMf46tcuhVAu5tv8dgNGgzEak8p
+fetchai/agents/ml_data_provider,QmeqfbEW6J11SKjrqnCRxjZCMr4VWvr9K1gJRd7ZCWP3uF
+fetchai/agents/ml_model_trainer,QmWnBK6TGFro2VrtcwwBq1eztiT5y4DV92DdeyHPQqGzcY
+fetchai/agents/my_first_aea,QmYqeuaG7mkxqPZTM2qUHP2bMm1A7VsSDLi6BfW6SaFbuZ
+fetchai/agents/simple_service_registration,QmY4oz8n2zjJnAa3vHRRDuzpZi8Taf8qsScX7NJoXrTk3u
+fetchai/agents/tac_controller,QmWVvJemSdE5N5iyMuDt5ZHh1FA32oijHxBqq91zaNkdY3
+fetchai/agents/tac_controller_contract,QmNYxVrNhHy4tfnr48ekReEVHvH1PBzciNQbj8jbJgn2Aj
+fetchai/agents/tac_participant,QmRmswKxJ9mdQe6zFRqxr9U1ZpYTybQf3DKsrAySt39aVc
+fetchai/agents/thermometer_aea,QmT1GNUCcB6xqnmB1vv3jTs4HqeYM6tLnnL4TSjv5raHpk
+fetchai/agents/thermometer_client,QmdWMJCb7Pkz8F3emJ8wKhNWpnEUXHpBFQTGcmJyziu6kH
+fetchai/agents/weather_client,Qmd5iiwyqEuw7Fg8NkdLsNjkuZQRatNRADpXVXwG13BvtP
+fetchai/agents/weather_station,QmRAs7AY2R9RNi5M4gnSDiQzLb58z4nuCYAnG2UAnv3XC2
fetchai/connections/gym,Qmack3EaCW6ARrHrtCnJmL3kR2xrHutJmgD8uoRVGFz6kH
fetchai/connections/http_client,QmaCa98anLuMAduNWtnApEwLWBcqdVkNBREBZ9T5VPSaUm
fetchai/connections/http_server,QmT6JV2sB1rv7XZgx1bEpMjfQJAtpq775D2n8yvzKzSXYK
@@ -29,7 +29,7 @@ fetchai/connections/p2p_libp2p_client,QmSbfL2DT9L1oooKn2pme1tjivEzkzaiRqJ4zahB4J
fetchai/connections/p2p_stub,QmecGYtXsb7HA2dSWrw2ARNTPFqZsKXAbVroBo57cdUQSG
fetchai/connections/scaffold,QmNUta43nLexAHaXLgmLQYEjntLXSV6MLNvc6Q2CTx7eBS
fetchai/connections/soef,Qme2vP55mGemMKMWdHKGUaC1nW88ZEdD55qgdY9a984T7i
-fetchai/connections/stub,QmWarW8MTJ3CHRgXdkbwKK7DyDKzvQKdZeb95uy8kSnxrT
+fetchai/connections/stub,QmQxzFLTBjPUMkpE1uBdkoyhb7iXY4k8VPzyykpjhuUcK1
fetchai/connections/tcp,QmPADQqZJQ4cw1ecdMC2wR7NwFCdk7MYzvmyP62nbfGk7E
fetchai/connections/webhook,QmWcm3WGxcm5JvhuYRyauQp5wmzFAkV61e2aYpDvYmNvWd
fetchai/contracts/erc1155,QmWu22zW9AVMBVySwF413JMiT5dcWsLsU2gk1KvFYWAwPq
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index ff6a6b85e7..578a857d65 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -588,7 +588,7 @@ def test_from_project(self):
aea = builder.build()
assert aea.name == self.agent_name
stub_connection = aea.resources.get_connection(
- PublicId.from_str("fetchai/stub:0.9.0")
+ PublicId.from_str("fetchai/stub:0.10.0")
)
assert stub_connection.configuration.config == dict(
input_file=self.expected_input_file, output_file=self.expected_output_file
diff --git a/tests/test_cli/test_get_multiaddress.py b/tests/test_cli/test_get_multiaddress.py
index 6f2c13e138..0f7643724c 100644
--- a/tests/test_cli/test_get_multiaddress.py
+++ b/tests/test_cli/test_get_multiaddress.py
@@ -79,7 +79,7 @@ def test_run(self, *mocks):
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--host-field",
"host",
"--port-field",
@@ -112,7 +112,7 @@ def test_run(self, *mocks):
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--uri-field",
"public_uri",
cwd=self.current_agent_context,
@@ -188,14 +188,14 @@ def test_run(self, *mocks):
# this will cause exception because no host configuration is in stub connection by default.
with pytest.raises(
Exception,
- match="Host field 'some_host' not present in connection configuration fetchai/stub:0.9.0",
+ match="Host field 'some_host' not present in connection configuration fetchai/stub:0.10.0",
):
self.run_cli_command(
"get-multiaddress",
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--host-field",
"some_host",
"--port-field",
@@ -219,14 +219,14 @@ def test_run(self, *mocks):
# this will cause exception because no port configuration is in stub connection by default.
with pytest.raises(
Exception,
- match="Port field 'some_port' not present in connection configuration fetchai/stub:0.9.0",
+ match="Port field 'some_port' not present in connection configuration fetchai/stub:0.10.0",
):
self.run_cli_command(
"get-multiaddress",
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--host-field",
"host",
"--port-field",
@@ -286,7 +286,7 @@ def test_run(self, *mocks):
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--host-field",
"host",
"--port-field",
@@ -313,7 +313,7 @@ def test_run(self, *mocks):
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--host-field",
"some_host",
cwd=self.current_agent_context,
@@ -331,14 +331,14 @@ def test_run(self, *mocks):
# this will cause exception because only the host, and not the port, are specified.
with pytest.raises(
Exception,
- match="URI field 'some_uri' not present in connection configuration fetchai/stub:0.9.0",
+ match="URI field 'some_uri' not present in connection configuration fetchai/stub:0.10.0",
):
self.run_cli_command(
"get-multiaddress",
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--uri-field",
"some_uri",
cwd=self.current_agent_context,
@@ -367,7 +367,7 @@ def test_run(self, *mocks):
FETCHAI,
"--connection",
"--connection-id",
- "fetchai/stub:0.9.0",
+ "fetchai/stub:0.10.0",
"--uri-field",
"some_uri",
cwd=self.current_agent_context,
diff --git a/tests/test_configurations/test_aea_config.py b/tests/test_configurations/test_aea_config.py
index e7616166e4..54ae447d41 100644
--- a/tests/test_configurations/test_aea_config.py
+++ b/tests/test_configurations/test_aea_config.py
@@ -59,7 +59,7 @@ class NotSet(type):
contracts: []
protocols: []
skills: []
-default_connection: fetchai/stub:0.9.0
+default_connection: fetchai/stub:0.10.0
default_ledger: cosmos
private_key_paths:
cosmos: tests/data/cosmos_private_key.txt
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-config.md b/tests/test_docs/test_bash_yaml/md_files/bash-config.md
index 0032df43c0..e7db01434d 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-config.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-config.md
@@ -14,7 +14,7 @@ aea_version: '>=0.6.0, <0.7.0' # AEA framework version(s) compa
fingerprint: {} # Fingerprint of AEA project components.
fingerprint_ignore_patterns: [] # Ignore pattern for the fingerprinting tool.
connections: # The list of connection public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX)
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: [] # The list of contract public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
protocols: # The list of protocol public ids the AEA project depends on (each public id must satisfy PUBLIC_ID_REGEX).
- fetchai/default:0.6.0
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-logging.md b/tests/test_docs/test_bash_yaml/md_files/bash-logging.md
index 2482123a70..2001ac16c8 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-logging.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-logging.md
@@ -12,13 +12,13 @@ aea_version: 0.6.0
fingerprint: {}
fingerprint_ignore_patterns: []
connections:
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
contracts: []
protocols:
- fetchai/default:0.6.0
skills:
- fetchai/error:0.6.0
-default_connection: fetchai/stub:0.9.0
+default_connection: fetchai/stub:0.10.0
default_ledger: fetchai
logging_config:
disable_existing_loggers: false
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-package-imports.md b/tests/test_docs/test_bash_yaml/md_files/bash-package-imports.md
index 2141939abe..35404987c2 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-package-imports.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-package-imports.md
@@ -29,5 +29,5 @@ aea_name/
```
``` yaml
connections:
-- fetchai/stub:0.9.0
+- fetchai/stub:0.10.0
```
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md b/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md
index fd9adbf3d6..e81c856ac9 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-quickstart.md
@@ -61,7 +61,7 @@ recipient_aea,sender_aea,fetchai/default:0.6.0,\x08\x01\x12\x011*\x07\n\x05hello
aea run
```
``` bash
-aea run --connections fetchai/stub:0.9.0
+aea run --connections fetchai/stub:0.10.0
```
``` bash
_ _____ _
From 04658164a0495bfad1017096657e60f8cfd96ee6 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 23 Sep 2020 23:16:28 +0100
Subject: [PATCH 071/131] fix aea builder test
---
tests/test_aea_builder.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index 578a857d65..667a3b6a96 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -568,7 +568,7 @@ def _add_stub_connection_config(self):
---
name: stub
author: fetchai
- version: 0.9.0
+ version: 0.10.0
type: connection
config:
input_file: "{self.expected_input_file}"
From 063653ef4e1f77406f15d19dc2fdf8d48ea6eadc Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Thu, 24 Sep 2020 10:22:20 +0300
Subject: [PATCH 072/131] aea.Manager: projects handling, agent alias creation
---
aea/aea_builder.py | 25 +++-
aea/cli/registry/fetch.py | 19 ++-
aea/configurations/loader.py | 10 +-
aea/manager.py | 228 ++++++++++++++++++++++++++++++-----
tests/test_manager.py | 107 ++++++++++++++++
5 files changed, 348 insertions(+), 41 deletions(-)
create mode 100644 tests/test_manager.py
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index a3570bbdef..2f9fdd22f8 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -292,6 +292,8 @@ class AEABuilder:
DEFAULT_RUNTIME_MODE = "threaded"
DEFAULT_SEARCH_SERVICE_ADDRESS = "fetchai/soef:*"
+ loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
+
# pylint: disable=attribute-defined-outside-init
def __init__(self, with_default_packages: bool = True):
@@ -1336,16 +1338,33 @@ def from_aea_project(
builder = AEABuilder(with_default_packages=False)
# load agent configuration file
- configuration_file = aea_project_path / DEFAULT_AEA_CONFIG_FILE
+ configuration_file = cls.get_configuration_file_path(aea_project_path)
+ agent_configuration = cls.loader.load(configuration_file.open())
- loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
- agent_configuration = loader.load(configuration_file.open())
+ builder.set_from_configuration(
+ agent_configuration, aea_project_path, skip_consistency_check
+ )
+ return builder
+
+ @classmethod
+ def from_config_json(
+ cls, json_data, aea_project_path: PathLike, skip_consistency_check: bool = False
+ ):
+ aea_project_path = Path(aea_project_path)
+ builder = AEABuilder(with_default_packages=False)
+
+ # load agent configuration file
+ agent_configuration = cls.loader._load_agent_config_from_json(json_data)
builder.set_from_configuration(
agent_configuration, aea_project_path, skip_consistency_check
)
return builder
+ @staticmethod
+ def get_configuration_file_path(aea_project_path):
+ return Path(aea_project_path) / DEFAULT_AEA_CONFIG_FILE
+
def _load_and_add_components(
self,
component_type: ComponentType,
diff --git a/aea/cli/registry/fetch.py b/aea/cli/registry/fetch.py
index 8efdd4e051..cf0270c391 100644
--- a/aea/cli/registry/fetch.py
+++ b/aea/cli/registry/fetch.py
@@ -16,6 +16,9 @@
# limitations under the License.
#
# ------------------------------------------------------------------------------
+from aea.helpers.base import cd
+import shutil
+
"""Methods for CLI fetch functionality."""
import os
@@ -32,7 +35,12 @@
@clean_after
-def fetch_agent(ctx: Context, public_id: PublicId, alias: Optional[str] = None) -> None:
+def fetch_agent(
+ ctx: Context,
+ public_id: PublicId,
+ alias: Optional[str] = None,
+ dir: Optional[str] = None,
+) -> None:
"""
Fetch Agent from Registry.
@@ -49,14 +57,17 @@ def fetch_agent(ctx: Context, public_id: PublicId, alias: Optional[str] = None)
filepath = download_file(file_url, ctx.cwd)
- folder_name = name if alias is None else alias
+ folder_name = dir or (name if alias is None else alias)
aea_folder = os.path.join(ctx.cwd, folder_name)
+ print(aea_folder)
ctx.clean_paths.append(aea_folder)
extract(filepath, ctx.cwd)
- if alias is not None:
- os.rename(name, alias)
+ if alias or dir:
+ shutil.move(
+ os.path.join(ctx.cwd, name), aea_folder,
+ )
ctx.cwd = aea_folder
try_to_load_agent_config(ctx)
diff --git a/aea/configurations/loader.py b/aea/configurations/loader.py
index 8a5c1e84d0..4956406c95 100644
--- a/aea/configurations/loader.py
+++ b/aea/configurations/loader.py
@@ -229,10 +229,7 @@ def _load_from_json(self, configuration_file_json: Dict) -> T:
configuration_obj._key_order = key_order # pylint: disable=protected-access
return configuration_obj
- def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
- """Load an agent configuration."""
- configuration_file_jsons = yaml_load_all(file_pointer)
-
+ def _load_agent_config_from_json(self, configuration_file_jsons) -> AgentConfig:
if len(configuration_file_jsons) == 0:
raise ValueError("Agent configuration file was empty.")
agent_config_json = configuration_file_jsons[0]
@@ -260,6 +257,11 @@ def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
agent_configuration_obj.component_configurations = component_configurations
return agent_configuration_obj
+ def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
+ """Load an agent configuration."""
+ configuration_file_jsons = yaml_load_all(file_pointer)
+ return self._load_agent_config_from_json(configuration_file_jsons)
+
def _dump_agent_config(
self, configuration: AgentConfig, file_pointer: TextIO
) -> None:
diff --git a/aea/manager.py b/aea/manager.py
index bbb289d858..643543597f 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -17,29 +17,82 @@
#
# ------------------------------------------------------------------------------
"""This module contains the implementation of AEA agents manager."""
-from abc import ABC, abstractmethod
-from typing import Dict, List
-
-from aea.aea_builder import PathLike
-from aea.configurations.base import PublicId
-
-
-class AbstractManager(ABC):
+import copy
+import os
+from shutil import rmtree
+from typing import Dict, List, Optional, Set
+
+from aea.aea import AEA
+from aea.aea_builder import AEABuilder
+from aea.cli.registry.fetch import fetch_agent
+from aea.cli.utils.context import Context
+from aea.configurations.base import ComponentId, PublicId
+from aea.configurations.constants import DEFAULT_LEDGER
+from aea.crypto.helpers import create_private_key
+from aea.helpers.base import yaml_load_all
+
+
+class Project:
+ """Agent project representation."""
+
+ def __init__(self, public_id: PublicId, path: str):
+ """Init project with public_id and project's path."""
+ self.public_id = public_id
+ self.path = path
+ self.agents: Set[str] = set()
+
+ @classmethod
+ def load(cls, working_dir, public_id) -> "Project":
+ """Load project with given pubblic_id to working_dir."""
+ ctx = Context(cwd=working_dir)
+ path = os.path.join(working_dir, public_id.author, public_id.name)
+ fetch_agent(ctx, public_id, dir=os.path.join(public_id.author, public_id.name))
+ return cls(public_id, path)
+
+ def remove(self):
+ """Remove project, do cleanup."""
+ rmtree(self.path)
+
+
+class AgentAlias:
+ """Agent alias representation."""
+
+ def __init__(self, project: Project, name: str, config: List[Dict], agent: AEA):
+ """Init agent alias with project, config, name, agent."""
+ self.project = project
+ self.config = config
+ self.name = name
+ self.agent = agent
+ self.project.agents.add(self.name)
+
+ def remove(self):
+ """Remove agent alias from project."""
+ self.project.agents.remove(self.name)
+
+
+class Manager:
"""Abstract agents manager."""
- def __init__(self, working_dir: PathLike) -> None:
+ AGENT_DO_NOT_OVERRIDE_VALUES = ["skills", "connections", "protocols", "contracts"]
+
+ def __init__(self, working_dir: str) -> None:
"""
Initialize manager.
:param working_dir: directory to store base agents.
"""
self.working_dir = working_dir
+ self._was_working_dir_created = False
+ self.is_started = False
+ self._projects: Dict[PublicId, Project] = {}
+ self._keys_dir = os.path.abspath(os.path.join(self.working_dir, "keys"))
+ self._agents: Dict[str, AgentAlias] = {}
- @abstractmethod
def start_manager(self) -> None:
"""Start manager."""
+ self._ensure_working_dir()
+ self.is_started = True
- @abstractmethod
def stop_manager(self, cleanup: bool = False) -> None:
"""
Stop manager.
@@ -50,40 +103,66 @@ def stop_manager(self, cleanup: bool = False) -> None:
:return: None
"""
+ if self._was_working_dir_created:
+ rmtree(self.working_dir)
+
+ self.is_started = False
- @abstractmethod
def add_project(self, public_id: PublicId) -> None:
"""Fetch agent project and all dependencies to working_dir."""
+ if public_id in self._projects:
+ raise ValueError(f"Project {public_id} was already added!")
+ self._projects[public_id] = Project.load(self.working_dir, public_id)
- @abstractmethod
def remove_project(self, public_id: PublicId) -> None:
"""Remove agent project."""
+ if public_id not in self._projects:
+ raise ValueError(f"Project {public_id} was not added!")
+
+ self._projects.pop(public_id).remove()
- @abstractmethod
def list_projects(self) -> List[PublicId]:
"""
List all agents projects added.
:return: lit of public ids of projects
"""
+ return list(self._projects.keys())
- @abstractmethod
def add_agent(
- self, project_id: PublicId, agent_name: str, config_overrides: Dict
+ self,
+ public_id: PublicId,
+ agent_name: str,
+ agent_overrides: Optional[dict] = None,
+ component_overrides: Optional[List[dict]] = None,
) -> None:
"""
Create new agent configuration based on project with config overrides applied.
Alias is stored in memory only!
- :param project_id: base agent public id
+ :param public_id: base agent project public id
:param agent_name: unique name for the agent
- :param config_overrides: overrides for component section.
+ :param agent_overrides: overrides for agent config.
+ :param component_overrides: overrides for component section.
:return: None
"""
+ if agent_name in self._agents:
+ raise ValueError(f"Agent with name {agent_name} already exists!")
+
+ if public_id not in self._projects:
+ raise ValueError(f"{public_id} project is not added!")
+ project = self._projects[public_id]
+
+ agent_alias = self._build_agent_alias(
+ project=project,
+ agent_name=agent_name,
+ agent_overrides=agent_overrides,
+ component_overrides=component_overrides,
+ )
+ self._agents[agent_name] = agent_alias
- @abstractmethod
def list_agents(self, running_only: bool = False) -> List[str]:
"""
List all agents.
@@ -92,8 +171,8 @@ def list_agents(self, running_only: bool = False) -> List[str]:
:return: list of agents names
"""
+ return list(self._agents.keys())
- @abstractmethod
def remove_agent(self, agent_name: str) -> None:
"""
Remove agent alias definition from registry.
@@ -102,8 +181,12 @@ def remove_agent(self, agent_name: str) -> None:
:return: None
"""
+ if agent_name not in self._agents:
+ raise ValueError(f"Agent with name {agent_name} does not exist!")
+
+ agent_alias = self._agents.pop(agent_name)
+ agent_alias.remove()
- @abstractmethod
def start_agent(self, agent_name: str) -> None:
"""
Start selected agent.
@@ -113,7 +196,6 @@ def start_agent(self, agent_name: str) -> None:
:return: None
"""
- @abstractmethod
def start_all_agents(self) -> None:
"""
Start all not started agents.
@@ -121,7 +203,6 @@ def start_all_agents(self) -> None:
:return: None
"""
- @abstractmethod
def stop_agent(self, agent_name: str) -> None:
"""
Stop running agent.
@@ -131,7 +212,6 @@ def stop_agent(self, agent_name: str) -> None:
:return: None
"""
- @abstractmethod
def stop_all_agents(self) -> None:
"""
Stop all agents running.
@@ -139,13 +219,101 @@ def stop_all_agents(self) -> None:
:return: None
"""
- @abstractmethod
- def get_agent_details(self, agent_name: str) -> dict:
+ def stop_agents(self, agent_names: List[str]) -> None:
+ """
+ Stop specified agents.
+
+ :return: None
+ """
+
+ def start_agents(self, agent_names: List[str]) -> None:
+ """
+ Stop specified agents.
+
+ :return: None
+ """
+
+ def get_agent_details(self, agent_name: str) -> AgentAlias:
"""
Return details about agent definition.
- {
- "project": str
- "overrides": dict
- }
+ :return: AgentAlias
"""
+ if agent_name not in self._agents:
+ raise ValueError(f"Agent with name {agent_name} does not exist!")
+ return self._agents[agent_name]
+
+ def _ensure_working_dir(self) -> None:
+ """Create working dir if needed."""
+ if not os.path.exists(self.working_dir):
+ os.makedirs(self.working_dir)
+ self._was_working_dir_created = True
+
+ if not os.path.isdir(self.working_dir):
+ raise ValueError(f"{self.working_dir} is not a directory!")
+ os.makedirs(self._keys_dir)
+
+ def _build_agent_alias(
+ self,
+ project: Project,
+ agent_name: str,
+ agent_overrides=None,
+ component_overrides=None,
+ ) -> AgentAlias:
+ """Create agent alias for project, with given name and overrided values."""
+ json_config = self._make_config(
+ project.path, agent_overrides, component_overrides
+ )
+
+ builder = AEABuilder.from_config_json(json_config, project.path)
+ builder.set_name(agent_name)
+
+ if not builder.private_key_paths:
+ default_ledger = json_config[0].get("default_ledger", DEFAULT_LEDGER)
+ builder.add_private_key(
+ default_ledger, self._create_private_key(agent_name, default_ledger)
+ )
+ agent = builder.build()
+ return AgentAlias(project, agent_name, json_config, agent)
+
+ def _update_dict(self, base: dict, override: dict) -> dict:
+ """Apply overrides for dict."""
+ base = copy.deepcopy(base)
+ base.update(override)
+ return base
+
+ def _make_config(
+ self,
+ project_path: str,
+ agent_overrides: Optional[dict] = None,
+ component_overrides: Optional[List[dict]] = None,
+ ) -> List[dict]:
+ """Make new config baseed on proejct's config with overrides applied."""
+ agent_overrides = agent_overrides or {}
+ component_overrides = component_overrides or []
+
+ if any([key in agent_overrides for key in self.AGENT_DO_NOT_OVERRIDE_VALUES]):
+ raise ValueError(
+ 'Do not override any of {" ".join(self.AGENT_DO_NOT_OVERRIDE_VALUES)}'
+ )
+
+ json_data = yaml_load_all(
+ AEABuilder.get_configuration_file_path(project_path).open()
+ )
+ agent_config = self._update_dict(json_data[0], agent_overrides)
+
+ components_configs = {PublicId.from_json(obj): obj for obj in json_data[1:]}
+
+ for obj in component_overrides:
+ component_id = ComponentId(obj["type"], PublicId.from_json(obj))
+ components_configs[component_id] = self._update_dict(
+ components_configs.get(component_id, {}), obj
+ )
+
+ return [agent_config] + list(components_configs.values())
+
+ def _create_private_key(self, name, ledger) -> str:
+ """Create new key for agent alias in working dir keys dir."""
+ path = os.path.join(self._keys_dir, f"{name}_{ledger}_private.key")
+ create_private_key(ledger, path)
+ return path
diff --git a/tests/test_manager.py b/tests/test_manager.py
new file mode 100644
index 0000000000..e5a4c6af57
--- /dev/null
+++ b/tests/test_manager.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+# ------------------------------------------------------------------------------
+#
+# Copyright 2018-2020 Fetch.AI Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ------------------------------------------------------------------------------
+"""This module contains tests for aea manager."""
+import os
+from contextlib import suppress
+from shutil import rmtree
+from typing import Dict, List, Optional, Set
+
+import pytest
+
+from aea.configurations.base import PublicId
+from aea.manager import Manager
+
+
+def test_manager():
+ """Perform some tests."""
+
+ try:
+ working_dir = "manager_dir"
+ project_public_id = PublicId("fetchai", "my_first_aea", "0.11.0")
+ project_path = os.path.join(
+ working_dir, project_public_id.author, project_public_id.name
+ )
+ assert not os.path.exists(working_dir)
+ manager = Manager(working_dir)
+ manager.start_manager()
+ assert os.path.exists(working_dir)
+ assert manager.is_started
+
+ manager.add_project(project_public_id)
+
+ assert project_public_id in manager.list_projects()
+ assert os.path.exists(project_path)
+ assert manager._projects[project_public_id].path == project_path
+
+ with pytest.raises(ValueError, match=r".*was already added.*"):
+ manager.add_project(project_public_id)
+
+ echo_skill_id = PublicId("fetchai", "echo", "0.7.0")
+ new_tick_interval = 1.1111
+ agent_name = "test_what_ever12"
+ manager.add_agent(
+ project_public_id,
+ agent_name,
+ component_overrides=[
+ {
+ "type": "skill",
+ **echo_skill_id.json,
+ "behaviours": {
+ "echo": {
+ "args": {"tick_interval": new_tick_interval},
+ "class_name": "EchoBehaviour",
+ }
+ },
+ }
+ ],
+ )
+ agent_alias = manager.get_agent_details(agent_name)
+ assert agent_alias.name == agent_name
+ assert (
+ agent_alias.agent.resources.get_behaviour(
+ echo_skill_id, "echo"
+ ).tick_interval
+ == new_tick_interval
+ )
+ with pytest.raises(ValueError, match="already exists"):
+ manager.add_agent(
+ project_public_id, agent_name,
+ )
+ assert agent_name in manager.list_agents()
+
+ manager.remove_agent(agent_name)
+ assert agent_name not in manager.list_agents()
+
+ with pytest.raises(ValueError, match="does not exist!"):
+ manager.remove_agent(agent_name)
+
+ manager.remove_project(project_public_id)
+ assert project_public_id not in manager._projects
+ assert not os.path.exists(project_path)
+ assert project_public_id not in manager.list_projects()
+
+ with pytest.raises(ValueError, match=r"was not added"):
+ manager.remove_project(project_public_id)
+
+ manager.stop_manager()
+ assert not os.path.exists(working_dir)
+ assert not manager.is_started
+ finally:
+ with suppress(FileNotFoundError):
+ rmtree(working_dir)
From 413ddee4cafa6cca52b667799cec2903cfcb1837 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 24 Sep 2020 10:01:54 +0100
Subject: [PATCH 073/131] fix tac contract yaml and dialogues
---
.../agents/tac_controller_contract/aea-config.yaml | 2 +-
.../fetchai/skills/tac_control_contract/behaviours.py | 9 +++++++++
.../fetchai/skills/tac_control_contract/dialogues.py | 6 ++++++
packages/fetchai/skills/tac_control_contract/skill.yaml | 4 ++--
packages/hashes.csv | 4 ++--
5 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index 8b7256a5ed..1d9f658154 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -34,7 +34,7 @@ private_key_paths: {}
registry_path: ../packages
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
- fetchai/ledger_api:0.5.0: fetchai/ledger:0.6.0
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
---
name: soef
diff --git a/packages/fetchai/skills/tac_control_contract/behaviours.py b/packages/fetchai/skills/tac_control_contract/behaviours.py
index dee52e40e7..bbf02c9ae4 100644
--- a/packages/fetchai/skills/tac_control_contract/behaviours.py
+++ b/packages/fetchai/skills/tac_control_contract/behaviours.py
@@ -75,6 +75,9 @@ def _request_contract_deploy_transaction(self) -> None:
)
contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue,)
contract_api_dialogue.terms = parameters.get_deploy_terms()
+ contract_api_dialogue.callable = (
+ ContractApiDialogue.Callable.GET_DEPLOY_TRANSACTION
+ )
self.context.outbox.put_message(message=contract_api_msg)
self.context.logger.info("requesting contract deployment transaction...")
@@ -162,6 +165,9 @@ def _request_create_items_transaction(self, game: Game) -> None:
)
contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
contract_api_dialogue.terms = parameters.get_create_token_terms()
+ contract_api_dialogue.callable = (
+ ContractApiDialogue.Callable.GET_CREATE_BATCH_TRANSACTION
+ )
self.context.outbox.put_message(message=contract_api_msg)
self.context.logger.info("requesting create items transaction...")
@@ -203,4 +209,7 @@ def _request_mint_items_transaction(self, game: Game) -> None:
)
contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
contract_api_dialogue.terms = parameters.get_mint_token_terms()
+ contract_api_dialogue.callable = (
+ ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION
+ )
self.context.outbox.put_message(message=contract_api_msg)
diff --git a/packages/fetchai/skills/tac_control_contract/dialogues.py b/packages/fetchai/skills/tac_control_contract/dialogues.py
index 9e2b5c2588..6f7fadfc61 100644
--- a/packages/fetchai/skills/tac_control_contract/dialogues.py
+++ b/packages/fetchai/skills/tac_control_contract/dialogues.py
@@ -130,6 +130,12 @@ def callable(self) -> "Callable":
raise ValueError("Callable not set!")
return self._callable
+ @callable.setter
+ def callable(self, callable: "Callable") -> None:
+ """Set the callable."""
+ enforce(self._callable is None, "Callable already set!")
+ self._callable = callable
+
@property
def terms(self) -> Terms:
"""Get the terms."""
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index 73c3ff5b53..a27a4461f6 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -9,8 +9,8 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmUiw6Dt97mXLzSizbnMNTsfLy3edGXKdYTNR5bke6sFsm
__init__.py: QmW9WBy1sNYVKpymGnpJY2pW5MEqGgVga2kBFUT9S34Yt5
- behaviours.py: QmYcW84nnvCuv2HeDntixfWnFuJA2k9xqrhCWdmVFerLPv
- dialogues.py: QmPJyBPETi7MggXLMKHWeYsAZbckxK2UFpci19dw3xwHDn
+ behaviours.py: QmaNbF9fuhEzrh56q7tnFF3hKXQtFYGr1tnsgELp3z3jRS
+ dialogues.py: QmYQ5XiaRoGeLdz7z3d8gcDTzY8EeyHCgB9Nagkuwmfwjy
game.py: QmQwskD5DBVNv1ouRpqGNLb3zQ5krLUcR6XXHUcJ5EVc8L
handlers.py: QmSzNcZ3s3RjVm7mCXBhGjA379nwv3Tm9viEmw193WcNTd
helpers.py: QmX3iv37Z5CmGupCtikc4muTpJyQ9zvjeLbNKDLF7iPhSZ
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 56e70841c7..9e4075b83d 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -12,7 +12,7 @@ fetchai/agents/ml_model_trainer,QmWnBK6TGFro2VrtcwwBq1eztiT5y4DV92DdeyHPQqGzcY
fetchai/agents/my_first_aea,QmYqeuaG7mkxqPZTM2qUHP2bMm1A7VsSDLi6BfW6SaFbuZ
fetchai/agents/simple_service_registration,QmY4oz8n2zjJnAa3vHRRDuzpZi8Taf8qsScX7NJoXrTk3u
fetchai/agents/tac_controller,QmWVvJemSdE5N5iyMuDt5ZHh1FA32oijHxBqq91zaNkdY3
-fetchai/agents/tac_controller_contract,QmNYxVrNhHy4tfnr48ekReEVHvH1PBzciNQbj8jbJgn2Aj
+fetchai/agents/tac_controller_contract,QmXmUu3XQj3E5jcSzi6fRT5ZkWw65HFnvzwqRDS5hcLqSz
fetchai/agents/tac_participant,QmRmswKxJ9mdQe6zFRqxr9U1ZpYTybQf3DKsrAySt39aVc
fetchai/agents/thermometer_aea,QmT1GNUCcB6xqnmB1vv3jTs4HqeYM6tLnnL4TSjv5raHpk
fetchai/agents/thermometer_client,QmdWMJCb7Pkz8F3emJ8wKhNWpnEUXHpBFQTGcmJyziu6kH
@@ -63,7 +63,7 @@ fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
fetchai/skills/tac_control,QmPFxFsYqRZvz7BRStWLV9Fo4Wd77iTNBWuBSU2VZeqrwL
-fetchai/skills/tac_control_contract,QmYX4gNaGbx1EAuASwhpSgTdLYwUzuzajtKTuqvNFR9f2Q
+fetchai/skills/tac_control_contract,QmSFbu21xtJTUqKXW5t1V6fQvVV49eA4FGtR4rgkcs8cBK
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
From 712a7b78a77778b66a30cdfa70848131444562f0 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 24 Sep 2020 11:27:35 +0100
Subject: [PATCH 074/131] fix contract deployment in tac skill
---
.../tac_participant_contract/aea-config.yaml | 44 +++++++++++++++++++
packages/fetchai/skills/tac_control/game.py | 3 --
.../fetchai/skills/tac_control/parameters.py | 2 +-
.../fetchai/skills/tac_control/skill.yaml | 4 +-
.../skills/tac_control_contract/behaviours.py | 4 +-
.../skills/tac_control_contract/dialogues.py | 4 +-
.../skills/tac_control_contract/handlers.py | 5 ++-
.../skills/tac_control_contract/skill.yaml | 6 +--
packages/hashes.csv | 5 ++-
9 files changed, 63 insertions(+), 14 deletions(-)
create mode 100644 packages/fetchai/agents/tac_participant_contract/aea-config.yaml
diff --git a/packages/fetchai/agents/tac_participant_contract/aea-config.yaml b/packages/fetchai/agents/tac_participant_contract/aea-config.yaml
new file mode 100644
index 0000000000..cde745ed9b
--- /dev/null
+++ b/packages/fetchai/agents/tac_participant_contract/aea-config.yaml
@@ -0,0 +1,44 @@
+agent_name: tac_participant
+author: fetchai
+version: 0.11.0
+description: An AEA to participate in the TAC (trading agent competition)
+license: Apache-2.0
+aea_version: '>=0.6.0, <0.7.0'
+fingerprint: {}
+fingerprint_ignore_patterns: []
+connections:
+- fetchai/ledger:0.6.0
+- fetchai/p2p_libp2p:0.10.0
+- fetchai/soef:0.9.0
+- fetchai/stub:0.10.0
+contracts:
+- fetchai/erc1155:0.10.0
+protocols:
+- fetchai/default:0.6.0
+- fetchai/fipa:0.7.0
+- fetchai/oef_search:0.7.0
+- fetchai/tac:0.7.0
+skills:
+- fetchai/error:0.6.0
+- fetchai/tac_negotiation:0.10.0
+- fetchai/tac_participation:0.9.0
+default_connection: fetchai/p2p_libp2p:0.10.0
+default_ledger: fetchai
+logging_config:
+ disable_existing_loggers: false
+ version: 1
+private_key_paths: {}
+registry_path: ../packages
+default_routing:
+ fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
+---
+name: tac_participation
+author: fetchai
+version: 0.9.0
+type: skill
+---
+name: tac_negotiation
+author: fetchai
+version: 0.10.0
+type: skill
diff --git a/packages/fetchai/skills/tac_control/game.py b/packages/fetchai/skills/tac_control/game.py
index 84b2469433..94f5277f55 100644
--- a/packages/fetchai/skills/tac_control/game.py
+++ b/packages/fetchai/skills/tac_control/game.py
@@ -72,15 +72,12 @@ class Phase(Enum):
PRE_GAME = "pre_game"
CONTRACT_DEPLOYMENT_PROPOSAL = "contract_deployment_proposal"
- CONTRACT_DEPLOYING = "contract_deploying"
CONTRACT_DEPLOYED = "contract_deployed"
GAME_REGISTRATION = "game_registration"
GAME_SETUP = "game_setup"
TOKENS_CREATION_PROPOSAL = "token_creation_proposal" # nosec
- TOKENS_CREATING = "tokens_creating"
TOKENS_CREATED = "tokens_created" # nosec
TOKENS_MINTING_PROPOSAL = "token_minting_proposal"
- TOKENS_MINTING = "token_minting" # nosec
TOKENS_MINTED = "tokens_minted" # nosec
GAME = "game"
POST_GAME = "post_game"
diff --git a/packages/fetchai/skills/tac_control/parameters.py b/packages/fetchai/skills/tac_control/parameters.py
index a490fa92c9..df7a105677 100644
--- a/packages/fetchai/skills/tac_control/parameters.py
+++ b/packages/fetchai/skills/tac_control/parameters.py
@@ -57,7 +57,7 @@ def __init__(self, **kwargs):
"""Instantiate the parameter class."""
self._ledger_id = kwargs.pop("ledger_id", DEFAULT_LEDGER_ID)
self._contract_address = kwargs.pop(
- "contract_adress", None
+ "contract_address", None
) # type: Optional[str]
self._good_ids = kwargs.pop("good_ids", []) # type: List[int]
self._currency_ids = kwargs.pop("currency_ids", []) # type: List[int]
diff --git a/packages/fetchai/skills/tac_control/skill.yaml b/packages/fetchai/skills/tac_control/skill.yaml
index 85cb506acc..c52139d7eb 100644
--- a/packages/fetchai/skills/tac_control/skill.yaml
+++ b/packages/fetchai/skills/tac_control/skill.yaml
@@ -11,10 +11,10 @@ fingerprint:
__init__.py: Qme9YfgfPXymvupw1EHMJWGUSMTT6JQZxk2qaeKE76pgyN
behaviours.py: QmcznM3tsmEDNx9Vbhv48o3PNtBEz5W1MVQ7SxJFGkH7di
dialogues.py: QmcVYVTZ95UKBnXzmKyGLo5LwSVcGYUTrifosQMSpzNnCX
- game.py: QmTovmW5vuhUcnvW4wQQcbPpiUFLLvMH7LaeTZYVvjqLcF
+ game.py: QmPabHgmR3vmhWLJh4BE1GUHPb7GkBwprpUq8mRcCtXdNN
handlers.py: QmSjwPKEN83C2gQS4WVH8uaHMv5ze7EJ9S8ugmRcKnSwnW
helpers.py: QmQXrtqV3h4oU5cDwWKhtNiTTAGLNZGhjoVnDvGj7mGwpe
- parameters.py: QmeviKY6o3H2FYNFaB9PibZGZc1CwMgLbrCbPoSmZDsikv
+ parameters.py: QmefuFt5DPCBciu4z17UJWcXxtb4vwA879pNwh4DoMKPUm
fingerprint_ignore_patterns: []
contracts:
- fetchai/erc1155:0.10.0
diff --git a/packages/fetchai/skills/tac_control_contract/behaviours.py b/packages/fetchai/skills/tac_control_contract/behaviours.py
index bbf02c9ae4..46cc65528a 100644
--- a/packages/fetchai/skills/tac_control_contract/behaviours.py
+++ b/packages/fetchai/skills/tac_control_contract/behaviours.py
@@ -99,7 +99,9 @@ def act(self) -> None:
game.phase = Phase.GAME_REGISTRATION
self._register_tac()
self.context.logger.info(
- "TAC open for registration until: {}".format(parameters.start_time)
+ "TAC open for registration until: {}".format(
+ parameters.registration_end_time
+ )
)
elif (
game.phase.value == Phase.GAME_REGISTRATION.value
diff --git a/packages/fetchai/skills/tac_control_contract/dialogues.py b/packages/fetchai/skills/tac_control_contract/dialogues.py
index 6f7fadfc61..af0adf5faa 100644
--- a/packages/fetchai/skills/tac_control_contract/dialogues.py
+++ b/packages/fetchai/skills/tac_control_contract/dialogues.py
@@ -131,7 +131,9 @@ def callable(self) -> "Callable":
return self._callable
@callable.setter
- def callable(self, callable: "Callable") -> None:
+ def callable( # pylint: disable=redefined-builtin
+ self, callable: "Callable"
+ ) -> None:
"""Set the callable."""
enforce(self._callable is None, "Callable already set!")
self._callable = callable
diff --git a/packages/fetchai/skills/tac_control_contract/handlers.py b/packages/fetchai/skills/tac_control_contract/handlers.py
index a286adde7c..bf14e68ec6 100644
--- a/packages/fetchai/skills/tac_control_contract/handlers.py
+++ b/packages/fetchai/skills/tac_control_contract/handlers.py
@@ -423,11 +423,13 @@ def _handle_transaction_receipt(
)
parameters.contract_address = contract_address
game.phase = Phase.CONTRACT_DEPLOYED
+ self.context.logger.info("contract deployed.")
elif (
contract_api_dialogue.callable
== ContractApiDialogue.Callable.GET_CREATE_BATCH_TRANSACTION
):
game.phase = Phase.TOKENS_CREATED
+ self.context.logger.info("TOKENS_CREATED created.")
elif (
contract_api_dialogue.callable
== ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION
@@ -435,8 +437,9 @@ def _handle_transaction_receipt(
parameters.nb_completed_minting += 1
if game.registration.nb_agents == parameters.nb_completed_minting:
game.phase = Phase.TOKENS_MINTED
+ self.context.logger.info("tokens minted.")
else:
- self.context.logger.error("Unexpected transaction receipt!")
+ self.context.logger.error("unexpected transaction receipt!")
else:
self.context.logger.error(
"transaction failed. Transaction receipt={}".format(
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index a27a4461f6..3a779d6a0b 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -9,10 +9,10 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmUiw6Dt97mXLzSizbnMNTsfLy3edGXKdYTNR5bke6sFsm
__init__.py: QmW9WBy1sNYVKpymGnpJY2pW5MEqGgVga2kBFUT9S34Yt5
- behaviours.py: QmaNbF9fuhEzrh56q7tnFF3hKXQtFYGr1tnsgELp3z3jRS
- dialogues.py: QmYQ5XiaRoGeLdz7z3d8gcDTzY8EeyHCgB9Nagkuwmfwjy
+ behaviours.py: QmVwuR8bhRfoSnYDZ7hmSy8o8bvUmdf52Vp3Tt8EHhEmyL
+ dialogues.py: QmWvhTeUnDimhQQTzuSfJJ6d2ViqgBNooCMfRiVzvzApw3
game.py: QmQwskD5DBVNv1ouRpqGNLb3zQ5krLUcR6XXHUcJ5EVc8L
- handlers.py: QmSzNcZ3s3RjVm7mCXBhGjA379nwv3Tm9viEmw193WcNTd
+ handlers.py: QmTgbPjKaKQYmTr9SgJkCvTaP96NNbDs6BFfbNXE9tr9bz
helpers.py: QmX3iv37Z5CmGupCtikc4muTpJyQ9zvjeLbNKDLF7iPhSZ
parameters.py: QmVMNP52fPxkzEbXPhXtQXspnaj2f4ErZNcNdPAqv4cvwq
fingerprint_ignore_patterns: []
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 9e4075b83d..0fe1906508 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -14,6 +14,7 @@ fetchai/agents/simple_service_registration,QmY4oz8n2zjJnAa3vHRRDuzpZi8Taf8qsScX7
fetchai/agents/tac_controller,QmWVvJemSdE5N5iyMuDt5ZHh1FA32oijHxBqq91zaNkdY3
fetchai/agents/tac_controller_contract,QmXmUu3XQj3E5jcSzi6fRT5ZkWw65HFnvzwqRDS5hcLqSz
fetchai/agents/tac_participant,QmRmswKxJ9mdQe6zFRqxr9U1ZpYTybQf3DKsrAySt39aVc
+fetchai/agents/tac_participant_contract,QmaZQ17y4Lm8MNVpDP9kUm31z5HpLDrGWW8yy3FWPwcFN4
fetchai/agents/thermometer_aea,QmT1GNUCcB6xqnmB1vv3jTs4HqeYM6tLnnL4TSjv5raHpk
fetchai/agents/thermometer_client,QmdWMJCb7Pkz8F3emJ8wKhNWpnEUXHpBFQTGcmJyziu6kH
fetchai/agents/weather_client,Qmd5iiwyqEuw7Fg8NkdLsNjkuZQRatNRADpXVXwG13BvtP
@@ -62,8 +63,8 @@ fetchai/skills/ml_data_provider,QmaKyLjyvcj35bCHaKKo15MeF7k48hKPCfFbrtvXCogYwV
fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
-fetchai/skills/tac_control,QmPFxFsYqRZvz7BRStWLV9Fo4Wd77iTNBWuBSU2VZeqrwL
-fetchai/skills/tac_control_contract,QmSFbu21xtJTUqKXW5t1V6fQvVV49eA4FGtR4rgkcs8cBK
+fetchai/skills/tac_control,QmSjh4JAzWG3oPUzazXvnTvKRBJ4nqRGLr9hCQeUP5x4eR
+fetchai/skills/tac_control_contract,QmQpFb1rWiR1TLfyDx3fJcCQNcAEZSh669iZhgAvgK98Us
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
From 89eff75542df6dbd382b45b23927f53c44c16be8 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 24 Sep 2020 11:31:09 +0100
Subject: [PATCH 075/131] fix log statement in tac control contract
---
packages/fetchai/skills/tac_control_contract/handlers.py | 2 +-
packages/fetchai/skills/tac_control_contract/skill.yaml | 2 +-
packages/hashes.csv | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/fetchai/skills/tac_control_contract/handlers.py b/packages/fetchai/skills/tac_control_contract/handlers.py
index bf14e68ec6..0c93082691 100644
--- a/packages/fetchai/skills/tac_control_contract/handlers.py
+++ b/packages/fetchai/skills/tac_control_contract/handlers.py
@@ -429,7 +429,7 @@ def _handle_transaction_receipt(
== ContractApiDialogue.Callable.GET_CREATE_BATCH_TRANSACTION
):
game.phase = Phase.TOKENS_CREATED
- self.context.logger.info("TOKENS_CREATED created.")
+ self.context.logger.info("tokens created.")
elif (
contract_api_dialogue.callable
== ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index 3a779d6a0b..d01fa264a8 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -12,7 +12,7 @@ fingerprint:
behaviours.py: QmVwuR8bhRfoSnYDZ7hmSy8o8bvUmdf52Vp3Tt8EHhEmyL
dialogues.py: QmWvhTeUnDimhQQTzuSfJJ6d2ViqgBNooCMfRiVzvzApw3
game.py: QmQwskD5DBVNv1ouRpqGNLb3zQ5krLUcR6XXHUcJ5EVc8L
- handlers.py: QmTgbPjKaKQYmTr9SgJkCvTaP96NNbDs6BFfbNXE9tr9bz
+ handlers.py: QmT1TaYDstQewEVptuRuUCgcEcyX1R47ZRzB2MGQWg2NxC
helpers.py: QmX3iv37Z5CmGupCtikc4muTpJyQ9zvjeLbNKDLF7iPhSZ
parameters.py: QmVMNP52fPxkzEbXPhXtQXspnaj2f4ErZNcNdPAqv4cvwq
fingerprint_ignore_patterns: []
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 0fe1906508..0d51597d5a 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -64,7 +64,7 @@ fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
fetchai/skills/tac_control,QmSjh4JAzWG3oPUzazXvnTvKRBJ4nqRGLr9hCQeUP5x4eR
-fetchai/skills/tac_control_contract,QmQpFb1rWiR1TLfyDx3fJcCQNcAEZSh669iZhgAvgK98Us
+fetchai/skills/tac_control_contract,QmUNSvgheuMrerJ5aX2PhGLX2xVwdMXdepYsBoKYJ649VX
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
From 51da3a65d3ef3cdea5c13fdb4aa926730ee7b012 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 24 Sep 2020 19:20:42 +0100
Subject: [PATCH 076/131] fix contract deployment, minting and creating
---
.../tac_controller_contract/aea-config.yaml | 2 +-
packages/fetchai/skills/tac_control/game.py | 12 +++
.../fetchai/skills/tac_control/skill.yaml | 2 +-
.../skills/tac_control_contract/behaviours.py | 80 ++++++++++---------
.../skills/tac_control_contract/handlers.py | 3 +-
.../skills/tac_control_contract/skill.yaml | 7 +-
packages/hashes.csv | 6 +-
7 files changed, 67 insertions(+), 45 deletions(-)
diff --git a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
index 1d9f658154..9846c1d80b 100644
--- a/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_controller_contract/aea-config.yaml
@@ -35,7 +35,7 @@ registry_path: ../packages
default_routing:
fetchai/contract_api:0.5.0: fetchai/ledger:0.6.0
fetchai/ledger_api:0.4.0: fetchai/ledger:0.6.0
- fetchai/oef_search:0.6.0: fetchai/soef:0.8.0
+ fetchai/oef_search:0.7.0: fetchai/soef:0.9.0
---
name: soef
author: fetchai
diff --git a/packages/fetchai/skills/tac_control/game.py b/packages/fetchai/skills/tac_control/game.py
index 94f5277f55..795d56349b 100644
--- a/packages/fetchai/skills/tac_control/game.py
+++ b/packages/fetchai/skills/tac_control/game.py
@@ -742,6 +742,7 @@ def __init__(self, **kwargs):
self._initial_agent_states = None # type: Optional[Dict[str, AgentState]]
self._current_agent_states = None # type: Optional[Dict[str, AgentState]]
self._transactions = Transactions()
+ self._already_minted_agents = [] # type: List[str]
@property
def phase(self) -> Phase:
@@ -798,6 +799,17 @@ def create(self):
self._phase = Phase.GAME_SETUP
self._generate()
+ def get_next_agent_state_for_minting(self) -> Optional[AgentState]:
+ """Get next agent state for token minting."""
+ result = None
+ for agent_addr, agent_state in self.initial_agent_states.items():
+ if agent_addr in self._already_minted_agents:
+ continue
+ self._already_minted_agents.append(agent_addr)
+ result = agent_state
+ break
+ return result
+
def _generate(self):
"""Generate a TAC game."""
parameters = cast(Parameters, self.context.parameters)
diff --git a/packages/fetchai/skills/tac_control/skill.yaml b/packages/fetchai/skills/tac_control/skill.yaml
index c52139d7eb..365cd3f603 100644
--- a/packages/fetchai/skills/tac_control/skill.yaml
+++ b/packages/fetchai/skills/tac_control/skill.yaml
@@ -11,7 +11,7 @@ fingerprint:
__init__.py: Qme9YfgfPXymvupw1EHMJWGUSMTT6JQZxk2qaeKE76pgyN
behaviours.py: QmcznM3tsmEDNx9Vbhv48o3PNtBEz5W1MVQ7SxJFGkH7di
dialogues.py: QmcVYVTZ95UKBnXzmKyGLo5LwSVcGYUTrifosQMSpzNnCX
- game.py: QmPabHgmR3vmhWLJh4BE1GUHPb7GkBwprpUq8mRcCtXdNN
+ game.py: QmaDGFufEofsvo62E8KGUfaAeyDrPc5Mxih3JjDFSEpkqU
handlers.py: QmSjwPKEN83C2gQS4WVH8uaHMv5ze7EJ9S8ugmRcKnSwnW
helpers.py: QmQXrtqV3h4oU5cDwWKhtNiTTAGLNZGhjoVnDvGj7mGwpe
parameters.py: QmefuFt5DPCBciu4z17UJWcXxtb4vwA879pNwh4DoMKPUm
diff --git a/packages/fetchai/skills/tac_control_contract/behaviours.py b/packages/fetchai/skills/tac_control_contract/behaviours.py
index 46cc65528a..50671a53ad 100644
--- a/packages/fetchai/skills/tac_control_contract/behaviours.py
+++ b/packages/fetchai/skills/tac_control_contract/behaviours.py
@@ -131,6 +131,8 @@ def act(self) -> None:
elif game.phase.value == Phase.TOKENS_CREATED.value:
game.phase = Phase.TOKENS_MINTING_PROPOSAL
self._request_mint_items_transaction(game)
+ elif game.phase.value == Phase.TOKENS_MINTING_PROPOSAL.value:
+ self._request_mint_items_transaction(game)
elif (
game.phase.value == Phase.TOKENS_MINTED.value
and parameters.start_time < now < parameters.end_time
@@ -160,6 +162,7 @@ def _request_create_items_transaction(self, game: Game) -> None:
performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
ledger_id=parameters.ledger_id,
contract_id="fetchai/erc1155:0.10.0",
+ contract_address=parameters.contract_address,
callable=ContractApiDialogue.Callable.GET_CREATE_BATCH_TRANSACTION.value,
kwargs=ContractApiMessage.Kwargs(
{"deployer_address": self.context.agent_address, "token_ids": token_ids}
@@ -179,39 +182,44 @@ def _request_mint_items_transaction(self, game: Game) -> None:
:return: None
"""
- self.context.logger.info("requesting mint_items transactions.")
- for agent_state in game.initial_agent_states.values():
- parameters = cast(Parameters, self.context.parameters)
- token_ids = [] # type: List[int]
- mint_quantities = [] # type: List[int]
- for good_id, quantity in agent_state.quantities_by_good_id.items():
- token_ids.append(int(good_id))
- mint_quantities.append(quantity)
- for currency_id, amount in agent_state.amount_by_currency_id.items():
- token_ids.append(int(currency_id))
- mint_quantities.append(amount)
- contract_api_dialogues = cast(
- ContractApiDialogues, self.context.contract_api_dialogues
- )
- contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
- counterparty=LEDGER_API_ADDRESS,
- performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
- ledger_id=parameters.ledger_id,
- contract_id="fetchai/erc1155:0.10.0",
- contract_address=parameters.contract_address,
- callable=ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION.value,
- kwargs=ContractApiMessage.Kwargs(
- {
- "deployer_address": self.context.agent_address,
- "recipient_address": self.context.agent_address,
- "token_ids": token_ids,
- "mint_quantities": mint_quantities,
- }
- ),
- )
- contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
- contract_api_dialogue.terms = parameters.get_mint_token_terms()
- contract_api_dialogue.callable = (
- ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION
- )
- self.context.outbox.put_message(message=contract_api_msg)
+ agent_state = game.get_next_agent_state_for_minting()
+ if agent_state is None:
+ return
+ name = game.registration.agent_addr_to_name[agent_state.agent_address]
+ self.context.logger.info(
+ f"requesting mint_items transactions for agent={name}."
+ )
+ parameters = cast(Parameters, self.context.parameters)
+ token_ids = [] # type: List[int]
+ mint_quantities = [] # type: List[int]
+ for good_id, quantity in agent_state.quantities_by_good_id.items():
+ token_ids.append(int(good_id))
+ mint_quantities.append(quantity)
+ for currency_id, amount in agent_state.amount_by_currency_id.items():
+ token_ids.append(int(currency_id))
+ mint_quantities.append(amount)
+ contract_api_dialogues = cast(
+ ContractApiDialogues, self.context.contract_api_dialogues
+ )
+ contract_api_msg, contract_api_dialogue = contract_api_dialogues.create(
+ counterparty=LEDGER_API_ADDRESS,
+ performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION,
+ ledger_id=parameters.ledger_id,
+ contract_id="fetchai/erc1155:0.10.0",
+ contract_address=parameters.contract_address,
+ callable=ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION.value,
+ kwargs=ContractApiMessage.Kwargs(
+ {
+ "deployer_address": self.context.agent_address,
+ "recipient_address": self.context.agent_address,
+ "token_ids": token_ids,
+ "mint_quantities": mint_quantities,
+ }
+ ),
+ )
+ contract_api_dialogue = cast(ContractApiDialogue, contract_api_dialogue)
+ contract_api_dialogue.terms = parameters.get_mint_token_terms()
+ contract_api_dialogue.callable = (
+ ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION
+ )
+ self.context.outbox.put_message(message=contract_api_msg)
diff --git a/packages/fetchai/skills/tac_control_contract/handlers.py b/packages/fetchai/skills/tac_control_contract/handlers.py
index 0c93082691..87079deb32 100644
--- a/packages/fetchai/skills/tac_control_contract/handlers.py
+++ b/packages/fetchai/skills/tac_control_contract/handlers.py
@@ -434,10 +434,11 @@ def _handle_transaction_receipt(
contract_api_dialogue.callable
== ContractApiDialogue.Callable.GET_MINT_BATCH_TRANSACTION
):
+ self.context.logger.info("tokens minted.")
parameters.nb_completed_minting += 1
if game.registration.nb_agents == parameters.nb_completed_minting:
game.phase = Phase.TOKENS_MINTED
- self.context.logger.info("tokens minted.")
+ self.context.logger.info("all tokens minted.")
else:
self.context.logger.error("unexpected transaction receipt!")
else:
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index d01fa264a8..7dc2f629f5 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -9,10 +9,10 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmUiw6Dt97mXLzSizbnMNTsfLy3edGXKdYTNR5bke6sFsm
__init__.py: QmW9WBy1sNYVKpymGnpJY2pW5MEqGgVga2kBFUT9S34Yt5
- behaviours.py: QmVwuR8bhRfoSnYDZ7hmSy8o8bvUmdf52Vp3Tt8EHhEmyL
+ behaviours.py: QmUKPVxyvj3XbEX5CSJh3PBCX6HUvvkgzQ3TqHnLa1r3xh
dialogues.py: QmWvhTeUnDimhQQTzuSfJJ6d2ViqgBNooCMfRiVzvzApw3
game.py: QmQwskD5DBVNv1ouRpqGNLb3zQ5krLUcR6XXHUcJ5EVc8L
- handlers.py: QmT1TaYDstQewEVptuRuUCgcEcyX1R47ZRzB2MGQWg2NxC
+ handlers.py: QmZse9uaY8XFzwLtiGM55if93Zx9PRCuZdSQSCYTRLyjq1
helpers.py: QmX3iv37Z5CmGupCtikc4muTpJyQ9zvjeLbNKDLF7iPhSZ
parameters.py: QmVMNP52fPxkzEbXPhXtQXspnaj2f4ErZNcNdPAqv4cvwq
fingerprint_ignore_patterns: []
@@ -77,7 +77,8 @@ models:
lower_bound_factor: 1
min_nb_agents: 2
money_endowment: 2000000
- nb_goods: 10
+ nb_currencies: 1
+ nb_goods: 9
registration_start_time: 01 01 2020 00:01
registration_timeout: 60
service_data:
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 0d51597d5a..0cbad7258c 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -12,7 +12,7 @@ fetchai/agents/ml_model_trainer,QmWnBK6TGFro2VrtcwwBq1eztiT5y4DV92DdeyHPQqGzcY
fetchai/agents/my_first_aea,QmYqeuaG7mkxqPZTM2qUHP2bMm1A7VsSDLi6BfW6SaFbuZ
fetchai/agents/simple_service_registration,QmY4oz8n2zjJnAa3vHRRDuzpZi8Taf8qsScX7NJoXrTk3u
fetchai/agents/tac_controller,QmWVvJemSdE5N5iyMuDt5ZHh1FA32oijHxBqq91zaNkdY3
-fetchai/agents/tac_controller_contract,QmXmUu3XQj3E5jcSzi6fRT5ZkWw65HFnvzwqRDS5hcLqSz
+fetchai/agents/tac_controller_contract,QmSZRM9QqFpZDosBuY1gCgX4Ho8icAMAnyh6VMti6UdwVE
fetchai/agents/tac_participant,QmRmswKxJ9mdQe6zFRqxr9U1ZpYTybQf3DKsrAySt39aVc
fetchai/agents/tac_participant_contract,QmaZQ17y4Lm8MNVpDP9kUm31z5HpLDrGWW8yy3FWPwcFN4
fetchai/agents/thermometer_aea,QmT1GNUCcB6xqnmB1vv3jTs4HqeYM6tLnnL4TSjv5raHpk
@@ -63,8 +63,8 @@ fetchai/skills/ml_data_provider,QmaKyLjyvcj35bCHaKKo15MeF7k48hKPCfFbrtvXCogYwV
fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
-fetchai/skills/tac_control,QmSjh4JAzWG3oPUzazXvnTvKRBJ4nqRGLr9hCQeUP5x4eR
-fetchai/skills/tac_control_contract,QmUNSvgheuMrerJ5aX2PhGLX2xVwdMXdepYsBoKYJ649VX
+fetchai/skills/tac_control,QmVHPpD3mHoBq523jkkDyZcmwWwWYUJsPp11yCdweKEADy
+fetchai/skills/tac_control_contract,QmPC8HhVYcSJW8TubwqxT1RLK4rV4AVrLAEFuJe4gNkHVR
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
From e7add9b6acc663818c9012cf2db61aa1f86db31b Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 24 Sep 2020 20:43:57 +0100
Subject: [PATCH 077/131] fix contract address forwarding
---
packages/fetchai/skills/tac_control/behaviours.py | 2 +-
packages/fetchai/skills/tac_control/game.py | 11 +++++++++++
packages/fetchai/skills/tac_control/skill.yaml | 4 ++--
.../fetchai/skills/tac_control_contract/behaviours.py | 4 ++++
.../fetchai/skills/tac_control_contract/handlers.py | 1 +
.../fetchai/skills/tac_control_contract/skill.yaml | 4 ++--
packages/hashes.csv | 4 ++--
7 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/packages/fetchai/skills/tac_control/behaviours.py b/packages/fetchai/skills/tac_control/behaviours.py
index 6b79c0f094..72fcf955d7 100644
--- a/packages/fetchai/skills/tac_control/behaviours.py
+++ b/packages/fetchai/skills/tac_control/behaviours.py
@@ -79,6 +79,7 @@ def act(self) -> None:
self._unregister_tac()
else:
game.phase = Phase.GAME_SETUP
+ game.create()
self._start_tac(game)
self._unregister_tac()
game.phase = Phase.GAME
@@ -174,7 +175,6 @@ def _unregister_agent(self) -> None:
def _start_tac(self, game: Game):
"""Create a game and send the game configuration to every registered agent."""
- game.create()
self.context.logger.info(
"started competition:\n{}".format(game.holdings_summary)
)
diff --git a/packages/fetchai/skills/tac_control/game.py b/packages/fetchai/skills/tac_control/game.py
index 795d56349b..e211937816 100644
--- a/packages/fetchai/skills/tac_control/game.py
+++ b/packages/fetchai/skills/tac_control/game.py
@@ -743,6 +743,7 @@ def __init__(self, **kwargs):
self._current_agent_states = None # type: Optional[Dict[str, AgentState]]
self._transactions = Transactions()
self._already_minted_agents = [] # type: List[str]
+ self._is_allowed_to_mint = True
@property
def phase(self) -> Phase:
@@ -799,6 +800,16 @@ def create(self):
self._phase = Phase.GAME_SETUP
self._generate()
+ @property
+ def is_allowed_to_mint(self):
+ """Get is allowed to mint."""
+ return self._is_allowed_to_mint
+
+ @is_allowed_to_mint.setter
+ def is_allowed_to_mint(self, is_allowed_to_mint: bool):
+ """Get is allowed to mint."""
+ self._is_allowed_to_mint = is_allowed_to_mint
+
def get_next_agent_state_for_minting(self) -> Optional[AgentState]:
"""Get next agent state for token minting."""
result = None
diff --git a/packages/fetchai/skills/tac_control/skill.yaml b/packages/fetchai/skills/tac_control/skill.yaml
index 365cd3f603..45fe2a38f5 100644
--- a/packages/fetchai/skills/tac_control/skill.yaml
+++ b/packages/fetchai/skills/tac_control/skill.yaml
@@ -9,9 +9,9 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmdWECpRXZXH5JPV6wVHqeUtvjBhieUFTEoT2e7EY16N8M
__init__.py: Qme9YfgfPXymvupw1EHMJWGUSMTT6JQZxk2qaeKE76pgyN
- behaviours.py: QmcznM3tsmEDNx9Vbhv48o3PNtBEz5W1MVQ7SxJFGkH7di
+ behaviours.py: QmPtGBEFGEdQCzeXC3ZkJuNTrSe217JupP1wtP8DMnm6cK
dialogues.py: QmcVYVTZ95UKBnXzmKyGLo5LwSVcGYUTrifosQMSpzNnCX
- game.py: QmaDGFufEofsvo62E8KGUfaAeyDrPc5Mxih3JjDFSEpkqU
+ game.py: QmU3jm1yqhtnW1XK9EGZAMx9iWeCiX8Cdvb55kQQKDXav1
handlers.py: QmSjwPKEN83C2gQS4WVH8uaHMv5ze7EJ9S8ugmRcKnSwnW
helpers.py: QmQXrtqV3h4oU5cDwWKhtNiTTAGLNZGhjoVnDvGj7mGwpe
parameters.py: QmefuFt5DPCBciu4z17UJWcXxtb4vwA879pNwh4DoMKPUm
diff --git a/packages/fetchai/skills/tac_control_contract/behaviours.py b/packages/fetchai/skills/tac_control_contract/behaviours.py
index 50671a53ad..5bf5178685 100644
--- a/packages/fetchai/skills/tac_control_contract/behaviours.py
+++ b/packages/fetchai/skills/tac_control_contract/behaviours.py
@@ -121,6 +121,7 @@ def act(self) -> None:
else:
game.phase = Phase.GAME_SETUP
game.create()
+ game.conf.contract_address = parameters.contract_address
self._unregister_tac()
elif (
game.phase.value == Phase.GAME_SETUP.value
@@ -182,6 +183,9 @@ def _request_mint_items_transaction(self, game: Game) -> None:
:return: None
"""
+ if not game.is_allowed_to_mint:
+ return
+ game.is_allowed_to_mint = False
agent_state = game.get_next_agent_state_for_minting()
if agent_state is None:
return
diff --git a/packages/fetchai/skills/tac_control_contract/handlers.py b/packages/fetchai/skills/tac_control_contract/handlers.py
index 87079deb32..2794aa4dec 100644
--- a/packages/fetchai/skills/tac_control_contract/handlers.py
+++ b/packages/fetchai/skills/tac_control_contract/handlers.py
@@ -436,6 +436,7 @@ def _handle_transaction_receipt(
):
self.context.logger.info("tokens minted.")
parameters.nb_completed_minting += 1
+ game.is_allowed_to_mint = True
if game.registration.nb_agents == parameters.nb_completed_minting:
game.phase = Phase.TOKENS_MINTED
self.context.logger.info("all tokens minted.")
diff --git a/packages/fetchai/skills/tac_control_contract/skill.yaml b/packages/fetchai/skills/tac_control_contract/skill.yaml
index 7dc2f629f5..7057bc6e20 100644
--- a/packages/fetchai/skills/tac_control_contract/skill.yaml
+++ b/packages/fetchai/skills/tac_control_contract/skill.yaml
@@ -9,10 +9,10 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmUiw6Dt97mXLzSizbnMNTsfLy3edGXKdYTNR5bke6sFsm
__init__.py: QmW9WBy1sNYVKpymGnpJY2pW5MEqGgVga2kBFUT9S34Yt5
- behaviours.py: QmUKPVxyvj3XbEX5CSJh3PBCX6HUvvkgzQ3TqHnLa1r3xh
+ behaviours.py: QmSfxtgDawQai52wzoYp58KHEVjXPsFiHQpyv4cYCcBo28
dialogues.py: QmWvhTeUnDimhQQTzuSfJJ6d2ViqgBNooCMfRiVzvzApw3
game.py: QmQwskD5DBVNv1ouRpqGNLb3zQ5krLUcR6XXHUcJ5EVc8L
- handlers.py: QmZse9uaY8XFzwLtiGM55if93Zx9PRCuZdSQSCYTRLyjq1
+ handlers.py: QmUevEFLkj94XQDPKqkWxRRRZJnY3XQBZFKXDK69xpwabB
helpers.py: QmX3iv37Z5CmGupCtikc4muTpJyQ9zvjeLbNKDLF7iPhSZ
parameters.py: QmVMNP52fPxkzEbXPhXtQXspnaj2f4ErZNcNdPAqv4cvwq
fingerprint_ignore_patterns: []
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 0cbad7258c..e11657a607 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -63,8 +63,8 @@ fetchai/skills/ml_data_provider,QmaKyLjyvcj35bCHaKKo15MeF7k48hKPCfFbrtvXCogYwV
fetchai/skills/ml_train,QmNoV8PRFQj7WEj9We6sEtX9G1Qb8qESoZ2QRK4MybVNoG
fetchai/skills/scaffold,QmRVUvLnRRPjgNDYw2gNZFY8MFBhGez1CfvY7z3N8yFMux
fetchai/skills/simple_service_registration,QmVTVvRoxKsP9N97TRGrj92bgPcEYhKYfYtohVuQ8BNzbr
-fetchai/skills/tac_control,QmVHPpD3mHoBq523jkkDyZcmwWwWYUJsPp11yCdweKEADy
-fetchai/skills/tac_control_contract,QmPC8HhVYcSJW8TubwqxT1RLK4rV4AVrLAEFuJe4gNkHVR
+fetchai/skills/tac_control,QmQqF4n4M1kYBHUFAUXsWoEdGZBDwvjwBDmtot5bzWtRMF
+fetchai/skills/tac_control_contract,QmQaYhgXfyZ3xP6USHWsVQ76hTQnuLxHUt2YGGXHEpUHqx
fetchai/skills/tac_negotiation,QmU6rghC95ESWaxM8gENDuRxuCXDgXQR3xkhrqFurQSEEo
fetchai/skills/tac_participation,QmdiCxur8qx2beRKz2HxGTF4GLzM6k7GEiecy67NvQ4iKt
fetchai/skills/thermometer,QmTud9hXxRq8wRzcf7hVeszou3crmAEZBaw5MjV8x4XtH1
From 3eb7cd9811e0d0d43e7d7261537d5bf805d81f89 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Fri, 25 Sep 2020 12:47:32 +0300
Subject: [PATCH 078/131] anget manager. start stop agents
---
aea/manager.py | 225 +++++++++++++++++++++++++++++++++++++++++-
tests/test_manager.py | 22 +++--
2 files changed, 236 insertions(+), 11 deletions(-)
diff --git a/aea/manager.py b/aea/manager.py
index 643543597f..de92bf7edb 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -17,10 +17,14 @@
#
# ------------------------------------------------------------------------------
"""This module contains the implementation of AEA agents manager."""
+import asyncio
import copy
import os
+import threading
+from asyncio.tasks import FIRST_COMPLETED
from shutil import rmtree
-from typing import Dict, List, Optional, Set
+from threading import Thread
+from typing import Callable, Dict, List, Optional, Set
from aea.aea import AEA
from aea.aea_builder import AEABuilder
@@ -70,12 +74,96 @@ def remove(self):
self.project.agents.remove(self.name)
+class AsyncTask:
+ """Async task wrapper for agent."""
+
+ def __init__(self, agent: AEA, loop: asyncio.AbstractEventLoop) -> None:
+ """Init task with agent and loop."""
+ self.run_loop: asyncio.AbstractEventLoop = loop
+ self.caller_loop: asyncio.AbstractEventLoop = loop
+ self._done_future: Optional[asyncio.Future] = None
+ self.task: Optional[asyncio.Task] = None
+ self.agent = agent
+
+ def create_run_loop(self) -> None:
+ """Create run loop."""
+ pass
+
+ def start(self) -> None:
+ """Start task."""
+ self.create_run_loop()
+ self.task = self.run_loop.create_task(self._run_wrapper())
+ self._done_future = asyncio.Future(loop=self.caller_loop)
+
+ def wait(self) -> asyncio.Future:
+ """Return future to wait task completed."""
+ if not self._done_future:
+ raise ValueError("Task not started!")
+ return self._done_future
+
+ def stop(self) -> None:
+ """Stop task."""
+ if not self.run_loop or not self.task:
+ raise ValueError("Task was not started!")
+ self.run_loop.call_soon_threadsafe(self.task.cancel)
+
+ async def _run_wrapper(self) -> None:
+ """Run task internals."""
+ if not self._done_future:
+ raise ValueError("Task was not started! please use start method")
+ try:
+ await self.run()
+ self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
+ except asyncio.CancelledError:
+ self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
+ except Exception as e:
+ self.caller_loop.call_soon_threadsafe(self._done_future.set_exception, e)
+
+ async def run(self) -> None:
+ """Run task body."""
+ self.agent.runtime.set_loop(self.run_loop)
+ try:
+ self.agent.runtime.start()
+ while True:
+ await asyncio.sleep(1)
+ finally:
+ self.agent.runtime.stop()
+
+ @property
+ def is_running(self) -> bool:
+ """Return is task running."""
+ return not self.wait().done()
+
+
+class ThreadedTask(AsyncTask):
+ """Threaded task."""
+
+ def __init__(self, agent: AEA, loop: asyncio.AbstractEventLoop) -> None:
+ """Init task with agent and loop."""
+ AsyncTask.__init__(self, agent, loop)
+ self._thread: Optional[Thread] = None
+
+ def create_run_loop(self) -> None:
+ """Create run loop."""
+ self.run_loop = asyncio.new_event_loop()
+
+ def start(self) -> None:
+ """Run task in a dedicated thread."""
+ super().start()
+ self._thread = threading.Thread(
+ target=self.run_loop.run_until_complete, args=[self.task], daemon=True
+ )
+ self._thread.start()
+
+
class Manager:
"""Abstract agents manager."""
AGENT_DO_NOT_OVERRIDE_VALUES = ["skills", "connections", "protocols", "contracts"]
+ MODES = ["async", "threaded"]
+ DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS = 60
- def __init__(self, working_dir: str) -> None:
+ def __init__(self, working_dir: str, mode: str = "async") -> None:
"""
Initialize manager.
@@ -83,15 +171,74 @@ def __init__(self, working_dir: str) -> None:
"""
self.working_dir = working_dir
self._was_working_dir_created = False
- self.is_started = False
+ self._is_running = False
self._projects: Dict[PublicId, Project] = {}
self._keys_dir = os.path.abspath(os.path.join(self.working_dir, "keys"))
self._agents: Dict[str, AgentAlias] = {}
+ self._agents_tasks: Dict[str, AsyncTask] = {}
+
+ self._thread = Thread(target=self._run_thread, daemon=True)
+ self._loop: Optional[asyncio.AbstractEventLoop] = None
+ self._event: Optional[asyncio.Event] = None
+
+ self._error_callbacks: List[Callable[[str, BaseException], None]] = []
+
+ if mode not in self.MODES:
+ raise ValueError(
+ f'Invalid mode {mode}. Valid modes are {", ".join(self.MODES)}'
+ )
+ self._started_event = threading.Event()
+ self._mode = mode
+
+ @property
+ def is_running(self) -> bool:
+ """Is manager running."""
+ return self._is_running
+
+ def _run_thread(self) -> None:
+ """Run internal thread with own event loop."""
+ self._loop = asyncio.new_event_loop()
+ self._event = asyncio.Event(loop=self._loop)
+ self._loop.run_until_complete(self._manager_loop())
+
+ async def _manager_loop(self) -> None:
+ """Perform manager stop."""
+ if not self._event:
+ raise ValueError("Do not use this method directly, use start_manager.")
+
+ self._started_event.set()
+
+ while self._is_running:
+ tasks_for_agents = {
+ task.wait(): agent_name
+ for agent_name, task in self._agents_tasks.items()
+ }
+ wait_tasks = list(tasks_for_agents.keys()) + [self._event.wait()] # type: ignore
+ done, _ = await asyncio.wait(wait_tasks, return_when=FIRST_COMPLETED)
+
+ if self._event.is_set():
+ self._event.clear()
+
+ for task in done:
+ if task not in tasks_for_agents:
+ await task
+ continue
+ agent_name = tasks_for_agents[task]
+ self._agents_tasks.pop(agent_name)
+ if task.exception():
+ print(agent_name, "exceptioned", task.exception())
+ for callback in self._error_callbacks:
+ callback(agent_name, task.exception())
+ else:
+ await task
def start_manager(self) -> None:
"""Start manager."""
self._ensure_working_dir()
- self.is_started = True
+ self._started_event.clear()
+ self._is_running = True
+ self._thread.start()
+ self._started_event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
def stop_manager(self, cleanup: bool = False) -> None:
"""
@@ -103,10 +250,16 @@ def stop_manager(self, cleanup: bool = False) -> None:
:return: None
"""
+ if not self._loop or not self._event:
+ raise ValueError("Manager was not started!")
if self._was_working_dir_created:
rmtree(self.working_dir)
- self.is_started = False
+ if self._thread.is_alive():
+ self.stop_all_agents()
+ self._is_running = False
+ self._loop.call_soon_threadsafe(self._event.set)
+ self._thread.join(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
def add_project(self, public_id: PublicId) -> None:
"""Fetch agent project and all dependencies to working_dir."""
@@ -119,6 +272,11 @@ def remove_project(self, public_id: PublicId) -> None:
if public_id not in self._projects:
raise ValueError(f"Project {public_id} was not added!")
+ if self._projects[public_id].agents:
+ raise ValueError(
+ f"Can not remove projects with aliases exists: {self._projects[public_id].agents}"
+ )
+
self._projects.pop(public_id).remove()
def list_projects(self) -> List[PublicId]:
@@ -171,6 +329,8 @@ def list_agents(self, running_only: bool = False) -> List[str]:
:return: list of agents names
"""
+ if running_only:
+ return list(self._agents_tasks.keys())
return list(self._agents.keys())
def remove_agent(self, agent_name: str) -> None:
@@ -184,6 +344,9 @@ def remove_agent(self, agent_name: str) -> None:
if agent_name not in self._agents:
raise ValueError(f"Agent with name {agent_name} does not exist!")
+ if self._is_agent_running(agent_name):
+ raise ValueError("Agent is running. stop it first!")
+
agent_alias = self._agents.pop(agent_name)
agent_alias.remove()
@@ -195,6 +358,33 @@ def start_agent(self, agent_name: str) -> None:
:return: None
"""
+ if not self._loop or not self._event:
+ raise ValueError("agent is not started!")
+
+ agent_alias = self._agents.get(agent_name)
+ if not agent_alias:
+ raise ValueError(f"{agent_name} is not registered!")
+ if self._is_agent_running(agent_name):
+ raise ValueError(f"{agent_name} is already started!")
+
+ if self._mode == "async":
+ task = AsyncTask(agent_alias.agent, self._loop)
+ elif self._mode == "threaded":
+ task = ThreadedTask(agent_alias.agent, self._loop)
+
+ task.start()
+ self._agents_tasks[agent_name] = task
+ self._loop.call_soon_threadsafe(self._event.set)
+
+ def _is_agent_running(self, agent_name):
+ if agent_name not in self._agents_tasks:
+ return False
+
+ task = self._agents_tasks[agent_name]
+ if task.is_running:
+ return True
+ del self._agents_tasks[agent_name]
+ return False
def start_all_agents(self) -> None:
"""
@@ -202,6 +392,10 @@ def start_all_agents(self) -> None:
:return: None
"""
+ for agent_name in self.list_agents():
+ if self._is_agent_running(agent_name):
+ continue
+ self.start_agent(agent_name)
def stop_agent(self, agent_name: str) -> None:
"""
@@ -211,6 +405,16 @@ def stop_agent(self, agent_name: str) -> None:
:return: None
"""
+ if not self._is_agent_running(agent_name):
+ raise ValueError(f"{agent_name} is not running!")
+ if self._thread.ident == threading.get_ident():
+ # In same thread do not perform blocking operations!
+ self._agents_tasks[agent_name].stop()
+ return
+ event = threading.Event()
+ self._agents_tasks[agent_name].wait().add_done_callback(lambda x: event.set())
+ self._agents_tasks[agent_name].stop()
+ event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
def stop_all_agents(self) -> None:
"""
@@ -218,6 +422,8 @@ def stop_all_agents(self) -> None:
:return: None
"""
+ for agent_name in self.list_agents(running_only=True):
+ self.stop_agent(agent_name)
def stop_agents(self, agent_names: List[str]) -> None:
"""
@@ -225,6 +431,12 @@ def stop_agents(self, agent_names: List[str]) -> None:
:return: None
"""
+ for agent_name in agent_names:
+ if not self._is_agent_running(agent_name):
+ raise ValueError(f"{agent_name} is not running!")
+
+ for agent_name in agent_names:
+ self.stop_agent(agent_name)
def start_agents(self, agent_names: List[str]) -> None:
"""
@@ -232,6 +444,8 @@ def start_agents(self, agent_names: List[str]) -> None:
:return: None
"""
+ for agent_name in agent_names:
+ self.start_agent(agent_name)
def get_agent_details(self, agent_name: str) -> AgentAlias:
"""
@@ -267,6 +481,7 @@ def _build_agent_alias(
builder = AEABuilder.from_config_json(json_config, project.path)
builder.set_name(agent_name)
+ # builder.set_runtime_mode("async")
if not builder.private_key_paths:
default_ledger = json_config[0].get("default_ledger", DEFAULT_LEDGER)
diff --git a/tests/test_manager.py b/tests/test_manager.py
index e5a4c6af57..170ea6b96e 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -18,9 +18,9 @@
# ------------------------------------------------------------------------------
"""This module contains tests for aea manager."""
import os
+import time
from contextlib import suppress
from shutil import rmtree
-from typing import Dict, List, Optional, Set
import pytest
@@ -30,7 +30,7 @@
def test_manager():
"""Perform some tests."""
-
+ # pydocsyle
try:
working_dir = "manager_dir"
project_public_id = PublicId("fetchai", "my_first_aea", "0.11.0")
@@ -41,7 +41,7 @@ def test_manager():
manager = Manager(working_dir)
manager.start_manager()
assert os.path.exists(working_dir)
- assert manager.is_started
+ assert manager.is_running
manager.add_project(project_public_id)
@@ -84,13 +84,24 @@ def test_manager():
project_public_id, agent_name,
)
assert agent_name in manager.list_agents()
+ manager.start_all_agents()
+ assert agent_name in manager.list_agents(running_only=True)
+ manager.start_all_agents()
+
+ with pytest.raises(ValueError, match="is already started!"):
+ manager.start_agents(manager.list_agents())
+
+ with pytest.raises(ValueError, match="Agent is running. stop it first!"):
+ manager.remove_agent(agent_name)
+
+ time.sleep(2)
+ manager.stop_all_agents()
manager.remove_agent(agent_name)
assert agent_name not in manager.list_agents()
with pytest.raises(ValueError, match="does not exist!"):
manager.remove_agent(agent_name)
-
manager.remove_project(project_public_id)
assert project_public_id not in manager._projects
assert not os.path.exists(project_path)
@@ -98,10 +109,9 @@ def test_manager():
with pytest.raises(ValueError, match=r"was not added"):
manager.remove_project(project_public_id)
-
manager.stop_manager()
assert not os.path.exists(working_dir)
- assert not manager.is_started
+ assert not manager.is_running
finally:
with suppress(FileNotFoundError):
rmtree(working_dir)
From 90ac861f61d2fb600e54e8c59088de42fe123d38 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 25 Sep 2020 11:59:48 +0100
Subject: [PATCH 079/131] add test for tac_control_contract
---
aea/test_tools/test_cases.py | 4 +-
.../tac_participant_contract/aea-config.yaml | 9 +-
packages/hashes.csv | 2 +-
tests/test_packages/test_skills/test_tac.py | 203 +++++++++++++-----
4 files changed, 159 insertions(+), 59 deletions(-)
diff --git a/aea/test_tools/test_cases.py b/aea/test_tools/test_cases.py
index d058f4d1f9..ac19fa1dee 100644
--- a/aea/test_tools/test_cases.py
+++ b/aea/test_tools/test_cases.py
@@ -269,11 +269,11 @@ def is_allowed_diff_in_agent_config(
with open(
os.path.join(path_to_fetched_aea, "aea-config.yaml"), "r"
) as file:
- content1 = yaml.full_load(file)
+ content1 = list(yaml.safe_load_all(file))[0] # only load first page
with open(
os.path.join(path_to_manually_created_aea, "aea-config.yaml"), "r"
) as file:
- content2 = yaml.full_load(file)
+ content2 = list(yaml.safe_load_all(file))[0]
content1c = copy.deepcopy(content1)
for key, value in content1c.items():
if content2[key] == value:
diff --git a/packages/fetchai/agents/tac_participant_contract/aea-config.yaml b/packages/fetchai/agents/tac_participant_contract/aea-config.yaml
index cde745ed9b..32726f5f0d 100644
--- a/packages/fetchai/agents/tac_participant_contract/aea-config.yaml
+++ b/packages/fetchai/agents/tac_participant_contract/aea-config.yaml
@@ -1,7 +1,8 @@
-agent_name: tac_participant
+agent_name: tac_participant_contract
author: fetchai
-version: 0.11.0
-description: An AEA to participate in the TAC (trading agent competition)
+version: 0.1.0
+description: An AEA to participate in the TAC (trading agent competition) using an
+ ERC1155 smart contract.
license: Apache-2.0
aea_version: '>=0.6.0, <0.7.0'
fingerprint: {}
@@ -23,7 +24,7 @@ skills:
- fetchai/tac_negotiation:0.10.0
- fetchai/tac_participation:0.9.0
default_connection: fetchai/p2p_libp2p:0.10.0
-default_ledger: fetchai
+default_ledger: ethereum
logging_config:
disable_existing_loggers: false
version: 1
diff --git a/packages/hashes.csv b/packages/hashes.csv
index e11657a607..8826c1bb2b 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -14,7 +14,7 @@ fetchai/agents/simple_service_registration,QmY4oz8n2zjJnAa3vHRRDuzpZi8Taf8qsScX7
fetchai/agents/tac_controller,QmWVvJemSdE5N5iyMuDt5ZHh1FA32oijHxBqq91zaNkdY3
fetchai/agents/tac_controller_contract,QmSZRM9QqFpZDosBuY1gCgX4Ho8icAMAnyh6VMti6UdwVE
fetchai/agents/tac_participant,QmRmswKxJ9mdQe6zFRqxr9U1ZpYTybQf3DKsrAySt39aVc
-fetchai/agents/tac_participant_contract,QmaZQ17y4Lm8MNVpDP9kUm31z5HpLDrGWW8yy3FWPwcFN4
+fetchai/agents/tac_participant_contract,QmVuA9fJAM2jrJH6PCfcq12mgp6999LFCktwkLNjhHhsLz
fetchai/agents/thermometer_aea,QmT1GNUCcB6xqnmB1vv3jTs4HqeYM6tLnnL4TSjv5raHpk
fetchai/agents/thermometer_client,QmdWMJCb7Pkz8F3emJ8wKhNWpnEUXHpBFQTGcmJyziu6kH
fetchai/agents/weather_client,Qmd5iiwyqEuw7Fg8NkdLsNjkuZQRatNRADpXVXwG13BvtP
diff --git a/tests/test_packages/test_skills/test_tac.py b/tests/test_packages/test_skills/test_tac.py
index 88a8c90156..c5c4f3bcfd 100644
--- a/tests/test_packages/test_skills/test_tac.py
+++ b/tests/test_packages/test_skills/test_tac.py
@@ -260,25 +260,34 @@ def test_tac(self):
class TestTacSkillsContract(AEATestCaseMany):
"""Test that tac skills work."""
- @pytest.mark.unstable
@pytest.mark.flaky(reruns=MAX_FLAKY_RERUNS_ETH) # cause possible network issues
def test_tac(self):
"""Run the tac skills sequence."""
tac_aea_one = "tac_participant_one"
tac_aea_two = "tac_participant_two"
- tac_controller_name = "tac_controller"
+ tac_controller_name = "tac_controller_contract"
# create tac controller, agent one and agent two
self.create_agents(
tac_aea_one, tac_aea_two, tac_controller_name,
)
+ default_routing = {
+ "fetchai/contract_api:0.5.0": "fetchai/ledger:0.6.0",
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
+ }
+
# prepare tac controller for test
self.set_agent_context(tac_controller_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
+ self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/tac_control_contract:0.9.0")
self.set_config("agent.default_ledger", ETHEREUM)
+ setting_path = "agent.default_routing"
+ self.force_set_config(setting_path, default_routing)
self.run_install()
diff = self.difference_to_fetched_agent(
@@ -288,23 +297,46 @@ def test_tac(self):
diff == []
), "Difference between created and fetched project for files={}".format(diff)
+ # add keys
self.generate_private_key(ETHEREUM)
+ self.generate_private_key(COSMOS, COSMOS_PRIVATE_KEY_FILE_CONNECTION)
self.add_private_key(ETHEREUM, ETHEREUM_PRIVATE_KEY_FILE)
+ self.add_private_key(
+ COSMOS, COSMOS_PRIVATE_KEY_FILE_CONNECTION, connection=True
+ )
self.replace_private_key_in_file(
FUNDED_ETH_PRIVATE_KEY_1, ETHEREUM_PRIVATE_KEY_FILE
)
+ self.replace_private_key_in_file(
+ NON_FUNDED_COSMOS_PRIVATE_KEY_1, COSMOS_PRIVATE_KEY_FILE_CONNECTION
+ )
+ setting_path = "vendor.fetchai.connections.p2p_libp2p.config.ledger_id"
+ self.force_set_config(setting_path, COSMOS)
+ setting_path = "vendor.fetchai.connections.soef.config.chain_identifier"
+ self.force_set_config(setting_path, ETHEREUM)
+ setting_path = "vendor.fetchai.skills.tac_control.is_abstract"
+ self.force_set_config(setting_path, True)
+
+ default_routing = {
+ "fetchai/ledger_api:0.4.0": "fetchai/ledger:0.6.0",
+ "fetchai/oef_search:0.7.0": "fetchai/soef:0.9.0",
+ }
# prepare agents for test
- for agent_name, eth_private_key in zip(
- (tac_aea_one, tac_aea_two),
- (FUNDED_ETH_PRIVATE_KEY_2, FUNDED_ETH_PRIVATE_KEY_3),
+ for agent_name, config, private_key in (
+ (tac_aea_one, NON_GENESIS_CONFIG, FUNDED_ETH_PRIVATE_KEY_2),
+ (tac_aea_two, NON_GENESIS_CONFIG_TWO, FUNDED_ETH_PRIVATE_KEY_3),
):
self.set_agent_context(agent_name)
self.add_item("connection", "fetchai/p2p_libp2p:0.10.0")
self.set_config("agent.default_connection", "fetchai/p2p_libp2p:0.10.0")
+ self.add_item("connection", "fetchai/soef:0.9.0")
+ self.add_item("connection", "fetchai/ledger:0.6.0")
self.add_item("skill", "fetchai/tac_participation:0.9.0")
self.add_item("skill", "fetchai/tac_negotiation:0.10.0")
self.set_config("agent.default_ledger", ETHEREUM)
+ setting_path = "agent.default_routing"
+ self.force_set_config(setting_path, default_routing)
self.set_config(
"vendor.fetchai.skills.tac_participation.models.game.args.is_using_contract",
True,
@@ -317,34 +349,59 @@ def test_tac(self):
)
self.run_install()
diff = self.difference_to_fetched_agent(
- "fetchai/tac_participant:0.11.0", agent_name
+ "fetchai/tac_participant_contract:0.1.0", agent_name
)
assert (
diff == []
), "Difference between created and fetched project for files={}".format(
diff
)
+
+ # add keys
self.generate_private_key(ETHEREUM)
+ self.generate_private_key(COSMOS, COSMOS_PRIVATE_KEY_FILE_CONNECTION)
self.add_private_key(ETHEREUM, ETHEREUM_PRIVATE_KEY_FILE)
- self.replace_private_key_in_file(eth_private_key, ETHEREUM_PRIVATE_KEY_FILE)
+ self.add_private_key(
+ COSMOS, COSMOS_PRIVATE_KEY_FILE_CONNECTION, connection=True
+ )
+ self.replace_private_key_in_file(private_key, ETHEREUM_PRIVATE_KEY_FILE)
+
+ # set p2p configs
+ setting_path = "vendor.fetchai.connections.p2p_libp2p.config"
+ self.force_set_config(setting_path, config)
+ setting_path = "vendor.fetchai.connections.p2p_libp2p.config.ledger_id"
+ self.force_set_config(setting_path, COSMOS)
# run tac controller
self.set_agent_context(tac_controller_name)
now = datetime.datetime.now().strftime("%d %m %Y %H:%M")
now_min = datetime.datetime.strptime(now, "%d %m %Y %H:%M")
- fut = now_min + datetime.timedelta(0, 360)
+ fut = now_min + datetime.timedelta(
+ 0, 180
+ ) # we provide 3 minutes time for contract deployment
start_time = fut.strftime("%d %m %Y %H:%M")
- setting_path = "vendor.fetchai.skills.tac_control_contract.models.parameters.args.start_time"
+ setting_path = "vendor.fetchai.skills.tac_control_contract.models.parameters.args.registration_start_time"
self.set_config(setting_path, start_time)
- tac_controller_process = self.run_agent(
- "--connections", "fetchai/p2p_libp2p:0.10.0"
- )
+ tac_controller_process = self.run_agent()
check_strings = (
- "Sending deploy transaction to decision maker.",
- "Sending deployment transaction to the ledger...",
- "The contract was successfully deployed. Contract address:",
- "Registering TAC data model",
+ "Downloading golang dependencies. This may take a while...",
+ "Finished downloading golang dependencies.",
+ "Starting libp2p node...",
+ "Connecting to libp2p node...",
+ "Successfully connected to libp2p node!",
+ "My libp2p addresses:",
+ "registering agent on SOEF.",
+ "requesting contract deployment transaction...",
+ "Start processing messages...",
+ "received raw transaction=",
+ "transaction signing was successful.",
+ "sending transaction to ledger.",
+ "transaction was successfully submitted. Transaction digest=",
+ "requesting transaction receipt.",
+ "transaction was successfully settled. Transaction receipt=",
+ "contract deployed.",
+ "registering TAC data model on SOEF.",
"TAC open for registration until:",
)
missing_strings = self.missing_from_output(
@@ -354,65 +411,107 @@ def test_tac(self):
missing_strings == []
), "Strings {} didn't appear in tac_controller output.".format(missing_strings)
- # run two participants as well
+ # run two agents (participants)
self.set_agent_context(tac_aea_one)
- tac_aea_one_process = self.run_agent(
- "--connections", "fetchai/p2p_libp2p:0.10.0"
- )
+ tac_aea_one_process = self.run_agent()
self.set_agent_context(tac_aea_two)
- tac_aea_two_process = self.run_agent(
- "--connections", "fetchai/p2p_libp2p:0.10.0"
+ tac_aea_two_process = self.run_agent()
+
+ check_strings = (
+ "Downloading golang dependencies. This may take a while...",
+ "Finished downloading golang dependencies.",
+ "Starting libp2p node...",
+ "Connecting to libp2p node...",
+ "Successfully connected to libp2p node!",
+ "My libp2p addresses:",
+ "Start processing messages...",
+ "searching for TAC, search_id=",
+ "found the TAC controller. Registering...",
)
+ missing_strings = self.missing_from_output(
+ tac_aea_one_process, check_strings, timeout=240, is_terminating=False
+ )
+ assert (
+ missing_strings == []
+ ), "Strings {} didn't appear in tac_aea_one output.".format(missing_strings)
check_strings = (
- "Agent registered:",
- "Closing registration!",
- "Setting Up the TAC game.",
- "Unregistering TAC data model",
- "Registering TAC data model",
- "Sending create_items transaction to decision maker.",
- "Sending creation transaction to the ledger..",
- "Successfully created the tokens. Transaction hash:",
- "Sending mint_items transactions to decision maker.",
- "Sending minting transaction to the ledger...",
- "Successfully minted the tokens for agent_addr=",
- "All tokens minted!",
- "Starting competition with configuration:",
- "Current good & money allocation & score:",
+ "Downloading golang dependencies. This may take a while...",
+ "Finished downloading golang dependencies.",
+ "Starting libp2p node...",
+ "Connecting to libp2p node...",
+ "Successfully connected to libp2p node!",
+ "My libp2p addresses:",
+ "Start processing messages...",
+ "searching for TAC, search_id=",
+ "found the TAC controller. Registering...",
)
missing_strings = self.missing_from_output(
- tac_controller_process, check_strings, timeout=300, is_terminating=False
+ tac_aea_two_process, check_strings, timeout=240, is_terminating=False
+ )
+ assert (
+ missing_strings == []
+ ), "Strings {} didn't appear in tac_aea_two output.".format(missing_strings)
+
+ check_strings = (
+ "agent registered:",
+ "closing registration!",
+ "unregistering TAC data model from SOEF.",
+ "requesting create items transaction...",
+ "received raw transaction=",
+ "proposing the transaction to the decision maker. Waiting for confirmation ...",
+ "transaction signing was successful.",
+ "transaction was successfully submitted. Transaction digest=",
+ "requesting transaction receipt.",
+ "transaction was successfully settled. Transaction receipt=",
+ "tokens created.",
+ "requesting mint_items transactions for agent=",
+ "tokens minted.",
+ "requesting mint_items transactions for agent=",
+ "tokens minted.",
+ "all tokens minted.",
+ "started competition:",
+ )
+ missing_strings = self.missing_from_output(
+ tac_controller_process, check_strings, timeout=240, is_terminating=False
)
assert (
missing_strings == []
), "Strings {} didn't appear in tac_controller output.".format(missing_strings)
check_strings = (
- "Searching for TAC, search_id=",
- "Found the TAC controller. Registering...",
- "Received start event from the controller. Starting to compete...",
- "Searching for sellers which match the demand of the agent, search_id=",
- "Searching for buyers which match the supply of the agent, search_id=",
+ "received start event from the controller. Starting to compete..."
+ "received a contract address:",
+ "registering agent on SOEF.",
+ "searching for sellers, search_id=",
+ "searching for buyers, search_id=",
"found potential sellers agents=",
"sending CFP to agent=",
- "Accepting propose",
- "sending match accept to",
- "sending atomic swap tx to ledger.",
- "tx_digest=",
- "waiting for tx to confirm. Sleeping for 3 seconds ...",
- "Successfully conducted atomic swap. Transaction digest:",
- "found potential buyers agents=",
- "sending CFP to agent=",
- "Declining propose",
)
missing_strings = self.missing_from_output(
- tac_aea_one_process, check_strings, timeout=360, is_terminating=False
+ tac_aea_one_process, check_strings, timeout=300, is_terminating=False
)
assert (
missing_strings == []
), "Strings {} didn't appear in tac_aea_one output.".format(missing_strings)
+ check_strings = (
+ "received start event from the controller. Starting to compete..."
+ "received a contract address:",
+ "registering agent on SOEF.",
+ "searching for sellers, search_id=",
+ "searching for buyers, search_id=",
+ "found potential sellers agents=",
+ "sending CFP to agent=",
+ )
+ missing_strings = self.missing_from_output(
+ tac_aea_two_process, check_strings, timeout=360, is_terminating=False
+ )
+ assert (
+ missing_strings == []
+ ), "Strings {} didn't appear in tac_aea_two output.".format(missing_strings)
+
# Note, we do not need to check std output of the other participant as it is implied
self.terminate_agents(
From 50c581b0e81aa4a0aa01c920c88794b82f35b201 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 25 Sep 2020 13:20:04 +0100
Subject: [PATCH 080/131] fix tac test marks
---
tests/test_packages/test_skills/test_tac.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tests/test_packages/test_skills/test_tac.py b/tests/test_packages/test_skills/test_tac.py
index c5c4f3bcfd..251bf42dca 100644
--- a/tests/test_packages/test_skills/test_tac.py
+++ b/tests/test_packages/test_skills/test_tac.py
@@ -256,10 +256,11 @@ def test_tac(self):
), "Agents weren't successfully terminated."
-@pytest.mark.ledger
class TestTacSkillsContract(AEATestCaseMany):
"""Test that tac skills work."""
+ @pytest.mark.integration
+ @pytest.mark.ledger
@pytest.mark.flaky(reruns=MAX_FLAKY_RERUNS_ETH) # cause possible network issues
def test_tac(self):
"""Run the tac skills sequence."""
@@ -371,6 +372,8 @@ def test_tac(self):
self.force_set_config(setting_path, config)
setting_path = "vendor.fetchai.connections.p2p_libp2p.config.ledger_id"
self.force_set_config(setting_path, COSMOS)
+ setting_path = "vendor.fetchai.connections.soef.config.chain_identifier"
+ self.force_set_config(setting_path, ETHEREUM)
# run tac controller
self.set_agent_context(tac_controller_name)
From f2e7a4e9acd90f84419e093d7309b57d4a8fe253 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 25 Sep 2020 18:10:37 +0100
Subject: [PATCH 081/131] add video from cvc to docs
---
docs/oef-ledger.md | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/docs/oef-ledger.md b/docs/oef-ledger.md
index 7b73b5202d..9575ac8e42 100644
--- a/docs/oef-ledger.md
+++ b/docs/oef-ledger.md
@@ -96,4 +96,10 @@ The Python version of the AEA Framework currently integrates with three ledgers:
- Ethereum ledger
- Cosmos ledger
-However, the framework makes it straightforward for further ledgers to be added by any developer.
\ No newline at end of file
+However, the framework makes it straightforward for further ledgers to be added by any developer.
+
+### AEAs as second layer technology
+
+The following presentation discusses how AEAs can be seen as second layer technology to ledgers.
+
+
From 42b89a029c974017e971f240deca315fcacb1be9 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Fri, 28 Aug 2020 11:52:48 +0300
Subject: [PATCH 082/131] runtime and agent loop async interface
---
aea/aea.py | 12 +-
aea/agent.py | 4 +-
aea/agent_loop.py | 95 +++++----
aea/helpers/async_utils.py | 190 ++++++++++++++++--
aea/helpers/multiple_executor.py | 3 -
aea/launcher.py | 2 +-
aea/multiplexer.py | 73 ++++---
aea/runner.py | 4 +-
aea/runtime.py | 254 ++++++++-----------------
tests/test_aea.py | 28 +--
tests/test_agent.py | 8 +-
tests/test_agent_loop.py | 102 +++++-----
tests/test_helpers/test_async_utils.py | 153 +++++++++++++--
tests/test_launcher.py | 1 -
tests/test_runtime.py | 50 ++---
tests/test_skills/test_error.py | 1 +
16 files changed, 590 insertions(+), 390 deletions(-)
diff --git a/aea/aea.py b/aea/aea.py
index 89a5022189..63086fdd02 100644
--- a/aea/aea.py
+++ b/aea/aea.py
@@ -55,6 +55,7 @@
from aea.protocols.default.message import DefaultMessage
from aea.registries.filter import Filter
from aea.registries.resources import Resources
+from aea.runtime import StopRuntime
from aea.skills.base import Behaviour, Handler
from aea.skills.error.handlers import ErrorHandler
@@ -241,8 +242,8 @@ def _get_msg_and_handlers_for_envelope(
if error_handler is None:
self.logger.warning("ErrorHandler not initialized. Stopping AEA!")
- self.stop()
- return None, []
+ raise StopRuntime()
+
error_handler = cast(ErrorHandler, error_handler)
if protocol is None:
@@ -363,9 +364,10 @@ def log_exception(e, fn):
if self._skills_exception_policy == ExceptionPolicyEnum.stop_and_exit:
log_exception(exception, function)
- self.stop()
- raise AEAException(
- f"AEA was terminated cause exception `{exception}` in skills {function}! Please check logs."
+ raise StopRuntime(
+ AEAException(
+ f"AEA was terminated cause exception `{exception}` in skills {function}! Please check logs."
+ )
)
if self._skills_exception_policy == ExceptionPolicyEnum.just_log:
diff --git a/aea/agent.py b/aea/agent.py
index b62acaadf6..70cd8fdc47 100644
--- a/aea/agent.py
+++ b/aea/agent.py
@@ -191,7 +191,8 @@ def start(self) -> None:
:return: None
"""
- self.runtime.start()
+ if self.runtime.start():
+ self.runtime.wait(sync=True)
def stop(self) -> None:
"""
@@ -206,6 +207,7 @@ def stop(self) -> None:
:return: None
"""
self.runtime.stop()
+ self.runtime.wait(sync=True)
@property
def state(self) -> RuntimeStates:
diff --git a/aea/agent_loop.py b/aea/agent_loop.py
index 59fff7c62d..40196f37a6 100644
--- a/aea/agent_loop.py
+++ b/aea/agent_loop.py
@@ -16,6 +16,8 @@
# limitations under the License.
#
# ------------------------------------------------------------------------------
+
+
"""This module contains the implementation of an agent loop using asyncio."""
import asyncio
import datetime
@@ -24,6 +26,7 @@
from asyncio import CancelledError
from asyncio.events import AbstractEventLoop
from asyncio.tasks import Task
+from contextlib import suppress
from enum import Enum
from functools import partial
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple
@@ -34,7 +37,7 @@
AsyncState,
HandlerItemGetter,
PeriodicCaller,
- ensure_loop,
+ Runnable,
)
from aea.helpers.exec_timeout import ExecTimeoutThreadGuard, TimeoutException
from aea.helpers.logging import WithLogger
@@ -43,11 +46,28 @@
logger = logging.getLogger(__name__)
-class BaseAgentLoop(WithLogger, ABC):
+class AgentLoopException(AEAException):
+ """Exception for agent loop runtime errors."""
+
+
+class AgentLoopStates(Enum):
+ """Internal agent loop states."""
+
+ initial = None
+ started = "started"
+ stopped = "stopped"
+ stopping = "stopping"
+ error = "error"
+
+
+class BaseAgentLoop(Runnable, WithLogger, ABC):
"""Base abstract agent loop class."""
def __init__(
- self, agent: AbstractAgent, loop: Optional[AbstractEventLoop] = None
+ self,
+ agent: AbstractAgent,
+ loop: Optional[AbstractEventLoop] = None,
+ threaded=False,
) -> None:
"""Init loop.
@@ -55,8 +75,9 @@ def __init__(
:params loop: optional asyncio event loop. if not specified a new loop will be created.
"""
WithLogger.__init__(self, logger)
+ Runnable.__init__(self, loop=loop, threaded=threaded)
+
self._agent: AbstractAgent = agent
- self.set_loop(ensure_loop(loop))
self._tasks: List[asyncio.Task] = []
self._state: AsyncState = AsyncState()
self._exceptions: List[Exception] = []
@@ -70,11 +91,6 @@ def set_loop(self, loop: AbstractEventLoop) -> None:
"""Set event loop and all event loopp related objects."""
self._loop: AbstractEventLoop = loop
- def start(self) -> None:
- """Start agent loop synchronously in own asyncio loop."""
- self.setup()
- self._loop.run_until_complete(self.run_loop())
-
def setup(self) -> None: # pylint: disable=no-self-use
"""Set up loop before started."""
# start and stop methods are classmethods cause one instance shared across muiltiple threads
@@ -85,16 +101,23 @@ def teardown(self): # pylint: disable=no-self-use
# start and stop methods are classmethods cause one instance shared across muiltiple threads
ExecTimeoutThreadGuard.stop()
- async def run_loop(self) -> None:
+ async def run(self) -> None:
"""Run agent loop."""
self.logger.debug("agent loop started")
+ self.setup()
self._set_tasks()
try:
await self._gather_tasks()
except (CancelledError, KeyboardInterrupt):
- await self.wait_run_loop_stopped()
- logger.debug("agent loop stopped")
- self._state.set(AgentLoopStates.stopped)
+ pass
+ finally:
+ self.teardown()
+ self._stop_tasks()
+ for t in self._tasks:
+ with suppress(BaseException):
+ await t
+ self._state.set(AgentLoopStates.stopped)
+ logger.debug("agent loop stopped")
async def _gather_tasks(self) -> None:
"""Wait till first task exception."""
@@ -105,27 +128,6 @@ def _set_tasks(self) -> None: # pragma: nocover
"""Set run loop tasks."""
raise NotImplementedError
- async def wait_run_loop_stopped(self) -> None:
- """Wait all tasks stopped."""
- return await asyncio.gather(
- *self._tasks, loop=self._loop, return_exceptions=True
- )
-
- def stop(self) -> None:
- """Stop agent loop."""
- self.teardown()
- self._state.set(AgentLoopStates.stopping)
- logger.debug("agent loop stopping!")
- if self._loop.is_running():
- self._loop.call_soon_threadsafe(self._stop_tasks)
- else:
-
- async def stop():
- self._stop_tasks()
- await self.wait_run_loop_stopped()
-
- self._loop.run_until_complete(stop())
-
def _stop_tasks(self) -> None:
"""Cancel all tasks."""
for task in self._tasks:
@@ -133,39 +135,32 @@ def _stop_tasks(self) -> None:
continue # Â pragma: nocover
task.cancel()
+ @property
+ def state(self) -> AgentLoopStates:
+ """Get current main loop state."""
+ return self._state.get()
+
@property
def is_running(self) -> bool:
"""Get running state of the loop."""
return self._state.get() == AgentLoopStates.started
-class AgentLoopException(AEAException):
- """Exception for agent loop runtime errors."""
-
-
-class AgentLoopStates(Enum):
- """Internal agent loop states."""
-
- initial = None
- started = "started"
- stopped = "stopped"
- stopping = "stopping"
- error = "error"
-
-
class AsyncAgentLoop(BaseAgentLoop):
"""Asyncio based agent loop suitable only for AEA."""
NEW_BEHAVIOURS_PROCESS_SLEEP = 1 # check new behaviours registered every second.
- def __init__(self, agent: AbstractAgent, loop: AbstractEventLoop = None):
+ def __init__(
+ self, agent: AbstractAgent, loop: AbstractEventLoop = None, threaded=False
+ ):
"""
Init agent loop.
:param agent: AEA instance
:param loop: asyncio loop to use. optional
"""
- super().__init__(agent=agent, loop=loop)
+ super().__init__(agent=agent, loop=loop, threaded=threaded)
self._agent: AbstractAgent = self._agent
self._periodic_tasks: Dict[Callable, PeriodicCaller] = {}
diff --git a/aea/helpers/async_utils.py b/aea/helpers/async_utils.py
index 0723a00b58..64155f510b 100644
--- a/aea/helpers/async_utils.py
+++ b/aea/helpers/async_utils.py
@@ -23,6 +23,7 @@
import logging
import subprocess # nosec
import time
+from abc import ABC, abstractmethod
from asyncio import CancelledError
from asyncio.events import AbstractEventLoop, TimerHandle
from asyncio.futures import Future
@@ -259,27 +260,6 @@ def stop(self) -> None:
self._timerhandle = None
-def ensure_loop(loop: Optional[AbstractEventLoop] = None) -> AbstractEventLoop:
- """
- Use loop provided or create new if not provided or closed.
-
- Return loop passed if its provided,not closed and not running, otherwise returns new event loop.
-
- :param loop: optional event loop
- :return: asyncio event loop
- """
- try:
- loop = loop or asyncio.new_event_loop()
- if loop.is_closed():
- raise ValueError("Event loop closed.") # pragma: nocover
- if loop.is_running():
- raise ValueError("Event loop running.")
- except (RuntimeError, ValueError):
- loop = asyncio.new_event_loop()
-
- return loop
-
-
class AnotherThreadTask:
"""
Schedule a task to run on the loop in another thread.
@@ -477,3 +457,171 @@ def __init__(self, getters: List[Tuple[Callable[[Any], None], Callable]]):
super().__init__(
[self._make_getter(handler, getter) for handler, getter in getters]
)
+
+
+ready_future: Future = Future()
+ready_future.set_result(None)
+
+
+class Runnable(ABC):
+ """Abstract Runnable class."""
+
+ def __init__(self, loop=None, threaded=False) -> None:
+ """
+ Init runnable.
+
+ :param loop: asyncio event loop to use.
+ :param threaded: bool. start in thread if True.
+
+ :return: None
+ """
+ if loop and threaded:
+ raise ValueError(
+ "You can not set a loop in threaded mode, cause own loop will be created"
+ )
+ self._loop = loop
+ self._threaded = threaded
+ self._task: Optional[asyncio.Task] = None
+ self._thread: Optional[Thread] = None
+ self._completed_event: Optional[asyncio.Event] = None
+ self._got_result = False
+
+ def start(self) -> bool:
+ """
+ Start runnable.
+
+ :return: bool started or not.
+ """
+ if self._task and not self._task.done():
+ logger.debug("already running")
+ return False
+
+ self._got_result = False
+ self._set_loop()
+ self._completed_event = asyncio.Event(loop=self._loop)
+ self._set_task()
+
+ if self._threaded:
+ self._thread = Thread(
+ target=self._loop.run_until_complete, args=[self._task]
+ )
+ self._thread.start()
+
+ return True
+
+ def _set_loop(self) -> None:
+ """Select and set loop."""
+ if self._threaded:
+ self._loop = asyncio.new_event_loop()
+ else:
+ try:
+ self._loop = self._loop or asyncio.get_event_loop()
+ except RuntimeError:
+ self._loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(self._loop)
+
+ def _set_task(self) -> None:
+ """Create task."""
+ self._task = self._loop.create_task(self._run_wrapper())
+
+ async def _run_wrapper(self) -> None:
+ """Wrap run() method."""
+ if not self._completed_event:
+ raise ValueError("Start was not called!")
+ try:
+ with suppress(asyncio.CancelledError):
+ return await self.run()
+ finally:
+ self._loop.call_soon_threadsafe(self._completed_event.set)
+
+ @abstractmethod
+ async def run(self) -> Any:
+ """Implement run logic respectfull to CancelError on termination."""
+
+ def wait(
+ self, sync: bool = False, timeout: float = None, force_result: bool = False
+ ) -> Awaitable:
+ """
+ Wait task to complete.
+
+ :param sync: bool. blocking wait
+ :param timeout: float seconds
+ :param force_result: check result even it was waited.
+
+ :return: awaitable if sync is False, otherise None
+ """
+ if not self._task:
+ logger.warning("Runnable is not no started")
+ return ready_future
+
+ if self._got_result and not force_result:
+ logger.warning("Already got result, skip")
+ return ready_future
+
+ if self._task.done():
+ return ready_future
+
+ coro = self._wait()
+ if timeout is not None:
+ coro = asyncio.wait_for(self._wait(), timeout=timeout) # type: ignore
+
+ if sync:
+ if self._loop.is_running():
+ start_time = time.time()
+ while not self._task.done():
+ time.sleep(0.01)
+ if timeout is not None and time.time() - start_time > timeout:
+ raise asyncio.TimeoutError()
+ self._got_result = True
+ if self._task.exception():
+ raise self._task.exception()
+ else:
+ self._loop.run_until_complete(coro)
+ return ready_future
+
+ if self._threaded:
+ loop = asyncio.get_event_loop()
+ fut = loop.create_future()
+
+ def done(task):
+ if fut.done(): # pragma: nocover
+ return
+ if task.exception():
+ fut.set_exception(task.exception())
+ else: # pragma: nocover
+ fut.set_result(None)
+
+ self._task.add_done_callback(
+ lambda task: loop.call_soon_threadsafe(lambda: done(task))
+ )
+ return fut
+
+ return coro
+
+ async def _wait(self) -> None:
+ """Wait internal method."""
+ if not self._task or not self._completed_event: # pragma: nocover
+ raise ValueError("Not started")
+
+ await self._completed_event.wait()
+
+ try:
+ await self._task
+ finally:
+ self._got_result = True
+
+ def stop(self) -> None:
+ """Stop runnable."""
+ logger.debug(f"{self} is going to be stopped {self._task}")
+ if not self._task:
+ logger.debug("not running!")
+ return
+ if self._task.done():
+ logger.debug("already completed")
+ return
+ self._loop.call_soon_threadsafe(self._task.cancel)
+
+ def start_and_wait(self, sync=False):
+ """Alias for start and wait methods."""
+ self.start()
+ return self.wait(sync=sync)
diff --git a/aea/helpers/multiple_executor.py b/aea/helpers/multiple_executor.py
index a4d0772c12..3fa00c859e 100644
--- a/aea/helpers/multiple_executor.py
+++ b/aea/helpers/multiple_executor.py
@@ -186,8 +186,6 @@ def stop(self) -> None:
self._loop.run_until_complete(
self._wait_tasks_complete(skip_exceptions=True)
)
- if self._executor_pool:
- self._executor_pool.shutdown(wait=True)
if self._executor_pool:
self._executor_pool.shutdown(wait=True)
@@ -393,7 +391,6 @@ def stop(self, timeout: float = 0) -> None:
:return: None
"""
self._executor.stop()
-
if self._thread is not None:
self._thread.join(timeout=timeout)
diff --git a/aea/launcher.py b/aea/launcher.py
index c8af13f718..f093e96d76 100644
--- a/aea/launcher.py
+++ b/aea/launcher.py
@@ -144,7 +144,7 @@ def create_async_task(self, loop: AbstractEventLoop) -> TaskAwaitable:
raise ValueError(
"Agent runtime is not async compatible. Please use runtime_mode=async"
)
- return loop.create_task(self._agent.runtime.run_runtime())
+ return loop.create_task(self._agent.runtime.start_and_wait())
@property
def id(self) -> Union[PathLike, str]:
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index e58db114a6..bc58fac40a 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -29,7 +29,11 @@
from aea.connections.base import Connection, ConnectionStates
from aea.exceptions import enforce
from aea.helpers.async_friendly_queue import AsyncFriendlyQueue
-from aea.helpers.async_utils import AsyncState, ThreadedAsyncRunner
+from aea.helpers.async_utils import (
+ AsyncState,
+ Runnable,
+ ThreadedAsyncRunner,
+)
from aea.helpers.exception_policy import ExceptionPolicyEnum
from aea.helpers.logging import WithLogger
from aea.mail.base import AEAConnectionError, Empty, Envelope, EnvelopeContext
@@ -67,7 +71,7 @@ def is_disconnecting(self) -> bool: # pragma: nocover
return self.get() == ConnectionStates.disconnecting
-class AsyncMultiplexer(WithLogger):
+class AsyncMultiplexer(Runnable, WithLogger):
"""This class can handle multiple connections at once."""
def __init__(
@@ -76,6 +80,7 @@ def __init__(
default_connection_index: int = 0,
loop: Optional[AbstractEventLoop] = None,
exception_policy: ExceptionPolicyEnum = ExceptionPolicyEnum.propagate,
+ threaded: bool = False,
):
"""
Initialize the connection multiplexer.
@@ -89,6 +94,8 @@ def __init__(
"""
super().__init__(default_logger)
self._exception_policy: ExceptionPolicyEnum = exception_policy
+ WithLogger.__init__(self, default_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
@@ -102,8 +109,21 @@ def __init__(
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)
+
+ async def run(self) -> None:
+ """Run multiplexer connect and recv/send tasks."""
+ self.set_loop(asyncio.get_event_loop())
+ try:
+ await self.connect()
+ if not self._recv_loop_task or not self._send_loop_task:
+ raise ValueError("Multiplexer is not connected properly.")
- self.set_loop(loop if loop is not None else asyncio.new_event_loop())
+ await asyncio.gather(self._recv_loop_task, self._send_loop_task)
+ finally:
+ await self.disconnect()
@property
def default_connection(self) -> Optional[Connection]:
@@ -117,8 +137,8 @@ def set_loop(self, loop: AbstractEventLoop) -> None:
:param loop: asyncio event loop.
:return: None
"""
- self._loop: AbstractEventLoop = loop
- self._lock: asyncio.Lock = asyncio.Lock(loop=self._loop)
+ self._loop = loop
+ self._lock = asyncio.Lock(loop=self._loop)
def _initialize_connections_if_any(
self, connections: Optional[Sequence[Connection]], default_connection_index: int
@@ -226,6 +246,7 @@ def connection_status(self) -> MultiplexerStatus:
async def connect(self) -> None:
"""Connect the multiplexer."""
+ self._loop = asyncio.get_event_loop()
self.logger.debug("Multiplexer connecting...")
self._connection_consistency_checks()
self._set_default_connection_if_none()
@@ -559,6 +580,25 @@ def put(self, envelope: Envelope) -> None:
"""
self.out_queue.put_nowait(envelope)
+ def setup(
+ self,
+ connections: Collection[Connection],
+ default_routing: Optional[Dict[PublicId, PublicId]] = None,
+ default_connection: Optional[PublicId] = None,
+ ) -> None:
+ """
+ Set up the multiplexer.
+
+ :param connections: the connections to use. It will replace the other ones.
+ :param default_routing: the default routing.
+ :param default_connection: the default connection.
+ :return: None.
+ """
+ self.default_routing = default_routing or {}
+ self._connections = []
+ for c in connections:
+ self.add_connection(c, c.public_id == default_connection)
+
class Multiplexer(AsyncMultiplexer):
"""Transit sync multiplexer for compatibility."""
@@ -635,30 +675,11 @@ def put(self, envelope: Envelope) -> None: # type: ignore # cause overrides co
"""
self._thread_runner.call(super()._put(envelope)) # .result(240)
- def setup(
- self,
- connections: Collection[Connection],
- default_routing: Optional[Dict[PublicId, PublicId]] = None,
- default_connection: Optional[PublicId] = None,
- ) -> None:
- """
- Set up the multiplexer.
-
- :param connections: the connections to use. It will replace the other ones.
- :param default_routing: the default routing.
- :param default_connection: the default connection.
- :return: None.
- """
- self.default_routing = default_routing or {}
- self._connections = []
- for c in connections:
- self.add_connection(c, c.public_id == default_connection)
-
class InBox:
"""A queue from where you can only consume envelopes."""
- def __init__(self, multiplexer: Multiplexer):
+ def __init__(self, multiplexer: AsyncMultiplexer):
"""
Initialize the inbox.
@@ -745,7 +766,7 @@ async def async_wait(self) -> None:
class OutBox:
"""A queue from where you can only enqueue envelopes."""
- def __init__(self, multiplexer: Multiplexer):
+ def __init__(self, multiplexer: AsyncMultiplexer):
"""
Initialize the outbox.
diff --git a/aea/runner.py b/aea/runner.py
index 4b00f4e0a4..782df4defc 100644
--- a/aea/runner.py
+++ b/aea/runner.py
@@ -59,7 +59,7 @@ def start(self) -> None:
def stop(self) -> None:
"""Stop task."""
- self._agent.stop()
+ self._agent.runtime.stop()
def create_async_task(self, loop: AbstractEventLoop) -> TaskAwaitable:
"""
@@ -73,7 +73,7 @@ def create_async_task(self, loop: AbstractEventLoop) -> TaskAwaitable:
raise ValueError(
"Agent runtime is not async compatible. Please use runtime_mode=async"
)
- return loop.create_task(self._agent.runtime.run_runtime())
+ return loop.create_task(self._agent.runtime.start_and_wait())
@property
def id(self):
diff --git a/aea/runtime.py b/aea/runtime.py
index d8c81f139c..766929fb35 100644
--- a/aea/runtime.py
+++ b/aea/runtime.py
@@ -22,24 +22,40 @@
import asyncio
import logging
-from abc import ABC, abstractmethod
from asyncio.events import AbstractEventLoop
+from concurrent.futures._base import CancelledError
from contextlib import suppress
from enum import Enum
from typing import Dict, Optional, Type, cast
from aea.abstract_agent import AbstractAgent
from aea.agent_loop import AsyncAgentLoop, AsyncState, BaseAgentLoop, SyncAgentLoop
+from aea.connections.base import ConnectionStates
from aea.decision_maker.base import DecisionMaker, DecisionMakerHandler
-from aea.helpers.async_utils import ensure_loop
+from aea.helpers.async_utils import Runnable
from aea.helpers.exception_policy import ExceptionPolicyEnum
-from aea.multiplexer import AsyncMultiplexer, Multiplexer
+from aea.multiplexer import AsyncMultiplexer
from aea.skills.tasks import TaskManager
logger = logging.getLogger(__name__)
+class StopRuntime(Exception):
+ """Exception to stop runtime."""
+
+ def __init__(self, reraise: Optional[Exception] = None):
+ """
+ Init StopRuntime exception.
+
+ :param reraise: exception to reraise.
+
+ :return: None
+ """
+ self.reraise = reraise
+ super().__init__("Stop runtime exception.")
+
+
class RuntimeStates(Enum):
"""Runtime states."""
@@ -50,7 +66,7 @@ class RuntimeStates(Enum):
error = "error"
-class BaseRuntime(ABC):
+class BaseRuntime(Runnable):
"""Abstract runtime class to create implementations."""
RUN_LOOPS: Dict[str, Type[BaseAgentLoop]] = {
@@ -64,6 +80,7 @@ def __init__(
agent: AbstractAgent,
loop_mode: Optional[str] = None,
loop: Optional[AbstractEventLoop] = None,
+ threaded=False,
) -> None:
"""
Init runtime.
@@ -73,12 +90,12 @@ def __init__(
: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)
self._agent: AbstractAgent = agent
- self._loop: AbstractEventLoop = ensure_loop(loop)
self._state: AsyncState = AsyncState(RuntimeStates.stopped, RuntimeStates)
self._state.add_callback(self._log_runtime_state)
- self._multiplexer: Multiplexer = self._get_multiplexer_instance()
+ self._multiplexer: AsyncMultiplexer = self._get_multiplexer_instance()
self._task_manager = TaskManager()
self._decision_maker: Optional[DecisionMaker] = None
@@ -107,16 +124,16 @@ def loop(self) -> AbstractEventLoop:
return self._loop
@property
- def multiplexer(self) -> Multiplexer:
+ def multiplexer(self) -> AsyncMultiplexer:
"""Get multiplexer."""
return self._multiplexer
- def _get_multiplexer_instance(self) -> Multiplexer:
+ def _get_multiplexer_instance(self) -> AsyncMultiplexer:
"""Create multiplexer instance."""
exception_policy = getattr(
self._agent, "_connection_exception_policy", ExceptionPolicyEnum.propagate
)
- return Multiplexer(
+ return AsyncMultiplexer(
self._agent.connections, loop=self.loop, exception_policy=exception_policy
)
@@ -134,6 +151,9 @@ def _get_main_loop_class(self, loop_mode: str) -> Type[BaseAgentLoop]:
)
return self.RUN_LOOPS[loop_mode]
+ def _set_task(self):
+ self._task = self._loop.create_task(self._run_wrapper(), name=self._agent.name)
+
@property
def decision_maker(self) -> DecisionMaker:
"""Return decision maker if set."""
@@ -162,29 +182,6 @@ def _log_runtime_state(self, state) -> None:
"""Log a runtime state changed."""
logger.debug(f"[{self._agent.name}]: Runtime state changed to {state}.")
- def start(self) -> None:
- """Start agent using runtime."""
- if self._state.get() is not RuntimeStates.stopped:
- logger.error(
- "[{}]: Runtime is not stopped. Please stop it and start after.".format(
- self._agent.name
- )
- )
- return
- self._start()
-
- def stop(self) -> None:
- """Stop agent and runtime."""
- if self._state.get() in (RuntimeStates.stopped, RuntimeStates.stopping):
- logger.error(
- "[{}]: Runtime is already stopped or stopping.".format(self._agent.name)
- )
- return
-
- logger.debug("[{}]: Runtime stopping...".format(self._agent.name))
- self._teardown()
- self._stop()
-
def _teardown(self) -> None:
"""Tear down runtime."""
logger.debug("[{}]: Runtime teardown...".format(self._agent.name))
@@ -194,16 +191,6 @@ def _teardown(self) -> None:
self._agent.teardown()
logger.debug("[{}]: Runtime teardown completed".format(self._agent.name))
- @abstractmethod
- def _start(self) -> None: # pragma: nocover
- """Implement runtime start function here."""
- raise NotImplementedError
-
- @abstractmethod
- def _stop(self) -> None: # pragma: nocover
- """Implement runtime stop function here."""
- raise NotImplementedError
-
@property
def is_running(self) -> bool:
"""Get running state of the runtime."""
@@ -241,6 +228,7 @@ def __init__(
agent: AbstractAgent,
loop_mode: Optional[str] = None,
loop: Optional[AbstractEventLoop] = None,
+ threaded=False,
) -> None:
"""
Init runtime.
@@ -250,9 +238,7 @@ def __init__(
:param loop: optional event loop. if not provided a new one will be created.
:return: None
"""
- super().__init__(agent=agent, loop_mode=loop_mode, loop=loop)
- self._stopping_task: Optional[asyncio.Task] = None
- self._async_stop_lock: Optional[asyncio.Lock] = None
+ super().__init__(agent=agent, loop_mode=loop_mode, loop=loop, threaded=threaded)
self._task: Optional[asyncio.Task] = None
def set_loop(self, loop: AbstractEventLoop) -> None:
@@ -261,165 +247,75 @@ def set_loop(self, loop: AbstractEventLoop) -> None:
:param loop: event loop to use.
"""
- super().set_loop(loop)
- self.multiplexer.set_loop(self.loop)
- self.main_loop.set_loop(self.loop)
- self._async_stop_lock = asyncio.Lock()
-
- def _start(self) -> None:
- """
- Start runtime synchronously.
+ BaseRuntime.set_loop(self, loop)
- Set event loops for multiplexer and agent run loop.
+ async def run(self) -> None:
+ """Start multiplexeor task."""
+ terminal_state = RuntimeStates.error
+ try:
+ await self.run_runtime()
+ except StopRuntime as e:
+ self._state.set(RuntimeStates.stopping)
+ terminal_state = RuntimeStates.stopped
+ if e.reraise:
+ raise e.reraise
+ except (asyncio.CancelledError, CancelledError, KeyboardInterrupt):
+ self._state.set(RuntimeStates.stopping)
+ terminal_state = RuntimeStates.stopped
+ finally:
+ await self.stop_runtime()
+ self._state.set(terminal_state)
- Start runtime asynchonously in own event loop.
+ async def stop_runtime(self) -> None:
"""
- self.set_loop(self.loop)
+ Stop runtime coroutine.
- logger.debug(f"Start runtime event loop {self.loop}: {id(self.loop)}")
- self._task = self.loop.create_task(self.run_runtime())
+ Stop main loop.
+ Agent teardown.
+ Disconnect multiplexer.
+ """
+ self.main_loop.stop()
+ with suppress(StopRuntime):
+ await self.main_loop.wait()
+ self._teardown()
- try:
- self.loop.run_until_complete(self._task)
- logger.debug("Runtime loop stopped!")
- except Exception:
- logger.exception("Exception raised during runtime processing")
- self._state.set(RuntimeStates.error)
- raise
- finally:
- self._stopping_task = None
+ self.multiplexer.stop()
+ await self.multiplexer.wait()
+ logger.debug("Runtime loop stopped!")
async def run_runtime(self) -> None:
"""Run agent and starts multiplexer."""
self._state.set(RuntimeStates.starting)
- try:
- await self._start_multiplexer()
- await self._start_agent_loop()
- except Exception:
- logger.exception("AsyncRuntime exception during run:")
- raise
- finally:
- if self._stopping_task and not self._stopping_task.done():
- await self._stopping_task
-
- async def _multiplexer_disconnect(self) -> None:
- """Call multiplexer disconnect asynchronous way."""
- await AsyncMultiplexer.disconnect(self.multiplexer)
+ await asyncio.gather(self._start_multiplexer(), self._start_agent_loop())
async def _start_multiplexer(self) -> None:
"""Call multiplexer connect asynchronous way."""
self.setup_multiplexer()
- await AsyncMultiplexer.connect(self.multiplexer)
+ self.multiplexer.set_loop(self._loop)
+ self.multiplexer.start()
+ await self.multiplexer.wait()
async def _start_agent_loop(self) -> None:
"""Start agent main loop asynchronous way."""
logger.debug("[{}]: Runtime started".format(self._agent.name))
+
+ await self.multiplexer.connection_status.wait(ConnectionStates.connected)
+
self.task_manager.start()
if self._decision_maker is not None: # pragma: nocover
self.decision_maker.start()
logger.debug("[{}]: Calling setup method...".format(self._agent.name))
self._agent.setup()
- self._state.set(RuntimeStates.running)
logger.debug("[{}]: Run main loop...".format(self._agent.name))
- await self.main_loop.run_loop()
-
- async def _stop_runtime(self) -> None:
- """
- Stop runtime.
-
- Disconnect multiplexer.
- Tear down agent.
- Stop agent main loop.
- """
+ self.main_loop.start()
+ self._state.set(RuntimeStates.running)
try:
- if self._async_stop_lock is None: # pragma: nocover
- return # even not started
-
- async with self._async_stop_lock:
-
- if self._state.get() in (
- RuntimeStates.stopped,
- RuntimeStates.stopping,
- ): # pragma: nocover
- return
-
- self._state.set(RuntimeStates.stopping)
- self.main_loop.stop()
-
- with suppress(BaseException):
- await self.main_loop.wait_run_loop_stopped()
-
- self._teardown()
-
- await self._multiplexer_disconnect()
-
- except BaseException: # pragma: nocover
- logger.exception("Runtime exception during stop:")
+ await self.main_loop.wait()
+ except asyncio.CancelledError:
+ self.main_loop.stop()
+ await self.main_loop.wait()
raise
- finally:
- self._state.set(RuntimeStates.stopped)
- logger.debug("[{}]: Runtime stopped".format(self._agent.name))
-
- def _stop(self) -> None:
- """
- Stop synchronously.
-
- This one calls async functions and does not guarantee to wait till runtime stopped.
- """
- logger.debug("Stop runtime coroutine.")
- if not self.loop.is_running(): # pragma: nocover
- logger.debug(
- "Runtime event loop is not running, start loop with `stop` coroutine"
- )
-
- with suppress(BaseException):
- self.loop.run_until_complete(asyncio.sleep(0.01))
-
- self.loop.run_until_complete(self._stop_runtime())
- return
-
- def set_task():
- self._stopping_task = self.loop.create_task(self._stop_runtime())
- self.loop.call_soon_threadsafe(set_task)
-
-class ThreadedRuntime(BaseRuntime):
+class ThreadedRuntime(AsyncRuntime):
"""Run agent and multiplexer in different threads with own asyncio loops."""
-
- def _start(self) -> None:
- """Implement runtime start function here."""
- self._state.set(RuntimeStates.starting)
-
- self.multiplexer.set_loop(asyncio.new_event_loop())
-
- self.setup_multiplexer()
- self.multiplexer.connect()
- self._agent.setup()
- self._start_agent_loop()
-
- def _start_agent_loop(self) -> None:
- """Start aget's main loop."""
- logger.debug("[{}]: Runtime started".format(self._agent.name))
- self.task_manager.start()
- if self._decision_maker is not None: # pragma: nocover
- self.decision_maker.start()
- try:
- self._state.set(RuntimeStates.running)
- self.main_loop.start()
- logger.debug("[{}]: Runtime stopped".format(self._agent.name))
- except KeyboardInterrupt: # pragma: nocover
- raise
- except BaseException: # pragma: nocover
- logger.exception("Runtime exception during stop:")
- self._state.set(RuntimeStates.error)
- raise
-
- def _stop(self) -> None:
- """Implement runtime stop function here."""
- self._state.set(RuntimeStates.stopping)
- self.main_loop.stop()
- self._teardown()
- self.multiplexer.disconnect()
- logger.debug("[{}]: Runtime stopped".format(self._agent.name))
- self._state.set(RuntimeStates.stopped)
diff --git a/tests/test_aea.py b/tests/test_aea.py
index 943b7e5be4..1f6f9be7dc 100644
--- a/tests/test_aea.py
+++ b/tests/test_aea.py
@@ -43,6 +43,7 @@
from aea.protocols.default.message import DefaultMessage
from aea.protocols.default.serialization import DefaultSerializer
from aea.registries.resources import Resources
+from aea.runtime import RuntimeStates, StopRuntime
from aea.skills.base import Skill, SkillContext
from packages.fetchai.connections.local.connection import LocalNode
@@ -137,7 +138,7 @@ def test_double_start():
with run_in_thread(agent.start, timeout=20):
try:
wait_for_condition(lambda: agent.is_running, timeout=20)
-
+ print(111, "started!")
t = Thread(target=agent.start)
t.start()
time.sleep(1)
@@ -530,11 +531,9 @@ def test_error_handler_is_not_set():
message=msg,
)
- with patch.object(agent, "stop") as mocked_stop:
+ with pytest.raises(StopRuntime):
agent.handle_envelope(envelope)
- mocked_stop.assert_called()
-
def test_no_handlers_registered():
"""Test no handlers are registered for message processing."""
@@ -562,11 +561,15 @@ def test_no_handlers_registered():
protocol_id=DefaultMessage.protocol_id,
message=msg,
)
- with patch.object(aea.filter, "get_active_handlers", return_value=[]):
+ with patch.object(
+ aea.filter, "get_active_handlers", return_value=[]
+ ), patch.object(
+ aea.runtime.multiplexer, "put",
+ ):
aea.handle_envelope(envelope)
- mock_logger.assert_any_call(
- f"Cannot handle envelope: no active handler registered for the protocol_id='{DefaultMessage.protocol_id}'."
- )
+ mock_logger.assert_any_call(
+ f"Cannot handle envelope: no active handler registered for the protocol_id='{DefaultMessage.protocol_id}'."
+ )
class TestContextNamespace:
@@ -721,7 +724,6 @@ def test_handle_just_log(self) -> None:
with patch.object(self.aea._logger, "exception") as patched:
t = Thread(target=self.aea.start)
t.start()
-
self.aea_tool.put_inbox(self.aea_tool.dummy_envelope())
self.aea_tool.put_inbox(self.aea_tool.dummy_envelope())
time.sleep(1)
@@ -736,14 +738,17 @@ def test_act_propagate(self) -> None:
with pytest.raises(ExpectedExcepton):
self.aea.start()
- assert not self.aea.is_running
+ assert self.aea.runtime.state == RuntimeStates.error
def test_act_stop_and_exit(self) -> None:
"""Test stop and exit policy on behaviour act."""
self.aea._skills_exception_policy = ExceptionPolicyEnum.stop_and_exit
self.behaviour.act = self.raise_exception # type: ignore # cause error: Cannot assign to a method
- self.aea.start()
+ with pytest.raises(
+ AEAException, match=r"AEA was terminated cause exception .*"
+ ):
+ self.aea.start()
assert not self.aea.is_running
@@ -772,7 +777,6 @@ def test_act_bad_policy(self) -> None:
def teardown(self) -> None:
"""Stop AEA if not stopped."""
- self.aea.teardown()
self.aea.stop()
diff --git a/tests/test_agent.py b/tests/test_agent.py
index b0de015614..010896682b 100644
--- a/tests/test_agent.py
+++ b/tests/test_agent.py
@@ -81,16 +81,14 @@ def test_run_agent():
assert agent.state == RuntimeStates.stopped
agent_thread.start()
try:
- wait_for_condition(
- lambda: agent.state == RuntimeStates.starting,
- timeout=10,
- error_msg="Agent state must be 'starting'",
- )
wait_for_condition(
lambda: agent.state == RuntimeStates.running,
timeout=10,
error_msg="Agent state must be 'running'",
)
+ print(33333)
+ except Exception as e:
+ print(111111111111111111111111, e)
finally:
agent.stop()
assert agent.state == RuntimeStates.stopped
diff --git a/tests/test_agent_loop.py b/tests/test_agent_loop.py
index 77f81453b2..cf3ad24fc6 100644
--- a/tests/test_agent_loop.py
+++ b/tests/test_agent_loop.py
@@ -26,7 +26,7 @@
import pytest
from aea.aea import AEA
-from aea.agent_loop import AsyncAgentLoop, BaseAgentLoop, SyncAgentLoop
+from aea.agent_loop import AgentLoopStates, AsyncAgentLoop, BaseAgentLoop, SyncAgentLoop
from aea.helpers.async_friendly_queue import AsyncFriendlyQueue
from aea.helpers.exception_policy import ExceptionPolicyEnum
from aea.mail.base import Envelope
@@ -36,7 +36,7 @@
from aea.skills.base import Behaviour, Handler, SkillContext
from aea.skills.behaviours import TickerBehaviour
-from tests.common.utils import run_in_thread, wait_for_condition
+from tests.common.utils import wait_for_condition
class CountHandler(Handler):
@@ -200,23 +200,27 @@ class TestAsyncAgentLoop:
def test_loop_start_stop(self):
"""Test loop start and stopped properly."""
- agent_loop = self.AGENT_LOOP_CLASS(self.FAKE_AGENT_CLASS())
- with run_in_thread(agent_loop.start):
- wait_for_condition(lambda: agent_loop.is_running, timeout=10)
- agent_loop.stop()
+ agent_loop = self.AGENT_LOOP_CLASS(self.FAKE_AGENT_CLASS(), threaded=True)
+
+ agent_loop.start()
+ wait_for_condition(lambda: agent_loop.is_running, timeout=10)
+ agent_loop.stop()
+ agent_loop.wait(sync=True)
+ assert not agent_loop.is_running, agent_loop.state
def test_handle_envelope(self):
"""Test one envelope handling."""
handler = CountHandler.make()
agent = self.FAKE_AGENT_CLASS(handlers=[handler])
- agent_loop = self.AGENT_LOOP_CLASS(agent)
+ agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True)
handler.setup()
- with run_in_thread(agent_loop.start, timeout=10):
- wait_for_condition(lambda: agent_loop.is_running, timeout=10)
- agent.put_inbox("msg")
- wait_for_condition(lambda: handler.counter == 1, timeout=2)
- agent_loop.stop()
+ agent_loop.start()
+ wait_for_condition(lambda: agent_loop.is_running, timeout=10)
+ agent.put_inbox("msg")
+ wait_for_condition(lambda: handler.counter == 1, timeout=2)
+ agent_loop.stop()
+ agent_loop.wait(sync=True)
def test_behaviour_act(self):
"""Test behaviour act called by schedule."""
@@ -225,44 +229,43 @@ def test_behaviour_act(self):
behaviour = CountBehaviour.make(tick_interval=tick_interval)
behaviour.setup()
agent = self.FAKE_AGENT_CLASS(behaviours=[behaviour])
- agent_loop = self.AGENT_LOOP_CLASS(agent)
+ agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True)
- with run_in_thread(agent_loop.start, timeout=5):
- wait_for_condition(lambda: agent_loop.is_running, timeout=10)
+ agent_loop.start()
+ wait_for_condition(lambda: agent_loop.is_running, timeout=10)
- # test behaviour called
- wait_for_condition(
- lambda: behaviour.counter >= 1, timeout=tick_interval * 2
- )
-
- agent_loop.stop()
+ wait_for_condition(lambda: behaviour.counter >= 1, timeout=tick_interval * 2)
+ agent_loop.stop()
+ agent_loop.wait(sync=True)
def test_internal_messages(self):
"""Test internal meesages are processed."""
agent = self.FAKE_AGENT_CLASS()
- agent_loop = self.AGENT_LOOP_CLASS(agent)
+ agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True)
- with run_in_thread(agent_loop.start, timeout=5):
- wait_for_condition(lambda: agent_loop.is_running, timeout=10)
- agent.put_internal_message("msg")
- wait_for_condition(
- lambda: agent.filter.handle_internal_message.called is True, timeout=5,
- )
- agent_loop.stop()
+ agent_loop.start()
+ wait_for_condition(lambda: agent_loop.is_running, timeout=10)
+ agent.put_internal_message("msg")
+ wait_for_condition(
+ lambda: agent.filter.handle_internal_message.called is True, timeout=5,
+ )
+ agent_loop.stop()
+ agent_loop.wait(sync=True)
def test_new_behaviours(self):
"""Test new behaviours are added."""
agent = self.FAKE_AGENT_CLASS()
- agent_loop = self.AGENT_LOOP_CLASS(agent)
+ agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True)
agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP = 0.5
- with run_in_thread(agent_loop.start, timeout=5):
- wait_for_condition(lambda: agent_loop.is_running, timeout=10)
- wait_for_condition(
- lambda: agent.filter.handle_new_handlers_and_behaviours.call_count >= 2,
- timeout=agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP * 3,
- )
- agent_loop.stop()
+ agent_loop.start()
+ wait_for_condition(lambda: agent_loop.is_running, timeout=10)
+ wait_for_condition(
+ lambda: agent.filter.handle_new_handlers_and_behaviours.call_count >= 2,
+ timeout=agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP * 3,
+ )
+ agent_loop.stop()
+ agent_loop.wait(sync=True)
@pytest.mark.asyncio
async def test_behaviour_exception(self):
@@ -270,25 +273,26 @@ async def test_behaviour_exception(self):
tick_interval = 0.1
behaviour = FailBehaviour.make(tick_interval)
agent = self.FAKE_AGENT_CLASS(behaviours=[behaviour])
- loop = asyncio.get_event_loop()
- agent_loop = self.AGENT_LOOP_CLASS(agent)
- agent_loop.set_loop(loop)
- loop_task = loop.create_task(agent_loop.run_loop())
- await asyncio.sleep(tick_interval * 2)
+ agent_loop = self.AGENT_LOOP_CLASS(agent, threaded=True)
+
agent._skills_exception_policy = ExceptionPolicyEnum.propagate
with pytest.raises(ValueError, match="expected!"):
- await loop_task
+ agent_loop.start()
+ agent_loop.wait(sync=True)
- def test_stop(self):
+ @pytest.mark.asyncio
+ async def test_stop(self):
"""Test loop stoped."""
agent = self.FAKE_AGENT_CLASS()
- loop = asyncio.get_event_loop()
agent_loop = self.AGENT_LOOP_CLASS(agent)
- agent_loop.set_loop(loop)
- loop_task = loop.create_task(agent_loop.run_loop())
+ agent_loop.start()
+ await asyncio.wait_for(
+ agent_loop._state.wait(AgentLoopStates.started), timeout=10
+ )
agent_loop.stop()
- loop.run_until_complete(asyncio.sleep(0.1))
- assert loop_task.done()
+ await asyncio.wait_for(
+ agent_loop._state.wait(AgentLoopStates.stopped), timeout=10
+ )
class TestSyncAgentLoop:
diff --git a/tests/test_helpers/test_async_utils.py b/tests/test_helpers/test_async_utils.py
index 6c008a29fd..c106cb595c 100644
--- a/tests/test_helpers/test_async_utils.py
+++ b/tests/test_helpers/test_async_utils.py
@@ -20,6 +20,7 @@
import asyncio
from concurrent.futures._base import CancelledError
from contextlib import suppress
+from threading import Thread
import pytest
@@ -28,9 +29,9 @@
AwaitableProc,
HandlerItemGetter,
PeriodicCaller,
+ Runnable,
ThreadedAsyncRunner,
ensure_list,
- ensure_loop,
)
@@ -167,16 +168,6 @@ def callback():
periodic_caller.stop()
-@pytest.mark.asyncio
-async def test_ensure_loop():
- """Test ensure_loop."""
- loop = asyncio.new_event_loop()
- assert ensure_loop(loop) == loop
-
- loop = asyncio.get_event_loop()
- assert ensure_loop(loop) != loop
-
-
@pytest.mark.asyncio
async def test_threaded_async_run():
"""Test threaded async runner."""
@@ -254,3 +245,143 @@ def test_libp2pconnection_awaitable_proc_cancelled():
proc = AwaitableProc(["sleep", "100"], shell=False)
proc_task = asyncio.ensure_future(proc.start())
proc_task.cancel()
+
+
+class RunAndExit(Runnable):
+ """Test class."""
+
+ async def run(self):
+ """Test method."""
+ await asyncio.sleep(0.2)
+
+
+class TestRunnable:
+ """Tests for Runnable object."""
+
+ def test_no_loop_and_threded(self):
+ """Test runnable fails on threaded mode and loop provided.."""
+ with pytest.raises(ValueError,):
+ RunAndExit(loop=asyncio.get_event_loop(), threaded=True)
+
+ @pytest.mark.asyncio
+ async def test_runnable_async(self):
+ """Test runnable async methods."""
+
+ class TestRun(Runnable):
+ async def run(self):
+ while True:
+ await asyncio.sleep(1)
+
+ run = TestRun()
+ run.start()
+ run.stop()
+ await run.wait()
+
+ run = TestRun(threaded=True)
+ run.start()
+ run.stop()
+ run.wait(sync=True)
+
+ run = RunAndExit()
+ await run.start_and_wait()
+
+ def test_runnable_sync(self):
+ """Test runnable sync methods."""
+ run = RunAndExit()
+ run.start_and_wait(sync=True)
+
+ @pytest.mark.asyncio
+ async def test_double_start(self):
+ """Test runnable async methods."""
+
+ class TestRun(Runnable):
+ async def run(self):
+ while True:
+ await asyncio.sleep(1)
+
+ run = TestRun()
+ await run.wait()
+ assert run.start()
+ assert not run.start()
+ run.stop()
+ await run.wait()
+ await run.wait()
+
+ @pytest.mark.asyncio
+ async def test_run_in_thread(self):
+ """Test runnable async methods."""
+
+ class TestRun(Runnable):
+ async def run(self):
+ while True:
+ await asyncio.sleep(1)
+
+ run = TestRun()
+ t = Thread(target=run.start)
+ t.start()
+ run.stop()
+ t.join()
+
+ @pytest.mark.asyncio
+ async def test_timeout(self):
+ """Test runnable async methods."""
+
+ class TestRun(Runnable):
+ async def run(self):
+ while True:
+ await asyncio.sleep(1)
+
+ run = TestRun(threaded=True)
+ run.start()
+ with pytest.raises(asyncio.TimeoutError):
+ run.wait(sync=True, timeout=0.1)
+
+ run.stop()
+ run.wait(sync=True)
+
+ run = TestRun()
+ run.start()
+ with pytest.raises(asyncio.TimeoutError):
+ await run.wait(timeout=0.1)
+ run.stop()
+ await run.wait()
+
+ @pytest.mark.asyncio
+ async def test_exception(self):
+ """Test runnable async methods."""
+
+ class TestRun(Runnable):
+ async def run(self):
+ raise Exception("awaited")
+
+ run = TestRun(threaded=True)
+ run.start()
+ with pytest.raises(Exception, match="awaited"):
+ run.wait(sync=True, timeout=0.1)
+
+ run.stop()
+ run.wait(sync=True)
+
+ run = TestRun()
+ run.start()
+ with pytest.raises(Exception, match="awaited"):
+ await run.wait(timeout=0.1)
+
+ run.stop()
+ await run.wait()
+
+ @pytest.mark.asyncio
+ async def test_wait_async_threaded(self):
+ """Test runnable async methods."""
+
+ class TestRun(Runnable):
+ async def run(self):
+ raise Exception("awaited")
+
+ run = TestRun(threaded=True)
+ run.start()
+ with pytest.raises(Exception, match="awaited"):
+ await run.wait(timeout=0.2)
+
+ run.stop()
+ await run.wait()
diff --git a/tests/test_launcher.py b/tests/test_launcher.py
index 2ea05053ff..b6ee6083b5 100644
--- a/tests/test_launcher.py
+++ b/tests/test_launcher.py
@@ -132,7 +132,6 @@ def test_one_fails(self) -> None:
with pytest.raises(Exception, match="Expected exception!"):
runner.start()
- time.sleep(1)
finally:
runner.stop()
diff --git a/tests/test_runtime.py b/tests/test_runtime.py
index 05cc970e66..1a4608e9a3 100644
--- a/tests/test_runtime.py
+++ b/tests/test_runtime.py
@@ -28,7 +28,8 @@
from aea.configurations.constants import DEFAULT_LEDGER, DEFAULT_PRIVATE_KEY_FILE
from aea.runtime import AsyncRuntime, BaseRuntime, RuntimeStates, ThreadedRuntime
-from tests.common.utils import run_in_thread, wait_for_condition
+from tests.common.utils import wait_for_condition
+
from tests.conftest import CUR_PATH
@@ -46,33 +47,36 @@ def setup(self):
builder.add_private_key(DEFAULT_LEDGER, private_key_path)
builder.add_skill(Path(CUR_PATH, "data", "dummy_skill"))
self.agent = builder.build()
- self.runtime = self.RUNTIME(self.agent)
+ self.runtime = self.RUNTIME(self.agent, threaded=True)
+
+ def teardown(self):
+ self.runtime.stop()
+ self.runtime.wait(sync=True)
def test_start_stop(self):
"""Test runtime tart/stop."""
- with run_in_thread(self.runtime.start, timeout=20):
- wait_for_condition(lambda: self.runtime.is_running, timeout=20)
- self.runtime.stop()
- wait_for_condition(lambda: not self.runtime.is_running, timeout=20)
+ self.runtime.start()
+ wait_for_condition(lambda: self.runtime.is_running, timeout=20)
+ self.runtime.stop()
+ self.runtime.wait(sync=True)
def test_double_start(self):
"""Test runtime double start do nothing."""
- with patch.object(self.runtime, "_start", side_effect=ValueError("oops")):
- with pytest.raises(ValueError, match="oops"):
- self.runtime.start()
-
- self.runtime._state.set(RuntimeStates.running)
- self.runtime.start()
+ assert self.runtime.start()
+ assert not self.runtime.start()
+ wait_for_condition(lambda: self.runtime.is_running, timeout=20)
def test_double_stop(self):
"""Test runtime double stop do nothing."""
- with patch.object(self.runtime, "_stop", side_effect=ValueError("oops")):
- self.runtime._state.set(RuntimeStates.running)
- with pytest.raises(ValueError, match="oops"):
- self.runtime.stop()
+ self.runtime.start()
+ wait_for_condition(lambda: self.runtime.is_running, timeout=20)
+ self.runtime.stop()
+ self.runtime.wait(sync=True)
+ assert self.runtime.is_stopped
- self.runtime._state.set(RuntimeStates.stopped)
- self.runtime.stop()
+ self.runtime.stop()
+ self.runtime.wait(sync=True)
+ assert self.runtime.is_stopped
def test_error_state(self):
"""Test runtime fails on start."""
@@ -80,9 +84,9 @@ def test_error_state(self):
self.runtime, "_start_agent_loop", side_effect=ValueError("oops")
):
with pytest.raises(ValueError, match="oops"):
- self.runtime.start()
+ self.runtime.start_and_wait(sync=True)
- assert self.runtime.state == RuntimeStates.error
+ assert self.runtime.state == RuntimeStates.error, self.runtime.state
class TestThreadedRuntime(TestAsyncRuntime):
@@ -96,8 +100,6 @@ def test_error_state(self):
self.runtime.main_loop, "start", side_effect=ValueError("oops")
):
with pytest.raises(ValueError, match="oops"):
- self.runtime.start()
-
- assert self.runtime.state == RuntimeStates.error
+ self.runtime.start_and_wait(sync=True)
- self.runtime._stop()
+ assert self.runtime.state == RuntimeStates.error, self.runtime.state
diff --git a/tests/test_skills/test_error.py b/tests/test_skills/test_error.py
index 926951face..70a1e7a358 100644
--- a/tests/test_skills/test_error.py
+++ b/tests/test_skills/test_error.py
@@ -188,6 +188,7 @@ def test_error_unsupported_skill(self):
msg = envelope.message
assert msg.performative == DefaultMessage.Performative.ERROR
assert msg.error_code == DefaultMessage.ErrorCode.UNSUPPORTED_SKILL
+ print("\n1111111, STOP in TEST\n", flush=True)
def test_error_unsupported_skill_when_skill_id_is_none(self):
"""Test the 'send_unsupported_skill' when the skill id in the envelope is None."""
From 699561453f001474e68a760f3c9c0e2e4eca2d8a Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Thu, 10 Sep 2020 17:52:44 +0300
Subject: [PATCH 083/131] threaded runtime. fixes. asyncio fix for stub
conection
---
aea/agent.py | 10 ++-
aea/agent_loop.py | 20 ++++--
aea/cli/launch.py | 1 -
aea/helpers/async_utils.py | 96 +++++++++++++++++---------
aea/launcher.py | 14 +++-
aea/multiplexer.py | 11 ++-
aea/runner.py | 2 +-
aea/runtime.py | 14 ++--
tests/test_aea.py | 5 +-
tests/test_agent.py | 3 -
tests/test_agent_loop.py | 12 ++--
tests/test_helpers/test_async_utils.py | 50 ++++++++------
tests/test_runtime.py | 13 ++--
tests/test_skills/test_error.py | 1 -
14 files changed, 156 insertions(+), 96 deletions(-)
diff --git a/aea/agent.py b/aea/agent.py
index 70cd8fdc47..6246e45451 100644
--- a/aea/agent.py
+++ b/aea/agent.py
@@ -191,8 +191,12 @@ def start(self) -> None:
:return: None
"""
- if self.runtime.start():
- self.runtime.wait(sync=True)
+ was_started = self.runtime.start()
+
+ if was_started:
+ self.runtime.wait_completed(sync=True)
+ else:
+ raise ValueError("Failed to start runtime! Ws it already started?")
def stop(self) -> None:
"""
@@ -207,7 +211,7 @@ def stop(self) -> None:
:return: None
"""
self.runtime.stop()
- self.runtime.wait(sync=True)
+ self.runtime.wait_completed(sync=True)
@property
def state(self) -> RuntimeStates:
diff --git a/aea/agent_loop.py b/aea/agent_loop.py
index 40196f37a6..dd02d1eca3 100644
--- a/aea/agent_loop.py
+++ b/aea/agent_loop.py
@@ -55,6 +55,7 @@ class AgentLoopStates(Enum):
initial = None
started = "started"
+ starting = "starting"
stopped = "stopped"
stopping = "stopping"
error = "error"
@@ -104,6 +105,7 @@ def teardown(self): # pylint: disable=no-self-use
async def run(self) -> None:
"""Run agent loop."""
self.logger.debug("agent loop started")
+ self._state.set(AgentLoopStates.starting)
self.setup()
self._set_tasks()
try:
@@ -111,13 +113,17 @@ async def run(self) -> None:
except (CancelledError, KeyboardInterrupt):
pass
finally:
- self.teardown()
- self._stop_tasks()
- for t in self._tasks:
- with suppress(BaseException):
- await t
- self._state.set(AgentLoopStates.stopped)
- logger.debug("agent loop stopped")
+ await self._stop()
+
+ async def _stop(self) -> None:
+ """Stop and cleanup."""
+ self.teardown()
+ self._stop_tasks()
+ for t in self._tasks:
+ with suppress(BaseException):
+ await t
+ self._state.set(AgentLoopStates.stopped)
+ logger.debug("agent loop stopped")
async def _gather_tasks(self) -> None:
"""Wait till first task exception."""
diff --git a/aea/cli/launch.py b/aea/cli/launch.py
index a35458d39b..dba5695ba7 100644
--- a/aea/cli/launch.py
+++ b/aea/cli/launch.py
@@ -115,7 +115,6 @@ def _launch_threads(agents: List[Path]) -> int:
for agent_directory in agents:
with cd(agent_directory):
aeas.append(AEABuilder.from_aea_project(".").build())
-
runner = AEARunner(
agents=aeas, mode="threaded", fail_policy=ExecutorExceptionPolicies.log_only
)
diff --git a/aea/helpers/async_utils.py b/aea/helpers/async_utils.py
index 64155f510b..7ca18a6b7f 100644
--- a/aea/helpers/async_utils.py
+++ b/aea/helpers/async_utils.py
@@ -373,7 +373,7 @@ def __init__(self, *args, **kwargs):
self.future = None
async def start(self):
- """Start the subprocess"""
+ """Start the subprocess."""
self.proc = subprocess.Popen(*self.args, **self.kwargs) # nosec
self.loop = asyncio.get_event_loop()
self.future = asyncio.futures.Future()
@@ -388,6 +388,7 @@ async def start(self):
self._thread.join()
def _in_thread(self):
+ """Run in dedicated thread."""
self.proc.wait()
self.loop.call_soon_threadsafe(self.future.set_result, self.proc.returncode)
@@ -485,6 +486,8 @@ def __init__(self, loop=None, threaded=False) -> None:
self._thread: Optional[Thread] = None
self._completed_event: Optional[asyncio.Event] = None
self._got_result = False
+ self._was_cancelled = False
+ self._is_running: bool = False
def start(self) -> bool:
"""
@@ -495,10 +498,11 @@ def start(self) -> bool:
if self._task and not self._task.done():
logger.debug("already running")
return False
-
+ self._is_running = False
self._got_result = False
self._set_loop()
self._completed_event = asyncio.Event(loop=self._loop)
+ self._was_cancelled = False
self._set_task()
if self._threaded:
@@ -528,21 +532,27 @@ async def _run_wrapper(self) -> None:
"""Wrap run() method."""
if not self._completed_event:
raise ValueError("Start was not called!")
+
try:
with suppress(asyncio.CancelledError):
return await self.run()
finally:
self._loop.call_soon_threadsafe(self._completed_event.set)
+ @property
+ def is_running(self) -> bool:
+ """Get running state."""
+ return self._is_running
+
@abstractmethod
async def run(self) -> Any:
"""Implement run logic respectfull to CancelError on termination."""
- def wait(
+ def wait_completed(
self, sync: bool = False, timeout: float = None, force_result: bool = False
) -> Awaitable:
"""
- Wait task to complete.
+ Wait runnable execution completed.
:param sync: bool. blocking wait
:param timeout: float seconds
@@ -559,44 +569,53 @@ def wait(
return ready_future
if self._task.done():
- return ready_future
-
- coro = self._wait()
- if timeout is not None:
- coro = asyncio.wait_for(self._wait(), timeout=timeout) # type: ignore
+ self._got_result = True
+ return self._task
if sync:
- if self._loop.is_running():
- start_time = time.time()
- while not self._task.done():
- time.sleep(0.01)
- if timeout is not None and time.time() - start_time > timeout:
- raise asyncio.TimeoutError()
- self._got_result = True
- if self._task.exception():
- raise self._task.exception()
- else:
- self._loop.run_until_complete(coro)
+ self._wait_sync(timeout)
return ready_future
- if self._threaded:
- loop = asyncio.get_event_loop()
- fut = loop.create_future()
+ if not self._threaded:
+ return asyncio.wait_for(self._wait(), timeout=timeout)
+
+ # for threaded mode create a future and bind it to task
+ loop = asyncio.get_event_loop()
+ fut = loop.create_future()
- def done(task):
+ def done(task):
+ try:
if fut.done(): # pragma: nocover
return
if task.exception():
fut.set_exception(task.exception())
else: # pragma: nocover
fut.set_result(None)
+ finally:
+ self._got_result = True
- self._task.add_done_callback(
- lambda task: loop.call_soon_threadsafe(lambda: done(task))
- )
- return fut
+ self._task.add_done_callback(
+ lambda task: loop.call_soon_threadsafe(lambda: done(task))
+ )
+ return fut
- return coro
+ def _wait_sync(self, timeout: Optional[float] = None) -> None:
+ """Wait task completed in sync manner."""
+ if self._task is None:
+ raise ValueError("task is not set!")
+ if self._loop.is_running():
+ start_time = time.time()
+ while not self._task.done():
+ time.sleep(0.01)
+ if timeout is not None and time.time() - start_time > timeout:
+ raise asyncio.TimeoutError()
+ self._got_result = True
+ if self._task.exception():
+ raise self._task.exception()
+ else:
+ self._loop.run_until_complete(
+ asyncio.wait_for(self._wait(), timeout=timeout)
+ )
async def _wait(self) -> None:
"""Wait internal method."""
@@ -610,7 +629,7 @@ async def _wait(self) -> None:
finally:
self._got_result = True
- def stop(self) -> None:
+ def stop(self, force: bool = False) -> None:
"""Stop runnable."""
logger.debug(f"{self} is going to be stopped {self._task}")
if not self._task:
@@ -619,9 +638,20 @@ def stop(self) -> None:
if self._task.done():
logger.debug("already completed")
return
- self._loop.call_soon_threadsafe(self._task.cancel)
+ self._loop.call_soon_threadsafe(self._task_cancel, force)
+
+ def _task_cancel(self, force: bool = False) -> None:
+ """Cancel task internal method."""
+ if self._task is None:
+ return
+
+ if self._was_cancelled and not force:
+ return
+
+ self._was_cancelled = True
+ self._task.cancel()
- def start_and_wait(self, sync=False):
+ def start_and_wait_completed(self, *args, **kwargs) -> Awaitable:
"""Alias for start and wait methods."""
self.start()
- return self.wait(sync=sync)
+ return self.wait_completed(*args, **kwargs)
diff --git a/aea/launcher.py b/aea/launcher.py
index f093e96d76..cc6eaf0903 100644
--- a/aea/launcher.py
+++ b/aea/launcher.py
@@ -89,8 +89,10 @@ def _run_agent(
_set_logger(log_level=log_level)
agent = load_agent(agent_dir)
+ on_stop = False
def stop_event_thread():
+ nonlocal on_stop
try:
stop_event.wait()
except (KeyboardInterrupt, EOFError, BrokenPipeError) as e: # pragma: nocover
@@ -98,7 +100,10 @@ def stop_event_thread():
f"Exception raised in stop_event_thread {e} {type(e)}. Skip it, looks process is closed."
)
finally:
- agent.stop()
+ if not on_stop:
+ logger.debug("_run_agent: stop event raised. call agent.stop")
+ on_stop = True
+ agent.stop()
Thread(target=stop_event_thread, daemon=True).start()
try:
@@ -111,7 +116,10 @@ def stop_event_thread():
exc.__traceback__ = e.__traceback__
raise exc
finally:
- agent.stop()
+ if not on_stop:
+ logger.debug("_run_agent: call agent.stop")
+ on_stop = True
+ agent.stop()
class AEADirTask(AbstractExecutorTask):
@@ -144,7 +152,7 @@ def create_async_task(self, loop: AbstractEventLoop) -> TaskAwaitable:
raise ValueError(
"Agent runtime is not async compatible. Please use runtime_mode=async"
)
- return loop.create_task(self._agent.runtime.start_and_wait())
+ return loop.create_task(self._agent.runtime.start_and_wait_completed())
@property
def id(self) -> Union[PathLike, str]:
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index bc58fac40a..ec4896ba0a 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -251,6 +251,7 @@ async def connect(self) -> None:
self._connection_consistency_checks()
self._set_default_connection_if_none()
self._out_queue = asyncio.Queue()
+
async with self._lock:
if self.connection_status.is_connected:
self.logger.debug("Multiplexer already connected.")
@@ -377,9 +378,9 @@ async def _disconnect_all(self) -> None:
self.logger.debug("Tear the multiplexer connections down.")
for connection_id, connection in self._id_to_connection.items():
try:
- await self._disconnect_one(connection_id)
+ await asyncio.wait_for(self._disconnect_one(connection_id), timeout=5)
except Exception as e: # pylint: disable=broad-except
- self.logger.error(
+ self.logger.exception(
"Error while disconnecting {}: {}".format(
str(type(connection)), str(e)
)
@@ -423,6 +424,7 @@ async def _send_loop(self) -> None:
"Received empty envelope. Quitting the sending loop..."
)
return None
+
self.logger.debug("Sending envelope {}".format(str(envelope)))
await self._send(envelope)
except asyncio.CancelledError:
@@ -578,7 +580,10 @@ def put(self, envelope: Envelope) -> None:
:param envelope: the envelope to be sent.
:return: None
"""
- self.out_queue.put_nowait(envelope)
+ if self._threaded:
+ self._loop.call_soon_threadsafe(self.out_queue.put_nowait, envelope)
+ else:
+ self.out_queue.put_nowait(envelope)
def setup(
self,
diff --git a/aea/runner.py b/aea/runner.py
index 782df4defc..5c6791925b 100644
--- a/aea/runner.py
+++ b/aea/runner.py
@@ -73,7 +73,7 @@ def create_async_task(self, loop: AbstractEventLoop) -> TaskAwaitable:
raise ValueError(
"Agent runtime is not async compatible. Please use runtime_mode=async"
)
- return loop.create_task(self._agent.runtime.start_and_wait())
+ return loop.create_task(self._agent.runtime.start_and_wait_completed())
@property
def id(self):
diff --git a/aea/runtime.py b/aea/runtime.py
index 766929fb35..ea906653f7 100644
--- a/aea/runtime.py
+++ b/aea/runtime.py
@@ -276,11 +276,11 @@ async def stop_runtime(self) -> None:
"""
self.main_loop.stop()
with suppress(StopRuntime):
- await self.main_loop.wait()
+ await self.main_loop.wait_completed()
self._teardown()
self.multiplexer.stop()
- await self.multiplexer.wait()
+ await self.multiplexer.wait_completed()
logger.debug("Runtime loop stopped!")
async def run_runtime(self) -> None:
@@ -293,7 +293,7 @@ async def _start_multiplexer(self) -> None:
self.setup_multiplexer()
self.multiplexer.set_loop(self._loop)
self.multiplexer.start()
- await self.multiplexer.wait()
+ await self.multiplexer.wait_completed()
async def _start_agent_loop(self) -> None:
"""Start agent main loop asynchronous way."""
@@ -310,12 +310,16 @@ async def _start_agent_loop(self) -> None:
self.main_loop.start()
self._state.set(RuntimeStates.running)
try:
- await self.main_loop.wait()
+ await self.main_loop.wait_completed()
except asyncio.CancelledError:
self.main_loop.stop()
- await self.main_loop.wait()
+ await self.main_loop.wait_completed()
raise
class ThreadedRuntime(AsyncRuntime):
"""Run agent and multiplexer in different threads with own asyncio loops."""
+
+ def _get_multiplexer_instance(self) -> AsyncMultiplexer:
+ """Create multiplexer instance."""
+ return AsyncMultiplexer(self._agent.connections, threaded=True)
diff --git a/tests/test_aea.py b/tests/test_aea.py
index 1f6f9be7dc..a4108c8c3e 100644
--- a/tests/test_aea.py
+++ b/tests/test_aea.py
@@ -138,7 +138,6 @@ def test_double_start():
with run_in_thread(agent.start, timeout=20):
try:
wait_for_condition(lambda: agent.is_running, timeout=20)
- print(111, "started!")
t = Thread(target=agent.start)
t.start()
time.sleep(1)
@@ -185,13 +184,17 @@ def test_react():
with run_in_thread(agent.start, timeout=20, on_exit=agent.stop):
wait_for_condition(lambda: agent.is_running, timeout=20)
+ time.sleep(1)
agent.outbox.put(envelope)
+ print("111 msg put", flush=True)
default_protocol_public_id = DefaultMessage.protocol_id
dummy_skill_public_id = DUMMY_SKILL_PUBLIC_ID
handler = agent.resources.get_handler(
default_protocol_public_id, dummy_skill_public_id
)
+
assert handler is not None, "Handler is not set."
+
wait_for_condition(
lambda: len(handler.handled_messages) > 0,
timeout=20,
diff --git a/tests/test_agent.py b/tests/test_agent.py
index 010896682b..93d6bcb58f 100644
--- a/tests/test_agent.py
+++ b/tests/test_agent.py
@@ -86,9 +86,6 @@ def test_run_agent():
timeout=10,
error_msg="Agent state must be 'running'",
)
- print(33333)
- except Exception as e:
- print(111111111111111111111111, e)
finally:
agent.stop()
assert agent.state == RuntimeStates.stopped
diff --git a/tests/test_agent_loop.py b/tests/test_agent_loop.py
index cf3ad24fc6..641f6537d4 100644
--- a/tests/test_agent_loop.py
+++ b/tests/test_agent_loop.py
@@ -205,7 +205,7 @@ def test_loop_start_stop(self):
agent_loop.start()
wait_for_condition(lambda: agent_loop.is_running, timeout=10)
agent_loop.stop()
- agent_loop.wait(sync=True)
+ agent_loop.wait_completed(sync=True)
assert not agent_loop.is_running, agent_loop.state
def test_handle_envelope(self):
@@ -220,7 +220,7 @@ def test_handle_envelope(self):
agent.put_inbox("msg")
wait_for_condition(lambda: handler.counter == 1, timeout=2)
agent_loop.stop()
- agent_loop.wait(sync=True)
+ agent_loop.wait_completed(sync=True)
def test_behaviour_act(self):
"""Test behaviour act called by schedule."""
@@ -236,7 +236,7 @@ def test_behaviour_act(self):
wait_for_condition(lambda: behaviour.counter >= 1, timeout=tick_interval * 2)
agent_loop.stop()
- agent_loop.wait(sync=True)
+ agent_loop.wait_completed(sync=True)
def test_internal_messages(self):
"""Test internal meesages are processed."""
@@ -250,7 +250,7 @@ def test_internal_messages(self):
lambda: agent.filter.handle_internal_message.called is True, timeout=5,
)
agent_loop.stop()
- agent_loop.wait(sync=True)
+ agent_loop.wait_completed(sync=True)
def test_new_behaviours(self):
"""Test new behaviours are added."""
@@ -265,7 +265,7 @@ def test_new_behaviours(self):
timeout=agent_loop.NEW_BEHAVIOURS_PROCESS_SLEEP * 3,
)
agent_loop.stop()
- agent_loop.wait(sync=True)
+ agent_loop.wait_completed(sync=True)
@pytest.mark.asyncio
async def test_behaviour_exception(self):
@@ -278,7 +278,7 @@ async def test_behaviour_exception(self):
agent._skills_exception_policy = ExceptionPolicyEnum.propagate
with pytest.raises(ValueError, match="expected!"):
agent_loop.start()
- agent_loop.wait(sync=True)
+ agent_loop.wait_completed(sync=True)
@pytest.mark.asyncio
async def test_stop(self):
diff --git a/tests/test_helpers/test_async_utils.py b/tests/test_helpers/test_async_utils.py
index c106cb595c..aba1ad6361 100644
--- a/tests/test_helpers/test_async_utils.py
+++ b/tests/test_helpers/test_async_utils.py
@@ -266,7 +266,7 @@ def test_no_loop_and_threded(self):
@pytest.mark.asyncio
async def test_runnable_async(self):
"""Test runnable async methods."""
-
+ # for pydocstyle
class TestRun(Runnable):
async def run(self):
while True:
@@ -275,42 +275,42 @@ async def run(self):
run = TestRun()
run.start()
run.stop()
- await run.wait()
+ await run.wait_completed()
run = TestRun(threaded=True)
run.start()
run.stop()
- run.wait(sync=True)
+ run.wait_completed(sync=True)
run = RunAndExit()
- await run.start_and_wait()
+ await run.start_and_wait_completed()
def test_runnable_sync(self):
"""Test runnable sync methods."""
run = RunAndExit()
- run.start_and_wait(sync=True)
+ run.start_and_wait_completed(sync=True)
@pytest.mark.asyncio
async def test_double_start(self):
"""Test runnable async methods."""
-
+ # for pydocstyle
class TestRun(Runnable):
async def run(self):
while True:
await asyncio.sleep(1)
run = TestRun()
- await run.wait()
+ await run.wait_completed()
assert run.start()
assert not run.start()
run.stop()
- await run.wait()
- await run.wait()
+ await run.wait_completed()
+ await run.wait_completed()
@pytest.mark.asyncio
async def test_run_in_thread(self):
"""Test runnable async methods."""
-
+ # for pydocstyle
class TestRun(Runnable):
async def run(self):
while True:
@@ -325,7 +325,7 @@ async def run(self):
@pytest.mark.asyncio
async def test_timeout(self):
"""Test runnable async methods."""
-
+ # for pydocstyle
class TestRun(Runnable):
async def run(self):
while True:
@@ -333,23 +333,24 @@ async def run(self):
run = TestRun(threaded=True)
run.start()
+ await asyncio.sleep(0.5)
with pytest.raises(asyncio.TimeoutError):
- run.wait(sync=True, timeout=0.1)
+ run.wait_completed(sync=True, timeout=1)
run.stop()
- run.wait(sync=True)
+ run.wait_completed(sync=True)
run = TestRun()
run.start()
with pytest.raises(asyncio.TimeoutError):
- await run.wait(timeout=0.1)
+ await run.wait_completed(timeout=1)
run.stop()
- await run.wait()
+ await run.wait_completed()
@pytest.mark.asyncio
async def test_exception(self):
"""Test runnable async methods."""
-
+ # for pydocstyle
class TestRun(Runnable):
async def run(self):
raise Exception("awaited")
@@ -357,31 +358,34 @@ async def run(self):
run = TestRun(threaded=True)
run.start()
with pytest.raises(Exception, match="awaited"):
- run.wait(sync=True, timeout=0.1)
+ run.wait_completed(sync=True, timeout=1)
run.stop()
- run.wait(sync=True)
+ run.wait_completed(sync=True)
run = TestRun()
run.start()
with pytest.raises(Exception, match="awaited"):
- await run.wait(timeout=0.1)
+ await run.wait_completed(timeout=1)
run.stop()
- await run.wait()
+ await run.wait_completed()
@pytest.mark.asyncio
async def test_wait_async_threaded(self):
"""Test runnable async methods."""
-
+ # for pydocstyle
class TestRun(Runnable):
async def run(self):
raise Exception("awaited")
run = TestRun(threaded=True)
run.start()
+ await asyncio.sleep(1)
+ assert run._task
+
with pytest.raises(Exception, match="awaited"):
- await run.wait(timeout=0.2)
+ await run.wait_completed(timeout=1)
run.stop()
- await run.wait()
+ await run.wait_completed()
diff --git a/tests/test_runtime.py b/tests/test_runtime.py
index 1a4608e9a3..d5481a17b6 100644
--- a/tests/test_runtime.py
+++ b/tests/test_runtime.py
@@ -50,15 +50,16 @@ def setup(self):
self.runtime = self.RUNTIME(self.agent, threaded=True)
def teardown(self):
+ """Tear down."""
self.runtime.stop()
- self.runtime.wait(sync=True)
+ self.runtime.wait_completed(sync=True)
def test_start_stop(self):
"""Test runtime tart/stop."""
self.runtime.start()
wait_for_condition(lambda: self.runtime.is_running, timeout=20)
self.runtime.stop()
- self.runtime.wait(sync=True)
+ self.runtime.wait_completed(sync=True)
def test_double_start(self):
"""Test runtime double start do nothing."""
@@ -71,11 +72,11 @@ def test_double_stop(self):
self.runtime.start()
wait_for_condition(lambda: self.runtime.is_running, timeout=20)
self.runtime.stop()
- self.runtime.wait(sync=True)
+ self.runtime.wait_completed(sync=True)
assert self.runtime.is_stopped
self.runtime.stop()
- self.runtime.wait(sync=True)
+ self.runtime.wait_completed(sync=True)
assert self.runtime.is_stopped
def test_error_state(self):
@@ -84,7 +85,7 @@ def test_error_state(self):
self.runtime, "_start_agent_loop", side_effect=ValueError("oops")
):
with pytest.raises(ValueError, match="oops"):
- self.runtime.start_and_wait(sync=True)
+ self.runtime.start_and_wait_completed(sync=True)
assert self.runtime.state == RuntimeStates.error, self.runtime.state
@@ -100,6 +101,6 @@ def test_error_state(self):
self.runtime.main_loop, "start", side_effect=ValueError("oops")
):
with pytest.raises(ValueError, match="oops"):
- self.runtime.start_and_wait(sync=True)
+ self.runtime.start_and_wait_completed(sync=True)
assert self.runtime.state == RuntimeStates.error, self.runtime.state
diff --git a/tests/test_skills/test_error.py b/tests/test_skills/test_error.py
index 70a1e7a358..926951face 100644
--- a/tests/test_skills/test_error.py
+++ b/tests/test_skills/test_error.py
@@ -188,7 +188,6 @@ def test_error_unsupported_skill(self):
msg = envelope.message
assert msg.performative == DefaultMessage.Performative.ERROR
assert msg.error_code == DefaultMessage.ErrorCode.UNSUPPORTED_SKILL
- print("\n1111111, STOP in TEST\n", flush=True)
def test_error_unsupported_skill_when_skill_id_is_none(self):
"""Test the 'send_unsupported_skill' when the skill id in the envelope is None."""
From aecd47ac9a3196a0aeb41c8778143b701645596c Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 14 Sep 2020 11:50:08 +0300
Subject: [PATCH 084/131] fixes
---
aea/agent.py | 2 +-
aea/launcher.py | 14 ++++----------
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/aea/agent.py b/aea/agent.py
index 6246e45451..920c4804f9 100644
--- a/aea/agent.py
+++ b/aea/agent.py
@@ -196,7 +196,7 @@ def start(self) -> None:
if was_started:
self.runtime.wait_completed(sync=True)
else:
- raise ValueError("Failed to start runtime! Ws it already started?")
+ raise ValueError("Failed to start runtime! Was it already started?")
def stop(self) -> None:
"""
diff --git a/aea/launcher.py b/aea/launcher.py
index cc6eaf0903..0bcbc5faa8 100644
--- a/aea/launcher.py
+++ b/aea/launcher.py
@@ -89,10 +89,8 @@ def _run_agent(
_set_logger(log_level=log_level)
agent = load_agent(agent_dir)
- on_stop = False
def stop_event_thread():
- nonlocal on_stop
try:
stop_event.wait()
except (KeyboardInterrupt, EOFError, BrokenPipeError) as e: # pragma: nocover
@@ -100,10 +98,8 @@ def stop_event_thread():
f"Exception raised in stop_event_thread {e} {type(e)}. Skip it, looks process is closed."
)
finally:
- if not on_stop:
- logger.debug("_run_agent: stop event raised. call agent.stop")
- on_stop = True
- agent.stop()
+ logger.debug("_run_agent: stop event raised. call agent.stop")
+ agent.runtime.stop()
Thread(target=stop_event_thread, daemon=True).start()
try:
@@ -116,10 +112,8 @@ def stop_event_thread():
exc.__traceback__ = e.__traceback__
raise exc
finally:
- if not on_stop:
- logger.debug("_run_agent: call agent.stop")
- on_stop = True
- agent.stop()
+ logger.debug("_run_agent: call agent.stop")
+ agent.stop()
class AEADirTask(AbstractExecutorTask):
From 1f33720f3be96890a40936f5eef88912cf570d9d Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 14 Sep 2020 19:37:28 +0300
Subject: [PATCH 085/131] fix for Runnable.wait_completed
---
aea/helpers/async_utils.py | 54 ++++++++++++++------------
tests/test_helpers/test_async_utils.py | 5 ++-
2 files changed, 34 insertions(+), 25 deletions(-)
diff --git a/aea/helpers/async_utils.py b/aea/helpers/async_utils.py
index 7ca18a6b7f..73b393f951 100644
--- a/aea/helpers/async_utils.py
+++ b/aea/helpers/async_utils.py
@@ -568,14 +568,34 @@ def wait_completed(
logger.warning("Already got result, skip")
return ready_future
- if self._task.done():
- self._got_result = True
- return self._task
-
if sync:
self._wait_sync(timeout)
return ready_future
+ return self._wait_async(timeout)
+
+ def _wait_sync(self, timeout: Optional[float] = None) -> None:
+ """Wait task completed in sync manner."""
+ if self._task is None:
+ raise ValueError("task is not set!")
+
+ if self._threaded or self._loop.is_running():
+ start_time = time.time()
+
+ while not self._task.done():
+ time.sleep(0.01)
+ if timeout is not None and time.time() - start_time > timeout:
+ raise asyncio.TimeoutError()
+
+ self._got_result = True
+ if self._task.exception():
+ raise self._task.exception()
+ else:
+ self._loop.run_until_complete(
+ asyncio.wait_for(self._wait(), timeout=timeout)
+ )
+
+ def _wait_async(self, timeout):
if not self._threaded:
return asyncio.wait_for(self._wait(), timeout=timeout)
@@ -594,29 +614,15 @@ def done(task):
finally:
self._got_result = True
- self._task.add_done_callback(
- lambda task: loop.call_soon_threadsafe(lambda: done(task))
- )
- return fut
-
- def _wait_sync(self, timeout: Optional[float] = None) -> None:
- """Wait task completed in sync manner."""
- if self._task is None:
- raise ValueError("task is not set!")
- if self._loop.is_running():
- start_time = time.time()
- while not self._task.done():
- time.sleep(0.01)
- if timeout is not None and time.time() - start_time > timeout:
- raise asyncio.TimeoutError()
- self._got_result = True
- if self._task.exception():
- raise self._task.exception()
+ if self._task.done():
+ done(self._task)
else:
- self._loop.run_until_complete(
- asyncio.wait_for(self._wait(), timeout=timeout)
+ self._task.add_done_callback(
+ lambda task: loop.call_soon_threadsafe(lambda: done(task))
)
+ return fut
+
async def _wait(self) -> None:
"""Wait internal method."""
if not self._task or not self._completed_event: # pragma: nocover
diff --git a/tests/test_helpers/test_async_utils.py b/tests/test_helpers/test_async_utils.py
index aba1ad6361..0cb3f2b843 100644
--- a/tests/test_helpers/test_async_utils.py
+++ b/tests/test_helpers/test_async_utils.py
@@ -351,12 +351,15 @@ async def run(self):
async def test_exception(self):
"""Test runnable async methods."""
# for pydocstyle
+ import time
+
class TestRun(Runnable):
async def run(self):
raise Exception("awaited")
run = TestRun(threaded=True)
run.start()
+ time.sleep(0.1)
with pytest.raises(Exception, match="awaited"):
run.wait_completed(sync=True, timeout=1)
@@ -381,7 +384,7 @@ async def run(self):
run = TestRun(threaded=True)
run.start()
- await asyncio.sleep(1)
+ await asyncio.sleep(0.4)
assert run._task
with pytest.raises(Exception, match="awaited"):
From a7539a895bf5798cfdc04a7bd714d5dbc59f18c5 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Thu, 17 Sep 2020 17:55:57 +0300
Subject: [PATCH 086/131] fixes
---
aea/runtime.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aea/runtime.py b/aea/runtime.py
index ea906653f7..d4781fe124 100644
--- a/aea/runtime.py
+++ b/aea/runtime.py
@@ -152,7 +152,7 @@ def _get_main_loop_class(self, loop_mode: str) -> Type[BaseAgentLoop]:
return self.RUN_LOOPS[loop_mode]
def _set_task(self):
- self._task = self._loop.create_task(self._run_wrapper(), name=self._agent.name)
+ self._task = self._loop.create_task(self._run_wrapper())
@property
def decision_maker(self) -> DecisionMaker:
From 6ec838c47ba5d195694514f58498c9babe717008 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 21 Sep 2020 10:40:18 +0300
Subject: [PATCH 087/131] multplexer fix for exception supression in receive
and send loops
---
aea/multiplexer.py | 58 +++++++++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index ec4896ba0a..252c6fab1a 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -291,19 +291,22 @@ async def disconnect(self) -> None:
async def _stop_receive_send_loops(self) -> None:
"""Stop receive and send loops."""
self.logger.debug("Stopping recv loop...")
+
if self._recv_loop_task:
self._recv_loop_task.cancel()
- with suppress(Exception):
+ with suppress(Exception, asyncio.CancelledError):
await self._recv_loop_task
+
self._recv_loop_task = None
self.logger.debug("Recv loop stopped.")
self.logger.debug("Stopping send loop...")
+
if self._send_loop_task:
# send a 'stop' token (a None value) to wake up the coroutine waiting for outgoing envelopes.
await self.out_queue.put(None)
self._send_loop_task.cancel()
- with suppress(Exception):
+ with suppress(Exception, asyncio.CancelledError):
await self._send_loop_task
self._send_loop_task = None
@@ -415,8 +418,8 @@ async def _send_loop(self) -> None:
)
return
- while self.is_connected:
- try:
+ try:
+ while self.is_connected:
self.logger.debug("Waiting for outgoing envelopes...")
envelope = await self.out_queue.get()
if envelope is None: # pragma: nocover
@@ -424,17 +427,18 @@ async def _send_loop(self) -> None:
"Received empty envelope. Quitting the sending loop..."
)
return None
-
self.logger.debug("Sending envelope {}".format(str(envelope)))
- await self._send(envelope)
- except asyncio.CancelledError:
- self.logger.debug("Sending loop cancelled.")
- return
- except AEAConnectionError as e:
- self.logger.error(str(e))
- except Exception as e: # pylint: disable=broad-except # pragma: nocover
- self.logger.error("Error in the sending loop: {}".format(str(e)))
- raise
+ try:
+ await self._send(envelope)
+ except AEAConnectionError as e:
+ self.logger.error(str(e))
+
+ except asyncio.CancelledError:
+ self.logger.debug("Sending loop cancelled.")
+ raise
+ except Exception as e: # pylint: disable=broad-except # pragma: nocover
+ self.logger.error("Error in the sending loop: {}".format(str(e)))
+ raise
async def _receiving_loop(self) -> None:
"""Process incoming envelopes."""
@@ -443,8 +447,8 @@ async def _receiving_loop(self) -> None:
asyncio.ensure_future(conn.receive()): conn for conn in self.connections
}
- while self.connection_status.is_connected and len(task_to_connection) > 0:
- try:
+ try:
+ while self.connection_status.is_connected and len(task_to_connection) > 0:
done, _pending = await asyncio.wait(
task_to_connection.keys(), return_when=asyncio.FIRST_COMPLETED
)
@@ -461,17 +465,17 @@ async def _receiving_loop(self) -> None:
new_task = asyncio.ensure_future(connection.receive())
task_to_connection[new_task] = connection
- except asyncio.CancelledError: # pragma: nocover
- self.logger.debug("Receiving loop cancelled.")
- break
- except Exception as e: # pylint: disable=broad-except
- self.logger.exception("Error in the receiving loop: {}".format(str(e)))
- break
-
- # cancel all the receiving tasks.
- for t in task_to_connection.keys():
- t.cancel()
- self.logger.debug("Receiving loop terminated.")
+ except asyncio.CancelledError: # pragma: nocover
+ self.logger.debug("Receiving loop cancelled.")
+ raise
+ except Exception as e: # pylint: disable=broad-except
+ self.logger.exception("Error in the receiving loop: {}".format(str(e)))
+ raise
+ finally:
+ # cancel all the receiving tasks.
+ for t in task_to_connection.keys():
+ t.cancel()
+ self.logger.debug("Receiving loop terminated.")
async def _send(self, envelope: Envelope) -> None:
"""
From 57e16a240d2c9159b1977d4f263df5b5ab84384b Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Fri, 25 Sep 2020 13:19:52 +0300
Subject: [PATCH 088/131] mac os fix
---
aea/launcher.py | 9 +++++++++
aea/multiplexer.py | 6 +-----
tests/test_runtime.py | 1 -
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/aea/launcher.py b/aea/launcher.py
index 0bcbc5faa8..a8927e494e 100644
--- a/aea/launcher.py
+++ b/aea/launcher.py
@@ -86,6 +86,15 @@ def _run_agent(
:return: None
"""
+ import asyncio # pylint: disable=import-outside-toplevel
+ import select # pylint: disable=import-outside-toplevel
+ import selectors # pylint: disable=import-outside-toplevel
+
+ if hasattr(select, "kqueue"):
+ selector = selectors.SelectSelector()
+ loop = asyncio.SelectorEventLoop(selector) # type: ignore
+ asyncio.set_event_loop(loop)
+
_set_logger(log_level=log_level)
agent = load_agent(agent_dir)
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index 252c6fab1a..de24c957d1 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -29,11 +29,7 @@
from aea.connections.base import Connection, ConnectionStates
from aea.exceptions import enforce
from aea.helpers.async_friendly_queue import AsyncFriendlyQueue
-from aea.helpers.async_utils import (
- AsyncState,
- Runnable,
- ThreadedAsyncRunner,
-)
+from aea.helpers.async_utils import AsyncState, Runnable, ThreadedAsyncRunner
from aea.helpers.exception_policy import ExceptionPolicyEnum
from aea.helpers.logging import WithLogger
from aea.mail.base import AEAConnectionError, Empty, Envelope, EnvelopeContext
diff --git a/tests/test_runtime.py b/tests/test_runtime.py
index d5481a17b6..9f754bddf9 100644
--- a/tests/test_runtime.py
+++ b/tests/test_runtime.py
@@ -29,7 +29,6 @@
from aea.runtime import AsyncRuntime, BaseRuntime, RuntimeStates, ThreadedRuntime
from tests.common.utils import wait_for_condition
-
from tests.conftest import CUR_PATH
From 1599dcc4ef1af4f88e9f0b9295542c7a70839204 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 28 Sep 2020 11:32:04 +0300
Subject: [PATCH 089/131] coverage fixes
---
aea/agent_loop.py | 2 +-
aea/helpers/async_utils.py | 6 +++---
aea/launcher.py | 2 +-
aea/multiplexer.py | 1 +
tests/test_agent_loop.py | 14 ++++++++++++++
tests/test_helpers/test_async_utils.py | 11 +++++++++++
tests/test_multiplexer.py | 12 ++++++++++++
7 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/aea/agent_loop.py b/aea/agent_loop.py
index dd02d1eca3..8de41f5f86 100644
--- a/aea/agent_loop.py
+++ b/aea/agent_loop.py
@@ -80,7 +80,7 @@ def __init__(
self._agent: AbstractAgent = agent
self._tasks: List[asyncio.Task] = []
- self._state: AsyncState = AsyncState()
+ self._state: AsyncState = AsyncState(AgentLoopStates.initial)
self._exceptions: List[Exception] = []
@property
diff --git a/aea/helpers/async_utils.py b/aea/helpers/async_utils.py
index 73b393f951..58c61314f8 100644
--- a/aea/helpers/async_utils.py
+++ b/aea/helpers/async_utils.py
@@ -530,7 +530,7 @@ def _set_task(self) -> None:
async def _run_wrapper(self) -> None:
"""Wrap run() method."""
- if not self._completed_event:
+ if not self._completed_event: # pragma: nocover
raise ValueError("Start was not called!")
try:
@@ -540,7 +540,7 @@ async def _run_wrapper(self) -> None:
self._loop.call_soon_threadsafe(self._completed_event.set)
@property
- def is_running(self) -> bool:
+ def is_running(self) -> bool: # pragma: nocover
"""Get running state."""
return self._is_running
@@ -576,7 +576,7 @@ def wait_completed(
def _wait_sync(self, timeout: Optional[float] = None) -> None:
"""Wait task completed in sync manner."""
- if self._task is None:
+ if self._task is None: # pragma: nocover
raise ValueError("task is not set!")
if self._threaded or self._loop.is_running():
diff --git a/aea/launcher.py b/aea/launcher.py
index a8927e494e..7f1198b21e 100644
--- a/aea/launcher.py
+++ b/aea/launcher.py
@@ -90,7 +90,7 @@ def _run_agent(
import select # pylint: disable=import-outside-toplevel
import selectors # pylint: disable=import-outside-toplevel
- if hasattr(select, "kqueue"):
+ if hasattr(select, "kqueue"): # pragma: nocover # cause platform specific
selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector) # type: ignore
asyncio.set_event_loop(loop)
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index de24c957d1..e4923995cd 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -114,6 +114,7 @@ async def run(self) -> None:
self.set_loop(asyncio.get_event_loop())
try:
await self.connect()
+
if not self._recv_loop_task or not self._send_loop_task:
raise ValueError("Multiplexer is not connected properly.")
diff --git a/tests/test_agent_loop.py b/tests/test_agent_loop.py
index 641f6537d4..aa6bd5482d 100644
--- a/tests/test_agent_loop.py
+++ b/tests/test_agent_loop.py
@@ -208,6 +208,20 @@ def test_loop_start_stop(self):
agent_loop.wait_completed(sync=True)
assert not agent_loop.is_running, agent_loop.state
+ def test_set_loop(self):
+ """Test set loop."""
+ agent_loop = self.AGENT_LOOP_CLASS(self.FAKE_AGENT_CLASS())
+
+ loop = asyncio.new_event_loop()
+ agent_loop.set_loop(loop=loop)
+ assert agent_loop._loop == loop
+
+ def test_state_property(self):
+ """Test state property."""
+ agent_loop = self.AGENT_LOOP_CLASS(self.FAKE_AGENT_CLASS())
+
+ assert agent_loop.state == AgentLoopStates.initial
+
def test_handle_envelope(self):
"""Test one envelope handling."""
handler = CountHandler.make()
diff --git a/tests/test_helpers/test_async_utils.py b/tests/test_helpers/test_async_utils.py
index 0cb3f2b843..b5ee1e636c 100644
--- a/tests/test_helpers/test_async_utils.py
+++ b/tests/test_helpers/test_async_utils.py
@@ -263,6 +263,17 @@ def test_no_loop_and_threded(self):
with pytest.raises(ValueError,):
RunAndExit(loop=asyncio.get_event_loop(), threaded=True)
+ def test_task_cancel_not_set(self):
+ """Test task cancel."""
+
+ class TestRun(Runnable):
+ async def run(self):
+ while True:
+ await asyncio.sleep(1)
+
+ run = TestRun()
+ run._task_cancel()
+
@pytest.mark.asyncio
async def test_runnable_async(self):
"""Test runnable async methods."""
diff --git a/tests/test_multiplexer.py b/tests/test_multiplexer.py
index e6129619a4..85fbf8c415 100644
--- a/tests/test_multiplexer.py
+++ b/tests/test_multiplexer.py
@@ -134,6 +134,18 @@ async def test_connect_twice_a_single_connection():
await multiplexer._disconnect_one(connection.connection_id)
+@pytest.mark.asyncio
+async def test_run_bad_conneect():
+ """Test that connecting twice a single connection behaves correctly."""
+ connection = _make_dummy_connection()
+ multiplexer = AsyncMultiplexer([connection])
+ f = asyncio.Future()
+ f.set_result(None)
+ with unittest.mock.patch.object(multiplexer, "connect", return_value=f):
+ with pytest.raises(ValueError, match="Multiplexer is not connected properly."):
+ await multiplexer.run()
+
+
def test_multiplexer_connect_all_raises_error():
"""Test the case when the multiplexer raises an exception while connecting."""
multiplexer = Multiplexer([_make_dummy_connection()])
From 58c5a0332759a0fe40673a528d6fae66184a89f9 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 28 Sep 2020 12:37:18 +0300
Subject: [PATCH 090/131] fixes
---
aea/aea.py | 6 ++---
aea/agent.py | 4 +++-
aea/agent_loop.py | 8 +++----
aea/helpers/async_utils.py | 32 +++++++++++++++++---------
aea/multiplexer.py | 1 -
aea/runtime.py | 27 +++++++++++++++-------
tests/test_aea.py | 10 ++++----
tests/test_helpers/test_async_utils.py | 2 +-
8 files changed, 55 insertions(+), 35 deletions(-)
diff --git a/aea/aea.py b/aea/aea.py
index 63086fdd02..be8265b06e 100644
--- a/aea/aea.py
+++ b/aea/aea.py
@@ -55,7 +55,7 @@
from aea.protocols.default.message import DefaultMessage
from aea.registries.filter import Filter
from aea.registries.resources import Resources
-from aea.runtime import StopRuntime
+from aea.runtime import _StopRuntime
from aea.skills.base import Behaviour, Handler
from aea.skills.error.handlers import ErrorHandler
@@ -242,7 +242,7 @@ def _get_msg_and_handlers_for_envelope(
if error_handler is None:
self.logger.warning("ErrorHandler not initialized. Stopping AEA!")
- raise StopRuntime()
+ raise _StopRuntime()
error_handler = cast(ErrorHandler, error_handler)
@@ -364,7 +364,7 @@ def log_exception(e, fn):
if self._skills_exception_policy == ExceptionPolicyEnum.stop_and_exit:
log_exception(exception, function)
- raise StopRuntime(
+ raise _StopRuntime(
AEAException(
f"AEA was terminated cause exception `{exception}` in skills {function}! Please check logs."
)
diff --git a/aea/agent.py b/aea/agent.py
index 920c4804f9..ac15fa6cfb 100644
--- a/aea/agent.py
+++ b/aea/agent.py
@@ -16,6 +16,7 @@
# limitations under the License.
#
# ------------------------------------------------------------------------------
+
"""This module contains the implementation of a generic agent."""
import datetime
import logging
@@ -24,6 +25,7 @@
from aea.abstract_agent import AbstractAgent
from aea.connections.base import Connection
+from aea.exceptions import AEAException
from aea.identity.base import Identity
from aea.mail.base import Envelope
from aea.multiplexer import InBox, OutBox
@@ -196,7 +198,7 @@ def start(self) -> None:
if was_started:
self.runtime.wait_completed(sync=True)
else:
- raise ValueError("Failed to start runtime! Was it already started?")
+ raise AEAException("Failed to start runtime! Was it already started?")
def stop(self) -> None:
"""
diff --git a/aea/agent_loop.py b/aea/agent_loop.py
index 8de41f5f86..2285f02451 100644
--- a/aea/agent_loop.py
+++ b/aea/agent_loop.py
@@ -92,12 +92,12 @@ def set_loop(self, loop: AbstractEventLoop) -> None:
"""Set event loop and all event loopp related objects."""
self._loop: AbstractEventLoop = loop
- def setup(self) -> None: # pylint: disable=no-self-use
+ def _setup(self) -> None: # pylint: disable=no-self-use
"""Set up loop before started."""
# start and stop methods are classmethods cause one instance shared across muiltiple threads
ExecTimeoutThreadGuard.start()
- def teardown(self): # pylint: disable=no-self-use
+ def _teardown(self): # pylint: disable=no-self-use
"""Tear down loop on stop."""
# start and stop methods are classmethods cause one instance shared across muiltiple threads
ExecTimeoutThreadGuard.stop()
@@ -106,7 +106,7 @@ async def run(self) -> None:
"""Run agent loop."""
self.logger.debug("agent loop started")
self._state.set(AgentLoopStates.starting)
- self.setup()
+ self._setup()
self._set_tasks()
try:
await self._gather_tasks()
@@ -117,7 +117,7 @@ async def run(self) -> None:
async def _stop(self) -> None:
"""Stop and cleanup."""
- self.teardown()
+ self._teardown()
self._stop_tasks()
for t in self._tasks:
with suppress(BaseException):
diff --git a/aea/helpers/async_utils.py b/aea/helpers/async_utils.py
index 58c61314f8..54022720c1 100644
--- a/aea/helpers/async_utils.py
+++ b/aea/helpers/async_utils.py
@@ -465,9 +465,17 @@ def __init__(self, getters: List[Tuple[Callable[[Any], None], Callable]]):
class Runnable(ABC):
- """Abstract Runnable class."""
+ """
+ Abstract Runnable class.
+
+ Use to run async task in same event loop or in dedicated thread.
+ Provides: start, stop sync methods to start and stop task
+ Use wait_completed to await task was completed.
+ """
- def __init__(self, loop=None, threaded=False) -> None:
+ def __init__(
+ self, loop: asyncio.AbstractEventLoop = None, threaded: bool = False
+ ) -> None:
"""
Init runnable.
@@ -496,8 +504,9 @@ def start(self) -> bool:
:return: bool started or not.
"""
if self._task and not self._task.done():
- logger.debug("already running")
+ logger.debug(f"{self} already running")
return False
+
self._is_running = False
self._got_result = False
self._set_loop()
@@ -507,7 +516,7 @@ def start(self) -> bool:
if self._threaded:
self._thread = Thread(
- target=self._loop.run_until_complete, args=[self._task]
+ target=self._loop.run_until_complete, args=[self._task] # type: ignore # loop was set in set_loop
)
self._thread.start()
@@ -526,11 +535,13 @@ def _set_loop(self) -> None:
def _set_task(self) -> None:
"""Create task."""
+ if not self._loop: # pragma: nocover
+ raise ValueError("Loop was not set.")
self._task = self._loop.create_task(self._run_wrapper())
async def _run_wrapper(self) -> None:
"""Wrap run() method."""
- if not self._completed_event: # pragma: nocover
+ if not self._completed_event or not self._loop: # pragma: nocover
raise ValueError("Start was not called!")
try:
@@ -561,11 +572,10 @@ def wait_completed(
:return: awaitable if sync is False, otherise None
"""
if not self._task:
- logger.warning("Runnable is not no started")
+ logger.warning("Runnable is not started")
return ready_future
if self._got_result and not force_result:
- logger.warning("Already got result, skip")
return ready_future
if sync:
@@ -576,7 +586,7 @@ def wait_completed(
def _wait_sync(self, timeout: Optional[float] = None) -> None:
"""Wait task completed in sync manner."""
- if self._task is None: # pragma: nocover
+ if self._task is None or not self._loop: # pragma: nocover
raise ValueError("task is not set!")
if self._threaded or self._loop.is_running():
@@ -638,12 +648,12 @@ async def _wait(self) -> None:
def stop(self, force: bool = False) -> None:
"""Stop runnable."""
logger.debug(f"{self} is going to be stopped {self._task}")
- if not self._task:
- logger.debug("not running!")
+ if not self._task or not self._loop:
return
+
if self._task.done():
- logger.debug("already completed")
return
+
self._loop.call_soon_threadsafe(self._task_cancel, force)
def _task_cancel(self, force: bool = False) -> None:
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index e4923995cd..d604b1e1f0 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -88,7 +88,6 @@ def __init__(
: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.
"""
- super().__init__(default_logger)
self._exception_policy: ExceptionPolicyEnum = exception_policy
WithLogger.__init__(self, default_logger)
Runnable.__init__(self, loop=loop, threaded=threaded)
diff --git a/aea/runtime.py b/aea/runtime.py
index d4781fe124..04e70e1ed9 100644
--- a/aea/runtime.py
+++ b/aea/runtime.py
@@ -41,12 +41,17 @@
logger = logging.getLogger(__name__)
-class StopRuntime(Exception):
- """Exception to stop runtime."""
+class _StopRuntime(Exception):
+ """
+ Exception to stop runtime.
+
+ For internal usage only!
+ Used to perform asyncio call from sync callbacks.
+ """
def __init__(self, reraise: Optional[Exception] = None):
"""
- Init StopRuntime exception.
+ Init _StopRuntime exception.
:param reraise: exception to reraise.
@@ -119,7 +124,7 @@ def task_manager(self) -> TaskManager:
return self._task_manager
@property
- def loop(self) -> AbstractEventLoop:
+ def loop(self) -> Optional[AbstractEventLoop]:
"""Get event loop."""
return self._loop
@@ -250,11 +255,15 @@ def set_loop(self, loop: AbstractEventLoop) -> None:
BaseRuntime.set_loop(self, loop)
async def run(self) -> None:
- """Start multiplexeor task."""
+ """
+ Start runtime task.
+
+ Starts multiplexer and agent loop.
+ """
terminal_state = RuntimeStates.error
try:
await self.run_runtime()
- except StopRuntime as e:
+ except _StopRuntime as e:
self._state.set(RuntimeStates.stopping)
terminal_state = RuntimeStates.stopped
if e.reraise:
@@ -271,11 +280,11 @@ async def stop_runtime(self) -> None:
Stop runtime coroutine.
Stop main loop.
- Agent teardown.
+ Tear down the agent..
Disconnect multiplexer.
"""
self.main_loop.stop()
- with suppress(StopRuntime):
+ with suppress(_StopRuntime):
await self.main_loop.wait_completed()
self._teardown()
@@ -291,6 +300,8 @@ async def run_runtime(self) -> None:
async def _start_multiplexer(self) -> None:
"""Call multiplexer connect asynchronous way."""
self.setup_multiplexer()
+ if not self._loop:
+ raise ValueError("no loop is set for runtime.")
self.multiplexer.set_loop(self._loop)
self.multiplexer.start()
await self.multiplexer.wait_completed()
diff --git a/tests/test_aea.py b/tests/test_aea.py
index a4108c8c3e..afaca49536 100644
--- a/tests/test_aea.py
+++ b/tests/test_aea.py
@@ -43,7 +43,7 @@
from aea.protocols.default.message import DefaultMessage
from aea.protocols.default.serialization import DefaultSerializer
from aea.registries.resources import Resources
-from aea.runtime import RuntimeStates, StopRuntime
+from aea.runtime import RuntimeStates, _StopRuntime
from aea.skills.base import Skill, SkillContext
from packages.fetchai.connections.local.connection import LocalNode
@@ -184,9 +184,7 @@ def test_react():
with run_in_thread(agent.start, timeout=20, on_exit=agent.stop):
wait_for_condition(lambda: agent.is_running, timeout=20)
- time.sleep(1)
agent.outbox.put(envelope)
- print("111 msg put", flush=True)
default_protocol_public_id = DefaultMessage.protocol_id
dummy_skill_public_id = DUMMY_SKILL_PUBLIC_ID
handler = agent.resources.get_handler(
@@ -534,7 +532,7 @@ def test_error_handler_is_not_set():
message=msg,
)
- with pytest.raises(StopRuntime):
+ with pytest.raises(_StopRuntime):
agent.handle_envelope(envelope)
@@ -809,7 +807,7 @@ def setUpClass(cls) -> None:
def tearDown(self) -> None:
"""Tear down."""
self.aea_tool.teardown()
- self.aea_tool.aea.runtime.main_loop.teardown()
+ self.aea_tool.aea.runtime.main_loop._teardown()
def prepare(self, function: Callable) -> None:
"""Prepare aea_tool for testing.
@@ -848,7 +846,7 @@ def handler_func(*args, **kwargs):
aea = builder.build()
self.aea_tool = AeaTool(aea)
self.envelope = AeaTool.dummy_envelope()
- self.aea_tool.aea.runtime.main_loop.setup()
+ self.aea_tool.aea.runtime.main_loop._setup()
def test_long_handler_cancelled_by_timeout(self):
"""Test long function terminated by timeout."""
diff --git a/tests/test_helpers/test_async_utils.py b/tests/test_helpers/test_async_utils.py
index b5ee1e636c..6264b21e13 100644
--- a/tests/test_helpers/test_async_utils.py
+++ b/tests/test_helpers/test_async_utils.py
@@ -320,7 +320,7 @@ async def run(self):
@pytest.mark.asyncio
async def test_run_in_thread(self):
- """Test runnable async methods."""
+ """Test runnable in thread mode."""
# for pydocstyle
class TestRun(Runnable):
async def run(self):
From 7403f5a6f0eb6737f98f2106197c83188d277a13 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 22 Sep 2020 11:33:48 +0300
Subject: [PATCH 091/131] agents manager interface
---
aea/manager.py | 151 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 151 insertions(+)
create mode 100644 aea/manager.py
diff --git a/aea/manager.py b/aea/manager.py
new file mode 100644
index 0000000000..bbb289d858
--- /dev/null
+++ b/aea/manager.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+# ------------------------------------------------------------------------------
+#
+# Copyright 2018-2020 Fetch.AI Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ------------------------------------------------------------------------------
+"""This module contains the implementation of AEA agents manager."""
+from abc import ABC, abstractmethod
+from typing import Dict, List
+
+from aea.aea_builder import PathLike
+from aea.configurations.base import PublicId
+
+
+class AbstractManager(ABC):
+ """Abstract agents manager."""
+
+ def __init__(self, working_dir: PathLike) -> None:
+ """
+ Initialize manager.
+
+ :param working_dir: directory to store base agents.
+ """
+ self.working_dir = working_dir
+
+ @abstractmethod
+ def start_manager(self) -> None:
+ """Start manager."""
+
+ @abstractmethod
+ def stop_manager(self, cleanup: bool = False) -> None:
+ """
+ Stop manager.
+
+ Stops all running agents and stop agent.
+
+ :param cleanup: remove agents_dir and purge in memory registry.
+
+ :return: None
+ """
+
+ @abstractmethod
+ def add_project(self, public_id: PublicId) -> None:
+ """Fetch agent project and all dependencies to working_dir."""
+
+ @abstractmethod
+ def remove_project(self, public_id: PublicId) -> None:
+ """Remove agent project."""
+
+ @abstractmethod
+ def list_projects(self) -> List[PublicId]:
+ """
+ List all agents projects added.
+
+ :return: lit of public ids of projects
+ """
+
+ @abstractmethod
+ def add_agent(
+ self, project_id: PublicId, agent_name: str, config_overrides: Dict
+ ) -> None:
+ """
+ Create new agent configuration based on project with config overrides applied.
+
+ Alias is stored in memory only!
+
+ :param project_id: base agent public id
+ :param agent_name: unique name for the agent
+ :param config_overrides: overrides for component section.
+
+ :return: None
+ """
+
+ @abstractmethod
+ def list_agents(self, running_only: bool = False) -> List[str]:
+ """
+ List all agents.
+
+ :param running_only: returns only running if set to True
+
+ :return: list of agents names
+ """
+
+ @abstractmethod
+ def remove_agent(self, agent_name: str) -> None:
+ """
+ Remove agent alias definition from registry.
+
+ :param agent_name: agent name to remove
+
+ :return: None
+ """
+
+ @abstractmethod
+ def start_agent(self, agent_name: str) -> None:
+ """
+ Start selected agent.
+
+ :param agent_name: agent name to start
+
+ :return: None
+ """
+
+ @abstractmethod
+ def start_all_agents(self) -> None:
+ """
+ Start all not started agents.
+
+ :return: None
+ """
+
+ @abstractmethod
+ def stop_agent(self, agent_name: str) -> None:
+ """
+ Stop running agent.
+
+ :param agent_name: agent name to stop
+
+ :return: None
+ """
+
+ @abstractmethod
+ def stop_all_agents(self) -> None:
+ """
+ Stop all agents running.
+
+ :return: None
+ """
+
+ @abstractmethod
+ def get_agent_details(self, agent_name: str) -> dict:
+ """
+ Return details about agent definition.
+
+ {
+ "project": str
+ "overrides": dict
+ }
+ """
From 02bcb67e55bb693d9eb9af941c146a8dba7abd6c Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Thu, 24 Sep 2020 10:22:20 +0300
Subject: [PATCH 092/131] aea.Manager: projects handling, agent alias creation
---
aea/aea_builder.py | 25 +++-
aea/cli/registry/fetch.py | 19 ++-
aea/configurations/loader.py | 10 +-
aea/manager.py | 228 ++++++++++++++++++++++++++++++-----
tests/test_manager.py | 107 ++++++++++++++++
5 files changed, 348 insertions(+), 41 deletions(-)
create mode 100644 tests/test_manager.py
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index ee5b77abe8..54e89d1642 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -292,6 +292,8 @@ class AEABuilder:
DEFAULT_RUNTIME_MODE = "threaded"
DEFAULT_SEARCH_SERVICE_ADDRESS = "fetchai/soef:*"
+ loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
+
# pylint: disable=attribute-defined-outside-init
def __init__(self, with_default_packages: bool = True):
@@ -1336,16 +1338,33 @@ def from_aea_project(
builder = AEABuilder(with_default_packages=False)
# load agent configuration file
- configuration_file = aea_project_path / DEFAULT_AEA_CONFIG_FILE
+ configuration_file = cls.get_configuration_file_path(aea_project_path)
+ agent_configuration = cls.loader.load(configuration_file.open())
- loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
- agent_configuration = loader.load(configuration_file.open())
+ builder.set_from_configuration(
+ agent_configuration, aea_project_path, skip_consistency_check
+ )
+ return builder
+
+ @classmethod
+ def from_config_json(
+ cls, json_data, aea_project_path: PathLike, skip_consistency_check: bool = False
+ ):
+ aea_project_path = Path(aea_project_path)
+ builder = AEABuilder(with_default_packages=False)
+
+ # load agent configuration file
+ agent_configuration = cls.loader._load_agent_config_from_json(json_data)
builder.set_from_configuration(
agent_configuration, aea_project_path, skip_consistency_check
)
return builder
+ @staticmethod
+ def get_configuration_file_path(aea_project_path):
+ return Path(aea_project_path) / DEFAULT_AEA_CONFIG_FILE
+
def _load_and_add_components(
self,
component_type: ComponentType,
diff --git a/aea/cli/registry/fetch.py b/aea/cli/registry/fetch.py
index 8efdd4e051..cf0270c391 100644
--- a/aea/cli/registry/fetch.py
+++ b/aea/cli/registry/fetch.py
@@ -16,6 +16,9 @@
# limitations under the License.
#
# ------------------------------------------------------------------------------
+from aea.helpers.base import cd
+import shutil
+
"""Methods for CLI fetch functionality."""
import os
@@ -32,7 +35,12 @@
@clean_after
-def fetch_agent(ctx: Context, public_id: PublicId, alias: Optional[str] = None) -> None:
+def fetch_agent(
+ ctx: Context,
+ public_id: PublicId,
+ alias: Optional[str] = None,
+ dir: Optional[str] = None,
+) -> None:
"""
Fetch Agent from Registry.
@@ -49,14 +57,17 @@ def fetch_agent(ctx: Context, public_id: PublicId, alias: Optional[str] = None)
filepath = download_file(file_url, ctx.cwd)
- folder_name = name if alias is None else alias
+ folder_name = dir or (name if alias is None else alias)
aea_folder = os.path.join(ctx.cwd, folder_name)
+ print(aea_folder)
ctx.clean_paths.append(aea_folder)
extract(filepath, ctx.cwd)
- if alias is not None:
- os.rename(name, alias)
+ if alias or dir:
+ shutil.move(
+ os.path.join(ctx.cwd, name), aea_folder,
+ )
ctx.cwd = aea_folder
try_to_load_agent_config(ctx)
diff --git a/aea/configurations/loader.py b/aea/configurations/loader.py
index 8a5c1e84d0..4956406c95 100644
--- a/aea/configurations/loader.py
+++ b/aea/configurations/loader.py
@@ -229,10 +229,7 @@ def _load_from_json(self, configuration_file_json: Dict) -> T:
configuration_obj._key_order = key_order # pylint: disable=protected-access
return configuration_obj
- def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
- """Load an agent configuration."""
- configuration_file_jsons = yaml_load_all(file_pointer)
-
+ def _load_agent_config_from_json(self, configuration_file_jsons) -> AgentConfig:
if len(configuration_file_jsons) == 0:
raise ValueError("Agent configuration file was empty.")
agent_config_json = configuration_file_jsons[0]
@@ -260,6 +257,11 @@ def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
agent_configuration_obj.component_configurations = component_configurations
return agent_configuration_obj
+ def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
+ """Load an agent configuration."""
+ configuration_file_jsons = yaml_load_all(file_pointer)
+ return self._load_agent_config_from_json(configuration_file_jsons)
+
def _dump_agent_config(
self, configuration: AgentConfig, file_pointer: TextIO
) -> None:
diff --git a/aea/manager.py b/aea/manager.py
index bbb289d858..643543597f 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -17,29 +17,82 @@
#
# ------------------------------------------------------------------------------
"""This module contains the implementation of AEA agents manager."""
-from abc import ABC, abstractmethod
-from typing import Dict, List
-
-from aea.aea_builder import PathLike
-from aea.configurations.base import PublicId
-
-
-class AbstractManager(ABC):
+import copy
+import os
+from shutil import rmtree
+from typing import Dict, List, Optional, Set
+
+from aea.aea import AEA
+from aea.aea_builder import AEABuilder
+from aea.cli.registry.fetch import fetch_agent
+from aea.cli.utils.context import Context
+from aea.configurations.base import ComponentId, PublicId
+from aea.configurations.constants import DEFAULT_LEDGER
+from aea.crypto.helpers import create_private_key
+from aea.helpers.base import yaml_load_all
+
+
+class Project:
+ """Agent project representation."""
+
+ def __init__(self, public_id: PublicId, path: str):
+ """Init project with public_id and project's path."""
+ self.public_id = public_id
+ self.path = path
+ self.agents: Set[str] = set()
+
+ @classmethod
+ def load(cls, working_dir, public_id) -> "Project":
+ """Load project with given pubblic_id to working_dir."""
+ ctx = Context(cwd=working_dir)
+ path = os.path.join(working_dir, public_id.author, public_id.name)
+ fetch_agent(ctx, public_id, dir=os.path.join(public_id.author, public_id.name))
+ return cls(public_id, path)
+
+ def remove(self):
+ """Remove project, do cleanup."""
+ rmtree(self.path)
+
+
+class AgentAlias:
+ """Agent alias representation."""
+
+ def __init__(self, project: Project, name: str, config: List[Dict], agent: AEA):
+ """Init agent alias with project, config, name, agent."""
+ self.project = project
+ self.config = config
+ self.name = name
+ self.agent = agent
+ self.project.agents.add(self.name)
+
+ def remove(self):
+ """Remove agent alias from project."""
+ self.project.agents.remove(self.name)
+
+
+class Manager:
"""Abstract agents manager."""
- def __init__(self, working_dir: PathLike) -> None:
+ AGENT_DO_NOT_OVERRIDE_VALUES = ["skills", "connections", "protocols", "contracts"]
+
+ def __init__(self, working_dir: str) -> None:
"""
Initialize manager.
:param working_dir: directory to store base agents.
"""
self.working_dir = working_dir
+ self._was_working_dir_created = False
+ self.is_started = False
+ self._projects: Dict[PublicId, Project] = {}
+ self._keys_dir = os.path.abspath(os.path.join(self.working_dir, "keys"))
+ self._agents: Dict[str, AgentAlias] = {}
- @abstractmethod
def start_manager(self) -> None:
"""Start manager."""
+ self._ensure_working_dir()
+ self.is_started = True
- @abstractmethod
def stop_manager(self, cleanup: bool = False) -> None:
"""
Stop manager.
@@ -50,40 +103,66 @@ def stop_manager(self, cleanup: bool = False) -> None:
:return: None
"""
+ if self._was_working_dir_created:
+ rmtree(self.working_dir)
+
+ self.is_started = False
- @abstractmethod
def add_project(self, public_id: PublicId) -> None:
"""Fetch agent project and all dependencies to working_dir."""
+ if public_id in self._projects:
+ raise ValueError(f"Project {public_id} was already added!")
+ self._projects[public_id] = Project.load(self.working_dir, public_id)
- @abstractmethod
def remove_project(self, public_id: PublicId) -> None:
"""Remove agent project."""
+ if public_id not in self._projects:
+ raise ValueError(f"Project {public_id} was not added!")
+
+ self._projects.pop(public_id).remove()
- @abstractmethod
def list_projects(self) -> List[PublicId]:
"""
List all agents projects added.
:return: lit of public ids of projects
"""
+ return list(self._projects.keys())
- @abstractmethod
def add_agent(
- self, project_id: PublicId, agent_name: str, config_overrides: Dict
+ self,
+ public_id: PublicId,
+ agent_name: str,
+ agent_overrides: Optional[dict] = None,
+ component_overrides: Optional[List[dict]] = None,
) -> None:
"""
Create new agent configuration based on project with config overrides applied.
Alias is stored in memory only!
- :param project_id: base agent public id
+ :param public_id: base agent project public id
:param agent_name: unique name for the agent
- :param config_overrides: overrides for component section.
+ :param agent_overrides: overrides for agent config.
+ :param component_overrides: overrides for component section.
:return: None
"""
+ if agent_name in self._agents:
+ raise ValueError(f"Agent with name {agent_name} already exists!")
+
+ if public_id not in self._projects:
+ raise ValueError(f"{public_id} project is not added!")
+ project = self._projects[public_id]
+
+ agent_alias = self._build_agent_alias(
+ project=project,
+ agent_name=agent_name,
+ agent_overrides=agent_overrides,
+ component_overrides=component_overrides,
+ )
+ self._agents[agent_name] = agent_alias
- @abstractmethod
def list_agents(self, running_only: bool = False) -> List[str]:
"""
List all agents.
@@ -92,8 +171,8 @@ def list_agents(self, running_only: bool = False) -> List[str]:
:return: list of agents names
"""
+ return list(self._agents.keys())
- @abstractmethod
def remove_agent(self, agent_name: str) -> None:
"""
Remove agent alias definition from registry.
@@ -102,8 +181,12 @@ def remove_agent(self, agent_name: str) -> None:
:return: None
"""
+ if agent_name not in self._agents:
+ raise ValueError(f"Agent with name {agent_name} does not exist!")
+
+ agent_alias = self._agents.pop(agent_name)
+ agent_alias.remove()
- @abstractmethod
def start_agent(self, agent_name: str) -> None:
"""
Start selected agent.
@@ -113,7 +196,6 @@ def start_agent(self, agent_name: str) -> None:
:return: None
"""
- @abstractmethod
def start_all_agents(self) -> None:
"""
Start all not started agents.
@@ -121,7 +203,6 @@ def start_all_agents(self) -> None:
:return: None
"""
- @abstractmethod
def stop_agent(self, agent_name: str) -> None:
"""
Stop running agent.
@@ -131,7 +212,6 @@ def stop_agent(self, agent_name: str) -> None:
:return: None
"""
- @abstractmethod
def stop_all_agents(self) -> None:
"""
Stop all agents running.
@@ -139,13 +219,101 @@ def stop_all_agents(self) -> None:
:return: None
"""
- @abstractmethod
- def get_agent_details(self, agent_name: str) -> dict:
+ def stop_agents(self, agent_names: List[str]) -> None:
+ """
+ Stop specified agents.
+
+ :return: None
+ """
+
+ def start_agents(self, agent_names: List[str]) -> None:
+ """
+ Stop specified agents.
+
+ :return: None
+ """
+
+ def get_agent_details(self, agent_name: str) -> AgentAlias:
"""
Return details about agent definition.
- {
- "project": str
- "overrides": dict
- }
+ :return: AgentAlias
"""
+ if agent_name not in self._agents:
+ raise ValueError(f"Agent with name {agent_name} does not exist!")
+ return self._agents[agent_name]
+
+ def _ensure_working_dir(self) -> None:
+ """Create working dir if needed."""
+ if not os.path.exists(self.working_dir):
+ os.makedirs(self.working_dir)
+ self._was_working_dir_created = True
+
+ if not os.path.isdir(self.working_dir):
+ raise ValueError(f"{self.working_dir} is not a directory!")
+ os.makedirs(self._keys_dir)
+
+ def _build_agent_alias(
+ self,
+ project: Project,
+ agent_name: str,
+ agent_overrides=None,
+ component_overrides=None,
+ ) -> AgentAlias:
+ """Create agent alias for project, with given name and overrided values."""
+ json_config = self._make_config(
+ project.path, agent_overrides, component_overrides
+ )
+
+ builder = AEABuilder.from_config_json(json_config, project.path)
+ builder.set_name(agent_name)
+
+ if not builder.private_key_paths:
+ default_ledger = json_config[0].get("default_ledger", DEFAULT_LEDGER)
+ builder.add_private_key(
+ default_ledger, self._create_private_key(agent_name, default_ledger)
+ )
+ agent = builder.build()
+ return AgentAlias(project, agent_name, json_config, agent)
+
+ def _update_dict(self, base: dict, override: dict) -> dict:
+ """Apply overrides for dict."""
+ base = copy.deepcopy(base)
+ base.update(override)
+ return base
+
+ def _make_config(
+ self,
+ project_path: str,
+ agent_overrides: Optional[dict] = None,
+ component_overrides: Optional[List[dict]] = None,
+ ) -> List[dict]:
+ """Make new config baseed on proejct's config with overrides applied."""
+ agent_overrides = agent_overrides or {}
+ component_overrides = component_overrides or []
+
+ if any([key in agent_overrides for key in self.AGENT_DO_NOT_OVERRIDE_VALUES]):
+ raise ValueError(
+ 'Do not override any of {" ".join(self.AGENT_DO_NOT_OVERRIDE_VALUES)}'
+ )
+
+ json_data = yaml_load_all(
+ AEABuilder.get_configuration_file_path(project_path).open()
+ )
+ agent_config = self._update_dict(json_data[0], agent_overrides)
+
+ components_configs = {PublicId.from_json(obj): obj for obj in json_data[1:]}
+
+ for obj in component_overrides:
+ component_id = ComponentId(obj["type"], PublicId.from_json(obj))
+ components_configs[component_id] = self._update_dict(
+ components_configs.get(component_id, {}), obj
+ )
+
+ return [agent_config] + list(components_configs.values())
+
+ def _create_private_key(self, name, ledger) -> str:
+ """Create new key for agent alias in working dir keys dir."""
+ path = os.path.join(self._keys_dir, f"{name}_{ledger}_private.key")
+ create_private_key(ledger, path)
+ return path
diff --git a/tests/test_manager.py b/tests/test_manager.py
new file mode 100644
index 0000000000..e5a4c6af57
--- /dev/null
+++ b/tests/test_manager.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+# ------------------------------------------------------------------------------
+#
+# Copyright 2018-2020 Fetch.AI Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ------------------------------------------------------------------------------
+"""This module contains tests for aea manager."""
+import os
+from contextlib import suppress
+from shutil import rmtree
+from typing import Dict, List, Optional, Set
+
+import pytest
+
+from aea.configurations.base import PublicId
+from aea.manager import Manager
+
+
+def test_manager():
+ """Perform some tests."""
+
+ try:
+ working_dir = "manager_dir"
+ project_public_id = PublicId("fetchai", "my_first_aea", "0.11.0")
+ project_path = os.path.join(
+ working_dir, project_public_id.author, project_public_id.name
+ )
+ assert not os.path.exists(working_dir)
+ manager = Manager(working_dir)
+ manager.start_manager()
+ assert os.path.exists(working_dir)
+ assert manager.is_started
+
+ manager.add_project(project_public_id)
+
+ assert project_public_id in manager.list_projects()
+ assert os.path.exists(project_path)
+ assert manager._projects[project_public_id].path == project_path
+
+ with pytest.raises(ValueError, match=r".*was already added.*"):
+ manager.add_project(project_public_id)
+
+ echo_skill_id = PublicId("fetchai", "echo", "0.7.0")
+ new_tick_interval = 1.1111
+ agent_name = "test_what_ever12"
+ manager.add_agent(
+ project_public_id,
+ agent_name,
+ component_overrides=[
+ {
+ "type": "skill",
+ **echo_skill_id.json,
+ "behaviours": {
+ "echo": {
+ "args": {"tick_interval": new_tick_interval},
+ "class_name": "EchoBehaviour",
+ }
+ },
+ }
+ ],
+ )
+ agent_alias = manager.get_agent_details(agent_name)
+ assert agent_alias.name == agent_name
+ assert (
+ agent_alias.agent.resources.get_behaviour(
+ echo_skill_id, "echo"
+ ).tick_interval
+ == new_tick_interval
+ )
+ with pytest.raises(ValueError, match="already exists"):
+ manager.add_agent(
+ project_public_id, agent_name,
+ )
+ assert agent_name in manager.list_agents()
+
+ manager.remove_agent(agent_name)
+ assert agent_name not in manager.list_agents()
+
+ with pytest.raises(ValueError, match="does not exist!"):
+ manager.remove_agent(agent_name)
+
+ manager.remove_project(project_public_id)
+ assert project_public_id not in manager._projects
+ assert not os.path.exists(project_path)
+ assert project_public_id not in manager.list_projects()
+
+ with pytest.raises(ValueError, match=r"was not added"):
+ manager.remove_project(project_public_id)
+
+ manager.stop_manager()
+ assert not os.path.exists(working_dir)
+ assert not manager.is_started
+ finally:
+ with suppress(FileNotFoundError):
+ rmtree(working_dir)
From 935395e40f8e27b295162092f0a6348efa1ccebf Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Fri, 25 Sep 2020 12:47:32 +0300
Subject: [PATCH 093/131] anget manager. start stop agents
---
aea/manager.py | 225 +++++++++++++++++++++++++++++++++++++++++-
tests/test_manager.py | 22 +++--
2 files changed, 236 insertions(+), 11 deletions(-)
diff --git a/aea/manager.py b/aea/manager.py
index 643543597f..de92bf7edb 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -17,10 +17,14 @@
#
# ------------------------------------------------------------------------------
"""This module contains the implementation of AEA agents manager."""
+import asyncio
import copy
import os
+import threading
+from asyncio.tasks import FIRST_COMPLETED
from shutil import rmtree
-from typing import Dict, List, Optional, Set
+from threading import Thread
+from typing import Callable, Dict, List, Optional, Set
from aea.aea import AEA
from aea.aea_builder import AEABuilder
@@ -70,12 +74,96 @@ def remove(self):
self.project.agents.remove(self.name)
+class AsyncTask:
+ """Async task wrapper for agent."""
+
+ def __init__(self, agent: AEA, loop: asyncio.AbstractEventLoop) -> None:
+ """Init task with agent and loop."""
+ self.run_loop: asyncio.AbstractEventLoop = loop
+ self.caller_loop: asyncio.AbstractEventLoop = loop
+ self._done_future: Optional[asyncio.Future] = None
+ self.task: Optional[asyncio.Task] = None
+ self.agent = agent
+
+ def create_run_loop(self) -> None:
+ """Create run loop."""
+ pass
+
+ def start(self) -> None:
+ """Start task."""
+ self.create_run_loop()
+ self.task = self.run_loop.create_task(self._run_wrapper())
+ self._done_future = asyncio.Future(loop=self.caller_loop)
+
+ def wait(self) -> asyncio.Future:
+ """Return future to wait task completed."""
+ if not self._done_future:
+ raise ValueError("Task not started!")
+ return self._done_future
+
+ def stop(self) -> None:
+ """Stop task."""
+ if not self.run_loop or not self.task:
+ raise ValueError("Task was not started!")
+ self.run_loop.call_soon_threadsafe(self.task.cancel)
+
+ async def _run_wrapper(self) -> None:
+ """Run task internals."""
+ if not self._done_future:
+ raise ValueError("Task was not started! please use start method")
+ try:
+ await self.run()
+ self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
+ except asyncio.CancelledError:
+ self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
+ except Exception as e:
+ self.caller_loop.call_soon_threadsafe(self._done_future.set_exception, e)
+
+ async def run(self) -> None:
+ """Run task body."""
+ self.agent.runtime.set_loop(self.run_loop)
+ try:
+ self.agent.runtime.start()
+ while True:
+ await asyncio.sleep(1)
+ finally:
+ self.agent.runtime.stop()
+
+ @property
+ def is_running(self) -> bool:
+ """Return is task running."""
+ return not self.wait().done()
+
+
+class ThreadedTask(AsyncTask):
+ """Threaded task."""
+
+ def __init__(self, agent: AEA, loop: asyncio.AbstractEventLoop) -> None:
+ """Init task with agent and loop."""
+ AsyncTask.__init__(self, agent, loop)
+ self._thread: Optional[Thread] = None
+
+ def create_run_loop(self) -> None:
+ """Create run loop."""
+ self.run_loop = asyncio.new_event_loop()
+
+ def start(self) -> None:
+ """Run task in a dedicated thread."""
+ super().start()
+ self._thread = threading.Thread(
+ target=self.run_loop.run_until_complete, args=[self.task], daemon=True
+ )
+ self._thread.start()
+
+
class Manager:
"""Abstract agents manager."""
AGENT_DO_NOT_OVERRIDE_VALUES = ["skills", "connections", "protocols", "contracts"]
+ MODES = ["async", "threaded"]
+ DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS = 60
- def __init__(self, working_dir: str) -> None:
+ def __init__(self, working_dir: str, mode: str = "async") -> None:
"""
Initialize manager.
@@ -83,15 +171,74 @@ def __init__(self, working_dir: str) -> None:
"""
self.working_dir = working_dir
self._was_working_dir_created = False
- self.is_started = False
+ self._is_running = False
self._projects: Dict[PublicId, Project] = {}
self._keys_dir = os.path.abspath(os.path.join(self.working_dir, "keys"))
self._agents: Dict[str, AgentAlias] = {}
+ self._agents_tasks: Dict[str, AsyncTask] = {}
+
+ self._thread = Thread(target=self._run_thread, daemon=True)
+ self._loop: Optional[asyncio.AbstractEventLoop] = None
+ self._event: Optional[asyncio.Event] = None
+
+ self._error_callbacks: List[Callable[[str, BaseException], None]] = []
+
+ if mode not in self.MODES:
+ raise ValueError(
+ f'Invalid mode {mode}. Valid modes are {", ".join(self.MODES)}'
+ )
+ self._started_event = threading.Event()
+ self._mode = mode
+
+ @property
+ def is_running(self) -> bool:
+ """Is manager running."""
+ return self._is_running
+
+ def _run_thread(self) -> None:
+ """Run internal thread with own event loop."""
+ self._loop = asyncio.new_event_loop()
+ self._event = asyncio.Event(loop=self._loop)
+ self._loop.run_until_complete(self._manager_loop())
+
+ async def _manager_loop(self) -> None:
+ """Perform manager stop."""
+ if not self._event:
+ raise ValueError("Do not use this method directly, use start_manager.")
+
+ self._started_event.set()
+
+ while self._is_running:
+ tasks_for_agents = {
+ task.wait(): agent_name
+ for agent_name, task in self._agents_tasks.items()
+ }
+ wait_tasks = list(tasks_for_agents.keys()) + [self._event.wait()] # type: ignore
+ done, _ = await asyncio.wait(wait_tasks, return_when=FIRST_COMPLETED)
+
+ if self._event.is_set():
+ self._event.clear()
+
+ for task in done:
+ if task not in tasks_for_agents:
+ await task
+ continue
+ agent_name = tasks_for_agents[task]
+ self._agents_tasks.pop(agent_name)
+ if task.exception():
+ print(agent_name, "exceptioned", task.exception())
+ for callback in self._error_callbacks:
+ callback(agent_name, task.exception())
+ else:
+ await task
def start_manager(self) -> None:
"""Start manager."""
self._ensure_working_dir()
- self.is_started = True
+ self._started_event.clear()
+ self._is_running = True
+ self._thread.start()
+ self._started_event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
def stop_manager(self, cleanup: bool = False) -> None:
"""
@@ -103,10 +250,16 @@ def stop_manager(self, cleanup: bool = False) -> None:
:return: None
"""
+ if not self._loop or not self._event:
+ raise ValueError("Manager was not started!")
if self._was_working_dir_created:
rmtree(self.working_dir)
- self.is_started = False
+ if self._thread.is_alive():
+ self.stop_all_agents()
+ self._is_running = False
+ self._loop.call_soon_threadsafe(self._event.set)
+ self._thread.join(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
def add_project(self, public_id: PublicId) -> None:
"""Fetch agent project and all dependencies to working_dir."""
@@ -119,6 +272,11 @@ def remove_project(self, public_id: PublicId) -> None:
if public_id not in self._projects:
raise ValueError(f"Project {public_id} was not added!")
+ if self._projects[public_id].agents:
+ raise ValueError(
+ f"Can not remove projects with aliases exists: {self._projects[public_id].agents}"
+ )
+
self._projects.pop(public_id).remove()
def list_projects(self) -> List[PublicId]:
@@ -171,6 +329,8 @@ def list_agents(self, running_only: bool = False) -> List[str]:
:return: list of agents names
"""
+ if running_only:
+ return list(self._agents_tasks.keys())
return list(self._agents.keys())
def remove_agent(self, agent_name: str) -> None:
@@ -184,6 +344,9 @@ def remove_agent(self, agent_name: str) -> None:
if agent_name not in self._agents:
raise ValueError(f"Agent with name {agent_name} does not exist!")
+ if self._is_agent_running(agent_name):
+ raise ValueError("Agent is running. stop it first!")
+
agent_alias = self._agents.pop(agent_name)
agent_alias.remove()
@@ -195,6 +358,33 @@ def start_agent(self, agent_name: str) -> None:
:return: None
"""
+ if not self._loop or not self._event:
+ raise ValueError("agent is not started!")
+
+ agent_alias = self._agents.get(agent_name)
+ if not agent_alias:
+ raise ValueError(f"{agent_name} is not registered!")
+ if self._is_agent_running(agent_name):
+ raise ValueError(f"{agent_name} is already started!")
+
+ if self._mode == "async":
+ task = AsyncTask(agent_alias.agent, self._loop)
+ elif self._mode == "threaded":
+ task = ThreadedTask(agent_alias.agent, self._loop)
+
+ task.start()
+ self._agents_tasks[agent_name] = task
+ self._loop.call_soon_threadsafe(self._event.set)
+
+ def _is_agent_running(self, agent_name):
+ if agent_name not in self._agents_tasks:
+ return False
+
+ task = self._agents_tasks[agent_name]
+ if task.is_running:
+ return True
+ del self._agents_tasks[agent_name]
+ return False
def start_all_agents(self) -> None:
"""
@@ -202,6 +392,10 @@ def start_all_agents(self) -> None:
:return: None
"""
+ for agent_name in self.list_agents():
+ if self._is_agent_running(agent_name):
+ continue
+ self.start_agent(agent_name)
def stop_agent(self, agent_name: str) -> None:
"""
@@ -211,6 +405,16 @@ def stop_agent(self, agent_name: str) -> None:
:return: None
"""
+ if not self._is_agent_running(agent_name):
+ raise ValueError(f"{agent_name} is not running!")
+ if self._thread.ident == threading.get_ident():
+ # In same thread do not perform blocking operations!
+ self._agents_tasks[agent_name].stop()
+ return
+ event = threading.Event()
+ self._agents_tasks[agent_name].wait().add_done_callback(lambda x: event.set())
+ self._agents_tasks[agent_name].stop()
+ event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
def stop_all_agents(self) -> None:
"""
@@ -218,6 +422,8 @@ def stop_all_agents(self) -> None:
:return: None
"""
+ for agent_name in self.list_agents(running_only=True):
+ self.stop_agent(agent_name)
def stop_agents(self, agent_names: List[str]) -> None:
"""
@@ -225,6 +431,12 @@ def stop_agents(self, agent_names: List[str]) -> None:
:return: None
"""
+ for agent_name in agent_names:
+ if not self._is_agent_running(agent_name):
+ raise ValueError(f"{agent_name} is not running!")
+
+ for agent_name in agent_names:
+ self.stop_agent(agent_name)
def start_agents(self, agent_names: List[str]) -> None:
"""
@@ -232,6 +444,8 @@ def start_agents(self, agent_names: List[str]) -> None:
:return: None
"""
+ for agent_name in agent_names:
+ self.start_agent(agent_name)
def get_agent_details(self, agent_name: str) -> AgentAlias:
"""
@@ -267,6 +481,7 @@ def _build_agent_alias(
builder = AEABuilder.from_config_json(json_config, project.path)
builder.set_name(agent_name)
+ # builder.set_runtime_mode("async")
if not builder.private_key_paths:
default_ledger = json_config[0].get("default_ledger", DEFAULT_LEDGER)
diff --git a/tests/test_manager.py b/tests/test_manager.py
index e5a4c6af57..170ea6b96e 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -18,9 +18,9 @@
# ------------------------------------------------------------------------------
"""This module contains tests for aea manager."""
import os
+import time
from contextlib import suppress
from shutil import rmtree
-from typing import Dict, List, Optional, Set
import pytest
@@ -30,7 +30,7 @@
def test_manager():
"""Perform some tests."""
-
+ # pydocsyle
try:
working_dir = "manager_dir"
project_public_id = PublicId("fetchai", "my_first_aea", "0.11.0")
@@ -41,7 +41,7 @@ def test_manager():
manager = Manager(working_dir)
manager.start_manager()
assert os.path.exists(working_dir)
- assert manager.is_started
+ assert manager.is_running
manager.add_project(project_public_id)
@@ -84,13 +84,24 @@ def test_manager():
project_public_id, agent_name,
)
assert agent_name in manager.list_agents()
+ manager.start_all_agents()
+ assert agent_name in manager.list_agents(running_only=True)
+ manager.start_all_agents()
+
+ with pytest.raises(ValueError, match="is already started!"):
+ manager.start_agents(manager.list_agents())
+
+ with pytest.raises(ValueError, match="Agent is running. stop it first!"):
+ manager.remove_agent(agent_name)
+
+ time.sleep(2)
+ manager.stop_all_agents()
manager.remove_agent(agent_name)
assert agent_name not in manager.list_agents()
with pytest.raises(ValueError, match="does not exist!"):
manager.remove_agent(agent_name)
-
manager.remove_project(project_public_id)
assert project_public_id not in manager._projects
assert not os.path.exists(project_path)
@@ -98,10 +109,9 @@ def test_manager():
with pytest.raises(ValueError, match=r"was not added"):
manager.remove_project(project_public_id)
-
manager.stop_manager()
assert not os.path.exists(working_dir)
- assert not manager.is_started
+ assert not manager.is_running
finally:
with suppress(FileNotFoundError):
rmtree(working_dir)
From 659bb2da99d4fe12b5a2c28fb4c03ed823660882 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 28 Sep 2020 15:52:27 +0200
Subject: [PATCH 094/131] add jsonschema for skill configurable part
---
.../skill-custom_config.json | 37 +++++++++++++++++++
.../schemas/skill-config_schema.json | 31 ++++++++++------
2 files changed, 57 insertions(+), 11 deletions(-)
create mode 100644 aea/configurations/schemas/configurable_parts/skill-custom_config.json
diff --git a/aea/configurations/schemas/configurable_parts/skill-custom_config.json b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
new file mode 100644
index 0000000000..1b2befcd2a
--- /dev/null
+++ b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
@@ -0,0 +1,37 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Schema for the configurable part of a skill configuration file.",
+ "additionalProperties": false,
+ "required": [
+ "name",
+ "author",
+ "version",
+ "type"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "definitions.json#/definitions/resource_name"
+ },
+ "author": {
+ "$ref": "definitions.json#/definitions/author"
+ },
+ "version": {
+ "$ref": "definitions.json#/definitions/package_version"
+ },
+ "type": {
+ "$ref": "definitions.json#/definitions/component_type"
+ },
+ "handlers": {
+ "$ref": "skill-config_schema.json#/definitions/handlers"
+ },
+ "behaviours": {
+ "$ref": "skill-config_schema.json#/definitions/behaviours"
+ },
+ "models": {
+ "$ref": "skill-config_schema.json#/definitions/models"
+ },
+ "is_abstract": {
+ "$ref": "skill-config_schema.json#/properties/is_abstract"
+ }
+ }
+}
diff --git a/aea/configurations/schemas/skill-config_schema.json b/aea/configurations/schemas/skill-config_schema.json
index bfb97e3d9d..69f0532f36 100644
--- a/aea/configurations/schemas/skill-config_schema.json
+++ b/aea/configurations/schemas/skill-config_schema.json
@@ -62,6 +62,26 @@
"$ref": "definitions.json#/definitions/public_id"
}
},
+ "handlers": {
+ "$ref": "#/definitions/handlers"
+ },
+ "behaviours": {
+ "$ref": "#/definitions/behaviours"
+ },
+ "models": {
+ "$ref": "#/definitions/models"
+ },
+ "dependencies": {
+ "$ref": "definitions.json#/definitions/dependencies"
+ },
+ "description": {
+ "$ref": "definitions.json#/definitions/description"
+ },
+ "is_abstract": {
+ "type": "boolean"
+ }
+ },
+ "definitions": {
"handlers": {
"type": "object",
"additionalProperties": false,
@@ -90,17 +110,6 @@
}
}
},
- "dependencies": {
- "$ref": "definitions.json#/definitions/dependencies"
- },
- "description": {
- "$ref": "definitions.json#/definitions/description"
- },
- "is_abstract": {
- "type": "boolean"
- }
- },
- "definitions": {
"behaviour": {
"type": "object",
"additionalProperties": false,
From 843cf906e8f87975485701b928326223f84839ca Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Mon, 28 Sep 2020 15:48:28 +0100
Subject: [PATCH 095/131] Update aea/helpers/async_utils.py
---
aea/helpers/async_utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aea/helpers/async_utils.py b/aea/helpers/async_utils.py
index 54022720c1..80c6218b5b 100644
--- a/aea/helpers/async_utils.py
+++ b/aea/helpers/async_utils.py
@@ -486,7 +486,7 @@ def __init__(
"""
if loop and threaded:
raise ValueError(
- "You can not set a loop in threaded mode, cause own loop will be created"
+ "You can not set a loop in threaded mode. A separate loop will be created in each thread."
)
self._loop = loop
self._threaded = threaded
From 26feda7686abb174318b408a730b16a4e4c9345f Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 28 Sep 2020 18:53:32 +0200
Subject: [PATCH 096/131] use jsonschema validators for custom configs
---
aea/configurations/base.py | 14 +-
aea/configurations/loader.py | 152 +++++++++---------
.../base-custom_config.json | 25 +++
.../connection-custom_config.json | 28 ++++
.../skill-custom_config.json | 2 +-
5 files changed, 135 insertions(+), 86 deletions(-)
create mode 100644 aea/configurations/schemas/configurable_parts/base-custom_config.json
create mode 100644 aea/configurations/schemas/configurable_parts/connection-custom_config.json
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index d59c28b5bd..ff92bf616b 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -753,7 +753,6 @@ class PackageConfiguration(Configuration, ABC):
default_configuration_filename: str
package_type: PackageType
- configurable_fields: Set[str] = set()
def __init__(
self,
@@ -930,7 +929,6 @@ class ConnectionConfig(ComponentConfiguration):
default_configuration_filename = DEFAULT_CONNECTION_CONFIG_FILE
package_type = PackageType.CONNECTION
- configurable_fields = {"config"}
def __init__(
self,
@@ -1166,7 +1164,6 @@ class SkillConfig(ComponentConfiguration):
default_configuration_filename = DEFAULT_SKILL_CONFIG_FILE
package_type = PackageType.SKILL
- configurable_fields = {"handlers", "behaviours", "models", "is_abstract"}
def __init__(
self,
@@ -1518,16 +1515,7 @@ def default_ledger(self, ledger_id: str):
def component_configurations_json(self) -> List[OrderedDict]:
"""Get the component configurations in JSON format."""
- return [
- OrderedDict(
- name=component_id.name,
- author=component_id.author,
- version=component_id.version,
- type=component_id.component_type.value,
- **obj,
- )
- for component_id, obj in self.component_configurations.items()
- ]
+ return list(map(OrderedDict, self.component_configurations.values()))
@property
def json(self) -> Dict:
diff --git a/aea/configurations/loader.py b/aea/configurations/loader.py
index 8a5c1e84d0..515dcfd615 100644
--- a/aea/configurations/loader.py
+++ b/aea/configurations/loader.py
@@ -25,7 +25,7 @@
import re
from copy import deepcopy
from pathlib import Path
-from typing import Dict, Generic, List, TextIO, Tuple, Type, TypeVar, Union, cast
+from typing import Dict, Generic, List, TextIO, Type, TypeVar, Union, cast
import jsonschema
import yaml
@@ -45,7 +45,6 @@
PublicId,
SkillConfig,
)
-from aea.exceptions import enforce
from aea.helpers.base import yaml_dump, yaml_dump_all, yaml_load, yaml_load_all
@@ -77,37 +76,74 @@ def make_jsonschema_base_uri(base_uri_path: Path) -> str:
return root_path
-class ConfigLoader(Generic[T]):
- """This class implement parsing, serialization and validation functionalities for the 'aea' configuration files."""
+def _get_path_to_custom_config_schema_from_type(component_type: ComponentType) -> str:
+ """
+ Get the path to the custom config schema
- def __init__(self, schema_filename: str, configuration_class: Type[T]):
+ :param component_type: a component type.
+ :return: the path to the JSON schema file.
+ """
+ path_prefix: Path = Path(_SCHEMAS_DIR) / "configurable_parts"
+ if component_type in {ComponentType.SKILL, ComponentType.CONNECTION}:
+ filename_prefix = component_type.value
+ else:
+ filename_prefix = "base"
+ full_path = path_prefix / (filename_prefix + "-custom_config.json")
+ return str(full_path)
+
+
+class BaseConfigLoader:
+ """Base class for configuration loader classes."""
+
+ def __init__(self, schema_filename: str):
"""
- Initialize the parser for configuration files.
+ Initialize the base configuration loader.
- :param schema_filename: the path to the JSON-schema file in 'aea/configurations/schemas'.
- :param configuration_class: the configuration class (e.g. AgentConfig, SkillConfig etc.)
+ :param schema_filename: the path to the schema.
"""
base_uri = Path(_SCHEMAS_DIR)
self._schema = json.load((base_uri / schema_filename).open())
root_path = make_jsonschema_base_uri(base_uri)
self._resolver = jsonschema.RefResolver(root_path, self._schema)
self._validator = Draft4Validator(self._schema, resolver=self._resolver)
- self._configuration_class = configuration_class # type: Type[T]
@property
def validator(self) -> Draft4Validator:
"""Get the json schema validator."""
return self._validator
+ def validate(self, json_data: Dict) -> None:
+ """
+ Validate a JSON object.
+
+ :param json_data: the JSON data.
+ :return: None.
+ """
+ self.validator.validate(json_data)
+
@property
def required_fields(self) -> List[str]:
"""
- Get required fields.
+ Get the required fields.
:return: list of required fields.
"""
return self._schema["required"]
+
+class ConfigLoader(Generic[T], BaseConfigLoader):
+ """Parsing, serialization and validation for package configuration files."""
+
+ def __init__(self, schema_filename: str, configuration_class: Type[T]):
+ """
+ Initialize the parser for configuration files.
+
+ :param schema_filename: the path to the JSON-schema file in 'aea/configurations/schemas'.
+ :param configuration_class: the configuration class (e.g. AgentConfig, SkillConfig etc.)
+ """
+ super().__init__(schema_filename)
+ self._configuration_class = configuration_class # type: Type[T]
+
@property
def configuration_class(self) -> Type[T]:
"""Get the configuration class of the loader."""
@@ -245,20 +281,33 @@ def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
key_order
)
+ component_configurations = self._get_component_configurations(
+ configuration_file_jsons
+ )
+ agent_configuration_obj.component_configurations = component_configurations
+ return agent_configuration_obj
+
+ def _get_component_configurations(
+ self, configuration_file_jsons
+ ) -> Dict[ComponentId, Dict]:
+ """
+ Get the component configurations from the tail pages of the aea-config.yaml file.
+
+ :param configuration_file_jsons: the JSON objects of the custom configurations of a aea-config.yaml file.
+ :return: a dictionary whose keys are component ids and values are the configurations.
+ """
component_configurations: Dict[ComponentId, Dict] = {}
# load the other components.
for i, component_configuration_json in enumerate(configuration_file_jsons[1:]):
- component_id, component_config = self._process_component_section(
+ component_id = self._process_component_section(
i, component_configuration_json
)
if component_id in component_configurations:
raise ValueError(
f"Configuration of component {component_id} occurs more than once."
)
- component_configurations[component_id] = component_config
-
- agent_configuration_obj.component_configurations = component_configurations
- return agent_configuration_obj
+ component_configurations[component_id] = component_configuration_json
+ return component_configurations
def _dump_agent_config(
self, configuration: AgentConfig, file_pointer: TextIO
@@ -278,7 +327,7 @@ def _dump_component_config(self, configuration: T, file_pointer: TextIO) -> None
def _process_component_section(
self, i: int, component_configuration_json: Dict
- ) -> Tuple[ComponentId, Dict]:
+ ) -> ComponentId:
"""
Process a component configuration in an agent configuration file.
@@ -291,17 +340,18 @@ def _process_component_section(
:param component_configuration_json: the JSON object.
:return: the processed component configuration.
"""
- component_id, result = self._split_component_id_and_config(
+ component_id = self._split_component_id_and_config(
i, component_configuration_json
)
- self._validate_component_configuration(component_id, result)
- self._check_only_configurable_fields(component_id, result)
- return component_id, result
+ self._validate_component_configuration(
+ component_id, component_configuration_json
+ )
+ return component_id
@staticmethod
def _split_component_id_and_config(
i: int, component_configuration_json: Dict
- ) -> Tuple[ComponentId, Dict]:
+ ) -> ComponentId:
"""
Split component id and configuration.
@@ -310,7 +360,6 @@ def _split_component_id_and_config(
:return: the component id and the configuration object.
:raises ValueError: if the component id cannot be extracted.
"""
- result = deepcopy(component_configuration_json)
# author, name, version, type are mandatory fields
missing_fields = {"author", "name", "version", "type"}.difference(
component_configuration_json.keys()
@@ -319,15 +368,15 @@ def _split_component_id_and_config(
raise ValueError(
f"There are missing fields in component id {i + 1}: {missing_fields}."
)
- component_name = result.pop("name")
- component_author = result.pop("author")
- component_version = result.pop("version")
- component_type = ComponentType(result.pop("type"))
+ component_name = component_configuration_json["name"]
+ component_author = component_configuration_json["author"]
+ component_version = component_configuration_json["version"]
+ component_type = ComponentType(component_configuration_json["type"])
component_public_id = PublicId(
component_author, component_name, component_version
)
component_id = ComponentId(component_type, component_public_id)
- return component_id, result
+ return component_id
@staticmethod
def _validate_component_configuration(
@@ -343,56 +392,15 @@ def _validate_component_configuration(
:return: None
:raises ValueError: if the configuration is not valid.
"""
- # we need to populate the required fields to validate the configurations.
- temporary_config = deepcopy(configuration)
- # common to every package
- temporary_config["name"] = component_id.name
- temporary_config["author"] = component_id.author
- temporary_config["version"] = component_id.version
- temporary_config["license"] = "some_license"
- temporary_config["aea_version"] = "0.1.0"
- if component_id.component_type == ComponentType.PROTOCOL:
- pass # no other required field
- elif component_id.component_type == ComponentType.CONNECTION:
- temporary_config["class_name"] = "SomeClassName"
- temporary_config["protocols"] = []
- temporary_config.setdefault("config", {})
- elif component_id.component_type == ComponentType.CONTRACT:
- temporary_config["class_name"] = "SomeClassName"
- elif component_id.component_type == ComponentType.SKILL:
- temporary_config["protocols"] = []
- temporary_config["contracts"] = []
- temporary_config["skills"] = []
- loader = ConfigLoaders.from_package_type(component_id.package_type)
+ schema_file = _get_path_to_custom_config_schema_from_type(
+ component_id.component_type
+ )
try:
- loader._load_from_json(temporary_config) # pylint: disable=protected-access
+ BaseConfigLoader(schema_file).validate(configuration)
except jsonschema.ValidationError as e:
raise ValueError(
f"Configuration of component {component_id} is not valid."
) from e
- # all good!
-
- @staticmethod
- def _check_only_configurable_fields(
- component_id: ComponentId, configuration: Dict
- ) -> None:
- """
- Check that there are only configurable fields.
-
- :param component_id: the component id.
- :param configuration: the configuration object.
- :return: None
- """
- configurable_fields = (
- component_id.package_type.configuration_class().configurable_fields
- )
- non_configurable_fields = set(configuration.keys()).difference(
- configurable_fields
- )
- enforce(
- len(non_configurable_fields) == 0,
- f"Bad configuration for component {component_id}: {non_configurable_fields} are non-configurable fields.",
- )
class ConfigLoaders:
diff --git a/aea/configurations/schemas/configurable_parts/base-custom_config.json b/aea/configurations/schemas/configurable_parts/base-custom_config.json
new file mode 100644
index 0000000000..7e44b416bf
--- /dev/null
+++ b/aea/configurations/schemas/configurable_parts/base-custom_config.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Base schema for a custom component configuration in the agent configuration file.",
+ "additionalProperties": false,
+ "required": [
+ "name",
+ "author",
+ "version",
+ "type"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "definitions.json#/definitions/resource_name"
+ },
+ "author": {
+ "$ref": "definitions.json#/definitions/author"
+ },
+ "version": {
+ "$ref": "definitions.json#/definitions/package_version"
+ },
+ "type": {
+ "$ref": "definitions.json#/definitions/component_type"
+ }
+ }
+}
diff --git a/aea/configurations/schemas/configurable_parts/connection-custom_config.json b/aea/configurations/schemas/configurable_parts/connection-custom_config.json
new file mode 100644
index 0000000000..a81b002836
--- /dev/null
+++ b/aea/configurations/schemas/configurable_parts/connection-custom_config.json
@@ -0,0 +1,28 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Schema for the configurable part of a connection configuration in the agent configuration file.",
+ "additionalProperties": false,
+ "required": [
+ "name",
+ "author",
+ "version",
+ "type"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "definitions.json#/definitions/resource_name"
+ },
+ "author": {
+ "$ref": "definitions.json#/definitions/author"
+ },
+ "version": {
+ "$ref": "definitions.json#/definitions/package_version"
+ },
+ "type": {
+ "$ref": "definitions.json#/definitions/component_type"
+ },
+ "config": {
+ "type": "object"
+ }
+ }
+}
diff --git a/aea/configurations/schemas/configurable_parts/skill-custom_config.json b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
index 1b2befcd2a..a1c43e2618 100644
--- a/aea/configurations/schemas/configurable_parts/skill-custom_config.json
+++ b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
- "description": "Schema for the configurable part of a skill configuration file.",
+ "description": "Schema for the configurable part of a skill configuration in the agent configuration file.",
"additionalProperties": false,
"required": [
"name",
From b6e46346be05818745ceedc571b75bbaae4634f7 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 28 Sep 2020 21:59:11 +0300
Subject: [PATCH 097/131] fixes
---
aea/aea_builder.py | 21 +++++++--
aea/cli/registry/fetch.py | 11 ++---
aea/configurations/loader.py | 19 +++++---
aea/configurations/project.py | 50 +++++++++++++++++++++
aea/manager.py | 84 ++++++++++++++++-------------------
5 files changed, 124 insertions(+), 61 deletions(-)
create mode 100644 aea/configurations/project.py
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index 54e89d1642..99ceef4f71 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -1348,13 +1348,25 @@ def from_aea_project(
@classmethod
def from_config_json(
- cls, json_data, aea_project_path: PathLike, skip_consistency_check: bool = False
- ):
+ cls,
+ json_data: List[Dict],
+ aea_project_path: PathLike,
+ skip_consistency_check: bool = False,
+ ) -> "AEABuilder":
+ """
+ Load agent configuration for alreaady provided json data.
+
+ :param json_data: list of dicts with agent configuration
+ :param aea_project_path: path to project root
+ :param skip_consistency_check: skip consistency check on configs load.
+
+ :return: AEABuilder instance
+ """
aea_project_path = Path(aea_project_path)
builder = AEABuilder(with_default_packages=False)
# load agent configuration file
- agent_configuration = cls.loader._load_agent_config_from_json(json_data)
+ agent_configuration = cls.loader.load_agent_config_from_json(json_data)
builder.set_from_configuration(
agent_configuration, aea_project_path, skip_consistency_check
@@ -1362,7 +1374,8 @@ def from_config_json(
return builder
@staticmethod
- def get_configuration_file_path(aea_project_path):
+ def get_configuration_file_path(aea_project_path: Union[Path, str]) -> Path:
+ """Return path to aea-config file for the given aea project path."""
return Path(aea_project_path) / DEFAULT_AEA_CONFIG_FILE
def _load_and_add_components(
diff --git a/aea/cli/registry/fetch.py b/aea/cli/registry/fetch.py
index cf0270c391..7d03503cb9 100644
--- a/aea/cli/registry/fetch.py
+++ b/aea/cli/registry/fetch.py
@@ -16,12 +16,10 @@
# limitations under the License.
#
# ------------------------------------------------------------------------------
-from aea.helpers.base import cd
-import shutil
-
"""Methods for CLI fetch functionality."""
import os
+import shutil
from typing import Optional
import click
@@ -39,7 +37,7 @@ def fetch_agent(
ctx: Context,
public_id: PublicId,
alias: Optional[str] = None,
- dir: Optional[str] = None,
+ target_dir: Optional[str] = None,
) -> None:
"""
Fetch Agent from Registry.
@@ -57,14 +55,13 @@ def fetch_agent(
filepath = download_file(file_url, ctx.cwd)
- folder_name = dir or (name if alias is None else alias)
+ folder_name = target_dir or (name if alias is None else alias)
aea_folder = os.path.join(ctx.cwd, folder_name)
- print(aea_folder)
ctx.clean_paths.append(aea_folder)
extract(filepath, ctx.cwd)
- if alias or dir:
+ if alias or target_dir:
shutil.move(
os.path.join(ctx.cwd, name), aea_folder,
)
diff --git a/aea/configurations/loader.py b/aea/configurations/loader.py
index 4956406c95..eef1a20ff1 100644
--- a/aea/configurations/loader.py
+++ b/aea/configurations/loader.py
@@ -229,10 +229,19 @@ def _load_from_json(self, configuration_file_json: Dict) -> T:
configuration_obj._key_order = key_order # pylint: disable=protected-access
return configuration_obj
- def _load_agent_config_from_json(self, configuration_file_jsons) -> AgentConfig:
- if len(configuration_file_jsons) == 0:
+ def load_agent_config_from_json(
+ self, configuration_json: List[Dict]
+ ) -> AgentConfig:
+ """
+ Load agent configuration from configuration json data.
+
+ :param configuration_json: list of dicts with aea configuration
+
+ :return: AgentConfig instance
+ """
+ if len(configuration_json) == 0:
raise ValueError("Agent configuration file was empty.")
- agent_config_json = configuration_file_jsons[0]
+ agent_config_json = configuration_json[0]
self._validate(agent_config_json)
key_order = list(agent_config_json.keys())
agent_configuration_obj = cast(
@@ -244,7 +253,7 @@ def _load_agent_config_from_json(self, configuration_file_jsons) -> AgentConfig:
component_configurations: Dict[ComponentId, Dict] = {}
# load the other components.
- for i, component_configuration_json in enumerate(configuration_file_jsons[1:]):
+ for i, component_configuration_json in enumerate(configuration_json[1:]):
component_id, component_config = self._process_component_section(
i, component_configuration_json
)
@@ -260,7 +269,7 @@ def _load_agent_config_from_json(self, configuration_file_jsons) -> AgentConfig:
def _load_agent_config(self, file_pointer: TextIO) -> AgentConfig:
"""Load an agent configuration."""
configuration_file_jsons = yaml_load_all(file_pointer)
- return self._load_agent_config_from_json(configuration_file_jsons)
+ return self.load_agent_config_from_json(configuration_file_jsons)
def _dump_agent_config(
self, configuration: AgentConfig, file_pointer: TextIO
diff --git a/aea/configurations/project.py b/aea/configurations/project.py
new file mode 100644
index 0000000000..8aeace45b8
--- /dev/null
+++ b/aea/configurations/project.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# ------------------------------------------------------------------------------
+#
+# Copyright 2018-2020 Fetch.AI Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ------------------------------------------------------------------------------
+"""This module contains the implementation of AEA agents project configuiration."""
+import os
+from shutil import rmtree
+from typing import Set
+
+from aea.cli.registry.fetch import fetch_agent
+from aea.cli.utils.context import Context
+from aea.configurations.base import PublicId
+
+
+class Project:
+ """Agent project representation."""
+
+ def __init__(self, public_id: PublicId, path: str):
+ """Init project with public_id and project's path."""
+ self.public_id: PublicId = public_id
+ self.path: str = path
+ self.agents: Set[str] = set()
+
+ @classmethod
+ def load(cls, working_dir: str, public_id: PublicId) -> "Project":
+ """Load project with given pubblic_id to working_dir."""
+ ctx = Context(cwd=working_dir)
+ path = os.path.join(working_dir, public_id.author, public_id.name)
+ fetch_agent(
+ ctx, public_id, target_dir=os.path.join(public_id.author, public_id.name)
+ )
+ return cls(public_id, path)
+
+ def remove(self) -> None:
+ """Remove project, do cleanup."""
+ rmtree(self.path)
diff --git a/aea/manager.py b/aea/manager.py
index de92bf7edb..d39e89b296 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -16,6 +16,7 @@
# limitations under the License.
#
# ------------------------------------------------------------------------------
+
"""This module contains the implementation of AEA agents manager."""
import asyncio
import copy
@@ -24,40 +25,17 @@
from asyncio.tasks import FIRST_COMPLETED
from shutil import rmtree
from threading import Thread
-from typing import Callable, Dict, List, Optional, Set
+from typing import Callable, Dict, List, Optional
from aea.aea import AEA
from aea.aea_builder import AEABuilder
-from aea.cli.registry.fetch import fetch_agent
-from aea.cli.utils.context import Context
from aea.configurations.base import ComponentId, PublicId
from aea.configurations.constants import DEFAULT_LEDGER
+from aea.configurations.project import Project
from aea.crypto.helpers import create_private_key
from aea.helpers.base import yaml_load_all
-class Project:
- """Agent project representation."""
-
- def __init__(self, public_id: PublicId, path: str):
- """Init project with public_id and project's path."""
- self.public_id = public_id
- self.path = path
- self.agents: Set[str] = set()
-
- @classmethod
- def load(cls, working_dir, public_id) -> "Project":
- """Load project with given pubblic_id to working_dir."""
- ctx = Context(cwd=working_dir)
- path = os.path.join(working_dir, public_id.author, public_id.name)
- fetch_agent(ctx, public_id, dir=os.path.join(public_id.author, public_id.name))
- return cls(public_id, path)
-
- def remove(self):
- """Remove project, do cleanup."""
- rmtree(self.path)
-
-
class AgentAlias:
"""Agent alias representation."""
@@ -116,7 +94,7 @@ async def _run_wrapper(self) -> None:
self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
except asyncio.CancelledError:
self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
- except Exception as e:
+ except Exception as e: # pylint: disable=broad-except
self.caller_loop.call_soon_threadsafe(self._done_future.set_exception, e)
async def run(self) -> None:
@@ -232,22 +210,21 @@ async def _manager_loop(self) -> None:
else:
await task
- def start_manager(self) -> None:
+ def start_manager(self) -> "Manager":
"""Start manager."""
self._ensure_working_dir()
self._started_event.clear()
self._is_running = True
self._thread.start()
self._started_event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
+ return self
- def stop_manager(self, cleanup: bool = False) -> None:
+ def stop_manager(self) -> "Manager":
"""
Stop manager.
Stops all running agents and stop agent.
- :param cleanup: remove agents_dir and purge in memory registry.
-
:return: None
"""
if not self._loop or not self._event:
@@ -260,14 +237,16 @@ def stop_manager(self, cleanup: bool = False) -> None:
self._is_running = False
self._loop.call_soon_threadsafe(self._event.set)
self._thread.join(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
+ return self
- def add_project(self, public_id: PublicId) -> None:
+ def add_project(self, public_id: PublicId) -> "Manager":
"""Fetch agent project and all dependencies to working_dir."""
if public_id in self._projects:
raise ValueError(f"Project {public_id} was already added!")
self._projects[public_id] = Project.load(self.working_dir, public_id)
+ return self
- def remove_project(self, public_id: PublicId) -> None:
+ def remove_project(self, public_id: PublicId) -> "Manager":
"""Remove agent project."""
if public_id not in self._projects:
raise ValueError(f"Project {public_id} was not added!")
@@ -278,6 +257,7 @@ def remove_project(self, public_id: PublicId) -> None:
)
self._projects.pop(public_id).remove()
+ return self
def list_projects(self) -> List[PublicId]:
"""
@@ -293,7 +273,7 @@ def add_agent(
agent_name: str,
agent_overrides: Optional[dict] = None,
component_overrides: Optional[List[dict]] = None,
- ) -> None:
+ ) -> "Manager":
"""
Create new agent configuration based on project with config overrides applied.
@@ -304,7 +284,7 @@ def add_agent(
:param agent_overrides: overrides for agent config.
:param component_overrides: overrides for component section.
- :return: None
+ :return: manager
"""
if agent_name in self._agents:
raise ValueError(f"Agent with name {agent_name} already exists!")
@@ -320,6 +300,7 @@ def add_agent(
component_overrides=component_overrides,
)
self._agents[agent_name] = agent_alias
+ return self
def list_agents(self, running_only: bool = False) -> List[str]:
"""
@@ -333,7 +314,7 @@ def list_agents(self, running_only: bool = False) -> List[str]:
return list(self._agents_tasks.keys())
return list(self._agents.keys())
- def remove_agent(self, agent_name: str) -> None:
+ def remove_agent(self, agent_name: str) -> "Manager":
"""
Remove agent alias definition from registry.
@@ -349,8 +330,9 @@ def remove_agent(self, agent_name: str) -> None:
agent_alias = self._agents.pop(agent_name)
agent_alias.remove()
+ return self
- def start_agent(self, agent_name: str) -> None:
+ def start_agent(self, agent_name: str) -> "Manager":
"""
Start selected agent.
@@ -375,6 +357,7 @@ def start_agent(self, agent_name: str) -> None:
task.start()
self._agents_tasks[agent_name] = task
self._loop.call_soon_threadsafe(self._event.set)
+ return self
def _is_agent_running(self, agent_name):
if agent_name not in self._agents_tasks:
@@ -386,7 +369,7 @@ def _is_agent_running(self, agent_name):
del self._agents_tasks[agent_name]
return False
- def start_all_agents(self) -> None:
+ def start_all_agents(self) -> "Manager":
"""
Start all not started agents.
@@ -397,7 +380,9 @@ def start_all_agents(self) -> None:
continue
self.start_agent(agent_name)
- def stop_agent(self, agent_name: str) -> None:
+ return self
+
+ def stop_agent(self, agent_name: str) -> "Manager":
"""
Stop running agent.
@@ -410,13 +395,15 @@ def stop_agent(self, agent_name: str) -> None:
if self._thread.ident == threading.get_ident():
# In same thread do not perform blocking operations!
self._agents_tasks[agent_name].stop()
- return
+ return self
event = threading.Event()
self._agents_tasks[agent_name].wait().add_done_callback(lambda x: event.set())
self._agents_tasks[agent_name].stop()
event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
- def stop_all_agents(self) -> None:
+ return self
+
+ def stop_all_agents(self) -> "Manager":
"""
Stop all agents running.
@@ -425,7 +412,9 @@ def stop_all_agents(self) -> None:
for agent_name in self.list_agents(running_only=True):
self.stop_agent(agent_name)
- def stop_agents(self, agent_names: List[str]) -> None:
+ return self
+
+ def stop_agents(self, agent_names: List[str]) -> "Manager":
"""
Stop specified agents.
@@ -438,7 +427,9 @@ def stop_agents(self, agent_names: List[str]) -> None:
for agent_name in agent_names:
self.stop_agent(agent_name)
- def start_agents(self, agent_names: List[str]) -> None:
+ return self
+
+ def start_agents(self, agent_names: List[str]) -> "Manager":
"""
Stop specified agents.
@@ -447,9 +438,11 @@ def start_agents(self, agent_names: List[str]) -> None:
for agent_name in agent_names:
self.start_agent(agent_name)
- def get_agent_details(self, agent_name: str) -> AgentAlias:
+ return self
+
+ def get_agent_alias(self, agent_name: str) -> AgentAlias:
"""
- Return details about agent definition.
+ Return details about agent alias definition.
:return: AgentAlias
"""
@@ -491,7 +484,8 @@ def _build_agent_alias(
agent = builder.build()
return AgentAlias(project, agent_name, json_config, agent)
- def _update_dict(self, base: dict, override: dict) -> dict:
+ @staticmethod
+ def _update_dict(base: dict, override: dict) -> dict:
"""Apply overrides for dict."""
base = copy.deepcopy(base)
base.update(override)
From 807044747fe3d00d7cc42db8ee21ec5d28c4835e Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 28 Sep 2020 22:02:28 +0300
Subject: [PATCH 098/131] small fix
---
aea/runtime.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/aea/runtime.py b/aea/runtime.py
index 04e70e1ed9..e6af111556 100644
--- a/aea/runtime.py
+++ b/aea/runtime.py
@@ -299,9 +299,11 @@ async def run_runtime(self) -> None:
async def _start_multiplexer(self) -> None:
"""Call multiplexer connect asynchronous way."""
- self.setup_multiplexer()
- if not self._loop:
+ if not self._loop: # pragma: nocover
raise ValueError("no loop is set for runtime.")
+
+ self.setup_multiplexer()
+
self.multiplexer.set_loop(self._loop)
self.multiplexer.start()
await self.multiplexer.wait_completed()
From 16cf1a1634f454a6eaf5d44f2db0ad2e2031c97a Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 29 Sep 2020 11:42:39 +0200
Subject: [PATCH 099/131] Update only arguments of components
---
aea/aea_builder.py | 28 +++++--
aea/configurations/base.py | 50 +++++++++----
.../skill-custom_config.json | 74 ++++++++++++++++++-
aea/helpers/base.py | 35 +++++++++
tests/conftest.py | 4 +-
tests/data/aea-config.example_multipage.yaml | 4 -
tests/test_configurations/test_base.py | 45 +++++++++--
7 files changed, 201 insertions(+), 39 deletions(-)
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index ee5b77abe8..3e71026779 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -1372,18 +1372,13 @@ def _load_and_add_components(
logging.Logger, make_logger(configuration, agent_name)
)
else:
- configuration = deepcopy(configuration)
- configuration.update(
- self._custom_component_configurations.get(
- configuration.component_id, {}
- )
- )
if configuration.is_abstract_component:
load_aea_package(configuration)
continue
- _logger = make_logger(configuration, agent_name)
+ new_configuration = self._overwrite_custom_configuration(configuration)
+ _logger = make_logger(new_configuration, agent_name)
component = load_component_from_config(
- configuration, logger=_logger, **kwargs
+ new_configuration, logger=_logger, **kwargs
)
resources.add_component(component)
@@ -1397,6 +1392,23 @@ def _check_we_can_build(self):
"Please call 'reset() if you want to build another agent."
)
+ def _overwrite_custom_configuration(self, configuration: ComponentConfiguration):
+ """
+ Overwrite custom configurations.
+
+ It deep-copies the configuration, to avoid undesired side-effects.
+
+ :param configuration: the configuration object.
+ :param custom_config: the configurations to apply.
+ :return: the new configuration instance.
+ """
+ new_configuration = deepcopy(configuration)
+ custom_config = self._custom_component_configurations.get(
+ new_configuration.component_id, {}
+ )
+ new_configuration.update(custom_config)
+ return new_configuration
+
def make_logger(
configuration: ComponentConfiguration, agent_name: str,
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index ff92bf616b..48cd40aa98 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -53,6 +53,7 @@
from aea.__version__ import __version__ as __aea_version__
from aea.exceptions import enforce
+from aea.helpers.base import merge_update
from aea.helpers.ipfs.base import IPFSHashOnly
@@ -1058,10 +1059,13 @@ def update(self, data: Dict) -> None:
"""
Update configuration with other data.
- :param data: the data to replace.
+ This method does side-effect on the configuration object.
+
+ :param data: the data to populate or replace.
:return: None
"""
- self.config = data.get("config", self.config)
+ new_config = data.get("config", {})
+ merge_update(self.config, new_config)
class ProtocolConfig(ComponentConfiguration):
@@ -1318,18 +1322,34 @@ def update(self, data: Dict) -> None:
:param data: the data to replace.
:return: None
"""
- for behaviour_id, behaviour_data in data.get("behaviours", {}).items():
- behaviour_config = SkillComponentConfiguration.from_json(behaviour_data)
- self.behaviours.update(behaviour_id, behaviour_config)
- for handler_id, handler_data in data.get("handlers", {}).items():
- handler_config = SkillComponentConfiguration.from_json(handler_data)
- self.handlers.update(handler_id, handler_config)
+ def _update_skill_component_config(type_plural: str, data: Dict):
+ """
+ Update skill component configurations with new data.
- for model_id, model_data in data.get("models", {}).items():
- model_config = SkillComponentConfiguration.from_json(model_data)
- self.models.update(model_id, model_config)
+ Also check that there are not undeclared components.
+ """
+ registry: CRUDCollection[SkillComponentConfiguration] = getattr(
+ self, type_plural
+ )
+ new_component_config = data.get(type_plural, {})
+ all_component_names = dict(registry.read_all())
+
+ new_skill_component_names = set(new_component_config.keys()).difference(
+ set(all_component_names.keys())
+ )
+ if len(new_skill_component_names) > 0:
+ raise ValueError(
+ f"The custom configuration for skill {self.public_id} includes new {type_plural}: {new_skill_component_names}. This is not allowed."
+ )
+
+ for component_name, component_data in data.get(type_plural, {}).items():
+ component_config = registry.read(component_name)
+ merge_update(component_config.args, component_data.get("args", {}))
+ _update_skill_component_config("behaviours", data)
+ _update_skill_component_config("handlers", data)
+ _update_skill_component_config("models", data)
self.is_abstract = data.get("is_abstract", self.is_abstract)
@@ -1625,10 +1645,10 @@ def from_json(cls, obj: Dict):
component_configurations = {}
for config in obj.get("component_configurations", []):
tmp = deepcopy(config)
- name = tmp.pop("name")
- author = tmp.pop("author")
- version = tmp.pop("version")
- type_ = tmp.pop("type")
+ name = tmp["name"]
+ author = tmp["author"]
+ version = tmp["version"]
+ type_ = tmp["type"]
component_id = ComponentId(
ComponentType(type_), PublicId(author, name, version)
)
diff --git a/aea/configurations/schemas/configurable_parts/skill-custom_config.json b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
index a1c43e2618..b470606888 100644
--- a/aea/configurations/schemas/configurable_parts/skill-custom_config.json
+++ b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
@@ -22,16 +22,82 @@
"$ref": "definitions.json#/definitions/component_type"
},
"handlers": {
- "$ref": "skill-config_schema.json#/definitions/handlers"
+ "$ref": "#/definitions/handlers"
},
"behaviours": {
- "$ref": "skill-config_schema.json#/definitions/behaviours"
+ "$ref": "#/definitions/behaviours"
},
"models": {
- "$ref": "skill-config_schema.json#/definitions/models"
+ "$ref": "#/definitions/models"
},
"is_abstract": {
- "$ref": "skill-config_schema.json#/properties/is_abstract"
+ "$ref": "#/properties/is_abstract"
+ }
+ },
+ "definitions": {
+ "handlers": {
+ "type": "object",
+ "additionalProperties": false,
+ "uniqueItems": true,
+ "patternProperties": {
+ "^[^\\d\\W]\\w*\\Z": {
+ "$ref": "#/definitions/handler"
+ }
+ }
+ },
+ "behaviours": {
+ "type": "object",
+ "uniqueItems": true,
+ "patternProperties": {
+ "^[^\\d\\W]\\w*\\Z": {
+ "$ref": "#/definitions/behaviour"
+ }
+ }
+ },
+ "models": {
+ "type": "object",
+ "uniqueItems": true,
+ "patternProperties": {
+ "^[^\\d\\W]\\w*\\Z": {
+ "$ref": "#/definitions/model"
+ }
+ }
+ },
+ "behaviour": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "args"
+ ],
+ "properties": {
+ "args": {
+ "type": "object"
+ }
+ }
+ },
+ "handler": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "args"
+ ],
+ "properties": {
+ "args": {
+ "type": "object"
+ }
+ }
+ },
+ "model": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "args"
+ ],
+ "properties": {
+ "args": {
+ "type": "object"
+ }
+ }
}
}
}
diff --git a/aea/helpers/base.py b/aea/helpers/base.py
index 89cd6e3e71..e39a9fe80b 100644
--- a/aea/helpers/base.py
+++ b/aea/helpers/base.py
@@ -390,3 +390,38 @@ def exception_log_and_reraise(log_method: Callable, message: str):
except BaseException as e: # pylint: disable=broad-except # pragma: no cover # generic code
log_method(message.format(e))
raise
+
+
+def merge_update(to_update: Dict, new_values: Dict):
+ """
+ Merge two dictionaries by replacing conflicts with the new values.
+
+ It does side-effects to the first dictionary.
+
+ >>> to_update = dict(a=1, b=2, subdict=dict(subfield1=1))
+ >>> new_values = dict(b=3, c=4, subdict=dict(subfield2=2))
+ >>> merge_update(to_update, new_values)
+ >>> to_update
+ {'a': 1, 'b': 3, 'subdict': {'subfield1': 1, 'subfield2': 2}, 'c': 4}
+
+ :param to_update: the dictionary to update.
+ :param new_values: the dictionary of new values to add/replace.
+ :return: the merged dictionary.
+ """
+ for key, value in new_values.items():
+ if key not in to_update:
+ to_update[key] = value
+ continue
+
+ value_to_update = to_update[key]
+ value_type = type(value)
+ value_to_update_type = type(value_to_update)
+ if value_type != value_to_update_type:
+ raise ValueError(
+ f"Trying to replace value '{value}' with value '{value_to_update}' which is of different type."
+ )
+
+ if value_type == value_to_update_type == dict:
+ merge_update(value_to_update, value)
+ else:
+ to_update[key] = value
diff --git a/tests/conftest.py b/tests/conftest.py
index 6eda95ebaa..6efe975b86 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -205,6 +205,8 @@
DUMMY_CONNECTION_PUBLIC_ID = PublicId("dummy_author", "dummy", "0.1.0")
DUMMY_SKILL_PUBLIC_ID = PublicId("dummy_author", "dummy", "0.1.0")
+DUMMY_SKILL_PATH = os.path.join(CUR_PATH, "data", "dummy_skill", SKILL_YAML)
+
MAX_FLAKY_RERUNS = 3
MAX_FLAKY_RERUNS_ETH = 1
MAX_FLAKY_RERUNS_INTEGRATION = 1
@@ -278,7 +280,7 @@
os.path.join(FETCHAI_PREF, "skills", "thermometer_client", SKILL_YAML),
os.path.join(FETCHAI_PREF, "skills", "weather_client", SKILL_YAML),
os.path.join(FETCHAI_PREF, "skills", "weather_station", SKILL_YAML),
- os.path.join(CUR_PATH, "data", "dummy_skill", SKILL_YAML),
+ DUMMY_SKILL_PATH,
os.path.join(CUR_PATH, "data", "dummy_aea", "skills", "dummy", SKILL_YAML),
os.path.join(CUR_PATH, "data", "dependencies_skill", SKILL_YAML),
os.path.join(CUR_PATH, "data", "exception_skill", SKILL_YAML),
diff --git a/tests/data/aea-config.example_multipage.yaml b/tests/data/aea-config.example_multipage.yaml
index 03ba6f66ee..1b205cb297 100644
--- a/tests/data/aea-config.example_multipage.yaml
+++ b/tests/data/aea-config.example_multipage.yaml
@@ -39,22 +39,18 @@ behaviours:
args:
behaviour_arg_1: 1
behaviour_arg_2: '2'
- class_name: DummyBehaviour
handlers:
dummy:
args:
handler_arg_1: 1
handler_arg_2: '2'
- class_name: DummyHandler
dummy_internal:
args:
handler_arg_1: 1
handler_arg_2: '2'
- class_name: DummyInternalHandler
models:
dummy:
args:
model_arg_1: 1
model_arg_2: '2'
- class_name: DummyModel
...
diff --git a/tests/test_configurations/test_base.py b/tests/test_configurations/test_base.py
index b8e3f700b2..f75385294f 100644
--- a/tests/test_configurations/test_base.py
+++ b/tests/test_configurations/test_base.py
@@ -19,6 +19,7 @@
"""This module contains the tests for the aea.configurations.base module."""
import re
+from copy import copy
from pathlib import Path
from unittest import TestCase, mock
@@ -52,6 +53,7 @@
from tests.conftest import (
AUTHOR,
+ DUMMY_SKILL_PATH,
ROOT_DIR,
agent_config_files,
connection_config_files,
@@ -200,6 +202,37 @@ def test_from_json_and_to_json(self, skill_path):
def test_update_method(self):
"""Test the update method."""
+ skill_config_path = Path(DUMMY_SKILL_PATH)
+ loader = ConfigLoaders.from_package_type(PackageType.SKILL)
+ skill_config = loader.load(skill_config_path.open())
+
+ dummy_behaviour = skill_config.behaviours.read("dummy")
+ expected_dummy_behaviour_args = copy(dummy_behaviour.args)
+ expected_dummy_behaviour_args["new_arg"] = 1
+
+ dummy_handler = skill_config.handlers.read("dummy")
+ expected_dummy_handler_args = copy(dummy_handler.args)
+ expected_dummy_handler_args["new_arg"] = 1
+
+ dummy_model = skill_config.models.read("dummy")
+ expected_dummy_model_args = copy(dummy_model.args)
+ expected_dummy_model_args["new_arg"] = 1
+
+ new_configurations = {
+ "behaviours": {"dummy": {"args": dict(new_arg=1)}},
+ "handlers": {"dummy": {"args": dict(new_arg=1)}},
+ "models": {"dummy": {"args": dict(new_arg=1)}},
+ }
+ skill_config.update(new_configurations)
+
+ assert (
+ expected_dummy_behaviour_args == skill_config.behaviours.read("dummy").args
+ )
+ assert expected_dummy_handler_args == skill_config.handlers.read("dummy").args
+ assert expected_dummy_model_args == skill_config.models.read("dummy").args
+
+ def test_update_method_raises_error_if_skill_component_not_allowed(self):
+ """Test that we raise error if the custom configuration contain unexpected skill components."""
skill_config_path = Path(
ROOT_DIR, "aea", "skills", "error", DEFAULT_SKILL_CONFIG_FILE
)
@@ -210,14 +243,12 @@ def test_update_method(self):
"handlers": {"new_handler": {"args": {}, "class_name": "SomeClass"}},
"models": {"new_model": {"args": {}, "class_name": "SomeClass"}},
}
- skill_config.update(new_configurations)
- new_behaviour = skill_config.behaviours.read("new_behaviour")
- assert new_behaviour.json == new_configurations["behaviours"]["new_behaviour"]
- new_handler = skill_config.handlers.read("new_handler")
- assert new_handler.json == new_configurations["handlers"]["new_handler"]
- new_model = skill_config.models.read("new_model")
- assert new_model.json == new_configurations["models"]["new_model"]
+ with pytest.raises(
+ ValueError,
+ match="The custom configuration for skill fetchai/error:0.6.0 includes new behaviours: {'new_behaviour'}. This is not allowed.",
+ ):
+ skill_config.update(new_configurations)
class TestAgentConfig:
From 3b1637ce20d8a69354a66c1116f53fa4a77841d1 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 29 Sep 2020 15:29:46 +0200
Subject: [PATCH 100/131] fix recursion in jsonschema
---
aea/configurations/loader.py | 12 ++++++------
.../configurable_parts/skill-custom_config.json | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/aea/configurations/loader.py b/aea/configurations/loader.py
index 515dcfd615..0f19ddaea4 100644
--- a/aea/configurations/loader.py
+++ b/aea/configurations/loader.py
@@ -326,7 +326,7 @@ def _dump_component_config(self, configuration: T, file_pointer: TextIO) -> None
yaml_dump(result, file_pointer)
def _process_component_section(
- self, i: int, component_configuration_json: Dict
+ self, component_index: int, component_configuration_json: Dict
) -> ComponentId:
"""
Process a component configuration in an agent configuration file.
@@ -336,12 +336,12 @@ def _process_component_section(
- validate the component configuration
- check that there are only configurable fields
- :param i: the index of the component in the file.
+ :param component_index: the index of the component in the file.
:param component_configuration_json: the JSON object.
:return: the processed component configuration.
"""
component_id = self._split_component_id_and_config(
- i, component_configuration_json
+ component_index, component_configuration_json
)
self._validate_component_configuration(
component_id, component_configuration_json
@@ -350,12 +350,12 @@ def _process_component_section(
@staticmethod
def _split_component_id_and_config(
- i: int, component_configuration_json: Dict
+ component_index: int, component_configuration_json: Dict
) -> ComponentId:
"""
Split component id and configuration.
- :param i: the position of the component configuration in the agent config file..
+ :param component_index: the position of the component configuration in the agent config file..
:param component_configuration_json: the JSON object to process.
:return: the component id and the configuration object.
:raises ValueError: if the component id cannot be extracted.
@@ -366,7 +366,7 @@ def _split_component_id_and_config(
)
if len(missing_fields) > 0:
raise ValueError(
- f"There are missing fields in component id {i + 1}: {missing_fields}."
+ f"There are missing fields in component id {component_index + 1}: {missing_fields}."
)
component_name = component_configuration_json["name"]
component_author = component_configuration_json["author"]
diff --git a/aea/configurations/schemas/configurable_parts/skill-custom_config.json b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
index b470606888..b5ab051d3c 100644
--- a/aea/configurations/schemas/configurable_parts/skill-custom_config.json
+++ b/aea/configurations/schemas/configurable_parts/skill-custom_config.json
@@ -31,7 +31,7 @@
"$ref": "#/definitions/models"
},
"is_abstract": {
- "$ref": "#/properties/is_abstract"
+ "$ref": "skill-config_schema.json#/properties/is_abstract"
}
},
"definitions": {
From 56860c903995daaf0fbf36d727b032eaa596d36f Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 29 Sep 2020 15:34:19 +0200
Subject: [PATCH 101/131] address PR comments
---
aea/configurations/base.py | 4 +++-
aea/configurations/loader.py | 15 +++++++++++----
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 48cd40aa98..2b4d2e6e26 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -1344,7 +1344,9 @@ def _update_skill_component_config(type_plural: str, data: Dict):
)
for component_name, component_data in data.get(type_plural, {}).items():
- component_config = registry.read(component_name)
+ component_config = cast(
+ SkillComponentConfiguration, registry.read(component_name)
+ )
merge_update(component_config.args, component_data.get("args", {}))
_update_skill_component_config("behaviours", data)
diff --git a/aea/configurations/loader.py b/aea/configurations/loader.py
index 0f19ddaea4..4723b209f1 100644
--- a/aea/configurations/loader.py
+++ b/aea/configurations/loader.py
@@ -51,6 +51,11 @@
_CUR_DIR = os.path.dirname(inspect.getfile(inspect.currentframe())) # type: ignore
_SCHEMAS_DIR = os.path.join(_CUR_DIR, "schemas")
+_PREFIX_BASE_CONFIGURABLE_PARTS = "base"
+_SCHEMAS_CONFIGURABLE_PARTS_DIRNAME = "configurable_parts"
+_POSTFIX_CUSTOM_CONFIG = "-custom_config.json"
+STARTING_INDEX_CUSTOM_CONFIGS = 1
+
T = TypeVar(
"T",
AgentConfig,
@@ -83,12 +88,12 @@ def _get_path_to_custom_config_schema_from_type(component_type: ComponentType) -
:param component_type: a component type.
:return: the path to the JSON schema file.
"""
- path_prefix: Path = Path(_SCHEMAS_DIR) / "configurable_parts"
+ path_prefix: Path = Path(_SCHEMAS_DIR) / _SCHEMAS_CONFIGURABLE_PARTS_DIRNAME
if component_type in {ComponentType.SKILL, ComponentType.CONNECTION}:
filename_prefix = component_type.value
else:
- filename_prefix = "base"
- full_path = path_prefix / (filename_prefix + "-custom_config.json")
+ filename_prefix = _PREFIX_BASE_CONFIGURABLE_PARTS
+ full_path = path_prefix / (filename_prefix + _POSTFIX_CUSTOM_CONFIG)
return str(full_path)
@@ -298,7 +303,9 @@ def _get_component_configurations(
"""
component_configurations: Dict[ComponentId, Dict] = {}
# load the other components.
- for i, component_configuration_json in enumerate(configuration_file_jsons[1:]):
+ for i, component_configuration_json in enumerate(
+ configuration_file_jsons[STARTING_INDEX_CUSTOM_CONFIGS:]
+ ):
component_id = self._process_component_section(
i, component_configuration_json
)
From d1223914eedde0517952e677396699be8b052e36 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Tue, 29 Sep 2020 16:03:54 +0100
Subject: [PATCH 102/131] fix logger name in some connections
---
packages/fetchai/connections/ledger/base.py | 11 ++---------
packages/fetchai/connections/ledger/connection.yaml | 6 +++---
.../fetchai/connections/ledger/contract_dispatcher.py | 10 +++++++++-
.../fetchai/connections/ledger/ledger_dispatcher.py | 10 +++++++++-
packages/fetchai/connections/soef/connection.py | 2 +-
packages/fetchai/connections/soef/connection.yaml | 2 +-
packages/hashes.csv | 4 ++--
7 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/packages/fetchai/connections/ledger/base.py b/packages/fetchai/connections/ledger/base.py
index c9fbdd4411..b26b5f8bf9 100644
--- a/packages/fetchai/connections/ledger/base.py
+++ b/packages/fetchai/connections/ledger/base.py
@@ -18,7 +18,6 @@
# ------------------------------------------------------------------------------
"""This module contains base classes for the ledger API connection."""
import asyncio
-import logging
from abc import ABC, abstractmethod
from asyncio import Task
from concurrent.futures._base import Executor
@@ -45,11 +44,11 @@ class RequestDispatcher(ABC):
def __init__(
self,
+ logger: Logger,
connection_state: AsyncState,
loop: Optional[asyncio.AbstractEventLoop] = None,
executor: Optional[Executor] = None,
api_configs: Optional[Dict[str, Dict[str, str]]] = None,
- logger: Optional[Logger] = None,
):
"""
Initialize the request dispatcher.
@@ -61,13 +60,7 @@ def __init__(
self.loop = loop if loop is not None else asyncio.get_event_loop()
self.executor = executor
self._api_configs = api_configs
- self.logger = (
- logger
- if logger is not None
- else logging.getLogger(
- "aea.packages.fetchai.connections.ledger.contract_dispatcher"
- )
- )
+ self.logger = logger
def api_config(self, ledger_id: str) -> Dict[str, str]:
"""Get api config."""
diff --git a/packages/fetchai/connections/ledger/connection.yaml b/packages/fetchai/connections/ledger/connection.yaml
index 63641cb273..2edc0b499a 100644
--- a/packages/fetchai/connections/ledger/connection.yaml
+++ b/packages/fetchai/connections/ledger/connection.yaml
@@ -8,10 +8,10 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmY6YCoxyUXSwQzFvNPKd3nfHaoMsjCLCZAvTGSGwZnZbP
__init__.py: QmZvYZ5ECcWwqiNGh8qNTg735wu51HqaLxTSifUxkQ4KGj
- base.py: QmNnSBVmVgdDFwzqDUncwLHeyDfMEfmvujJdKbdGNGH4Be
+ base.py: QmdWmK8S9dX1U6jiRotdFrEfAbPhLUDvPj8yPiCwsJnUDZ
connection.py: Qmdibf99GzdFjFCcoTX7AiiBVWznKvPZWvur8cngSRNdye
- contract_dispatcher.py: QmXMPf7Mekyfo8SofcVYWWgMwADQZw68cXbmtf1pyKchVc
- ledger_dispatcher.py: QmTGvnN5W7VHZ9McQSyDQ1jPQoFWmQmuR2a3y8LL6J7aiM
+ contract_dispatcher.py: QmNYR1K1MAMo6jZE84XhsTQBDtUZMuCE1PeBpJ2sMxM4dc
+ ledger_dispatcher.py: QmcpASNeDRwuPJ9wLfTHp3qEMutrUZV9VUzLWzvk312K2i
fingerprint_ignore_patterns: []
protocols:
- fetchai/contract_api:0.5.0
diff --git a/packages/fetchai/connections/ledger/contract_dispatcher.py b/packages/fetchai/connections/ledger/contract_dispatcher.py
index c553633baa..f9cddf8341 100644
--- a/packages/fetchai/connections/ledger/contract_dispatcher.py
+++ b/packages/fetchai/connections/ledger/contract_dispatcher.py
@@ -19,6 +19,7 @@
"""This module contains the implementation of the contract API request dispatcher."""
import inspect
+import logging
from typing import Callable, Optional, cast
from aea.contracts import Contract, contract_registry
@@ -38,6 +39,11 @@
)
+_default_logger = logging.getLogger(
+ "aea.packages.fetchai.connections.ledger.contract_dispatcher"
+)
+
+
class ContractApiDialogues(BaseContractApiDialogues):
"""The dialogues class keeps track of all dialogues."""
@@ -73,7 +79,9 @@ class ContractApiRequestDispatcher(RequestDispatcher):
def __init__(self, *args, **kwargs):
"""Initialize the dispatcher."""
- super().__init__(*args, **kwargs)
+ logger = kwargs.pop("logger", None)
+ logger = logger if logger is not None else _default_logger
+ super().__init__(*args, **kwargs, logger=logger)
self._contract_api_dialogues = ContractApiDialogues()
@property
diff --git a/packages/fetchai/connections/ledger/ledger_dispatcher.py b/packages/fetchai/connections/ledger/ledger_dispatcher.py
index 224e5dfbe3..9f38cfd79c 100644
--- a/packages/fetchai/connections/ledger/ledger_dispatcher.py
+++ b/packages/fetchai/connections/ledger/ledger_dispatcher.py
@@ -17,6 +17,7 @@
#
# ------------------------------------------------------------------------------
"""This module contains the implementation of the ledger API request dispatcher."""
+import logging
import time
from typing import cast
@@ -36,6 +37,11 @@
from packages.fetchai.protocols.ledger_api.message import LedgerApiMessage
+_default_logger = logging.getLogger(
+ "aea.packages.fetchai.connections.ledger.ledger_dispatcher"
+)
+
+
class LedgerApiDialogues(BaseLedgerApiDialogues):
"""The dialogues class keeps track of all dialogues."""
@@ -71,7 +77,9 @@ class LedgerApiRequestDispatcher(RequestDispatcher):
def __init__(self, *args, **kwargs):
"""Initialize the dispatcher."""
- super().__init__(*args, **kwargs)
+ logger = kwargs.pop("logger", None)
+ logger = logger if logger is not None else _default_logger
+ super().__init__(*args, **kwargs, logger=logger)
self._ledger_api_dialogues = LedgerApiDialogues()
def get_ledger_id(self, message: Message) -> str:
diff --git a/packages/fetchai/connections/soef/connection.py b/packages/fetchai/connections/soef/connection.py
index 66a39a80b3..9760e022db 100644
--- a/packages/fetchai/connections/soef/connection.py
+++ b/packages/fetchai/connections/soef/connection.py
@@ -63,7 +63,7 @@
from packages.fetchai.protocols.oef_search.message import OefSearchMessage
-_default_logger = logging.getLogger("aea.packages.fetchai.connections.oef")
+_default_logger = logging.getLogger("aea.packages.fetchai.connections.soef")
PUBLIC_ID = PublicId.from_str("fetchai/soef:0.9.0")
diff --git a/packages/fetchai/connections/soef/connection.yaml b/packages/fetchai/connections/soef/connection.yaml
index da4a8d5dc4..3d84862432 100644
--- a/packages/fetchai/connections/soef/connection.yaml
+++ b/packages/fetchai/connections/soef/connection.yaml
@@ -8,7 +8,7 @@ aea_version: '>=0.6.0, <0.7.0'
fingerprint:
README.md: QmS9zorTodmaRyaxocELEwEqHEPowKoG9wgSAak7s59rZD
__init__.py: Qmd5VBGFJHXFe1H45XoUh5mMSYBwvLSViJuGFeMgbPdQts
- connection.py: QmRTPeJ8aTDuWs28EM7vbBEDbZ75XqqzCo8zhSNXEGmeK3
+ connection.py: QmZaBtcck4gXs92SH5vcptJMm1d1f8WqUuCwvfTXnxsc3y
fingerprint_ignore_patterns: []
protocols:
- fetchai/oef_search:0.7.0
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 8826c1bb2b..2c5b8f816b 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -22,14 +22,14 @@ fetchai/agents/weather_station,QmRAs7AY2R9RNi5M4gnSDiQzLb58z4nuCYAnG2UAnv3XC2
fetchai/connections/gym,Qmack3EaCW6ARrHrtCnJmL3kR2xrHutJmgD8uoRVGFz6kH
fetchai/connections/http_client,QmaCa98anLuMAduNWtnApEwLWBcqdVkNBREBZ9T5VPSaUm
fetchai/connections/http_server,QmT6JV2sB1rv7XZgx1bEpMjfQJAtpq775D2n8yvzKzSXYK
-fetchai/connections/ledger,QmYzBWDgAETzBr8PGPyKvdDMJMGPSo3KFiKVP9MmkVGfd9
+fetchai/connections/ledger,QmQRTE8m3ABL8cPeckfsL3pSYyaMFqqo6CFyZJuSfo62BH
fetchai/connections/local,QmNXMDuB7vfGrhv2Q4R8REDicSUgXfVPd7x1tAP3847jsr
fetchai/connections/oef,QmT6nbEYgjHPTwoXqV5FNeg7SUaraXGQGUhGeVGEhqXVDg
fetchai/connections/p2p_libp2p,QmbPgTY8am7PgLoP3ksaHyuwZzfFGXN4cBrvjV9byramEh
fetchai/connections/p2p_libp2p_client,QmSbfL2DT9L1oooKn2pme1tjivEzkzaiRqJ4zahB4Jb27b
fetchai/connections/p2p_stub,QmecGYtXsb7HA2dSWrw2ARNTPFqZsKXAbVroBo57cdUQSG
fetchai/connections/scaffold,QmNUta43nLexAHaXLgmLQYEjntLXSV6MLNvc6Q2CTx7eBS
-fetchai/connections/soef,Qme2vP55mGemMKMWdHKGUaC1nW88ZEdD55qgdY9a984T7i
+fetchai/connections/soef,QmXBtvcw2mQdMwkEaoU9h4pRLkGGZueqJNzGCHA279CNQk
fetchai/connections/stub,QmQxzFLTBjPUMkpE1uBdkoyhb7iXY4k8VPzyykpjhuUcK1
fetchai/connections/tcp,QmPADQqZJQ4cw1ecdMC2wR7NwFCdk7MYzvmyP62nbfGk7E
fetchai/connections/webhook,QmWcm3WGxcm5JvhuYRyauQp5wmzFAkV61e2aYpDvYmNvWd
From 1b93a80c052b9e00983c9ca3e091bfb8daf6343b Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 29 Sep 2020 18:36:46 +0300
Subject: [PATCH 103/131] fixes and tests
---
aea/manager.py | 142 ++++++++++++++------
tests/test_manager.py | 292 +++++++++++++++++++++++++++++++++---------
2 files changed, 334 insertions(+), 100 deletions(-)
diff --git a/aea/manager.py b/aea/manager.py
index a303eb7991..2c711f8057 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -16,6 +16,7 @@
# limitations under the License.
#
# ------------------------------------------------------------------------------
+
"""This module contains the implementation of AEA agents manager."""
import asyncio
import copy
@@ -74,37 +75,43 @@ def start(self) -> None:
def wait(self) -> asyncio.Future:
"""Return future to wait task completed."""
- if not self._done_future:
+ if not self._done_future: # pragma: nocover
raise ValueError("Task not started!")
return self._done_future
def stop(self) -> None:
"""Stop task."""
- if not self.run_loop or not self.task:
+ if not self.run_loop or not self.task: # pragma: nocover
raise ValueError("Task was not started!")
self.run_loop.call_soon_threadsafe(self.task.cancel)
async def _run_wrapper(self) -> None:
"""Run task internals."""
- if not self._done_future:
+ if not self._done_future: # pragma: nocover
raise ValueError("Task was not started! please use start method")
+ exc = None
try:
await self.run()
- self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
- except asyncio.CancelledError:
- self.caller_loop.call_soon_threadsafe(self._done_future.set_result, None)
+ except asyncio.CancelledError: # pragma: nocover
+ pass
except Exception as e: # pylint: disable=broad-except
- self.caller_loop.call_soon_threadsafe(self._done_future.set_exception, e)
+ exc = e
+ finally:
+ self.caller_loop.call_soon_threadsafe(self._set_result, exc)
+
+ def _set_result(self, exc: Optional[BaseException]) -> None:
+ """Set result of task execution."""
+ if not self._done_future: # pragma: nocover
+ return
+ if exc:
+ self._done_future.set_exception(exc)
+ else:
+ self._done_future.set_result(None)
async def run(self) -> None:
"""Run task body."""
self.agent.runtime.set_loop(self.run_loop)
- try:
- self.agent.runtime.start()
- while True:
- await asyncio.sleep(1)
- finally:
- self.agent.runtime.stop()
+ await self.agent.runtime.run()
@property
def is_running(self) -> bool:
@@ -154,7 +161,7 @@ def __init__(self, working_dir: str, mode: str = "async") -> None:
self._agents: Dict[str, AgentAlias] = {}
self._agents_tasks: Dict[str, AsyncTask] = {}
- self._thread = Thread(target=self._run_thread, daemon=True)
+ self._thread: Optional[Thread] = None
self._loop: Optional[asyncio.AbstractEventLoop] = None
self._event: Optional[asyncio.Event] = None
@@ -203,17 +210,26 @@ async def _manager_loop(self) -> None:
agent_name = tasks_for_agents[task]
self._agents_tasks.pop(agent_name)
if task.exception():
- print(agent_name, "exceptioned", task.exception())
for callback in self._error_callbacks:
callback(agent_name, task.exception())
else:
await task
+ def add_error_callback(
+ self, error_callback: Callable[[str, BaseException], None]
+ ) -> None:
+ """Add error callback to call on error raised."""
+ self._error_callbacks.append(error_callback)
+
def start_manager(self) -> "Manager":
"""Start manager."""
+ if self._is_running:
+ return self
+
self._ensure_working_dir()
self._started_event.clear()
self._is_running = True
+ self._thread = Thread(target=self._run_thread, daemon=True)
self._thread.start()
self._started_event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
return self
@@ -226,18 +242,40 @@ def stop_manager(self) -> "Manager":
:return: None
"""
- if not self._loop or not self._event:
+ if not self._is_running:
+ return self
+
+ if not self._loop or not self._event or not self._thread: # pragma: nocover
raise ValueError("Manager was not started!")
- if self._was_working_dir_created:
- rmtree(self.working_dir)
- if self._thread.is_alive():
- self.stop_all_agents()
+ if not self._thread.is_alive(): # pragma: nocover
+ return self
+
+ self.stop_all_agents()
+
+ for agent_name in self.list_agents():
+ self.remove_agent(agent_name)
+
+ for project in list(self._projects.keys()):
+ self.remove_project(project)
+
+ self._cleanup()
+
self._is_running = False
+
self._loop.call_soon_threadsafe(self._event.set)
- self._thread.join(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
+
+ if self._thread.ident != threading.get_ident():
+ self._thread.join(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
+
+ self._thread = None
return self
+ def _cleanup(self) -> None:
+ """Remove workdir if was created."""
+ if self._was_working_dir_created and os.path.exists(self.working_dir):
+ rmtree(self.working_dir)
+
def add_project(self, public_id: PublicId) -> "Manager":
"""Fetch agent project and all dependencies to working_dir."""
if public_id in self._projects:
@@ -290,6 +328,7 @@ def add_agent(
if public_id not in self._projects:
raise ValueError(f"{public_id} project is not added!")
+
project = self._projects[public_id]
agent_alias = self._build_agent_alias(
@@ -310,7 +349,7 @@ def list_agents(self, running_only: bool = False) -> List[str]:
:return: list of agents names
"""
if running_only:
- return list(self._agents_tasks.keys())
+ return [i for i in self._agents.keys() if self._is_agent_running(i)]
return list(self._agents.keys())
def remove_agent(self, agent_name: str) -> "Manager":
@@ -339,12 +378,14 @@ def start_agent(self, agent_name: str) -> "Manager":
:return: None
"""
- if not self._loop or not self._event:
+ if not self._loop or not self._event: # pragma: nocover
raise ValueError("agent is not started!")
agent_alias = self._agents.get(agent_name)
+
if not agent_alias:
raise ValueError(f"{agent_name} is not registered!")
+
if self._is_agent_running(agent_name):
raise ValueError(f"{agent_name} is already started!")
@@ -358,15 +399,13 @@ def start_agent(self, agent_name: str) -> "Manager":
self._loop.call_soon_threadsafe(self._event.set)
return self
- def _is_agent_running(self, agent_name):
+ def _is_agent_running(self, agent_name: str) -> bool:
+ """Return is agent running state."""
if agent_name not in self._agents_tasks:
return False
task = self._agents_tasks[agent_name]
- if task.is_running:
- return True
- del self._agents_tasks[agent_name]
- return False
+ return task.is_running
def start_all_agents(self) -> "Manager":
"""
@@ -374,10 +413,13 @@ def start_all_agents(self) -> "Manager":
:return: None
"""
- for agent_name in self.list_agents():
- if self._is_agent_running(agent_name):
- continue
- self.start_agent(agent_name)
+ self.start_agents(
+ [
+ agent_name
+ for agent_name in self.list_agents()
+ if not self._is_agent_running(agent_name)
+ ]
+ )
return self
@@ -389,15 +431,31 @@ def stop_agent(self, agent_name: str) -> "Manager":
:return: None
"""
- if not self._is_agent_running(agent_name):
+ if not self._is_agent_running(agent_name) or not self._thread or not self._loop:
raise ValueError(f"{agent_name} is not running!")
- if self._thread.ident == threading.get_ident():
+
+ agent_task = self._agents_tasks[agent_name]
+
+ if self._thread.ident == threading.get_ident(): # pragma: nocover
# In same thread do not perform blocking operations!
- self._agents_tasks[agent_name].stop()
+ agent_task.stop()
return self
+
+ wait_future = agent_task.wait()
+
event = threading.Event()
- self._agents_tasks[agent_name].wait().add_done_callback(lambda x: event.set())
- self._agents_tasks[agent_name].stop()
+
+ def event_set(*args): # pylint: disable=unused-argument
+ event.set()
+
+ def _add_cb():
+ if wait_future.done():
+ event_set() # pragma: nocover
+ else:
+ wait_future.add_done_callback(event_set) # pramga: nocover
+
+ self._loop.call_soon_threadsafe(_add_cb)
+ agent_task.stop()
event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
return self
@@ -408,8 +466,8 @@ def stop_all_agents(self) -> "Manager":
:return: None
"""
- for agent_name in self.list_agents(running_only=True):
- self.stop_agent(agent_name)
+ agents_list = self.list_agents(running_only=True)
+ self.stop_agents(agents_list)
return self
@@ -445,7 +503,7 @@ def get_agent_alias(self, agent_name: str) -> AgentAlias:
:return: AgentAlias
"""
- if agent_name not in self._agents:
+ if agent_name not in self._agents: # pragma: nocover
raise ValueError(f"Agent with name {agent_name} does not exist!")
return self._agents[agent_name]
@@ -455,7 +513,7 @@ def _ensure_working_dir(self) -> None:
os.makedirs(self.working_dir)
self._was_working_dir_created = True
- if not os.path.isdir(self.working_dir):
+ if not os.path.isdir(self.working_dir): # pragma: nocover
raise ValueError(f"{self.working_dir} is not a directory!")
os.makedirs(self._keys_dir)
@@ -473,7 +531,7 @@ def _build_agent_alias(
builder = AEABuilder.from_config_json(json_config, project.path)
builder.set_name(agent_name)
- # builder.set_runtime_mode("async")
+ builder.set_runtime_mode("threaded")
if not builder.private_key_paths:
default_ledger = json_config[0].get("default_ledger", DEFAULT_LEDGER)
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 170ea6b96e..a0b08ecf6a 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -18,50 +18,91 @@
# ------------------------------------------------------------------------------
"""This module contains tests for aea manager."""
import os
-import time
-from contextlib import suppress
-from shutil import rmtree
+from unittest.mock import Mock, patch
import pytest
from aea.configurations.base import PublicId
from aea.manager import Manager
+from tests.common.utils import wait_for_condition
-def test_manager():
- """Perform some tests."""
- # pydocsyle
- try:
- working_dir = "manager_dir"
- project_public_id = PublicId("fetchai", "my_first_aea", "0.11.0")
- project_path = os.path.join(
- working_dir, project_public_id.author, project_public_id.name
+
+class TestManagerAsyncMode: # pylint: disable=unused-argument,protected-access,attribute-defined-outside-init
+ """Tests for manager in async mode."""
+
+ MODE = "async"
+
+ echo_skill_id = PublicId("fetchai", "echo", "0.7.0")
+
+ def setup(self):
+ """Set test case."""
+ self.agent_name = "test_what_ever12"
+ self.working_dir = "manager_dir"
+ self.project_public_id = PublicId("fetchai", "my_first_aea", "0.11.0")
+ self.project_path = os.path.join(
+ self.working_dir, self.project_public_id.author, self.project_public_id.name
)
- assert not os.path.exists(working_dir)
- manager = Manager(working_dir)
- manager.start_manager()
- assert os.path.exists(working_dir)
- assert manager.is_running
+ assert not os.path.exists(self.working_dir)
+ self.manager = Manager(self.working_dir, mode=self.MODE)
+
+ def teardown(self):
+ """Tear down test case."""
+ self.manager.stop_manager()
+
+ def test_workdir_created_removed(self):
+ """Check work dit created removed on manager start and stop."""
+ assert not os.path.exists(self.working_dir)
+ self.manager.start_manager()
+ assert os.path.exists(self.working_dir)
+ self.manager.stop_manager()
+ assert not os.path.exists(self.working_dir)
+
+ def test_manager_is_running(self):
+ """Check manager is running property reflects state."""
+ assert not self.manager.is_running
+ self.manager.start_manager()
+ assert self.manager.is_running
+ self.manager.stop_manager()
+ assert not self.manager.is_running
- manager.add_project(project_public_id)
+ def test_add_remove_project(self):
+ """Test add and remove project."""
+ self.manager.start_manager()
- assert project_public_id in manager.list_projects()
- assert os.path.exists(project_path)
- assert manager._projects[project_public_id].path == project_path
+ self.manager.add_project(self.project_public_id)
+
+ assert self.project_public_id in self.manager.list_projects()
+ assert os.path.exists(self.project_path)
with pytest.raises(ValueError, match=r".*was already added.*"):
- manager.add_project(project_public_id)
-
- echo_skill_id = PublicId("fetchai", "echo", "0.7.0")
- new_tick_interval = 1.1111
- agent_name = "test_what_ever12"
- manager.add_agent(
- project_public_id,
- agent_name,
+ self.manager.add_project(self.project_public_id)
+
+ self.manager.remove_project(self.project_public_id)
+ assert self.project_public_id not in self.manager.list_projects()
+
+ with pytest.raises(ValueError, match=r"was not added"):
+ self.manager.remove_project(self.project_public_id)
+
+ self.manager.add_project(self.project_public_id)
+ assert self.project_public_id in self.manager.list_projects()
+ assert os.path.exists(self.project_path)
+
+ def test_add_agent(self):
+ """Test add agent alias."""
+ self.manager.start_manager()
+
+ self.manager.add_project(self.project_public_id)
+
+ new_tick_interval = 0.2111
+
+ self.manager.add_agent(
+ self.project_public_id,
+ self.agent_name,
component_overrides=[
{
"type": "skill",
- **echo_skill_id.json,
+ **self.echo_skill_id.json,
"behaviours": {
"echo": {
"args": {"tick_interval": new_tick_interval},
@@ -71,47 +112,182 @@ def test_manager():
}
],
)
- agent_alias = manager.get_agent_details(agent_name)
- assert agent_alias.name == agent_name
+ agent_alias = self.manager.get_agent_alias(self.agent_name)
+ assert agent_alias.name == self.agent_name
assert (
agent_alias.agent.resources.get_behaviour(
- echo_skill_id, "echo"
+ self.echo_skill_id, "echo"
).tick_interval
== new_tick_interval
)
with pytest.raises(ValueError, match="already exists"):
- manager.add_agent(
- project_public_id, agent_name,
+ self.manager.add_agent(
+ self.project_public_id, self.agent_name,
)
- assert agent_name in manager.list_agents()
- manager.start_all_agents()
- assert agent_name in manager.list_agents(running_only=True)
- manager.start_all_agents()
+
+ def test_remove_agent(self):
+ """Test remove agent alias."""
+ self.test_add_agent()
+ assert self.agent_name in self.manager.list_agents()
+ self.manager.remove_agent(self.agent_name)
+ assert self.agent_name not in self.manager.list_agents()
+
+ with pytest.raises(ValueError, match="does not exist!"):
+ self.manager.remove_agent(self.agent_name)
+
+ def test_remove_project_with_alias(self):
+ """Test remove project with alias presents."""
+ self.test_add_agent()
+
+ with pytest.raises(
+ ValueError, match="Can not remove projects with aliases exists"
+ ):
+ self.manager.remove_project(self.project_public_id)
+
+ def test_add_agent_for_non_exist_project(self):
+ """Test add agent when no project added."""
+ with pytest.raises(ValueError, match=" project is not added"):
+ self.manager.add_agent(PublicId("test", "test", "0.1.0"), "another_agent")
+
+ def test_agent_acually_running(self):
+ """Test manager starts agent correctly and agent perform acts."""
+ self.test_add_agent()
+ agent_alias = self.manager.get_agent_alias(self.agent_name)
+ behaviour = agent_alias.agent.resources.get_behaviour(
+ self.echo_skill_id, "echo"
+ )
+ assert behaviour
+ with patch.object(behaviour, "act") as act_mock:
+ self.manager.start_all_agents()
+ wait_for_condition(lambda: act_mock.call_count > 0, timeout=10)
+
+ def test_exception_handling(self):
+ """Test erro callback works."""
+ self.test_add_agent()
+ agent_alias = self.manager.get_agent_alias(self.agent_name)
+ behaviour = agent_alias.agent.resources.get_behaviour(
+ self.echo_skill_id, "echo"
+ )
+ callback_mock = Mock()
+
+ self.manager.add_error_callback(callback_mock)
+ assert behaviour
+
+ with patch.object(behaviour, "act", side_effect=ValueError("expected")):
+ self.manager.start_all_agents()
+ wait_for_condition(lambda: callback_mock.call_count > 0, timeout=10)
+
+ def test_stop_from_exception_handling(self):
+ """Test stop manager from erro callback."""
+ self.test_add_agent()
+ agent_alias = self.manager.get_agent_alias(self.agent_name)
+ behaviour = agent_alias.agent.resources.get_behaviour(
+ self.echo_skill_id, "echo"
+ )
+
+ def handler(*args, **kwargs):
+ self.manager.stop_manager()
+
+ self.manager.add_error_callback(handler)
+
+ assert behaviour
+
+ with patch.object(behaviour, "act", side_effect=ValueError("expected")):
+ self.manager.start_all_agents()
+ wait_for_condition(lambda: not self.manager.is_running, timeout=10)
+
+ def test_start_all(self):
+ """Test manager start all agents."""
+ self.test_add_agent()
+ assert self.agent_name in self.manager.list_agents()
+ assert self.agent_name not in self.manager.list_agents(running_only=True)
+ self.manager.start_all_agents()
+ assert self.agent_name in self.manager.list_agents(running_only=True)
+
+ self.manager.start_all_agents()
+
+ with pytest.raises(ValueError, match="is already started!"):
+ self.manager.start_agents(self.manager.list_agents())
with pytest.raises(ValueError, match="is already started!"):
- manager.start_agents(manager.list_agents())
+ self.manager.start_agent(self.agent_name)
+
+ with pytest.raises(ValueError, match="is not registered!"):
+ self.manager.start_agent("non_exists_agent")
+
+ def test_stop_agent(self):
+ """Test stop agent."""
+ self.test_start_all()
+ wait_for_condition(
+ lambda: self.manager.list_agents(running_only=True), timeout=10
+ )
+ self.manager.stop_all_agents()
+
+ assert not self.manager.list_agents(running_only=True)
+ with pytest.raises(ValueError, match=" is not running!"):
+ self.manager.stop_agent(self.agent_name)
+
+ with pytest.raises(ValueError, match=" is not running!"):
+ self.manager.stop_agents([self.agent_name])
+
+ def test_do_no_allow_override_some_fields(self):
+ """Do not allo to override some values in agent config."""
+ self.manager.start_manager()
+
+ self.manager.add_project(self.project_public_id)
+
+ BAD_OVERRIDES = ["skills", "connections", "contracts", "protocols"]
+
+ for bad_override in BAD_OVERRIDES:
+ with pytest.raises(ValueError, match="Do not override any"):
+ self.manager.add_agent(
+ self.project_public_id,
+ self.agent_name,
+ agent_overrides={bad_override: "some value"},
+ )
+
+ @staticmethod
+ def test_invalid_mode():
+ """Test manager fails on invalid mode."""
+ with pytest.raises(ValueError, match="Invalid mode"):
+ Manager("test_dir", mode="invalid_mode")
+
+ def test_double_start(self):
+ """Test double manager start."""
+ self.manager.start_manager()
+ self.manager.start_manager()
+
+ def test_double_stop(self):
+ """Test double manager stop."""
+ self.manager.start_manager()
+ self.manager.stop_manager()
+ self.manager.stop_manager()
+
+ @pytest.mark.asyncio
+ async def test_run_loop_direct_call(self):
+ """Test do not allow to run manager_loop directly."""
+ with pytest.raises(
+ ValueError, match="Do not use this method directly, use start_manager"
+ ):
+ await self.manager._manager_loop()
+
+ def test_remove_running_agent(self):
+ """Test fail on remove running agent."""
+ self.test_start_all()
with pytest.raises(ValueError, match="Agent is running. stop it first!"):
- manager.remove_agent(agent_name)
+ self.manager.remove_agent(self.agent_name)
- time.sleep(2)
- manager.stop_all_agents()
+ self.manager.stop_all_agents()
+ wait_for_condition(
+ lambda: self.agent_name not in self.manager.list_agents(running_only=True),
+ timeout=5,
+ )
+ self.manager.remove_agent(self.agent_name)
+ assert self.agent_name not in self.manager.list_agents()
- manager.remove_agent(agent_name)
- assert agent_name not in manager.list_agents()
- with pytest.raises(ValueError, match="does not exist!"):
- manager.remove_agent(agent_name)
- manager.remove_project(project_public_id)
- assert project_public_id not in manager._projects
- assert not os.path.exists(project_path)
- assert project_public_id not in manager.list_projects()
+class TestManagerThreadedMode(TestManagerAsyncMode):
+ """Tests for manager in threaded mode."""
- with pytest.raises(ValueError, match=r"was not added"):
- manager.remove_project(project_public_id)
- manager.stop_manager()
- assert not os.path.exists(working_dir)
- assert not manager.is_running
- finally:
- with suppress(FileNotFoundError):
- rmtree(working_dir)
+ MODE = "threaded"
From 8eb1b6d7492b41b7bbf6f9f34691c0e8f4acd58a Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Tue, 29 Sep 2020 17:03:54 +0100
Subject: [PATCH 104/131] fix issues with previous commit
---
packages/fetchai/connections/ledger/connection.yaml | 4 ++--
packages/fetchai/connections/ledger/contract_dispatcher.py | 3 ++-
packages/fetchai/connections/ledger/ledger_dispatcher.py | 2 +-
packages/hashes.csv | 2 +-
4 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/packages/fetchai/connections/ledger/connection.yaml b/packages/fetchai/connections/ledger/connection.yaml
index 2edc0b499a..e5e6fb9093 100644
--- a/packages/fetchai/connections/ledger/connection.yaml
+++ b/packages/fetchai/connections/ledger/connection.yaml
@@ -10,8 +10,8 @@ fingerprint:
__init__.py: QmZvYZ5ECcWwqiNGh8qNTg735wu51HqaLxTSifUxkQ4KGj
base.py: QmdWmK8S9dX1U6jiRotdFrEfAbPhLUDvPj8yPiCwsJnUDZ
connection.py: Qmdibf99GzdFjFCcoTX7AiiBVWznKvPZWvur8cngSRNdye
- contract_dispatcher.py: QmNYR1K1MAMo6jZE84XhsTQBDtUZMuCE1PeBpJ2sMxM4dc
- ledger_dispatcher.py: QmcpASNeDRwuPJ9wLfTHp3qEMutrUZV9VUzLWzvk312K2i
+ contract_dispatcher.py: QmbwomSmrddSY4wREL7ywHF2p9qQ3daCiv9VoYf9cbBR61
+ ledger_dispatcher.py: QmfFNHQQdGiE33Cef5vRHMnXJmLVr6mQGR3iENx5ShDnQk
fingerprint_ignore_patterns: []
protocols:
- fetchai/contract_api:0.5.0
diff --git a/packages/fetchai/connections/ledger/contract_dispatcher.py b/packages/fetchai/connections/ledger/contract_dispatcher.py
index f9cddf8341..503d116088 100644
--- a/packages/fetchai/connections/ledger/contract_dispatcher.py
+++ b/packages/fetchai/connections/ledger/contract_dispatcher.py
@@ -81,7 +81,8 @@ def __init__(self, *args, **kwargs):
"""Initialize the dispatcher."""
logger = kwargs.pop("logger", None)
logger = logger if logger is not None else _default_logger
- super().__init__(*args, **kwargs, logger=logger)
+
+ super().__init__(logger, *args, **kwargs)
self._contract_api_dialogues = ContractApiDialogues()
@property
diff --git a/packages/fetchai/connections/ledger/ledger_dispatcher.py b/packages/fetchai/connections/ledger/ledger_dispatcher.py
index 9f38cfd79c..4756d9a1eb 100644
--- a/packages/fetchai/connections/ledger/ledger_dispatcher.py
+++ b/packages/fetchai/connections/ledger/ledger_dispatcher.py
@@ -79,7 +79,7 @@ def __init__(self, *args, **kwargs):
"""Initialize the dispatcher."""
logger = kwargs.pop("logger", None)
logger = logger if logger is not None else _default_logger
- super().__init__(*args, **kwargs, logger=logger)
+ super().__init__(logger, *args, **kwargs)
self._ledger_api_dialogues = LedgerApiDialogues()
def get_ledger_id(self, message: Message) -> str:
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 2c5b8f816b..712b147ae5 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -22,7 +22,7 @@ fetchai/agents/weather_station,QmRAs7AY2R9RNi5M4gnSDiQzLb58z4nuCYAnG2UAnv3XC2
fetchai/connections/gym,Qmack3EaCW6ARrHrtCnJmL3kR2xrHutJmgD8uoRVGFz6kH
fetchai/connections/http_client,QmaCa98anLuMAduNWtnApEwLWBcqdVkNBREBZ9T5VPSaUm
fetchai/connections/http_server,QmT6JV2sB1rv7XZgx1bEpMjfQJAtpq775D2n8yvzKzSXYK
-fetchai/connections/ledger,QmQRTE8m3ABL8cPeckfsL3pSYyaMFqqo6CFyZJuSfo62BH
+fetchai/connections/ledger,QmPwbSbzK66j147Bjjxaqp3jRAR2ui59zthqFAqB5i7Uxy
fetchai/connections/local,QmNXMDuB7vfGrhv2Q4R8REDicSUgXfVPd7x1tAP3847jsr
fetchai/connections/oef,QmT6nbEYgjHPTwoXqV5FNeg7SUaraXGQGUhGeVGEhqXVDg
fetchai/connections/p2p_libp2p,QmbPgTY8am7PgLoP3ksaHyuwZzfFGXN4cBrvjV9byramEh
From f82f467650c86c74d1622ddb5002a4d3a93762f5 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 29 Sep 2020 18:18:08 +0200
Subject: [PATCH 105/131] update tests
---
aea/aea_builder.py | 4 +-
aea/configurations/base.py | 6 +--
aea/helpers/base.py | 23 ++++++------
tests/test_aea_builder.py | 21 +++++------
tests/test_configurations/test_base.py | 21 ++++++++---
tests/test_helpers/test_base.py | 51 +++++++++++++++++++++++++-
6 files changed, 91 insertions(+), 35 deletions(-)
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index 3e71026779..82e66e5276 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -1372,10 +1372,10 @@ def _load_and_add_components(
logging.Logger, make_logger(configuration, agent_name)
)
else:
- if configuration.is_abstract_component:
+ new_configuration = self._overwrite_custom_configuration(configuration)
+ if new_configuration.is_abstract_component:
load_aea_package(configuration)
continue
- new_configuration = self._overwrite_custom_configuration(configuration)
_logger = make_logger(new_configuration, agent_name)
component = load_component_from_config(
new_configuration, logger=_logger, **kwargs
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 2b4d2e6e26..190dee4ef3 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -53,7 +53,7 @@
from aea.__version__ import __version__ as __aea_version__
from aea.exceptions import enforce
-from aea.helpers.base import merge_update
+from aea.helpers.base import recursive_update
from aea.helpers.ipfs.base import IPFSHashOnly
@@ -1065,7 +1065,7 @@ def update(self, data: Dict) -> None:
:return: None
"""
new_config = data.get("config", {})
- merge_update(self.config, new_config)
+ recursive_update(self.config, new_config)
class ProtocolConfig(ComponentConfiguration):
@@ -1347,7 +1347,7 @@ def _update_skill_component_config(type_plural: str, data: Dict):
component_config = cast(
SkillComponentConfiguration, registry.read(component_name)
)
- merge_update(component_config.args, component_data.get("args", {}))
+ recursive_update(component_config.args, component_data.get("args", {}))
_update_skill_component_config("behaviours", data)
_update_skill_component_config("handlers", data)
diff --git a/aea/helpers/base.py b/aea/helpers/base.py
index e39a9fe80b..3289f0c175 100644
--- a/aea/helpers/base.py
+++ b/aea/helpers/base.py
@@ -392,36 +392,37 @@ def exception_log_and_reraise(log_method: Callable, message: str):
raise
-def merge_update(to_update: Dict, new_values: Dict):
+def recursive_update(to_update: Dict, new_values: Dict):
"""
- Merge two dictionaries by replacing conflicts with the new values.
+ Update a dictionary by replacing conflicts with the new values.
It does side-effects to the first dictionary.
>>> to_update = dict(a=1, b=2, subdict=dict(subfield1=1))
- >>> new_values = dict(b=3, c=4, subdict=dict(subfield2=2))
- >>> merge_update(to_update, new_values)
+ >>> new_values = dict(b=3, subdict=dict(subfield1=2))
+ >>> recursive_update(to_update, new_values)
>>> to_update
- {'a': 1, 'b': 3, 'subdict': {'subfield1': 1, 'subfield2': 2}, 'c': 4}
+ {'a': 1, 'b': 3, 'subdict': {'subfield1': 2}}
:param to_update: the dictionary to update.
- :param new_values: the dictionary of new values to add/replace.
- :return: the merged dictionary.
+ :param new_values: the dictionary of new values to replace.
+ :return: the updated dictionary.
"""
for key, value in new_values.items():
if key not in to_update:
- to_update[key] = value
- continue
+ raise ValueError(
+ f"Key '{key}' is not contained in the dictionary to update."
+ )
value_to_update = to_update[key]
value_type = type(value)
value_to_update_type = type(value_to_update)
if value_type != value_to_update_type:
raise ValueError(
- f"Trying to replace value '{value}' with value '{value_to_update}' which is of different type."
+ f"Trying to replace value '{value_to_update}' with value '{value}' which is of different type."
)
if value_type == value_to_update_type == dict:
- merge_update(value_to_update, value)
+ recursive_update(value_to_update, value)
else:
to_update[key] = value
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index 667a3b6a96..f99aa5fbec 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -616,18 +616,15 @@ def _add_dummy_skill_config(self):
behaviours:
dummy:
args:
- {indent(yaml.dump(self.expected_behaviour_args), " ")}
- class_name: DummyBehaviour
+ {indent(yaml.dump(self.new_behaviour_args), " ")}
handlers:
dummy:
args:
- {indent(yaml.dump(self.expected_handler_args), " ")}
- class_name: DummyHandler
+ {indent(yaml.dump(self.new_handler_args), " ")}
models:
dummy:
args:
- {indent(yaml.dump(self.expected_model_args), " ")}
- class_name: DummyModel
+ {indent(yaml.dump(self.new_model_args), " ")}
...
"""
)
@@ -635,9 +632,9 @@ def _add_dummy_skill_config(self):
def test_from_project(self):
"""Test builder set from project dir."""
- self.expected_behaviour_args = {"behaviour_arg_1": 42}
- self.expected_handler_args = {"handler_arg_1": 42}
- self.expected_model_args = {"model_arg_1": 42}
+ self.new_behaviour_args = {"behaviour_arg_1": 42}
+ self.new_handler_args = {"handler_arg_1": 42}
+ self.new_model_args = {"model_arg_1": 42}
self._add_dummy_skill_config()
builder = AEABuilder.from_aea_project(Path(self._get_cwd()))
with cd(self._get_cwd()):
@@ -647,11 +644,11 @@ def test_from_project(self):
PublicId("dummy_author", "dummy", "0.1.0")
)
dummy_behaviour = dummy_skill.behaviours["dummy"]
- assert dummy_behaviour.config == self.expected_behaviour_args
+ assert dummy_behaviour.config == {"behaviour_arg_1": 42, "behaviour_arg_2": "2"}
dummy_handler = dummy_skill.handlers["dummy"]
- assert dummy_handler.config == self.expected_handler_args
+ assert dummy_handler.config == {"handler_arg_1": 42, "handler_arg_2": "2"}
dummy_model = dummy_skill.models["dummy"]
- assert dummy_model.config == self.expected_model_args
+ assert dummy_model.config == {"model_arg_1": 42, "model_arg_2": "2"}
class TestFromAEAProjectMakeSkillAbstract(AEATestCase):
diff --git a/tests/test_configurations/test_base.py b/tests/test_configurations/test_base.py
index f75385294f..c2fb7954ec 100644
--- a/tests/test_configurations/test_base.py
+++ b/tests/test_configurations/test_base.py
@@ -208,20 +208,20 @@ def test_update_method(self):
dummy_behaviour = skill_config.behaviours.read("dummy")
expected_dummy_behaviour_args = copy(dummy_behaviour.args)
- expected_dummy_behaviour_args["new_arg"] = 1
+ expected_dummy_behaviour_args["behaviour_arg_1"] = 42
dummy_handler = skill_config.handlers.read("dummy")
expected_dummy_handler_args = copy(dummy_handler.args)
- expected_dummy_handler_args["new_arg"] = 1
+ expected_dummy_handler_args["handler_arg_1"] = 42
dummy_model = skill_config.models.read("dummy")
expected_dummy_model_args = copy(dummy_model.args)
- expected_dummy_model_args["new_arg"] = 1
+ expected_dummy_model_args["model_arg_1"] = 42
new_configurations = {
- "behaviours": {"dummy": {"args": dict(new_arg=1)}},
- "handlers": {"dummy": {"args": dict(new_arg=1)}},
- "models": {"dummy": {"args": dict(new_arg=1)}},
+ "behaviours": {"dummy": {"args": dict(behaviour_arg_1=42)}},
+ "handlers": {"dummy": {"args": dict(handler_arg_1=42)}},
+ "models": {"dummy": {"args": dict(model_arg_1=42)}},
}
skill_config.update(new_configurations)
@@ -744,3 +744,12 @@ def test_package_version_lt():
v2 = PackageVersion("0.2.0")
v3 = PackageVersion("latest")
assert v1 < v2 < v3
+
+
+def test_configuration_class():
+ """Test the attribute 'configuration class' of PackageType."""
+ assert PackageType.PROTOCOL.configuration_class() == ProtocolConfig
+ assert PackageType.CONNECTION.configuration_class() == ConnectionConfig
+ assert PackageType.CONTRACT.configuration_class() == ContractConfig
+ assert PackageType.SKILL.configuration_class() == SkillConfig
+ assert PackageType.AGENT.configuration_class() == AgentConfig
diff --git a/tests/test_helpers/test_base.py b/tests/test_helpers/test_base.py
index b063cc3732..24b5678032 100644
--- a/tests/test_helpers/test_base.py
+++ b/tests/test_helpers/test_base.py
@@ -38,6 +38,7 @@
load_env_file,
load_module,
locate,
+ recursive_update,
retry_decorator,
send_control_c,
try_decorator,
@@ -209,7 +210,7 @@ def test_send_control_c():
# because o/w pytest would be stopped.
process = Popen( # nosec
["timeout" if platform.system() == "Windows" else "sleep", "5"],
- **win_popen_kwargs()
+ **win_popen_kwargs(),
)
time.sleep(0.001)
send_control_c(process)
@@ -241,3 +242,51 @@ def test_yaml_dump_all_load_all():
f.seek(0)
assert yaml_load_all(f) == data
+
+
+def test_recursive_update_no_recursion():
+ """Test the 'recursive update' utility, in the case there's no recursion."""
+ to_update = dict(not_updated=0, an_integer=1, a_list=[1, 2, 3], a_tuple=(1, 2, 3))
+
+ new_integer, new_list, new_tuple = 2, [3], (3,)
+ new_values = dict(an_integer=new_integer, a_list=new_list, a_tuple=new_tuple)
+ recursive_update(to_update, new_values)
+ assert to_update == dict(
+ not_updated=0, an_integer=new_integer, a_list=new_list, a_tuple=new_tuple
+ )
+
+
+def test_recursive_update_with_recursion():
+ """Test the 'recursive update' utility with recursion."""
+ # here we try to update an integer and add a new value
+ to_update = dict(subdict=dict(to_update=1))
+ new_values = dict(subdict=dict(to_update=2))
+
+ recursive_update(to_update, new_values)
+ assert to_update == dict(subdict=dict(to_update=2))
+
+
+def test_recursive_update_negative_different_type():
+ """Test the 'recursive update' utility, when the types are different."""
+ # here we try to update an integer with a boolean - it raises error.
+ to_update = dict(subdict=dict(to_update=1))
+ new_values = dict(subdict=dict(to_update=False))
+
+ with pytest.raises(
+ ValueError,
+ match=f"Trying to replace value '1' with value 'False' which is of different type.",
+ ):
+ recursive_update(to_update, new_values)
+
+
+def test_recursive_update_negative_unknown_field():
+ """Test the 'recursive update' utility, when there are unknown fields."""
+ # here we try to update an integer with a boolean - it raises error.
+ to_update = dict(subdict=dict(field=1))
+ new_values = dict(subdict=dict(new_field=False))
+
+ with pytest.raises(
+ ValueError,
+ match=f"Key 'new_field' is not contained in the dictionary to update.",
+ ):
+ recursive_update(to_update, new_values)
From 437c116e969acc9b844d690fbe9a03203f1cca4a Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 29 Sep 2020 23:59:35 +0300
Subject: [PATCH 106/131] fixes
---
aea/configurations/project.py | 21 ++++++++-
aea/manager.py | 88 +++++++++++++++--------------------
scripts/whitelist.py | 9 ++++
tests/test_manager.py | 40 ++++++++--------
4 files changed, 87 insertions(+), 71 deletions(-)
diff --git a/aea/configurations/project.py b/aea/configurations/project.py
index 8aeace45b8..11e6631807 100644
--- a/aea/configurations/project.py
+++ b/aea/configurations/project.py
@@ -19,8 +19,9 @@
"""This module contains the implementation of AEA agents project configuiration."""
import os
from shutil import rmtree
-from typing import Set
+from typing import Dict, List, Set
+from aea.aea import AEA
from aea.cli.registry.fetch import fetch_agent
from aea.cli.utils.context import Context
from aea.configurations.base import PublicId
@@ -48,3 +49,21 @@ def load(cls, working_dir: str, public_id: PublicId) -> "Project":
def remove(self) -> None:
"""Remove project, do cleanup."""
rmtree(self.path)
+
+
+class AgentAlias:
+ """Agent alias representation."""
+
+ def __init__(
+ self, project: Project, agent_name: str, config: List[Dict], agent: AEA
+ ):
+ """Init agent alias with project, config, name, agent."""
+ self.project = project
+ self.config = config
+ self.agent_name = agent_name
+ self.agent = agent
+ self.project.agents.add(self.agent_name)
+
+ def remove_from_project(self):
+ """Remove agent alias from project."""
+ self.project.agents.remove(self.agent_name)
diff --git a/aea/manager.py b/aea/manager.py
index 2c711f8057..470e4f8e0f 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -31,28 +31,12 @@
from aea.aea_builder import AEABuilder
from aea.configurations.base import ComponentId, PublicId
from aea.configurations.constants import DEFAULT_LEDGER
-from aea.configurations.project import Project
+from aea.configurations.project import AgentAlias, Project
from aea.crypto.helpers import create_private_key
from aea.helpers.base import yaml_load_all
-class AgentAlias:
- """Agent alias representation."""
-
- def __init__(self, project: Project, name: str, config: List[Dict], agent: AEA):
- """Init agent alias with project, config, name, agent."""
- self.project = project
- self.config = config
- self.name = name
- self.agent = agent
- self.project.agents.add(self.name)
-
- def remove(self):
- """Remove agent alias from project."""
- self.project.agents.remove(self.name)
-
-
-class AsyncTask:
+class AgentRunAsyncTask:
"""Async task wrapper for agent."""
def __init__(self, agent: AEA, loop: asyncio.AbstractEventLoop) -> None:
@@ -119,12 +103,12 @@ def is_running(self) -> bool:
return not self.wait().done()
-class ThreadedTask(AsyncTask):
- """Threaded task."""
+class AgentRunThreadTask(AgentRunAsyncTask):
+ """Threaded wrapper to run agent."""
def __init__(self, agent: AEA, loop: asyncio.AbstractEventLoop) -> None:
"""Init task with agent and loop."""
- AsyncTask.__init__(self, agent, loop)
+ AgentRunAsyncTask.__init__(self, agent, loop)
self._thread: Optional[Thread] = None
def create_run_loop(self) -> None:
@@ -140,12 +124,12 @@ def start(self) -> None:
self._thread.start()
-class Manager:
- """Abstract agents manager."""
+class MultiAgentManager:
+ """Multi agents manager."""
AGENT_DO_NOT_OVERRIDE_VALUES = ["skills", "connections", "protocols", "contracts"]
MODES = ["async", "threaded"]
- DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS = 60
+ DEFAULT_TIMEOUT_FOR_BLOCKING_OPERATIONS = 60
def __init__(self, working_dir: str, mode: str = "async") -> None:
"""
@@ -159,7 +143,7 @@ def __init__(self, working_dir: str, mode: str = "async") -> None:
self._projects: Dict[PublicId, Project] = {}
self._keys_dir = os.path.abspath(os.path.join(self.working_dir, "keys"))
self._agents: Dict[str, AgentAlias] = {}
- self._agents_tasks: Dict[str, AsyncTask] = {}
+ self._agents_tasks: Dict[str, AgentRunAsyncTask] = {}
self._thread: Optional[Thread] = None
self._loop: Optional[asyncio.AbstractEventLoop] = None
@@ -186,28 +170,30 @@ def _run_thread(self) -> None:
self._loop.run_until_complete(self._manager_loop())
async def _manager_loop(self) -> None:
- """Perform manager stop."""
+ """Await and control running manager."""
if not self._event:
raise ValueError("Do not use this method directly, use start_manager.")
self._started_event.set()
while self._is_running:
- tasks_for_agents = {
+ agents_run_tasks_futures = {
task.wait(): agent_name
for agent_name, task in self._agents_tasks.items()
}
- wait_tasks = list(tasks_for_agents.keys()) + [self._event.wait()] # type: ignore
+ wait_tasks = list(agents_run_tasks_futures.keys()) + [self._event.wait()] # type: ignore
done, _ = await asyncio.wait(wait_tasks, return_when=FIRST_COMPLETED)
if self._event.is_set():
self._event.clear()
for task in done:
- if task not in tasks_for_agents:
+ if task not in agents_run_tasks_futures:
+ # task not in agents_run_tasks_futures, so it's event_wait, skip it
await task
continue
- agent_name = tasks_for_agents[task]
+
+ agent_name = agents_run_tasks_futures[task]
self._agents_tasks.pop(agent_name)
if task.exception():
for callback in self._error_callbacks:
@@ -221,7 +207,7 @@ def add_error_callback(
"""Add error callback to call on error raised."""
self._error_callbacks.append(error_callback)
- def start_manager(self) -> "Manager":
+ def start_manager(self) -> "MultiAgentManager":
"""Start manager."""
if self._is_running:
return self
@@ -231,10 +217,10 @@ def start_manager(self) -> "Manager":
self._is_running = True
self._thread = Thread(target=self._run_thread, daemon=True)
self._thread.start()
- self._started_event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
+ self._started_event.wait(self.DEFAULT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
return self
- def stop_manager(self) -> "Manager":
+ def stop_manager(self) -> "MultiAgentManager":
"""
Stop manager.
@@ -266,7 +252,7 @@ def stop_manager(self) -> "Manager":
self._loop.call_soon_threadsafe(self._event.set)
if self._thread.ident != threading.get_ident():
- self._thread.join(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
+ self._thread.join(self.DEFAULT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
self._thread = None
return self
@@ -276,17 +262,17 @@ def _cleanup(self) -> None:
if self._was_working_dir_created and os.path.exists(self.working_dir):
rmtree(self.working_dir)
- def add_project(self, public_id: PublicId) -> "Manager":
+ def add_project(self, public_id: PublicId) -> "MultiAgentManager":
"""Fetch agent project and all dependencies to working_dir."""
if public_id in self._projects:
raise ValueError(f"Project {public_id} was already added!")
self._projects[public_id] = Project.load(self.working_dir, public_id)
return self
- def remove_project(self, public_id: PublicId) -> "Manager":
+ def remove_project(self, public_id: PublicId) -> "MultiAgentManager":
"""Remove agent project."""
if public_id not in self._projects:
- raise ValueError(f"Project {public_id} was not added!")
+ raise ValueError(f"Project {public_id} is not present!")
if self._projects[public_id].agents:
raise ValueError(
@@ -307,10 +293,10 @@ def list_projects(self) -> List[PublicId]:
def add_agent(
self,
public_id: PublicId,
- agent_name: str,
+ agent_name: Optional[str] = None,
agent_overrides: Optional[dict] = None,
component_overrides: Optional[List[dict]] = None,
- ) -> "Manager":
+ ) -> "MultiAgentManager":
"""
Create new agent configuration based on project with config overrides applied.
@@ -323,6 +309,8 @@ def add_agent(
:return: manager
"""
+ agent_name = agent_name or public_id.name
+
if agent_name in self._agents:
raise ValueError(f"Agent with name {agent_name} already exists!")
@@ -352,7 +340,7 @@ def list_agents(self, running_only: bool = False) -> List[str]:
return [i for i in self._agents.keys() if self._is_agent_running(i)]
return list(self._agents.keys())
- def remove_agent(self, agent_name: str) -> "Manager":
+ def remove_agent(self, agent_name: str) -> "MultiAgentManager":
"""
Remove agent alias definition from registry.
@@ -367,10 +355,10 @@ def remove_agent(self, agent_name: str) -> "Manager":
raise ValueError("Agent is running. stop it first!")
agent_alias = self._agents.pop(agent_name)
- agent_alias.remove()
+ agent_alias.remove_from_project()
return self
- def start_agent(self, agent_name: str) -> "Manager":
+ def start_agent(self, agent_name: str) -> "MultiAgentManager":
"""
Start selected agent.
@@ -390,9 +378,9 @@ def start_agent(self, agent_name: str) -> "Manager":
raise ValueError(f"{agent_name} is already started!")
if self._mode == "async":
- task = AsyncTask(agent_alias.agent, self._loop)
+ task = AgentRunAsyncTask(agent_alias.agent, self._loop)
elif self._mode == "threaded":
- task = ThreadedTask(agent_alias.agent, self._loop)
+ task = AgentRunThreadTask(agent_alias.agent, self._loop)
task.start()
self._agents_tasks[agent_name] = task
@@ -407,7 +395,7 @@ def _is_agent_running(self, agent_name: str) -> bool:
task = self._agents_tasks[agent_name]
return task.is_running
- def start_all_agents(self) -> "Manager":
+ def start_all_agents(self) -> "MultiAgentManager":
"""
Start all not started agents.
@@ -423,7 +411,7 @@ def start_all_agents(self) -> "Manager":
return self
- def stop_agent(self, agent_name: str) -> "Manager":
+ def stop_agent(self, agent_name: str) -> "MultiAgentManager":
"""
Stop running agent.
@@ -456,11 +444,11 @@ def _add_cb():
self._loop.call_soon_threadsafe(_add_cb)
agent_task.stop()
- event.wait(self.DEFALUT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
+ event.wait(self.DEFAULT_TIMEOUT_FOR_BLOCKING_OPERATIONS)
return self
- def stop_all_agents(self) -> "Manager":
+ def stop_all_agents(self) -> "MultiAgentManager":
"""
Stop all agents running.
@@ -471,7 +459,7 @@ def stop_all_agents(self) -> "Manager":
return self
- def stop_agents(self, agent_names: List[str]) -> "Manager":
+ def stop_agents(self, agent_names: List[str]) -> "MultiAgentManager":
"""
Stop specified agents.
@@ -486,7 +474,7 @@ def stop_agents(self, agent_names: List[str]) -> "Manager":
return self
- def start_agents(self, agent_names: List[str]) -> "Manager":
+ def start_agents(self, agent_names: List[str]) -> "MultiAgentManager":
"""
Stop specified agents.
diff --git a/scripts/whitelist.py b/scripts/whitelist.py
index 9547a8a7fa..e16caa277f 100644
--- a/scripts/whitelist.py
+++ b/scripts/whitelist.py
@@ -190,3 +190,12 @@
receiver_address # unused variable (aea/decision_maker/default.py:99)
create_with_message # unused method (aea/helpers/dialogue/base.py:1054)
_.is_disconnecting # unused property (aea/multiplexer.py:67)
+MultiAgentManager # unused class (aea/manager.py:127)
+_.add_error_callback # unused method (aea/manager.py:202)
+_.start_manager # unused method (aea/manager.py:208)
+_.stop_manager # unused method (aea/manager.py:221)
+_.add_project # unused method (aea/manager.py:263)
+_.list_projects # unused method (aea/manager.py:283)
+_.add_agent # unused method (aea/manager.py:291)
+_.start_all_agents # unused method (aea/manager.py:396)
+_.get_agent_alias # unused method (aea/manager.py:486)
diff --git a/tests/test_manager.py b/tests/test_manager.py
index a0b08ecf6a..46237f3b1e 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -23,13 +23,13 @@
import pytest
from aea.configurations.base import PublicId
-from aea.manager import Manager
+from aea.manager import MultiAgentManager
from tests.common.utils import wait_for_condition
-class TestManagerAsyncMode: # pylint: disable=unused-argument,protected-access,attribute-defined-outside-init
- """Tests for manager in async mode."""
+class TestMultiAgentManagerAsyncMode: # pylint: disable=unused-argument,protected-access,attribute-defined-outside-init
+ """Tests for MultiAgentManager in async mode."""
MODE = "async"
@@ -38,28 +38,28 @@ class TestManagerAsyncMode: # pylint: disable=unused-argument,protected-access,
def setup(self):
"""Set test case."""
self.agent_name = "test_what_ever12"
- self.working_dir = "manager_dir"
+ self.working_dir = "MultiAgentManager_dir"
self.project_public_id = PublicId("fetchai", "my_first_aea", "0.11.0")
self.project_path = os.path.join(
self.working_dir, self.project_public_id.author, self.project_public_id.name
)
assert not os.path.exists(self.working_dir)
- self.manager = Manager(self.working_dir, mode=self.MODE)
+ self.manager = MultiAgentManager(self.working_dir, mode=self.MODE)
def teardown(self):
"""Tear down test case."""
self.manager.stop_manager()
def test_workdir_created_removed(self):
- """Check work dit created removed on manager start and stop."""
+ """Check work dit created removed on MultiAgentManager start and stop."""
assert not os.path.exists(self.working_dir)
self.manager.start_manager()
assert os.path.exists(self.working_dir)
self.manager.stop_manager()
assert not os.path.exists(self.working_dir)
- def test_manager_is_running(self):
- """Check manager is running property reflects state."""
+ def test_MultiAgentManager_is_running(self):
+ """Check MultiAgentManager is running property reflects state."""
assert not self.manager.is_running
self.manager.start_manager()
assert self.manager.is_running
@@ -81,7 +81,7 @@ def test_add_remove_project(self):
self.manager.remove_project(self.project_public_id)
assert self.project_public_id not in self.manager.list_projects()
- with pytest.raises(ValueError, match=r"was not added"):
+ with pytest.raises(ValueError, match=r"is not present"):
self.manager.remove_project(self.project_public_id)
self.manager.add_project(self.project_public_id)
@@ -113,7 +113,7 @@ def test_add_agent(self):
],
)
agent_alias = self.manager.get_agent_alias(self.agent_name)
- assert agent_alias.name == self.agent_name
+ assert agent_alias.agent_name == self.agent_name
assert (
agent_alias.agent.resources.get_behaviour(
self.echo_skill_id, "echo"
@@ -150,7 +150,7 @@ def test_add_agent_for_non_exist_project(self):
self.manager.add_agent(PublicId("test", "test", "0.1.0"), "another_agent")
def test_agent_acually_running(self):
- """Test manager starts agent correctly and agent perform acts."""
+ """Test MultiAgentManager starts agent correctly and agent perform acts."""
self.test_add_agent()
agent_alias = self.manager.get_agent_alias(self.agent_name)
behaviour = agent_alias.agent.resources.get_behaviour(
@@ -178,7 +178,7 @@ def test_exception_handling(self):
wait_for_condition(lambda: callback_mock.call_count > 0, timeout=10)
def test_stop_from_exception_handling(self):
- """Test stop manager from erro callback."""
+ """Test stop MultiAgentManager from erro callback."""
self.test_add_agent()
agent_alias = self.manager.get_agent_alias(self.agent_name)
behaviour = agent_alias.agent.resources.get_behaviour(
@@ -197,7 +197,7 @@ def handler(*args, **kwargs):
wait_for_condition(lambda: not self.manager.is_running, timeout=10)
def test_start_all(self):
- """Test manager start all agents."""
+ """Test MultiAgentManager start all agents."""
self.test_add_agent()
assert self.agent_name in self.manager.list_agents()
assert self.agent_name not in self.manager.list_agents(running_only=True)
@@ -249,24 +249,24 @@ def test_do_no_allow_override_some_fields(self):
@staticmethod
def test_invalid_mode():
- """Test manager fails on invalid mode."""
+ """Test MultiAgentManager fails on invalid mode."""
with pytest.raises(ValueError, match="Invalid mode"):
- Manager("test_dir", mode="invalid_mode")
+ MultiAgentManager("test_dir", mode="invalid_mode")
def test_double_start(self):
- """Test double manager start."""
+ """Test double MultiAgentManager start."""
self.manager.start_manager()
self.manager.start_manager()
def test_double_stop(self):
- """Test double manager stop."""
+ """Test double MultiAgentManager stop."""
self.manager.start_manager()
self.manager.stop_manager()
self.manager.stop_manager()
@pytest.mark.asyncio
async def test_run_loop_direct_call(self):
- """Test do not allow to run manager_loop directly."""
+ """Test do not allow to run MultiAgentManager_loop directly."""
with pytest.raises(
ValueError, match="Do not use this method directly, use start_manager"
):
@@ -287,7 +287,7 @@ def test_remove_running_agent(self):
assert self.agent_name not in self.manager.list_agents()
-class TestManagerThreadedMode(TestManagerAsyncMode):
- """Tests for manager in threaded mode."""
+class TestMultiAgentManagerThreadedMode(TestMultiAgentManagerAsyncMode):
+ """Tests for MultiAgentManager in threaded mode."""
MODE = "threaded"
From 10cbc3911c6c7ff1d7ba046e00fd426edd05432c Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 30 Sep 2020 11:27:42 +0100
Subject: [PATCH 107/131] docs updates, including multi agent manager
---
docs/acn.md | 4 +++
docs/config.md | 2 +-
docs/message-routing.md | 8 +++---
docs/multi-agent-manager.md | 54 +++++++++++++++++++++++++++++++++++++
mkdocs.yml | 1 +
5 files changed, 65 insertions(+), 4 deletions(-)
create mode 100644 docs/multi-agent-manager.md
diff --git a/docs/acn.md b/docs/acn.md
index ff5e4ec970..63d7572a7d 100644
--- a/docs/acn.md
+++ b/docs/acn.md
@@ -4,4 +4,8 @@
Details coming soon. In the meantime check out this section.
+
+missing:
+- different configurations of setting up peer and client
+
diff --git a/docs/config.md b/docs/config.md
index 6e4435706e..1173780dbf 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -10,7 +10,7 @@ PUBLIC_ID_REGEX: "^[a-zA-Z0-9_]*/[a-zA-Z_][a-zA-Z0-9_]*:(0|[1-9]\\d*)\\.(0|[1-9]
LEDGER_ID_REGEX: "^[^\\d\\W]\\w*\\Z"
```
-The `aea-config.yaml` defines the AEA project. The compulsary components are listed below:
+The `aea-config.yaml` defines the AEA project. The compulsory components are listed below:
``` yaml
agent_name: my_agent # Name of the AEA project (must satisfy PACKAGE_REGEX)
author: fetchai # Author handle of the project's author (must satisfy AUTHOR_REGEX)
diff --git a/docs/message-routing.md b/docs/message-routing.md
index a387eab022..8b2741aaf1 100644
--- a/docs/message-routing.md
+++ b/docs/message-routing.md
@@ -13,9 +13,11 @@ Message routing can be split up into the routing of incoming and outgoing `Messa
- `Skills` deposit `Messages` in `OutBox`
- `OutBox` constructs an `Envelope` from the `Message`
- `Multiplexer` assigns messages to relevant `Connection` based on three rules:
-1. checks if `EnvelopeContext` exists and specifies a `Connection`, if so uses that else
-2. checks if default routing is specified for the `protocol_id` referenced in the `Envelope`, if so uses that else
-3. sends to default `Connection`.
+
+ 1. checks if `EnvelopeContext` exists and specifies a `Connection`, if so uses that else
+ 2. checks if default routing is specified for the `protocol_id` referenced in the `Envelope`, if so uses that else
+ 3. sends to default `Connection`.
+
- `Connections` can encode envelopes where necessary or pass them on for transport to another agent
## Address fields in `Envelopes`/`Messages`
diff --git a/docs/multi-agent-manager.md b/docs/multi-agent-manager.md
new file mode 100644
index 0000000000..4ff3d1747f
--- /dev/null
+++ b/docs/multi-agent-manager.md
@@ -0,0 +1,54 @@
+
+The `MultiAgentManager` allows managing multiple agent projects programmatically.
+
+## Setup
+
+We intantiate the manager by providing it with the working directory in which to operate and starting it:
+
+``` python
+from aea.manager import MultiAgentManager
+
+WORKING_DIR = "."
+
+manager = MultiAgentManager(WORKING_DIR)
+manager.start_manager()
+```
+
+## Adding projects
+
+We first add a couple of finished AEA project:
+
+``` python
+manager.add_project("fetchai/weather_client:0.13.0")
+manager.add_project("fetchai/weather_station:0.13.0")
+```
+
+## Adding agent instances
+
+``` python
+manager.add_agent("fetchai/weather_client:0.13.0")
+manager.add_agent("fetchai/weather_station:0.13.0")
+```
+
+missing:
+- configuring private keys
+- configure delayed startup sequence
+
+
+## Running the agents:
+
+``` python
+manager.start_all_agents()
+```
+
+## Stopping the agents:
+
+``` python
+manager.stop_all_agents()
+```
+
+## Cleaning up
+
+``` python
+manager.stop_manager()
+```
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 749294b81b..d68fc85c12 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -62,6 +62,7 @@ nav:
- AEAs vs agents: 'agent-vs-aea.md'
- Upgrading versions: 'upgrading.md'
- Modes of running an AEA: 'modes.md'
+ - Multi agent manager: 'multi-agent-manager.md'
- Use case components:
- Generic skills: 'generic-skills.md'
- Front-end intergration: 'connect-a-frontend.md'
From 0ba97ccf5aaa29d909b74ae8ad3e1c755685ffda Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Wed, 30 Sep 2020 13:19:06 +0300
Subject: [PATCH 108/131] fix for cancellerror supression in
multiplexer._connect_all
---
aea/multiplexer.py | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index d604b1e1f0..8c2e58b907 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -264,7 +264,10 @@ async def connect(self) -> None:
self._recv_loop_task = self._loop.create_task(self._receiving_loop())
self._send_loop_task = self._loop.create_task(self._send_loop())
self.logger.debug("Multiplexer connected and running.")
- except (CancelledError, Exception):
+ except (CancelledError, asyncio.CancelledError):
+ await self._stop()
+ raise asyncio.CancelledError()
+ except Exception:
self.logger.exception("Exception on connect:")
await self._stop()
raise AEAConnectionError("Failed to connect the multiplexer.")
@@ -274,7 +277,7 @@ async def disconnect(self) -> None:
self.logger.debug("Multiplexer disconnecting...")
async with self._lock:
if self.connection_status.is_disconnected:
- self.logger.debug("Multiplexer already disconnected.")
+ self.logger.debug("Multiplexer disconnected.")
return
try:
self.connection_status.set(ConnectionStates.disconnecting)
@@ -341,14 +344,13 @@ async def _connect_all(self) -> None:
await self._connect_one(connection_id)
connected.append(connection_id)
except Exception as e: # pylint: disable=broad-except
- self.logger.error(
- "Error while connecting {}: {}".format(
- str(type(connection)), str(e)
+ if not isinstance(e, (asyncio.CancelledError, CancelledError)):
+ self.logger.exception(
+ "Error while connecting {}: {}".format(
+ str(type(connection)), repr(e)
+ )
)
- )
- for c in connected:
- await self._disconnect_one(c)
- break
+ raise
self.logger.debug("Multiplexer connections are set.")
async def _connect_one(self, connection_id: PublicId) -> None:
From 86c0b9304bf4e6b74845c99589d9ee585c90cf16 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 30 Sep 2020 16:02:37 +0200
Subject: [PATCH 109/131] overwrite agent configs in manager
---
aea/configurations/base.py | 63 +++++++++++++++++++++++++++++---------
aea/helpers/base.py | 4 +--
aea/manager.py | 53 +++++++++++++++++++-------------
tests/test_manager.py | 7 ++---
4 files changed, 84 insertions(+), 43 deletions(-)
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 190dee4ef3..a8ba960947 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -27,7 +27,7 @@
import re
from abc import ABC, abstractmethod
from collections import OrderedDict
-from copy import deepcopy
+from copy import copy, deepcopy
from enum import Enum
from pathlib import Path
from typing import (
@@ -833,6 +833,14 @@ def package_dependencies(self) -> Set[ComponentId]:
"""Get the package dependencies."""
return set()
+ def update(self, data: Dict) -> None:
+ """
+ Update configuration with other data.
+
+ :param data: the data to replace.
+ :return: None
+ """
+
class ComponentConfiguration(PackageConfiguration, ABC):
"""Class to represent an agent component configuration."""
@@ -916,14 +924,6 @@ def check_aea_version(self):
"""
_check_aea_version(self)
- def update(self, data: Dict) -> None:
- """
- Update configuration with other data.
-
- :param data: the data to replace.
- :return: None
- """
-
class ConnectionConfig(ComponentConfiguration):
"""Handle connection configuration."""
@@ -1537,7 +1537,18 @@ def default_ledger(self, ledger_id: str):
def component_configurations_json(self) -> List[OrderedDict]:
"""Get the component configurations in JSON format."""
- return list(map(OrderedDict, self.component_configurations.values()))
+ result: List[OrderedDict] = []
+ for component_id, config in self.component_configurations.items():
+ result.append(
+ OrderedDict(
+ author=component_id.author,
+ name=component_id.name,
+ version=component_id.version,
+ type=str(component_id.component_type),
+ **config,
+ )
+ )
+ return result
@property
def json(self) -> Dict:
@@ -1647,10 +1658,10 @@ def from_json(cls, obj: Dict):
component_configurations = {}
for config in obj.get("component_configurations", []):
tmp = deepcopy(config)
- name = tmp["name"]
- author = tmp["author"]
- version = tmp["version"]
- type_ = tmp["type"]
+ name = tmp.pop("name")
+ author = tmp.pop("author")
+ version = tmp.pop("version")
+ type_ = tmp.pop("type")
component_id = ComponentId(
ComponentType(type_), PublicId(author, name, version)
)
@@ -1665,6 +1676,30 @@ def from_json(cls, obj: Dict):
return agent_config
+ def update(self, data: Dict) -> None:
+ """
+ Update configuration with other data.
+
+ To update the component parts, populate the field "component_configurations" as a
+ mapping from ComponentId to configurations.
+
+ :param data: the data to replace.
+ :return: None
+ """
+ data = copy(data)
+ # update component parts
+ new_component_configurations: Dict = data.pop("component_configurations", {})
+ result: Dict[ComponentId, Dict] = copy(self.component_configurations)
+ for component_id, obj in new_component_configurations.items():
+ if component_id not in result:
+ result[component_id] = obj
+ else:
+ recursive_update(result[component_id], obj)
+ self.component_configurations = result
+
+ # update other fields
+ # currently not supported.
+
class SpeechActContentConfig(Configuration):
"""Handle a speech_act content configuration."""
diff --git a/aea/helpers/base.py b/aea/helpers/base.py
index 3289f0c175..b4a22ced9f 100644
--- a/aea/helpers/base.py
+++ b/aea/helpers/base.py
@@ -392,7 +392,7 @@ def exception_log_and_reraise(log_method: Callable, message: str):
raise
-def recursive_update(to_update: Dict, new_values: Dict):
+def recursive_update(to_update: Dict, new_values: Dict) -> None:
"""
Update a dictionary by replacing conflicts with the new values.
@@ -406,7 +406,7 @@ def recursive_update(to_update: Dict, new_values: Dict):
:param to_update: the dictionary to update.
:param new_values: the dictionary of new values to replace.
- :return: the updated dictionary.
+ :return: None
"""
for key, value in new_values.items():
if key not in to_update:
diff --git a/aea/manager.py b/aea/manager.py
index 470e4f8e0f..ce40d6756f 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -23,17 +23,18 @@
import os
import threading
from asyncio.tasks import FIRST_COMPLETED
+from pathlib import Path
from shutil import rmtree
from threading import Thread
from typing import Callable, Dict, List, Optional
from aea.aea import AEA
from aea.aea_builder import AEABuilder
-from aea.configurations.base import ComponentId, PublicId
+from aea.configurations.base import AgentConfig, ComponentId, PackageType, PublicId
from aea.configurations.constants import DEFAULT_LEDGER
+from aea.configurations.loader import ConfigLoaders
from aea.configurations.project import AgentAlias, Project
from aea.crypto.helpers import create_private_key
-from aea.helpers.base import yaml_load_all
class AgentRunAsyncTask:
@@ -509,8 +510,8 @@ def _build_agent_alias(
self,
project: Project,
agent_name: str,
- agent_overrides=None,
- component_overrides=None,
+ agent_overrides: Optional[dict] = None,
+ component_overrides: Optional[List[dict]] = None,
) -> AgentAlias:
"""Create agent alias for project, with given name and overrided values."""
json_config = self._make_config(
@@ -529,13 +530,6 @@ def _build_agent_alias(
agent = builder.build()
return AgentAlias(project, agent_name, json_config, agent)
- @staticmethod
- def _update_dict(base: dict, override: dict) -> dict:
- """Apply overrides for dict."""
- base = copy.deepcopy(base)
- base.update(override)
- return base
-
def _make_config(
self,
project_path: str,
@@ -551,20 +545,35 @@ def _make_config(
'Do not override any of {" ".join(self.AGENT_DO_NOT_OVERRIDE_VALUES)}'
)
- json_data = yaml_load_all(
- AEABuilder.get_configuration_file_path(project_path).open()
+ agent_configuration_file_path: Path = AEABuilder.get_configuration_file_path(
+ project_path
)
- agent_config = self._update_dict(json_data[0], agent_overrides)
-
- components_configs = {PublicId.from_json(obj): obj for obj in json_data[1:]}
-
+ loader = ConfigLoaders.from_package_type(PackageType.AGENT)
+ with agent_configuration_file_path.open() as fp:
+ agent_config: AgentConfig = loader.load(fp)
+
+ # prepare configuration overrides
+ # - agent part
+ agent_update_dictionary: Dict = dict(**agent_overrides)
+ # - components part
+ components_configs: Dict[ComponentId, Dict] = {}
for obj in component_overrides:
- component_id = ComponentId(obj["type"], PublicId.from_json(obj))
- components_configs[component_id] = self._update_dict(
- components_configs.get(component_id, {}), obj
+ obj = copy.copy(obj)
+ author, name, version = (
+ obj.pop("author"),
+ obj.pop("name"),
+ obj.pop("version"),
)
-
- return [agent_config] + list(components_configs.values())
+ component_id = ComponentId(obj.pop("type"), PublicId(author, name, version))
+ components_configs[component_id] = obj
+ agent_update_dictionary["component_configurations"] = components_configs
+ # do the override (and valiation)
+ agent_config.update(agent_update_dictionary)
+
+ # return the multi-paged JSON object.
+ json_data = agent_config.ordered_json
+ result: List[Dict] = [json_data] + json_data.pop("component_configurations")
+ return result
def _create_private_key(self, name, ledger) -> str:
"""Create new key for agent alias in working dir keys dir."""
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 46237f3b1e..7b680ee698 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -101,13 +101,10 @@ def test_add_agent(self):
self.agent_name,
component_overrides=[
{
- "type": "skill",
**self.echo_skill_id.json,
+ "type": "skill",
"behaviours": {
- "echo": {
- "args": {"tick_interval": new_tick_interval},
- "class_name": "EchoBehaviour",
- }
+ "echo": {"args": {"tick_interval": new_tick_interval}}
},
}
],
From a8102c62ad74f9ffe1c3a0f14d6dfb958895e891 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 30 Sep 2020 17:07:04 +0200
Subject: [PATCH 110/131] fix tests on aea builder
---
aea/configurations/base.py | 5 +++++
aea/configurations/loader.py | 12 +++++++-----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index a8ba960947..91e046ccbb 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -733,6 +733,11 @@ def prefix_import_path(self) -> str:
self.public_id.author, self.component_type.to_plural(), self.public_id.name
)
+ @property
+ def json(self) -> Dict:
+ """Get the JSON representation."""
+ return dict(**self.public_id.json, type=str(self.component_type))
+
ProtocolId = PublicId
ContractId = PublicId
diff --git a/aea/configurations/loader.py b/aea/configurations/loader.py
index f58eb43fa9..2779585959 100644
--- a/aea/configurations/loader.py
+++ b/aea/configurations/loader.py
@@ -386,10 +386,10 @@ def _split_component_id_and_config(
raise ValueError(
f"There are missing fields in component id {component_index + 1}: {missing_fields}."
)
- component_name = component_configuration_json["name"]
- component_author = component_configuration_json["author"]
- component_version = component_configuration_json["version"]
- component_type = ComponentType(component_configuration_json["type"])
+ component_name = component_configuration_json.pop("name")
+ component_author = component_configuration_json.pop("author")
+ component_version = component_configuration_json.pop("version")
+ component_type = ComponentType(component_configuration_json.pop("type"))
component_public_id = PublicId(
component_author, component_name, component_version
)
@@ -414,7 +414,9 @@ def _validate_component_configuration(
component_id.component_type
)
try:
- BaseConfigLoader(schema_file).validate(configuration)
+ BaseConfigLoader(schema_file).validate(
+ dict(**component_id.json, **configuration)
+ )
except jsonschema.ValidationError as e:
raise ValueError(
f"Configuration of component {component_id} is not valid."
From 5136887ccb7c6071880a405a2746e657e7a72d52 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Wed, 30 Sep 2020 16:22:39 +0300
Subject: [PATCH 111/131] fixes
---
aea/multiplexer.py | 2 +-
tests/common/pexpect_popen.py | 10 ++++++++--
tests/test_cli/test_launch.py | 4 ++--
tests/test_multiplexer.py | 9 ++++++---
4 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index 8c2e58b907..a766694392 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -277,7 +277,7 @@ async def disconnect(self) -> None:
self.logger.debug("Multiplexer disconnecting...")
async with self._lock:
if self.connection_status.is_disconnected:
- self.logger.debug("Multiplexer disconnected.")
+ self.logger.debug("Multiplexer already disconnected.")
return
try:
self.connection_status.set(ConnectionStates.disconnecting)
diff --git a/tests/common/pexpect_popen.py b/tests/common/pexpect_popen.py
index e4e591a9b3..220bfd58c3 100644
--- a/tests/common/pexpect_popen.py
+++ b/tests/common/pexpect_popen.py
@@ -86,12 +86,15 @@ def aea_cli(cls, args) -> "PexpectWrapper":
logfile=sys.stdout,
)
- def expect_all(self, pattern_list: List[str], timeout: float = 10) -> None:
+ def expect_all(
+ self, pattern_list: List[str], timeout: float = 10, strict: bool = True
+ ) -> None:
"""
Wait for all patterns appear in process output.
:param pattern_list: list of string to expect
:param timeout: timeout in seconds
+ :param strict: if non strict, it allows regular expression
:return: None
"""
@@ -102,7 +105,10 @@ def expect_all(self, pattern_list: List[str], timeout: float = 10) -> None:
time_spent = time.time() - start_time
if time_spent > timeout:
raise TIMEOUT(timeout)
- idx = self.expect_exact(pattern_list, timeout - time_spent)
+ if strict:
+ idx = self.expect_exact(pattern_list, timeout - time_spent)
+ else:
+ idx = self.expect(pattern_list, timeout - time_spent)
pattern_list.pop(idx)
def wait_eof(self, timeout: float = 10) -> None:
diff --git a/tests/test_cli/test_launch.py b/tests/test_cli/test_launch.py
index 91b7a65fba..0918f98772 100644
--- a/tests/test_cli/test_launch.py
+++ b/tests/test_cli/test_launch.py
@@ -213,11 +213,11 @@ def test_exit_code_equal_to_zero(self):
f"[{self.agent_name_1}] Start processing messages",
f"[{self.agent_name_2}] Start processing messages",
],
- timeout=20,
+ timeout=30,
)
process_launch.control_c()
process_launch.expect_all(
- ["Exit cli. code: 0"], timeout=20,
+ ["Exit cli. code: 0"], timeout=30,
)
diff --git a/tests/test_multiplexer.py b/tests/test_multiplexer.py
index 93b206e796..e16806ca3b 100644
--- a/tests/test_multiplexer.py
+++ b/tests/test_multiplexer.py
@@ -728,12 +728,15 @@ def test_multiplexer_disconnected_on_early_interruption(self):
)
self.proc.expect_all(
- ["Finished downloading golang dependencies"], timeout=20,
+ ["Finished downloading golang dependencies"], timeout=50,
)
self.proc.control_c()
self.proc.expect_all(
- ["Multiplexer disconnecting...", "Multiplexer disconnected.", EOF],
- timeout=20,
+ ["Multiplexer .*disconnected."], timeout=20, strict=False,
+ )
+
+ self.proc.expect_all(
+ [EOF], timeout=20,
)
def test_multiplexer_disconnected_on_termination_after_connected(self):
From 6c1a327f16790d699614a2620aa1af7226e18cd9 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 30 Sep 2020 17:13:18 +0200
Subject: [PATCH 112/131] add basic test to AgentConfig.update
---
tests/test_configurations/test_base.py | 42 ++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/tests/test_configurations/test_base.py b/tests/test_configurations/test_base.py
index c2fb7954ec..6506a797ed 100644
--- a/tests/test_configurations/test_base.py
+++ b/tests/test_configurations/test_base.py
@@ -34,6 +34,7 @@
ComponentType,
ConnectionConfig,
ContractConfig,
+ DEFAULT_AEA_CONFIG_FILE,
DEFAULT_SKILL_CONFIG_FILE,
PackageId,
PackageType,
@@ -53,7 +54,9 @@
from tests.conftest import (
AUTHOR,
+ CUR_PATH,
DUMMY_SKILL_PATH,
+ DUMMY_SKILL_PUBLIC_ID,
ROOT_DIR,
agent_config_files,
connection_config_files,
@@ -270,6 +273,45 @@ def test_from_json_and_to_json(self, agent_path):
actual_json = actual_config.json
assert expected_json == actual_json
+ def test_update(self):
+ """Test the update method."""
+ aea_config_path = Path(CUR_PATH, "data", "dummy_aea", DEFAULT_AEA_CONFIG_FILE)
+ loader = ConfigLoaders.from_package_type(PackageType.AGENT)
+ aea_config: AgentConfig = loader.load(aea_config_path.open())
+
+ dummy_skill_component_id = ComponentId(
+ ComponentType.SKILL, DUMMY_SKILL_PUBLIC_ID
+ )
+
+ new_dummy_skill_config = {
+ "behaviours": {"dummy": {"args": dict(behaviour_arg_1=42)}},
+ "handlers": {"dummy": {"args": dict(handler_arg_1=42)}},
+ "models": {"dummy": {"args": dict(model_arg_1=42)}},
+ }
+
+ aea_config.update(
+ dict(
+ component_configurations={
+ dummy_skill_component_id: new_dummy_skill_config
+ }
+ )
+ )
+ assert (
+ aea_config.component_configurations[dummy_skill_component_id]
+ == new_dummy_skill_config
+ )
+ aea_config.update(
+ dict(
+ component_configurations={
+ dummy_skill_component_id: new_dummy_skill_config
+ }
+ )
+ )
+ assert (
+ aea_config.component_configurations[dummy_skill_component_id]
+ == new_dummy_skill_config
+ )
+
class GetDefaultConfigurationFileNameFromStrTestCase(TestCase):
"""Test case for _get_default_configuration_file_name_from_type method."""
From 9fa4f988871db01b8eead2fc45be711c8f013bbc Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 30 Sep 2020 18:20:31 +0100
Subject: [PATCH 113/131] fix based on PR comments
---
aea/cli/registry/fetch.py | 5 ++---
aea/manager.py | 2 +-
tests/test_helpers/test_base.py | 4 ++--
tests/test_manager.py | 7 ++++++-
4 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/aea/cli/registry/fetch.py b/aea/cli/registry/fetch.py
index c3eedebc9d..c98f6a47d3 100644
--- a/aea/cli/registry/fetch.py
+++ b/aea/cli/registry/fetch.py
@@ -42,9 +42,9 @@ def fetch_agent(
Fetch Agent from Registry.
:param ctx: Context
- :param public_id: str public ID of desirable Agent.
- :param ctx: a Context object.
+ :param public_id: str public ID of desirable agent.
:param alias: an optional alias.
+ :param target_dir: the target directory to which the agent is fetched.
:return: None
"""
author, name, version = public_id.author, public_id.name, public_id.version
@@ -56,7 +56,6 @@ def fetch_agent(
folder_name = target_dir or (name if alias is None else alias)
aea_folder = os.path.join(ctx.cwd, folder_name)
- print(aea_folder)
ctx.clean_paths.append(aea_folder)
extract(filepath, ctx.cwd)
diff --git a/aea/manager.py b/aea/manager.py
index ce40d6756f..8dff9ff952 100644
--- a/aea/manager.py
+++ b/aea/manager.py
@@ -536,7 +536,7 @@ def _make_config(
agent_overrides: Optional[dict] = None,
component_overrides: Optional[List[dict]] = None,
) -> List[dict]:
- """Make new config baseed on proejct's config with overrides applied."""
+ """Make new config based on project's config with overrides applied."""
agent_overrides = agent_overrides or {}
component_overrides = component_overrides or []
diff --git a/tests/test_helpers/test_base.py b/tests/test_helpers/test_base.py
index 24b5678032..916b4218f1 100644
--- a/tests/test_helpers/test_base.py
+++ b/tests/test_helpers/test_base.py
@@ -274,7 +274,7 @@ def test_recursive_update_negative_different_type():
with pytest.raises(
ValueError,
- match=f"Trying to replace value '1' with value 'False' which is of different type.",
+ match="Trying to replace value '1' with value 'False' which is of different type.",
):
recursive_update(to_update, new_values)
@@ -287,6 +287,6 @@ def test_recursive_update_negative_unknown_field():
with pytest.raises(
ValueError,
- match=f"Key 'new_field' is not contained in the dictionary to update.",
+ match="Key 'new_field' is not contained in the dictionary to update.",
):
recursive_update(to_update, new_values)
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 7b680ee698..b78e9866bb 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -146,7 +146,7 @@ def test_add_agent_for_non_exist_project(self):
with pytest.raises(ValueError, match=" project is not added"):
self.manager.add_agent(PublicId("test", "test", "0.1.0"), "another_agent")
- def test_agent_acually_running(self):
+ def test_agent_actually_running(self):
"""Test MultiAgentManager starts agent correctly and agent perform acts."""
self.test_add_agent()
agent_alias = self.manager.get_agent_alias(self.agent_name)
@@ -253,13 +253,18 @@ def test_invalid_mode():
def test_double_start(self):
"""Test double MultiAgentManager start."""
self.manager.start_manager()
+ assert self.manager.is_running
self.manager.start_manager()
+ assert self.manager.is_running
def test_double_stop(self):
"""Test double MultiAgentManager stop."""
self.manager.start_manager()
+ assert self.manager.is_running
self.manager.stop_manager()
+ assert not self.manager.is_running
self.manager.stop_manager()
+ assert not self.manager.is_running
@pytest.mark.asyncio
async def test_run_loop_direct_call(self):
From 57bff07981ca54ff0c34ff946043deca6f92c0e0 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 30 Sep 2020 19:49:40 +0100
Subject: [PATCH 114/131] ignore coverage
---
aea/multiplexer.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aea/multiplexer.py b/aea/multiplexer.py
index a766694392..ea384fe5a1 100644
--- a/aea/multiplexer.py
+++ b/aea/multiplexer.py
@@ -258,7 +258,7 @@ async def connect(self) -> None:
if all(c.is_connected for c in self._connections):
self.connection_status.set(ConnectionStates.connected)
- else:
+ else: # pragma: nocover
raise AEAConnectionError("Failed to connect the multiplexer.")
self._recv_loop_task = self._loop.create_task(self._receiving_loop())
From 93fb0012a1c954176ef58424f619fe2f52a2cc77 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 30 Sep 2020 21:55:23 +0100
Subject: [PATCH 115/131] extend agent manager documentation
---
docs/multi-agent-manager.md | 53 ++++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 9 deletions(-)
diff --git a/docs/multi-agent-manager.md b/docs/multi-agent-manager.md
index 4ff3d1747f..f23c3ac4a5 100644
--- a/docs/multi-agent-manager.md
+++ b/docs/multi-agent-manager.md
@@ -19,26 +19,61 @@ manager.start_manager()
We first add a couple of finished AEA project:
``` python
-manager.add_project("fetchai/weather_client:0.13.0")
-manager.add_project("fetchai/weather_station:0.13.0")
+from aea.configurations.base import PublicId
+
+weather_client_id = PublicId.from_str("fetchai/weather_client:0.13.0")
+weather_station_id = PublicId.from_str("fetchai/weather_station:0.13.0")
+manager.add_project(weather_client_id)
+manager.add_project(weather_station_id)
```
## Adding agent instances
+Save the following private keys in the respective files.
``` python
-manager.add_agent("fetchai/weather_client:0.13.0")
-manager.add_agent("fetchai/weather_station:0.13.0")
+# 72d3149f5689f0749eaec5ebf6dba5deeb1e89b93ae1c58c71fd43dfaa231e87
+FET_PRIVATE_KEY_PATH_1 = "fetchai_private_key_1.txt"
+# bf529acb2546e13615ef6004c48e393f0638a5dc0c4979631a9a4bc554079f6f
+COSMOS_PRIVATE_KEY_PATH_1 = "cosmos_private_key_1.txt"
+# 589839ae54b71b8754a7fe96b52045364077c28705a1806b74441debcae16e0a
+FET_PRIVATE_KEY_PATH_2 = "fetchai_private_key_2.txt"
+# c9b38eff57f678f5ab5304447997351edb08eceb883267fa4ad849074bec07e4
+COSMOS_PRIVATE_KEY_PATH_2 = "cosmos_private_key_2.txt"
```
-missing:
-- configuring private keys
-- configure delayed startup sequence
-
+Add the agent instances
+``` python
+agent_overrides = {
+ "private_key_paths": {"fetchai": FET_PRIVATE_KEY_PATH_1},
+ "connection_private_key_paths": {"cosmos": COSMOS_PRIVATE_KEY_PATH_1}
+}
+manager.add_agent(weather_station_id, agent_overrides=agent_overrides)
+
+component_overrides = {
+ "name": "p2p_libp2p",
+ "author": "fetchai",
+ "version": "0.9.0",
+ "type": "connection",
+ "config": {
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ['/dns4/127.0.0.1/tcp/9000/p2p/16Uiu2HAkzgZYyk25XjAhmgXcdMbahrHYi18uuAzHuxPn1KkdmLRw'],
+ "local_uri": "127.0.0.1:9001",
+ "public_uri": "127.0.0.1:9001",
+ }
+}
+agent_overrides = {
+ "private_key_paths": {"fetchai": FET_PRIVATE_KEY_PATH_2},
+ "connection_private_key_paths": {"cosmos": COSMOS_PRIVATE_KEY_PATH_2}
+}
+manager.add_agent(weather_client_id, component_overrides=[component_overrides], agent_overrides=agent_overrides)
+```
## Running the agents:
``` python
-manager.start_all_agents()
+manager.start_agent(weather_station_id.name)
+# wait for ~10 seconds for peer node to go live
+manager.start_agent(weather_station_id.name)
```
## Stopping the agents:
From 36d578052cfd5b70323b22ca838422b61b5597d0 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Thu, 1 Oct 2020 00:42:39 +0200
Subject: [PATCH 116/131] add update of agent config all configurable fields
---
aea/configurations/base.py | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 91e046ccbb..5d4d8ae8b8 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -1402,8 +1402,8 @@ def __init__(
self.agent_name = agent_name
self.registry_path = registry_path
self.description = description
- self.private_key_paths = CRUDCollection[str]()
- self.connection_private_key_paths = CRUDCollection[str]()
+ self.private_key_paths: CRUDCollection[str] = CRUDCollection[str]()
+ self.connection_private_key_paths: CRUDCollection[str] = CRUDCollection[str]()
self.logging_config = logging_config if logging_config is not None else {}
self._default_ledger = None # type: Optional[str]
@@ -1703,7 +1703,14 @@ def update(self, data: Dict) -> None:
self.component_configurations = result
# update other fields
- # currently not supported.
+ for item_id, value in data.get("private_key_paths", {}):
+ self.private_key_paths.update(item_id, value)
+
+ for item_id, value in data.get("connection_private_key_paths", {}):
+ self.connection_private_key_paths.update(item_id, value)
+
+ self.logging_config = data.get("logging_config", self.logging_config)
+ self.registry_path = data.get("registry_path", self.registry_path)
class SpeechActContentConfig(Configuration):
From c15fd2293d9d3a4a5f28f6614eb05c0e98b3d326 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Thu, 1 Oct 2020 00:55:26 +0200
Subject: [PATCH 117/131] overwrite only existing private keys ids.
---
aea/configurations/base.py | 10 ++++++----
tests/test_configurations/test_base.py | 13 ++++++++++++-
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 5d4d8ae8b8..30786ca9e3 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -347,6 +347,8 @@ def update(self, item_id: str, item: T) -> None:
:param item: the item to be added.
:return: None
"""
+ if item_id not in self._items_by_id:
+ raise ValueError(f"No item registered with id '{item_id}'.")
self._items_by_id[item_id] = item
def delete(self, item_id: str) -> None:
@@ -1402,8 +1404,8 @@ def __init__(
self.agent_name = agent_name
self.registry_path = registry_path
self.description = description
- self.private_key_paths: CRUDCollection[str] = CRUDCollection[str]()
- self.connection_private_key_paths: CRUDCollection[str] = CRUDCollection[str]()
+ self.private_key_paths = CRUDCollection[str]()
+ self.connection_private_key_paths = CRUDCollection[str]()
self.logging_config = logging_config if logging_config is not None else {}
self._default_ledger = None # type: Optional[str]
@@ -1703,10 +1705,10 @@ def update(self, data: Dict) -> None:
self.component_configurations = result
# update other fields
- for item_id, value in data.get("private_key_paths", {}):
+ for item_id, value in data.get("private_key_paths", {}).items():
self.private_key_paths.update(item_id, value)
- for item_id, value in data.get("connection_private_key_paths", {}):
+ for item_id, value in data.get("connection_private_key_paths", {}).items():
self.connection_private_key_paths.update(item_id, value)
self.logging_config = data.get("logging_config", self.logging_config)
diff --git a/tests/test_configurations/test_base.py b/tests/test_configurations/test_base.py
index 6506a797ed..6956269208 100644
--- a/tests/test_configurations/test_base.py
+++ b/tests/test_configurations/test_base.py
@@ -99,6 +99,9 @@ def test_update(self):
collection.update("one", 2)
assert collection.read("one") == 2
+ with pytest.raises(ValueError, match=f"No item registered with id 'two'."):
+ collection.update("two", 2)
+
def test_delete(self):
"""Test that the delete method works correctly."""
collection = CRUDCollection()
@@ -293,13 +296,21 @@ def test_update(self):
dict(
component_configurations={
dummy_skill_component_id: new_dummy_skill_config
- }
+ },
+ private_key_paths=dict(foo="bar"),
+ connection_private_key_paths=dict(foo="bar"),
)
)
assert (
aea_config.component_configurations[dummy_skill_component_id]
== new_dummy_skill_config
)
+ assert dict(aea_config.private_key_paths.read_all()) == {"foo": "bar"}
+ assert dict(aea_config.connection_private_key_paths.read_all()) == {
+ "foo": "bar"
+ }
+
+ # test idempotence
aea_config.update(
dict(
component_configurations={
From 68814b9250126287f807b84c4d5d0a8e232fbce2 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Thu, 1 Oct 2020 01:02:34 +0200
Subject: [PATCH 118/131] update test on overwrite of private keys config
---
aea/configurations/base.py | 2 +-
tests/data/dummy_aea/aea-config.yaml | 3 +++
tests/data/hashes.csv | 2 +-
tests/test_configurations/test_base.py | 14 ++++++++------
4 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 30786ca9e3..8ad9f910c8 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -1548,8 +1548,8 @@ def component_configurations_json(self) -> List[OrderedDict]:
for component_id, config in self.component_configurations.items():
result.append(
OrderedDict(
- author=component_id.author,
name=component_id.name,
+ author=component_id.author,
version=component_id.version,
type=str(component_id.component_type),
**config,
diff --git a/tests/data/dummy_aea/aea-config.yaml b/tests/data/dummy_aea/aea-config.yaml
index 5c038adebf..cea1bf386a 100644
--- a/tests/data/dummy_aea/aea-config.yaml
+++ b/tests/data/dummy_aea/aea-config.yaml
@@ -25,4 +25,7 @@ logging_config:
private_key_paths:
cosmos: cosmos_private_key.txt
ethereum: ethereum_private_key.txt
+connection_private_key_paths:
+ cosmos: cosmos_private_key.txt
+ ethereum: ethereum_private_key.txt
registry_path: ../../packages
diff --git a/tests/data/hashes.csv b/tests/data/hashes.csv
index f068b6b33c..5a2e72f81a 100644
--- a/tests/data/hashes.csv
+++ b/tests/data/hashes.csv
@@ -1,4 +1,4 @@
-dummy_author/agents/dummy_aea,QmaFcsXAx9mCjPnYEzATwGJyBFJRgCHftfYmKCfZtSGSLw
+dummy_author/agents/dummy_aea,QmYEVtxkYh889JfQy5umXqM7KBNVfjDunV1SWf1Kd9zDfm
dummy_author/skills/dummy_skill,QmTBZg36AhCipACz8x7eJsA5CHKqUQN1SwT3n8zX6n9XNF
fetchai/connections/dummy_connection,QmWegP8qsY6Ngdh9xorMDCSA1UBjt4CrrPeVWQqyVfHvob
fetchai/contracts/dummy_contract,QmPMs9VDGZGF8xJ8XBYLVb1xK5XAgiaJr5Gwcq7Vr3TUyu
diff --git a/tests/test_configurations/test_base.py b/tests/test_configurations/test_base.py
index 6956269208..c7f5ab549a 100644
--- a/tests/test_configurations/test_base.py
+++ b/tests/test_configurations/test_base.py
@@ -292,23 +292,25 @@ def test_update(self):
"models": {"dummy": {"args": dict(model_arg_1=42)}},
}
+ new_private_key_paths = dict(ethereum="foo", cosmos="bar")
aea_config.update(
dict(
component_configurations={
dummy_skill_component_id: new_dummy_skill_config
},
- private_key_paths=dict(foo="bar"),
- connection_private_key_paths=dict(foo="bar"),
+ private_key_paths=new_private_key_paths,
+ connection_private_key_paths=new_private_key_paths,
)
)
assert (
aea_config.component_configurations[dummy_skill_component_id]
== new_dummy_skill_config
)
- assert dict(aea_config.private_key_paths.read_all()) == {"foo": "bar"}
- assert dict(aea_config.connection_private_key_paths.read_all()) == {
- "foo": "bar"
- }
+ assert dict(aea_config.private_key_paths.read_all()) == new_private_key_paths
+ assert (
+ dict(aea_config.connection_private_key_paths.read_all())
+ == new_private_key_paths
+ )
# test idempotence
aea_config.update(
From fb7349b8de20dc33eeaee134fec7cf55ac63c81b Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 1 Oct 2020 09:24:46 +0100
Subject: [PATCH 119/131] add acn documentation
---
docs/acn.md | 60 +++++++++++++++++++++++++++--
docs/assets/acn-tiers.png | Bin 0 -> 69774 bytes
docs/assets/acn-trust-security.png | Bin 0 -> 92534 bytes
docs/assets/dht.png | Bin 0 -> 159612 bytes
4 files changed, 57 insertions(+), 3 deletions(-)
create mode 100644 docs/assets/acn-tiers.png
create mode 100644 docs/assets/acn-trust-security.png
create mode 100644 docs/assets/dht.png
diff --git a/docs/acn.md b/docs/acn.md
index 63d7572a7d..e091fdab46 100644
--- a/docs/acn.md
+++ b/docs/acn.md
@@ -1,11 +1,65 @@
+The agent communication network (ACN) provides the agents with a system to find each other based on their addresses and communicate.
+
+An agent owner faces the following problem: Given a wallet address, how can my agent whilst maintaining certain guarantees deliver a message to the holder of this address (i.e. another agent)?
+
+The guarantees we would like to have are:
+
+- Reliability: with guarantees on message delivery
+- Security: no third-party can tamper with the message
+- Authentication: prevent impersonation
+- Confidentiality: prevent exposing sensitive information
+- Availability: some guarantees about the liveness of the service (tampering detection)
+
+The problem statement and the context impose a number of design constraints:
+
+- Distributed environment: no assumption are placed about the location of the agent, they can be anywhere in the publicly reachable internet
+- Decentralized environment: no trusted central authority
+- Support for resource-constrained devices
+
+The ACN solves the above problem whilst providing the above guarantees and satisfying the constraints.
+
+## Peers
+
+The ACN is maintained by peers. Peers are not to be equated with agents. They are processes (usually distributed and decentralized) that together maintain the service.
+
+## Distributed hash table
+
+At its core, the ACN comrises of a distributed hash table (DHT). A DHT is similar to a regular hash table in that it stores key-value pairs. However, storage is distributed across multiple machines (peers) with an efficient lookup mechanism. This is enabled by:
+
+- Consistent hashing: assignment
+- Structured overlays: (efficient) routing
+
+
+
+For the ACN, we use the DHT to store and maintain association between an agent address and the (network) location of its peer.
+
+
+## N-tier architecture
+
+To satisfy different resource constraints and flexible deployment the ACN is implemented as a multi-tier architecture. As such, it provides an extension of the client-server model. For the agent framework different tiers implemented as different `Connections`:
+
+
+
Note
-
Details coming soon. In the meantime check out this section.
+
The `p2p_libp2p_mailbox` connection is not available yet.
+
+## Trust and security
+
+An agent can choose which connection to use depending on the resource and trust requirements:
+
+- `p2p_libp2p` connection: the agent maintains a peer of the ACN. The agent does not need to trust any other entity.
+- `p2p_libp2p_client` connection: the agent maintains a client connection to a server which is operated by a peer of the ACN. The agent does need to trust the entity operating the peer.
+
+The main protocol uses public cryptography to provide trust and security:
+- DHT process starts with a public key pair signed by agent
+- Lookup for agent addresses includes agent signature
+- TLS handshake (with self-signed certificates)
+
+
-missing:
-- different configurations of setting up peer and client
diff --git a/docs/assets/acn-tiers.png b/docs/assets/acn-tiers.png
new file mode 100644
index 0000000000000000000000000000000000000000..92b7560f391b866c60e017cc8a19309f04592811
GIT binary patch
literal 69774
zcma&N1ymK?7dK2xNC*f5B1j{pba%IabV}!?LmCtWl8h
zf8W<NT
zHMJBIQ}{Iqz!cItay?1S`UIJizfZn@7m_`=f&aQaUoJ2BwNgG8FPdqk7a!ya=+
zx5GV7|JcSu+^F)Vg55oMl7`+N!vPP@ggAqxA6~cyb5lzq;Nka=7dS87@{}o%h5Jz#
z$^8>qUUQ=@K1W6#e&G)PMR7nM<(J*t39Sr=)ywxn)`=PY{X`wfjU%F1F?1$pms&UG
zme)1-%M8J*_I~ea;-#oR?+0@Sq*fJl`d<8V9v>Xti^6xZV?REw
zA|MlvVLyHBO1R&i^_Vl5TQr%BA(;j$VQvsvMAZEbTFb>RY))rOOB}!ECCE|iMIIQ!Q`=}6@_t8-KA!E+Kb2#{
zg+CR>a`Z#3wd4?cl(%`0-isyxckhlkMdpKJj2981!uLjeABI881aM&mm>zuQja`3Y7v(Y
zJH&nof5%F4ps_=lwrAnSzJnda<|)RcK~nR?ZLGP|i94|0s<`T7t*UYtsx0c)4LKz}
zLcLuhf)^4(B@r}Zg$wzP!BWuFj0>%_H>DBRL%2Etq+b+`X-g}9+$+3STDqi(=L*l4
z-_~xu{^1oSW^a6EI4$
zG-FyX(w387NiPs`8l^wBzraTDB3W-GHAQFiXR;3<@_-}5ffE(xet^9wj4O?(YLxcX
zUZA^G{^=b?B-2cULZq!0$DLiUTHpf6
zsa}Ua#Zmo&UM8h`5Bv3dq{j==cccBXA16s;QAosoe`s<~#lKLJlVU1Td-=}tQ%3}z
zFlTbEC{JnZeZqaLugb($ueCF=)*r;acO0-_M@tJ>&14(Eb$(X=ut?N;pveO96@oy7
zzC^=7u7wcFQ_^=KTE=z{NS0nYX!6Ft?=17sBwmoj6
zuT7~(D|stU5wk9R_@?36`$V}^1zpK$`DrPe$F4YJI2STh(e#~h_|l=2zhvHIvksvQ
z=?^)m(B`Ea1{I1`Q+P&Fe%~;muZz`{nH3Y1+@TVp!B#$`KgRc!eJCNFB%viTA!7MS
zH``eixQNwz8Q72(mVBl>f!b6s!fHUE{>Rr~q)(FNuM6l2WAyXbf0iGDug
zw%+>^X|itkz>bbx*QR!6FM9zIrK8l;o(Q3Xq64dgUb5!i;P=6|=CRglMu$z$8=hyB
zeJD$C2z4lPsQUGMiJ7Lu*>FGctml3YVvlu?8zrNpz2sX-M$+d(Sx#T9W1?st(@?}X
z#(2|cD9k36%eN~W$ZI5VCeJ==@73+0N$zEzdgfIaO>gDS(*Jl+A7UPch7L$HN{dg%UBQ^T2en--2srG)|Xx$7+??Y0ydS~aQb#vpN
z9oZ3D9IJ&0&{e-V6G9
z*Q3W_b=mRQG5t+_aF-bN8|dn})0(4BTWRU{(*4q7`}V!%z4r@llr|KO6q^+16it-o
zQq|)3va&v^OX#g>?IAU4>(9B*{c`$NBQczX_mN9-F2W%s>KnU~FzvgHQnR*g%?nLS
z8{>y>m%bK-G~n$%5Td-!4fzuC3$K7yQ1(H}Q`!Y*3Q7m<#q=*4G9P3ZqV1^ps2O5(
zR1Z~HRjgF?bAxh<6}OYw&4#9B)`okAs4NvWvJYbq(>AVR+G$HtrqdSEp2s`bhAzb}
z(wpZdEA(c(a!#IQzpe~SdfhY9BapOv=5R^u<4eF|t*V~k$DqmL{^ahx;`_&M5hMyE
zA}SCoG|YuM(R#FEhAFWKG(tV8bvq?H52im)7uA&BM+qy{Ul21?%tf~tm2c?sDZDhrgvy&*3}dE
z73J&DB1VO-8B^L(EmhWX!^Ejg>(4QsF(-n)I<5pZw<&%T{jtWev+4uF{#|{XI>Qsu
z&9=rj&9U_f#mwGybS}>iUWR?eAP_ozvR_coI>YKQaa4i`ovlYQpwJqEjyP=u<&bs1
zSy_8B&G3X_mIaTI@1*w!Bp*too8Hvu{iZ*Zi6Mj`hoPhhUBAk+s&zAZ6njiwbGS6V
zs@iM2+huqxt>`d+x<0*LzYbdP*C&A`VXO+WxXFF-5j5J>hW9ckEWh*XyeO^RiT~zQEe8ZKqm$
zZgNs!)l+@sgG*O^dJ~Z+i#OS^w`!BlRke4I_x+1jpOx!5-|v?Tlm6?7MRz9dZ24B+
zI1E4T_^^+XZKN({@Ugb6fW9biY45bXs29FB*oXLPxR`QGDnEjlOwZxnE1O?stxMG3
zE_6(onrIyr`7P4MUTrOB$7oE_R99t$3c9SWz0FWcUriPCq1o$+s<<}C&M?lf=HGRK
zE(Dys5o>n8ar``!+q96i`}LEYPeL+Zhs(pQyF2_2JU{pQHQY7&4Bj_QIxwA0zTYAm
zZ?Hp!@Yf~z9-Ng(G-FL`+o#w!T!vq#bv3NIS^GF$+ZrS&jSqSnoiI-;HTrJ(&$kW-
zhX(I95DH}p<$Kv2)gFg@i=h;_Cy?Niap`%YIx*}&TP}3>`p03<#zcf~(51%*h>F39
z)7e35b9~cN@3O6&@$Rwf)9Z#3bbZW5W?$oTvlE@;so`CfIe|xsXX%H~&A@};)rdhd
z2sXi8tgcf>=sBHVYmk{a;@&tj+`1*)Q|8u#c9Y&TC8oEl>G_iLLPot!%1nZABkhVV
zx@*;NrDUAJ$dM$Rqt6BCkuuZM+Z7l>ZIrMv2{C8gQ6VUI3^d_{tx)Czz3lA`59a6Z
zxJ!MtLl|Hca~fAeyElsoJyQ9gX!Z+X?~TRIhm4g|Q*5<+pJ#5yZZOJxL)djcg}wrL
zN2sZ$jG2N0+!Jt)3Wo$w42KNP;K4@_p5&i%Nq9Oq#M|o#aB#tva7cgMqX>?$zewMjRVK;&I?X$O`VO%
z-ED2`oOs;@C~oiI1?RBKEEMFow>Vo1P-rSBlZ!zdP02Z!*_oeG2%?jdlk+>8nDMHJ
zOaApZ_)mbs!r9rLmxaa6&5hZOjTz!-&hm_hhlk}UD+?>SXL_Y42g{*g5%cANYTM`gh9TkG^m+brgfxf+w8?|K0V!
z9{%4S|L+HH=hXUlPIj*UW6J;e<*z6CSzx69&sO~2=i94bqXp6VS^i;~AbNJF*ayJJ
zhnC_>YTyW@?DlU5eA9ss>iEt=K1{K5Kzhg_$7>hfrC$Fzvi^@A2)y}aq#y@
z|8sa@a(`r0bllp5I_LkU6&3vy>(BGU78copfP{=TeWuI%U#o-zH+bFolCfHiQod
zK-%$QCjHN?f)7A|BK|jxRHbktA_#7R3E}^_Rd6EkbN@X&60W9SCb>UfhMd%YFdRqN
zFVk=LzlTRaV-!}7Y)R|Sq5LDOU{3;ZaQn~U;r{=M0}h_Q_r-B1w$LR`Onn|ZyMH%J
zv#x9`-Mz`q)Hi=#VEBDe?Rf!}@4PY8d3kn#hA};CT8aOs
z-SPKBLPbY-xtJ-9zMg_qGvk_4^PN$v!ed;^;ZsY0ir9qVdli_ppp~?Aip|>rDb#@{lKQqcz`Qy@T?vc}#zDbhx
z0y^NuF?T2@K>FY3Saf@x@X6iP?r>a3cOpJ!*>#
z!pidn3*jyS2yTaXMdE+rJvlxQe&rEvT1IdzJ$>oODk38PBkzygfY$-surd0CYXJ1Y
z0Mo4y55M+fh6VK>H|_(_{MT6>JVt2X_?0jw1`YjXn_|u%iTeSFGsIwvJ4MIAKeehg
zPW%72!JVrGy4$|Hx%gz-3g4_fBoN
z;26e2LyL$1<#n3uAH}B>h))ZF*^^&DVfIGtzwwIr^PPvN|B=f$p}^?SS*7B|gQKR`
zGoGYOa+;rNp?@OIj|nWa`l)J236PAEAigm)^yxvRO58u{oHF3D=<}u2QY75Rbeauj
zIqx2xC#Ukdure~_rh3iiHaQ;u6jI3)hVM)lXi!bQpRoNso+;&Ub5t(>MFBy=_&15i
ze~?OUB|w^oH|`0O?CZ=-)$WdR?`~{|xddH9XCz<}sD?i&gefk>{&D%jtUx$T$i3b{
zg(;Ab({woEiiB(;5s)$DV(#cjk;M@&iq0=#&&J(cU8kt!sYuW$r9UJb|03}xufc5q
z)^X;I@5Usbotb%LtcQlaxI^-=34@qxpOlDe-!>p%{hli8AK30k2Bb-d&L*@NY`C*G
z{Y(?s)SYcU?LS!kS}ib3Z`0aPHPDgDB@5RPpyOGJ^2mRZe;=^nmzkyX^zkhTWVYoK@t5NZHhHUeT+ASv|=Mlbzlg6xcCv*$lT*l1f
z?$lkT@;J#JZH`iVpC9g6vNOG}Z<(yJUTN`1d|pDUa^IvU@wwGlA$<~?dAM3sY~Za>
z3V#8UP$3cBqslkAy8Go)<{3a!UmE=?ja{#t6UtP_gOw*`o*xPov~AHcwQ}s<|%P&0%M6eJ3uK`D;PfPr+;E<4yQ&d0l0qOWhSzB&pZj%pK^rHm5B5Jx)
zIo|6{o>zyT0Y4=7mpdsphH}E1G34hNvLJXMt~z`RV}5K*8v@J>iEmtfOXc-wV?&$M
z+7;2NFg+;FfUKMv_OEyRx}@_>t3TVHRw+Fe
zgSl3?+{ERYq3whFYfmf@k=lUNh+EdSoB`JM?JiX|At5Vn-7~KY&LqF|;r2W(WYjDb
z=7h{L^11$uEKI)VUOXhJ(|;6UtEUoHIGc5LNa?4qgFZ9MEqFr
zxPh-;we1uQ2sPpmkkL;CbZNV0ON|02a{WaEQ7|tb5%#{f+sd%eM$&dA_ukS`FP)>O
z^gPom1eW$~JmbozCqOcuD75e;k2XB#gy^mb_*}mGs`BZl%WVI(I%kmq1JmZ*
z^2}({Nr9tp!5+;U63){XM4YwFKze1M6Fzp0b3!-#G^26`R+}4VUF4SMhSn8=i$(tX
zeIzB))juapSFkUdwhdQ=fB@VuYKq+mmU{)a^nfmWZ~
zmsd@DwtQQt;;KMKlj~!*VIGi0PMIX;4l=fzyJ$WC_(`K_<1a@gqJvrG-Dj?Mki}4r
z>5$n*+70)DG46-;gOh_1?k34{FXAVx)R+o~G;D3wC8@Sd0>ddjY$
zmk+6bxA}%yEEo$I;a%VT#V{7x*+!4{0y~P6QHyAyh$bG2;~dhm|E^dUFEx9uq(08c|hcE0n}MsF5XcUW-Q`p
z=1DsP14I)DqIekknjUSGMEc%bX>6)7F$H5i+S>^iSAOa_NtJZiY0=M+F|oXjEyQM;
zdn^er;-4TmdOsjQ&GLu;Z>q$BUQx7J=sX6V@p(f&ML@tn!`7D&yrC*<4SKEeZ2s%h
zC3^Jpjoggol>~$M)!r1j?a3;I|JLTy+~`o7;W8k<}2a6og6n*{)<%R30P-jcFWBTFvv>OrM5`O
z{yYx&zs>yzps=r>5T+cUqQ6|)In+i&S2-RiGyb+b-x{b=Yj4Dss@z4{XUpS#UMZi>
zuVvSK<;wPgLCV*mE29;=DxV
zyyo9=PQ842*Zeq~qp{4h501}trl*BAE8KSVJAoOAJ|iovqh_vK#`R73IrHg&=n=28
zwDUT(cZ$SKnRVNSAyhT$Qh!~C|2zUZ6V2ylSAxud`UPebF{;{ln>-m|VSa*-q;&
z*-!FGSJiWq?uQYSkMy*9fV4p$ShYHFRGve$DRjeZ=>q`O5KoYWzvoWi*>c
z*UkFQOq1%Nw##63?r{Q#lb?bw23PtK6lotch2LHqb9tW$Pzm~o=H8?JRH=@BS
z(W)>D^~B@72?(Ma%Ys~t6lnB&rLtQ_dtDukk1^NncQLFCN|7D;m?8Tc0_zcQf9bRo
z9NTE{8R$NPj<~Luj7SoPOI9}LW#sJL<~m0-p3A9{eUk{meX|=v1;k5a
zee;d$4ofnWsW)bqVq@@xqwb>!4cjs4tM$A!{b&tO0ZQK+?+%^#ARLxMUsYmu
ztDPCMBH-slB{4mR5BhbowxDwU0dKPVt#_r5NFc{{*Nz?d8^`PIt4^J)<6WmL1ajvX
zEQdQ8T-M3_GYgLo>Kv_GhuUp&8yN`;`Zitva=;2BnZg++
z864K}muG7kiK1$|Wxf;@985@aENmsO`=+>DWQf%q+(WwOVHOPv(5P
zNg$1nc`ubS1ij_YUO857Vb=QJ_!>Utayi1UI^V9D>zUxax1Y>moo(Kq?l@tZaOE3v
z?YoY-fJwrcNHTSv?FE9bm1OJUXE$@7ZBI7~O8CY0%%Yg}>fO7CJW1;zOC9f5JBnv7
zua+W&dY&qN4I|`&Z$I9iGHne&rg=KxgqRjNVR`itQd+26r$WG_ZPLb&_TXZtVVCp6
zyUF$F!GnQ?G`Cqx1USs+Pt*(PY$q#!1z2H;RHu{2h~P+VDlE5>fytSD_}q
z!)pVM098Xd8VMP@%3GedM({*?opzWo6lyx(P^ew4IXUB&VDgKYo{t*i4^62retl6DEp%y#(Ff;4^qIk79#p3VkS7FEoyEJ87Cb
z_p;QdXbmka#%vs~|2TduLeP}d>^f^;BkEJR^MY;#Q^6VwIdymJL8F9&eD(Ed;7O66
z`NiGXi$|8b0wotqMG|Yu139YW=|ja%TouI!?Ciy=3WwXTr#%ij*9@2wE|Jlbz00lx
zGs(vUgs*PR&M#(|*?C0sui0TV@V2^`Fwfv1I|`b=I+5qj|{#ZK12f_+orxeOdhKwVx+W3BB}b%
z*O{a7#Sh~MnSI)+qoA9}$71rr2h&dd)EkJvyscS9?i~&*c?KdC2)v5X6C=9vUG%v+
z&*6C&6>}lA);Pe0nEq;$o?g51^VyBtm5-J1P@R)Gy38^#
zPFxq--uU=JIMh52dbtF!b*^o7k9y(t4zDMHWn-vwTw(Q&97|#CEJ^D}rGkaZ%x!C*
zL6PRQ($5RY);))ql}}s61f+J~=Jv!`T(_uH1xXp)*lieDt+Wis2(*71((4wgAEN5yXf-R^Wp!h83aHxZR^t+=3Z&<&7h-RSIgGr6%pUHN%@
zmpa?X59?00e@E&{IxQDJ%LKCv(vqW)zxA}=CsMh!|TD!
zOzkSGp;`yyU1|%u%e)~KQjnQ13Vn{gWYAV(LO<967Ki7b!|==
zHWQw^ir3i9h~GTQnj`cLyPmb;e)$HWbIoEPQ({hf;Orr<%ce;X^N^p?9J7k`D$ibS
zSM~qtJmmK!TR-=k$@Vjonx1DXWh*aqoAh-#IpJ6^5yOoXEBEjV2rUQxO0R?KI>$sm
z>^K`vC)weJwCp*kM&DifxMG3&yx{W1r$(JE&R7x3j?LA`K!iEkO9hd1p+YXQL#J=K
z=|`8t?LX@aTul$u1N%6hdQQB;Lro;Tx%swvUoKnWz{y{1_>Q(rzfWLO!%;o^gMpiQ
zeT}^QX=fchqRSgG7J(nD&o;&iGEOvU3pGXj1u>POULLgUA)LSSa~ur>UipCV-I>4g
zLkAbzU+&M4kbnIsSTMj7X|2o51ge(R{w}+EeHt0)MO8<7A;;EY&B$JwGVic%`MPSiO)Y&i_;W6qomshK=s
zTFi1MZ3aH+YACY5G$@pbi$<{qz=~g?-Mg(&2tKetHiP^gl`BoFnsW=m&}1Q?nCZ@yDYI@wG3Mi(_#!KD=k--&StgC!q;dKS^-;-K7K8`2P+C>
zJo8Y_j6v8+LG*oimQiVQQp-PcV5-_#kv5eW5>CS5EBy-lp;gerFRsJLQ3_1t)xK1U
z6n-a^b$ek?S6i<3^Yvl4F>jUsI98B#j+
zw75yqCP`16d|At|VKIDJz5MQlG`^6!RkyZCM
zGT)!x`7NeZ{R3i6L>r6
zeOqWg8q>$s@^`>lfb5Ol`O^m;e_p9mE5$ofzc5ER=
z4PA#fEdE-%GYvH!=d+feCOa4AvNe`ehvY1XfhnP)Q}{Sfg-?+-^pTKHW753VT;vGX
zUH0sK((@-(LYf-f;yahVB|bZE)~%CKOyf67?-05k
zH`u>E-B4Kx(q6+vU+qn%@#Z&Or)q|VUFVdGZ&;hutjXNOq?-s$XU=cp=9um`#z9}W
zk9+bDs+%dE^~f_f8umt%d;Rj-I31`f!wU93tedtUE}Av=)<8Mlc)TR&KF%M~>^g2F
zBN#t-pyU$CB1i^N?2O}!kk_e{++Xe9)p<=hR+O138~23OW8XxoGDPw(tEPm|^L)N|
zmg;xhq8$+6B;tSVn;h=319^al3Fpk{?oFXZt9zsu{*dP-jl>lQm2*G_vF6Rtdcw~@
zhgzjSSKg*o!$voN7DDDe56@N^-puI>B14TCyYER;F7C9+)xFM1~VXdC(k$?s+hR|Tqa
zpI+-zVeJ0pM?8%2g6E3I+cQj6c6DMw;nyR&;&fuz_n|)>lbXDm3|@1lpCPHU7`$A?
zd%$)kH?iL?Y3cY4b5%3#ORdjGGoSw9tyDgzd<)c4=c^s6Z<_5aXLg58D0ACo`m}U!
zU9gpfZp)mFAOxx{2nKciQ3Kbi_{@1-<;+>$*CDe%$M3u^l%S=)UXD@fQ4nuJD===-
z=`Lx$w(8&-PZ>Pt6kX|xE7F_IAmOsZPh;CI?`A%*8@|6KnOl5Erz9OO@9Rz`xzlRT
zONGUso|xxUH9^mKef<^dQyz<)~$P;XXKAU&5zlfGk%
z9oHa+(gdmNI})xwBrVhK_$t&Mr7NG!-LtVGogB&c#Nl_*MbGr#5p&2o*XFoxPo8-r
z8eU(Xu{tb@9|VO!Ef*Vl5}%1dPZu%pu3diq7`*W2+abFDa(&=Kx%D{nfxz$?g(eQF
z6yVoGfj-RJR$nz0?HLAo-}OPnNU_@VyR94hi@x%kT!AbI+VqX|o&ML}h&^X_PIeFY
zq*^mI^dqsQ?mqk0c(q{exYR3S;5|}y28DiHK9;Zlo-9Z6gK+(^`YoiG<2mXJK!*
zS@z>pe&@oR4+n%^t;iwfq!%IWP?J{3bx2fsK6^Hk>38r?2Mhl7K@l5PbGTI^kr)~U
z@eG@>vgxA^Z?G%9NV%X6&$i%)0{=DizT6PgN2!ST7X|7evx!W4_0G}WW5GO5tBEO5
z*aC-ePV;5)Ygq4cH?f6gH>khaOxk*nW$;diDMnf|
zHM_6=94=dQ`JBP;v9Fo(KEb8pRe!obxzn1WlbFVM6&A;+$HPNRcyCYdgVkPGQG%`7
zCxKZ{rE&Cwh<~~#Nd3EG=~a7Dc9GHXp9*1<@|s*XpLdWz@T(3nA54!3ZRSJqXyl*H
zQDde#3xbf|(w$WMGvK*Okv0cgQnjL4qs;`X<&V-2u`C9&KQ;zLfttqY*wsmZ?y}Lj
z*0=R>!6B0Q^P6*tFai$$cqq>jpNSHkx3!Bq-CUlu7t3L?GxrnBB)i%Llmiq$6p!h-nw8~qHf@QJ?GD**2Q&_g(2ZpdaoiBXqm@Xs;BJO#Ee$@(x$vt
zv5^8`38wnHrFK}tnW7A85!##G{Q}e(?@6f7nCmsK&$kkZo=DT4jLP`9$bjg{1I}3x
z?nR6B0>!Rmg;A@q_Zs!2-?$*T7v5CukyLKfkM;OQ_9}u0%WHi
zb8n2rb1N>{CEn4VlzT}PCQ%{jb?D42uc}T?HA`^tztrFPOa|*kkk102GCkT3t5~o!
zXv-IksfdFz~J-3hg}MZo22aH!m`$;4|*xw$c#eY3G_-^LMRTVX=Tj6$AbJWRqq|
z$g4kf9Ax#D7w#HLn;BZpK8U1K1}9tM3iZ0G&@3-j?+;qoAbAuPZHFV3rSm?==q(j#
zsu#4HC9lnQr$4*wUNQSjRrJM8bm=8^_xF|>Ashk8DdW`_?yC;{2B8r$vtj$)wRs0C
zLlhc`)s}`?ts%^q#5Iu`DA-(E1saTT)#;DJ4_Q1+yY$Wb1{dN}OF_r$1EB@ttt;Ta
zbp>w!x`Jj6RwtyqR0Y?tb&$r7({s<;>%uL
zSLLhdzA7?;BQd8uP{Yrz_8o-z>~FJF%%09+%%QA%5L0ZN(1)!(mTa;k?R$&tuL))Z
zLWf)G18UxU0#$%%>2t2$^k+v284A=zWZtsr?$tFlZ6g5zMJZgJ-k4UN*OV?@4-1s0
z3|u{)PtuTr|F$9JEtWub_oMzV-3psy
zPa$gSWvT>TOgv6kCz~_f{cchH9X^KPqlVd_NMj~21`5FctvLXoFz&`Q@(Q%Zr%s3(C~Pp5n)u8kW=aMX{3M+m52w1G<=6NvOX!o%mT89t)F3A}Th6cTxacA526R=VR|
zQr6h~3}1CpXPBJ6s^Xz-fN(tJ4Id+4wH+tqp6-i66Y|{J)dv9xI%AS#=7n6rQy^8k!u@Sa%NCJ?f-G&8?BL
zlN1hXg1F6%jL)SibO^AnLS(5PSpx=$+|mR%_;f&1ZsJO8>$a~v%>wiPf`0|ku%5%u
z{r74D=h+v)sV;+By$E3vh`B5Wv)*K%+odC;DG3eWQ!-saDaRG2v*CDkCk&3iP=ojg-UFpz23KFP5v
zGYv|$U+Z~Bc5&bt=)Na2g&lhCY6Vw5IWp@>t`%NY)O%@{-{3T+6fBHJ47g4#-+KAUN{I9X1&p%B`Elo?V9fp1Oc(c99EY#{v1GcFu;0h
z*CpNbkN`u^!^S3Qfp%qZaNNR1s6P4K$ER8yZ8*ty`HmHUaB^&rtz(Cb9L3Bvxw0`l
z9)gcAJ{7Znix{8)TZZGIDl0DrgbkD2l@=DSx48-s-Xby#V_N*+5ly~FKIR;i0m0;9#dGHkshh{DO_S=4SrG0kL8$w)eLJCk=x{ec6Oa
z=`xAr*jj3z8Z}V)y&Zx<8nDbJBkInqXb(Oj5G$ZUE`Z5p>~$
zK}R~9#HN0u4eX1B0W`++Y=32cL{&*DscL$C>GTMT^=yW_F&hA?_(84sqNf9(N0teD~V<#7}U+ujz^=6sC+
zQgC@lt?|2k?U#lCu!^NUDO^ebp+d_7J#Ly~*8_9kC8*4jFHIV;;;S3aGa)2!v%2guc;z+Ch7p285
z4p{h@G)lTxx-yeI>O9{1{X4KGlZW)bF}?oc_qc&Ix&&EMG*D?7&;-iTEn;`NqbSLf-bC2@q@{#77LIaS9>h;)bgV7pQwFbC~|Q-0KF%Q
z?WvjsTx!|c3sDP!f9U&1QvCd^0c&)JU;G*#5JyE{%&qCuld0gdixdif7{AaSEC+BE
zi`)CPkN)A!|H8v?VFvv}gAga7k}?j-iM(;s1M_SL{tS6t9C>qsfjL+wCH
zV~{cUFU$XTSOi$CtrogOK?79znd}rg1zqX;c`T`7dMf@jnAbWUBP>06)UxEh6{#
zME=VNAcKm6bxwDhPV_ytifW>FSK0n&7cD_wK3nDsd=$tE-d0*1c2m;5g+Al>M+`rp
zJ8w_E=!hU=fq^1Ehy@2}-(C9`3HKL9*r$*=Et6b*|HHVPGEP0I`9DH4NZ`JjWWEfH
zXgp|i=*)VorCDf5o&7834j@0o2~OKQl%t@te}$c6Lnb03i&y>6{EGM7k0;DcfBq;N
zDm4;=^?Oy5CHVfP4<1RE3iy|-zR-kExcIdtv>-ejH?Mr~7cX$7=IhqdV?dEn8o)D5
zfng7ETG0I${3!edhL(_&5%CARfb?V~bqOf>FkvOq-@KG&h5@#S1YT8wUa-kAd#{PS7
zVR8qUm#*10c3lB@+KibkRs$3LLs9V!81DiL)R{{9EuQ^#
zBUN}y5GKho40QmY+;V`2xNB{7|Kgqf-@@QK@1g^KD|#2tH{d36SuD{0o+wh+5O`=-
z!xp$a&9W@{3_*c2JHh|ihsaMrVUxul;#dOerNbnf`2j$aMD;e+fsuog-@>=sNC~7i
zW~;bC(X1!&p4GF|;D0Fn`~85j`a@v!Ty3tN(?pOlxXjW2w%0PCW(^E#WTV@5x@wUgnHWm
zIa@=2$m1v;ghl!Uw9lOEC@rN7#j46gPs5Ri#*$Cka3WNLc(i
zDRD|$0H{a2y$nRJ$X?+wSd9mLd@x{~q7|;K$gS^g0gh=;qEwIkUO+%!QF7N98K-#f
zG3Xj3fX+~kHWUT<6`qjwSRpL2ev5MF=K7-KA;0^;NE(9%v#L)%ro(!8g?WD$z->?i
zj8(XeQQVUkCIBNCZbR~36b}9dVXTzw`lNic6Je^_mhGm=*^$JO1i=#RF2L05zuKU#
zJD#*Q?MvmcB<=G-(q-Cfy+bBlqTi(JjR|Unv7ks)droY@4`Zb8CE)TGgACs5P+TUu
z&vTz8zFe4$Rmzm_<_f^arO-Q><*6^x(Ce4W3xCUXiG))BTJRL>HR7+R^8y-GVPlrDif%|ULNw!jkpvotCq9i`I;y@kQVH{KgfcdY@5qZCdQJMET!}U>Q
zQHpEwBtWr?<`To)oPQ>;YXOUk^U|nPD#`=rWyM3wtz%J!aw?J+7rXIsa)dI+4|#G<
zTAaAHkNhgqABTkB9OXVdKl5Wen!Y<%yTj+C4{{lk%Xbngj0i@p8NQEVHgi}wR*t<)
zBiY}#9VNAWJe1nqNfT%neIL~wrq5)+c+DwW^;-RBZPf1f+9(Kyh=_$x>KkE3dF^&HQsdetDo-?Bi>78^lS2JcHbpGW;#s$b>+z2tT59-x2a2l
z&tgd4{8ou~e}b+ji+=t)T1HJqB36?_Pp?c8G<1YG^lR>bfcai-MEG1FjNCc22-bH*
zL<|)lt~~Mwp`aY759Wx6;FjAjh@P;g##7(~fGJQdQvX5@!d|_BCwGuG0p`2yC&?#S6z6*-7F$~2|XsBiNC_VP|VwWFW;Ycgn
zZ!V)vRGU`V%rrhfv<-?jEskR-dBVKG()d)u14`n$`-3Kht2pMP@53nEbSGKQ^q$cJ
zmj-5Jbb@%sbPqx=LhmrqV57+@~s^8hXIsq9#%*c>7|$@LIZn12{9ZvN>A>
zfPwFs
zmR*6$EQr3kDP3f(l{jxioSH*bgC>iYykPLC~kOkvcGR1>#8EN1x
z30Er+Apef1%`4?Vpi}*HWs0fv2%@Xa#q&q?x#17_&VwgDL2%cfO$k5{
zFBg;6gcFv<2+~;S)-QhIv2Mg*_j&+)aty0!Neqa-yCO)&yOY>*sX>rN!}!_F4bSP_
zk!}fSzxSgewUJa!C1*oAWgMCK0`q^=Er-oH3eV4o`Pt~pcdbgRG!F%
z;WJs$Z8I(;n9yKT_QZa-?^d8}!QKsd-T%-=*-&A=pna=w(yN8f
zOR3>vC;CNqU$4&I5Xo++3!=dq*MsZT0#=*7f=^{i$Lo|uyn>cvpujj*tVPd6GG`Q?
z=P1VH;j%70$b;`ZXyl)6;gmrnDqZ7Uw#)}!ya=A)GU~Y)+I{1s1m&oNz>Cnej2Q^~^K<7Q-$}-dd1d_5m7^eN!ZoC$u$GVM}{BJ=BEM?v%i#@Bzm4jiXJL~mUQGBdK
zTH8;?;jzNlw&1==l7gQ`j1N%C+ykCTjuOVCi-DIFotqe(Eux-WbZQ
zQG6ye#a^;&xusG8N&?pE%rUuq{B%;+Zkj<6DHNlSMxIU{7}T?>%fNK@Wo?z67!mu+
zLN_6R{tdVf2+0I%MtWvT7n<3EVv-LF5wk#4j6@(Ap1)>EwmpE({!F5)jnq21GVUXcSxNf#=vm4qCT(N8)e8*tL;C9{
z)EHfzc(mEi4}!B#T0TI(x{vSX>rFK3Wgej1^)jza74(+Pk7r~Am_^C@6C&~xp`ljK
z!m4ujS;md&`Zs45$jD=YwsO@r6EX7Qg-(=(S7vdCo9Br{f_Y;_E~e|B(Z=W-pU=k`
zf@G3{9;{TRcRfKu8OPh$>Xstd8)8gaUB4-E1{8_kpnRD>M?-Iu!set~KUFr?g1STV
zG=m=vogo&|Zn+r87iwK`cDaeZY?>(Mnz=$o=FMm=8c*1dk5czImkfkXlv-YCTRy*`
zaY|P#FN|TLHGmmiSc@wK0GubGb!@qbj)%1Z4b|QKcaBqP2nroh(HYTvDEx%kf#uK2
zBRMNaL#KeqhJaYXPY(!~tBfl4ZQzgvOeK|e1mFBCu)f{bhJgX+RZqUp>hV!2LBo~{
zs`%s)z1jnXwMQ!E3@y)v8Ja~}gR17fU%AcTN>63Hj8o
zPos1u%=rjVacMBxabBPxADAh`2+r_@aXc$?N$+b{&N}2M_gr&52tpL`r*2mQasi7m
z*XD9%}2aY(D)SB=LN1`Uf-t&0H|i;C&&Na-dV~sjKZy
zgCjT>EvWa3ZDeru{Z_VC6G`s}#2_DXm)&}`u0w`WP9a2
zQ7M<#qF*_aLX3LF(bWlUYRDO5a{E3onDMH+YBt-D)tCj10ffZxV7aK|lbWEu25_sU
zVJ#qLWFhlDj53$*u-PAyW0_E)jU&fl0Jmv&sIoGr7w3_>Y$=_-5OJ11@FO_=xCD>bK20I?{E=)NIIPDW5YA|2OW(7cD9@Q&%4!-^xWWs6ljcpL$j3tn$~yp;7@O`o;DU?)dXC5+
z2^k<9V^4yi%)6K#y=t1L<=wq0h#UM|n=V>^^_jHBY0o&s_w=sME+CfwA8GF$j^+RV
z4~+b=-XyYTW=7egC3{A;kiGZzd!Bl~Ki|*q
z{@%xN|8XCOBdN=IzRuTp&d1|%w#9#(Y@)r#?o=WT81_*i&epx`w}YnA9>*>=VrV8V
zglGC32tC5jZ!j58c9otmYJL5oREycnF86|tpenyn{RPqc&moF=Gq+tER~t}&Pe}h_
z6|<5Hj{z+O>r{18tgG(+56dOK4~N6u0FXV%Qwi)*%O?9Sr7
z0y_bKCs^T-oK?jLK65m84fYLO}(Sq^SKoZG6w`>|^IgyaI&JklvsA
zwQYrrC-u?Z-b409pJoRtIvCSjG_lwNy@7|jUJFrk;8sIF2HIS~ep#y84*{gk#Zvtt
z_SQddm+Ah5P91A1-Cxokns}Hs;aPr^J-0$Yo3E@qo%W(uuj4v1Z4&TcPS&XN5>Y|z
z_ccMHzbvHpua)n7ByEhnrUO7RHh|eu@0DFWMzn;)u6hgW^8-4NAU`nod{UiGp+A)<
zG;~JL1mi_~)%ZMf`~~0d)A-QQ603!H
zlI2pIVS|2H$jD;c`YgW%-6Z3Y(#fWkT?U3l_Y)-LwR(<KTFlx^_jYWXI8W2;@99sngAZn}v)&8hb+8tY3C^k7
zs1wZ49%b(-wF~W^uGZPQ{zzJPFxw+Ot#a!!=q|J|
zirMX+Z2Rry7@2WQL#ZuOY17=NPV_I08vh!iK^gb9kJ6BHCZ)1Q6OT8);|UaBeqHim
z18RM}w|RbID9?Z)ZXH;w$^YzetbzAaKWm)hvZ9Zh^?W}U(sg$P5>k7zVkqs-yF8Yd
z=(?IhNqQ_+d{y<*_qxEMOpDO&CmR#b|I|mt4+Ey7u6<|u#hl}(#wSyCW^VML!&3&FY@)tMY#9dYs^_?A=|d#4
z>aujI2l}9Q+{r|_?_}^@6SrcT?J2nz`_v&P=l25+hga0^I=4J>0==6f6jE|2e=
zZD{(`y%9l^2|M}FgZ&2Y9HMebH)O1D?TvmGn9Oh3=Mst}uoedTH_48BROi{1H
zR7xcK5MAq|Ii0@f0uXVwnKvhA&`_e`R`@*
zGPo@7^gJcjgcoaTh^E^k4aa>#t(r>kYgj%)8|mu|X0
z<+blP7{)uL4j`CH=&-&fFQEOAXu&+WHs1J7ezl2&15^%FCQ-evQYNq^5=y>JUpSmQ
zi$Y?0K3z^IyvCo>*RB0&jK##FsG+$U9c44*^l7r`@x4Ld6$t1ZAkDO&@9!iE@vPXf
z3nKKEtqnZ$nc2kA1AXfrBZT57U|k+-Azx8bDDW$~PE}$n8Q}vdzHhZV*k
zBf9k*l-ZTvo*Q!7co)@zwcrHWLPdM7zGU5qUD<%PTp+XAwydN+0N43VS}{{S1!+-?
zS_`jCUMGEN?##KT6YDTv63-D}{rte>#}d#{>VYI|1cf(aPJy1M%&aWWHx9&!%KsnY+0M>
zj$ZJjYXxVe&Fr%KY+)h5f^b_5yqdJ#v{R4b!eNPj`!0x9uo
z!K6kIOWqld)yb?6$c}EJ+1q|twJ;)Kjin
zJfF&39Kr$pE;r#k*vmb*hi2rVN&Uq-P?Mt(EA;
zVL9e2W^$~)6l?FO?_{V}&V&vDGfUt)#d%3S?KSpXj_j72!JF&67GFG1sKKhaz9Iq)
zcbrcg5a&Cyv^qXB!F@j@zAB{@y{{$M+y^22fxmGh~oIQvCNv%4w%iDE;h1O
zW)RGo9K-P4n&2pif
ztH77pzeV61vQIkbg>4t(fg4^ep8XzA_&3l1bXvM@N&aNVR3!`k=fY|FN&iXTi7KNfP8dxwDT$g5CEnrq7oCw7no6(U#KZ(XX&C0vxf!lf|9U
z(QWO~-y_hvO<*WFN=&J68=O2qt()26M;FpQmO}%eJxQKIpkL)N4daZmYDGr2QHu3w
z2lo&f&3Y^Mjxnd?Tya#^oEig@-eim9f#8?Yl&-r>`KeGgSM9qptz!?v;XvaHu$>C*Qz%0p>apIyOXpI?y>1AuO|Vnr~tj!lY_ulpJu!G(aAUq1nNI?O`i!rTQF*z|M9xT`i$d|
zuFdU?B4v(>pTCU{!65xFC;3h4nOpEg)HP5Q8kNhq|4$-Y2;s2*7LlIMzq_*aV?_{ti^Z!L%&_m9mK
zI)K20wI|=Goo^O-!CeELReYhk$|`vTo=kApL`Py^$-W*H%ZmZ6AC}!
zWOFIjBNdWaCj>TGEp+)7E+>7R;?`9G3)&}!~cbV6h
zHyw1OC_3*atg`QX_dkQQ9R{rix+J%+wLj^ub9kxn&XQhiyX*aRFZ#!j!?ZR5KmpjI
zy5OLP^T~a^#;Iw)UcdPKL>rRycyb%D8URiNf2}$Ay+=GoE#y$6
z&pJIczpHcYgZY4{KuwM(blXa$@I+mF0)9RLnK?qmFGC)-{5Su*BO?+T-#kT*Id;!-{H?Pt*oaE|UDE
zV^aK1<%0#CiRoz4?W3M5axq-$>{g|fyzv%pljTR@q?Sj?^m1!>l|0iqh!M9_tB<^B
zF&NY8?dIe)^&v-TC=2JcwKCBF$#ZrSmvisWPp2tObP9)ZAVa2|Ydzsb&ct5}vH+}g
zx<`Xa(Fi_zG=;^tN>+JKWLqr4j8q1}cC;skMgG%k4MLj3WW7te*1Ctz4_ZM$D=4Ig
zy4WI=`(dRWcb967sSTOV=+)L$O~22Sv2dMf>PnRLeJez^YHBl-0*A-=%}FNv6#KR5
z%Chnq`;}5~Nc^z77p~reQ~3`reN}O-!ePU{rTt8kJ)0g!+uA#a1mLr)y}!-1@T@d3
z!Am9a32$l6gU*>CX{hUbDC%)P3M_&vaaUY7fveoue_~qz`mxV+W&2RAA@1VIMBkfll0x^Ut(j8O02al5X%WEbza)J=
zLKu?)LG827x|}DS=`1}3k0OCH8%2iKxBZRUf)#Gu_-Qj@T(;9Sz4*n8!ng8U?tRyf
z$`jkgaCVi0Qmxb+m+Lsj#S(>PUfQ;SkiuK_D<)-80gpWF~Q3-op`*9>K875HWB>lI)OKEZ~C
z-UA2d*^yB$B6z_ek8ILnES%XB6|4HNO#1}}yb{D94#166z>w~*-zkB{6K^+*`E!Wy
zVX&+dZf+jO7;ZoyZ?rz!GoG3_SPd-Ps;HTpUNp-aGWl!C4mW-#>#VYW3=mr=gHy`6
zwjDt;Tk6SVZ*?sjX;AY67yO*plz%V44$t+BFT5gum-K}MY61aka=Cn>V?kH!R$wQ{
z#IbjOB3>OT>gB88$|96q{)R@whUDofG!3=m--FQP>csTYc9#?)bPzYrG|%}h;Nh8=
zPRY9+t8?KH+eJkWlqwGuwtnIeWNbS#vn_{R9NW#Be@ZXO%FI6m5%{~v)$Nm-0N?cF!Pz~U|KKGhcDuMpOn)AoIg|Sdg
zY7y(tGfLS3)&g6g#CH0YMQQJc|ID&HqLzoh4Gvume_w!z56p%omSamWIKGM$hn
zML8ZgXA7A)dW~8x89`XF3lJXAS=%!dHhGYE6h%Hw^cLE+EQss~X{~9(vCaL!#;+xr
z=j5Ap6Bx!@1;jo*=GJlfg~>iU!>!ExbguPo`-L>fVTH5hO(=-)ka-iE|8Zv{J4F4l
zgb;0?8-p5#p-<=Kl9%F7>4`_~fOH{vl_4`XqO=Xlx$6Y@PGnX??>ivh6Xld@_`rWy
z+L5&Hx&ye%Qey)|vofnp%zBAL&Z&U#mQw7E^rG`^buzXr5XDI00VI+dfRaWWCEI
zq|f2^Q_=TjqvL?N^7k`SgMN1^f-A|z>Z3)hQg6lxxA}D(0Lsq6%e})p)nRR#E}Xqp
z^49$n95MA>uzB~(B&-?0D{JkNT)#;N}ZAuEWTyyb0NQeJxmT~5GYWD
zp*#U|ZjvsSdlMiiJ!;RN5`VN9;)76`Km3ra7W3y