ActiveBlockference v0.5+ targets inferactively-pymdp >= 1.0.1. The 1.0
release is a JAX/Equinox rewrite that removes or relocates many of the
helpers the legacy 0.0.x series exposed:
| Legacy symbol | Status in 1.0+ | Replacement in ActiveBlockference |
|---|---|---|
pymdp.maths.spm_log_single |
removed | blockference.maths.log_stable |
pymdp.maths.softmax |
removed | blockference.maths.softmax |
pymdp.utils.norm_dist |
removed | blockference.maths.norm_dist |
pymdp.utils.sample |
removed | blockference.maths.sample |
pymdp.utils.onehot |
removed | blockference.maths.onehot |
pymdp.control.construct_policies |
present, returns JAX array | blockference.maths.construct_policies (numpy) |
pymdp.agent.Agent (legacy ctor) |
new ctor: per-modality lists | blockference.agent.BlockferenceAgent (passthru) |
The legacy primitives are small, well-defined NumPy operations. Owning
them inside blockference.maths gives us:
- Numerical stability we control (e.g.
MIN_PROB = 1e-16floor onlog_stable). - Determinism under the legacy
np.random.seed(...)idiom, which many of the project's notebooks and tests rely on. - Independence from upstream's API churn — pymdp may rewrite again, and we don't need to follow every time.
- No JAX in cadCAD state — cadCAD/radCAD doesn't compose well with JAX tracers, so keeping the inference loop pure NumPy is a hard requirement.
We still install pymdp 1.0+ so callers who want the high-level Agent
class can opt in via BlockferenceAgent.
The pymdp 1.0 Agent constructor expects:
A— a list of JAX arrays, one per observation modality.B— a list of JAX arrays, one per hidden-state factor.- Renamed kwargs (
inference_algo='VANILLA'→'fpi', etc.).
BlockferenceAgent is a thin extension hook over the 1.0 Agent —
all kwargs are forwarded verbatim. ActiveBlockference's grid pipeline
does not use it; the per-step inference loop runs the math directly.
If you only use from blockference import ...:
- Nothing. The public surface is unchanged.
If you imported pymdp helpers directly:
- Replace
from pymdp.maths import softmax, spm_log_singlewithfrom blockference.maths import softmax, log_stable. - Replace
from pymdp.utils import sample, onehot, norm_distwithfrom blockference.maths import sample, onehot, norm_dist. - Replace
from pymdp.control import construct_policieswithfrom blockference.maths import construct_policiesif you want a NumPy array back.
uv run pytest tests/test_maths.py -v # 21 unit tests for primitives
uv run pytest tests/ # full suite — currently 103/103
uv run python -m blockference.simulations.grid_sim --pipeline configs/example.yml
ls output/gridworld_example/ # full artefact tree present
cat output/gridworld_example/run.log # structured log of the run
cat output/gridworld_example/validation_report.json # all checks pass