@jaik7/bloomkit
flwr new @jaik7/bloomkitBloomKit
A fully-local, open-source creative studio built on Flower. Three Flower SuperNodes each host a specialized agent, one SuperLink orchestrates them, and the whole thing runs on your laptop with no cloud calls after the first model download.
The director runs the creative pipeline in two stages: the lyrics SuperNode generates text first, then the director passes that text through Flower messages to the music and poster SuperNodes. This makes one agent's output available to the next agent without relying on shared filesystem paths.
Give it a theme + artist; it produces:
| Node role | Model (smallest OSS) | Output | Runs on |
|---|---|---|---|
| lyrics | Qwen/Qwen2.5-0.5B-Instruct (~500 MB) or zero-download template | outputs/lyrics.txt | CPU |
| music | facebook/musicgen-small (~300 MB) | outputs/music.wav | CPU |
| poster | SVG template (0 MB, optional SD-Turbo) | outputs/poster.svg | CPU |
First run pulls ~800 MB of weights from Hugging Face; after that BloomKit works offline — no API keys, no telemetry, no external inference.
Architecture
┌────────────────────┐ brief (theme, artist)
│ ServerApp (main) │──────────────► ┌──────────────┐
│ runs on SuperLink │◄────────────── │ Grid.send_ │
└────────────────────┘ artifacts │ and_receive │
└──────┬───────┘
┌──────────────────────────────────┼──────────────────────────────┐
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌────────────────────┐
│ SuperNode 0 │ │ SuperNode 1 │ │ SuperNode 2 │
│ role = lyrics │ │ role = music │ │ role = poster │
│ Qwen2.5-0.5B │ │ MusicGen-small │ │ SVG template │
└───────────────────┘ └───────────────────┘ └────────────────────┘
Roles are assigned deterministically by SuperNode index (bloomkit/task.py), so scaling the node count in pyproject.toml just round-robins the roles.
Quickstart
Windows (PowerShell):
cd bloomkit .\run.ps1
macOS / Linux:
cd bloomkit bash run.sh
Then open http://127.0.0.1:8000.
Publish to Flower
Validate and publish the director-style Flower app with the pinned CLI:
uvx --from flwr==1.37.0 flwr app publish
The command validates the ServerApp, ClientApp, and package before upload. Authenticate the Flower CLI first if the upload ends with 401 Not authenticated.
Manual invocation
python -m venv .venv && source .venv/bin/activate # (or .venv\Scripts\Activate.ps1) pip install -e . # SuperLink + 3 in-process SuperNodes via Flower's simulation runtime flwr run . local-sim --run-config "theme='midnight rooms' artist='vela'" # local web viewer python -m bloomkit.viewer
Real SuperLink + SuperNode processes (no simulation)
flwr run is the fastest path. To split the SuperLink and SuperNodes into real processes (as you would across machines), open four terminals:
# term 1 — SuperLink flower-superlink --insecure # terms 2, 3, 4 — three SuperNodes with distinct partition ids flower-supernode --insecure --superlink="127.0.0.1:9092" \ --node-config="partition-id=0 num-partitions=3" \ --clientappio-api-address="127.0.0.1:9094" flower-supernode --insecure --superlink="127.0.0.1:9092" \ --node-config="partition-id=1 num-partitions=3" \ --clientappio-api-address="127.0.0.1:9095" flower-supernode --insecure --superlink="127.0.0.1:9092" \ --node-config="partition-id=2 num-partitions=3" \ --clientappio-api-address="127.0.0.1:9096" # submit the app run against those live nodes flwr run . local-deployment
Add a local-deployment federation to pyproject.toml when you want that:
[tool.flwr.federations.local-deployment] address = "127.0.0.1:9093" insecure = true
Lyrics: zero-download mode
The lyrics node runs 100% locally either way. By default it uses Qwen2.5-0.5B (cached after first download). For instant runs with no download at all:
LYRICS_MODE=template flwr run . local-sim
This uses a pure-Python template + word-bank generator — no model, no network, runs in milliseconds. Same output path (outputs/lyrics.txt).
You can also try it standalone:
python -m bloomkit.agents.lyrics_agent "neon gospel"
Optional: SD-Turbo hero image on the poster
USE_SD_TURBO=1 flwr run . local-sim
Adds stabilityai/sd-turbo (~2 GB) and writes outputs/poster.hero.png.
Files
bloomkit/
├── pyproject.toml ← Flower app + federation config
├── run.ps1 / run.sh ← one-shot install + run
├── bloomkit/
│ ├── server_app.py ← ServerApp on the SuperLink
│ ├── client_app.py ← ClientApp on every SuperNode
│ ├── task.py ← role assignment
│ ├── viewer.py ← local FastAPI viewer
│ └── agents/
│ ├── lyrics_agent.py ← Qwen2.5-0.5B
│ ├── music_agent.py ← MusicGen-small
│ └── poster_agent.py ← SVG template (+ optional SD-Turbo)
├── web/
│ ├── index.html ← viewer UI
│ └── poster_template.svg ← Jinja2 SVG poster
└── outputs/ ← manifest.json, lyrics.txt, music.wav, poster.svg
Why BloomKit?
- Bloom — a nod to Flower, the orchestration framework the whole thing is built on.
- Kit — a boxed set of small, self-contained tools you run on your own machine.
No cloud, no accounts, no bill. Just a laptop, three small models, and one brief.