This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Open AEA (Autonomous Economic Agent) Framework — a Python framework for building autonomous economic agents, forked from Fetch.AI's AEA to remove vendor lock-in. Maintained by Valory AG. Supports Python 3.10–3.14.
make new_env # Create poetry environment with all dev dependencies
poetry shell # Enter virtual environment# Protobuf compiler (needed for protocol generator tests)
# macOS: brew install protobuf
# Linux: download from https://github.com/protocolbuffers/protobuf/releases
# protolint (needs Go installed)
make protolint_install
# IPFS v0.6.0 (needed for TestDirectoryHashing only)
# Download from https://github.com/valory-xyz/open-aea/releases/tag/ipfs-v0.6.0-binariesmake formatters # Run isort + black via tox
make code-checks # Run all linters in parallel (black-check, isort-check, flake8, mypy, pylint, vulture, darglint)
make security # Run bandit, safety, gitleaks# Run all tests with coverage
make test
# Test a specific submodule (aea.{SUBMODULE} with tests/test_{TESTMODULE})
make dir=cli tdir=cli test-sub
# Test a specific package
make dir=skills tdir=packages/test_skills test-sub-p
# Run a single test file directly
pytest tests/test_aea.py -rfE
# Run a single test
pytest tests/test_aea.py::TestAEA::test_name -rfE
# Full tox matrix
make test-allmake generators # Regenerate hashes, docs, copyright headers, protocol code
make common-checks-1 # Verify copyright, hashes, package dependencies
make common-checks-2 # Check API docs and doc link hashes
make hashes # Just regenerate package hashes (via `tox -e lock-packages`)make build-proto # Compile .proto files (requires INCLUDE=PATH_TO_PROTOC_INCLUDE)
make protolint # Lint .proto files- Black with line length 88,
isortwith black-compatible profile - Docstrings: Sphinx style (enforced by
darglint) - All files must include the Apache 2.0 license header (checked by
tox -e fix-copyright) - Generated
*_pb2.pyfiles are excluded from all linting
The AEA runtime is an asyncio-based agent loop. Key classes:
AEA(aea/aea.py) — Main agent class inheriting fromAgent. Manages life cycle, communications, and resource coordinationAEABuilder(aea/aea_builder.py) — Programmatic agent construction, configuration loading, dependency resolutionMultiplexer(aea/multiplexer.py) — Communication hub managing multiple connections, withInBox/OutBoxmessage queues
Agents are composed of four component types, each loaded via configuration:
- Skills (
aea/skills/) — Agent behaviour: Handlers (reactive, respond to messages), Behaviours (proactive, internally triggered), Models (state), Tasks (background work). Skills are horizontally arranged and can compete. - Protocols (
aea/protocols/) — Define message syntax and dialogues. Use Protocol Buffers for serialization. Each skill maps to at least one protocol. - Connections (
aea/connections/) — Network/service interfaces wrapping SDKs/APIs. Translate between Envelopes/Messages and external protocols. - Contracts (
aea/contracts/) — Blockchain smart contract wrappers.
Communication uses Envelopes (to, sender, protocol_id, message, context) routed through the Multiplexer.
Ledger integrations and CLI extensions are plugins, each with their own setup.py and tests:
aea-ledger-ethereum,aea-ledger-cosmos,aea-ledger-fetchai,aea-ledger-solanaaea-ledger-ethereum-hwiaea-cli-ipfs,aea-cli-benchmark
Crypto implementations are registered via a plugin registry (aea/crypto/).
Reusable agent components organized by vendor (fetchai/, valory/, open_aea/), each containing agents, connections, contracts, protocols, and skills. Package integrity is verified via hash checking (make hashes, tox -e hash-check).
Click-based CLI (entry point: aea). Supports creating, running, and managing agents and packages.
Pytest with custom markers: integration (requires external services), ledger (requires test networks), flaky, unstable (excluded from CI), sync, profiling. Test config in pytest.ini. Large conftest.py with shared fixtures.
make cleanmake formattersmake code-checksmake security- If
packages/modified:make generatorsthenmake common-checks-1andmake common-checks-2 - If
packages/not modified:make check-copyright
Do NOT commit until every check below passes locally. Do not cherry-pick a subset; each one has caught real regressions. When linters report no findings you are much better off than inferring from the output of a partial run.
The full set (per tox env):
tox -e black-check
tox -e isort-check
tox -e flake8
tox -e check-copyright
tox -e darglint # catches missing :param: / :return: lines
tox -e dependencies-check
tox -e hash-check # only if packages/ or aea/ scaffolds touched
tox -e check-doc-links-hashes # only if docs/ touched
tox -e check-api-docs # only if any aea/ or plugins/*/aea_*/ source touchedNotes:
tox -e darglintalso scans stale setuptools build artifacts under the plugins directory. If you see an error in abuild/lib/...path, runrm -rf plugins/*/buildand re-run.- For Go changes under
libs/go/aealiteorpackages/valory/connections/p2p_libp2p/libp2p_node, also rungo build ./... && go vet ./... && go test ./...in each module, plusgolangci-lint run --timeout=5mon aealite. The libp2p_node module is not yet covered by golangci (see CLEANUP.md). make code-checksbundles most of the Python tox envs above but runs them in parallel; if it fails, re-run the failing ones individually to see which one reported what.
Check-mode envs above are read-only. When they fail, run the matching fix-mode env (or manual step), then re-run the check until clean:
tox -e hash-checkfails →tox -e lock-packagesregeneratespackages/packages.jsonhashes +docs/package_list.md. Commit the regenerated files.tox -e check-doc-links-hashesfails →tox -e fix-doc-hashes.tox -e check-copyrightfails →tox -e fix-copyright.tox -e black-check/tox -e isort-checkfail →make formatters.tox -e check-api-docsfails →tox -e generate-api-documentationregenerates the markdown underdocs/api/. Commit the regenerated files. The check is essentially a "no uncommitted regen needed" gate, so it fails whenever a public docstring or signature changed without rerunning the generator.