Architecture & Flow Diagrams

One repository, several deliberately separable layers. At v1.0.0 the framework is a uv workspace with a lean modeling core and optional application layers on top — install exactly as much of the platform as you need.

The split is simple to state: pip install mmm-framework gives you the business logic only — the Bayesian modeling engine on the PyMC 6 stack, with reporting, validation, planning, and estimands, and nothing that phones an LLM or serves HTTP. The mmm-framework[agents] extra adds the LangGraph oracle (langgraph / langchain, plus httpx, pypdf, and python-docx for knowledge-base ingestion). The web application is its own package: mmm-framework-server (repo directory server/, Python package mmm_framework_server) is the FastAPI app, run with uvicorn mmm_framework_server.main:app. The frontend/ directory holds the React UI that talks to it over HTTP and SSE.

One rename matters if you knew the pre-1.0 layout: the former mmm_framework.api service modules — the sessions store, run history, pacing, scorecard, triangulation, backfill, backup, and friends — are now mmm_framework.platform. They are dependency-light and shared by both the agents layer and the server, so the core package can carry them without dragging in a web stack. A lean-import gate test (tests/test_lean_imports.py) pins the invariant: importing the core must not pull the agent or server dependencies.

Install what you need

# Modeling core only — PyMC 6 stack, no LLM, no web server
pip install mmm-framework

# Core + the LangGraph oracle agent (langgraph/langchain, httpx, pypdf, python-docx)
pip install "mmm-framework[agents]"

# The FastAPI application (depends on mmm-framework[agents])
pip install mmm-framework-server
uvicorn mmm_framework_server.main:app --host 0.0.0.0 --port 8000

# Optional data-integration extras for the core
pip install "mmm-framework[gcp]"   # GCS + BigQuery readers
pip install "mmm-framework[s3]"    # S3 object store

💡 Who this page is for

Technical evaluators and developers deciding what to deploy where. If you want the guided product tour instead, start with the Platform Overview; if you want to fit a model in ten minutes, start with Getting Started.

1 · Package & dependency architecture

Dependencies point in exactly one direction: the server depends on the core with the agents extra, the agents extra depends on the core, and the core depends on nothing above it. The React frontend is not a Python dependency at all — it speaks HTTP and SSE to the server. The session kernel image is a deploy artifact built from the lean core (plus ipykernel, python-pptx, and matplotlib for in-kernel deck and chart rendering) and deliberately carries no LLM or web stack: user code executed in a session never has the credentials or the libraries to call out.

