diff --git a/aea/cli/fetch.py b/aea/cli/fetch.py
index 3e881a3a09..9690c9ade2 100644
--- a/aea/cli/fetch.py
+++ b/aea/cli/fetch.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -45,6 +45,7 @@
AGENTS,
CONNECTION,
CONTRACT,
+ CUSTOM,
DEFAULT_AEA_CONFIG_FILE,
PROTOCOL,
SKILL,
@@ -266,7 +267,7 @@ def _fetch_agent_deps(ctx: Context) -> None:
:param ctx: context object.
"""
- for item_type in (PROTOCOL, CONTRACT, CONNECTION, SKILL):
+ for item_type in (PROTOCOL, CONTRACT, CUSTOM, CONNECTION, SKILL):
item_type_plural = "{}s".format(item_type)
required_items = cast(set, getattr(ctx.agent_config, item_type_plural))
required_items_check = required_items.copy()
diff --git a/aea/cli/scaffold.py b/aea/cli/scaffold.py
index 70dd712934..68ca6d86fb 100644
--- a/aea/cli/scaffold.py
+++ b/aea/cli/scaffold.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2021-2023 Valory AG
+# Copyright 2021-2024 Valory AG
# Copyright 2018-2019 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,18 +41,17 @@
validate_package_name,
)
from aea.configurations.base import PackageType, PublicId
-from aea.configurations.constants import ( # noqa: F401 # pylint: disable=unused-import
+from aea.configurations.constants import (
BUILD,
CONNECTION,
CONTRACT,
CONTRACTS,
+ CUSTOM,
DEFAULT_AEA_CONFIG_FILE,
- DEFAULT_CONNECTION_CONFIG_FILE,
DEFAULT_CONTRACT_CONFIG_FILE,
- DEFAULT_PROTOCOL_CONFIG_FILE,
- DEFAULT_SKILL_CONFIG_FILE,
DEFAULT_VERSION,
DOTTED_PATH_MODULE_ELEMENT_SEPARATOR,
+ PACKAGE_TYPE_TO_CONFIG_FILE,
PROTOCOL,
SCAFFOLD_PUBLIC_ID,
SKILL,
@@ -155,6 +154,14 @@ def contract(
add_contract_abi(ctx, contract_name, Path(contract_abi_path))
+@scaffold.command()
+@click.argument("name", type=str, required=True)
+@pass_ctx
+def custom(ctx: Context, name: str) -> None:
+ """Scaffold a custom component package."""
+ scaffold_item(ctx, CUSTOM, name)
+
+
@scaffold.command()
@click.argument("protocol_name", type=str, required=True)
@click.option("-y", "--yes", is_flag=True, default=False)
@@ -205,7 +212,7 @@ def scaffold_item(ctx: Context, item_type: str, item_name: str) -> None:
validate_package_name(item_name)
author_name = ctx.agent_config.author
loader = getattr(ctx, f"{item_type}_loader")
- default_config_filename = globals()[f"DEFAULT_{item_type.upper()}_CONFIG_FILE"]
+ default_config_filename = PACKAGE_TYPE_TO_CONFIG_FILE[item_type]
to_local_registry = ctx.config.get("to_local_registry")
diff --git a/aea/cli/utils/context.py b/aea/cli/utils/context.py
index 34613ca657..7e1b45bc60 100644
--- a/aea/cli/utils/context.py
+++ b/aea/cli/utils/context.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -155,6 +155,13 @@ def contract_loader(self) -> ConfigLoader:
PackageType.CONTRACT, skip_aea_validation=self.skip_aea_validation
)
+ @property
+ def custom_loader(self) -> ConfigLoader:
+ """Get the custom loader."""
+ return ConfigLoader.from_configuration_type(
+ PackageType.CUSTOM, skip_aea_validation=self.skip_aea_validation
+ )
+
def set_config(self, key: str, value: Any) -> None:
"""
Set a config.
@@ -263,6 +270,7 @@ def _update_dependencies(updates: Dependencies) -> None:
for item_type in (
PackageType.PROTOCOL,
PackageType.CONTRACT,
+ PackageType.CUSTOM,
PackageType.CONNECTION,
PackageType.SKILL,
PackageType.AGENT,
diff --git a/aea/configurations/base.py b/aea/configurations/base.py
index 95bd7c0909..877db4fe8a 100644
--- a/aea/configurations/base.py
+++ b/aea/configurations/base.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2021-2023 Valory AG
+# Copyright 2021-2024 Valory AG
# Copyright 2018-2019 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -48,9 +48,11 @@
from aea.configurations.constants import (
CONNECTIONS,
CONTRACTS,
+ CUSTOMS,
DEFAULT_AEA_CONFIG_FILE,
DEFAULT_CONNECTION_CONFIG_FILE,
DEFAULT_CONTRACT_CONFIG_FILE,
+ DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE,
DEFAULT_FINGERPRINT_IGNORE_PATTERNS,
DEFAULT_LICENSE,
DEFAULT_LOGGING_CONFIG,
@@ -146,6 +148,8 @@ def _get_default_configuration_file_name_from_type(
return DEFAULT_CONTRACT_CONFIG_FILE
if item_type == PackageType.SERVICE:
return DEFAULT_SERVICE_CONFIG_FILE
+ if item_type == PackageType.CUSTOM:
+ return DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE
raise ValueError( # pragma: no cover
"Item type not valid: {}".format(str(item_type))
)
@@ -964,6 +968,7 @@ class SkillConfig(ComponentConfiguration):
"connections",
"protocols",
"contracts",
+ "customs",
"skills",
"dependencies",
"description",
@@ -987,6 +992,7 @@ def __init__(
connections: Optional[Set[PublicId]] = None,
protocols: Optional[Set[PublicId]] = None,
contracts: Optional[Set[PublicId]] = None,
+ customs: Optional[Set[PublicId]] = None,
skills: Optional[Set[PublicId]] = None,
dependencies: Optional[Dependencies] = None,
description: str = "",
@@ -1008,6 +1014,7 @@ def __init__(
self.connections = connections if connections is not None else set()
self.protocols = protocols if protocols is not None else set()
self.contracts = contracts if contracts is not None else set()
+ self.customs = customs if customs is not None else set()
self.skills = skills if skills is not None else set()
self.dependencies = dependencies if dependencies is not None else {}
self.description = description
@@ -1040,6 +1047,12 @@ def package_dependencies(self) -> Set[ComponentId]:
for connection_id in self.connections
}
)
+ .union(
+ {
+ ComponentId(ComponentType.CUSTOM, custom_id)
+ for custom_id in self.customs
+ }
+ )
)
@property
@@ -1063,6 +1076,7 @@ def json(self) -> Dict:
"fingerprint_ignore_patterns": self.fingerprint_ignore_patterns,
CONNECTIONS: sorted(map(str, self.connections)),
CONTRACTS: sorted(map(str, self.contracts)),
+ CUSTOMS: sorted(map(str, self.customs)),
PROTOCOLS: sorted(map(str, self.protocols)),
SKILLS: sorted(map(str, self.skills)),
"behaviours": {key: b.json for key, b in self.behaviours.read_all()},
@@ -1097,6 +1111,7 @@ def _create_or_update_from_json(
connections = {PublicId.from_str(id_) for id_ in obj.get(CONNECTIONS, set())}
protocols = {PublicId.from_str(id_) for id_ in obj.get(PROTOCOLS, set())}
contracts = {PublicId.from_str(id_) for id_ in obj.get(CONTRACTS, set())}
+ customs = {PublicId.from_str(id_) for id_ in obj.get(CUSTOMS, set())}
skills = {PublicId.from_str(id_) for id_ in obj.get(SKILLS, set())}
dependencies = dependencies_from_json(obj.get("dependencies", {}))
description = cast(str, obj.get("description", ""))
@@ -1112,6 +1127,7 @@ def _create_or_update_from_json(
connections=connections,
protocols=protocols,
contracts=contracts,
+ customs=customs,
skills=skills,
dependencies=dependencies,
description=description,
@@ -1211,6 +1227,7 @@ class AgentConfig(PackageConfiguration):
"protocols",
"skills",
"contracts",
+ "customs",
"period",
"execution_timeout",
"max_reactions",
@@ -1294,6 +1311,7 @@ def __init__( # pylint: disable=too-many-arguments,too-many-locals
)
self.connections = set() # type: Set[PublicId]
self.contracts = set() # type: Set[PublicId]
+ self.customs = set() # type: Set[PublicId]
self.protocols = set() # type: Set[PublicId]
self.skills = set() # type: Set[PublicId]
@@ -1341,6 +1359,7 @@ def component_configurations(self, d: Dict[ComponentId, Dict]) -> None:
PackageType.PROTOCOL: {epid.without_hash() for epid in self.protocols},
PackageType.CONNECTION: {epid.without_hash() for epid in self.connections},
PackageType.CONTRACT: {epid.without_hash() for epid in self.contracts},
+ PackageType.CUSTOM: {epid.without_hash() for epid in self.customs},
PackageType.SKILL: {epid.without_hash() for epid in self.skills},
}
for component_id, component_configuration in d.items():
@@ -1368,13 +1387,14 @@ def package_dependencies(self) -> Set[ComponentId]:
skills = set(
ComponentId(ComponentType.SKILL, public_id) for public_id in self.skills
)
-
contracts = set(
ComponentId(ComponentType.CONTRACT, public_id)
for public_id in self.contracts
)
-
- return set.union(protocols, contracts, connections, skills)
+ customs = set(
+ ComponentId(ComponentType.CUSTOM, public_id) for public_id in self.customs
+ )
+ return set.union(protocols, contracts, customs, connections, skills)
@property
def private_key_paths_dict(self) -> Dict[str, str]:
@@ -1421,9 +1441,12 @@ def json(self) -> Dict:
CONTRACTS: sorted(map(str, self.contracts)),
PROTOCOLS: sorted(map(str, self.protocols)),
SKILLS: sorted(map(str, self.skills)),
- "default_connection": str(self.default_connection)
- if self.default_connection is not None
- else None,
+ CUSTOMS: sorted(map(str, self.customs)),
+ "default_connection": (
+ str(self.default_connection)
+ if self.default_connection is not None
+ else None
+ ),
"default_ledger": self.default_ledger,
"required_ledgers": self.required_ledgers or [],
"default_routing": {
@@ -1540,6 +1563,14 @@ def _create_or_update_from_json(
)
)
+ # parse custom public ids
+ agent_config.customs = set(
+ map(
+ PublicId.from_str,
+ obj.get(CUSTOMS, []),
+ )
+ )
+
# parse protocol public ids
agent_config.protocols = set(
map(
@@ -1575,6 +1606,7 @@ def all_components_id(self) -> List[ComponentId]:
ComponentType.PROTOCOL: self.protocols,
ComponentType.CONNECTION: self.connections,
ComponentType.CONTRACT: self.contracts,
+ ComponentType.CUSTOM: self.customs,
ComponentType.SKILL: self.skills,
}
result = []
@@ -1879,6 +1911,87 @@ def package_dependencies(self) -> Set[ComponentId]:
}
+class CustomComponentConfig(PackageConfiguration):
+ """Custom component configuratiopn."""
+
+ default_configuration_filename = DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE
+ package_type = PackageType.CUSTOM
+ component_type = ComponentType.CUSTOM
+ schema = "custom-config_schema.json"
+
+ FIELDS_ALLOWED_TO_UPDATE: FrozenSet[str] = frozenset(
+ ["config", "cert_requests", "is_abstract", "build_directory"]
+ )
+
+ def __init__(
+ self,
+ name: SimpleIdOrStr,
+ author: SimpleIdOrStr,
+ version: str = "",
+ license_: str = "",
+ aea_version: str = "",
+ description: str = "",
+ fingerprint: Optional[Dict[str, str]] = None,
+ fingerprint_ignore_patterns: Optional[Sequence[str]] = None,
+ dependencies: Optional[Dependencies] = None,
+ **kwargs: Any,
+ ) -> None:
+ """Initialize a custom configuration object."""
+ super().__init__(
+ name,
+ author,
+ version,
+ license_,
+ aea_version,
+ fingerprint,
+ fingerprint_ignore_patterns,
+ )
+ self.dependencies = dependencies if dependencies is not None else {}
+ self.description = description
+ self.kwargs = kwargs
+
+ def get(self, name: str) -> Any:
+ """Get parameter."""
+ return self.kwargs.get(name)
+
+ def set(self, name: str, value: Any) -> None:
+ """Set extra parameter value."""
+ self.kwargs[name] = value
+
+ @property
+ def json(self) -> Dict:
+ """Return the JSON representation."""
+ result = OrderedDict(
+ {
+ "name": self.name,
+ "author": self.author,
+ "version": self.version,
+ "type": self.component_type.value,
+ "description": self.description,
+ "license": self.license,
+ "aea_version": self.aea_version,
+ "fingerprint": self.fingerprint,
+ "fingerprint_ignore_patterns": self.fingerprint_ignore_patterns,
+ "dependencies": dependencies_to_json(self.dependencies),
+ **self.kwargs,
+ }
+ )
+ return result
+
+ @classmethod
+ def _create_or_update_from_json(
+ cls, obj: Dict, instance: Optional["CustomComponentConfig"] = None
+ ) -> "CustomComponentConfig":
+ """Initialize from a JSON object."""
+ params = {**(instance.json if instance else {}), **copy(obj)}
+ params["dependencies"] = cast(
+ Dependencies, dependencies_from_json(obj.get("dependencies", {}))
+ )
+ return cast(
+ CustomComponentConfig, cls._apply_params_to_instance(params, instance)
+ )
+
+
"""The following functions are called from aea.cli.utils."""
@@ -2045,4 +2158,5 @@ def _get_public_id_from_file(
PackageType.CONNECTION: ConnectionConfig,
PackageType.SKILL: SkillConfig,
PackageType.CONTRACT: ContractConfig,
+ PackageType.CUSTOM: CustomComponentConfig,
}
diff --git a/aea/configurations/constants.py b/aea/configurations/constants.py
index 9f14c0da32..1d1483930d 100644
--- a/aea/configurations/constants.py
+++ b/aea/configurations/constants.py
@@ -51,6 +51,8 @@
AGENT = "agent"
AGENTS = "agents"
BUILD = "build"
+CUSTOM = "custom"
+CUSTOMS = "customs"
CONNECTION = "connection"
CONNECTIONS = "connections"
CONTRACT = "contract"
@@ -66,6 +68,7 @@
DEFAULT_AEA_CONFIG_FILE = "aea-config.yaml"
DEFAULT_SKILL_CONFIG_FILE = "skill.yaml"
DEFAULT_CONNECTION_CONFIG_FILE = "connection.yaml"
+DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE = "component.yaml"
DEFAULT_CONTRACT_CONFIG_FILE = "contract.yaml"
DEFAULT_PROTOCOL_CONFIG_FILE = "protocol.yaml"
DEFAULT_SERVICE_CONFIG_FILE = "service.yaml"
@@ -81,6 +84,7 @@
DEFAULT_CONNECTION_CONFIG_FILE,
DEFAULT_SKILL_CONFIG_FILE,
DEFAULT_CONTRACT_CONFIG_FILE,
+ DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE,
PRIVATE_KEY_PATH_SCHEMA.format("*"),
]
DEFAULT_PYPI_INDEX_URL = "https://pypi.org/simple"
@@ -100,6 +104,7 @@
DEFAULT_CONTRACT_CONFIG_FILE: CONTRACT,
DEFAULT_SERVICE_CONFIG_FILE: SERVICE,
DEFAULT_AEA_CONFIG_FILE: AGENT,
+ DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE: CUSTOM,
} # type: Dict[str, str]
PACKAGE_TYPE_TO_CONFIG_FILE = {
diff --git a/aea/configurations/data_types.py b/aea/configurations/data_types.py
index 91ff0ab406..b0b1ca7768 100644
--- a/aea/configurations/data_types.py
+++ b/aea/configurations/data_types.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -44,6 +44,7 @@
AGENT,
CONNECTION,
CONTRACT,
+ CUSTOM,
DEFAULT_GIT_REF,
PROTOCOL,
SERVICE,
@@ -170,6 +171,7 @@ class PackageType(Enum):
PROTOCOL = PROTOCOL
CONNECTION = CONNECTION
CONTRACT = CONTRACT
+ CUSTOM = CUSTOM
SKILL = SKILL
SERVICE = SERVICE
@@ -204,6 +206,7 @@ class ComponentType(Enum):
CONNECTION = CONNECTION
SKILL = SKILL
CONTRACT = CONTRACT
+ CUSTOM = CUSTOM
def to_package_type(self) -> PackageType:
"""Get package type for component type."""
@@ -215,7 +218,7 @@ def plurals() -> Collection[str]: # pylint: disable=unsubscriptable-object
Get the collection of type names, plural.
>>> ComponentType.plurals()
- ['protocols', 'connections', 'skills', 'contracts']
+ ['protocols', 'connections', 'skills', 'contracts', 'customs']
:return: list of all pluralised component types
"""
@@ -559,13 +562,14 @@ def __str__(self) -> str:
class PackageId:
"""A package identifier."""
- PACKAGE_TYPE_REGEX = r"({}|{}|{}|{}|{}|{})".format(
+ PACKAGE_TYPE_REGEX = r"({}|{}|{}|{}|{}|{}|{})".format(
PackageType.AGENT,
PackageType.PROTOCOL,
PackageType.SKILL,
PackageType.CONNECTION,
PackageType.CONTRACT,
PackageType.SERVICE,
+ PackageType.CUSTOM,
)
PACKAGE_ID_URI_REGEX = r"{}/{}".format(
PACKAGE_TYPE_REGEX, PublicId.PUBLIC_ID_URI_REGEX[1:-1]
diff --git a/aea/configurations/schemas/aea-config_schema.json b/aea/configurations/schemas/aea-config_schema.json
index 4a7cfe3a35..b3d9864679 100644
--- a/aea/configurations/schemas/aea-config_schema.json
+++ b/aea/configurations/schemas/aea-config_schema.json
@@ -98,11 +98,15 @@
"$ref": "definitions.json#/definitions/public_id"
}
},
+ "customs": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "definitions.json#/definitions/public_id"
+ }
+ },
"default_connection": {
- "type": [
- "string",
- "null"
- ]
+ "type": ["string", "null"]
},
"protocols": {
"type": "array",
diff --git a/aea/configurations/schemas/custom-config_schema.json b/aea/configurations/schemas/custom-config_schema.json
new file mode 100644
index 0000000000..f72695abac
--- /dev/null
+++ b/aea/configurations/schemas/custom-config_schema.json
@@ -0,0 +1,50 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Schema for the contract configuration file.",
+ "additionalProperties": true,
+ "type": "object",
+ "required": [
+ "name",
+ "author",
+ "version",
+ "type",
+ "description",
+ "license",
+ "aea_version",
+ "fingerprint",
+ "fingerprint_ignore_patterns",
+ "dependencies"
+ ],
+ "properties": {
+ "name": {
+ "$ref": "definitions.json#/definitions/resource_name"
+ },
+ "author": {
+ "$ref": "definitions.json#/definitions/author"
+ },
+ "version": {
+ "$ref": "definitions.json#/definitions/package_version"
+ },
+ "type": {
+ "enum": ["custom"]
+ },
+ "description": {
+ "$ref": "definitions.json#/definitions/description"
+ },
+ "license": {
+ "$ref": "definitions.json#/definitions/license"
+ },
+ "aea_version": {
+ "$ref": "definitions.json#/definitions/aea_version"
+ },
+ "fingerprint": {
+ "$ref": "definitions.json#/definitions/fingerprint"
+ },
+ "fingerprint_ignore_patterns": {
+ "$ref": "definitions.json#/definitions/fingerprint_ignore_patterns"
+ },
+ "dependencies": {
+ "$ref": "definitions.json#/definitions/dependencies"
+ }
+ }
+}
diff --git a/aea/configurations/schemas/skill-config_schema.json b/aea/configurations/schemas/skill-config_schema.json
index fd23e74c04..e95736c860 100644
--- a/aea/configurations/schemas/skill-config_schema.json
+++ b/aea/configurations/schemas/skill-config_schema.json
@@ -34,9 +34,7 @@
"$ref": "definitions.json#/definitions/package_version"
},
"type": {
- "enum": [
- "skill"
- ]
+ "enum": ["skill"]
},
"license": {
"$ref": "definitions.json#/definitions/license"
@@ -80,6 +78,14 @@
"$ref": "definitions.json#/definitions/public_id"
}
},
+ "customs": {
+ "type": "array",
+ "additionalProperties": false,
+ "uniqueItems": true,
+ "items": {
+ "$ref": "definitions.json#/definitions/public_id"
+ }
+ },
"skills": {
"type": "array",
"additionalProperties": false,
diff --git a/aea/customs/__init__.py b/aea/customs/__init__.py
new file mode 100644
index 0000000000..ac58867cb2
--- /dev/null
+++ b/aea/customs/__init__.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# ------------------------------------------------------------------------------
+#
+# Copyright 2024 Valory AG
+#
+# 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.
+#
+# ------------------------------------------------------------------------------
+
+"""Custom packages helper."""
diff --git a/aea/customs/scaffold/__init__.py b/aea/customs/scaffold/__init__.py
new file mode 100644
index 0000000000..15bd10246c
--- /dev/null
+++ b/aea/customs/scaffold/__init__.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# ------------------------------------------------------------------------------
+#
+# Copyright 2024 Valory AG
+#
+# 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 a custom package."""
diff --git a/aea/customs/scaffold/component.yaml b/aea/customs/scaffold/component.yaml
new file mode 100644
index 0000000000..bcc8d87ddf
--- /dev/null
+++ b/aea/customs/scaffold/component.yaml
@@ -0,0 +1,12 @@
+name: component
+author: open_aea
+version: 0.1.0
+type: custom
+description: The custom component package.
+license: Apache-2.0
+aea_version: '>=1.0.0, <2.0.0'
+fingerprint:
+ __init__.py: bafybeidey4syohls5hxmso6qsp5p4uhtzle5txv2mlbym6ktjzknich6oa
+ kelly_criterion.py: bafybeibqwl52cnz64cysjd2jnjijuakdvyrffapxq65cdzx6g65gu42deq
+fingerprint_ignore_patterns: []
+dependencies: {}
\ No newline at end of file
diff --git a/aea/helpers/dependency_tree.py b/aea/helpers/dependency_tree.py
index c6a66b1560..343fe67b01 100644
--- a/aea/helpers/dependency_tree.py
+++ b/aea/helpers/dependency_tree.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022 Valory AG
+# Copyright 2022-2024 Valory AG
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -27,9 +27,11 @@
AGENT,
CONNECTION,
CONTRACT,
+ CUSTOM,
DEFAULT_AEA_CONFIG_FILE,
DEFAULT_CONNECTION_CONFIG_FILE,
DEFAULT_CONTRACT_CONFIG_FILE,
+ DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE,
DEFAULT_PROTOCOL_CONFIG_FILE,
DEFAULT_SERVICE_CONFIG_FILE,
DEFAULT_SKILL_CONFIG_FILE,
@@ -50,6 +52,7 @@
(CONTRACT, DEFAULT_CONTRACT_CONFIG_FILE),
(CONNECTION, DEFAULT_CONNECTION_CONFIG_FILE),
(PROTOCOL, DEFAULT_PROTOCOL_CONFIG_FILE),
+ (CUSTOM, DEFAULT_CUSTOM_COMPONENT_CONFIG_FILE),
(SERVICE, DEFAULT_SERVICE_CONFIG_FILE),
]
diff --git a/aea/package_manager/v1.py b/aea/package_manager/v1.py
index 43a5a0196a..f1d875914f 100644
--- a/aea/package_manager/v1.py
+++ b/aea/package_manager/v1.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -55,6 +55,16 @@
"https://raw.githubusercontent.com/{repo}/{tag}/packages/packages.json"
)
+_PACKAGE_ORDER = [
+ PackageType.CUSTOM,
+ PackageType.PROTOCOL,
+ PackageType.CONTRACT,
+ PackageType.CONNECTION,
+ PackageType.SKILL,
+ PackageType.AGENT,
+ PackageType.SERVICE,
+]
+
class PackageManagerV1(BasePackageManager):
"""Package manager V1"""
@@ -421,10 +431,16 @@ def json(
data["dev"] = OrderedDict()
data["third_party"] = OrderedDict()
- for package_id, package_hash in self._dev_packages.items():
+ for package_id, package_hash in sorted(
+ self._dev_packages.items(),
+ key=lambda x: _PACKAGE_ORDER.index(x[0].package_type),
+ ):
data["dev"][package_id.to_uri_path] = package_hash
- for package_id, package_hash in self._third_party_packages.items():
+ for package_id, package_hash in sorted(
+ self._third_party_packages.items(),
+ key=lambda x: _PACKAGE_ORDER.index(x[0].package_type),
+ ):
data["third_party"][package_id.to_uri_path] = package_hash
return data
diff --git a/docs/api/configurations/base.md b/docs/api/configurations/base.md
index 74f66551c4..790203d178 100644
--- a/docs/api/configurations/base.md
+++ b/docs/api/configurations/base.md
@@ -734,6 +734,7 @@ def __init__(name: SimpleIdOrStr,
connections: Optional[Set[PublicId]] = None,
protocols: Optional[Set[PublicId]] = None,
contracts: Optional[Set[PublicId]] = None,
+ customs: Optional[Set[PublicId]] = None,
skills: Optional[Set[PublicId]] = None,
dependencies: Optional[Dependencies] = None,
description: str = "",
@@ -1120,6 +1121,66 @@ def package_dependencies() -> Set[ComponentId]
Get the contract dependencies.
+
+
+## CustomComponentConfig Objects
+
+```python
+class CustomComponentConfig(PackageConfiguration)
+```
+
+Custom component configuratiopn.
+
+
+
+#### `__`init`__`
+
+```python
+def __init__(name: SimpleIdOrStr,
+ author: SimpleIdOrStr,
+ version: str = "",
+ license_: str = "",
+ aea_version: str = "",
+ description: str = "",
+ fingerprint: Optional[Dict[str, str]] = None,
+ fingerprint_ignore_patterns: Optional[Sequence[str]] = None,
+ dependencies: Optional[Dependencies] = None,
+ **kwargs: Any) -> None
+```
+
+Initialize a custom configuration object.
+
+
+
+#### get
+
+```python
+def get(name: str) -> Any
+```
+
+Get parameter.
+
+
+
+#### set
+
+```python
+def set(name: str, value: Any) -> None
+```
+
+Set extra parameter value.
+
+
+
+#### json
+
+```python
+@property
+def json() -> Dict
+```
+
+Return the JSON representation.
+
## AEAVersionError Objects
diff --git a/docs/api/configurations/data_types.md b/docs/api/configurations/data_types.md
index c75c754cdb..5c2b2d0a48 100644
--- a/docs/api/configurations/data_types.md
+++ b/docs/api/configurations/data_types.md
@@ -192,7 +192,7 @@ def plurals() -> Collection[str]
Get the collection of type names, plural.
>>> ComponentType.plurals()
-['protocols', 'connections', 'skills', 'contracts']
+['protocols', 'connections', 'skills', 'contracts', 'customs']
**Returns**:
diff --git a/packages/packages.json b/packages/packages.json
index a8cb557311..56ccb53c96 100644
--- a/packages/packages.json
+++ b/packages/packages.json
@@ -1,44 +1,44 @@
{
"dev": {
"protocol/fetchai/gym/1.0.0": "bafybeiflnuet6ofanewmst3lchg2gkoj2vuspcajya7esfkrmiqqphuwxq",
- "connection/fetchai/gym/0.19.0": "bafybeicqqvl4tt3qbulnkoffciagmfd6p3hxxi3i2mrrqtnbycv757pn6y",
"protocol/fetchai/default/1.0.0": "bafybeihdvtmnz7fzy7kwi3wlo6rfl27f6q3g5entplgvq7y23i3v5uoz24",
"protocol/valory/acn/1.1.0": "bafybeidluaoeakae3exseupaea4i3yvvk5vivyt227xshjlffywwxzcxqe",
"protocol/valory/contract_api/1.0.0": "bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i",
"protocol/valory/http/1.0.0": "bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae",
"protocol/valory/ledger_api/1.0.0": "bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni",
+ "protocol/fetchai/fipa/1.0.0": "bafybeidbt5dwzdeywi723n3wendidxfbzheovb4dheb6h7mcsrkmlkwkh4",
+ "protocol/fetchai/oef_search/1.0.0": "bafybeid3eokuse7uiwmhdb4vx7yvev35cccvzo2xuhwuy7lernfupjymwm",
+ "protocol/fetchai/state_update/1.0.0": "bafybeiftntpyadajwnse25qwpvpidmahkn5qksg7jdzuemuqc7zsuek5xy",
+ "protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi",
+ "protocol/fetchai/tac/1.0.0": "bafybeid3i7yew5pv3in5cg76oguxu5ncllxaiog64q42m2fq3k2rpphs2m",
+ "contract/fetchai/erc1155/0.22.0": "bafybeiff7a6xncyad53o2r7lekpnhexcspze6ocy55xtpzqeuacnlpunm4",
+ "connection/fetchai/gym/0.19.0": "bafybeicqqvl4tt3qbulnkoffciagmfd6p3hxxi3i2mrrqtnbycv757pn6y",
"connection/fetchai/stub/0.21.0": "bafybeibybboiwgklfiqpkkcw6rwj65s5jalzfzf6mh6fstxdlt6habzwvy",
"connection/valory/ledger/0.19.0": "bafybeic3ft7l7ca3qgnderm4xupsfmyoihgi27ukotnz7b5hdczla2enya",
"connection/valory/http_server/0.22.0": "bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m",
"connection/valory/p2p_libp2p/0.1.0": "bafybeic2u7azbwjny2nhaltqnbohlvysx3x6ectzbege7sxwrbzcz4lcma",
"connection/valory/p2p_libp2p_client/0.1.0": "bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e",
"connection/valory/p2p_libp2p_mailbox/0.1.0": "bafybeiecclc65ogngs3piaxpwhiyl77mlpqun5ejlyv4kamwzrrh746guq",
- "contract/fetchai/erc1155/0.22.0": "bafybeiff7a6xncyad53o2r7lekpnhexcspze6ocy55xtpzqeuacnlpunm4",
- "protocol/fetchai/fipa/1.0.0": "bafybeidbt5dwzdeywi723n3wendidxfbzheovb4dheb6h7mcsrkmlkwkh4",
- "protocol/fetchai/oef_search/1.0.0": "bafybeid3eokuse7uiwmhdb4vx7yvev35cccvzo2xuhwuy7lernfupjymwm",
- "protocol/fetchai/state_update/1.0.0": "bafybeiftntpyadajwnse25qwpvpidmahkn5qksg7jdzuemuqc7zsuek5xy",
- "protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi",
+ "connection/fetchai/local/0.20.0": "bafybeiema4rnxi54luhzbrccb27pfrwlohemka45eqf4nidgmtkwwmxeyi",
+ "connection/valory/http_client/0.23.0": "bafybeih5vzo22p2umhqo52nzluaanxx7kejvvpcpdsrdymckkyvmsim6gm",
+ "connection/valory/test_libp2p/0.1.0": "bafybeid4uexpzjgb3m6npbekohqayn2oukf3fershneha2dptmwtkayxza",
"skill/fetchai/echo/0.19.0": "bafybeicoawiackcbgqo3na3e56tpdc62atag4yxknur77py37caqq4mmya",
"skill/fetchai/error_test_skill/0.1.0": "bafybeihsbtlpe7h6fsvoxban5rilkmwviwkokul5cqym6atoolirontiyu",
"skill/fetchai/gym/0.20.0": "bafybeie7y2fsxfuhsqxqcaluo5exskmrm5q3a6e2hfcskcuvzvxjjhijh4",
"skill/fetchai/http_echo/0.20.0": "bafybeicfiri2juaqh3azeit3z3rf44kgxdo6oj4lgxjgvnowq6m7j47qrm",
- "agent/fetchai/error_test/0.1.0": "bafybeiecm675ndzbh35jkejtxn4ughoutztltjhgwzfbp57okabedjmnpq",
- "agent/fetchai/gym_aea/0.25.0": "bafybeibzn3qomqmkaksgpd3gn6aijffvvw7rojswhoytiovohuc737fvfm",
- "agent/fetchai/my_first_aea/0.27.0": "bafybeiejpnatbwp7zlyqazflzexm6jboahy7w7gtrn5oi6ubwiu7jgwzom",
- "agent/open_aea/gym_aea/0.1.0": "bafybeietomk7c6dn6gvgix4s3jfzbrqjqzday6lofbk7wmkczhtgrijvmy",
- "agent/open_aea/http_echo/0.1.0": "bafybeigeufwgu6cxjcvxsks2j4mjk6kir7vnjgr2wfbytqlztqezkzijwy",
- "agent/open_aea/my_first_aea/0.1.0": "bafybeiaf6fgfmljz6pl7q6zfs3lhqmqbzydlqcen3qek5jjly77vhjowra",
- "connection/fetchai/local/0.20.0": "bafybeiema4rnxi54luhzbrccb27pfrwlohemka45eqf4nidgmtkwwmxeyi",
- "connection/valory/http_client/0.23.0": "bafybeih5vzo22p2umhqo52nzluaanxx7kejvvpcpdsrdymckkyvmsim6gm",
- "connection/valory/test_libp2p/0.1.0": "bafybeid4uexpzjgb3m6npbekohqayn2oukf3fershneha2dptmwtkayxza",
- "protocol/fetchai/tac/1.0.0": "bafybeid3i7yew5pv3in5cg76oguxu5ncllxaiog64q42m2fq3k2rpphs2m",
"skill/fetchai/erc1155_client/0.28.0": "bafybeiauu446slcix3khzdqlgbt5ab323ik5fc3s7s4lxoanecrewfktju",
"skill/fetchai/erc1155_deploy/0.30.0": "bafybeifgsf5wp6lb6ztkf7orbhv2wc7b4mrxosgyt6yrnjclmssmsqru2e",
"skill/fetchai/error/0.17.0": "bafybeicboomvykqhel3otyv4qg5t3hzpo6kmn5bk4ljluithhuieu7flsm",
"skill/fetchai/fipa_dummy_buyer/0.2.0": "bafybeidgso7lo5ay44mbxsp3lxilrgeek3ye44e6wus2ayq6kyxfvc3vjm",
"skill/fetchai/generic_buyer/0.26.0": "bafybeif56kwbxbtuhjzd7dohivfdzlkvgprnugymlyizazudzkded3nblm",
"skill/fetchai/generic_seller/0.27.0": "bafybeic6sgtjyd5j4xqwuruijtqnl22y3sfdbf3mnrkchu2x4bx7eo2t6e",
- "skill/fetchai/task_test_skill/0.1.0": "bafybeidv77u2xl52mnxakwvh7fuh46aiwfpteyof4eaptfd4agoi6cdble"
+ "skill/fetchai/task_test_skill/0.1.0": "bafybeidv77u2xl52mnxakwvh7fuh46aiwfpteyof4eaptfd4agoi6cdble",
+ "agent/fetchai/error_test/0.1.0": "bafybeiecm675ndzbh35jkejtxn4ughoutztltjhgwzfbp57okabedjmnpq",
+ "agent/fetchai/gym_aea/0.25.0": "bafybeibzn3qomqmkaksgpd3gn6aijffvvw7rojswhoytiovohuc737fvfm",
+ "agent/fetchai/my_first_aea/0.27.0": "bafybeiejpnatbwp7zlyqazflzexm6jboahy7w7gtrn5oi6ubwiu7jgwzom",
+ "agent/open_aea/gym_aea/0.1.0": "bafybeietomk7c6dn6gvgix4s3jfzbrqjqzday6lofbk7wmkczhtgrijvmy",
+ "agent/open_aea/http_echo/0.1.0": "bafybeigeufwgu6cxjcvxsks2j4mjk6kir7vnjgr2wfbytqlztqezkzijwy",
+ "agent/open_aea/my_first_aea/0.1.0": "bafybeiaf6fgfmljz6pl7q6zfs3lhqmqbzydlqcen3qek5jjly77vhjowra"
},
"third_party": {}
}
\ No newline at end of file
diff --git a/scripts/check_copyright_notice.py b/scripts/check_copyright_notice.py
index c58b8fb618..3c6b358641 100755
--- a/scripts/check_copyright_notice.py
+++ b/scripts/check_copyright_notice.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -46,7 +46,7 @@
)
GIT_PATH = shutil.which("git")
START_YEARS_FETCHAI = (2018, 2019, 2020, 2021)
-START_YEARS_VALORY = (2021, 2022, 2023)
+START_YEARS_VALORY = (2021, 2022, 2023, 2024)
FETCHAI = "FetchAI"
VALORY = "Valory"
MIXED = "Mixed"
diff --git a/scripts/whitelist.py b/scripts/whitelist.py
index 7a62f1b4ad..fc8968b019 100644
--- a/scripts/whitelist.py
+++ b/scripts/whitelist.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2021-2023 Valory AG
+# Copyright 2021-2024 Valory AG
# Copyright 2018-2019 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -341,3 +341,5 @@
target_blocks # unused variable (aea/crypto/base.py:435)
from_pipfile_string # unused method (aea/configurations/data_types.py:876)
to_pipfile_string # unused method (aea/configurations/data_types.py:973)
+custom # unused function (aea/cli/scaffold.py:157)
+custom_loader # unused property (aea/cli/utils/context.py:158)
diff --git a/tests/data/packages/packages.json b/tests/data/packages/packages.json
index e26b0a6faf..94a75f0496 100644
--- a/tests/data/packages/packages.json
+++ b/tests/data/packages/packages.json
@@ -1,9 +1,9 @@
{
"dev": {
- "contract/default_author/stub_0/0.1.0": "bafybeidicpfgwqbr54v5pca77wu6ifnf23idf5htpdrudhbwxzaavm3wyy",
- "contract/default_author/stub_1/0.1.0": "bafybeibpmdrfhgz33ubww57rmmzn56g67e5xe462xiulk2p2ttezgujn5a",
"protocol/fetchai/t_protocol/0.1.0": "bafybeia2xlfdayeozya4qrl3kkgejgkhyqgoclonqjnjro2pcfgrpruq2y",
- "protocol/fetchai/t_protocol_no_ct/0.1.0": "bafybeihdrj3xjkpcnvkvqmzsuiqocatrhgrzisizr7l7nmtjbruauo363m"
+ "protocol/fetchai/t_protocol_no_ct/0.1.0": "bafybeihdrj3xjkpcnvkvqmzsuiqocatrhgrzisizr7l7nmtjbruauo363m",
+ "contract/default_author/stub_0/0.1.0": "bafybeidicpfgwqbr54v5pca77wu6ifnf23idf5htpdrudhbwxzaavm3wyy",
+ "contract/default_author/stub_1/0.1.0": "bafybeibpmdrfhgz33ubww57rmmzn56g67e5xe462xiulk2p2ttezgujn5a"
},
"third_party": {}
}
\ No newline at end of file
diff --git a/tests/test_cli/test_config.py b/tests/test_cli/test_config.py
index a473308f54..e896557c4d 100644
--- a/tests/test_cli/test_config.py
+++ b/tests/test_cli/test_config.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2021-2023 Valory AG
+# Copyright 2021-2024 Valory AG
# Copyright 2018-2019 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -264,7 +264,7 @@ def test_get_fails_when_getting_vendor_dependency_with_wrong_component_type(self
standalone_mode=False,
)
assert result.exit_code == 1
- s = "'component_type_not_correct' is not a valid component type. Please use one of ['protocols', 'connections', 'skills', 'contracts']."
+ s = "'component_type_not_correct' is not a valid component type. Please use one of ['protocols', 'connections', 'skills', 'contracts', 'customs']."
assert result.exception.message == s
@classmethod
diff --git a/tests/test_cli/test_test.py b/tests/test_cli/test_test.py
index 552d1cc960..9c456981a0 100644
--- a/tests/test_cli/test_test.py
+++ b/tests/test_cli/test_test.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,6 +26,7 @@
from typing import Any, Sequence, Type
from unittest import mock
+import _strptime # noqa: F401
import click.testing
import pytest
from _pytest.config import ExitCode # type: ignore
@@ -47,6 +48,7 @@
OK_PYTEST_EXIT_CODE = ExitCode.OK
NO_TESTS_COLLECTED_PYTEST_EXIT_CODE = ExitCode.NO_TESTS_COLLECTED
+PACKAGE_TYPES = [t for t in ComponentType if t != ComponentType.CUSTOM]
def _parametrize_class(test_cls: Type) -> Type:
@@ -266,7 +268,7 @@ def test_run(self, mock_sys_modules) -> None:
class TestPackageTestByTypeEmptyTestSuite(BaseAEATestCommand):
"""Test that the command 'aea test item_type public_id' works as expected (with an empty test suite)."""
- @pytest.mark.parametrize("package_type", list(ComponentType))
+ @pytest.mark.parametrize("package_type", PACKAGE_TYPES)
def test_run(self, package_type: ComponentType, mock_sys_modules) -> None:
"""Assert that the exit code is equal to 5 (empty test suite)."""
self._scaffold_item(package_type)
@@ -279,7 +281,7 @@ def test_run(self, package_type: ComponentType, mock_sys_modules) -> None:
class TestPackageTestByType(BaseAEATestCommand):
"""Test that the command 'aea test item_type public_id' works as expected (with a non-empty test suite)."""
- @pytest.mark.parametrize("package_type", list(ComponentType))
+ @pytest.mark.parametrize("package_type", PACKAGE_TYPES)
def test_run(
self, package_type: ComponentType, mock_sys_modules, *_mocks: Any
) -> None:
@@ -295,7 +297,7 @@ def test_run(
class TestVendorPackageTestByTypeEmptyTestSuite(BaseAEATestCommand):
"""Test that the command 'aea test item_type public_id' for vendor packages works as expected (with an empty test suite)."""
- @pytest.mark.parametrize("package_type", list(ComponentType))
+ @pytest.mark.parametrize("package_type", PACKAGE_TYPES)
def test_run(self, package_type: ComponentType, mock_sys_modules) -> None:
"""Assert that the exit code is equal to 5 (empty test suite)."""
self._scaffold_item(package_type)
@@ -309,7 +311,7 @@ def test_run(self, package_type: ComponentType, mock_sys_modules) -> None:
class TestVendorPackageTestByType(BaseAEATestCommand):
"""Test that the command 'aea test item_type public_id' for vendor packages works as expected (with a non-empty test suite)."""
- @pytest.mark.parametrize("package_type", list(ComponentType))
+ @pytest.mark.parametrize("package_type", PACKAGE_TYPES)
def test_run(
self, package_type: ComponentType, mock_sys_modules, *_mocks: Any
) -> None:
@@ -331,7 +333,7 @@ def test_run(
class TestPackageTestByPathEmptyTestSuite(BaseAEATestCommand):
"""Test that the command 'aea test by-path path-to-package' works as expected (empty test suite)."""
- @pytest.mark.parametrize("package_type", list(ComponentType))
+ @pytest.mark.parametrize("package_type", PACKAGE_TYPES)
def test_run(self, package_type: ComponentType, mock_sys_modules) -> None:
"""Assert that the exit code is equal to 0 (tests are run successfully)."""
self._scaffold_item(package_type)
@@ -349,7 +351,7 @@ def test_run(self, package_type: ComponentType, mock_sys_modules) -> None:
class TestPackageTestByPath(BaseAEATestCommand):
"""Test that the command 'aea test by-path path-to-package' works as expected (non-empty test suite)."""
- @pytest.mark.parametrize("package_type", list(ComponentType))
+ @pytest.mark.parametrize("package_type", PACKAGE_TYPES)
def test_run(
self, package_type: ComponentType, mock_sys_modules, *_mocks: Any
) -> None:
@@ -369,7 +371,7 @@ def test_run(
class TestPackageTestByPathWithCov(BaseAEATestCommand):
"""Test that the command 'aea test by-path path-to-package' works as expected (non-empty test suite)."""
- @pytest.mark.parametrize("package_type", list(ComponentType))
+ @pytest.mark.parametrize("package_type", PACKAGE_TYPES)
def test_run(
self, package_type: ComponentType, mock_sys_modules, *_mocks: Any
) -> None:
diff --git a/tests/test_cli/tools_for_testing.py b/tests/test_cli/tools_for_testing.py
index 21d0d2f022..39714610bb 100644
--- a/tests/test_cli/tools_for_testing.py
+++ b/tests/test_cli/tools_for_testing.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
#
-# Copyright 2022-2023 Valory AG
+# Copyright 2022-2024 Valory AG
# Copyright 2018-2021 Fetch.AI Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -50,6 +50,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
)
self.connections: List[str] = kwargs.get("connections", [])
self.contracts: List[str] = kwargs.get("contracts", [])
+ self.customs: List[str] = kwargs.get("customs", [])
self.description: str = kwargs.get("description", "")
self.version: str = kwargs.get("version", "")
self.protocols: List[str] = kwargs.get("protocols", [])