- Python 100%
Modernized re-implementation of ActiveInferenceInstitute/ActiveBlockference (unlicensed, last push Jul 2023, broken under current deps) targeting inferactively-pymdp 0.0.7.x and cadCAD 0.5.3. What's here: - aif.py: env-agnostic AIF inference loop + agent factory - envs/grid.py: discrete grid env with consistent B-matrix builder - cadcad_glue.py: single-agent PSU - multi.py: multi-agent (NetworkX graph) PSU + collision resolution - examples/: single-agent + 3-agent runnable demos - tests/: 17 passing (env, agent, AIF loop, cadCAD, multi-agent) - UPSTREAM_PATCHES.md: 6 catalogued bugs / quality issues for upstream PRs MIT licensed. No code copied from upstream — pattern only. |
||
|---|---|---|
| examples | ||
| src/blockference | ||
| tests | ||
| .gitignore | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| UPSTREAM_PATCHES.md | ||
blockference
Active inference agents in cadCAD — clean-room re-implementation of the ActiveBlockference pattern, modernized for current pymdp and cadCAD.
Why this exists
ActiveBlockference (last push July 2023) demonstrated wiring pymdp's active
inference loop into cadCAD partial state-update functions. The repo has no
license, doesn't run against current dependencies, and contains several bugs
(agent.py super-init drops args; gridference.py collides with matplotlib.pyplot.grid;
simulations/grid_sim.py imports a non-existent model module). The
intellectual contribution — AIF agents as cadCAD PSUs — is sound and worth
preserving.
This package re-implements the pattern from scratch under MIT, against:
inferactively-pymdp >= 0.0.7, < 1.0(last stable numpy API; a JAX variant forpymdp >= 1.0is planned)cadCAD >= 0.5.3- Python 3.9+
Install
pip install -e .[dev]
Quick start
from blockference.aif import build_agent, make_preference_C, make_initial_D
from blockference.envs.grid import GridEnv
env = GridEnv(width=4)
target_idx = env.to_idx((3, 3))
agent = build_agent(
num_states=env.num_states,
num_controls=env.num_actions,
B=env.build_B(), # match generative model to env
C=make_preference_C(env.num_states, target_idx, strength=4.0),
D=make_initial_D(env.num_states, env.to_idx((0, 0))),
policy_len=4,
action_selection="stochastic",
)
End-to-end via cadCAD:
python examples/single_agent_gridworld.py
python examples/multi_agent_network.py
Layout
src/blockference/
aif.py # env-agnostic AIF inference loop + agent factory
envs/grid.py # discrete grid env + B-matrix builder
cadcad_glue.py # single-agent cadCAD PSU
multi.py # multi-agent (NetworkX graph) + collision-resolved PSU
examples/
single_agent_gridworld.py
multi_agent_network.py
tests/ # 17 passing
What's preserved from upstream
| Upstream concept | Where it lives now |
|---|---|
| AIF inference loop (infer_states → infer_policies → sample_action) | aif.step_agent |
| Grid environment with UP/DOWN/LEFT/RIGHT/STAY actions | envs/grid.GridEnv |
| Single-agent cadCAD PSU pattern | cadcad_glue.make_psu_block |
| Multi-agent NetworkX graph | multi.build_agent_network |
actinf_graph per-agent inference loop |
multi.p_actinf_multi |
What's improved
- Composition over inheritance:
build_agent(...)is a factory; no broken subclass that drops its own kwargs. - B-matrix consistency:
GridEnv.build_B()produces a deterministic transition tensor matching the env. Without this, the agent's generative model is random and "navigation" is a random walk. - Decoupled concerns: inference (
aif.py), env transitions (envs/), and cadCAD wiring (cadcad_glue.py,multi.py) are separate modules. - Swappable collision policy:
multi.resolve_collisionsis a single function; replace it for different physics. - Tested end-to-end: 17 pytest cases cover env, agent factory, AIF loop, cadCAD integration, and multi-agent collision logic.
Roadmap
- JAX-native variant against
pymdp >= 1.0to plug intocadcad-jax. - Swap upstream's hardcoded action grid for an
ActionSpaceprotocol so non-grid envs (continuous, graph) reuse the AIF loop. - Cookiecutter integration: ship as an
--active-inferenceflavor ofcookiecutter-cadcad-model. - Inductive planning (
use_inductive=Truein pymdp 1.x) for longer horizons.
License
MIT. Upstream ActiveBlockference is unlicensed; nothing was copied verbatim.