Skip to content

Commit fdc1f84

Browse files
Merge pull request #919 from valory-xyz/chore/release-v2.2.7
chore: release v2.2.7
2 parents a73534b + e460d59 commit fdc1f84

22 files changed

Lines changed: 79 additions & 28 deletions

File tree

HISTORY.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
# Release History - open AEA
22

3-
## Unreleased
3+
## 2.2.7 (2026-05-27)
44

55
Framework:
66

7-
- `aea.configurations.loader`: exposes `parse_service_yaml(file_pointer) -> (head, overrides)` as a public module-level helper that parses a service YAML stream into the head document and the trailing override documents without schema validation. `ConfigLoader._load_service_config` now delegates to it. Lets downstream packagers (e.g. open-autonomy, which needs to substitute environment variables in the head document before validating it through its own `Service` config class) drop a hand-maintained copy of the parse-and-split logic. Raises `ValueError("Service configuration file was empty.")` whenever the head document is not a mapping — covers empty streams, bare `---`, and YAML scalars (`false`, `0`, `""`, `[]`) — so the failure surfaces at parse time rather than as an opaque `AttributeError` from the downstream validator.
8-
- `aea.cli.scaffold.scaffold_item`: saves `ctx.cwd` on entry and restores it via `try ... finally`. Previously the `--to-local-registry` branch swapped `ctx.cwd` to `<registry_path>/<author>` to make the inner `fingerprint_item` call resolve correctly, but never restored it, leaking the registry path back to callers. The post-fingerprint steps in the same function (notably the `--with-symlinks` block, which builds vendor symlinks from `ctx.cwd`) also see the original value again. Downstream wrappers that had to bracket `scaffold_item` with their own `preserve_cwd = ctx.cwd; ...; ctx.cwd = preserve_cwd` can drop the workaround.
9-
- `aea.contracts.base.Contract.from_config` and `aea.connections.base.Connection.from_config`: pass the canonical packages-prefixed dotted path (`packages.<author>.contracts.<name>.contract` / `packages.<author>.connections.<name>.connection`) to `load_module` instead of the bare `"contracts"` / `"connection_module"` constants. With the new `sys.modules` registration in `load_module` (below), the bare keys would have collided across contracts and across connections loaded in the same process. Caller-visible behaviour is unchanged because `load_module` always returns a fresh module object.
10-
- `aea.skills.base._SkillComponentLoader`: makes the dotted module path returned by `_compute_module_dotted_path` the canonical one (`packages.<author>.skills.<name>.<file>`), drops the now-redundant "exclude classes whose `__module__` starts with this skill's dotted path" condition from `_filter_classes`, and updates the unused-class warning filter at `_print_warning_message_for_unused_classes` to keep classes that belong to this skill (both submodule classes and those defined at the skill's own `__init__.py` level) instead of dropping every `packages.`-prefixed class. Cross-skill re-exports (the canonical FSM composition idiom — `class_name: AbciDialogues` in `skill.yaml` bound to an `AbciDialogues` imported from a parent skill) still pass the filter because their `__module__` starts with another skill's prefix, not `aea.`. The legacy `_parse_module` filter (used by `Behaviour.parse_module` / `Handler.parse_module` / `Model.parse_module`) drops the same local-prefix exclusion clause and switches its `load_module` call to the canonical packages-prefixed dotted path so its `sys.modules` cache entries do not collide on bare keys (`"behaviours"` / `"handlers"` / `"models"`) across skills loaded in the same process. The remaining difference vs. `_filter_classes` is the legacy filter's name-allowlist gate (`x[0] in component_names`), which is unchanged. `aea.helpers.base.load_module` now registers the loaded module in `sys.modules` under its dotted path before `exec_module` and rolls the entry back if `exec_module` raises, so (a) a subsequent ordinary `from packages.<author>.skills.<name>.<file> import X` returns the same module object instead of re-executing the file and producing a second copy of every class defined in it, and (b) a transient module-level error does not permanently poison `sys.modules` with a half-initialised stub. Together these eliminate the dual short-name / long-name class objects that downstream code (open-autonomy's `_MetaPayload.registry`) previously had to paper over with a key-rewrite loop. `_compute_module_dotted_path` is no longer a `@classmethod` (it reads `self.skill_dotted_path`) — internal API, no out-of-tree caller.
7+
- `aea.configurations.loader`: exposes `parse_service_yaml(file_pointer) -> (head, overrides)` as a public module-level helper that parses a service YAML stream into the head document and the trailing override documents without schema validation. `ConfigLoader._load_service_config` now delegates to it. Lets downstream packagers (e.g. open-autonomy, which needs to substitute environment variables in the head document before validating it through its own `Service` config class) drop a hand-maintained copy of the parse-and-split logic. Raises `ValueError("Service configuration file was empty.")` whenever the head document is not a mapping — covers empty streams, bare `---`, and YAML scalars (`false`, `0`, `""`, `[]`) — so the failure surfaces at parse time rather than as an opaque `AttributeError` from the downstream validator. #918
8+
- `aea.cli.scaffold.scaffold_item`: saves `ctx.cwd` on entry and restores it via `try ... finally`. Previously the `--to-local-registry` branch swapped `ctx.cwd` to `<registry_path>/<author>` to make the inner `fingerprint_item` call resolve correctly, but never restored it, leaking the registry path back to callers. The post-fingerprint steps in the same function (notably the `--with-symlinks` block, which builds vendor symlinks from `ctx.cwd`) also see the original value again. Downstream wrappers that had to bracket `scaffold_item` with their own `preserve_cwd = ctx.cwd; ...; ctx.cwd = preserve_cwd` can drop the workaround. #918
9+
- `aea.contracts.base.Contract.from_config` and `aea.connections.base.Connection.from_config`: pass the canonical packages-prefixed dotted path (`packages.<author>.contracts.<name>.contract` / `packages.<author>.connections.<name>.connection`) to `load_module` instead of the bare `"contracts"` / `"connection_module"` constants. With the new `sys.modules` registration in `load_module` (below), the bare keys would have collided across contracts and across connections loaded in the same process. Caller-visible behaviour is unchanged because `load_module` always returns a fresh module object. #918
10+
- `aea.skills.base._SkillComponentLoader`: makes the dotted module path returned by `_compute_module_dotted_path` the canonical one (`packages.<author>.skills.<name>.<file>`), drops the now-redundant "exclude classes whose `__module__` starts with this skill's dotted path" condition from `_filter_classes`, and updates the unused-class warning filter at `_print_warning_message_for_unused_classes` to keep classes that belong to this skill (both submodule classes and those defined at the skill's own `__init__.py` level) instead of dropping every `packages.`-prefixed class. Cross-skill re-exports (the canonical FSM composition idiom — `class_name: AbciDialogues` in `skill.yaml` bound to an `AbciDialogues` imported from a parent skill) still pass the filter because their `__module__` starts with another skill's prefix, not `aea.`. The legacy `_parse_module` filter (used by `Behaviour.parse_module` / `Handler.parse_module` / `Model.parse_module`) drops the same local-prefix exclusion clause and switches its `load_module` call to the canonical packages-prefixed dotted path so its `sys.modules` cache entries do not collide on bare keys (`"behaviours"` / `"handlers"` / `"models"`) across skills loaded in the same process. The remaining difference vs. `_filter_classes` is the legacy filter's name-allowlist gate (`x[0] in component_names`), which is unchanged. `aea.helpers.base.load_module` now registers the loaded module in `sys.modules` under its dotted path before `exec_module` (reusing any module already registered at that path so a subsequent ordinary `from packages.<author>.skills.<name>.<file> import X` returns the same object instead of re-executing the file and producing a second copy of every class defined in it), and rolls the entry back if `exec_module` raises. Together these eliminate the dual short-name / long-name class objects that downstream code (open-autonomy's `_MetaPayload.registry`) previously had to paper over with a key-rewrite loop. `_compute_module_dotted_path` is no longer a `@classmethod` (it reads `self.skill_dotted_path`) — internal API, no out-of-tree caller. #918
1111

