open-aea 2.2.6__tar.gz → 2.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {open_aea-2.2.6 → open_aea-2.2.7}/PKG-INFO +1 -1
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/__version__.py +1 -1
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/generate_all_protocols.py +1 -1
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/scaffold.py +11 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/loader.py +40 -5
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/utils.py +25 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/connections/base.py +8 -2
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/contracts/base.py +8 -1
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/base.py +29 -1
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/env_vars.py +83 -6
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/logging.py +15 -1
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/protocols.py +3 -2
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/base.py +71 -23
- {open_aea-2.2.6 → open_aea-2.2.7}/pyproject.toml +1 -1
- {open_aea-2.2.6 → open_aea-2.2.7}/AUTHORS.md +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/LICENSE +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/README.md +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/abstract_agent.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/aea.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/aea_builder.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/agent.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/agent_loop.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/__main__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/add.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/add_key.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/build.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/check_packages.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/config.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/core.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/create.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/delete.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/eject.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/fetch.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/fingerprint.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/freeze.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/generate.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/generate_key.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/generate_wealth.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/get_address.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/get_multiaddress.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/get_public_key.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/get_wealth.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/init.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/install.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/ipfs_hash.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/issue_certificates.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/launch.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/list.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/local_registry_sync.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/login.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/logout.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/packages.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/plugin.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/publish.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/push.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/push_all.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/register.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/add.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/fetch.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/login.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/logout.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/publish.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/push.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/registration.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/settings.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/registry/utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/remove.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/remove_key.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/reset_password.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/run.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/search.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/test.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/transfer.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/upgrade.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/click_utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/config.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/constants.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/context.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/decorators.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/exceptions.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/formatting.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/generic.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/loggers.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/cli/utils/package_utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/common.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/components/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/components/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/components/loader.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/components/utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/constants.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/data_types.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/manager.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/pypi.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/aea-config_schema.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/cli_config.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/configurable_parts/base-custom_config.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/configurable_parts/connection-custom_config.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/configurable_parts/contract-custom_config.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/configurable_parts/protocol-custom_config.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/configurable_parts/skill-custom_config.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/connection-config_schema.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/contract-config_schema.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/custom-config_schema.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/definitions.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/protocol-config_schema.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/protocol-specification_schema.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/schemas/skill-config_schema.json +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/configurations/validation.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/connections/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/connections/scaffold/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/connections/scaffold/connection.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/connections/scaffold/connection.yaml +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/connections/scaffold/readme.md +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/context/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/context/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/contracts/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/contracts/scaffold/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/contracts/scaffold/contract.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/contracts/scaffold/contract.yaml +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/helpers.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/ledger_apis.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/plugin.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/registries/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/registries/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/crypto/wallet.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/customs/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/customs/scaffold/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/customs/scaffold/component.yaml +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/decision_maker/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/decision_maker/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/decision_maker/default.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/decision_maker/scaffold.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/error_handler/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/error_handler/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/error_handler/default.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/error_handler/scaffold.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/exceptions.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/acn/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/acn/agent_record.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/acn/uri.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/async_friendly_queue.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/async_utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/cid.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/constants.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/dependency_tree.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/exception_policy.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/exec_timeout.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/file_io.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/file_lock.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/fingerprint.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/git.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/http_requests.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/install_dependency.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/io.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/pb/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/pb/merkledag.proto +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/pb/merkledag_pb2.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/pb/unixfs.proto +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/pb/unixfs_pb2.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/ipfs/utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/json_schema.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/multiaddr/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/multiaddr/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/multiaddr/crypto.proto +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/multiaddr/crypto_pb2.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/multiformat.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/multiformat_codecs.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/multiple_executor.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/pipe.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/preference_representations/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/preference_representations/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/profiler_type_black_list.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/profiling.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/search/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/search/generic.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/search/models.proto +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/search/models.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/search/models_pb2.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/secp256k1.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/serializers.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/storage/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/storage/backends/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/storage/backends/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/storage/backends/binaries/README.txt +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/storage/backends/binaries/json1.dll +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/storage/backends/sqlite.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/storage/generic_storage.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/sym_link.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/transaction/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/transaction/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/win32.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/helpers/yaml_utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/identity/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/identity/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/launcher.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/mail/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/mail/base.proto +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/mail/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/mail/base_pb2.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/manager/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/manager/helpers.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/manager/manager.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/manager/project.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/manager/utils.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/multiplexer.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/package_manager/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/package_manager/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/package_manager/v0.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/package_manager/v1.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/dialogue/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/dialogue/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/generator/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/generator/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/generator/common.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/generator/extract_specification.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/generator/isort.cfg +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/generator/validate.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/scaffold/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/scaffold/message.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/scaffold/protocol.yaml +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/protocols/scaffold/serialization.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/py.typed +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/registries/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/registries/base.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/registries/filter.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/registries/resources.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/runner.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/runtime.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/behaviours.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/scaffold/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/scaffold/behaviours.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/scaffold/handlers.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/scaffold/my_model.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/scaffold/skill.yaml +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/skills/tasks.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/__init__.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/click_testing.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/constants.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/docker_image.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/exceptions.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/generic.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/mocks.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/network.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/test_cases.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/test_contract.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/test_protocol.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/test_skill.py +0 -0
- {open_aea-2.2.6 → open_aea-2.2.7}/aea/test_tools/utils.py +0 -0
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
__title__ = "open-aea"
|
|
24
24
|
__description__ = "Open Autonomous Economic Agent framework (without vendor lock-in)"
|
|
25
25
|
__url__ = "https://github.com/valory-xyz/open-aea.git"
|
|
26
|
-
__version__ = "2.2.
|
|
26
|
+
__version__ = "2.2.7"
|
|
27
27
|
__author__ = "Valory AG"
|
|
28
28
|
__license__ = "Apache-2.0"
|
|
29
29
|
__copyright__ = "2021 Valory AG, 2019 Fetch.AI Limited"
|
|
@@ -66,7 +66,6 @@ LIBPROTOC_VERSION = "libprotoc 24.3"
|
|
|
66
66
|
CUSTOM_TYPE_MODULE_NAME = "custom_types.py"
|
|
67
67
|
PROTOCOL_GENERATOR_DOCSTRING_REGEX = "It was created with protocol buffer compiler version `libprotoc .*` and aea protocol generator version `.*`."
|
|
68
68
|
|
|
69
|
-
logging.basicConfig(format="[%(asctime)s][%(levelname)s] %(message)s")
|
|
70
69
|
logger = logging.getLogger("generate_all_protocols")
|
|
71
70
|
logger.setLevel(logging.INFO)
|
|
72
71
|
|
|
@@ -460,6 +459,7 @@ def generate_all_protocols(
|
|
|
460
459
|
check_clean: bool,
|
|
461
460
|
) -> None:
|
|
462
461
|
"""Generate all protocols."""
|
|
462
|
+
logging.basicConfig(format="[%(asctime)s][%(levelname)s] %(message)s")
|
|
463
463
|
|
|
464
464
|
_check_preliminaries()
|
|
465
465
|
|
|
@@ -244,6 +244,9 @@ def scaffold_item(ctx: Context, item_type: str, item_name: str) -> None:
|
|
|
244
244
|
)
|
|
245
245
|
|
|
246
246
|
ctx.clean_paths.append(str(dest))
|
|
247
|
+
# Save ctx.cwd so the local-registry path swap below does not leak out
|
|
248
|
+
# of this call.
|
|
249
|
+
preserve_cwd = ctx.cwd
|
|
247
250
|
try:
|
|
248
251
|
# copy the item package into the agent project.
|
|
249
252
|
src = Path(os.path.join(AEA_DIR, item_type_plural, "scaffold"))
|
|
@@ -283,6 +286,12 @@ def scaffold_item(ctx: Context, item_type: str, item_name: str) -> None:
|
|
|
283
286
|
if to_local_registry:
|
|
284
287
|
ctx.cwd = str(registry_path / author_name)
|
|
285
288
|
fingerprint_item(ctx, item_type, new_public_id)
|
|
289
|
+
# Restore now (not just in the `finally` below) so the
|
|
290
|
+
# `--with-symlinks` calls to `create_symlink_vendor_to_local` /
|
|
291
|
+
# `create_symlink_packages_to_vendor` further down — both of
|
|
292
|
+
# which read `ctx.cwd` — see the original agent directory
|
|
293
|
+
# instead of the registry author path.
|
|
294
|
+
ctx.cwd = preserve_cwd
|
|
286
295
|
else:
|
|
287
296
|
fingerprint_item(ctx, item_type, new_public_id)
|
|
288
297
|
|
|
@@ -314,6 +323,8 @@ def scaffold_item(ctx: Context, item_type: str, item_name: str) -> None:
|
|
|
314
323
|
)
|
|
315
324
|
except Exception as e:
|
|
316
325
|
raise click.ClickException(str(e))
|
|
326
|
+
finally:
|
|
327
|
+
ctx.cwd = preserve_cwd
|
|
317
328
|
|
|
318
329
|
|
|
319
330
|
def _scaffold_dm_handler(ctx: Context) -> None:
|
|
@@ -29,6 +29,7 @@ from typing import (
|
|
|
29
29
|
List,
|
|
30
30
|
Optional,
|
|
31
31
|
TextIO,
|
|
32
|
+
Tuple,
|
|
32
33
|
Type,
|
|
33
34
|
TypeVar,
|
|
34
35
|
Union,
|
|
@@ -320,11 +321,7 @@ class ConfigLoader(Generic[T], BaseConfigLoader):
|
|
|
320
321
|
|
|
321
322
|
def _load_service_config(self, file_pointer: TextIO) -> PackageConfiguration:
|
|
322
323
|
"""Load a service configuration."""
|
|
323
|
-
|
|
324
|
-
if not configuration_data:
|
|
325
|
-
raise ValueError("Service configuration file was empty.")
|
|
326
|
-
|
|
327
|
-
service_config, *overrides = configuration_data
|
|
324
|
+
service_config, overrides = parse_service_yaml(file_pointer)
|
|
328
325
|
self.validate(service_config)
|
|
329
326
|
key_order = list(service_config.keys())
|
|
330
327
|
service = self.configuration_class.from_json(service_config)
|
|
@@ -384,6 +381,44 @@ class ConfigLoader(Generic[T], BaseConfigLoader):
|
|
|
384
381
|
return component_id
|
|
385
382
|
|
|
386
383
|
|
|
384
|
+
def parse_service_yaml(
|
|
385
|
+
file_pointer: TextIO,
|
|
386
|
+
) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
|
|
387
|
+
"""
|
|
388
|
+
Parse a service configuration YAML stream into its raw documents.
|
|
389
|
+
|
|
390
|
+
Returns the head service configuration document and any override
|
|
391
|
+
documents without applying schema validation or constructing a
|
|
392
|
+
typed configuration object. Callers that need to apply additional
|
|
393
|
+
transformations (e.g. environment variable substitution) before
|
|
394
|
+
validation can use this helper as the parse step.
|
|
395
|
+
|
|
396
|
+
:param file_pointer: an open text stream pointing at a service.yaml.
|
|
397
|
+
:return: a ``(service_config, overrides)`` tuple where ``service_config``
|
|
398
|
+
is the head document and ``overrides`` is the list of trailing
|
|
399
|
+
documents.
|
|
400
|
+
:raises ValueError: if the stream is empty, or if the head document is
|
|
401
|
+
not a YAML mapping (e.g. a bare ``---``, a scalar, or a sequence).
|
|
402
|
+
:raises yaml.YAMLError: if the stream contains malformed YAML and the underlying parser fails (propagated as-is so callers can handle parse errors and shape errors distinctly). # noqa: DAR402
|
|
403
|
+
"""
|
|
404
|
+
configuration_data = yaml_load_all(file_pointer)
|
|
405
|
+
if not configuration_data:
|
|
406
|
+
raise ValueError("Service configuration file was empty.")
|
|
407
|
+
service_config, *overrides = configuration_data
|
|
408
|
+
# The head document must be a mapping. `yaml_load_all` happily returns
|
|
409
|
+
# `[None]` / `[False]` / `[0]` / `[""]` / `[[]]` for malformed YAML
|
|
410
|
+
# (bare `---`, a scalar, a sequence, etc.) — surface those at parse
|
|
411
|
+
# time rather than as opaque AttributeErrors from the downstream
|
|
412
|
+
# validator. Distinct from the empty-stream message so an operator
|
|
413
|
+
# reading the traceback can tell the two cases apart.
|
|
414
|
+
if not isinstance(service_config, dict):
|
|
415
|
+
raise ValueError(
|
|
416
|
+
"Service configuration head document must be a YAML mapping, "
|
|
417
|
+
f"got {type(service_config).__name__}."
|
|
418
|
+
)
|
|
419
|
+
return service_config, overrides
|
|
420
|
+
|
|
421
|
+
|
|
387
422
|
class ConfigLoaders:
|
|
388
423
|
"""Configuration Loader class to load any package type."""
|
|
389
424
|
|
|
@@ -34,9 +34,34 @@ from aea.configurations.base import (
|
|
|
34
34
|
PublicId,
|
|
35
35
|
SkillConfig,
|
|
36
36
|
)
|
|
37
|
+
from aea.configurations.constants import PACKAGES
|
|
37
38
|
from aea.configurations.data_types import PackageIdPrefix
|
|
38
39
|
|
|
39
40
|
|
|
41
|
+
def package_dotted_path(
|
|
42
|
+
author: str,
|
|
43
|
+
package_type_plural: str,
|
|
44
|
+
package_name: str,
|
|
45
|
+
file_stem: str,
|
|
46
|
+
) -> str:
|
|
47
|
+
"""
|
|
48
|
+
Compose the canonical dotted path string for a file inside an AEA package.
|
|
49
|
+
|
|
50
|
+
Returns a string of the form ``packages.<author>.<plural>.<name>.<stem>``.
|
|
51
|
+
Has no side effects; the loaded module is registered in
|
|
52
|
+
``sys.modules`` by ``aea.helpers.base.load_module``.
|
|
53
|
+
|
|
54
|
+
:param author: package author (e.g. ``"valory"``).
|
|
55
|
+
:param package_type_plural: plural package-type token (``"skills"`` /
|
|
56
|
+
``"contracts"`` / ``"connections"`` / ``"protocols"``).
|
|
57
|
+
:param package_name: the package's local name.
|
|
58
|
+
:param file_stem: source file stem without the ``.py`` suffix
|
|
59
|
+
(``"contract"`` / ``"connection"`` / ``"behaviours"`` / ...).
|
|
60
|
+
:return: the composed packages-prefixed dotted path string.
|
|
61
|
+
"""
|
|
62
|
+
return f"{PACKAGES}.{author}.{package_type_plural}.{package_name}.{file_stem}"
|
|
63
|
+
|
|
64
|
+
|
|
40
65
|
@singledispatch
|
|
41
66
|
def replace_component_ids(
|
|
42
67
|
_arg: PackageConfiguration,
|
|
@@ -30,8 +30,10 @@ from typing import Any, Callable, Generator, Optional, Set, TYPE_CHECKING, cast
|
|
|
30
30
|
|
|
31
31
|
from aea.components.base import Component, load_aea_package
|
|
32
32
|
from aea.configurations.base import ComponentType, ConnectionConfig
|
|
33
|
+
from aea.configurations.constants import CONNECTIONS
|
|
33
34
|
from aea.configurations.data_types import PublicId
|
|
34
35
|
from aea.configurations.loader import load_component_configuration
|
|
36
|
+
from aea.configurations.utils import package_dotted_path
|
|
35
37
|
from aea.crypto.wallet import CryptoStore
|
|
36
38
|
from aea.exceptions import (
|
|
37
39
|
AEAComponentLoadException,
|
|
@@ -284,9 +286,13 @@ class Connection(Component, ABC):
|
|
|
284
286
|
"Connection module '{}' not found.".format(connection_module_path)
|
|
285
287
|
)
|
|
286
288
|
load_aea_package(configuration)
|
|
287
|
-
|
|
288
|
-
|
|
289
|
+
dotted_path = package_dotted_path(
|
|
290
|
+
configuration.public_id.author,
|
|
291
|
+
CONNECTIONS,
|
|
292
|
+
configuration.public_id.name,
|
|
293
|
+
"connection",
|
|
289
294
|
)
|
|
295
|
+
connection_module = load_module(dotted_path, directory / "connection.py")
|
|
290
296
|
classes = inspect.getmembers(connection_module, inspect.isclass)
|
|
291
297
|
connection_class_name = cast(str, configuration.class_name)
|
|
292
298
|
connection_classes = list(
|
|
@@ -30,6 +30,7 @@ from aea.components.base import Component, load_aea_package
|
|
|
30
30
|
from aea.configurations.base import ComponentType, ContractConfig, PublicId
|
|
31
31
|
from aea.configurations.constants import CONTRACTS
|
|
32
32
|
from aea.configurations.loader import load_component_configuration
|
|
33
|
+
from aea.configurations.utils import package_dotted_path
|
|
33
34
|
from aea.crypto.base import LedgerApi
|
|
34
35
|
from aea.crypto.registries import Registry, ledger_apis_registry, make_ledger_api_cls
|
|
35
36
|
from aea.exceptions import AEAComponentLoadException, AEAException
|
|
@@ -123,7 +124,13 @@ class Contract(Component):
|
|
|
123
124
|
raise ValueError("Configuration must be associated with a directory.")
|
|
124
125
|
directory = configuration.directory
|
|
125
126
|
load_aea_package(configuration)
|
|
126
|
-
|
|
127
|
+
dotted_path = package_dotted_path(
|
|
128
|
+
configuration.public_id.author,
|
|
129
|
+
CONTRACTS,
|
|
130
|
+
configuration.public_id.name,
|
|
131
|
+
"contract",
|
|
132
|
+
)
|
|
133
|
+
contract_module = load_module(dotted_path, directory / "contract.py")
|
|
127
134
|
classes = inspect.getmembers(contract_module, inspect.isclass)
|
|
128
135
|
contract_class_name = cast(str, configuration.class_name)
|
|
129
136
|
contract_classes = list(filter(lambda x: x[0] == contract_class_name, classes))
|
|
@@ -127,9 +127,37 @@ def load_module(dotted_path: str, filepath: Path) -> types.ModuleType:
|
|
|
127
127
|
:raises ValueError: if the filepath provided is not a module. # noqa: DAR402
|
|
128
128
|
:raises Exception: if the execution of the module raises exception. # noqa: DAR402
|
|
129
129
|
"""
|
|
130
|
+
# If the dotted path is already in ``sys.modules``, reuse it instead
|
|
131
|
+
# of re-executing the file. Re-execution creates a duplicate copy of
|
|
132
|
+
# every class defined in the source, breaking class identity for
|
|
133
|
+
# callers that already hold a reference (e.g. via an earlier
|
|
134
|
+
# ``from ... import X``). ``__file__`` is intentionally NOT compared
|
|
135
|
+
# — in test fixtures the same logical package may be reached
|
|
136
|
+
# through different physical files (vendor copy in a tmpdir vs the
|
|
137
|
+
# source tree) but both register the same dotted path and must
|
|
138
|
+
# resolve to the same module object across the whole process. An
|
|
139
|
+
# explicit ``None`` entry is CPython's block-import sentinel: raise
|
|
140
|
+
# ``ImportError`` to match the standard import semantics rather
|
|
141
|
+
# than silently overwriting it with a fresh exec.
|
|
142
|
+
if dotted_path in sys.modules:
|
|
143
|
+
existing = sys.modules[dotted_path]
|
|
144
|
+
if existing is None:
|
|
145
|
+
raise ImportError(f"import of {dotted_path!r} halted; None in sys.modules")
|
|
146
|
+
return existing
|
|
130
147
|
spec = importlib.util.spec_from_file_location(dotted_path, str(filepath))
|
|
131
148
|
module = importlib.util.module_from_spec(cast(ModuleSpec, spec))
|
|
132
|
-
|
|
149
|
+
# Register before exec so a downstream `import` of the same dotted
|
|
150
|
+
# path during exec resolves to this module. We only reach this point
|
|
151
|
+
# when the key was absent (the cache-hit and block-import branches
|
|
152
|
+
# above covered the other two cases), so on exec failure we pop the
|
|
153
|
+
# half-built stub rather than restoring a prior entry that, by
|
|
154
|
+
# construction, did not exist.
|
|
155
|
+
sys.modules[dotted_path] = module
|
|
156
|
+
try:
|
|
157
|
+
spec.loader.exec_module(module) # type: ignore
|
|
158
|
+
except BaseException: # pylint: disable=broad-except
|
|
159
|
+
sys.modules.pop(dotted_path, None)
|
|
160
|
+
raise
|
|
133
161
|
return module
|
|
134
162
|
|
|
135
163
|
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"""Implementation of the environment variables support."""
|
|
22
22
|
|
|
23
23
|
import json
|
|
24
|
+
import logging
|
|
24
25
|
import re
|
|
25
26
|
from collections.abc import Mapping as MappingType
|
|
26
27
|
from typing import Any, Dict, List, Mapping, Optional, Tuple, Union, cast
|
|
@@ -33,6 +34,8 @@ from aea.helpers.constants import (
|
|
|
33
34
|
NULL_EQUIVALENTS,
|
|
34
35
|
)
|
|
35
36
|
|
|
37
|
+
_logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
36
39
|
ENV_VARIABLE_RE = re.compile(r"^\$\{(([A-Z0-9_]+):?)?([a-z]+)?(:(.+))?}$")
|
|
37
40
|
MODELS = "models"
|
|
38
41
|
ARGS = "args"
|
|
@@ -272,6 +275,30 @@ def is_strict_list(data: Union[List, Tuple]) -> bool:
|
|
|
272
275
|
return is_strict
|
|
273
276
|
|
|
274
277
|
|
|
278
|
+
_BASH_SAFE_KEY_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def has_env_safe_keys(data: dict) -> bool:
|
|
282
|
+
"""
|
|
283
|
+
Check if a dict can be safely flattened into per-key env vars.
|
|
284
|
+
|
|
285
|
+
Returns True only when every key is a string matching the bash
|
|
286
|
+
identifier rule `[A-Za-z_][A-Za-z0-9_]*`. An empty dict is
|
|
287
|
+
vacuously safe (True). When this returns False, flattening would
|
|
288
|
+
produce env var names that bash refuses to set (notably containing
|
|
289
|
+
`.`), so callers should JSON-encode the whole dict as a single env
|
|
290
|
+
var instead.
|
|
291
|
+
|
|
292
|
+
For example, `{"timeout": 30, "retries": 5}` returns True; while
|
|
293
|
+
`{"0.0": 0, "1.0": 100}` and `{1: "v"}` return False.
|
|
294
|
+
|
|
295
|
+
:param data: Data dict
|
|
296
|
+
:return: True if every key is a valid bash identifier, or the
|
|
297
|
+
dict is empty.
|
|
298
|
+
"""
|
|
299
|
+
return all(isinstance(k, str) and _BASH_SAFE_KEY_RE.match(k) for k in data)
|
|
300
|
+
|
|
301
|
+
|
|
275
302
|
def list_to_nested_dict(lst: list, val: Any) -> dict:
|
|
276
303
|
"""Convert a list to a nested dict."""
|
|
277
304
|
nested_dict = val
|
|
@@ -280,6 +307,37 @@ def list_to_nested_dict(lst: list, val: Any) -> dict:
|
|
|
280
307
|
return nested_dict
|
|
281
308
|
|
|
282
309
|
|
|
310
|
+
def _encode_as_json_env_var(
|
|
311
|
+
data: JSON_TYPES, export_path: List[str]
|
|
312
|
+
) -> Tuple[str, str]:
|
|
313
|
+
"""
|
|
314
|
+
Encode data as a single JSON-string env var.
|
|
315
|
+
|
|
316
|
+
Used when a value cannot be flattened per-leaf (e.g. a list with
|
|
317
|
+
non-scalar elements, or a dict with bash-unsafe keys). Honours
|
|
318
|
+
`restrict_model_args`: if the export path is truncated by the model
|
|
319
|
+
arg restriction, the data is nested under the restricted suffix
|
|
320
|
+
(the deeper path keys) before encoding so they are not lost.
|
|
321
|
+
|
|
322
|
+
:param data: JSON-encodable value to encode.
|
|
323
|
+
:param export_path: Path keys leading to the value, from
|
|
324
|
+
`generate_env_vars_recursively`.
|
|
325
|
+
:return: (env_var_name, json_value) pair.
|
|
326
|
+
:raises ValueError: if ``data`` contains a value ``json.dumps`` cannot
|
|
327
|
+
serialise. The export path is included in the message so the
|
|
328
|
+
operator can locate the offending config key.
|
|
329
|
+
"""
|
|
330
|
+
restricted, path = export_path_to_env_var_string(export_path=export_path)
|
|
331
|
+
payload = list_to_nested_dict(restricted, data) if restricted else data
|
|
332
|
+
try:
|
|
333
|
+
encoded = json.dumps(payload, separators=(",", ":"))
|
|
334
|
+
except TypeError as e:
|
|
335
|
+
raise ValueError(
|
|
336
|
+
f"Cannot JSON-encode value at export path {export_path}: {e}"
|
|
337
|
+
) from e
|
|
338
|
+
return path, encoded
|
|
339
|
+
|
|
340
|
+
|
|
283
341
|
def ensure_dict(dict_: Dict[str, Union[dict, str]]) -> dict:
|
|
284
342
|
"""Return the given dictionary converting any values which are json strings as dicts."""
|
|
285
343
|
return {k: json.loads(v) for k, v in dict_.items() if isinstance(v, str)}
|
|
@@ -312,6 +370,26 @@ def generate_env_vars_recursively(
|
|
|
312
370
|
env_var_dict: Dict[str, Any] = {}
|
|
313
371
|
|
|
314
372
|
if isinstance(data, dict):
|
|
373
|
+
if not has_env_safe_keys(data):
|
|
374
|
+
safe_keys = [
|
|
375
|
+
k for k in data if isinstance(k, str) and _BASH_SAFE_KEY_RE.match(k)
|
|
376
|
+
]
|
|
377
|
+
if safe_keys:
|
|
378
|
+
# Mixed-key dict: per-key env var overrides for the safe
|
|
379
|
+
# keys silently stop applying once the whole dict is
|
|
380
|
+
# JSON-encoded. Warn so the operator can see why their
|
|
381
|
+
# override does not take effect.
|
|
382
|
+
_logger.warning(
|
|
383
|
+
"Collapsing mixed-key dict at export path %s to a "
|
|
384
|
+
"single JSON env var because of bash-unsafe keys; "
|
|
385
|
+
"per-key overrides for safe keys %s will no longer "
|
|
386
|
+
"apply. Set the whole-dict env var instead.",
|
|
387
|
+
export_path,
|
|
388
|
+
safe_keys,
|
|
389
|
+
)
|
|
390
|
+
path, value = _encode_as_json_env_var(data, export_path)
|
|
391
|
+
env_var_dict[path] = value
|
|
392
|
+
return env_var_dict
|
|
315
393
|
for key, value in data.items():
|
|
316
394
|
res = generate_env_vars_recursively(
|
|
317
395
|
data=value,
|
|
@@ -325,11 +403,8 @@ def generate_env_vars_recursively(
|
|
|
325
403
|
env_var_dict.update(res)
|
|
326
404
|
elif isinstance(data, list):
|
|
327
405
|
if is_strict_list(data=data):
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
env_var_dict[path] = json.dumps(list_to_nested_dict(restricted, data))
|
|
331
|
-
else:
|
|
332
|
-
env_var_dict[path] = json.dumps(data, separators=(",", ":"))
|
|
406
|
+
path, value = _encode_as_json_env_var(data, export_path)
|
|
407
|
+
env_var_dict[path] = value
|
|
333
408
|
else:
|
|
334
409
|
for key, value in enumerate(data):
|
|
335
410
|
res = generate_env_vars_recursively(
|
|
@@ -340,7 +415,9 @@ def generate_env_vars_recursively(
|
|
|
340
415
|
else:
|
|
341
416
|
restricted, path = export_path_to_env_var_string(export_path=export_path)
|
|
342
417
|
if restricted:
|
|
343
|
-
env_var_dict[path] = json.dumps(
|
|
418
|
+
env_var_dict[path] = json.dumps(
|
|
419
|
+
list_to_nested_dict(restricted, data), separators=(",", ":")
|
|
420
|
+
)
|
|
344
421
|
else:
|
|
345
422
|
env_var_dict[path] = data
|
|
346
423
|
|
|
@@ -31,7 +31,21 @@ DEFAULT_FORMAT = "[%(asctime)s][%(levelname)s] %(message)s"
|
|
|
31
31
|
def setup_logger(
|
|
32
32
|
name: str, level: int = logging.INFO, log_format: str = DEFAULT_FORMAT
|
|
33
33
|
) -> Logger:
|
|
34
|
-
"""Set up the logger.
|
|
34
|
+
"""Set up the logger.
|
|
35
|
+
|
|
36
|
+
Kept as a public helper for downstream consumers outside this repo;
|
|
37
|
+
new in-repo callers should prefer ``logging.getLogger(name)`` and set
|
|
38
|
+
the level directly. Calling ``logging.basicConfig`` at module-import
|
|
39
|
+
time pollutes the root logger and was the cause of the duplicate-log
|
|
40
|
+
bug fixed in #914 (PR #917).
|
|
41
|
+
|
|
42
|
+
:param name: logger name.
|
|
43
|
+
:param level: log level applied to the returned logger.
|
|
44
|
+
:param log_format: format string passed to ``logging.basicConfig``.
|
|
45
|
+
Only takes effect on the first call when the root logger has no
|
|
46
|
+
handlers yet; subsequent calls are a no-op for the format.
|
|
47
|
+
:return: the configured logger.
|
|
48
|
+
"""
|
|
35
49
|
logging.basicConfig(format=log_format)
|
|
36
50
|
logger = logging.getLogger(name)
|
|
37
51
|
logger.setLevel(level)
|
|
@@ -19,20 +19,21 @@
|
|
|
19
19
|
|
|
20
20
|
"""Protocol helpers."""
|
|
21
21
|
|
|
22
|
+
import logging
|
|
22
23
|
import re
|
|
23
24
|
from pathlib import Path
|
|
24
25
|
from typing import Match, cast
|
|
25
26
|
|
|
26
27
|
from aea.configurations.loader import load_protocol_specification_from_string
|
|
27
28
|
from aea.exceptions import enforce
|
|
28
|
-
from aea.helpers.logging import setup_logger
|
|
29
29
|
|
|
30
30
|
SPECIFICATION_REGEX = re.compile(r"(---\nname.*\.\.\.)", re.DOTALL)
|
|
31
31
|
PROTOCOL_SPECIFICATION_ID_IN_SPECIFICATION_REGEX = re.compile(
|
|
32
32
|
"^protocol_specification_id: (.*)$", re.MULTILINE
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
-
_logger =
|
|
35
|
+
_logger = logging.getLogger(__name__)
|
|
36
|
+
_logger.setLevel(logging.INFO)
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
def get_protocol_specification_from_readme(package_path: Path) -> str:
|
|
@@ -41,7 +41,9 @@ from aea.configurations.base import (
|
|
|
41
41
|
SkillComponentConfiguration,
|
|
42
42
|
SkillConfig,
|
|
43
43
|
)
|
|
44
|
+
from aea.configurations.constants import SKILLS
|
|
44
45
|
from aea.configurations.loader import load_component_configuration
|
|
46
|
+
from aea.configurations.utils import package_dotted_path
|
|
45
47
|
from aea.context.base import AgentContext
|
|
46
48
|
from aea.exceptions import (
|
|
47
49
|
AEAActException,
|
|
@@ -759,17 +761,44 @@ def _parse_module(
|
|
|
759
761
|
if component_configs == {}:
|
|
760
762
|
return components
|
|
761
763
|
component_names = set(config.class_name for _, config in component_configs.items())
|
|
762
|
-
|
|
764
|
+
# Build the same canonical dotted key the main loader uses for the
|
|
765
|
+
# same physical file (including subpackage files such as
|
|
766
|
+
# `<skill>/subpkg/behaviours.py`) so `sys.modules` cache hits across
|
|
767
|
+
# both load paths. `SkillContext` stores the Skill on the private
|
|
768
|
+
# `_skill` attribute (no public `skill` property — see the
|
|
769
|
+
# ``self._skill_context._skill = self`` assignment in ``Skill.__init__``),
|
|
770
|
+
# so we walk that explicitly. The `relative_to` call's narrow
|
|
771
|
+
# exceptions are caught only at the point they can fire.
|
|
772
|
+
file_stem = Path(path).stem
|
|
773
|
+
parent_parts: Tuple[str, ...] = ()
|
|
774
|
+
skill_dir = getattr(
|
|
775
|
+
getattr(getattr(skill_context, "_skill", None), "configuration", None),
|
|
776
|
+
"directory",
|
|
777
|
+
None,
|
|
778
|
+
)
|
|
779
|
+
if skill_dir is not None:
|
|
780
|
+
try:
|
|
781
|
+
relative = Path(path).resolve().relative_to(Path(skill_dir).resolve())
|
|
782
|
+
parent_parts = relative.parent.parts
|
|
783
|
+
except (ValueError, OSError):
|
|
784
|
+
pass
|
|
785
|
+
dotted_path = package_dotted_path(
|
|
786
|
+
skill_context.skill_id.author,
|
|
787
|
+
SKILLS,
|
|
788
|
+
skill_context.skill_id.name,
|
|
789
|
+
".".join(parent_parts + (file_stem,)),
|
|
790
|
+
)
|
|
791
|
+
component_module = load_module(dotted_path, Path(path))
|
|
763
792
|
classes = inspect.getmembers(component_module, inspect.isclass)
|
|
793
|
+
# Keep `SkillComponent` subclasses except those provided by the
|
|
794
|
+
# framework (`aea.*`). Cross-skill re-exports (composition idiom)
|
|
795
|
+
# have a `__module__` from another skill, not `aea.`, and are kept
|
|
796
|
+
# by design.
|
|
764
797
|
component_classes = list(
|
|
765
798
|
filter(
|
|
766
799
|
lambda x: x[0] in component_names
|
|
767
800
|
and issubclass(x[1], component_class)
|
|
768
|
-
and not str.startswith(x[1].__module__, "aea.")
|
|
769
|
-
and not str.startswith(
|
|
770
|
-
x[1].__module__,
|
|
771
|
-
f"packages.{skill_context.skill_id.author}.skills.{skill_context.skill_id.name}",
|
|
772
|
-
),
|
|
801
|
+
and not str.startswith(x[1].__module__, "aea."),
|
|
773
802
|
classes,
|
|
774
803
|
)
|
|
775
804
|
)
|
|
@@ -924,11 +953,25 @@ class _SkillComponentLoader:
|
|
|
924
953
|
)
|
|
925
954
|
return module_paths
|
|
926
955
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
956
|
+
def _compute_module_dotted_path(self, module_path: Path) -> str:
|
|
957
|
+
"""Compute the dotted path for a skill module.
|
|
958
|
+
|
|
959
|
+
``__init__.py`` files are registered by ``load_aea_package``
|
|
960
|
+
under the parent package's dotted path (no ``.__init__``
|
|
961
|
+
suffix). Return that exact key so ``load_module`` cache-hits
|
|
962
|
+
on the already-loaded module instead of re-executing the file
|
|
963
|
+
(which would create duplicate class objects).
|
|
964
|
+
|
|
965
|
+
:param module_path: the module path, relative to the skill directory.
|
|
966
|
+
:return: the canonical dotted import path for that module.
|
|
967
|
+
"""
|
|
968
|
+
if module_path.name == "__init__.py":
|
|
969
|
+
parent_parts = module_path.parent.parts
|
|
970
|
+
if not parent_parts:
|
|
971
|
+
return self.skill_dotted_path
|
|
972
|
+
return f"{self.skill_dotted_path}.{'.'.join(parent_parts)}"
|
|
930
973
|
suffix = ".".join(module_path.with_name(module_path.stem).parts)
|
|
931
|
-
return suffix
|
|
974
|
+
return f"{self.skill_dotted_path}.{suffix}"
|
|
932
975
|
|
|
933
976
|
def _filter_classes(
|
|
934
977
|
self, classes: List[Tuple[str, Type]]
|
|
@@ -937,23 +980,24 @@ class _SkillComponentLoader:
|
|
|
937
980
|
Filter classes of skill components.
|
|
938
981
|
|
|
939
982
|
The following filters are applied:
|
|
940
|
-
- the class must be a subclass of
|
|
941
|
-
- its __module__ attribute must not start with
|
|
942
|
-
|
|
943
|
-
|
|
983
|
+
- the class must be a subclass of ``SkillComponent``;
|
|
984
|
+
- its ``__module__`` attribute must not start with ``aea.``
|
|
985
|
+
(classes provided by the framework are excluded).
|
|
986
|
+
|
|
987
|
+
Cross-skill re-exports (composition skills binding another skill's
|
|
988
|
+
``Handler``, ``Model``, etc. as their own — including the
|
|
989
|
+
``Model``-wrapped dialogues classes such as ``AbciDialogues``) are
|
|
990
|
+
kept by design: such classes have a ``__module__`` from another
|
|
991
|
+
skill and pass the filter. Framework dialogue base classes from
|
|
992
|
+
``aea.protocols.dialogue.base`` are not ``SkillComponent``
|
|
993
|
+
subclasses and are filtered out by the first condition anyway.
|
|
944
994
|
|
|
945
995
|
:param classes: a list of pairs (class name, class object)
|
|
946
996
|
:return: a list of the same kind, but filtered with only skill component classes.
|
|
947
997
|
"""
|
|
948
998
|
filtered_classes = filter(
|
|
949
999
|
lambda name_and_class: issubclass(name_and_class[1], SkillComponent)
|
|
950
|
-
|
|
951
|
-
and not str.startswith(name_and_class[1].__module__, "aea.")
|
|
952
|
-
# the following condition filters out classes imported
|
|
953
|
-
# from other skills
|
|
954
|
-
and not str.startswith(
|
|
955
|
-
name_and_class[1].__module__, self.skill_dotted_path + "."
|
|
956
|
-
),
|
|
1000
|
+
and not str.startswith(name_and_class[1].__module__, "aea."),
|
|
957
1001
|
classes,
|
|
958
1002
|
)
|
|
959
1003
|
classes = list(filtered_classes)
|
|
@@ -1186,10 +1230,14 @@ class _SkillComponentLoader:
|
|
|
1186
1230
|
set_of_unused_classes = set(
|
|
1187
1231
|
filter(lambda x: x not in used_classes, set_of_classes)
|
|
1188
1232
|
)
|
|
1189
|
-
#
|
|
1233
|
+
# Filter out classes that are from other packages. Match both
|
|
1234
|
+
# submodule classes (`packages.<a>.skills.<n>.foo.Bar`) and
|
|
1235
|
+
# classes defined at the skill's `__init__.py` level (whose
|
|
1236
|
+
# `__module__` equals `self.skill_dotted_path` exactly).
|
|
1190
1237
|
set_of_unused_classes = set(
|
|
1191
1238
|
filter(
|
|
1192
|
-
lambda x:
|
|
1239
|
+
lambda x: x.__module__ == self.skill_dotted_path
|
|
1240
|
+
or str.startswith(x.__module__, self.skill_dotted_path + "."),
|
|
1193
1241
|
set_of_unused_classes,
|
|
1194
1242
|
)
|
|
1195
1243
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|