An Amplifier Story
When freezing Python breaks a plugin loader
Amplifier is a modular Python framework that finds its own plugins at runtime by reading packaging metadata off disk. So the way it's shipped determines whether it can find itself at all.
The claim sounds abstract — until you look at the code that does the finding.
In loader.py the framework calls importlib.metadata.entry_points(group="amplifier.modules") — and 9 installed modules register themselves through that exact group.
Discovery-by-metadata is a fact in the code. Now watch where that code runs.
Kepler (michaeljabbour/amplifier-desktop) is a cross-platform desktop app. Its Tauri shell spawns Amplifier as a FastAPI/uvicorn process named amplifier-sidecar and talks to it over a WebSocket.
A separate Python process — which means how that process is packaged now matters directly.
Today that sidecar is packaged with PyInstaller (sidecar.spec, bundle-sidecar.cjs) into one frozen binary — the exact model that collapses the on-disk .dist-info the loader reads. It has been packaged this way since the very first commit.
So what happens to a loader that expects metadata on disk when the disk metadata is gone?
Because entry-point modules load dynamically, PyInstaller can't detect them. The spec is forced to hand-enumerate a hidden_imports list of every amplifier_* package, or they vanish from the frozen build.
Hand-maintained fragility. There's a cleaner path.
If the sidecar is a real Python environment instead of a frozen archive, the .dist-info simply stays on disk, intact, exactly where the loader expects to read it. No hand-maintained hidden_imports list required.
And it turns out that environment already exists.
Under oob/app/sidecar/.venv, a real python3.11 site-packages carries intact dist-info for all 9 modules — proof the fix works. Yet it's an untracked, git-ignored artifact: no commit landed it, no build script ships it.
The resolution is proven in principle — and still aspirational in this repo.
Keep the packaging metadata real and the loader finds its plugins for free. Collapse it into a frozen binary and you hand-maintain fragility forever — one hidden import at a time.
Package the metadata, not around it.
Feature status: Aspirational / Not Shipped — the venv-instead-of-freeze resolution is demonstrated on disk but not committed or built by any script in the primary repo.
Primary sources: repos under /home/ramparte/dev/ANext (amplifier-core, amplifier-foundation, amplifier-distro-kepler, oob, amplifier-module-*). Every claim re-derived from command output; nothing trusted from input.
Research performed:
grep -n 'group="amplifier.modules"' amplifier-core/amplifier_core/loader.py (lines 109 & 319)sed -n '10,20p' amplifier-module-tool-bash/pyproject.tomlgrep -rl 'amplifier.modules' oob/app/sidecar/.venv/lib/python3.11/site-packages/*.dist-info/entry_points.txt | wc -l (= 9)sed -n '1,60p' oob/app/sidecar/main.py; grep -n '127.0.0.1|/chat|sidecar_port' amplifier-distro-kepler/src-tauri/src/lib.rs (ws port 19876)sed -n '1,10p' amplifier-distro-kepler/sidecar/sidecar.spec; grep -n 'pyinstaller' amplifier-distro-kepler/scripts/bundle-sidecar.cjsgit -C oob ls-files app/sidecar/.venv | wc -l (= 0); grep -n venv oob/app/.gitignoregit -C amplifier-distro-kepler log --format='%an <%ae>' | sort | uniq -c | sort -rnGaps / caveats: The desktop shell is Tauri, not Electron. "python-build-standalone" appears only inside PyInstaller's vendored source, not in any Amplifier build script. No build-time metadata-verification step was found, and no repo evidence of an observed crash exists — the failure is stated as mechanism/risk, not an incident.
Primary contributors: Michael J. Jabbour (38 commits), Marc Goodner (15), Sam Schillace (13) on amplifier-distro-kepler.