1212
- `aea.cli` / `aea.helpers.protocols`: removes the two module-top `logging.basicConfig(...)` calls that fired as a side effect of `import aea.cli` and attached a stderr `StreamHandler` to the root logger. That orphan root handler survived the agent's `logging.config.dictConfig` (the config block has no `root:` key) and caught every `aea.agent.*` record a second time via propagation, producing the `] [INFO]` vs `][INFO]` doubling seen in operator captures. Fix moves the `basicConfig` in `aea/cli/generate_all_protocols.py` into the click command body and switches `aea/helpers/protocols.py` from `setup_logger(__name__)` to `logging.getLogger(__name__)`. Behaviour change for operators: third-party library `INFO`/`DEBUG` logs (e.g. from `web3`, `requests` in the ledger plugins) that the orphan handler previously surfaced now go silent under an agent config without a `root:` block in `logging_config`. `WARNING` and above still appear on stderr via Python's `logging.lastResort` handler, though with that handler's bare-message format (just `%(message)s`, no level or logger-name prefix and no timestamp) rather than the formatted one the orphan installed. Operators who want the previous behaviour (timestamped third-party `INFO`/`DEBUG`) can add a `root:` block to `logging_config` in the agent's `aea-config.yaml`. #914 #917
13+
- `aea.helpers.env_vars.generate_env_vars_recursively`: adds an `is_strict_dict`-style branch that JSON-encodes a whole dict as a single env var when any key fails the bash identifier rule (`^[A-Za-z_][A-Za-z0-9_]*$`), mirroring the existing `is_strict_list` handling. Previously a dict keyed by bash-unsafe strings (e.g. probability thresholds like `"0.0"`, `"0.6"`, `"1.0"`) flattened per key to env var names such as `..._BET_AMOUNT_PER_THRESHOLD_0.0` that bash rejects at export time, so the override silently never reached the agent (see [open-autonomy#2243](https://github.com/valory-xyz/open-autonomy/issues/2243)). Also fixes a latent key-corruption bug where the per-key path round-tripped numeric-looking string keys through `json.loads` inside `parse_list`. All-safe-key dicts still flatten per key (no regression); mixed-key dicts now travel as one JSON-encoded env var. Agent-side reads through `convert_value_str_to_type` JSON-decode the `:dict:`/`:list:` placeholders unchanged. #915
14+
15+
Plugins:
16+
17+
- `open-aea-ci-helpers` (`aea-ci check-dependencies`): `PyProjectToml.load` now reads `[tool.poetry.group.*.dependencies]` tables in addition to the main `[tool.poetry.dependencies]` block, and accepts dict-form entries without an `extras` key (so `{version = "...", optional = true}` deps are no longer silently dropped). Implementation refactored around two helpers (`_normalize_version`, `_dependency_from_spec`) that handle string and dict forms uniformly; main-deps entries still win on name collisions. New unit tests at `plugins/aea-ci-helpers/tests/test_check_dependencies.py` cover the four entry formats, `dev` + `docs` groups, main-vs-group precedence, missing `[tool.poetry]` table, and the `python` ignore filter. Removes a sharp edge for anyone using `aea-ci check-dependencies` locally against a project with grouped or optional-without-extras deps. #916
18+
19+
Documentation:
20+
21+
- `docs/connection-resilience.md` rewrite addressing @DavidMinarsch's review of the original v2.2.6 doc. Adds a "What the protocol's speech acts imply" section that walks through the protocols in the repo and groups them by failure-channel shape (typed-error, status-with-classification, response-only, routing-failure) — making explicit how a protocol's `speech_acts` and reply rules pin down what the skill can decide. Terminology aligned with the framework convention (`speech_acts` over "vocabulary", with FIPA's "performatives" as a one-line synonym). Cross-links added to Design principles, Architectural diagram, Skills, Connections, Protocols, Message routing, Decision maker, and Ledger & Crypto APIs. Accuracy pass on the original draft (`fetchai/default` routing failures are surfaced by the `fetchai/error` skill, not the multiplexer; protocols decide failure-signal richness, not which layer retries; ACN reply rules clarified per performative). Net 261 → 91 lines for the same coverage plus the new protocol section. #912
1322

1423
## 2.2.6 (2026-05-14)
1524

aea/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
__title__ = "open-aea"
2424
__description__ = "Open Autonomous Economic Agent framework (without vendor lock-in)"
2525
__url__ = "https://github.com/valory-xyz/open-aea.git"
26-
__version__ = "2.2.6"
26+
__version__ = "2.2.7"
2727
__author__ = "Valory AG"
2828
__license__ = "Apache-2.0"
2929
__copyright__ = "2021 Valory AG, 2019 Fetch.AI Limited"

deploy-image/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ RUN apk add --no-cache go
1616

1717
# aea installation
1818
RUN pip install --upgrade pip
19-
RUN pip install --upgrade --force-reinstall open-aea[all]==2.2.6 "open-aea-cli-ipfs<3.0.0,>=2.2.6"
19+
RUN pip install --upgrade --force-reinstall open-aea[all]==2.2.7 "open-aea-cli-ipfs<3.0.0,>=2.2.7"
2020

2121
# directories and aea cli config
2222
WORKDIR /home/agents

deploy-image/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The example uses the `fetchai/my_first_aea` project. You will likely want to mod
1111
Install subversion, then download the example directory to your local working directory
1212

1313
``` bash
14-
svn checkout https://github.com/valory-xyz/open-aea/tags/v2.2.6/packages packages
14+
svn checkout https://github.com/valory-xyz/open-aea/tags/v2.2.7/packages packages
1515
```
1616

1717
### Modify scripts

develop-image/docker-env.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22

33
# Swap the following lines if you want to work with 'latest'
4-
DOCKER_IMAGE_TAG=valory/open-aea-develop:2.2.6
4+
DOCKER_IMAGE_TAG=valory/open-aea-develop:2.2.7
55
# DOCKER_IMAGE_TAG=valory/open-aea-develop:latest
66

77
DOCKER_BUILD_CONTEXT_DIR=..

0 commit comments

Comments
 (0)