Joint Observation-Planning Architecture — the same factor graph for learning and planning.
Or: Poor Man's Active Inference via message passing.
Active Inference (de Vries, 2026) · VMP in Factor Graphs (Şenöz et al., 2021) · Lazy Dynamics
JOPA is a feasibility study for doing perception, learning, and control on a single probabilistic factor graph. It takes raw pixel images and torque inputs, learns a latent dynamical system via Bayesian message passing, and plans actions by running inference on the same graph. No reward functions, no policy networks, no replay buffers.
This is a fun weekend project, not a paper. It shows the idea works on a toy pendulum and rotating digits. There are plenty of rough edges — see Known limitations and the open issues for what's missing.
How this was built. This codebase was largely written by Claude Code. The only component Claude couldn't derive was the message-passing rules for the Continuous Transition node — those were provided as hand-derived VMP update equations. Everything else was assembled from a description of the generative model.
Note on tests. The inference diagnostic test suite has been removed from this release as it relies on internal tooling that cannot be open-sourced yet.
A linear dynamical system in a VAE's latent space:
with priors on
| Task | Inferred | Fixed |
|---|---|---|
| System identification | VAE, images, actions | |
| Variational EM |
|
images, actions |
| Planning | actions |
|
Learn dynamics — forward-backward messages estimate latent states, VMP messages update beliefs about
Plan actions — fix the learned model, observe start and goal images, treat actions as latent variables. The same VMP machinery infers an action sequence. A receding-horizon loop (observe → plan → act → repeat) gives closed-loop control from pixels.
It shares the spirit — perception and action as inference on a generative model — but cuts corners: gradient-based VAE training instead of full Bayesian treatment, no epistemic priors or expected free energy, linear dynamics only. The planning is goal-conditioned VMP, not proper Active Inference. But the factor graph is real, and every operation on it is a message.
- VAE pre-training is not message passing. The observation model uses gradient descent. The EM refines it, but the initial representation comes from deep learning.
- No velocity from a single image. Can swing to a target but can't stabilise — a single frame doesn't encode angular velocity.
- Linear dynamics. Works when the VAE learns a good representation, breaks when it doesn't. Planning fails for some goal angles due to latent space topology.
- Slow E-step. Python loops over small matrices. The proper fix (JIT the full VMP loop) is an open problem.
- Training variance. Results depend on VAE initialisation. No automated validation that a checkpoint is good enough for planning.
Contributions are welcome. The best place to start is the open issues — each one describes a concrete direction that would make this more than a toy:
- Nonlinear transition node — replace linear dynamics with a learned function, keeping the message passing structure
- Multi-frame encoder — encode velocity from frame stacks to fix the stabilisation problem
- Expected free energy — add epistemic priors for proper Active Inference
- Standard benchmarks — CartPole, Acrobot, Reacher — show where the Bayesian approach helps
Pick one, open a PR, and we'll review it.
git clone https://github.com/lazydynamics/JOPA.git && cd JOPA
uv pip install -e .
uv run python examples/pendulum.py # swing-up demo
uv run marimo run notebook.py # interactive notebookjopa/
distributions.py # Gaussian, Wishart in natural parameter form
message_passing.py # Forward-backward messages, VMP accumulation
inference.py # infer() — learn dynamics, plan() — infer actions
em.py # variational_em() — joint VAE + dynamics learning
nodes/
transition.py # Continuous transition node (VMP message rules)
observation.py # VAE observation node
nn/
vae.py # Convolutional VAE (Flax)
data.py # MNIST loading and rotation utilities
envs/ # Simulation environments (pendulum)
- de Vries, B. "Active Inference for Physical AI Agents — An Engineering Perspective", arXiv:2603.20927, 2026.
- Şenöz, I. et al. "Variational Message Passing and Local Constraint Manipulation in Factor Graphs", Entropy, 2021.
GPL-3.0 — free to use, derivatives must also be open source.



