Active inference agents in cadCAD — clean-room re-implementation of ActiveBlockference, modernized for current pymdp + cadCAD
Find a file
Jeff Emmett 98999c7cc7 feat: clean-room blockference v0.1 — AIF agents in cadCAD
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.
2026-05-09 01:22:14 -04:00
examples feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00
src/blockference feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00
tests feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00
.gitignore feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00
LICENSE feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00
pyproject.toml feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00
README.md feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00
UPSTREAM_PATCHES.md feat: clean-room blockference v0.1 — AIF agents in cadCAD 2026-05-09 01:22:14 -04:00

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 for pymdp >= 1.0 is 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_collisions is 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.0 to plug into cadcad-jax.
  • Swap upstream's hardcoded action grid for an ActionSpace protocol so non-grid envs (continuous, graph) reuse the AIF loop.
  • Cookiecutter integration: ship as an --active-inference flavor of cookiecutter-cadcad-model.
  • Inductive planning (use_inductive=True in pymdp 1.x) for longer horizons.

License

MIT. Upstream ActiveBlockference is unlicensed; nothing was copied verbatim.