graph TD FE["frontend/
React + Vite UI"] SRV["mmm-framework-server
FastAPI app · repo server/ · package mmm_framework_server"] AGENTS["mmm-framework with the agents extra
LangGraph oracle · langgraph, langchain, httpx, pypdf, python-docx"] CORE["mmm-framework — the core
model · transforms · config + builders · reporting · validation
planning · estimands · diagnostics · eda · synth · platform · auth core
"] KERNEL["session kernel image
lean core + ipykernel + python-pptx + matplotlib
no LLM or web stack
"] GCP["gcp extra
GCS + BigQuery"] S3["s3 extra
S3 object store"] FE -->|"HTTP + SSE"| SRV SRV -->|"depends on"| AGENTS AGENTS -->|"depends on"| CORE KERNEL -->|"built from"| CORE GCP -.->|"optional extra of"| CORE S3 -.->|"optional extra of"| CORE style FE fill:#e6f0f7,stroke:#4a6d8a style SRV fill:#f7f0e6,stroke:#8a6d4a style AGENTS fill:#f0e6f7,stroke:#6d4a8a style CORE fill:#f0f7e6,stroke:#6d8a4a style KERNEL fill:#e6f7f0,stroke:#4a8a6d
Solid arrows are hard dependencies; dotted arrows are optional extras. Nothing in the core depends outward.

2 · Model-building data flow

The modeling pipeline is a straight line from data to a fitted posterior, then a fan-out into everything you do with one. Data arrives as an MFF (Master Flat File) CSV, a wide CSV, or a bundled load_example() dataset; MFFLoader validates it (schema, cadence, coverage) and produces a PanelDataset; BayesianMMM builds the PyMC graph — adstock, then saturation, then trend, seasonality, and controls, then the likelihood — and fits it with full NUTS (PyMC or numpyro), an approximate method for fast iteration (MAP, ADVI, pathfinder, Laplace), or tempered SMC, which is exact. Everything downstream consumes the same MMMResults object.

graph LR subgraph IN["Data in"] MFF["MFF CSV
long format"] WIDE["wide CSV"] EX["load_example()"] end LOAD["MFFLoader
validation · cadence checks"] PANEL["PanelDataset"] MODEL["BayesianMMM
adstock → saturation → trend, seasonality, controls → likelihood
fit: NUTS / numpyro · approximate MAP, ADVI, pathfinder, Laplace · SMC exact
"] RES["MMMResults
posterior · diagnostics · estimands"] subgraph OUT["Fan-out"] REP["MMMReportGenerator
Augur HTML readout"] IREP["InteractiveReportGenerator
recompute-in-browser report"] SER["MMMSerializer
persisted model directory"] ANA["analysis + estimands
ROI · marginal ROAS · counterfactuals"] VAL["validation
backtests · SBC · refutation"] end MFF --> LOAD WIDE --> LOAD EX --> LOAD LOAD --> PANEL PANEL --> MODEL MODEL --> RES RES --> REP RES --> IREP RES --> SER RES --> ANA RES --> VAL style IN fill:#e6f0f7,stroke:#4a6d8a style OUT fill:#f0f7e6,stroke:#6d8a4a style MODEL fill:#f7f0e6,stroke:#8a6d4a
One results object feeds every downstream surface — reports, persistence, analysis, and validation never re-fit.

3 · Application request flow

When the full application is deployed, a chat turn traces a single round trip. The React UI (dev port 5173) opens an SSE stream against the FastAPI server's /chat endpoint (port 8000); the server resumes the LangGraph agent from its checkpoint; the agent — held to one workflow step per user turn by the workflow-step guard — calls tools; heavy work (including model fits) runs inside the per-session kernel, which can be in-process, a subprocess, or a sandboxed container; durable state lands in the SQLite sessions store under mmm_framework.platform.sessions. Results stream back as typed SSE events and render into the workspace tabs.

sequenceDiagram autonumber actor User participant UI as React UI (port 5173) participant API as FastAPI server (port 8000) participant Agent as LangGraph agent participant Tools as Tools layer participant Kernel as Session kernel participant Store as platform.sessions (SQLite) User->>UI: Ask a question in the Oracle UI->>API: POST /chat — SSE stream opens API->>Agent: Resume thread from checkpoint Note over Agent: Workflow-step guard —
one pipeline milestone per turn Agent->>Tools: Tool call (EDA, build, fit, report, ...) Tools->>Kernel: execute_python — fits run in-kernel Kernel-->>Tools: stdout, plots, tables Tools->>Store: Persist artifacts, experiments, run metrics Store-->>API: Session state and artifact refs API-->>UI: SSE events — messages, plots, tables, artifacts UI-->>User: Rendered in the workspace tabs
The kernel does the compute; the store keeps the durable record; the UI only ever sees typed SSE events.

4 · The measurement loop

The product story is not a one-off model fit — it is an adaptive measurement cycle. A fitted, calibration-aware MMM (T₀) tells you where the posterior is weakest; expected information gain and expected value of information rank which experiment to run next (T₁); experiments are designed and pre-registered with a full lifecycle — draft → planned → running → completed → calibrated (T₂); completed readouts enter the next refit as in-graph experiment likelihoods, not post-hoc adjustments (T₃); the calibrated model drives budget allocation (T₄); and information decay triggers re-tests as the market drifts (T₅), feeding the next round of priorities. The experiment registry and its lifecycle live in mmm_framework.platform.sessions.

graph LR T0["T₀ · Fit
Bayesian MMM with calibration"] T1["T₁ · Prioritize
EIG / EVOI per channel"] T2["T₂ · Design + pre-register
geo lift · DiD · flighting
draft → planned → running → completed → calibrated
"] T3["T₃ · Calibrated refit
experiment likelihoods in-graph"] T4["T₄ · Allocate
budget optimizer"] T5["T₅ · Re-evaluate
information decay triggers re-tests"] T0 --> T1 T1 --> T2 T2 --> T3 T3 --> T4 T4 --> T5 T5 -->|"new priorities"| T1 style T0 fill:#f0f7e6,stroke:#6d8a4a style T3 fill:#f0f7e6,stroke:#6d8a4a style T1 fill:#e6f0f7,stroke:#4a6d8a style T5 fill:#e6f0f7,stroke:#4a6d8a style T2 fill:#f7f0e6,stroke:#8a6d4a style T4 fill:#f7f0e6,stroke:#8a6d4a
The loop closes at T₅ → T₁: yesterday's answers decay, and the model itself nominates the next experiment.

Where things live

A quick map from subsystem to import path. Everything in the first column below the double rule ships in the core package; the last two rows are the agents extra and the separate server package.

SubsystemImport path
Core modeling (engine, transforms, configuration)mmm_framework.model · .transforms · .builders · .config
Data loading and panelsmmm_framework.data_loader · .dataset · .datasets
Inference resultsmmm_framework.model.results
Estimands (named, serializable causal quantities)mmm_framework.estimands
Reporting (Augur readout, interactive report, decks)mmm_framework.reporting
Validation and diagnostics (backtests, SBC, coverage, refutation)mmm_framework.validation · .diagnostics
Experiment planning (EIG/EVOI, design, economics, optimizer)mmm_framework.planning
Platform services (sessions store, run history, pacing, scorecard, triangulation, backfill, backup)mmm_framework.platform
Agent — LangGraph oracle (requires the agents extra)mmm_framework.agents
Server — FastAPI application (separate package)mmm_framework_server.main

Where to go next

The shapes on this page are frozen by contract: the request/response schemas and artifact formats the diagrams gesture at are specified in API Contracts, and every server endpoint is documented in the REST API reference. For the guided product walkthrough see the Platform Overview, and to fit your first model, Getting Started.

See it in motion

The diagrams are the map — the contracts and the quickstart are the territory.